From 438a83fc819f98ce57f687abfd9d1a6e06a5415c Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Mon, 21 Dec 2009 09:28:17 +0100 Subject: [PATCH 1/4] Update experimental dictionary #calc for new Coco pragmas --- .../test/dictionary/calcEntry/SimpleCalc.atg | 3 + .../test/dictionary/calcEntry/build.sh | 2 - .../dictionary/calcEntry/calcEntryParser.cpp | 6 +- .../dictionary/calcEntry/calcEntryParser.h | 5 +- .../dictionary/calcEntry/calcEntryScanner.cpp | 499 +++++++++++------- .../dictionary/calcEntry/calcEntryScanner.h | 195 ++++--- applications/test/dictionary/testDict | 1 - applications/test/dictionary/testDictCalc | 2 +- 8 files changed, 421 insertions(+), 292 deletions(-) diff --git a/applications/test/dictionary/calcEntry/SimpleCalc.atg b/applications/test/dictionary/calcEntry/SimpleCalc.atg index cdc84cd0c9..57e41ed407 100644 --- a/applications/test/dictionary/calcEntry/SimpleCalc.atg +++ b/applications/test/dictionary/calcEntry/SimpleCalc.atg @@ -14,6 +14,9 @@ COMPILER SimpleCalc +$prefix=calcEntry +$namespace=Foam::functionEntries::calcEntryInternal + // Simple four function calculator for OpenFOAM dictionaries //! with debug diff --git a/applications/test/dictionary/calcEntry/build.sh b/applications/test/dictionary/calcEntry/build.sh index 4bbaf0eeaf..f13e716d92 100755 --- a/applications/test/dictionary/calcEntry/build.sh +++ b/applications/test/dictionary/calcEntry/build.sh @@ -5,7 +5,5 @@ cd ${0%/*} || exit 1 # run from this directory Coco \ -frames $WM_THIRD_PARTY_DIR/coco-r \ - -prefix calcEntry \ - -namespace Foam::functionEntries::calcEntryInternal \ SimpleCalc.atg diff --git a/applications/test/dictionary/calcEntry/calcEntryParser.cpp b/applications/test/dictionary/calcEntry/calcEntryParser.cpp index 412a00c52f..421d8ba7fa 100644 --- a/applications/test/dictionary/calcEntry/calcEntryParser.cpp +++ b/applications/test/dictionary/calcEntry/calcEntryParser.cpp @@ -199,14 +199,12 @@ 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(); @@ -317,8 +315,12 @@ void Errors::Exception(const wchar_t* msg) { ::exit(1); } + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + } // namespace } // namespace } // namespace +// ************************************************************************* // diff --git a/applications/test/dictionary/calcEntry/calcEntryParser.h b/applications/test/dictionary/calcEntry/calcEntryParser.h index d3da4d05fc..66b30a10ff 100644 --- a/applications/test/dictionary/calcEntry/calcEntryParser.h +++ b/applications/test/dictionary/calcEntry/calcEntryParser.h @@ -55,11 +55,12 @@ private: _variable=3, _number=4, }; - int maxT; + static const int maxT = 13; + + static const int minErrDist = 2; //!< min. distance before reporting errors Token *dummyToken; bool deleteErrorsDestruct_; //!< delete the 'errors' member in destructor - int minErrDist; int errDist; void SynErr(int n); //!< Handle syntax error 'n' diff --git a/applications/test/dictionary/calcEntry/calcEntryScanner.cpp b/applications/test/dictionary/calcEntry/calcEntryScanner.cpp index 86a92d3233..ab0d7b78d3 100644 --- a/applications/test/dictionary/calcEntry/calcEntryScanner.cpp +++ b/applications/test/dictionary/calcEntry/calcEntryScanner.cpp @@ -1,9 +1,16 @@ -#include -#include +#include + #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 functionEntries { namespace calcEntryInternal { @@ -36,29 +43,6 @@ wchar_t* coco_string_create(const wchar_t* str, int index, int length) { 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; } @@ -178,7 +162,7 @@ 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[i] = wchar_t(str[i]); } dest[len] = 0; return dest; @@ -188,7 +172,7 @@ 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[i] = wchar_t(str[index + i]); } dest[len] = 0; return dest; @@ -200,7 +184,7 @@ char* coco_string_create_char(const wchar_t* str) { char *dest = new char[len + 1]; for (int i = 0; i < len; ++i) { - dest[i] = (char) str[i]; + dest[i] = char(str[i]); } dest[len] = 0; 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]; for (int i = 0; i < len; ++i) { - dest[i] = (char) str[index + i]; + dest[i] = char(str[index + i]); } dest[len] = 0; 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() { 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 #if _MSC_VER >= 1300 - _setmode(_fileno(s), _O_BINARY); + _setmode(_fileno(cStream), _O_BINARY); #endif - stream = s; this->isUserStream = isUserStream; + if (CanSeek()) { - fseek(s, 0, SEEK_END); - fileLen = ftell(s); - fseek(s, 0, SEEK_SET); + fseek(cStream, 0, SEEK_END); + fileLen = ftell(cStream); + fseek(cStream, 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) @@ -280,45 +298,74 @@ Buffer::Buffer(FILE* s, bool isUserStream) { } -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(std::istream* istr, bool isUserStream) +: + buf(NULL), + bufCapacity(0), + bufLen(0), + bufPos(0), + bufStart(0), + fileLen(0), + cStream(NULL), + stdStream(istr), + isUserStream_(isUserStream) +{ + // ensure binary read on windows +#if _MSC_VER >= 1300 + // TODO +#endif } -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(std::string& str) +: + buf(NULL), + bufCapacity(0), + bufLen(0), + bufPos(0), + bufStart(0), + 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) { - 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* 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() { Close(); - if (buf != NULL) { + if (buf) { delete [] buf; buf = NULL; } @@ -326,20 +373,36 @@ Buffer::~Buffer() { void Buffer::Close() { - if (!isUserStream && stream != NULL) { - fclose(stream); - stream = NULL; + if (!isUserStream_) { + if (cStream) { + fclose(cStream); + cStream = NULL; + } + else if (stdStream) { + delete stdStream; + stdStream = 0; + } } } int Buffer::Read() { + if (stdStream) + { + int ch = stdStream->get(); + if (stdStream->eof()) + { + return EoF; + } + return ch; + } + 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)) { + } else if (cStream && !CanSeek() && (ReadNextStreamChunk() > 0)) { return buf[bufPos++]; } else { 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 ch; do { @@ -464,42 +442,143 @@ int UTF8Buffer::Read() { } -Scanner::Scanner(const unsigned char* buf, int len) { - buffer = new Buffer(buf, len); +int Buffer::Peek() { + 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(); } -Scanner::Scanner(const char* buf, int len) { - buffer = new Buffer(buf, len); +Scanner::Scanner(std::istream& istr) +: + buffer(new Buffer(&istr, true)) +{ Init(); } Scanner::Scanner(const wchar_t* fileName) { - FILE* stream; 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); ::exit(1); } coco_string_delete(chFileName); - buffer = new Buffer(stream, false); + buffer = new Buffer(istr, false); Init(); } -Scanner::Scanner(FILE* s) { - buffer = new Buffer(s, true); +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() { - char* cur = (char*) firstHeap; + char* cur = reinterpret_cast(firstHeap); - while (cur != NULL) { - cur = *(char**) (cur + HEAP_BLOCK_SIZE); + while (cur) { + cur = *(reinterpret_cast(cur + HEAP_BLOCK_SIZE)); free(firstHeap); firstHeap = cur; } @@ -509,14 +588,11 @@ Scanner::~Scanner() { 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); + for (int i = 65; i <= 90; ++i) start.set(i, 1); + for (int i = 97; i <= 122; ++i) start.set(i, 1); + for (int i = 36; i <= 36; ++i) start.set(i, 5); 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(46, 7); start.set(123, 14); @@ -526,7 +602,8 @@ void Scanner::Init() { start.set(47, 17); start.set(40, 18); start.set(41, 19); - start.set(Buffer::EoF, -1); + start.set(Buffer::EoF, -1); + tvalLength = 128; @@ -535,7 +612,9 @@ void Scanner::Init() { // 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 = + reinterpret_cast + (reinterpret_cast(heap) + HEAP_BLOCK_SIZE); *heapEnd = 0; heapTop = heap; if (sizeof(Token) > HEAP_BLOCK_SIZE) { @@ -645,19 +724,25 @@ bool Scanner::Comment1() { void Scanner::CreateHeapBlock() { - void* newHeap; - char* cur = (char*) firstHeap; + char* cur = reinterpret_cast(firstHeap); - while (((char*) tokens < cur) || ((char*) tokens > (cur + HEAP_BLOCK_SIZE))) { - cur = *((char**) (cur + HEAP_BLOCK_SIZE)); + // release unused blocks + while + ( + (reinterpret_cast(tokens) < cur) + || (reinterpret_cast(tokens) > (cur + HEAP_BLOCK_SIZE)) + ) { + cur = *(reinterpret_cast(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*)); + void* newHeap = malloc(HEAP_BLOCK_SIZE + sizeof(void*)); *heapEnd = newHeap; - heapEnd = (void**) (((char*) newHeap) + HEAP_BLOCK_SIZE); + heapEnd = + reinterpret_cast + (reinterpret_cast(newHeap) + HEAP_BLOCK_SIZE); *heapEnd = 0; heap = newHeap; heapTop = heap; @@ -665,32 +750,51 @@ void Scanner::CreateHeapBlock() { Token* Scanner::CreateToken() { - Token *t; - if (((char*) heapTop + (int) sizeof(Token)) >= (char*) heapEnd) { + const int reqMem = sizeof(Token); + if + ( + (reinterpret_cast(heapTop) + reqMem) + >= reinterpret_cast(heapEnd) + ) { CreateHeapBlock(); } - t = (Token*) heapTop; - heapTop = (void*) ((char*) heapTop + sizeof(Token)); - t->val = NULL; - t->next = NULL; - return t; + // token 'occupies' heap starting at heapTop + Token* tok = reinterpret_cast(heapTop); + // increment past this part of the heap, which is now used + heapTop = + reinterpret_cast + (reinterpret_cast(heapTop) + reqMem); + tok->val = NULL; + tok->next = NULL; + return tok; } -void Scanner::AppendVal(Token *t) { - int reqMem = (tlen + 1) * sizeof(wchar_t); - if (((char*) heapTop + reqMem) >= (char*) heapEnd) { +void Scanner::AppendVal(Token* tok) { + const int reqMem = (tlen + 1) * sizeof(wchar_t); + if + ( + (reinterpret_cast(heapTop) + reqMem) + >= reinterpret_cast(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'; + // add text value from heap + tok->val = reinterpret_cast(heapTop); + + // increment past this part of the heap, which is now used + heapTop = + reinterpret_cast + (reinterpret_cast(heapTop) + reqMem); + + // copy the currently parsed tval into the token + wcsncpy(tok->val, tval, tlen); + tok->val[tlen] = L'\0'; } @@ -818,8 +922,11 @@ void Scanner::ResetPeek() { } +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + } // namespace } // namespace } // namespace +// ************************************************************************* // diff --git a/applications/test/dictionary/calcEntry/calcEntryScanner.h b/applications/test/dictionary/calcEntry/calcEntryScanner.h index 8847c9fd2e..fdebddeebe 100644 --- a/applications/test/dictionary/calcEntry/calcEntryScanner.h +++ b/applications/test/dictionary/calcEntry/calcEntryScanner.h @@ -3,11 +3,14 @@ #ifndef COCO_calcEntrySCANNER_H__ #define COCO_calcEntrySCANNER_H__ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include // io.h and fcntl are used to ensure binary read from streams on windows #if _MSC_VER >= 1300 @@ -24,10 +27,8 @@ #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 { @@ -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 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); @@ -138,7 +133,6 @@ float coco_string_toFloat(const char* str); // * * * * * * * * * End of Wide Character String Routines * * * * * * * * * // - //! Scanner Token class Token { @@ -151,7 +145,7 @@ public: Token *next; //!< Peek tokens are kept in linked list Token(); //!< Construct null - ~Token(); //!< Destructor - cleanup allocated val + ~Token(); //!< Destructor - cleanup allocated val?? }; @@ -166,30 +160,48 @@ 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 bufStart; //!< position of first byte in buffer relative to input stream + 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(); - 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: 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*); + //! Attach buffer to a stdio stream. + //! User streams are not closed in the destructor + Buffer(FILE*, bool isUserStream = true); + + //! 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 void Close(); - virtual int Read(); - virtual int Peek(); - virtual wchar_t* GetString(int beg, int end); - virtual int GetPos(); + virtual void Close(); //!< Close stream (but not user streams) + virtual int Read(); //!< Get character from stream or buffer + virtual int Peek(); //!< Peek character from stream or buffer + + virtual int GetPos() const; virtual void SetPos(int value); }; @@ -205,31 +217,31 @@ public: //------------------------------------------------------------------------------ // StartStates //------------------------------------------------------------------------------ -//! maps characters to start states of tokens +//! maps characters (integers) 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(int k, int v) : + key(k), val(v), next(0) + {} }; Elem **tab; public: - StartStates() { - tab = new Elem*[128]; + 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) { + while (e) { Elem *next = e->next; delete e; e = next; @@ -240,15 +252,15 @@ public: void set(int key, int val) { Elem *e = new Elem(key, val); - int k = ((unsigned int) key) % 128; + int k = unsigned(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; + Elem *e = tab[unsigned(key) % 128]; + while (e && e->key != key) e = e->next; + return e ? e->val : 0; } }; @@ -264,11 +276,9 @@ private: 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; - } + Elem(const wchar_t *k, int v) : + key(coco_string_create(k)), val(v), next(0) + {} virtual ~Elem() { coco_string_delete(key); } @@ -277,14 +287,16 @@ private: Elem **tab; public: - KeywordMap() { - tab = new Elem*[128]; + 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) { + while (e) { Elem *next = e->next; delete e; e = next; @@ -295,14 +307,15 @@ public: 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; + const 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; + while (e && !coco_string_equal(e->key, key)) e = e->next; + return e ? e->val : defaultVal; } }; @@ -310,24 +323,24 @@ public: //! 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 + static const int maxT = 13; + static const int noSym = 13; - void *firstHeap; - void *heap; - void *heapTop; - void **heapEnd; + static const int eofSym = 0; //!< end-of-file token id + static const char EOL = '\n'; //!< end-of-line character - int noSym; //!< noSym gets highest number, set in Parser - int maxT; - int charSetSize; //!< unused? - StartStates start; - KeywordMap keywords; + void *firstHeap; //!< the start of the heap management + void *heap; //!< the currently active block + void *heapTop; //!< the top of the heap + void **heapEnd; //!< the end of the last heap block + + StartStates start; //!< A map of start states for particular characters + KeywordMap keywords; //!< A hash of keyword literals to token kind 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 + int tvalLength; //!< maximum capacity (length) for tval + int tlen; //!< length of tval Token *tokens; //!< list of tokens already peeked (first token is a dummy) Token *pt; //!< current peek token @@ -337,36 +350,42 @@ private: 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; + int oldEols; //!< the number of EOLs that appeared in a comment - void CreateHeapBlock(); - Token* CreateToken(); - void AppendVal(Token*); + void CreateHeapBlock(); //!< add a heap block, freeing unused ones + Token* CreateToken(); //!< fit token on the heap + void AppendVal(Token* tok); //!< adjust tok->val to point to the heap and copy tval into it - void Init(); - void NextCh(); - void AddCh(); + void Init(); //!< complete the initialization for the constructors + void NextCh(); //!< get the next input character into ch + void AddCh(); //!< append the character ch to tval bool Comment0(); bool Comment1(); - Token* NextToken(); + Token* NextToken(); //!< get the next token public: - //! scanner buffer + //! The 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(); + Scanner(FILE*); + + //! Using an existing open STL std stream + explicit Scanner(std::istream&); + + //! 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 diff --git a/applications/test/dictionary/testDict b/applications/test/dictionary/testDict index 42a473a52b..8c9e672e7b 100644 --- a/applications/test/dictionary/testDict +++ b/applications/test/dictionary/testDict @@ -67,7 +67,6 @@ boundaryField // error #remove self; x 5; y 6; - another #calc{x $x; y $y;}; } // this should have no effect diff --git a/applications/test/dictionary/testDictCalc b/applications/test/dictionary/testDictCalc index cfce0e0b52..134a8daaa8 100644 --- a/applications/test/dictionary/testDictCalc +++ b/applications/test/dictionary/testDictCalc @@ -26,7 +26,7 @@ y 20; // + 1 /*100 */ 10 // }; -p #test{ 1 + 2 + 10 * 15 + $x - $y }; +p #calc{ 1 + 2 + 10 * 15 + $x - $y }; foo 30; From 27926249969c7d16a0b552df295636f3ae9e7001 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Mon, 21 Dec 2009 10:24:35 +0100 Subject: [PATCH 2/4] Expose STL std streams in a consistent manner for serial streams. Previously Fstreams had stdStream() as a public member and the other streams had stream() as a protected member. All serial streams now have public method stdStream() and the stream() method has been eliminated. This is not only more consistent, but also avoids confusion (for the programmer, not the compiler) with the ITstream::stream() method. --- src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C | 33 +++++++++++------ src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H | 22 ++++++------ src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C | 35 ++++++++++++------- src/OpenFOAM/db/IOstreams/Fstreams/OFstream.H | 22 ++++++------ src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C | 2 +- src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H | 32 ++++++++--------- src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H | 30 ++++++++-------- .../IOstreams/StringStreams/IStringStream.H | 7 ++-- .../IOstreams/StringStreams/OStringStream.H | 13 ++++--- .../db/IOstreams/hashes/OSHA1stream.H | 4 +-- src/conversion/ensight/file/ensightFile.C | 18 +++++----- 11 files changed, 124 insertions(+), 94 deletions(-) diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C index 68fe61ce2c..33f243541a 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C +++ b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C @@ -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 * * * * * * * * * * * * * * // Foam::IFstream::IFstream @@ -143,6 +132,28 @@ Foam::IFstream::~IFstream() // * * * * * * * * * * * * * * * 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 { // Print File data diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H index 791e94df9e..ebe163f445 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H +++ b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H @@ -51,7 +51,7 @@ namespace Foam class IFstream; /*---------------------------------------------------------------------------*\ - Class IFstreamAllocator Declaration + Class IFstreamAllocator Declaration \*---------------------------------------------------------------------------*/ //- A std::istream with ability to handle compressed files @@ -74,19 +74,11 @@ class IFstreamAllocator // Destructor ~IFstreamAllocator(); - - -public: - - // Member functions - - //- Access to underlying std::istream (for e.g. lexer) - istream& stdStream(); }; /*---------------------------------------------------------------------------*\ - Class IFstream Declaration + Class IFstream Declaration \*---------------------------------------------------------------------------*/ class IFstream @@ -136,6 +128,16 @@ public: 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 description of IOstream to Ostream diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C index 27dc86436b..16946d7d5b 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C +++ b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C @@ -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 * * * * * * * * * * * * * * // Foam::OFstream::OFstream @@ -131,7 +120,7 @@ Foam::OFstream::OFstream } -// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * // +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // Foam::OFstream::~OFstream() {} @@ -139,6 +128,28 @@ Foam::OFstream::~OFstream() // * * * * * * * * * * * * * * * 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 { os << " OFstream: "; diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.H b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.H index 7ad2ebd88a..19654ca35e 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.H +++ b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.H @@ -51,7 +51,7 @@ namespace Foam class OFstream; /*---------------------------------------------------------------------------*\ - Class OFstreamAllocator Declaration + Class OFstreamAllocator Declaration \*---------------------------------------------------------------------------*/ //- A std::ostream with ability to handle compressed files @@ -74,18 +74,11 @@ class OFstreamAllocator ~OFstreamAllocator(); - -public: - - // Member functions - - //- Access to underlying std::ostream - ostream& stdStream(); }; /*---------------------------------------------------------------------------*\ - Class OFstream Declaration + Class OFstream Declaration \*---------------------------------------------------------------------------*/ 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 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; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C index d98d75d076..76ec06dc5d 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C +++ b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C @@ -551,7 +551,7 @@ Foam::Istream& Foam::ISstream::read(char* buf, std::streamsize count) Foam::Istream& Foam::ISstream::rewind() { - stream().rdbuf()->pubseekpos(0); + stdStream().rdbuf()->pubseekpos(0); return *this; } diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H index 0c6bc9d44b..814d6a3af1 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H +++ b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H @@ -72,23 +72,6 @@ class 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: // Constructors @@ -185,6 +168,21 @@ public: 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 description of IOstream to Ostream diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H index 5c862afd93..c41cf46d77 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H +++ b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H @@ -67,21 +67,6 @@ class 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: // Constructors @@ -187,6 +172,21 @@ public: 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 description of IOstream to Ostream diff --git a/src/OpenFOAM/db/IOstreams/StringStreams/IStringStream.H b/src/OpenFOAM/db/IOstreams/StringStreams/IStringStream.H index d7e9995e9b..5b242537e5 100644 --- a/src/OpenFOAM/db/IOstreams/StringStreams/IStringStream.H +++ b/src/OpenFOAM/db/IOstreams/StringStreams/IStringStream.H @@ -97,7 +97,7 @@ public: ~IStringStream() { - delete &dynamic_cast(stream()); + delete &dynamic_cast(stdStream()); } @@ -108,7 +108,10 @@ public: //- Return the string string str() const { - return dynamic_cast(stream()).str(); + return dynamic_cast + ( + stdStream() + ).str(); } diff --git a/src/OpenFOAM/db/IOstreams/StringStreams/OStringStream.H b/src/OpenFOAM/db/IOstreams/StringStreams/OStringStream.H index 8f76748292..9336daa02c 100644 --- a/src/OpenFOAM/db/IOstreams/StringStreams/OStringStream.H +++ b/src/OpenFOAM/db/IOstreams/StringStreams/OStringStream.H @@ -83,7 +83,7 @@ public: ( dynamic_cast ( - oss.stream() + oss.stdStream() ).str() ) ), @@ -98,7 +98,7 @@ public: ~OStringStream() { - delete &dynamic_cast(stream()); + delete &dynamic_cast(stdStream()); } @@ -109,7 +109,10 @@ public: //- Return the string string str() const { - return dynamic_cast(stream()).str(); + return dynamic_cast + ( + stdStream() + ).str(); } @@ -119,9 +122,9 @@ public: void rewind() { # if __GNUC__ < 4 && __GNUC_MINOR__ < 4 - stream().rdbuf()->pubsetbuf(" ", 1); + stdStream().rdbuf()->pubsetbuf(" ", 1); # else - stream().rdbuf()->pubseekpos(0); + stdStream().rdbuf()->pubseekpos(0); # endif } diff --git a/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H b/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H index 00b72fd7bf..7bc2d8abbd 100644 --- a/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H +++ b/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H @@ -170,7 +170,7 @@ public: ~OSHA1stream() { - delete &dynamic_cast(stream()); + delete &dynamic_cast(stdStream()); } @@ -181,7 +181,7 @@ public: //- Full access to the sha1 Foam::SHA1& sha1() { - return dynamic_cast(stream()).sha1(); + return dynamic_cast(stdStream()).sha1(); } //- Return SHA1::Digest for the data processed until now diff --git a/src/conversion/ensight/file/ensightFile.C b/src/conversion/ensight/file/ensightFile.C index 095d2659f8..af0ad554e8 100644 --- a/src/conversion/ensight/file/ensightFile.C +++ b/src/conversion/ensight/file/ensightFile.C @@ -91,7 +91,7 @@ Foam::Ostream& Foam::ensightFile::write std::streamsize count ) { - stream().write(buf, count); + stdStream().write(buf, count); return *this; } @@ -126,7 +126,7 @@ Foam::Ostream& Foam::ensightFile::write(const string& value) } else { - stream() << buf; + stdStream() << buf; } return *this; @@ -147,8 +147,8 @@ Foam::Ostream& Foam::ensightFile::write(const label value) } else { - stream().width(10); - stream() << value; + stdStream().width(10); + stdStream() << value; } return *this; @@ -173,8 +173,8 @@ Foam::Ostream& Foam::ensightFile::write } else { - stream().width(fieldWidth); - stream() << value; + stdStream().width(fieldWidth); + stdStream() << value; } return *this; @@ -195,8 +195,8 @@ Foam::Ostream& Foam::ensightFile::write(const scalar value) } else { - stream().width(12); - stream() << value; + stdStream().width(12); + stdStream() << value; } return *this; @@ -207,7 +207,7 @@ void Foam::ensightFile::newline() { if (format() == IOstream::ASCII) { - stream() << nl; + stdStream() << nl; } } From ccdbf4735fe16dc8ea639e829d612db687dca24c Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Mon, 21 Dec 2009 14:14:30 +0100 Subject: [PATCH 3/4] Move CocoParserErrors.H template class into src/OpenFOAM/db/error --- .../calcEntry => src/OpenFOAM/db/error}/CocoParserErrors.H | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {applications/test/dictionary/calcEntry => src/OpenFOAM/db/error}/CocoParserErrors.H (100%) diff --git a/applications/test/dictionary/calcEntry/CocoParserErrors.H b/src/OpenFOAM/db/error/CocoParserErrors.H similarity index 100% rename from applications/test/dictionary/calcEntry/CocoParserErrors.H rename to src/OpenFOAM/db/error/CocoParserErrors.H From 8bf3807c3e1b6c18d21d1aa1cab99c9b6c5d0837 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Mon, 21 Dec 2009 15:02:33 +0100 Subject: [PATCH 4/4] Update dictionary calcEntry testing for updated CoCo/R --- applications/test/dictionary/Allwmake | 15 +++ .../test/dictionary/calcEntry/build.sh | 9 -- .../test/dictionary/calcEntry/calcEntry.C | 108 ++---------------- .../{SimpleCalc.atg => calcEntry.atg} | 86 +++++++++----- .../dictionary/calcEntry/calcEntryParser.cpp | 53 +++++---- .../dictionary/calcEntry/calcEntryParser.h | 27 +++-- .../dictionary/calcEntry/calcEntryScanner.cpp | 2 +- applications/test/dictionary/testDictCalc | 19 ++- 8 files changed, 149 insertions(+), 170 deletions(-) create mode 100755 applications/test/dictionary/Allwmake delete mode 100755 applications/test/dictionary/calcEntry/build.sh rename applications/test/dictionary/calcEntry/{SimpleCalc.atg => calcEntry.atg} (67%) diff --git a/applications/test/dictionary/Allwmake b/applications/test/dictionary/Allwmake new file mode 100755 index 0000000000..fcf297dc89 --- /dev/null +++ b/applications/test/dictionary/Allwmake @@ -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 diff --git a/applications/test/dictionary/calcEntry/build.sh b/applications/test/dictionary/calcEntry/build.sh deleted file mode 100755 index f13e716d92..0000000000 --- a/applications/test/dictionary/calcEntry/build.sh +++ /dev/null @@ -1,9 +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 \ - SimpleCalc.atg - diff --git a/applications/test/dictionary/calcEntry/calcEntry.C b/applications/test/dictionary/calcEntry/calcEntry.C index ccfc68b702..9810812308 100644 --- a/applications/test/dictionary/calcEntry/calcEntry.C +++ b/applications/test/dictionary/calcEntry/calcEntry.C @@ -26,8 +26,6 @@ License #include "calcEntry.H" #include "dictionary.H" -#include "IStringStream.H" -#include "OStringStream.H" #include "addToMemberFunctionSelectionTable.H" #include "ISstream.H" @@ -60,121 +58,33 @@ bool Foam::functionEntries::calcEntry::execute ( const dictionary& parentDict, primitiveEntry& entry, - Istream& istr + Istream& is ) { - static const int maxLen = 1024; - static const int errLen = 80; // truncate error message for readability - static char buf[maxLen]; - - ISstream& is = dynamicCast(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; - + std::istream& iss = dynamicCast(is).stdStream(); // define parser error handler CocoParserErrors - myErrorHandler("calcEntry::Parser--"); + myErrorHandler("calcEntryInternal::Parser"); - calcEntryInternal::Scanner scanner(buf, nChar); + calcEntryInternal::Scanner scanner(iss); calcEntryInternal::Parser parser(&scanner, &myErrorHandler); // Attach dictionary context parser.dict(parentDict); + // Attach scalar functions + // parser.functions(parentDict); + parser.Parse(); -// Info<<"got: " << parser.Result() << endl; - + // make a small input list to contain the answer tokenList tokens(2); tokens[0] = parser.Result(); tokens[1] = token::END_STATEMENT; -// Info<<"tokens[0] = " << tokens[0].info() < scalar scalar getScalar() const { @@ -43,11 +46,11 @@ $namespace=Foam::functionEntries::calcEntryInternal return s; } - //! attach a dictionary - void dict(const dictionary& dict) const + void dict(const dictionary& dict) { dict_ = const_cast(&dict); + hasDict_ = true; } @@ -56,11 +59,11 @@ $namespace=Foam::functionEntries::calcEntryInternal { scalar dictValue = 0; - if (!dict_) + if (!hasDict_) { FatalErrorIn ( - "SimpleCalc::getDictEntry() const" + "calcEntry::getDictEntry() const" ) << "No dictionary attached!" << exit(FatalError); @@ -84,13 +87,22 @@ $namespace=Foam::functionEntries::calcEntryInternal entry* entryPtr = dict_->lookupEntryPtr(keyword, true, false); 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; } else { FatalErrorIn ( - "SimpleCalc::getDictEntry() const" + "calcEntry::getDictEntry() const" ) << "keyword " << keyword << " is undefined in dictionary " << exit(FatalError); } @@ -105,7 +117,7 @@ $namespace=Foam::functionEntries::calcEntryInternal } -// * * * * * * * * * * * * * * * CHARACTERS * * * * * * * * * * * * * * * * // +/*---------------------------------------------------------------------------*/ CHARACTERS letter = 'A'..'Z' + 'a'..'z'. @@ -148,38 +160,49 @@ number = COMMENTS FROM "/*" TO "*/" NESTED COMMENTS FROM "//" TO lf -// ignore unprintables -IGNORE ANY - printable +IGNORE cr + lf + tab // * * * * * * * * * * * * * * * PRODUCTIONS * * * * * * * * * * * * * * * // PRODUCTIONS -SimpleCalc (. val = 0; - if (debug){Info<<"start val"<< nl;} +calcEntry (. val = 0; + if (debug){Info<<"start val pos:"<< t->pos << nl;} .) = - ( '{' Expr '}' | Expr ) - EOF + '{' Expr '}' (. + 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 EOF ) . /*---------------------------------------------------------------------------*/ Expr (. scalar val2 = 0; - if (debug) {Info<<"Expr:"<< val<< nl;} + if (debug) {Info<<"Expr:"<< val<< " pos:"<< t->pos << nl;} .) = Term { - "+" Term (. if (debug) {Info<<"+Term:"< (. if (debug) {Info<<"+Term:"<pos << nl;} val += val2; - if (debug) {Info<<"="<< val << nl;} + if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;} .) - | "-" Term (. if (debug) {Info<<"-Term:"< (. if (debug) {Info<<"-Term:"<pos << nl;} val -= val2; - if (debug) {Info<<"="<< val << nl;} + if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;} .) } . @@ -188,18 +211,18 @@ Expr (. scalar val2 = 0; /*---------------------------------------------------------------------------*/ Term (. scalar val2 = 0; - if (debug) {Info<<"Term:"<< val<< nl;} + if (debug) {Info<<"Term:"<< val<< " pos:"<< t->pos << nl;} .) = Factor { - "*" Factor (. if (debug) {Info<<"*Factor:"< (. if (debug) {Info<<"*Factor:"<pos << nl;} val *= val2; - if (debug) {Info<<"="<< val << nl; } + if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;} .) - | "/" Factor (. if (debug) {Info<<"/Factor:"< (. if (debug) {Info<<"/Factor:"<pos << nl;} val /= val2; - if (debug) {Info<<"="<< val << nl; } + if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;} .) } . @@ -209,20 +232,21 @@ Term (. scalar val2 = 0; Factor = variable (. val = getDictLookup(); - if (debug) {Info<<"lookup:"<pos << nl;} .) | number (. val = getScalar(); - if (debug) {Info<<"got num:"<pos << nl;} .) | '-' '(' Expr ')' (. val = -val; - if (debug) {Info<<"inv:"<pos << nl;} + .) + | '(' Expr ')' (. if (debug){Info<<"got Expr:"<pos << nl;} .) - | '(' Expr ')' (. if (debug){Info<<"got Expr:"<pos << nl;} if (la->kind == 5) { Get(); Expr(val); 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)) { Expr(val); + Expect(0); } else SynErr(14); - Expect(0); } void Parser::Expr(scalar& val) { scalar val2 = 0; - if (debug) {Info<<"Expr:"<< val<< nl;} + if (debug) {Info<<"Expr:"<< val<< " pos:"<< t->pos << nl;} Term(val); while (la->kind == 7 || la->kind == 8) { if (la->kind == 7) { Get(); Term(val2); - if (debug) {Info<<"+Term:"<pos << nl;} val += val2; - if (debug) {Info<<"="<< val << nl;} + if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;} } else { Get(); Term(val2); - if (debug) {Info<<"-Term:"<pos << nl;} 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) { scalar val2 = 0; - if (debug) {Info<<"Term:"<< val<< nl;} + if (debug) {Info<<"Term:"<< val<< " pos:"<< t->pos << nl;} Factor(val); while (la->kind == 9 || la->kind == 10) { if (la->kind == 9) { Get(); Factor(val2); - if (debug) {Info<<"*Factor:"<pos << nl;} val *= val2; - if (debug) {Info<<"="<< val << nl; } + if (debug) {Info<<"="<< val<< " pos:"<< t->pos << nl;} } else { Get(); Factor(val2); - if (debug) {Info<<"/Factor:"<pos << nl;} 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) { Get(); val = getDictLookup(); - if (debug) {Info<<"lookup:"<pos << nl;} } else if (la->kind == 4) { Get(); val = getScalar(); - if (debug) {Info<<"got num:"<pos << nl;} } else if (la->kind == 8) { Get(); @@ -169,13 +181,14 @@ void Parser::Factor(scalar& val) { Expr(val); Expect(12); val = -val; - if (debug) {Info<<"inv:"<pos << nl;} } else if (la->kind == 11) { Get(); Expr(val); Expect(12); - if (debug){Info<<"got Expr:"<pos << nl;} + } else SynErr(15); } @@ -189,9 +202,9 @@ void Parser::Parse() { la = dummyToken = new Token(); la->val = coco_string_create(L"Dummy Token"); Get(); - SimpleCalc(); + calcEntry(); + // let grammar deal with end-of-file expectations - Expect(0); } @@ -272,7 +285,7 @@ wchar_t* Errors::strerror(int n) 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 14: s = coco_string_create(L"invalid calcEntry"); break; case 15: s = coco_string_create(L"invalid Factor"); break; default: diff --git a/applications/test/dictionary/calcEntry/calcEntryParser.h b/applications/test/dictionary/calcEntry/calcEntryParser.h index 66b30a10ff..de12a3961e 100644 --- a/applications/test/dictionary/calcEntry/calcEntryParser.h +++ b/applications/test/dictionary/calcEntry/calcEntryParser.h @@ -82,9 +82,13 @@ static const int debug = 0; //! The parent dictionary mutable dictionary* dict_; + //! Track that parent dictionary was set + bool hasDict_; + //! The calculation result scalar val; + //! token -> scalar scalar getScalar() const { @@ -100,11 +104,11 @@ static const int debug = 0; return s; } - //! attach a dictionary - void dict(const dictionary& dict) const + void dict(const dictionary& dict) { dict_ = const_cast(&dict); + hasDict_ = true; } @@ -113,11 +117,11 @@ static const int debug = 0; { scalar dictValue = 0; - if (!dict_) + if (!hasDict_) { FatalErrorIn ( - "SimpleCalc::getDictEntry() const" + "calcEntry::getDictEntry() const" ) << "No dictionary attached!" << exit(FatalError); @@ -141,13 +145,22 @@ static const int debug = 0; entry* entryPtr = dict_->lookupEntryPtr(keyword, true, false); 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; } else { FatalErrorIn ( - "SimpleCalc::getDictEntry() const" + "calcEntry::getDictEntry() const" ) << "keyword " << keyword << " is undefined in dictionary " << exit(FatalError); } @@ -162,7 +175,7 @@ static const int debug = 0; } -// * * * * * * * * * * * * * * * CHARACTERS * * * * * * * * * * * * * * * * // +/*---------------------------------------------------------------------------*/ @@ -175,7 +188,7 @@ static const int debug = 0; ~Parser(); //!< Destructor - cleanup errors and dummyToken void SemErr(const wchar_t* msg); //!< Handle semantic error - void SimpleCalc(); + void calcEntry(); void Expr(scalar& val); void Term(scalar& val); void Factor(scalar& val); diff --git a/applications/test/dictionary/calcEntry/calcEntryScanner.cpp b/applications/test/dictionary/calcEntry/calcEntryScanner.cpp index ab0d7b78d3..b070bcf3f3 100644 --- a/applications/test/dictionary/calcEntry/calcEntryScanner.cpp +++ b/applications/test/dictionary/calcEntry/calcEntryScanner.cpp @@ -800,7 +800,7 @@ void Scanner::AppendVal(Token* tok) { Token* Scanner::NextToken() { while (ch == ' ' || - ch <= 31 || (ch >= 127 && ch <= 65535) + (ch >= 9 && ch <= 10) || ch == 13 ) NextCh(); if ((ch == L'/' && Comment0()) || (ch == L'/' && Comment1())) return NextToken(); t = CreateToken(); diff --git a/applications/test/dictionary/testDictCalc b/applications/test/dictionary/testDictCalc index 134a8daaa8..f1d67650e8 100644 --- a/applications/test/dictionary/testDictCalc +++ b/applications/test/dictionary/testDictCalc @@ -14,8 +14,11 @@ FoamFile } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -x 10 /* what ever */ 20; +flowRatePerHour 720; + +x 10; y 20; +z t s v; // z #test{ // this // 123 - 456 // // comments // are @@ -26,8 +29,18 @@ y 20; // + 1 /*100 */ 10 // }; -p #calc{ 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; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //