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

This commit is contained in:
andy
2009-12-22 10:35:22 +00:00
22 changed files with 693 additions and 555 deletions

View File

@ -0,0 +1,15 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
# this will have to do until we have a makefile rule
if type Coco > /dev/null 2>&1
then
Coco \
-frames $WM_THIRD_PARTY_DIR/coco-r \
calcEntry/calcEntry.atg
else
echo "Coco not installed"
fi
wmake

View File

@ -1,11 +0,0 @@
#/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

@ -26,8 +26,6 @@ License
#include "calcEntry.H" #include "calcEntry.H"
#include "dictionary.H" #include "dictionary.H"
#include "IStringStream.H"
#include "OStringStream.H"
#include "addToMemberFunctionSelectionTable.H" #include "addToMemberFunctionSelectionTable.H"
#include "ISstream.H" #include "ISstream.H"
@ -60,121 +58,33 @@ bool Foam::functionEntries::calcEntry::execute
( (
const dictionary& parentDict, const dictionary& parentDict,
primitiveEntry& entry, primitiveEntry& entry,
Istream& istr Istream& is
) )
{ {
static const int maxLen = 1024; std::istream& iss = dynamicCast<ISstream>(is).stdStream();
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 // define parser error handler
CocoParserErrors<calcEntryInternal::Errors> CocoParserErrors<calcEntryInternal::Errors>
myErrorHandler("calcEntry::Parser--"); myErrorHandler("calcEntryInternal::Parser");
calcEntryInternal::Scanner scanner(buf, nChar); calcEntryInternal::Scanner scanner(iss);
calcEntryInternal::Parser parser(&scanner, &myErrorHandler); calcEntryInternal::Parser parser(&scanner, &myErrorHandler);
// Attach dictionary context // Attach dictionary context
parser.dict(parentDict); parser.dict(parentDict);
// Attach scalar functions
// parser.functions(parentDict);
parser.Parse(); parser.Parse();
// Info<<"got: " << parser.Result() << endl; // make a small input list to contain the answer
tokenList tokens(2); tokenList tokens(2);
tokens[0] = parser.Result(); tokens[0] = parser.Result();
tokens[1] = token::END_STATEMENT; tokens[1] = token::END_STATEMENT;
// Info<<"tokens[0] = " << tokens[0].info() <<nl; entry.read(parentDict, ITstream("ParserResult", tokens)());
// 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; return true;
} }

View File

