Merge branch 'master' of ssh://noisy/home/noisy3/OpenFOAM/OpenFOAM-dev

This commit is contained in:
andy
2009-12-16 15:03:19 +00:00
41 changed files with 2799 additions and 314 deletions

View File

@ -1,4 +1,7 @@
calcEntry/calcEntry.C
dictionaryTest.C
calcEntry/calcEntry.C
calcEntry/calcEntryParser.cpp
calcEntry/calcEntryScanner.cpp
EXE = $(FOAM_USER_APPBIN)/dictionaryTest

View File

@ -0,0 +1,141 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::CocoParserErrors
Description
Templated class to shadow the error handling for Coco/R parsers
\*---------------------------------------------------------------------------*/
#ifndef CocoParserErrors_H
#define CocoParserErrors_H
#include "error.H"
#include "wchar.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class CocoParserErrors Declaration
\*---------------------------------------------------------------------------*/
template<class BaseClass>
class CocoParserErrors
:
public BaseClass
{
// Private data
//- The name issued in warnings and errors
word name_;
public:
// Constructors
//- Construct with given name
CocoParserErrors(const word& name)
:
BaseClass(),
name_(name)
{}
//- Destructor
virtual ~CocoParserErrors()
{}
// Member functions
//- Return the name issued for warnings
virtual const word& name() const
{
return name_;
}
//- Return the name issued for warnings
virtual word& name()
{
return name_;
}
// Error Handling
//- Handle a general warning 'msg'
virtual void Warning(const wchar_t* msg)
{
WarningIn(name_)
<< msg << endl;
}
//- Handle a general warning 'msg'
virtual void Warning(int line, int col, const wchar_t* msg)
{
WarningIn(name_)
<<"line " << line << " col " << col << ": "
<< msg << endl;
}
//- Handle general error 'msg' (eg, a semantic error)
virtual void Error(int line, int col, const wchar_t* msg)
{
FatalErrorIn(name_)
<< "line " << line << " col " << col <<": " << msg << endl
<< exit(FatalError);
}
//- Handle general error 'msg' (eg, a semantic error)
virtual void Error(const wchar_t* msg)
{
FatalErrorIn(name_)
<< msg << endl
<< exit(FatalError);
}
//- Handle a general exception 'msg'
virtual void Exception(const wchar_t* msg)
{
this->Error(msg);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,225 @@
/*-------------------------------------------------------------------------
compile with:
Coco \
-frames $WM_THIRD_PARTY_DIR/coco-r \
-prefix calcEntry \
-namespace Foam::functionEntries::calcEntryInternal \
SimpleCalc.atg
-------------------------------------------------------------------------*/
#include "dictionary.H"
#include "scalar.H"
#include "error.H"
#include "wchar.H"
COMPILER SimpleCalc
// Simple four function calculator for OpenFOAM dictionaries
//! with debug
static const int debug = 0;
//! The parent dictionary
mutable dictionary* dict_;
//! The calculation result
scalar val;
//! token -> scalar
scalar getScalar() const
{
return coco_string_toDouble(t->val);
}
//! token -> string
std::string getString() const
{
char* str = coco_string_create_char(t->val);
std::string s(str);
coco_string_delete(str);
return s;
}
//! attach a dictionary
void dict(const dictionary& dict) const
{
dict_ = const_cast<dictionary*>(&dict);
}
//! lookup dictionary entry
scalar getDictLookup() const
{
scalar dictValue = 0;
if (!dict_)
{
FatalErrorIn
(
"SimpleCalc::getDictEntry() const"
) << "No dictionary attached!"
<< exit(FatalError);
return 0;
}
char* chars = coco_string_create_char
(
t->val,
1,
(coco_string_length(t->val) - 1)
);
word keyword(chars);
coco_string_delete(chars);
if (debug)
{
Info<<"lookup: " << keyword << nl;
}
entry* entryPtr = dict_->lookupEntryPtr(keyword, true, false);
if (entryPtr && !entryPtr->isDict())
{
entryPtr->stream() >> dictValue;
}
else
{
FatalErrorIn
(
"SimpleCalc::getDictEntry() const"
) << "keyword " << keyword << " is undefined in dictionary "
<< exit(FatalError);
}
return dictValue;
}
scalar Result() const
{
return val;
}
// * * * * * * * * * * * * * * * CHARACTERS * * * * * * * * * * * * * * * * //
CHARACTERS
letter = 'A'..'Z' + 'a'..'z'.
qualifier = '_' + ':'.
dollar = '$'.
digit = "0123456789".
sign = '+' + '-'.
cr = '\r'.
lf = '\n'.
tab = '\t'.
stringCh = ANY - '"' - '\\' - cr - lf.
printable = '\u0020' .. '\u007e'.
// * * * * * * * * * * * * * * * * TOKENS * * * * * * * * * * * * * * * * * //
TOKENS
// identifier
ident =
letter { letter | digit | qualifier }.
// string
string =
'"' { stringCh | '\\' printable } '"'.
// dictionary lookup identifier
// starts with '$' and otherwise limited to a normal indentifier
variable =
dollar letter { letter | digit | qualifier }.
// floating point and integer numbers
number =
[sign] ('.' digit { digit } ) | ( digit { digit } [ '.' { digit } ])
[ ('E' | 'e') [sign] digit { digit } ].
// * * * * * * * * * * * PRAGMAS / COMMENTS / IGNORE * * * * * * * * * * * //
COMMENTS FROM "/*" TO "*/" NESTED
COMMENTS FROM "//" TO lf
// ignore unprintables
IGNORE ANY - printable
// * * * * * * * * * * * * * * * PRODUCTIONS * * * * * * * * * * * * * * * //
PRODUCTIONS
SimpleCalc (. val = 0;
if (debug){Info<<"start val"<< nl;}
.)
=
( '{' Expr<val> '}' | Expr<val> )
EOF
.
/*---------------------------------------------------------------------------*/
Expr<scalar& val> (. scalar val2 = 0;
if (debug) {Info<<"Expr:"<< val<< nl;}
.)
=
Term<val>
{
"+" Term<val2> (. if (debug) {Info<<"+Term:"<<val2 <<nl;}
val += val2;
if (debug) {Info<<"="<< val << nl;}
.)
| "-" Term<val2> (. if (debug) {Info<<"-Term:"<<val2 <<nl;}
val -= val2;
if (debug) {Info<<"="<< val << nl;}
.)
}
.
/*---------------------------------------------------------------------------*/
Term<scalar& val> (. scalar val2 = 0;
if (debug) {Info<<"Term:"<< val<< nl;}
.)
=
Factor<val>
{
"*" Factor<val2> (. if (debug) {Info<<"*Factor:"<<val2 << nl;}
val *= val2;
if (debug) {Info<<"="<< val << nl; }
.)
| "/" Factor<val2> (. if (debug) {Info<<"/Factor:"<<val2 << nl;}
val /= val2;
if (debug) {Info<<"="<< val << nl; }
.)
}
.
/*---------------------------------------------------------------------------*/
Factor<scalar& val>
=
variable (. val = getDictLookup();
if (debug) {Info<<"lookup:"<<val<<nl;}
.)
| number (. val = getScalar();
if (debug) {Info<<"got num:"<<val<<nl;}
.)
| '-' '(' Expr<val> ')' (. val = -val;
if (debug) {Info<<"inv:"<<val<<nl;}
.)
| '(' Expr<val> ')' (. if (debug){Info<<"got Expr:"<<val<<nl;} .)
.
/*---------------------------------------------------------------------------*/
END SimpleCalc.
// ************************************************************************* //

View File

@ -0,0 +1,11 @@
#/bin/sh
cd ${0%/*} || exit 1 # run from this directory
# this will have to do until we make a makefile rule
Coco \
-frames $WM_THIRD_PARTY_DIR/coco-r \
-prefix calcEntry \
-namespace Foam::functionEntries::calcEntryInternal \
SimpleCalc.atg

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -30,6 +30,10 @@ License
#include "OStringStream.H"
#include "addToMemberFunctionSelectionTable.H"
#include "ISstream.H"
#include "CocoParserErrors.H"
#include "calcEntryParser.h"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
@ -56,14 +60,121 @@ bool Foam::functionEntries::calcEntry::execute
(
const dictionary& parentDict,
primitiveEntry& entry,
Istream& is
Istream& istr
)
{
dictionary args(parentDict, is);
OStringStream resultStream;
resultStream
<< (args.lookup("x")[0].number() + args.lookup("y")[0].number());
entry.read(parentDict, IStringStream(resultStream.str())());
static const int maxLen = 1024;
static const int errLen = 80; // truncate error message for readability
static char buf[maxLen];
ISstream& is = dynamicCast<ISstream>(istr);
// get the { ... } argument without the enclosing brace brackets
//
// THIS NEEDS REWORKING (LATER) ...
char c = 0;
if (!is.read(c).good() || c != token::BEGIN_BLOCK)
{
is.setBad();
FatalIOErrorIn("functionEntries::calcEntry::execute()", is)
<< "Expected a '" << token::BEGIN_BLOCK
<< "', found '" << c << "'" << exit(FatalIOError);
return false;
}
register int nChar = 0;
buf[nChar++] = token::BEGIN_BLOCK;
int listDepth = 1; // already saw the first '{'
while (is.get(c).good())
{
buf[nChar++] = c;
if (nChar == maxLen)
{
buf[errLen] = '\0';
FatalIOErrorIn("functionEntries::calcEntry::execute()", is)
<< "argument \"" << buf << "...\"\n"
<< " is too long (max. " << maxLen << " characters)"
<< exit(FatalIOError);
return false;
}
// handle nested blocks, even if we don't know what they'd
// be useful for
if (c == token::BEGIN_BLOCK)
{
++listDepth;
}
else if (c == token::END_BLOCK)
{
if (--listDepth == 0)
{
// done reading - overwrite the final '}'
// --nChar;
break;
}
}
}
buf[nChar] = '\0';
// emit some info
Info<< "grabbed " << nChar << " characters:" << nl
<< "----------\n"
<< buf << nl
<< "----------\n"
<< nl;
// define parser error handler
CocoParserErrors<calcEntryInternal::Errors>
myErrorHandler("calcEntry::Parser--");
calcEntryInternal::Scanner scanner(buf, nChar);
calcEntryInternal::Parser parser(&scanner, &myErrorHandler);
// Attach dictionary context
parser.dict(parentDict);
parser.Parse();
// Info<<"got: " << parser.Result() << endl;
tokenList tokens(2);
tokens[0] = parser.Result();
tokens[1] = token::END_STATEMENT;
// Info<<"tokens[0] = " << tokens[0].info() <<nl;
// Info<<"tokens[1] = " << tokens[1].info() <<nl;
//
// {
// const tokenList& toks = entry;
//
// forAll(toks, tokI)
// {
// Info<< tokI <<":= " << toks[tokI].info() << endl;
// }
// }
ITstream its("ParserResult", tokens);
entry.read(parentDict, its);
// Info<< "size: " << entry.size() << endl;
// entry = newente;
// entry.print(Info);
/// const tokenList& toks = entry;
///
/// forAll(toks, tokI)
/// {
/// Info<< tokI <<":= " << toks[tokI].info() << endl;
/// }
///
return true;
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -26,6 +26,8 @@ Class
Foam::functionEntries::calcEntry
Description
This dictionary function entry may or may not do anything particularly
useful - depending upon what is currently being used to test.
SourceFiles
calcEntry.C
@ -45,7 +47,7 @@ namespace functionEntries
{
/*---------------------------------------------------------------------------*\
Class calcEntry Declaration
Class calcEntry Declaration
\*---------------------------------------------------------------------------*/
class calcEntry

View File

@ -0,0 +1,324 @@
#include <wchar.h>
#include "calcEntryParser.h"
namespace Foam {
namespace functionEntries {
namespace calcEntryInternal {
// ----------------------------------------------------------------------------
// Parser Implementation
// ----------------------------------------------------------------------------
void Parser::SynErr(int n) {
if (errDist >= minErrDist) errors->SynErr(la->line, la->col, n);
errDist = 0;
}
void Parser::SemErr(const wchar_t* msg) {
if (errDist >= minErrDist) errors->Error(t->line, t->col, msg);
errDist = 0;
}
void Parser::Get() {
for (;;) {
t = la;
la = scanner->Scan();
if (la->kind <= maxT) {
++errDist;
break;
}
if (dummyToken != t) {
dummyToken->kind = t->kind;
dummyToken->pos = t->pos;
dummyToken->col = t->col;
dummyToken->line = t->line;
dummyToken->next = NULL;
coco_string_delete(dummyToken->val);
dummyToken->val = coco_string_create(t->val);
t = dummyToken;
}
la = t;
}
}
void Parser::Expect(int n) {
if (la->kind == n) {
Get();
}
else {
SynErr(n);
}
}
void Parser::ExpectWeak(int n, int follow) {
if (la->kind == n) {
Get();
}
else {
SynErr(n);
while (!StartOf(follow)) {
Get();
}
}
}
bool Parser::WeakSeparator(int n, int syFol, int repFol) {
if (la->kind == n) {
Get();
return true;
}
else if (StartOf(repFol)) {
return false;
}
else {
SynErr(n);
while (!(StartOf(syFol) || StartOf(repFol) || StartOf(0))) {
Get();
}
return StartOf(syFol);
}
}
void Parser::SimpleCalc() {
val = 0;
if (debug){Info<<"start val"<< nl;}
if (la->kind == 5) {
Get();
Expr(val);
Expect(6);
} else if (StartOf(1)) {
Expr(val);
} else SynErr(14);
Expect(0);
}
void Parser::Expr(scalar& val) {
scalar val2 = 0;
if (debug) {Info<<"Expr:"<< val<< nl;}
Term(val);
while (la->kind == 7 || la->kind == 8) {
if (la->kind == 7) {
Get();
Term(val2);
if (debug) {Info<<"+Term:"<<val2 <<nl;}
val += val2;
if (debug) {Info<<"="<< val << nl;}
} else {
Get();
Term(val2);
if (debug) {Info<<"-Term:"<<val2 <<nl;}
val -= val2;
if (debug) {Info<<"="<< val << nl;}
}
}
}
void Parser::Term(scalar& val) {
scalar val2 = 0;
if (debug) {Info<<"Term:"<< val<< nl;}
Factor(val);
while (la->kind == 9 || la->kind == 10) {
if (la->kind == 9) {
Get();
Factor(val2);
if (debug) {Info<<"*Factor:"<<val2 << nl;}
val *= val2;
if (debug) {Info<<"="<< val << nl; }
} else {
Get();
Factor(val2);
if (debug) {Info<<"/Factor:"<<val2 << nl;}
val /= val2;
if (debug) {Info<<"="<< val << nl; }
}
}
}
void Parser::Factor(scalar& val) {
if (la->kind == 3) {
Get();
val = getDictLookup();
if (debug) {Info<<"lookup:"<<val<<nl;}
} else if (la->kind == 4) {
Get();
val = getScalar();
if (debug) {Info<<"got num:"<<val<<nl;}
} else if (la->kind == 8) {
Get();
Expect(11);
Expr(val);
Expect(12);
val = -val;
if (debug) {Info<<"inv:"<<val<<nl;}
} else if (la->kind == 11) {
Get();
Expr(val);
Expect(12);
if (debug){Info<<"got Expr:"<<val<<nl;}
} else SynErr(15);
}
void Parser::Parse() {
t = NULL;
if (dummyToken) { // safety: someone might call Parse() twice
delete dummyToken;
}
la = dummyToken = new Token();
la->val = coco_string_create(L"Dummy Token");
Get();
SimpleCalc();
Expect(0);
}
Parser::Parser(Scanner* scan, Errors* err)
:
dummyToken(NULL),
deleteErrorsDestruct_(!err),
minErrDist(2),
errDist(minErrDist),
scanner(scan),
errors(err),
t(NULL),
la(NULL)
{
maxT = 13;
if (!errors) { // add in default error handling
errors = new Errors();
}
}
bool Parser::StartOf(int s) {
const bool T = true;
const bool x = false;
static bool set[2][15] = {
{T,x,x,x, x,x,x,x, x,x,x,x, x,x,x},
{x,x,x,T, T,x,x,x, T,x,x,T, x,x,x}
};
return set[s][la->kind];
}
Parser::~Parser() {
if (deleteErrorsDestruct_) { // delete default error handling
delete errors;
}
delete dummyToken;
}
// ----------------------------------------------------------------------------
// Errors Implementation
// ----------------------------------------------------------------------------
Errors::Errors()
:
count(0)
{}
Errors::~Errors()
{}
void Errors::clear() {
count = 0;
}
wchar_t* Errors::strerror(int n)
{
wchar_t* s;
switch (n) {
case 0: s = coco_string_create(L"EOF expected"); break;
case 1: s = coco_string_create(L"ident expected"); break;
case 2: s = coco_string_create(L"string expected"); break;
case 3: s = coco_string_create(L"variable expected"); break;
case 4: s = coco_string_create(L"number expected"); break;
case 5: s = coco_string_create(L"\"{\" expected"); break;
case 6: s = coco_string_create(L"\"}\" expected"); break;
case 7: s = coco_string_create(L"\"+\" expected"); break;
case 8: s = coco_string_create(L"\"-\" expected"); break;
case 9: s = coco_string_create(L"\"*\" expected"); break;
case 10: s = coco_string_create(L"\"/\" expected"); break;
case 11: s = coco_string_create(L"\"(\" expected"); break;
case 12: s = coco_string_create(L"\")\" expected"); break;
case 13: s = coco_string_create(L"??? expected"); break;
case 14: s = coco_string_create(L"invalid SimpleCalc"); break;
case 15: s = coco_string_create(L"invalid Factor"); break;
default:
{
wchar_t format[20];
coco_swprintf(format, 20, L"error %d", n);
s = coco_string_create(format);
}
break;
}
return s;
}
void Errors::Warning(const wchar_t* msg) {
wprintf(L"%ls\n", msg);
}
void Errors::Warning(int line, int col, const wchar_t* msg) {
wprintf(L"-- line %d col %d: %ls\n", line, col, msg);
}
void Errors::Error(int line, int col, const wchar_t* msg) {
wprintf(L"-- line %d col %d: %ls\n", line, col, msg);
count++;
}
void Errors::SynErr(int line, int col, int n) {
wchar_t* msg = this->strerror(n);
this->Error(line, col, msg);
coco_string_delete(msg);
}
void Errors::Exception(const wchar_t* msg) {
wprintf(L"%ls", msg);
::exit(1);
}
} // namespace
} // namespace
} // namespace

View File

@ -0,0 +1,192 @@
#ifndef COCO_calcEntryPARSER_H__
#define COCO_calcEntryPARSER_H__
#include "dictionary.H"
#include "scalar.H"
#include "error.H"
#include "wchar.H"
#include "calcEntryScanner.h"
namespace Foam {
namespace functionEntries {
namespace calcEntryInternal {
//! Parser error handing
class Errors {
public:
int count; //!< The number of errors detected
//! Allocate and return a string describing the given error code.
/** It is the responsibility of the caller to free this string,
* eg, with coco_string_delete()
*/
static wchar_t* strerror(int n);
Errors(); //!< Construct null - start with no errors
virtual ~Errors(); //!< Destructor
virtual void clear(); //!< Clear the error count
//! Handle a general warning 'msg'
virtual void Warning(const wchar_t* msg);
//! Handle a general warning 'msg'
virtual void Warning(int line, int col, const wchar_t* msg);
//! Handle general error 'msg' (eg, a semantic error)
virtual void Error(int line, int col, const wchar_t* msg);
//! Handle syntax error 'n', uses strerror for the message, calls Error()
virtual void SynErr(int line, int col, int n);
//! Handle a general exception 'msg'
virtual void Exception(const wchar_t* msg);
}; // Errors
//! A Coco/R Parser
class Parser {
private:
enum {
_EOF=0,
_ident=1,
_string=2,
_variable=3,
_number=4,
};
int maxT;
Token *dummyToken;
bool deleteErrorsDestruct_; //!< delete the 'errors' member in destructor
int minErrDist;
int errDist;
void SynErr(int n); //!< Handle syntax error 'n'
void Get();
void Expect(int n);
bool StartOf(int s);
void ExpectWeak(int n, int follow);
bool WeakSeparator(int n, int syFol, int repFol);
public:
Scanner *scanner;
Errors *errors;
Token *t; //!< last recognized token
Token *la; //!< lookahead token
static const int debug = 0;
//! The parent dictionary
mutable dictionary* dict_;
//! The calculation result
scalar val;
//! token -> scalar
scalar getScalar() const
{
return coco_string_toDouble(t->val);
}
//! token -> string
std::string getString() const
{
char* str = coco_string_create_char(t->val);
std::string s(str);
coco_string_delete(str);
return s;
}
//! attach a dictionary
void dict(const dictionary& dict) const
{
dict_ = const_cast<dictionary*>(&dict);
}
//! lookup dictionary entry
scalar getDictLookup() const
{
scalar dictValue = 0;
if (!dict_)
{
FatalErrorIn
(
"SimpleCalc::getDictEntry() const"
) << "No dictionary attached!"
<< exit(FatalError);
return 0;
}
char* chars = coco_string_create_char
(
t->val,
1,
(coco_string_length(t->val) - 1)
);
word keyword(chars);
coco_string_delete(chars);
if (debug)
{
Info<<"lookup: " << keyword << nl;
}
entry* entryPtr = dict_->lookupEntryPtr(keyword, true, false);
if (entryPtr && !entryPtr->isDict())
{
entryPtr->stream() >> dictValue;
}
else
{
FatalErrorIn
(
"SimpleCalc::getDictEntry() const"
) << "keyword " << keyword << " is undefined in dictionary "
<< exit(FatalError);
}
return dictValue;
}
scalar Result() const
{
return val;
}
// * * * * * * * * * * * * * * * CHARACTERS * * * * * * * * * * * * * * * * //
//! Construct for the specified scanner
/**
* Use the default error handling, or optionally provide an error
* handler, which will not be deleted upon destruction.
*/
Parser(Scanner* scan, Errors* err = 0);
~Parser(); //!< Destructor - cleanup errors and dummyToken
void SemErr(const wchar_t* msg); //!< Handle semantic error
void SimpleCalc();
void Expr(scalar& val);
void Term(scalar& val);
void Factor(scalar& val);
void Parse(); //!< Execute the parse operation
}; // end Parser
} // namespace
} // namespace
} // namespace
#endif // COCO_calcEntryPARSER_H__

View File

@ -0,0 +1,825 @@
#include <memory.h>
#include <string.h>
#include "calcEntryScanner.h"
namespace Foam {
namespace functionEntries {
namespace calcEntryInternal {
// * * * * * * * * * * Wide Character String Routines * * * * * * * * * * * //
// string handling, wide character
wchar_t* coco_string_create(const wchar_t* str) {
int len = coco_string_length(str);
wchar_t* dest = new wchar_t[len + 1];
if (len) {
wcsncpy(dest, str, len);
}
dest[len] = 0;
return dest;
}
wchar_t* coco_string_create(const wchar_t* str, int index, int length) {
int len = coco_string_length(str);
if (len) {
len = length;
}
wchar_t* dest = new wchar_t[len + 1];
if (len) {
wcsncpy(dest, &(str[index]), len);
}
dest[len] = 0;
return dest;
}
wchar_t* coco_string_create_upper(const wchar_t* str) {
if (!str) { return NULL; }
return coco_string_create_upper(str, 0, wcslen(str));
}
wchar_t* coco_string_create_upper(const wchar_t* str, int index, int len) {
if (!str) { return NULL; }
wchar_t* dest = new wchar_t[len + 1];
for (int i = 0; i < len; i++) {
const wchar_t ch = str[index + i];
if ((L'a' <= ch) && (ch <= L'z')) {
dest[i] = ch + (L'A' - L'a');
}
else {
dest[i] = ch;
}
}
dest[len] = L'\0';
return dest;
}
wchar_t* coco_string_create_lower(const wchar_t* str) {
if (!str) { return NULL; }
return coco_string_create_lower(str, 0, wcslen(str));
}
wchar_t* coco_string_create_lower(const wchar_t* str, int index, int len) {
if (!str) { return NULL; }
wchar_t* dest = new wchar_t[len + 1];
for (int i = 0; i < len; i++) {
const wchar_t ch = str[index + i];
if ((L'A' <= ch) && (ch <= L'Z')) {
dest[i] = ch - (L'A' - L'a');
}
else {
dest[i] = ch;
}
}
dest[len] = L'\0';
return dest;
}
wchar_t* coco_string_create_append(const wchar_t* str1, const wchar_t* str2) {
int str1Len = coco_string_length(str1);
int str2Len = coco_string_length(str2);
wchar_t* dest = new wchar_t[str1Len + str2Len + 1];
if (str1Len) { wcscpy(dest, str1); }
if (str2Len) { wcscpy(dest + str1Len, str2); }
dest[str1Len + str2Len] = 0;
return dest;
}
wchar_t* coco_string_create_append(const wchar_t* str1, const wchar_t ch) {
int len = coco_string_length(str1);
wchar_t* dest = new wchar_t[len + 2];
wcsncpy(dest, str1, len); // or use if (len) { wcscpy(dest, str1); }
dest[len] = ch;
dest[len + 1] = 0;
return dest;
}
void coco_string_delete(wchar_t* &str) {
delete [] str;
str = NULL;
}
int coco_string_length(const wchar_t* str) {
return str ? wcslen(str) : 0;
}
bool coco_string_endswith(const wchar_t* str, const wchar_t* endstr) {
int strLen = wcslen(str);
int endLen = wcslen(endstr);
return (endLen <= strLen) && (wcscmp(str + strLen - endLen, endstr) == 0);
}
int coco_string_indexof(const wchar_t* str, const wchar_t ch) {
const wchar_t* fnd = wcschr(str, ch);
return fnd ? (fnd - str) : -1;
}
int coco_string_lastindexof(const wchar_t* str, const wchar_t ch) {
const wchar_t* fnd = wcsrchr(str, ch);
return fnd ? (fnd - str) : -1;
}
void coco_string_merge(wchar_t* &dest, const wchar_t* str) {
if (!str) { return; }
wchar_t* newstr = coco_string_create_append(dest, str);
delete [] dest;
dest = newstr;
}
bool coco_string_equal(const wchar_t* str1, const wchar_t* str2) {
return wcscmp(str1, str2) == 0;
}
int coco_string_compareto(const wchar_t* str1, const wchar_t* str2) {
return wcscmp(str1, str2);
}
int coco_string_hash(const wchar_t* str) {
int h = 0;
if (!str) { return 0; }
while (*str != 0) {
h = (h * 7) ^ *str;
++str;
}
if (h < 0) { h = -h; }
return h;
}
double coco_string_toDouble(const wchar_t* str)
{
return str ? wcstod(str, NULL) : 0;
}
float coco_string_toFloat(const wchar_t* str)
{
return str ? wcstof(str, NULL) : 0;
}
//
// string handling, byte character
//
wchar_t* coco_string_create(const char* str) {
int len = str ? strlen(str) : 0;
wchar_t* dest = new wchar_t[len + 1];
for (int i = 0; i < len; ++i) {
dest[i] = (wchar_t) str[i];
}
dest[len] = 0;
return dest;
}
wchar_t* coco_string_create(const char* str, int index, int length) {
int len = str ? length : 0;
wchar_t* dest = new wchar_t[len + 1];
for (int i = 0; i < len; ++i) {
dest[i] = (wchar_t) str[index + i];
}
dest[len] = 0;
return dest;
}
char* coco_string_create_char(const wchar_t* str) {
int len = coco_string_length(str);
char *dest = new char[len + 1];
for (int i = 0; i < len; ++i)
{
dest[i] = (char) str[i];
}
dest[len] = 0;
return dest;
}
char* coco_string_create_char(const wchar_t* str, int index, int length) {
int len = coco_string_length(str);
if (len) {
len = length;
}
char *dest = new char[len + 1];
for (int i = 0; i < len; ++i) {
dest[i] = (char) str[index + i];
}
dest[len] = 0;
return dest;
}
void coco_string_delete(char* &str) {
delete [] str;
str = NULL;
}
double coco_string_toDouble(const char* str)
{
return str ? strtod(str, NULL) : 0;
}
float coco_string_toFloat(const char* str)
{
return str ? strtof(str, NULL) : 0;
}
// * * * * * * * * * End of Wide Character String Routines * * * * * * * * * //
Token::Token()
:
kind(0),
pos(0),
col(0),
line(0),
val(NULL),
next(NULL)
{}
Token::~Token() {
coco_string_delete(val);
}
Buffer::Buffer(FILE* s, bool isUserStream) {
// ensure binary read on windows
#if _MSC_VER >= 1300
_setmode(_fileno(s), _O_BINARY);
#endif
stream = s; this->isUserStream = isUserStream;
if (CanSeek()) {
fseek(s, 0, SEEK_END);
fileLen = ftell(s);
fseek(s, 0, SEEK_SET);
bufLen = (fileLen < MAX_BUFFER_LENGTH) ? fileLen : MAX_BUFFER_LENGTH;
bufStart = INT_MAX; // nothing in the buffer so far
}
else {
fileLen = bufLen = bufStart = 0;
}
bufCapacity = (bufLen > 0) ? bufLen : MIN_BUFFER_LENGTH;
buf = new unsigned char[bufCapacity];
if (fileLen > 0) SetPos(0); // setup buffer to position 0 (start)
else bufPos = 0; // index 0 is already after the file, thus Pos = 0 is invalid
if (bufLen == fileLen && CanSeek()) Close();
}
Buffer::Buffer(Buffer* b) {
buf = b->buf;
bufCapacity = b->bufCapacity;
b->buf = NULL;
bufStart = b->bufStart;
bufLen = b->bufLen;
fileLen = b->fileLen;
bufPos = b->bufPos;
stream = b->stream;
b->stream = NULL;
isUserStream = b->isUserStream;
}
Buffer::Buffer(const unsigned char* buf, int len) {
this->buf = new unsigned char[len];
memcpy(this->buf, buf, len*sizeof(unsigned char));
bufStart = 0;
bufCapacity = bufLen = len;
fileLen = len;
bufPos = 0;
stream = NULL;
}
Buffer::Buffer(const char* buf, int len) {
this->buf = new unsigned char[len];
memcpy(this->buf, buf, len*sizeof(unsigned char));
bufStart = 0;
bufCapacity = bufLen = len;
fileLen = len;
bufPos = 0;
stream = NULL;
}
Buffer::~Buffer() {
Close();
if (buf != NULL) {
delete [] buf;
buf = NULL;
}
}
void Buffer::Close() {
if (!isUserStream && stream != NULL) {
fclose(stream);
stream = NULL;
}
}
int Buffer::Read() {
if (bufPos < bufLen) {
return buf[bufPos++];
} else if (GetPos() < fileLen) {
SetPos(GetPos()); // shift buffer start to Pos
return buf[bufPos++];
} else if ((stream != NULL) && !CanSeek() && (ReadNextStreamChunk() > 0)) {
return buf[bufPos++];
} else {
return EoF;
}
}
int Buffer::Peek() {
int curPos = GetPos();
int ch = Read();
SetPos(curPos);
return ch;
}
wchar_t* Buffer::GetString(int beg, int end) {
int len = 0;
wchar_t *buf = new wchar_t[end - beg];
int oldPos = GetPos();
SetPos(beg);
while (GetPos() < end) buf[len++] = (wchar_t) Read();
SetPos(oldPos);
wchar_t *res = coco_string_create(buf, 0, len);
coco_string_delete(buf);
return res;
}
int Buffer::GetPos() {
return bufPos + bufStart;
}
void Buffer::SetPos(int value) {
if ((value >= fileLen) && (stream != NULL) && !CanSeek()) {
// Wanted position is after buffer and the stream
// is not seek-able e.g. network or console,
// thus we have to read the stream manually till
// the wanted position is in sight.
while ((value >= fileLen) && (ReadNextStreamChunk() > 0))
{}
}
if ((value < 0) || (value > fileLen)) {
wprintf(L"--- buffer out of bounds access, position: %d\n", value);
::exit(1);
}
if ((value >= bufStart) && (value < (bufStart + bufLen))) { // already in buffer
bufPos = value - bufStart;
} else if (stream != NULL) { // must be swapped in
fseek(stream, value, SEEK_SET);
bufLen = fread(buf, sizeof(unsigned char), bufCapacity, stream);
bufStart = value; bufPos = 0;
} else {
bufPos = fileLen - bufStart; // make Pos return fileLen
}
}
// Read the next chunk of bytes from the stream, increases the buffer
// if needed and updates the fields fileLen and bufLen.
// Returns the number of bytes read.
int Buffer::ReadNextStreamChunk() {
int freeLen = bufCapacity - bufLen;
if (freeLen == 0) {
// in the case of a growing input stream
// we can neither seek in the stream, nor can we
// foresee the maximum length, thus we must adapt
// the buffer size on demand.
bufCapacity = bufLen * 2;
unsigned char *newBuf = new unsigned char[bufCapacity];
memcpy(newBuf, buf, bufLen*sizeof(unsigned char));
delete [] buf;
buf = newBuf;
freeLen = bufLen;
}
int read = fread(buf + bufLen, sizeof(unsigned char), freeLen, stream);
if (read > 0) {
fileLen = bufLen = (bufLen + read);
return read;
}
// end of stream reached
return 0;
}
bool Buffer::CanSeek() {
return (stream != NULL) && (ftell(stream) != -1);
}
int UTF8Buffer::Read() {
int ch;
do {
ch = Buffer::Read();
// until we find a utf8 start (0xxxxxxx or 11xxxxxx)
} while ((ch >= 128) && ((ch & 0xC0) != 0xC0) && (ch != EoF));
if (ch < 128 || ch == EoF) {
// nothing to do, first 127 chars are the same in ascii and utf8
// 0xxxxxxx or end of file character
} else if ((ch & 0xF0) == 0xF0) {
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
int c1 = ch & 0x07; ch = Buffer::Read();
int c2 = ch & 0x3F; ch = Buffer::Read();
int c3 = ch & 0x3F; ch = Buffer::Read();
int c4 = ch & 0x3F;
ch = (((((c1 << 6) | c2) << 6) | c3) << 6) | c4;
} else if ((ch & 0xE0) == 0xE0) {
// 1110xxxx 10xxxxxx 10xxxxxx
int c1 = ch & 0x0F; ch = Buffer::Read();
int c2 = ch & 0x3F; ch = Buffer::Read();
int c3 = ch & 0x3F;
ch = (((c1 << 6) | c2) << 6) | c3;
} else if ((ch & 0xC0) == 0xC0) {
// 110xxxxx 10xxxxxx
int c1 = ch & 0x1F; ch = Buffer::Read();
int c2 = ch & 0x3F;
ch = (c1 << 6) | c2;
}
return ch;
}
Scanner::Scanner(const unsigned char* buf, int len) {
buffer = new Buffer(buf, len);
Init();
}
Scanner::Scanner(const char* buf, int len) {
buffer = new Buffer(buf, len);
Init();
}
Scanner::Scanner(const wchar_t* fileName) {
FILE* stream;
char *chFileName = coco_string_create_char(fileName);
if ((stream = fopen(chFileName, "rb")) == NULL) {
wprintf(L"--- Cannot open file %ls\n", fileName);
::exit(1);
}
coco_string_delete(chFileName);
buffer = new Buffer(stream, false);
Init();
}
Scanner::Scanner(FILE* s) {
buffer = new Buffer(s, true);
Init();
}
Scanner::~Scanner() {
char* cur = (char*) firstHeap;
while (cur != NULL) {
cur = *(char**) (cur + HEAP_BLOCK_SIZE);
free(firstHeap);
firstHeap = cur;
}
delete [] tval;
delete buffer;
}
void Scanner::Init() {
maxT = 13;
noSym = 13;
int i;
for (i = 65; i <= 90; ++i) start.set(i, 1);
for (i = 97; i <= 122; ++i) start.set(i, 1);
for (i = 36; i <= 36; ++i) start.set(i, 5);
start.set(45, 20);
for (i = 48; i <= 57; ++i) start.set(i, 9);
start.set(34, 2);
start.set(46, 7);
start.set(123, 14);
start.set(125, 15);
start.set(43, 21);
start.set(42, 16);
start.set(47, 17);
start.set(40, 18);
start.set(41, 19);
start.set(Buffer::EoF, -1);
tvalLength = 128;
tval = new wchar_t[tvalLength]; // text of current token
// HEAP_BLOCK_SIZE byte heap + pointer to next heap block
heap = malloc(HEAP_BLOCK_SIZE + sizeof(void*));
firstHeap = heap;
heapEnd = (void**) (((char*) heap) + HEAP_BLOCK_SIZE);
*heapEnd = 0;
heapTop = heap;
if (sizeof(Token) > HEAP_BLOCK_SIZE) {
wprintf(L"--- Too small HEAP_BLOCK_SIZE\n");
::exit(1);
}
pos = -1; line = 1; col = 0;
oldEols = 0;
NextCh();
if (ch == 0xEF) { // check optional byte order mark for UTF-8
NextCh(); int ch1 = ch;
NextCh(); int ch2 = ch;
if (ch1 != 0xBB || ch2 != 0xBF) {
wprintf(L"Illegal byte order mark at start of file");
::exit(1);
}
Buffer *oldBuf = buffer;
buffer = new UTF8Buffer(buffer); col = 0;
delete oldBuf; oldBuf = NULL;
NextCh();
}
pt = tokens = CreateToken(); // first token is a dummy
}
void Scanner::NextCh() {
if (oldEols > 0) {
ch = EOL;
oldEols--;
}
else {
pos = buffer->GetPos();
ch = buffer->Read(); col++;
// replace isolated '\r' by '\n' in order to make
// eol handling uniform across Windows, Unix and Mac
if (ch == L'\r' && buffer->Peek() != L'\n') ch = EOL;
if (ch == EOL) { line++; col = 0; }
}
}
void Scanner::AddCh() {
if (tlen >= tvalLength) {
tvalLength *= 2;
wchar_t *newBuf = new wchar_t[tvalLength];
memcpy(newBuf, tval, tlen*sizeof(wchar_t));
delete [] tval;
tval = newBuf;
}
if (ch != Buffer::EoF) {
tval[tlen++] = ch;
NextCh();
}
}
bool Scanner::Comment0() {
int level = 1, pos0 = pos, line0 = line, col0 = col;
NextCh();
if (ch == L'/') {
NextCh();
for(;;) {
if (ch == 10) {
level--;
if (level == 0) { oldEols = line - line0; NextCh(); return true; }
NextCh();
} else if (ch == buffer->EoF) return false;
else NextCh();
}
} else {
buffer->SetPos(pos0); NextCh(); line = line0; col = col0;
}
return false;
}
bool Scanner::Comment1() {
int level = 1, pos0 = pos, line0 = line, col0 = col;
NextCh();
if (ch == L'*') {
NextCh();
for(;;) {
if (ch == L'*') {
NextCh();
if (ch == L'/') {
level--;
if (level == 0) { oldEols = line - line0; NextCh(); return true; }
NextCh();
}
} else if (ch == L'/') {
NextCh();
if (ch == L'*') {
level++; NextCh();
}
} else if (ch == buffer->EoF) return false;
else NextCh();
}
} else {
buffer->SetPos(pos0); NextCh(); line = line0; col = col0;
}
return false;
}
void Scanner::CreateHeapBlock() {
void* newHeap;
char* cur = (char*) firstHeap;
while (((char*) tokens < cur) || ((char*) tokens > (cur + HEAP_BLOCK_SIZE))) {
cur = *((char**) (cur + HEAP_BLOCK_SIZE));
free(firstHeap);
firstHeap = cur;
}
// HEAP_BLOCK_SIZE byte heap + pointer to next heap block
newHeap = malloc(HEAP_BLOCK_SIZE + sizeof(void*));
*heapEnd = newHeap;
heapEnd = (void**) (((char*) newHeap) + HEAP_BLOCK_SIZE);
*heapEnd = 0;
heap = newHeap;
heapTop = heap;
}
Token* Scanner::CreateToken() {
Token *t;
if (((char*) heapTop + (int) sizeof(Token)) >= (char*) heapEnd) {
CreateHeapBlock();
}
t = (Token*) heapTop;
heapTop = (void*) ((char*) heapTop + sizeof(Token));
t->val = NULL;
t->next = NULL;
return t;
}
void Scanner::AppendVal(Token *t) {
int reqMem = (tlen + 1) * sizeof(wchar_t);
if (((char*) heapTop + reqMem) >= (char*) heapEnd) {
if (reqMem > HEAP_BLOCK_SIZE) {
wprintf(L"--- Too long token value\n");
::exit(1);
}
CreateHeapBlock();
}
t->val = (wchar_t*) heapTop;
heapTop = (void*) ((char*) heapTop + reqMem);
wcsncpy(t->val, tval, tlen);
t->val[tlen] = L'\0';
}
Token* Scanner::NextToken() {
while (ch == ' ' ||
ch <= 31 || (ch >= 127 && ch <= 65535)
) NextCh();
if ((ch == L'/' && Comment0()) || (ch == L'/' && Comment1())) return NextToken();
t = CreateToken();
t->pos = pos; t->col = col; t->line = line;
int state = start.state(ch);
tlen = 0; AddCh();
switch (state) {
case -1: { t->kind = eofSym; break; } // NextCh already done
case 0: { t->kind = noSym; break; } // NextCh already done
case 1:
case_1:
if ((ch >= L'0' && ch <= L':') || (ch >= L'A' && ch <= L'Z') || ch == L'_' || (ch >= L'a' && ch <= L'z')) {AddCh(); goto case_1;}
else {t->kind = 1; break;}
case 2:
case_2:
if (ch <= 9 || (ch >= 11 && ch <= 12) || (ch >= 14 && ch <= L'!') || (ch >= L'#' && ch <= L'[') || (ch >= L']' && ch <= 65535)) {AddCh(); goto case_2;}
else if (ch == L'"') {AddCh(); goto case_4;}
else if (ch == 92) {AddCh(); goto case_3;}
else {t->kind = noSym; break;}
case 3:
case_3:
if ((ch >= L' ' && ch <= L'~')) {AddCh(); goto case_2;}
else {t->kind = noSym; break;}
case 4:
case_4:
{t->kind = 2; break;}
case 5:
if ((ch >= L'A' && ch <= L'Z') || (ch >= L'a' && ch <= L'z')) {AddCh(); goto case_6;}
else {t->kind = noSym; break;}
case 6:
case_6:
if ((ch >= L'0' && ch <= L':') || (ch >= L'A' && ch <= L'Z') || ch == L'_' || (ch >= L'a' && ch <= L'z')) {AddCh(); goto case_6;}
else {t->kind = 3; break;}
case 7:
case_7:
if ((ch >= L'0' && ch <= L'9')) {AddCh(); goto case_8;}
else {t->kind = noSym; break;}
case 8:
case_8:
if ((ch >= L'0' && ch <= L'9')) {AddCh(); goto case_8;}
else {t->kind = 4; break;}
case 9:
case_9:
if ((ch >= L'0' && ch <= L'9')) {AddCh(); goto case_9;}
else if (ch == L'E' || ch == L'e') {AddCh(); goto case_10;}
else if (ch == L'.') {AddCh(); goto case_13;}
else {t->kind = 4; break;}
case 10:
case_10:
if ((ch >= L'0' && ch <= L'9')) {AddCh(); goto case_12;}
else if (ch == L'+' || ch == L'-') {AddCh(); goto case_11;}
else {t->kind = noSym; break;}
case 11:
case_11:
if ((ch >= L'0' && ch <= L'9')) {AddCh(); goto case_12;}
else {t->kind = noSym; break;}
case 12:
case_12:
if ((ch >= L'0' && ch <= L'9')) {AddCh(); goto case_12;}
else {t->kind = 4; break;}
case 13:
case_13:
if ((ch >= L'0' && ch <= L'9')) {AddCh(); goto case_13;}
else if (ch == L'E' || ch == L'e') {AddCh(); goto case_10;}
else {t->kind = 4; break;}
case 14:
{t->kind = 5; break;}
case 15:
{t->kind = 6; break;}
case 16:
{t->kind = 9; break;}
case 17:
{t->kind = 10; break;}
case 18:
{t->kind = 11; break;}
case 19:
{t->kind = 12; break;}
case 20:
if (ch == L'.') {AddCh(); goto case_7;}
else {t->kind = 8; break;}
case 21:
if (ch == L'.') {AddCh(); goto case_7;}
else {t->kind = 7; break;}
}
AppendVal(t);
return t;
}
// get the next token (possibly a token already seen during peeking)
Token* Scanner::Scan() {
if (tokens->next == NULL) {
return pt = tokens = NextToken();
} else {
pt = tokens = tokens->next;
return tokens;
}
}
// peek for the next token, ignore pragmas
Token* Scanner::Peek() {
do {
if (pt->next == NULL) {
pt->next = NextToken();
}
pt = pt->next;
} while (pt->kind > maxT); // skip pragmas
return pt;
}
// make sure that peeking starts at the current scan position
void Scanner::ResetPeek() {
pt = tokens;
}
} // namespace
} // namespace
} // namespace

View File

@ -0,0 +1,379 @@
#ifndef COCO_calcEntrySCANNER_H__
#define COCO_calcEntrySCANNER_H__
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
// io.h and fcntl are used to ensure binary read from streams on windows
#if _MSC_VER >= 1300
#include <io.h>
#include <fcntl.h>
#endif
#if _MSC_VER >= 1400
#define coco_swprintf swprintf_s
#elif _MSC_VER >= 1300
#define coco_swprintf _snwprintf
#else
// assume every other compiler knows swprintf
#define coco_swprintf swprintf
#endif
#define COCO_WCHAR_MAX 65535
#define MIN_BUFFER_LENGTH 1024
#define MAX_BUFFER_LENGTH (64*MIN_BUFFER_LENGTH)
#define HEAP_BLOCK_SIZE (64*1024)
namespace Foam {
namespace functionEntries {
namespace calcEntryInternal {
// * * * * * * * * * * Wide Character String Routines * * * * * * * * * * * //
//
// string handling, wide character
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//! Create by copying str
wchar_t* coco_string_create(const wchar_t* str);
//! Create a substring of str starting at index and length characters long
wchar_t* coco_string_create(const wchar_t* str, int index, int length);
//! Create an uppercase string from str
wchar_t* coco_string_create_upper(const wchar_t* str);
//! Create an uppercase substring from str starting at index and length characters long
wchar_t* coco_string_create_upper(const wchar_t* str, int index, int length);
//! Create a lowercase string from str
wchar_t* coco_string_create_lower(const wchar_t* str);
//! Create a lowercase substring from str starting at index and length characters long
wchar_t* coco_string_create_lower(const wchar_t* str, int index, int length);
//! Create a string by concatenating str1 and str2
wchar_t* coco_string_create_append(const wchar_t* str1, const wchar_t* str2);
//! Create a string by concatenating a character to the end of str
wchar_t* coco_string_create_append(const wchar_t* str, const wchar_t ch);
//! Free storage and nullify the argument
void coco_string_delete(wchar_t* &str);
//! The length of the str, or 0 if the str is NULL
int coco_string_length(const wchar_t* str);
//! Return true if the str ends with the endstr
bool coco_string_endswith(const wchar_t* str, const wchar_t* endstr);
//! Return the index of the first occurrence of ch.
// Return -1 if nothing is found.
int coco_string_indexof(const wchar_t* str, const wchar_t ch);
//! Return the index of the last occurrence of ch.
// Return -1 if nothing is found.
int coco_string_lastindexof(const wchar_t* str, const wchar_t ch);
//! Append str to dest
void coco_string_merge(wchar_t* &dest, const wchar_t* str);
//! Compare strings, return true if they are equal
bool coco_string_equal(const wchar_t* str1, const wchar_t* str2);
//! Compare strings, return 0 if they are equal
int coco_string_compareto(const wchar_t* str1, const wchar_t* str2);
//! Simple string hashing function
int coco_string_hash(const wchar_t* str);
//
// String conversions
// ~~~~~~~~~~~~~~~~~~
//! Convert wide string to double
double coco_string_toDouble(const wchar_t* str);
//! Convert wide string to float
float coco_string_toFloat(const wchar_t* str);
//
// String handling, byte character
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//! Create by copying byte str
wchar_t* coco_string_create(const char* str);
//! Create a substring of byte str starting at index and length characters long
wchar_t* coco_string_create(const char* str, int index, int length);
//! Create a byte string by copying str
char* coco_string_create_char(const wchar_t* str);
//! Create a byte substring of str starting at index and length characters long
char* coco_string_create_char(const wchar_t* str, int index, int length);
//! Free storage and nullify the argument
void coco_string_delete(char* &str);
//
// String conversions, byte character
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//! Convert byte string to double
double coco_string_toDouble(const char* str);
//! Convert byte string to float
float coco_string_toFloat(const char* str);
// * * * * * * * * * End of Wide Character String Routines * * * * * * * * * //
//! Scanner Token
class Token
{
public:
int kind; //!< token kind
int pos; //!< token position in the source text (starting at 0)
int col; //!< token column (starting at 1)
int line; //!< token line (starting at 1)
wchar_t* val; //!< token value
Token *next; //!< Peek tokens are kept in linked list
Token(); //!< Construct null
~Token(); //!< Destructor - cleanup allocated val
};
//! Scanner Buffer
//
//! This Buffer supports the following cases:
//! -# seekable stream (file)
//! -# whole stream in buffer
//! -# part of stream in buffer
//! -# non seekable stream (network, console)
class Buffer {
private:
unsigned char *buf; //!< input buffer
int bufCapacity; //!< capacity of buf
int bufStart; //!< position of first byte in buffer relative to input stream
int bufLen; //!< length of buffer
int fileLen; //!< length of input stream (may change if the stream is no file)
int bufPos; //!< current position in buffer
FILE* stream; //!< input stream (seekable)
bool isUserStream; //!< was the stream opened by the user?
int ReadNextStreamChunk();
bool CanSeek(); //!< true if stream can be seeked otherwise false
public:
static const int EoF = COCO_WCHAR_MAX + 1;
Buffer(FILE*, bool isUserStream);
Buffer(const unsigned char* buf, int len);
Buffer(const char* buf, int len);
Buffer(Buffer*);
virtual ~Buffer();
virtual void Close();
virtual int Read();
virtual int Peek();
virtual wchar_t* GetString(int beg, int end);
virtual int GetPos();
virtual void SetPos(int value);
};
//! A Scanner buffer that handles UTF-8 characters
class UTF8Buffer : public Buffer {
public:
UTF8Buffer(Buffer* b) : Buffer(b) {}
virtual int Read();
};
//------------------------------------------------------------------------------
// StartStates
//------------------------------------------------------------------------------
//! maps characters to start states of tokens
class StartStates {
private:
class Elem {
public:
int key, val;
Elem *next;
Elem(int key, int val) {
this->key = key;
this->val = val;
next = NULL;
}
};
Elem **tab;
public:
StartStates() {
tab = new Elem*[128];
memset(tab, 0, 128 * sizeof(Elem*));
}
virtual ~StartStates() {
for (int i = 0; i < 128; ++i) {
Elem *e = tab[i];
while (e != NULL) {
Elem *next = e->next;
delete e;
e = next;
}
}
delete [] tab;
}
void set(int key, int val) {
Elem *e = new Elem(key, val);
int k = ((unsigned int) key) % 128;
e->next = tab[k];
tab[k] = e;
}
int state(int key) {
Elem *e = tab[((unsigned int) key) % 128];
while (e != NULL && e->key != key) e = e->next;
return e == NULL ? 0 : e->val;
}
};
//------------------------------------------------------------------------------
// KeywordMap
//------------------------------------------------------------------------------
//! maps strings to integers (identifiers to keyword kinds)
class KeywordMap {
private:
class Elem {
public:
wchar_t *key;
int val;
Elem *next;
Elem(const wchar_t *key, int val) {
this->key = coco_string_create(key);
this->val = val;
next = NULL;
}
virtual ~Elem() {
coco_string_delete(key);
}
};
Elem **tab;
public:
KeywordMap() {
tab = new Elem*[128];
memset(tab, 0, 128 * sizeof(Elem*));
}
virtual ~KeywordMap() {
for (int i = 0; i < 128; ++i) {
Elem *e = tab[i];
while (e != NULL) {
Elem *next = e->next;
delete e;
e = next;
}
}
delete [] tab;
}
void set(const wchar_t *key, int val) {
Elem *e = new Elem(key, val);
int k = coco_string_hash(key) % 128;
e->next = tab[k]; tab[k] = e;
}
int get(const wchar_t *key, int defaultVal) {
Elem *e = tab[coco_string_hash(key) % 128];
while (e != NULL && !coco_string_equal(e->key, key)) e = e->next;
return e == NULL ? defaultVal : e->val;
}
};
//! A Coco/R Scanner
class Scanner {
private:
static const unsigned char EOL = '\n'; // end-of-line character
static const int eofSym = 0; // end-of-file token id
void *firstHeap;
void *heap;
void *heapTop;
void **heapEnd;
int noSym; //!< noSym gets highest number, set in Parser
int maxT;
int charSetSize; //!< unused?
StartStates start;
KeywordMap keywords;
Token *t; //!< current token
wchar_t *tval; //!< text of current token
int tvalLength; //!< length of text of current token
int tlen; //!< length of current token
Token *tokens; //!< list of tokens already peeked (first token is a dummy)
Token *pt; //!< current peek token
int ch; //!< current input character
int pos; //!< byte position of current character
int line; //!< line number of current character
int col; //!< column number of current character
int oldEols; //!< EOLs that appeared in a comment;
void CreateHeapBlock();
Token* CreateToken();
void AppendVal(Token*);
void Init();
void NextCh();
void AddCh();
bool Comment0();
bool Comment1();
Token* NextToken();
public:
//! scanner buffer
Buffer *buffer;
//! Attach scanner to an existing character buffer
Scanner(const unsigned char* buf, int len);
//! Attach scanner to an existing character buffer
Scanner(const char* buf, int len);
//! Open a file for reading and attach scanner
Scanner(const wchar_t* fileName);
//! Using an existing open file handle for the scanner
Scanner(FILE* s);
~Scanner();
Token* Scan();
Token* Peek();
void ResetPeek();
}; // end Scanner
} // namespace
} // namespace
} // namespace
#endif // COCO_calcEntrySCANNER_H__

View File

@ -43,70 +43,86 @@ using namespace Foam;
int main(int argc, char *argv[])
{
argList::noParallel();
argList args(argc, argv);
argList::validArgs.insert("dict .. dictN");
argList args(argc, argv, false, true);
Info<< nl
<< "FOAM_CASE=" << getEnv("FOAM_CASE") << nl
<< "FOAM_CASENAME=" << getEnv("FOAM_CASENAME") << nl
<< endl;
if (args.additionalArgs().empty())
{
dictionary dict1(IFstream("testDict")());
Info<< "dict1: " << dict1 << nl
<< "toc: " << dict1.toc() << nl
<< "keys: " << dict1.keys() << nl
<< "patterns: " << dict1.keys(true) << endl;
{
dictionary dict1(IFstream("testDict")());
Info<< "dict1: " << dict1 << nl
<< "toc: " << dict1.toc() << nl
<< "keys: " << dict1.keys() << nl
<< "patterns: " << dict1.keys(true) << endl;
dictionary dict2(dict1.xfer());
dictionary dict2(dict1.xfer());
Info<< "dict1.toc(): " << dict1.name() << " " << dict1.toc() << nl
<< "dict2.toc(): " << dict2.name() << " " << dict2.toc() << endl;
Info<< "dict1.toc(): " << dict1.name() << " " << dict1.toc() << nl
<< "dict2.toc(): " << dict2.name() << " " << dict2.toc() << endl;
// copy back
dict1 = dict2;
Info<< "dict1.toc(): " << dict1.name() << " " << dict1.toc() << endl;
// copy back
dict1 = dict2;
Info<< "dict1.toc(): " << dict1.name() << " " << dict1.toc() << endl;
dictionary dict3(dict2.subDictPtr("boundaryField"));
dictionary dict4(dict2.subDictPtr("NONEXISTENT"));
dictionary dict3(dict2.subDictPtr("boundaryField"));
dictionary dict4(dict2.subDictPtr("NONEXISTENT"));
Info<< "dictionary construct from pointer" << nl
<< "ok = " << dict3.name() << " " << dict3.toc() << nl
<< "no = " << dict4.name() << " " << dict4.toc() << endl;
Info<< "dictionary construct from pointer" << nl
<< "ok = " << dict3.name() << " " << dict3.toc() << nl
<< "no = " << dict4.name() << " " << dict4.toc() << endl;
}
IOobject::writeDivider(Info);
{
dictionary dict(IFstream("testDictRegex")());
dict.add(keyType("fooba[rz]", true), "anything");
Info<< "dict:" << dict << nl
<< "toc: " << dict.toc() << nl
<< "keys: " << dict.keys() << nl
<< "patterns: " << dict.keys(true) << endl;
Info<< "Pattern find \"abc\" in top directory : "
<< dict.lookup("abc") << endl;
Info<< "Pattern find \"abc\" in sub directory : "
<< dict.subDict("someDict").lookup("abc")
<< endl;
Info<< "Recursive pattern find \"def\" in sub directory : "
<< dict.subDict("someDict").lookup("def", true)
<< endl;
Info<< "Recursive pattern find \"foo\" in sub directory : "
<< dict.subDict("someDict").lookup("foo", true)
<< endl;
Info<< "Recursive pattern find \"fooz\" in sub directory : "
<< dict.subDict("someDict").lookup("fooz", true)
<< endl;
Info<< "Recursive pattern find \"bar\" in sub directory : "
<< dict.subDict("someDict").lookup("bar", true)
<< endl;
Info<< "Recursive pattern find \"xxx\" in sub directory : "
<< dict.subDict("someDict").lookup("xxx", true)
<< endl;
}
}
IOobject::writeDivider(Info);
else
{
dictionary dict(IFstream("testDictRegex")());
dict.add(keyType("fooba[rz]", true), "anything");
IOobject::writeDivider(Info);
forAll(args.additionalArgs(), argI)
{
const string& dictFile = args.additionalArgs()[argI];
IFstream is(dictFile);
Info<< "dict:" << dict << nl
<< "toc: " << dict.toc() << nl
<< "keys: " << dict.keys() << nl
<< "patterns: " << dict.keys(true) << endl;
dictionary dict(is);
Info<< "Pattern find \"abc\" in top directory : "
<< dict.lookup("abc") << endl;
Info<< "Pattern find \"abc\" in sub directory : "
<< dict.subDict("someDict").lookup("abc")
<< endl;
Info<< "Recursive pattern find \"def\" in sub directory : "
<< dict.subDict("someDict").lookup("def", true)
<< endl;
Info<< "Recursive pattern find \"foo\" in sub directory : "
<< dict.subDict("someDict").lookup("foo", true)
<< endl;
Info<< "Recursive pattern find \"fooz\" in sub directory : "
<< dict.subDict("someDict").lookup("fooz", true)
<< endl;
Info<< "Recursive pattern find \"bar\" in sub directory : "
<< dict.subDict("someDict").lookup("bar", true)
<< endl;
Info<< "Recursive pattern find \"xxx\" in sub directory : "
<< dict.subDict("someDict").lookup("xxx", true)
<< endl;
Info<< dict << endl;
}
}
return 0;

View File

@ -0,0 +1,33 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: Any |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object testDictTest;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
x 10 /* what ever */ 20;
y 20;
// z #test{ // this
// 123 - 456
// // comments // are
// /* stripped
// * 10
// * {}
// */
// + 1 /*100 */ 10
// };
p #test{ 1 + 2 + 10 * 15 + $x - $y };
foo 30;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -142,7 +142,6 @@ void rotateFields(const argList& args, const Time& runTime, const tensor& T)
int main(int argc, char *argv[])
{
#include "addRegionOption.H"
argList::addOption
(
"translate",
@ -168,7 +167,11 @@ int main(int argc, char *argv[])
"vector",
"transform in terms of '( yaw pitch roll )' in degrees"
);
argList::addBoolOption("rotateFields");
argList::addBoolOption
(
"rotateFields",
"read and transform vector and tensor fields too"
);
argList::addOption
(
"scale",
@ -177,8 +180,9 @@ int main(int argc, char *argv[])
"uniform [mm] to [m] scaling"
);
#include "setRootCase.H"
#include "createTime.H"
# include "addRegionOption.H"
# include "setRootCase.H"
# include "createTime.H"
word regionName = polyMesh::defaultRegion;
fileName meshDir;

View File

@ -132,7 +132,7 @@ unset MPI_ARCH_PATH
switch ("$WM_MPLIB")
case OPENMPI:
set mpi_version=openmpi-1.3.4
set mpi_version=openmpi-1.4
setenv MPI_HOME $WM_THIRD_PARTY_DIR/$mpi_version
setenv MPI_ARCH_PATH $MPI_HOME/platforms/$WM_OPTIONS

View File

@ -163,7 +163,7 @@ unset MPI_ARCH_PATH
case "$WM_MPLIB" in
OPENMPI)
mpi_version=openmpi-1.3.4
mpi_version=openmpi-1.4
export MPI_HOME=$WM_THIRD_PARTY_DIR/$mpi_version
export MPI_ARCH_PATH=$MPI_HOME/platforms/$WM_OPTIONS

View File

@ -10,7 +10,9 @@ $(bools)/bool/boolIO.C
$(bools)/Switch/Switch.C
$(bools)/Switch/SwitchIO.C
primitives/char/charIO.C
chars = primitives/chars
$(chars)/char/charIO.C
$(chars)/wchar/wcharIO.C
ints = primitives/ints
$(ints)/int/intIO.C

View File

@ -267,8 +267,8 @@ Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
template<unsigned nBits>
void Foam::PackedList<nBits>::operator=(const PackedList<nBits>& lst)
{
setCapacity(lst.size());
StorageList::operator=(lst);
size_ = lst.size();
}
@ -276,6 +276,7 @@ template<unsigned nBits>
void Foam::PackedList<nBits>::operator=(const UList<label>& lst)
{
setCapacity(lst.size());
size_ = lst.size();
forAll(lst, i)
{

View File

@ -25,35 +25,9 @@ License
\*---------------------------------------------------------------------------*/
#include "Istream.H"
#include "bool.H"
#include "token.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Set t to the put back token if there is one and return true,
// otherwise return false
bool Foam::Istream::getBack(token& t)
{
if (bad())
{
FatalIOErrorIn("void Istream::getBack(token&)", *this)
<< "Attempt to get back from bad stream"
<< exit(FatalIOError);
return false;
}
else if (putBack_)
{
t = putBackToken_;
putBack_ = false;
return true;
}
return false;
}
// Keep the put back token
void Foam::Istream::putBack(const token& t)
{
if (bad())
@ -76,6 +50,40 @@ void Foam::Istream::putBack(const token& t)
}
bool Foam::Istream::getBack(token& t)
{
if (bad())
{
FatalIOErrorIn("void Istream::getBack(token&)", *this)
<< "Attempt to get back from bad stream"
<< exit(FatalIOError);
}
else if (putBack_)
{
t = putBackToken_;
putBack_ = false;
return true;
}
return false;
}
bool Foam::Istream::peekBack(token& t)
{
if (putBack_)
{
t = putBackToken_;
}
else
{
t = token::undefinedToken;
}
return putBack_;
}
// Functions for reading object delimiters ( ... )
Foam::Istream& Foam::Istream::readBegin(const char* funcName)

View File

@ -62,7 +62,7 @@ class Istream
{
// Private data
//- Has a token been put back on the stream
//- Has a token been put back on the stream?
bool putBack_;
//- The last token put back on the stream
@ -97,12 +97,19 @@ public:
// Read functions
//- Put back token
// Only a single put back is permitted
void putBack(const token&);
//- Get the put back token
//- Get the put back token if there is one and return true.
// Return false if no put back token is available.
bool getBack(token&);
//- Return next token from stream
//- Peek at the put back token without removing it.
// Returns false if no put back token is available and set the
// token to undefined.
bool peekBack(token&);
//- Return next token from stream
virtual Istream& read(token&) = 0;
//- Read a character

View File

@ -79,7 +79,7 @@ Foam::Istream& Foam::ITstream::read(token& t)
{
FatalIOErrorIn
(
"ITstream::read(token& t)",
"ITstream::read(token&)",
*this
) << "attempt to read beyond EOF"
<< exit(FatalIOError);
@ -91,17 +91,16 @@ Foam::Istream& Foam::ITstream::read(token& t)
setEof();
}
t = token::undefinedToken;
if (size())
{
token::undefinedToken.lineNumber()
= operator[](size() - 1).lineNumber();
t.lineNumber() = tokenList::last().lineNumber();
}
else
{
token::undefinedToken.lineNumber() = lineNumber();
t.lineNumber() = lineNumber();
}
t = token::undefinedToken;
}
return *this;
@ -110,7 +109,7 @@ Foam::Istream& Foam::ITstream::read(token& t)
Foam::Istream& Foam::ITstream::read(char&)
{
notImplemented("Istream& ITstream::read(char& c)");
notImplemented("Istream& ITstream::read(char&)");
return *this;
}
@ -157,14 +156,13 @@ Foam::Istream& Foam::ITstream::read(char*, std::streamsize)
}
// Rewind the token stream so that it may be read again
Foam::Istream& Foam::ITstream::rewind()
{
tokenIndex_ = 0;
if (size())
{
lineNumber_ = operator[](0).lineNumber();
lineNumber_ = tokenList::first().lineNumber();
}
setGood();

View File

@ -70,7 +70,26 @@ public:
ITstream
(
const string& name,
const tokenList& tokens,
const UList<token>& tokens,
streamFormat format=ASCII,
versionNumber version=currentVersion
)
:
Istream(format, version),
tokenList(tokens),
name_(name),
tokenIndex_(0)
{
setOpened();
setGood();
}
//- Construct from components, transferring the tokens
ITstream
(
const string& name,
const Xfer< List<token> >& tokens,
streamFormat format=ASCII,
versionNumber version=currentVersion
)
@ -98,8 +117,7 @@ public:
}
// Destructor
//- Destructor
virtual ~ITstream()
{}

View File

@ -92,7 +92,7 @@ public:
const dictionary& dict
);
//- Construct as copy for the given parentDict
//- Construct as copy for the given parent dictionary
dictionaryEntry
(
const dictionary& parentDict,

View File

@ -79,7 +79,7 @@ void Foam::dictionaryEntry::write(Ostream& os) const
}
// * * * * * * * * * * * * * Ostream operator * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Ostream operator * * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const dictionaryEntry& de)
{

View File

@ -26,33 +26,92 @@ License
#include "primitiveEntry.H"
#include "dictionary.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::primitiveEntry::append(const UList<token>& varTokens)
{
forAll(varTokens, i)
{
newElmt(tokenIndex()++) = varTokens[i];
}
}
bool Foam::primitiveEntry::expandVariable
(
const word& w,
const dictionary& dict
)
{
word varName = w(1, w.size()-1);
// lookup the variable name in the given dictionary....
// Note: allow wildcards to match? For now disabled since following
// would expand internalField to wildcard match and not expected
// internalField:
// internalField XXX;
// boundaryField { ".*" {YYY;} movingWall {value $internalField;}
const entry* ePtr = dict.lookupEntryPtr(varName, true, false);
// ...if defined append its tokens into this
if (ePtr)
{
append(ePtr->stream());
}
else
{
// not in the dictionary - try an environment variable
string envStr = getEnv(varName);
if (envStr.empty())
{
return false;
}
append(tokenList(IStringStream('(' + envStr + ')')()));
}
return true;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::primitiveEntry::primitiveEntry(const keyType& key, const ITstream& tokens)
Foam::primitiveEntry::primitiveEntry(const keyType& key, const ITstream& is)
:
entry(key),
ITstream(tokens)
ITstream(is)
{
name() += "::" + keyword();
}
Foam::primitiveEntry::primitiveEntry(const keyType& keyword, const token& t)
Foam::primitiveEntry::primitiveEntry(const keyType& key, const token& t)
:
entry(keyword),
ITstream(keyword, tokenList(1, t))
entry(key),
ITstream(key, tokenList(1, t))
{}
Foam::primitiveEntry::primitiveEntry
(
const keyType& keyword,
const tokenList& tokens
const keyType& key,
const UList<token>& tokens
)
:
entry(keyword),
ITstream(keyword, tokens)
entry(key),
ITstream(key, tokens)
{}
Foam::primitiveEntry::primitiveEntry
(
const keyType& key,
const Xfer< List<token> >& tokens
)
:
entry(key),
ITstream(key, tokens)
{}
@ -60,34 +119,39 @@ Foam::primitiveEntry::primitiveEntry
Foam::label Foam::primitiveEntry::startLineNumber() const
{
if (size())
const tokenList& tokens = *this;
if (tokens.empty())
{
return operator[](0).lineNumber();
return -1;
}
else
{
return -1;
return tokens.first().lineNumber();
}
}
Foam::label Foam::primitiveEntry::endLineNumber() const
{
if (size())
const tokenList& tokens = *this;
if (tokens.empty())
{
return operator[](size()-1).lineNumber();
return -1;
}
else
{
return -1;
return tokens.last().lineNumber();
}
}
Foam::ITstream& Foam::primitiveEntry::stream() const
{
ITstream& dataStream = const_cast<primitiveEntry&>(*this);
dataStream.rewind();
return dataStream;
ITstream& is = const_cast<primitiveEntry&>(*this);
is.rewind();
return is;
}
@ -113,43 +177,4 @@ Foam::dictionary& Foam::primitiveEntry::dict()
}
void Foam::primitiveEntry::insert
(
const tokenList& varTokens,
const label posI
)
{
tokenList& tokens = *this;
if (varTokens.empty())
{
label end = tokens.size() - 1;
for (label j=posI; j<end; j++)
{
tokens[j] = tokens[j+1];
}
tokens.setSize(tokens.size() - 1);
}
else if (varTokens.size() > 1)
{
tokens.setSize(tokens.size() + varTokens.size() - 1);
label end = tokens.size() - 1;
label offset = varTokens.size() - 1;
for (label j=end; j>posI; j--)
{
tokens[j] = tokens[j-offset];
}
}
forAll(varTokens, j)
{
tokens[posI + j] = varTokens[j];
}
}
// ************************************************************************* //

View File

@ -68,6 +68,9 @@ class primitiveEntry
{
// Private member functions
//- Append the given tokens starting at the current tokenIndex
void append(const UList<token>&);
//- Append the given token to this entry
void append
(
@ -76,9 +79,6 @@ class primitiveEntry
Istream&
);
//- Append the given tokens starting at the current tokenIndex
void append(const tokenList&);
//- Expand the given variable (keyword starts with $)
bool expandVariable(const word&, const dictionary&);
@ -93,9 +93,6 @@ class primitiveEntry
//- Read the complete entry from the given stream
void readEntry(const dictionary&, Istream&);
//- Insert the given tokens at token posI
void insert(const tokenList&, const label posI);
public:
@ -110,11 +107,14 @@ public:
//- Construct from keyword and a ITstream
primitiveEntry(const keyType&, const ITstream&);
//- Construct from keyword and a token
//- Construct from keyword and a single token
primitiveEntry(const keyType&, const token&);
//- Construct from keyword and a tokenList
primitiveEntry(const keyType&, const tokenList&);
//- Construct from keyword and a list of tokens
primitiveEntry(const keyType&, const UList<token>&);
//- Construct from keyword and by transferring a list of tokens
primitiveEntry(const keyType&, const Xfer< List<token> >&);
//- Construct from keyword and a T
template<class T>
@ -166,7 +166,7 @@ public:
//- Read tokens from the given stream
bool read(const dictionary&, Istream&);
// Write
//- Write
void write(Ostream&) const;
//- Return info proxy.

View File

@ -28,10 +28,9 @@ Description
\*---------------------------------------------------------------------------*/
#include "primitiveEntry.H"
#include "OSspecific.H"
#include "functionEntry.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::primitiveEntry::append
(
@ -63,55 +62,6 @@ void Foam::primitiveEntry::append
}
void Foam::primitiveEntry::append(const tokenList& varTokens)
{
forAll(varTokens, i)
{
newElmt(tokenIndex()++) = varTokens[i];
}
}
bool Foam::primitiveEntry::expandVariable
(
const word& w,
const dictionary& dict
)
{
word varName = w(1, w.size()-1);
// lookup the variable name in the given dictionary....
// Note: allow wildcards to match? For now disabled since following
// would expand internalField to wildcard match and not expected
// internalField:
// internalField XXX;
// boundaryField { ".*" {YYY;} movingWall {value $internalField;}
const entry* ePtr = dict.lookupEntryPtr(varName, true, false);
// ...if defined insert its tokens into this
if (ePtr != NULL)
{
append(ePtr->stream());
return true;
}
else
{
// if not in the dictionary see if it is an environment
// variable
string enVarString = getEnv(varName);
if (enVarString.size())
{
append(tokenList(IStringStream('(' + enVarString + ')')()));
return true;
}
return false;
}
}
bool Foam::primitiveEntry::expandFunction
(
const word& keyword,
@ -221,6 +171,8 @@ void Foam::primitiveEntry::readEntry(const dictionary& dict, Istream& is)
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::primitiveEntry::primitiveEntry
(
const keyType& key,

View File

@ -30,13 +30,13 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class T>
Foam::primitiveEntry::primitiveEntry(const keyType& keyword, const T& t)
Foam::primitiveEntry::primitiveEntry(const keyType& key, const T& t)
:
entry(keyword),
ITstream(keyword, tokenList(10))
entry(key),
ITstream(key, tokenList(10))
{
OStringStream os;
os << t << token::END_STATEMENT;
os << t << token::END_STATEMENT;
readEntry(dictionary::null, IStringStream(os.str())());
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2008-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -57,7 +57,9 @@ class StaticAssertionFailed<true>
template<unsigned Test>
class StaticAssertionTest {};
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -62,7 +62,7 @@ Ostream& operator<<(Ostream&, const error&);
/*---------------------------------------------------------------------------*\
Class error Declaration
Class error Declaration
\*---------------------------------------------------------------------------*/
class error
@ -92,10 +92,10 @@ public:
error(const string& title);
//- Construct from dictionary
error(const dictionary& errDict);
error(const dictionary&);
//- Construct as copy
error(const error& err);
error(const error&);
// Destructor
@ -132,8 +132,8 @@ public:
throwExceptions_ = false;
}
//- Convert to Ostream
// Prints basic message and then returns Ostream for further info.
//- Convert to OSstream
// Prints basic message and returns OSstream for further info.
OSstream& operator()
(
const char* functionName,
@ -141,6 +141,8 @@ public:
const int sourceFileLineNumber = 0
);
//- Convert to OSstream
// Prints basic message and returns OSstream for further info.
OSstream& operator()
(
const string& functionName,
@ -148,11 +150,11 @@ public:
const int sourceFileLineNumber = 0
);
//- Convert to Ostream
// Prints basic message and then returns Ostream for further info.
//- Convert to OSstream
// Prints basic message and returns OSstream for further info.
operator OSstream&();
//- Explicitly convert to Ostream for << operations
//- Explicitly convert to OSstream for << operations
OSstream& operator()()
{
return operator OSstream&();
@ -163,14 +165,14 @@ public:
//- Helper function to print a stack
static void printStack(Ostream& os);
static void printStack(Ostream&);
//- Exit : can be called for any error to exit program. Prints stack
// before exiting.
//- Exit : can be called for any error to exit program.
// Prints stack before exiting.
void exit(const int errNo = 1);
//- Abort : used to stop code for fatal errors. Prints stack before
// exiting.
//- Abort : used to stop code for fatal errors.
// Prints stack before exiting.
void abort();
@ -181,9 +183,7 @@ public:
// Forward declaration of friend functions and operators
class IOerror;
Ostream& operator<<(Ostream&, const IOerror&);
@ -211,7 +211,7 @@ public:
IOerror(const string& title);
//- Construct from dictionary
IOerror(const dictionary& errDict);
IOerror(const dictionary&);
// Destructor
@ -236,8 +236,8 @@ public:
return ioEndLineNumber_;
}
//- Convert to Ostream
// Prints basic message and then returns Ostream for further info.
//- Convert to OSstream
// Prints basic message and returns OSstream for further info.
OSstream& operator()
(
const char* functionName,
@ -248,8 +248,8 @@ public:
const label ioEndLineNumber = -1
);
//- Convert to Ostream
// Prints basic message and then returns Ostream for further info.
//- Convert to OSstream
// Prints basic message and returns OSstream for further info.
OSstream& operator()
(
const char* functionName,
@ -258,8 +258,8 @@ public:
const IOstream&
);
//- Convert to Ostream
// Prints basic message and then returns Ostream for further info.
//- Convert to OSstream
// Prints basic message and returns OSstream for further info.
OSstream& operator()
(
const char* functionName,
@ -288,24 +288,47 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Global error declarations: defined in error.C
extern error FatalError;
extern error FatalError;
extern IOerror FatalIOError;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Convienient macros to add the file name and line number to the function name
#define FatalErrorIn(fn) FatalError(fn, __FILE__, __LINE__)
#define FatalIOErrorIn(fn, ios) FatalIOError(fn, __FILE__, __LINE__, ios)
// Call for functions which are not currently implemented.
// The functionName is printed and then abort is called.
#define notImplemented(fn) \
FatalErrorIn(fn) << "Not implemented" << Foam::abort(FatalError);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Convenience macros to add the file name and line number to the function name
/**
* @def FatalErrorIn(functionName)
* Report an error message using Foam::FatalError for functionName in
* file __FILE__ at line __LINE__
*/
#define FatalErrorIn(fn) \
::Foam::FatalError((fn), __FILE__, __LINE__)
/**
* @def FatalIOErrorIn(functionName, ios)
* Report an error message using Foam::FatalIOError for functionName in
* file __FILE__ at line __LINE__
* for a particular IOstream
*/
#define FatalIOErrorIn(fn, ios) \
::Foam::FatalIOError((fn), __FILE__, __LINE__, (ios))
/**
* @def notImplemented(functionName)
* Issue a FatalErrorIn for the functionName.
* This is used for functions that are not currently implemented.
* The functionName is printed and then abort is called.
*
* @note
* This macro can be particularly useful when methods must be defined to
* complete the interface of a derived class even if they should never be
* called for this derived class.
*/
#define notImplemented(fn) \
FatalErrorIn(fn) << "Not implemented" << ::Foam::abort(FatalError);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "errorManip.H"

View File

@ -49,7 +49,6 @@ namespace Foam
{
// Forward declaration of friend functions and operators
template<class Err> class errorManip;
template<class Err> Ostream& operator<<(Ostream&, errorManip<Err>);
@ -59,7 +58,7 @@ Ostream& operator<<(Ostream&, errorManipArg<Err, T>);
/*---------------------------------------------------------------------------*\
Class errorManip Declaration
Class errorManip Declaration
\*---------------------------------------------------------------------------*/
template<class Err>
@ -89,7 +88,7 @@ inline Ostream& operator<<(Ostream& os, errorManip<Err> m)
/*---------------------------------------------------------------------------*\
Class errorManipArg Declaration
Class errorManipArg Declaration
\*---------------------------------------------------------------------------*/
//- errorManipArg
@ -123,23 +122,29 @@ inline Ostream& operator<<(Ostream& os, errorManipArg<Err, T> m)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
inline errorManipArg<error, int> exit(error& err, const int errNo = 1)
inline errorManipArg<error, int>
exit(error& err, const int errNo = 1)
{
return errorManipArg<error, int>(&error::exit, err, errNo);
}
inline errorManip<error> abort(error& err)
inline errorManip<error>
abort(error& err)
{
return errorManip<error>(&error::abort, err);
}
inline errorManipArg<IOerror, int> exit(IOerror& err, const int errNo = 1)
inline errorManipArg<IOerror, int>
exit(IOerror& err, const int errNo = 1)
{
return errorManipArg<IOerror, int>(&IOerror::exit, err, errNo);
}
inline errorManip<IOerror> abort(IOerror& err)
inline errorManip<IOerror>
abort(IOerror& err)
{
return errorManip<IOerror>(&IOerror::abort, err);
}

View File

@ -36,7 +36,8 @@ Description
Usage
@code
messageStream << "message1" << "message2" << FoamDataType << endl;
messageStream
<< "message1" << "message2" << FoamDataType << endl;
@endcode
SourceFiles
@ -55,6 +56,7 @@ SourceFiles
namespace Foam
{
// Forward declaration of classes
class IOstream;
class Ostream;
class OSstream;
@ -103,13 +105,13 @@ public:
messageStream
(
const string& title,
errorSeverity sev,
errorSeverity,
const int maxErrors = 0
);
//- Construct from dictionary
messageStream(const dictionary& dict);
messageStream(const dictionary&);
// Member functions
@ -133,8 +135,8 @@ public:
return maxErrors_;
}
//- Convert to Ostream
// Prints basic message and then returns Ostream for further info.
//- Convert to OSstream
// Prints basic message and returns OSstream for further info.
OSstream& operator()
(
const char* functionName,
@ -142,6 +144,8 @@ public:
const int sourceFileLineNumber = 0
);
//- Convert to OSstream
// Prints basic message and returns OSstream for further info.
OSstream& operator()
(
const string& functionName,
@ -149,8 +153,8 @@ public:
const int sourceFileLineNumber = 0
);
//- Convert to Ostream
// Prints basic message and then returns Ostream for further info.
//- Convert to OSstream
// Prints basic message and returns OSstream for further info.
OSstream& operator()
(
const char* functionName,
@ -161,8 +165,8 @@ public:
const label ioEndLineNumber = -1
);
//- Convert to Ostream
// Prints basic message and then returns Ostream for further info.
//- Convert to OSstream
// Prints basic message and returns OSstream for further info.
OSstream& operator()
(
const char* functionName,
@ -171,8 +175,8 @@ public:
const IOstream&
);
//- Convert to Ostream
// Prints basic message and then returns Ostream for further info.
//- Convert to OSstream
// Prints basic message and returns OSstream for further info.
OSstream& operator()
(
const char* functionName,
@ -181,10 +185,10 @@ public:
const dictionary&
);
//- Convert to Ostream for << operations
//- Convert to OSstream for << operations
operator OSstream&();
//- Explicitly convert to Ostream for << operations
//- Explicitly convert to OSstream for << operations
OSstream& operator()()
{
return operator OSstream&();
@ -199,18 +203,6 @@ extern messageStream SeriousError;
extern messageStream Warning;
extern messageStream Info;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Convienient macros to add the file name and line number to the function name
#define SeriousErrorIn(fn) SeriousError(fn, __FILE__, __LINE__)
#define SeriousIOErrorIn(fn, ios) SeriousError(fn, __FILE__, __LINE__, ios)
#define WarningIn(fn) Warning(fn, __FILE__, __LINE__)
#define IOWarningIn(fn, ios) Warning(fn, __FILE__, __LINE__, ios)
#define InfoIn(fn) Info(fn, __FILE__, __LINE__)
#define IOInfoIn(fn, ios) Info(fn, __FILE__, __LINE__, ios)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
@ -219,6 +211,60 @@ extern messageStream Info;
#include "OSstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Convenience macros to add the file name and line number to the function name
/**
* @def SeriousErrorIn(functionName)
* Report an error message using Foam::SeriousError for functionName in
* file __FILE__ at line __LINE__
*/
#define SeriousErrorIn(fn) \
::Foam::SeriousError((fn), __FILE__, __LINE__)
/**
* @def SeriousIOErrorIn(functionName, ios)
* Report an IO error message using Foam::SeriousError for functionName in
* file __FILE__ at line __LINE__
* for a particular IOstream
*/
#define SeriousIOErrorIn(fn, ios) \
::Foam::SeriousError((fn), __FILE__, __LINE__, ios)
/**
* @def WarningIn(functionName)
* Report a warning using Foam::Warning for functionName in
* file __FILE__ at line __LINE__
*/
#define WarningIn(fn) \
::Foam::Warning((fn), __FILE__, __LINE__)
/**
* @def IOWarningIn(functionName, ios)
* Report an IO warning using Foam::Warning for functionName in
* file __FILE__ at line __LINE__
* for a particular IOstream
*/
#define IOWarningIn(fn, ios) \
::Foam::Warning((fn), __FILE__, __LINE__, (ios))
/**
* @def InfoIn(functionName)
* Report a information message using Foam::Info for functionName in
* file __FILE__ at line __LINE__
*/
#define InfoIn(fn) \
::Foam::Info((fn), __FILE__, __LINE__)
/**
* @def IOInfoIn(functionName, ios)
* Report an IO information message using Foam::Info for functionName in
* file __FILE__ at line __LINE__
* for a particular IOstream
*/
#define IOInfoIn(fn, ios) \
::Foam::Info((fn), __FILE__, __LINE__, (ios))
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif

View File

@ -60,7 +60,7 @@ word name(const Scalar val)
Scalar readScalar(Istream& is)
{
Scalar rs;
is >> rs;
is >> rs;
return rs;
}

View File

@ -50,9 +50,9 @@ public:
enum
{
dim = 3, // Dimensionality of space
rank = 0, // Rank of Scalar is 0
nComponents = 1 // Number of components in Scalar is 1
dim = 3, //!< Dimensionality of space
rank = 0, //!< Rank of Scalar is 0
nComponents = 1 //!< Number of components in Scalar is 1
};
// Static data members
@ -72,6 +72,7 @@ public:
// Member Functions
//- Conversion to a Scalar
operator Scalar() const
{
return p_;

View File

@ -86,8 +86,8 @@ public:
enum
{
dim = 3, // Dimensionality of space
nComponents = nCmpt // Number of components in this vector space
dim = 3, //!< Dimensionality of space
nComponents = nCmpt //!< Number of components in this vector space
};

View File

@ -76,9 +76,9 @@ public:
enum
{
dim = 3, // Dimensionality of space
rank = 0, // Rank of bool is 0
nComponents = 1 // Number of components in bool is 1
dim = 3, //!< Dimensionality of space
rank = 0, //!< Rank of bool is 0
nComponents = 1 //!< Number of components in bool is 1
};
// Static data members
@ -95,6 +95,7 @@ public:
// Member Functions
//- Conversion to a bool
operator bool() const
{
return p_;

View File

@ -0,0 +1,66 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Primitive
wchar_t
Description
A wide-character and a pointer to a wide-character string.
SourceFiles
wcharIO.C
\*---------------------------------------------------------------------------*/
#ifndef wchar_H
#define wchar_H
#include <cwchar>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class Istream;
class Ostream;
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
//- Output via a normal char
Ostream& operator<<(Ostream&, const wchar_t);
//- Output string via normal char
Ostream& operator<<(Ostream&, const wchar_t*);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,62 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
Reads a char from an input stream, for a given version
number and File format. If an ascii File is being read, then the line
numbers are counted and an erroneous read is reported.
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "wchar.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const wchar_t wc)
{
os.write(char(wc));
os.check("Ostream& operator<<(Ostream&, const wchar_t)");
return os;
}
Foam::Ostream& Foam::operator<<(Ostream& os, const wchar_t* ws)
{
if (ws)
{
for (const wchar_t* p = ws; *p; ++p)
{
os.write(char(*p));
}
}
os.check("Ostream& operator<<(Ostream&, const wchar_t*)");
return os;
}
// ************************************************************************* //

View File

@ -148,9 +148,9 @@ public:
enum
{
dim = 3, // Dimensionality of space
rank = 0, // Rank of label is 0
nComponents = 1 // Number of components in label is 1
dim = 3, //!< Dimensionality of space
rank = 0, //!< Rank of label is 0
nComponents = 1 //!< Number of components in label is 1
};
// Static data members
@ -169,6 +169,7 @@ public:
// Member Functions
//- Conversion to a label
operator label() const
{
return p_;

View File

@ -132,9 +132,9 @@ public:
enum
{
dim = 3, // Dimensionality of space
rank = 0, // Rank of uLabel is 0
nComponents = 1 // Number of components in uLabel is 1
dim = 3, //!< Dimensionality of space
rank = 0, //!< Rank of uLabel is 0
nComponents = 1 //!< Number of components in uLabel is 1
};
// Static data members
@ -154,6 +154,7 @@ public:
// Member Functions
//- Conversion to a uLabel
operator uLabel() const
{
return p_;