@ -2,9 +2,7 @@
compile with: compile with:
Coco \ Coco \
-frames $WM_THIRD_PARTY_DIR/coco-r \ -frames $WM_THIRD_PARTY_DIR/coco-r \
-prefix calcEntry \ calcEntry.atg
-namespace Foam::functionEntries::calcEntryInternal \
SimpleCalc.atg
-------------------------------------------------------------------------*/ -------------------------------------------------------------------------*/
#include "dictionary.H" #include "dictionary.H"
@ -13,7 +11,11 @@
#include "wchar.H" #include "wchar.H"
COMPILER SimpleCalc COMPILER calcEntry
$prefix=calcEntry
$namespace=Foam::functionEntries::calcEntryInternal
$eof=true // grammar handles eof itself
// Simple four function calculator for OpenFOAM dictionaries // Simple four function calculator for OpenFOAM dictionaries
//! with debug //! with debug
@ -22,9 +24,13 @@ COMPILER SimpleCalc
//! The parent dictionary //! The parent dictionary
mutable dictionary* dict_; mutable dictionary* dict_;
//! Track that parent dictionary was set
bool hasDict_;
//! The calculation result //! The calculation result
scalar val; scalar val;
//! token -> scalar //! token -> scalar
scalar getScalar() const scalar getScalar() const
{ {
@ -40,11 +46,11 @@ COMPILER SimpleCalc
return s; return s;
} }
//! attach a dictionary //! attach a dictionary
void dict(const dictionary& dict) const void dict(const dictionary& dict)
{ {
dict_ = const_cast<dictionary*>(&dict); dict_ = const_cast<dictionary*>(&dict);
hasDict_ = true;
} }
@ -53,11 +59,11 @@ COMPILER SimpleCalc
{ {
scalar dictValue = 0; scalar dictValue = 0;
if (!dict_) if (!hasDict_)
{ {
FatalErrorIn FatalErrorIn
( (
"SimpleCalc::getDictEntry() const" "calcEntry::getDictEntry() const"
) << "No dictionary attached!" ) << "No dictionary attached!"
<< exit(FatalError); << exit(FatalError);
@ -81,13 +87,22 @@ COMPILER SimpleCalc
entry* entryPtr = dict_->lookupEntryPtr(keyword, true, false); entry* entryPtr = dict_->lookupEntryPtr(keyword, true, false);
if (entryPtr && !entryPtr->isDict()) if (entryPtr && !entryPtr->isDict())
{ {
if (entryPtr->stream().size() != 1)
{
FatalErrorIn
(
"calcEntry::getDictEntry() const"
) << "keyword " << keyword << " has "
<< entryPtr->stream().size() << " values in dictionary "
<< exit(FatalError);
}
entryPtr->stream() >> dictValue; entryPtr->stream() >> dictValue;
} }
else else
{ {
FatalErrorIn FatalErrorIn
( (
"SimpleCalc::getDictEntry() const" "calcEntry::getDictEntry() const"
) << "keyword " << keyword << " is undefined in dictionary " ) << "keyword " << keyword << " is undefined in dictionary "
<< exit(FatalError); << exit(FatalError);
} }
@ -102,7 +117,7 @@ COMPILER SimpleCalc
} }
// * * * * * * * * * * * * * * * CHARACTERS * * * * * * * * * * * * * * * * // /*---------------------------------------------------------------------------*/
CHARACTERS CHARACTERS
letter = 'A'..'Z' + 'a'..'z'. letter = 'A'..'Z' + 'a'..'z'.
@ -145,38 +160,49 @@ number =
COMMENTS FROM "/*" TO "*/" NESTED COMMENTS FROM "/*" TO "*/" NESTED
COMMENTS FROM "//" TO lf COMMENTS FROM "//" TO lf
// ignore unprintables IGNORE cr + lf + tab
IGNORE ANY - printable
// * * * * * * * * * * * * * * * PRODUCTIONS * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * PRODUCTIONS * * * * * * * * * * * * * * * //
PRODUCTIONS PRODUCTIONS
SimpleCalc (. val = 0; calcEntry (. val = 0;
if (debug){Info<<"start val"<< nl;} if (debug){Info<<"start val pos:"<< t->pos << nl;}
.) .)
= =
( '{' Expr<val> '}' | Expr<val> ) '{' Expr<val> '}' (.
EOF if (debug){
Info<<"end {} at pos:"<< t->pos
<<" val:"<< t->val
<<" len:"<< coco_string_length(t->val)
<<" la pos:"<< la->pos << nl;
}
// reposition to immediately after the closing '}'
scanner->buffer->SetPos
(
t->pos + coco_string_length(t->val)
);
.)
| ( Expr<val> EOF )
. .
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
Expr<scalar& val> (. scalar val2 = 0; Expr<scalar& val> (. scalar val2 = 0;
if (debug) {Info<<"Expr:"<< val<< nl;} if (debug) {Info<<"Expr:"<< val<< " pos:"<< t->pos << nl;}
.) .)
= =
Term<val> Term<val>
{ {
"+" Term<val2> (. if (debug) {Info<<"+Term:"<<val2 <<nl;} "+" Term<val2> (. if (debug) {Info<<"+Term:"<<val2 << " pos:"<< t->pos << nl;}
val += val2; val += val2;
if (debug) {Info<<"="<< val << nl;} if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
.) .)
| "-" Term<val2> (. if (debug) {Info<<"-Term:"<<val2 <<nl;} | "-" Term<val2> (. if (debug) {Info<<"-Term:"<<val2<< " pos:"<< t->pos << nl;}
val -= val2; val -= val2;
if (debug) {Info<<"="<< val << nl;} if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
.) .)
} }
. .
@ -185,18 +211,18 @@ Expr<scalar& val> (. scalar val2 = 0;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
Term<scalar& val> (. scalar val2 = 0; Term<scalar& val> (. scalar val2 = 0;
if (debug) {Info<<"Term:"<< val<< nl;} if (debug) {Info<<"Term:"<< val<< " pos:"<< t->pos << nl;}
.) .)
= =
Factor<val> Factor<val>
{ {
"*" Factor<val2> (. if (debug) {Info<<"*Factor:"<<val2 << nl;} "*" Factor<val2> (. if (debug) {Info<<"*Factor:"<<val2<< " pos:"<< t->pos << nl;}
val *= val2; val *= val2;
if (debug) {Info<<"="<< val << nl; } if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
.) .)
| "/" Factor<val2> (. if (debug) {Info<<"/Factor:"<<val2 << nl;} | "/" Factor<val2> (. if (debug) {Info<<"/Factor:"<<val2<< " pos:"<< t->pos << nl;}
val /= val2; val /= val2;
if (debug) {Info<<"="<< val << nl; } if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
.) .)
} }
. .
@ -206,20 +232,21 @@ Term<scalar& val> (. scalar val2 = 0;
Factor<scalar& val> Factor<scalar& val>
= =
variable (. val = getDictLookup(); variable (. val = getDictLookup();
if (debug) {Info<<"lookup:"<<val<<nl;} if (debug) {Info<<"lookup:"<<val<< " pos:"<< t->pos << nl;}
.) .)
| number (. val = getScalar(); | number (. val = getScalar();
if (debug) {Info<<"got num:"<<val<<nl;} if (debug) {Info<<"got num:"<<val<< " pos:"<< t->pos << nl;}
.) .)
| '-' '(' Expr<val> ')' (. val = -val; | '-' '(' Expr<val> ')' (. val = -val;
if (debug) {Info<<"inv:"<<val<<nl;} if (debug) {Info<<"inv:"<<val<< " pos:"<< t->pos << nl;}
.)
| '(' Expr<val> ')' (. if (debug){Info<<"got Expr:"<<val<< " pos:"<< t->pos << nl;}
.) .)
| '(' Expr<val> ')' (. if (debug){Info<<"got Expr:"<<val<<nl;} .)
. .
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
END SimpleCalc. END calcEntry.
// ************************************************************************* // // ************************************************************************* //

View File

@ -90,39 +90,51 @@ bool Parser::WeakSeparator(int n, int syFol, int repFol) {
} }
void Parser::SimpleCalc() { void Parser::calcEntry() {
val = 0; val = 0;
if (debug){Info<<"start val"<< nl;} if (debug){Info<<"start val pos:"<< t->pos << nl;}
if (la->kind == 5) { if (la->kind == 5) {
Get(); Get();
Expr(val); Expr(val);
Expect(6); Expect(6);
if (debug){
Info<<"end {} at pos:"<< t->pos
<<" val:"<< t->val
<<" len:"<< coco_string_length(t->val)
<<" la pos:"<< la->pos << nl;
}
// reposition to immediately after the closing '}'
scanner->buffer->SetPos
(
t->pos + coco_string_length(t->val)
);
} else if (StartOf(1)) { } else if (StartOf(1)) {
Expr(val); Expr(val);
Expect(0);
} else SynErr(14); } else SynErr(14);
Expect(0);
} }
void Parser::Expr(scalar& val) { void Parser::Expr(scalar& val) {
scalar val2 = 0; scalar val2 = 0;
if (debug) {Info<<"Expr:"<< val<< nl;} if (debug) {Info<<"Expr:"<< val<< " pos:"<< t->pos << nl;}
Term(val); Term(val);
while (la->kind == 7 || la->kind == 8) { while (la->kind == 7 || la->kind == 8) {
if (la->kind == 7) { if (la->kind == 7) {
Get(); Get();
Term(val2); Term(val2);
if (debug) {Info<<"+Term:"<<val2 <<nl;} if (debug) {Info<<"+Term:"<<val2 << " pos:"<< t->pos << nl;}
val += val2; val += val2;
if (debug) {Info<<"="<< val << nl;} if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
} else { } else {
Get(); Get();
Term(val2); Term(val2);
if (debug) {Info<<"-Term:"<<val2 <<nl;} if (debug) {Info<<"-Term:"<<val2<< " pos:"<< t->pos << nl;}
val -= val2; val -= val2;
if (debug) {Info<<"="<< val << nl;} if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
} }
} }
@ -130,23 +142,23 @@ void Parser::Expr(scalar& val) {
void Parser::Term(scalar& val) { void Parser::Term(scalar& val) {
scalar val2 = 0; scalar val2 = 0;
if (debug) {Info<<"Term:"<< val<< nl;} if (debug) {Info<<"Term:"<< val<< " pos:"<< t->pos << nl;}
Factor(val); Factor(val);
while (la->kind == 9 || la->kind == 10) { while (la->kind == 9 || la->kind == 10) {
if (la->kind == 9) { if (la->kind == 9) {
Get(); Get();
Factor(val2); Factor(val2);
if (debug) {Info<<"*Factor:"<<val2 << nl;} if (debug) {Info<<"*Factor:"<<val2<< " pos:"<< t->pos << nl;}
val *= val2; val *= val2;
if (debug) {Info<<"="<< val << nl; } if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
} else { } else {
Get(); Get();
Factor(val2); Factor(val2);
if (debug) {Info<<"/Factor:"<<val2 << nl;} if (debug) {Info<<"/Factor:"<<val2<< " pos:"<< t->pos << nl;}
val /= val2; val /= val2;
if (debug) {Info<<"="<< val << nl; } if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;}
} }
} }
@ -156,12 +168,12 @@ void Parser::Factor(scalar& val) {
if (la->kind == 3) { if (la->kind == 3) {
Get(); Get();
val = getDictLookup(); val = getDictLookup();
if (debug) {Info<<"lookup:"<<val<<nl;} if (debug) {Info<<"lookup:"<<val<< " pos:"<< t->pos << nl;}
} else if (la->kind == 4) { } else if (la->kind == 4) {
Get(); Get();
val = getScalar(); val = getScalar();
if (debug) {Info<<"got num:"<<val<<nl;} if (debug) {Info<<"got num:"<<val<< " pos:"<< t->pos << nl;}
} else if (la->kind == 8) { } else if (la->kind == 8) {
Get(); Get();
@ -169,13 +181,14 @@ void Parser::Factor(scalar& val) {
Expr(val); Expr(val);
Expect(12); Expect(12);
val = -val; val = -val;
if (debug) {Info<<"inv:"<<val<<nl;} if (debug) {Info<<"inv:"<<val<< " pos:"<< t->pos << nl;}
} else if (la->kind == 11) { } else if (la->kind == 11) {
Get(); Get();
Expr(val); Expr(val);
Expect(12); Expect(12);
if (debug){Info<<"got Expr:"<<val<<nl;} if (debug){Info<<"got Expr:"<<val<< " pos:"<< t->pos << nl;}
} else SynErr(15); } else SynErr(15);
} }
@ -189,9 +202,9 @@ void Parser::Parse() {
la = dummyToken = new Token(); la = dummyToken = new Token();
la->val = coco_string_create(L"Dummy Token"); la->val = coco_string_create(L"Dummy Token");
Get(); Get();
SimpleCalc(); calcEntry();
// let grammar deal with end-of-file expectations
Expect(0);
} }
@ -199,14 +212,12 @@ Parser::Parser(Scanner* scan, Errors* err)
: :
dummyToken(NULL), dummyToken(NULL),
deleteErrorsDestruct_(!err), deleteErrorsDestruct_(!err),
minErrDist(2),
errDist(minErrDist), errDist(minErrDist),
scanner(scan), scanner(scan),
errors(err), errors(err),
t(NULL), t(NULL),
la(NULL) la(NULL)
{ {
maxT = 13;
if (!errors) { // add in default error handling if (!errors) { // add in default error handling
errors = new Errors(); errors = new Errors();
@ -274,7 +285,7 @@ wchar_t* Errors::strerror(int n)
case 11: 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 12: s = coco_string_create(L"\")\" expected"); break;
case 13: 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 14: s = coco_string_create(L"invalid calcEntry"); break;
case 15: s = coco_string_create(L"invalid Factor"); break; case 15: s = coco_string_create(L"invalid Factor"); break;
default: default:
@ -317,8 +328,12 @@ void Errors::Exception(const wchar_t* msg) {
::exit(1); ::exit(1);
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // namespace } // namespace
} // namespace } // namespace
} // namespace } // namespace
// ************************************************************************* //

View File

@ -55,11 +55,12 @@ private:
_variable=3, _variable=3,
_number=4, _number=4,
}; };
int maxT; static const int maxT = 13;
static const int minErrDist = 2; //!< min. distance before reporting errors
Token *dummyToken; Token *dummyToken;
bool deleteErrorsDestruct_; //!< delete the 'errors' member in destructor bool deleteErrorsDestruct_; //!< delete the 'errors' member in destructor
int minErrDist;
int errDist; int errDist;
void SynErr(int n); //!< Handle syntax error 'n' void SynErr(int n); //!< Handle syntax error 'n'
@ -81,9 +82,13 @@ static const int debug = 0;
//! The parent dictionary //! The parent dictionary
mutable dictionary* dict_; mutable dictionary* dict_;
//! Track that parent dictionary was set
bool hasDict_;
//! The calculation result //! The calculation result
scalar val; scalar val;
//! token -> scalar //! token -> scalar
scalar getScalar() const scalar getScalar() const
{ {
@ -99,11 +104,11 @@ static const int debug = 0;
return s; return s;
} }
//! attach a dictionary //! attach a dictionary
void dict(const dictionary& dict) const void dict(const dictionary& dict)
{ {
dict_ = const_cast<dictionary*>(&dict); dict_ = const_cast<dictionary*>(&dict);
hasDict_ = true;
} }
@ -112,11 +117,11 @@ static const int debug = 0;
{ {
scalar dictValue = 0; scalar dictValue = 0;
if (!dict_) if (!hasDict_)
{ {
FatalErrorIn FatalErrorIn
( (
"SimpleCalc::getDictEntry() const" "calcEntry::getDictEntry() const"
) << "No dictionary attached!" ) << "No dictionary attached!"
<< exit(FatalError); << exit(FatalError);
@ -140,13 +145,22 @@ static const int debug = 0;
entry* entryPtr = dict_->lookupEntryPtr(keyword, true, false); entry* entryPtr = dict_->lookupEntryPtr(keyword, true, false);
if (entryPtr && !entryPtr->isDict()) if (entryPtr && !entryPtr->isDict())
{ {
if (entryPtr->stream().size() != 1)
{
FatalErrorIn
(
"calcEntry::getDictEntry() const"
) << "keyword " << keyword << " has "
<< entryPtr->stream().size() << " values in dictionary "
<< exit(FatalError);
}
entryPtr->stream() >> dictValue; entryPtr->stream() >> dictValue;
} }
else else
{ {
FatalErrorIn FatalErrorIn
( (
"SimpleCalc::getDictEntry() const" "calcEntry::getDictEntry() const"
) << "keyword " << keyword << " is undefined in dictionary " ) << "keyword " << keyword << " is undefined in dictionary "
<< exit(FatalError); << exit(FatalError);
} }
@ -161,7 +175,7 @@ static const int debug = 0;
} }
// * * * * * * * * * * * * * * * CHARACTERS * * * * * * * * * * * * * * * * // /*---------------------------------------------------------------------------*/
@ -174,7 +188,7 @@ static const int debug = 0;
~Parser(); //!< Destructor - cleanup errors and dummyToken ~Parser(); //!< Destructor - cleanup errors and dummyToken
void SemErr(const wchar_t* msg); //!< Handle semantic error void SemErr(const wchar_t* msg); //!< Handle semantic error
void SimpleCalc(); void calcEntry();
void Expr(scalar& val); void Expr(scalar& val);
void Term(scalar& val); void Term(scalar& val);
void Factor(scalar& val); void Factor(scalar& val);

View File

@ -1,9 +1,16 @@
#include <memory.h> #include <sstream>
#include <string.h>
#include "calcEntryScanner.h" #include "calcEntryScanner.h"
// values for the file stream buffering
#define MIN_BUFFER_LENGTH 1024 // 1KB
#define MAX_BUFFER_LENGTH (64*MIN_BUFFER_LENGTH) // 64KB
// value for the heap management
#define HEAP_BLOCK_SIZE (64*1024) // 64KB
namespace Foam { namespace Foam {
namespace functionEntries { namespace functionEntries {
namespace calcEntryInternal { namespace calcEntryInternal {
@ -36,29 +43,6 @@ wchar_t* coco_string_create(const wchar_t* str, int index, int length) {
return dest; 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) { wchar_t* coco_string_create_lower(const wchar_t* str) {
if (!str) { return NULL; } if (!str) { return NULL; }
@ -178,7 +162,7 @@ wchar_t* coco_string_create(const char* str) {
int len = str ? strlen(str) : 0; int len = str ? strlen(str) : 0;
wchar_t* dest = new wchar_t[len + 1]; wchar_t* dest = new wchar_t[len + 1];
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) {
dest[i] = (wchar_t) str[i]; dest[i] = wchar_t(str[i]);
} }
dest[len] = 0; dest[len] = 0;
return dest; return dest;
@ -188,7 +172,7 @@ wchar_t* coco_string_create(const char* str, int index, int length) {
int len = str ? length : 0; int len = str ? length : 0;
wchar_t* dest = new wchar_t[len + 1]; wchar_t* dest = new wchar_t[len + 1];
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) {
dest[i] = (wchar_t) str[index + i]; dest[i] = wchar_t(str[index + i]);
} }
dest[len] = 0; dest[len] = 0;
return dest; return dest;
@ -200,7 +184,7 @@ char* coco_string_create_char(const wchar_t* str) {
char *dest = new char[len + 1]; char *dest = new char[len + 1];
for (int i = 0; i < len; ++i) for (int i = 0; i < len; ++i)
{ {
dest[i] = (char) str[i]; dest[i] = char(str[i]);
} }
dest[len] = 0; dest[len] = 0;
return dest; return dest;
@ -213,7 +197,7 @@ char* coco_string_create_char(const wchar_t* str, int index, int length) {
} }
char *dest = new char[len + 1]; char *dest = new char[len + 1];
for (int i = 0; i < len; ++i) { for (int i = 0; i < len; ++i) {
dest[i] = (char) str[index + i]; dest[i] = char(str[index + i]);
} }
dest[len] = 0; dest[len] = 0;
return dest; return dest;
@ -251,27 +235,61 @@ Token::Token()
{} {}
// Note: this delete may not be correct if the token was actually
// allocated by the internal heap mechanism
Token::~Token() { Token::~Token() {
coco_string_delete(val); coco_string_delete(val);
} }
Buffer::Buffer(FILE* s, bool isUserStream) { // ----------------------------------------------------------------------------
// Buffer Implementation
// ----------------------------------------------------------------------------
Buffer::Buffer(Buffer* b)
:
buf(b->buf),
bufCapacity(b->bufCapacity),
bufLen(b->bufLen),
bufPos(b->bufPos),
bufStart(b->bufStart),
fileLen(b->fileLen),
cStream(b->cStream),
stdStream(b->stdStream),
isUserStream_(b->isUserStream_)
{
// avoid accidental deletion on any of these members
b->buf = NULL;
b->cStream = NULL;
b->stdStream = NULL;
}
Buffer::Buffer(FILE* istr, bool isUserStream)
:
buf(NULL),
bufCapacity(0),
bufLen(0),
bufPos(0),
bufStart(0),
fileLen(0),
cStream(istr),
stdStream(NULL),
isUserStream_(isUserStream)
{
// ensure binary read on windows // ensure binary read on windows
#if _MSC_VER >= 1300 #if _MSC_VER >= 1300
_setmode(_fileno(s), _O_BINARY); _setmode(_fileno(cStream), _O_BINARY);
#endif #endif
stream = s; this->isUserStream = isUserStream;
if (CanSeek()) { if (CanSeek()) {
fseek(s, 0, SEEK_END); fseek(cStream, 0, SEEK_END);
fileLen = ftell(s); fileLen = ftell(cStream);
fseek(s, 0, SEEK_SET); fseek(cStream, 0, SEEK_SET);
bufLen = (fileLen < MAX_BUFFER_LENGTH) ? fileLen : MAX_BUFFER_LENGTH; bufLen = (fileLen < MAX_BUFFER_LENGTH) ? fileLen : MAX_BUFFER_LENGTH;
bufStart = INT_MAX; // nothing in the buffer so far bufStart = INT_MAX; // nothing in the buffer so far
} }
else {
fileLen = bufLen = bufStart = 0;
}
bufCapacity = (bufLen > 0) ? bufLen : MIN_BUFFER_LENGTH; bufCapacity = (bufLen > 0) ? bufLen : MIN_BUFFER_LENGTH;
buf = new unsigned char[bufCapacity]; buf = new unsigned char[bufCapacity];
if (fileLen > 0) SetPos(0); // setup buffer to position 0 (start) if (fileLen > 0) SetPos(0); // setup buffer to position 0 (start)
@ -280,45 +298,74 @@ Buffer::Buffer(FILE* s, bool isUserStream) {
} }
Buffer::Buffer(Buffer* b) { Buffer::Buffer(std::istream* istr, bool isUserStream)
buf = b->buf; :
bufCapacity = b->bufCapacity; buf(NULL),
b->buf = NULL; bufCapacity(0),
bufStart = b->bufStart; bufLen(0),
bufLen = b->bufLen; bufPos(0),
fileLen = b->fileLen; bufStart(0),
bufPos = b->bufPos; fileLen(0),
stream = b->stream; cStream(NULL),
b->stream = NULL; stdStream(istr),
isUserStream = b->isUserStream; isUserStream_(isUserStream)
{
// ensure binary read on windows
#if _MSC_VER >= 1300
// TODO
#endif
} }
Buffer::Buffer(const unsigned char* buf, int len) { Buffer::Buffer(std::string& str)
this->buf = new unsigned char[len]; :
memcpy(this->buf, buf, len*sizeof(unsigned char)); buf(NULL),
bufStart = 0; bufCapacity(0),
bufCapacity = bufLen = len; bufLen(0),
fileLen = len; bufPos(0),
bufPos = 0; bufStart(0),
stream = NULL; fileLen(0),
cStream(NULL),
stdStream(new std::istringstream(str)),
isUserStream_(false)
{}
Buffer::Buffer(const unsigned char* chars, int len)
:
buf(new unsigned char[len]),
bufCapacity(len),
bufLen(len),
bufPos(0),
bufStart(0),
fileLen(len),
cStream(NULL),
stdStream(NULL),
isUserStream_(false)
{
memcpy(this->buf, chars, len*sizeof(char));
} }
Buffer::Buffer(const char* buf, int len) { Buffer::Buffer(const char* chars, int len)
this->buf = new unsigned char[len]; :
memcpy(this->buf, buf, len*sizeof(unsigned char)); buf(new unsigned char[len]),
bufStart = 0; bufCapacity(len),
bufCapacity = bufLen = len; bufLen(len),
fileLen = len; bufPos(0),
bufPos = 0; bufStart(0),
stream = NULL; fileLen(len),
cStream(NULL),
stdStream(NULL),
isUserStream_(false)
{
memcpy(this->buf, chars, len*sizeof(char));
} }
Buffer::~Buffer() { Buffer::~Buffer() {
Close(); Close();
if (buf != NULL) { if (buf) {
delete [] buf; delete [] buf;
buf = NULL; buf = NULL;
} }
@ -326,20 +373,36 @@ Buffer::~Buffer() {
void Buffer::Close() { void Buffer::Close() {
if (!isUserStream && stream != NULL) { if (!isUserStream_) {
fclose(stream); if (cStream) {
stream = NULL; fclose(cStream);
cStream = NULL;
}
else if (stdStream) {
delete stdStream;
stdStream = 0;
}
} }
} }
int Buffer::Read() { int Buffer::Read() {
if (stdStream)
{
int ch = stdStream->get();
if (stdStream->eof())
{
return EoF;
}
return ch;
}
if (bufPos < bufLen) { if (bufPos < bufLen) {
return buf[bufPos++]; return buf[bufPos++];
} else if (GetPos() < fileLen) { } else if (GetPos() < fileLen) {
SetPos(GetPos()); // shift buffer start to Pos SetPos(GetPos()); // shift buffer start to Pos
return buf[bufPos++]; return buf[bufPos++];
} else if ((stream != NULL) && !CanSeek() && (ReadNextStreamChunk() > 0)) { } else if (cStream && !CanSeek() && (ReadNextStreamChunk() > 0)) {
return buf[bufPos++]; return buf[bufPos++];
} else { } else {
return EoF; return EoF;
@ -347,91 +410,6 @@ int Buffer::Read() {
} }
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 UTF8Buffer::Read() {
int ch; int ch;
do { do {
@ -464,42 +442,143 @@ int UTF8Buffer::Read() {
} }
Scanner::Scanner(const unsigned char* buf, int len) { int Buffer::Peek() {
buffer = new Buffer(buf, len); int curPos = GetPos();
int ch = Read();
SetPos(curPos);
return ch;
}
int Buffer::GetPos() const {
if (stdStream)
{
return stdStream->tellg();
}
return bufPos + bufStart;
}
void Buffer::SetPos(int value) {
if (stdStream)
{
stdStream->seekg(value, std::ios::beg);
return;
}
if ((value >= fileLen) && cStream && !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 (cStream) { // must be swapped in
fseek(cStream, value, SEEK_SET);
bufLen = fread(buf, sizeof(char), bufCapacity, cStream);
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(char));
delete [] buf;
buf = newBuf;
freeLen = bufLen;
}
int read = fread(buf + bufLen, sizeof(char), freeLen, cStream);
if (read > 0) {
fileLen = bufLen = (bufLen + read);
return read;
}
// end of stream reached
return 0;
}
bool Buffer::CanSeek() const {
return cStream && (ftell(cStream) != -1);
}
// ----------------------------------------------------------------------------
// Scanner Implementation
// ----------------------------------------------------------------------------
Scanner::Scanner(FILE* istr)
:
buffer(new Buffer(istr, true))
{
Init(); Init();
} }
Scanner::Scanner(const char* buf, int len) { Scanner::Scanner(std::istream& istr)
buffer = new Buffer(buf, len); :
buffer(new Buffer(&istr, true))
{
Init(); Init();
} }
Scanner::Scanner(const wchar_t* fileName) { Scanner::Scanner(const wchar_t* fileName) {
FILE* stream;
char *chFileName = coco_string_create_char(fileName); char *chFileName = coco_string_create_char(fileName);
if ((stream = fopen(chFileName, "rb")) == NULL) { FILE* istr;
if ((istr = fopen(chFileName, "rb")) == NULL) {
wprintf(L"--- Cannot open file %ls\n", fileName); wprintf(L"--- Cannot open file %ls\n", fileName);
::exit(1); ::exit(1);
} }
coco_string_delete(chFileName); coco_string_delete(chFileName);
buffer = new Buffer(stream, false); buffer = new Buffer(istr, false);
Init(); Init();
} }
Scanner::Scanner(FILE* s) { Scanner::Scanner(const unsigned char* buf, int len)
buffer = new Buffer(s, true); :
buffer(new Buffer(buf, len))
{
Init();
}
Scanner::Scanner(const char* buf, int len)
:
buffer(new Buffer(buf, len))
{
Init(); Init();
} }
Scanner::~Scanner() { Scanner::~Scanner() {
char* cur = (char*) firstHeap; char* cur = reinterpret_cast<char*>(firstHeap);
while (cur != NULL) { while (cur) {
cur = *(char**) (cur + HEAP_BLOCK_SIZE); cur = *(reinterpret_cast<char**>(cur + HEAP_BLOCK_SIZE));
free(firstHeap); free(firstHeap);
firstHeap = cur; firstHeap = cur;
} }
@ -509,14 +588,11 @@ Scanner::~Scanner() {
void Scanner::Init() { void Scanner::Init() {
maxT = 13; for (int i = 65; i <= 90; ++i) start.set(i, 1);
noSym = 13; for (int i = 97; i <= 122; ++i) start.set(i, 1);
int i; for (int i = 36; i <= 36; ++i) start.set(i, 5);
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); start.set(45, 20);
for (i = 48; i <= 57; ++i) start.set(i, 9); for (int i = 48; i <= 57; ++i) start.set(i, 9);
start.set(34, 2); start.set(34, 2);
start.set(46, 7); start.set(46, 7);
start.set(123, 14); start.set(123, 14);
@ -526,7 +602,8 @@ void Scanner::Init() {
start.set(47, 17); start.set(47, 17);
start.set(40, 18); start.set(40, 18);
start.set(41, 19); start.set(41, 19);
start.set(Buffer::EoF, -1); start.set(Buffer::EoF, -1);
tvalLength = 128; tvalLength = 128;
@ -535,7 +612,9 @@ void Scanner::Init() {
// HEAP_BLOCK_SIZE byte heap + pointer to next heap block // HEAP_BLOCK_SIZE byte heap + pointer to next heap block
heap = malloc(HEAP_BLOCK_SIZE + sizeof(void*)); heap = malloc(HEAP_BLOCK_SIZE + sizeof(void*));
firstHeap = heap; firstHeap = heap;
heapEnd = (void**) (((char*) heap) + HEAP_BLOCK_SIZE); heapEnd =
reinterpret_cast<void**>
(reinterpret_cast<char*>(heap) + HEAP_BLOCK_SIZE);
*heapEnd = 0; *heapEnd = 0;
heapTop = heap; heapTop = heap;
if (sizeof(Token) > HEAP_BLOCK_SIZE) { if (sizeof(Token) > HEAP_BLOCK_SIZE) {
@ -645,19 +724,25 @@ bool Scanner::Comment1() {
void Scanner::CreateHeapBlock() { void Scanner::CreateHeapBlock() {
void* newHeap; char* cur = reinterpret_cast<char*>(firstHeap);
char* cur = (char*) firstHeap;
while (((char*) tokens < cur) || ((char*) tokens > (cur + HEAP_BLOCK_SIZE))) { // release unused blocks
cur = *((char**) (cur + HEAP_BLOCK_SIZE)); while
(
(reinterpret_cast<char*>(tokens) < cur)
|| (reinterpret_cast<char*>(tokens) > (cur + HEAP_BLOCK_SIZE))
) {
cur = *(reinterpret_cast<char**>(cur + HEAP_BLOCK_SIZE));
free(firstHeap); free(firstHeap);
firstHeap = cur; firstHeap = cur;
} }
// HEAP_BLOCK_SIZE byte heap + pointer to next heap block // HEAP_BLOCK_SIZE byte heap + pointer to next heap block
newHeap = malloc(HEAP_BLOCK_SIZE + sizeof(void*)); void* newHeap = malloc(HEAP_BLOCK_SIZE + sizeof(void*));
*heapEnd = newHeap; *heapEnd = newHeap;
heapEnd = (void**) (((char*) newHeap) + HEAP_BLOCK_SIZE); heapEnd =
reinterpret_cast<void**>
(reinterpret_cast<char*>(newHeap) + HEAP_BLOCK_SIZE);
*heapEnd = 0; *heapEnd = 0;
heap = newHeap; heap = newHeap;
heapTop = heap; heapTop = heap;
@ -665,38 +750,57 @@ void Scanner::CreateHeapBlock() {
Token* Scanner::CreateToken() { Token* Scanner::CreateToken() {
Token *t; const int reqMem = sizeof(Token);
if (((char*) heapTop + (int) sizeof(Token)) >= (char*) heapEnd) { if
(
(reinterpret_cast<char*>(heapTop) + reqMem)
>= reinterpret_cast<char*>(heapEnd)
) {
CreateHeapBlock(); CreateHeapBlock();
} }
t = (Token*) heapTop; // token 'occupies' heap starting at heapTop
heapTop = (void*) ((char*) heapTop + sizeof(Token)); Token* tok = reinterpret_cast<Token*>(heapTop);
t->val = NULL; // increment past this part of the heap, which is now used
t->next = NULL; heapTop =
return t; reinterpret_cast<void*>
(reinterpret_cast<char*>(heapTop) + reqMem);
tok->val = NULL;
tok->next = NULL;
return tok;
} }
void Scanner::AppendVal(Token *t) { void Scanner::AppendVal(Token* tok) {
int reqMem = (tlen + 1) * sizeof(wchar_t); const int reqMem = (tlen + 1) * sizeof(wchar_t);
if (((char*) heapTop + reqMem) >= (char*) heapEnd) { if
(
(reinterpret_cast<char*>(heapTop) + reqMem)
>= reinterpret_cast<char*>(heapEnd)
) {
if (reqMem > HEAP_BLOCK_SIZE) { if (reqMem > HEAP_BLOCK_SIZE) {
wprintf(L"--- Too long token value\n"); wprintf(L"--- Too long token value\n");
::exit(1); ::exit(1);
} }
CreateHeapBlock(); CreateHeapBlock();
} }
t->val = (wchar_t*) heapTop;
heapTop = (void*) ((char*) heapTop + reqMem);
wcsncpy(t->val, tval, tlen); // add text value from heap
t->val[tlen] = L'\0'; tok->val = reinterpret_cast<wchar_t*>(heapTop);
// increment past this part of the heap, which is now used
heapTop =
reinterpret_cast<void*>
(reinterpret_cast<char*>(heapTop) + reqMem);
// copy the currently parsed tval into the token
wcsncpy(tok->val, tval, tlen);
tok->val[tlen] = L'\0';
} }
Token* Scanner::NextToken() { Token* Scanner::NextToken() {
while (ch == ' ' || while (ch == ' ' ||
ch <= 31 || (ch >= 127 && ch <= 65535) (ch >= 9 && ch <= 10) || ch == 13
) NextCh(); ) NextCh();
if ((ch == L'/' && Comment0()) || (ch == L'/' && Comment1())) return NextToken(); if ((ch == L'/' && Comment0()) || (ch == L'/' && Comment1())) return NextToken();
t = CreateToken(); t = CreateToken();
@ -818,8 +922,11 @@ void Scanner::ResetPeek() {
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // namespace } // namespace
} // namespace } // namespace
} // namespace } // namespace
// ************************************************************************* //

View File

@ -3,11 +3,14 @@
#ifndef COCO_calcEntrySCANNER_H__ #ifndef COCO_calcEntrySCANNER_H__
#define COCO_calcEntrySCANNER_H__ #define COCO_calcEntrySCANNER_H__
#include <limits.h> #include <climits>
#include <stdio.h> #include <cstdio>
#include <stdlib.h> #include <cstdlib>
#include <string.h> #include <cstring>
#include <wchar.h> #include <cwchar>
#include <string>
#include <fstream>
#include <iostream>
// io.h and fcntl are used to ensure binary read from streams on windows // io.h and fcntl are used to ensure binary read from streams on windows
#if _MSC_VER >= 1300 #if _MSC_VER >= 1300
@ -24,10 +27,8 @@
#define coco_swprintf swprintf #define coco_swprintf swprintf
#endif #endif
#define COCO_WCHAR_MAX 65535 #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 Foam {
@ -48,12 +49,6 @@ wchar_t* coco_string_create(const wchar_t* str);
//! Create a substring of str starting at index and length characters long //! 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); 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 //! Create a lowercase string from str
wchar_t* coco_string_create_lower(const wchar_t* str); wchar_t* coco_string_create_lower(const wchar_t* str);
@ -138,7 +133,6 @@ float coco_string_toFloat(const char* str);
// * * * * * * * * * End of Wide Character String Routines * * * * * * * * * // // * * * * * * * * * End of Wide Character String Routines * * * * * * * * * //
//! Scanner Token //! Scanner Token
class Token class Token
{ {
@ -151,7 +145,7 @@ public:
Token *next; //!< Peek tokens are kept in linked list Token *next; //!< Peek tokens are kept in linked list
Token(); //!< Construct null Token(); //!< Construct null
~Token(); //!< Destructor - cleanup allocated val ~Token(); //!< Destructor - cleanup allocated val??
}; };
@ -166,30 +160,48 @@ class Buffer {
private: private:
unsigned char *buf; //!< input buffer unsigned char *buf; //!< input buffer
int bufCapacity; //!< capacity of buf int bufCapacity; //!< capacity of buf
int bufStart; //!< position of first byte in buffer relative to input stream
int bufLen; //!< length of buffer 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 int bufPos; //!< current position in buffer
FILE* stream; //!< input stream (seekable) int bufStart; //!< position of first byte in buffer relative to input stream
bool isUserStream; //!< was the stream opened by the user? int fileLen; //!< length of input stream (may change if the stream is no file)
FILE* cStream; //!< input stdio stream (normally seekable)
std::istream* stdStream; //!< STL std stream (seekable)
bool isUserStream_; //!< was the stream opened by the user?
int ReadNextStreamChunk(); int ReadNextStreamChunk();
bool CanSeek(); //!< true if stream can be seeked otherwise false bool CanSeek() const; //!< true if stream can be seeked otherwise false
protected:
Buffer(Buffer*); //!< for the UTF8Buffer
public: public:
static const int EoF = COCO_WCHAR_MAX + 1; static const int EoF = COCO_WCHAR_MAX + 1;
Buffer(FILE*, bool isUserStream); //! Attach buffer to a stdio stream.
Buffer(const unsigned char* buf, int len); //! User streams are not closed in the destructor
Buffer(const char* buf, int len); Buffer(FILE*, bool isUserStream = true);
Buffer(Buffer*);
//! Attach buffer to an STL std stream
//! User streams are not closed in the destructor
explicit Buffer(std::istream*, bool isUserStream = true);
//! Copy buffer contents from constant string
//! Handled internally as an istringstream
explicit Buffer(std::string&);
//! Copy buffer contents from constant character string
Buffer(const unsigned char* chars, int len);
//! Copy buffer contents from constant character string
Buffer(const char* chars, int len);
//! Close stream (but not user streams) and free buf (if any)
virtual ~Buffer(); virtual ~Buffer();
virtual void Close(); virtual void Close(); //!< Close stream (but not user streams)
virtual int Read(); virtual int Read(); //!< Get character from stream or buffer
virtual int Peek(); virtual int Peek(); //!< Peek character from stream or buffer
virtual wchar_t* GetString(int beg, int end);
virtual int GetPos(); virtual int GetPos() const;
virtual void SetPos(int value); virtual void SetPos(int value);
}; };
@ -205,31 +217,31 @@ public:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// StartStates // StartStates
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//! maps characters to start states of tokens //! maps characters (integers) to start states of tokens
class StartStates { class StartStates {
private: private:
class Elem { class Elem {
public: public:
int key, val; int key, val;
Elem *next; Elem *next;
Elem(int key, int val) { Elem(int k, int v) :
this->key = key; key(k), val(v), next(0)
this->val = val; {}
next = NULL;
}
}; };
Elem **tab; Elem **tab;
public: public:
StartStates() { StartStates() :
tab = new Elem*[128]; tab(new Elem*[128])
{
memset(tab, 0, 128 * sizeof(Elem*)); memset(tab, 0, 128 * sizeof(Elem*));
} }
virtual ~StartStates() { virtual ~StartStates() {
for (int i = 0; i < 128; ++i) { for (int i = 0; i < 128; ++i) {
Elem *e = tab[i]; Elem *e = tab[i];
while (e != NULL) { while (e) {
Elem *next = e->next; Elem *next = e->next;
delete e; delete e;
e = next; e = next;
@ -240,15 +252,15 @@ public:
void set(int key, int val) { void set(int key, int val) {
Elem *e = new Elem(key, val); Elem *e = new Elem(key, val);
int k = ((unsigned int) key) % 128; int k = unsigned(key) % 128;
e->next = tab[k]; e->next = tab[k];
tab[k] = e; tab[k] = e;
} }
int state(int key) { int state(int key) {
Elem *e = tab[((unsigned int) key) % 128]; Elem *e = tab[unsigned(key) % 128];
while (e != NULL && e->key != key) e = e->next; while (e && e->key != key) e = e->next;
return e == NULL ? 0 : e->val; return e ? e->val : 0;
} }
}; };
@ -264,11 +276,9 @@ private:
wchar_t *key; wchar_t *key;
int val; int val;
Elem *next; Elem *next;
Elem(const wchar_t *key, int val) { Elem(const wchar_t *k, int v) :
this->key = coco_string_create(key); key(coco_string_create(k)), val(v), next(0)
this->val = val; {}
next = NULL;
}
virtual ~Elem() { virtual ~Elem() {
coco_string_delete(key); coco_string_delete(key);
} }
@ -277,14 +287,16 @@ private:
Elem **tab; Elem **tab;
public: public:
KeywordMap() { KeywordMap() :
tab = new Elem*[128]; tab(new Elem*[128])
{
memset(tab, 0, 128 * sizeof(Elem*)); memset(tab, 0, 128 * sizeof(Elem*));
} }
virtual ~KeywordMap() { virtual ~KeywordMap() {
for (int i = 0; i < 128; ++i) { for (int i = 0; i < 128; ++i) {
Elem *e = tab[i]; Elem *e = tab[i];
while (e != NULL) { while (e) {
Elem *next = e->next; Elem *next = e->next;
delete e; delete e;
e = next; e = next;
@ -295,14 +307,15 @@ public:
void set(const wchar_t *key, int val) { void set(const wchar_t *key, int val) {
Elem *e = new Elem(key, val); Elem *e = new Elem(key, val);
int k = coco_string_hash(key) % 128; const int k = coco_string_hash(key) % 128;
e->next = tab[k]; tab[k] = e; e->next = tab[k];
tab[k] = e;
} }
int get(const wchar_t *key, int defaultVal) { int get(const wchar_t *key, int defaultVal) {
Elem *e = tab[coco_string_hash(key) % 128]; Elem *e = tab[coco_string_hash(key) % 128];
while (e != NULL && !coco_string_equal(e->key, key)) e = e->next; while (e && !coco_string_equal(e->key, key)) e = e->next;
return e == NULL ? defaultVal : e->val; return e ? e->val : defaultVal;
} }
}; };
@ -310,24 +323,24 @@ public:
//! A Coco/R Scanner //! A Coco/R Scanner
class Scanner { class Scanner {
private: private:
static const unsigned char EOL = '\n'; // end-of-line character static const int maxT = 13;
static const int eofSym = 0; // end-of-file token id static const int noSym = 13;
void *firstHeap; static const int eofSym = 0; //!< end-of-file token id
void *heap; static const char EOL = '\n'; //!< end-of-line character
void *heapTop;
void **heapEnd;
int noSym; //!< noSym gets highest number, set in Parser void *firstHeap; //!< the start of the heap management
int maxT; void *heap; //!< the currently active block
int charSetSize; //!< unused? void *heapTop; //!< the top of the heap
StartStates start; void **heapEnd; //!< the end of the last heap block
KeywordMap keywords;
StartStates start; //!< A map of start states for particular characters
KeywordMap keywords; //!< A hash of keyword literals to token kind
Token *t; //!< current token Token *t; //!< current token
wchar_t *tval; //!< text of current token wchar_t *tval; //!< text of current token
int tvalLength; //!< length of text of current token int tvalLength; //!< maximum capacity (length) for tval
int tlen; //!< length of current token int tlen; //!< length of tval
Token *tokens; //!< list of tokens already peeked (first token is a dummy) Token *tokens; //!< list of tokens already peeked (first token is a dummy)
Token *pt; //!< current peek token Token *pt; //!< current peek token
@ -337,36 +350,42 @@ private:
int pos; //!< byte position of current character int pos; //!< byte position of current character
int line; //!< line number of current character int line; //!< line number of current character
int col; //!< column number of current character int col; //!< column number of current character
int oldEols; //!< EOLs that appeared in a comment; int oldEols; //!< the number of EOLs that appeared in a comment
void CreateHeapBlock(); void CreateHeapBlock(); //!< add a heap block, freeing unused ones
Token* CreateToken(); Token* CreateToken(); //!< fit token on the heap
void AppendVal(Token*); void AppendVal(Token* tok); //!< adjust tok->val to point to the heap and copy tval into it
void Init(); void Init(); //!< complete the initialization for the constructors
void NextCh(); void NextCh(); //!< get the next input character into ch
void AddCh(); void AddCh(); //!< append the character ch to tval
bool Comment0(); bool Comment0();
bool Comment1(); bool Comment1();
Token* NextToken(); Token* NextToken(); //!< get the next token
public: public:
//! scanner buffer //! The scanner buffer
Buffer *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 //! Using an existing open file handle for the scanner
Scanner(FILE* s); Scanner(FILE*);
~Scanner();
Token* Scan(); //! Using an existing open STL std stream
Token* Peek(); explicit Scanner(std::istream&);
void ResetPeek();
//! Open a file for reading and attach scanner
explicit Scanner(const wchar_t* fileName);
//! Attach scanner to an existing character buffer
Scanner(const unsigned char* chars, int len);
//! Attach scanner to an existing character buffer
Scanner(const char* chars, int len);
~Scanner(); //!< free heap and allocated memory
Token* Scan(); //!< get the next token (possibly a token already seen during peeking)
Token* Peek(); //!< peek for the next token, ignore pragmas
void ResetPeek(); //!< ensure that peeking starts at the current scan position
}; // end Scanner }; // end Scanner

View File

@ -67,7 +67,6 @@ boundaryField
// error #remove self; // error #remove self;
x 5; x 5;
y 6; y 6;
another #calc{x $x; y $y;};
} }
// this should have no effect // this should have no effect

View File

@ -14,8 +14,11 @@ FoamFile
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
x 10 /* what ever */ 20; flowRatePerHour 720;
x 10;
y 20; y 20;
z t s v;
// z #test{ // this // z #test{ // this
// 123 - 456 // 123 - 456
// // comments // are // // comments // are
@ -26,8 +29,18 @@ y 20;
// + 1 /*100 */ 10 // + 1 /*100 */ 10
// }; // };
p #test{ 1 + 2 + 10 * 15 + $x - $y }; p this calculation #calc{
1 + 2 + 10 * 15 +
$x - $y
// $x + $y
}
is done inplace;
foo 30;
flowRate #calc{ $flowRatePerHour / 3600};
xxx yyy;
foo 30;
bar 15;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -78,17 +78,6 @@ Foam::IFstreamAllocator::~IFstreamAllocator()
} }
std::istream& Foam::IFstreamAllocator::stdStream()
{
if (!ifPtr_)
{
FatalErrorIn("IFstreamAllocator::stdStream()")
<< "No stream allocated" << abort(FatalError);
}
return *ifPtr_;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::IFstream::IFstream Foam::IFstream::IFstream
@ -143,6 +132,28 @@ Foam::IFstream::~IFstream()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
std::istream& Foam::IFstream::stdStream()
{
if (!ifPtr_)
{
FatalErrorIn("IFstream::stdStream()")
<< "No stream allocated" << abort(FatalError);
}
return *ifPtr_;
}
const std::istream& Foam::IFstream::stdStream() const
{
if (!ifPtr_)
{
FatalErrorIn("IFstream::stdStream() const")
<< "No stream allocated" << abort(FatalError);
}
return *ifPtr_;
}
void Foam::IFstream::print(Ostream& os) const void Foam::IFstream::print(Ostream& os) const
{ {
// Print File data // Print File data

View File

@ -51,7 +51,7 @@ namespace Foam
class IFstream; class IFstream;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class IFstreamAllocator Declaration Class IFstreamAllocator Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
//- A std::istream with ability to handle compressed files //- A std::istream with ability to handle compressed files
@ -74,19 +74,11 @@ class IFstreamAllocator
// Destructor // Destructor
~IFstreamAllocator(); ~IFstreamAllocator();
public:
// Member functions
//- Access to underlying std::istream (for e.g. lexer)
istream& stdStream();
}; };
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class IFstream Declaration Class IFstream Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class IFstream class IFstream
@ -136,6 +128,16 @@ public:
return pathname_; return pathname_;
} }
// STL stream
//- Access to underlying std::istream
virtual istream& stdStream();
//- Const access to underlying std::istream
virtual const istream& stdStream() const;
// Print // Print
//- Print description of IOstream to Ostream //- Print description of IOstream to Ostream

View File

@ -81,17 +81,6 @@ Foam::OFstreamAllocator::~OFstreamAllocator()
} }
std::ostream& Foam::OFstreamAllocator::stdStream()
{
if (!ofPtr_)
{
FatalErrorIn("OFstreamAllocator::stdStream()")
<< "No stream allocated." << abort(FatalError);
}
return *ofPtr_;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::OFstream::OFstream Foam::OFstream::OFstream
@ -131,7 +120,7 @@ Foam::OFstream::OFstream
} }
// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::OFstream::~OFstream() Foam::OFstream::~OFstream()
{} {}
@ -139,6 +128,28 @@ Foam::OFstream::~OFstream()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
std::ostream& Foam::OFstream::stdStream()
{
if (!ofPtr_)
{
FatalErrorIn("OFstream::stdStream()")
<< "No stream allocated." << abort(FatalError);
}
return *ofPtr_;
}
const std::ostream& Foam::OFstream::stdStream() const
{
if (!ofPtr_)
{
FatalErrorIn("OFstreamAllocator::stdStream() const")
<< "No stream allocated." << abort(FatalError);
}
return *ofPtr_;
}
void Foam::OFstream::print(Ostream& os) const void Foam::OFstream::print(Ostream& os) const
{ {
os << " OFstream: "; os << " OFstream: ";

View File

@ -51,7 +51,7 @@ namespace Foam
class OFstream; class OFstream;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class OFstreamAllocator Declaration Class OFstreamAllocator Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
//- A std::ostream with ability to handle compressed files //- A std::ostream with ability to handle compressed files
@ -74,18 +74,11 @@ class OFstreamAllocator
~OFstreamAllocator(); ~OFstreamAllocator();
public:
// Member functions
//- Access to underlying std::ostream
ostream& stdStream();
}; };
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class OFstream Declaration Class OFstream Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class OFstream class OFstream
@ -138,6 +131,15 @@ public:
} }
// STL stream
//- Access to underlying std::ostream
virtual ostream& stdStream();
//- Const access to underlying std::ostream
virtual const ostream& stdStream() const;
// Print // Print
//- Print description of IOstream to Ostream //- Print description of IOstream to Ostream
@ -146,8 +148,8 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Global predefined null output stream
//- Global predefined null output stream "/dev/null"
extern OFstream Snull; extern OFstream Snull;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -551,7 +551,7 @@ Foam::Istream& Foam::ISstream::read(char* buf, std::streamsize count)
Foam::Istream& Foam::ISstream::rewind() Foam::Istream& Foam::ISstream::rewind()
{ {
stream().rdbuf()->pubseekpos(0); stdStream().rdbuf()->pubseekpos(0);
return *this; return *this;
} }

View File

@ -72,23 +72,6 @@ class ISstream
void operator=(const ISstream&); void operator=(const ISstream&);
protected:
// Protected member functions
//- Return the stream reference
istream& stream()
{
return is_;
}
//- Return the const stream reference
const istream& stream() const
{
return is_;
}
public: public:
// Constructors // Constructors
@ -185,6 +168,21 @@ public:
virtual ios_base::fmtflags flags(const ios_base::fmtflags flags); virtual ios_base::fmtflags flags(const ios_base::fmtflags flags);
// STL stream
//- Access to underlying std::istream
virtual istream& stdStream()
{
return is_;
}
//- Const access to underlying std::istream
virtual const istream& stdStream() const
{
return is_;
}
// Print // Print
//- Print description of IOstream to Ostream //- Print description of IOstream to Ostream

View File

@ -67,21 +67,6 @@ class OSstream
void operator=(const OSstream&); void operator=(const OSstream&);
protected:
//- Return the stream reference
ostream& stream()
{
return os_;
}
//- Return the const stream reference
const ostream& stream() const
{
return os_;
}
public: public:
// Constructors // Constructors
@ -187,6 +172,21 @@ public:
virtual int precision(const int); virtual int precision(const int);
// STL stream
//- Access to underlying std::ostream
virtual ostream& stdStream()
{
return os_;
}
//- Const access to underlying std::ostream
virtual const ostream& stdStream() const
{
return os_;
}
// Print // Print
//- Print description of IOstream to Ostream //- Print description of IOstream to Ostream

View File

@ -97,7 +97,7 @@ public:
~IStringStream() ~IStringStream()
{ {
delete &dynamic_cast<std::istringstream&>(stream()); delete &dynamic_cast<std::istringstream&>(stdStream());
} }
@ -108,7 +108,10 @@ public:
//- Return the string //- Return the string
string str() const string str() const
{ {
return dynamic_cast<const std::istringstream&>(stream()).str(); return dynamic_cast<const std::istringstream&>
(
stdStream()
).str();
} }

View File

@ -83,7 +83,7 @@ public:
( (
dynamic_cast<const std::ostringstream&> dynamic_cast<const std::ostringstream&>
( (
oss.stream() oss.stdStream()
).str() ).str()
) )
), ),
@ -98,7 +98,7 @@ public:
~OStringStream() ~OStringStream()
{ {
delete &dynamic_cast<std::ostringstream&>(stream()); delete &dynamic_cast<std::ostringstream&>(stdStream());
} }
@ -109,7 +109,10 @@ public:
//- Return the string //- Return the string
string str() const string str() const
{ {
return dynamic_cast<const std::ostringstream&>(stream()).str(); return dynamic_cast<const std::ostringstream&>
(
stdStream()
).str();
} }
@ -119,9 +122,9 @@ public:
void rewind() void rewind()
{ {
# if __GNUC__ < 4 && __GNUC_MINOR__ < 4 # if __GNUC__ < 4 && __GNUC_MINOR__ < 4
stream().rdbuf()->pubsetbuf(" ", 1); stdStream().rdbuf()->pubsetbuf(" ", 1);
# else # else
stream().rdbuf()->pubseekpos(0); stdStream().rdbuf()->pubseekpos(0);
# endif # endif
} }

View File

@ -170,7 +170,7 @@ public:
~OSHA1stream() ~OSHA1stream()
{ {
delete &dynamic_cast<osha1stream&>(stream()); delete &dynamic_cast<osha1stream&>(stdStream());
} }
@ -181,7 +181,7 @@ public:
//- Full access to the sha1 //- Full access to the sha1
Foam::SHA1& sha1() Foam::SHA1& sha1()
{ {
return dynamic_cast<osha1stream&>(stream()).sha1(); return dynamic_cast<osha1stream&>(stdStream()).sha1();
} }
//- Return SHA1::Digest for the data processed until now //- Return SHA1::Digest for the data processed until now

View File

@ -91,7 +91,7 @@ Foam::Ostream& Foam::ensightFile::write
std::streamsize count std::streamsize count
) )
{ {
stream().write(buf, count); stdStream().write(buf, count);
return *this; return *this;
} }
@ -126,7 +126,7 @@ Foam::Ostream& Foam::ensightFile::write(const string& value)
} }
else else
{ {
stream() << buf; stdStream() << buf;
} }
return *this; return *this;
@ -147,8 +147,8 @@ Foam::Ostream& Foam::ensightFile::write(const label value)
} }
else else
{ {
stream().width(10); stdStream().width(10);
stream() << value; stdStream() << value;
} }
return *this; return *this;
@ -173,8 +173,8 @@ Foam::Ostream& Foam::ensightFile::write
} }
else else
{ {
stream().width(fieldWidth); stdStream().width(fieldWidth);
stream() << value; stdStream() << value;
} }
return *this; return *this;
@ -195,8 +195,8 @@ Foam::Ostream& Foam::ensightFile::write(const scalar value)
} }
else else
{ {
stream().width(12); stdStream().width(12);
stream() << value; stdStream() << value;
} }
return *this; return *this;
@ -207,7 +207,7 @@ void Foam::ensightFile::newline()
{ {
if (format() == IOstream::ASCII) if (format() == IOstream::ASCII)
{ {
stream() << nl; stdStream() << nl;
} }
} }