From 8d52910d558b28b3be2332464f2fdb4683c658df Mon Sep 17 00:00:00 2001 From: hama Date: Sat, 4 Apr 2015 13:35:11 +0200 Subject: [PATCH] Refactoring, formatted, common license --- .cproject | 9 +- .gitignore | 6 + .project | 2 +- base/ReByteStorage.cpp | 126 +- base/ReByteStorage.hpp | 68 +- base/ReCharPtrMap.cpp | 18 +- base/ReCharPtrMap.hpp | 29 +- base/ReConfig.cpp | 175 +- base/ReConfig.hpp | 47 +- base/ReConfigurator.hpp | 17 +- base/ReContainer.cpp | 537 ++--- base/ReContainer.hpp | 114 +- base/ReException.cpp | 146 +- base/ReException.hpp | 51 +- base/ReLogger.cpp | 486 +++-- base/ReLogger.hpp | 211 +- base/ReQString.cpp | 238 ++- base/ReQtring.hpp | 55 +- base/ReStringUtil.cpp | 708 +++---- base/ReStringUtil.hpp | 54 +- base/ReTerminator.cpp | 42 +- base/ReTerminator.hpp | 33 +- base/ReTest.cpp | 421 ++-- base/ReTest.hpp | 97 +- base/ReWriter.cpp | 150 +- base/ReWriter.hpp | 82 +- base/rebase.hpp | 13 +- base/testrplexample.cpp | 69 +- cunit/cuReConfig.cpp | 11 +- cunit/cuReContainer.cpp | 11 +- cunit/cuReEnigma.cpp | 11 +- cunit/main.cpp | 13 +- cunit/rplastree_test.cpp | 13 +- cunit/rplbench.cpp | 13 +- cunit/rplbytestorage_test.cpp | 13 +- cunit/rplcharptrmap_test.cpp | 13 +- cunit/rplexception_test.cpp | 13 +- cunit/rpllexer_test.cpp | 13 +- cunit/rplmatrix_test.cpp | 12 +- cunit/rplmfparser_test.cpp | 13 +- cunit/rplqstring_test.cpp | 13 +- cunit/rplsource_test.cpp | 13 +- cunit/rplstring_test.cpp | 13 +- cunit/rplvm_test.cpp | 13 +- cunit/rplwriter_test.cpp | 14 +- expr/ReASClasses.cpp | 1102 ++++++++++ expr/ReASClasses.hpp | 210 ++ expr/ReASTree.cpp | 3723 +++++++++++++++------------------ expr/ReASTree.hpp | 1075 +++++----- expr/ReAsClasses.cpp | 1186 ----------- expr/ReAsClasses.hpp | 214 -- expr/ReLexer.cpp | 1520 +++++++------- expr/ReLexer.hpp | 418 ++-- expr/ReMFParser.cpp | 1920 +++++++++-------- expr/ReMFParser.hpp | 185 +- expr/ReParser.cpp | 164 +- expr/ReParser.hpp | 81 +- expr/ReSource.cpp | 599 +++--- expr/ReSource.hpp | 308 +-- expr/ReVM.cpp | 402 ++-- expr/ReVM.hpp | 160 +- expr/reexpr.hpp | 26 +- math/ReEnigma.cpp | 283 +-- math/ReEnigma.hpp | 96 +- math/ReMatrix.cpp | 580 +++-- math/ReMatrix.hpp | 133 +- math/ReRandom.cpp | 89 +- math/ReRandom.hpp | 40 +- math/remath.hpp | 11 +- net/ReNetConfig.cpp | 13 +- net/ReNetConfig.hpp | 23 +- net/ReTCPClient.cpp | 123 +- net/ReTCPClient.hpp | 98 +- net/ReTCPPeer.cpp | 393 ++-- net/ReTCPPeer.hpp | 125 +- net/ReTCPServer.cpp | 166 +- net/ReTCPServer.hpp | 148 +- net/renet.hpp | 11 +- remodules.hpp | 43 +- static/getsrc.pl | 29 + static/rplstaticlib.cpp | 13 +- static/rplstaticlib.hpp | 13 +- 82 files changed, 9776 insertions(+), 10166 deletions(-) create mode 100644 expr/ReASClasses.cpp create mode 100644 expr/ReASClasses.hpp delete mode 100644 expr/ReAsClasses.cpp delete mode 100644 expr/ReAsClasses.hpp create mode 100644 static/getsrc.pl diff --git a/.cproject b/.cproject index 858efea..427ca30 100644 --- a/.cproject +++ b/.cproject @@ -1,7 +1,5 @@ - - - + @@ -33,6 +31,10 @@ + + + + @@ -48,4 +50,5 @@ + diff --git a/.gitignore b/.gitignore index c597c10..f657ced 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,10 @@ *.pro.user doc/ *.log +*.o +build-rplstatic-Desktop-Debug/ +build-rplstatic-Desktop-Release/ +.cproject +.project +*.pro.user.* diff --git a/.project b/.project index aabb6ff..43d97f6 100644 --- a/.project +++ b/.project @@ -1,6 +1,6 @@ - rplqt + reqt diff --git a/base/ReByteStorage.cpp b/base/ReByteStorage.cpp index 033c048..644c7c2 100644 --- a/base/ReByteStorage.cpp +++ b/base/ReByteStorage.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * ReByteStorage.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * @@ -40,28 +43,26 @@ * @param bufferSize the size of one buffer */ ReByteStorage::ReByteStorage(int bufferSize) : - m_bufferSize(bufferSize), - m_buffer(NULL), - m_rest(0), - m_freePosition(NULL), - m_summarySize(0), - m_buffers(0) -{ + m_bufferSize(bufferSize), + m_buffer(NULL), + m_rest(0), + m_freePosition(NULL), + m_summarySize(0), + m_buffers(0){ } /** * @brief Destructor. */ -ReByteStorage::~ReByteStorage() -{ - const uint8_t* ptr = m_buffer; - while(ptr != NULL){ - const uint8_t* old = ptr; - ptr = *(const uint8_t**)(ptr); - delete[] old; - m_buffers--; - } - assert(m_buffers == 0); +ReByteStorage::~ReByteStorage(){ + const uint8_t* ptr = m_buffer; + while (ptr != NULL){ + const uint8_t* old = ptr; + ptr = *(const uint8_t**) (ptr); + delete[] old; + m_buffers--; + } + assert(m_buffers == 0); } /** @@ -76,20 +77,19 @@ ReByteStorage::~ReByteStorage() * @param size of the new block (inclusive the trailing '\0') * @return a new block with the size bytes */ -char* ReByteStorage::allocBuffer(int size) -{ - m_rest = size + sizeof(uint8_t*) <= (size_t) m_bufferSize - ? m_bufferSize : size + sizeof(uint8_t*); - m_summarySize += m_rest; - m_buffers++; - uint8_t* rc = new uint8_t[m_rest]; - * (uint8_t**)rc = m_buffer; - m_buffer = rc; - rc += sizeof(uint8_t*); - // the block allocation will be done outside! - m_freePosition = rc; - m_rest -= sizeof(uint8_t*); - return reinterpret_cast(rc); +char* ReByteStorage::allocBuffer(int size){ + m_rest = size + sizeof(uint8_t*) <= (size_t) m_bufferSize ? + m_bufferSize : size + sizeof(uint8_t*); + m_summarySize += m_rest; + m_buffers++; + uint8_t* rc = new uint8_t[m_rest]; + *(uint8_t**) rc = m_buffer; + m_buffer = rc; + rc += sizeof(uint8_t*); + // the block allocation will be done outside! + m_freePosition = rc; + m_rest -= sizeof(uint8_t*); + return reinterpret_cast (rc); } /** @@ -100,14 +100,13 @@ char* ReByteStorage::allocBuffer(int size) * If < 0 strlen(source) will be used * @return a copy of the source string. The copy ends always with '\0' */ -const char* ReByteStorage::allocateChars(const char* source, int size) -{ - if (size < 0) - size = strlen(source); - const char* rc = allocateChars(size + 1); - memcpy((void*) rc, source, size); - ((char*)rc)[size] = '\0'; - return rc; +const char* ReByteStorage::allocateChars(const char* source, int size){ + if (size < 0) + size = strlen(source); + const char* rc = allocateChars(size + 1); + memcpy((void*) rc, source, size); + ((char*) rc)[size] = '\0'; + return rc; } /** @@ -118,10 +117,9 @@ const char* ReByteStorage::allocateChars(const char* source, int size) * @param source the source string * @return a copy of the source string. The copy ends always with '\0' */ -const char* ReByteStorage::allocUtf8(const ReString& source) -{ - const char* rc = allocateChars(source.toUtf8().constData()); - return rc; +const char* ReByteStorage::allocUtf8(const ReString& source){ + const char* rc = allocateChars(source.toUtf8().constData()); + return rc; } /** @@ -131,13 +129,13 @@ const char* ReByteStorage::allocUtf8(const ReString& source) * * @return a byte block (without a trailing '\0') */ -uint8_t* ReByteStorage::allocateBytes(int size) -{ - uint8_t* rc = size <= m_rest ? m_freePosition - : reinterpret_cast(allocBuffer(size)); - m_freePosition += size; - m_rest -= size; - return rc; +uint8_t* ReByteStorage::allocateBytes(int size){ + uint8_t* rc = + size <= m_rest ? + m_freePosition : reinterpret_cast (allocBuffer(size)); + m_freePosition += size; + m_rest -= size; + return rc; } /** @@ -147,11 +145,10 @@ uint8_t* ReByteStorage::allocateBytes(int size) * * @return a byte block (without a trailing '\0') */ -uint8_t* ReByteStorage::allocateZeros(int size) -{ - uint8_t* rc = allocateBytes(size); - memset(rc, 0, size); - return rc; +uint8_t* ReByteStorage::allocateZeros(int size){ + uint8_t* rc = allocateBytes(size); + memset(rc, 0, size); + return rc; } /** @@ -161,9 +158,8 @@ uint8_t* ReByteStorage::allocateZeros(int size) * @param size the size of the block to allocate * @return a byte block (without a trailing '\0') */ -uint8_t* ReByteStorage::allocateBytes(void* source, int size) -{ - uint8_t* rc = allocateBytes(size); - memcpy(rc, source, size); - return rc; +uint8_t* ReByteStorage::allocateBytes(void* source, int size){ + uint8_t* rc = allocateBytes(size); + memcpy(rc, source, size); + return rc; } diff --git a/base/ReByteStorage.hpp b/base/ReByteStorage.hpp index 51496b6..e54fb96 100644 --- a/base/ReByteStorage.hpp +++ b/base/ReByteStorage.hpp @@ -1,46 +1,46 @@ /* - * Licence: + * ReByteStorage.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ - + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #ifndef RECHARSTORAGE_HPP #define RECHARSTORAGE_HPP -class ReByteStorage -{ +class ReByteStorage { public: - ReByteStorage(int blockSize); - ~ReByteStorage(); + ReByteStorage(int blockSize); + ~ReByteStorage(); public: - char* allocBuffer(int size); - /** - * @brief Allocates a char block. - * - * @return a new block - */ - inline char* allocateChars(int size){ - char* rc = size <= m_rest ? (char*) m_freePosition - : allocBuffer(size); - m_freePosition += size; - m_rest -= size; - return rc; - } - const char* allocateChars(const char* source, int size = -1); - const char* allocUtf8(const ReString& source); - uint8_t* allocateBytes(int size); - uint8_t* allocateZeros(int size); - uint8_t*allocateBytes(void* source, int size); + char* allocBuffer(int size); + /** + * @brief Allocates a char block. + * + * @return a new block + */ + inline char* allocateChars(int size){ + char* rc = size <= m_rest ? (char*) m_freePosition : allocBuffer(size); + m_freePosition += size; + m_rest -= size; + return rc; + } + const char* allocateChars(const char* source, int size = -1); + const char* allocUtf8(const ReString& source); + uint8_t* allocateBytes(int size); + uint8_t* allocateZeros(int size); + uint8_t*allocateBytes(void* source, int size); private: - int m_bufferSize; - uint8_t* m_buffer; - int m_rest; - uint8_t* m_freePosition; - int64_t m_summarySize; - int m_buffers; + int m_bufferSize; + uint8_t* m_buffer; + int m_rest; + uint8_t* m_freePosition; + int64_t m_summarySize; + int m_buffers; }; #endif // RECHARSTORAGE_HPP diff --git a/base/ReCharPtrMap.cpp b/base/ReCharPtrMap.cpp index d421b62..c898af5 100644 --- a/base/ReCharPtrMap.cpp +++ b/base/ReCharPtrMap.cpp @@ -1,11 +1,13 @@ /* - * Licence: + * ReCharPtrMap.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ - + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #include "base/rebase.hpp" @@ -29,11 +31,9 @@ * not the content */ ReKeyCharPtr::ReKeyCharPtr(const char* ptr) : - m_ptr(ptr) -{ + m_ptr(ptr){ } - /** @class ReCharPtrMap ReCharPtrMap.hpp "base/ReCharPtrMap.hpp" * * @brief A template for a map using const char* as keys. diff --git a/base/ReCharPtrMap.hpp b/base/ReCharPtrMap.hpp index f76bcfb..6a7b515 100644 --- a/base/ReCharPtrMap.hpp +++ b/base/ReCharPtrMap.hpp @@ -1,21 +1,23 @@ /* - * Licence: + * ReCharPtrMap.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ - + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #ifndef RECHARPTRMAP_HPP #define RECHARPTRMAP_HPP class ReKeyCharPtr { - friend bool operator <(ReKeyCharPtr const& op1, ReKeyCharPtr const& op2); + friend bool operator <(ReKeyCharPtr const& op1, ReKeyCharPtr const& op2); public: - ReKeyCharPtr(const char* ptr); + ReKeyCharPtr(const char* ptr); private: - const char* m_ptr; + const char* m_ptr; }; /** * @brief Compares two instances of the class ReKeyCharPtr. @@ -25,13 +27,12 @@ private: * false: op1 >= op2 */ inline bool operator <(ReKeyCharPtr const& op1, ReKeyCharPtr const& op2){ - bool rc = strcmp(op1.m_ptr, op2.m_ptr) < 0; - return rc; + bool rc = strcmp(op1.m_ptr, op2.m_ptr) < 0; + return rc; } -template -class ReCharPtrMap : public QMap -{ +template +class ReCharPtrMap: public QMap { }; #endif // RECHARPTRMAP_HPP diff --git a/base/ReConfig.cpp b/base/ReConfig.cpp index b605572..9962b2b 100644 --- a/base/ReConfig.cpp +++ b/base/ReConfig.cpp @@ -1,9 +1,12 @@ /* - * Licence: + * ReConfig.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #include "base/rebase.hpp" @@ -31,10 +34,8 @@ */ enum Locations { - LOC_WRITE_1 = LOC_FIRST_OF(LOC_CONFIG), // 10201 - LOC_WRITE_2, - LOC_READ_1, - LOC_READ_2, + LOC_WRITE_1 = LOC_FIRST_OF(LOC_CONFIG), // 10201 + LOC_WRITE_2, LOC_READ_1, LOC_READ_2, }; /** @@ -47,16 +48,16 @@ enum Locations { * @param logger NULL or a logger */ ReConfig::ReConfig(const char* file, bool readOnly, ReLogger* logger) : - m_file(file), - m_lineList(), - m_readOnly(readOnly), - m_logger(logger), - m_ownLogger(logger == NULL) { - if(logger == NULL) { - initLogger(); - } - if(file != NULL) - read(file); + m_file(file), + m_lineList(), + m_readOnly(readOnly), + m_logger(logger), + m_ownLogger(logger == NULL){ + if (logger == NULL){ + initLogger(); + } + if (file != NULL) + read(file); } /** @@ -64,24 +65,24 @@ ReConfig::ReConfig(const char* file, bool readOnly, ReLogger* logger) : * * Frees the resources. */ -ReConfig::~ReConfig() { - if(m_ownLogger) - delete m_logger; - m_logger = NULL; +ReConfig::~ReConfig(){ + if (m_ownLogger) + delete m_logger; + m_logger = NULL; } /** * Inititializes a logger. */ -void ReConfig::initLogger() { - m_logger = new ReLogger(); - ReMemoryAppender* appender = new ReMemoryAppender(); - appender->setAutoDelete(true); - m_logger->addAppender(appender); +void ReConfig::initLogger(){ + m_logger = new ReLogger(); + ReMemoryAppender* appender = new ReMemoryAppender(); + appender->setAutoDelete(true); + m_logger->addAppender(appender); - ReStreamAppender* appender2 = new ReStreamAppender(stdout); - appender2->setAutoDelete(true); - m_logger->addAppender(appender2); + ReStreamAppender* appender2 = new ReStreamAppender(stdout); + appender2->setAutoDelete(true); + m_logger->addAppender(appender2); } /** @@ -92,12 +93,12 @@ void ReConfig::initLogger() { * @return defaultValue: key does not exist * otherwise: the value assigned to key */ -int ReConfig::asInt(const char* key, int defaultValue) const { - int rc = defaultValue; - if(contains(key)) { - rc = atoi((*this)[key]); - } - return rc; +int ReConfig::asInt(const char* key, int defaultValue) const{ + int rc = defaultValue; + if (contains(key)){ + rc = atoi((*this)[key]); + } + return rc; } /** @@ -108,15 +109,15 @@ int ReConfig::asInt(const char* key, int defaultValue) const { * @return defaultValue: key does not exist * otherwise: the value assigned to key */ -bool ReConfig::asBool(const char* key, bool defaultValue) const { - bool rc = defaultValue; - if(contains(key)) { - QByteArray value = (*this)[key].toLower(); - rc = value == "1" || value == "y" || value == "yes" || value == "t" - || value == "true"; - } +bool ReConfig::asBool(const char* key, bool defaultValue) const{ + bool rc = defaultValue; + if (contains(key)){ + QByteArray value = (*this)[key].toLower(); + rc = value == "1" || value == "y" || value == "yes" || value == "t" + || value == "true"; + } - return rc; + return rc; } /** @@ -126,12 +127,12 @@ bool ReConfig::asBool(const char* key, bool defaultValue) const { * @param defaultValue if the key does not exist this is the result * @return defaultValue: key does not exist */ -QByteArray ReConfig::asString(const char* key, const char* defaultValue) { - QByteArray rc = defaultValue; - if(contains(key)) { - rc = (*this)[key]; - } - return rc; +QByteArray ReConfig::asString(const char* key, const char* defaultValue){ + QByteArray rc = defaultValue; + if (contains(key)){ + rc = (*this)[key]; + } + return rc; } /** @@ -141,34 +142,34 @@ QByteArray ReConfig::asString(const char* key, const char* defaultValue) { * @return true: OK
* false: error occurred */ -bool ReConfig::read(const char* file) { - bool rc = true; - m_lineList.reserve(1024); - FILE* fp = fopen(file, "r"); - if(fp == NULL) { - m_logger->logv(LOG_ERROR, LOC_READ_1, "cannot read: %s", file); - rc = false; - } else { - char line[64000]; - char* separator; - int lineNo = 0; - while(fgets(line, sizeof line, fp) != NULL) { - lineNo++; - m_lineList.append(line); - if(isalnum(line[0]) && (separator = strchr(line, '=')) != NULL) { - QByteArray key(line, separator - line); - QByteArray value(separator + 1); - key = key.trimmed(); - value = value.trimmed(); - if(contains(key)) - m_logger->logv(LOG_WARNING, LOC_READ_2, - "defined more than once: %s-%d: %s", file, lineNo, line); - else - insert(key, value); - } - } - } - return rc; +bool ReConfig::read(const char* file){ + bool rc = true; + m_lineList.reserve(1024); + FILE* fp = fopen(file, "r"); + if (fp == NULL){ + m_logger->logv(LOG_ERROR, LOC_READ_1, "cannot read: %s", file); + rc = false; + }else{ + char line[64000]; + char* separator; + int lineNo = 0; + while (fgets(line, sizeof line, fp) != NULL){ + lineNo++; + m_lineList.append(line); + if (isalnum(line[0]) && (separator = strchr(line, '=')) != NULL){ + QByteArray key(line, separator - line); + QByteArray value(separator + 1); + key = key.trimmed(); + value = value.trimmed(); + if (contains(key)) + m_logger->logv(LOG_WARNING, LOC_READ_2, + "defined more than once: %s-%d: %s", file, lineNo, line); + else + insert(key, value); + } + } + } + return rc; } /** @@ -178,14 +179,14 @@ bool ReConfig::read(const char* file) { * @return true: OK
* false: error occurred */ -bool ReConfig::write(const char* file) { - bool rc = false; - if(m_readOnly) - m_logger->log(LOG_ERROR, LOC_WRITE_1, "cannot write: (readonly"); - else { - m_logger->logv(LOG_ERROR, LOC_WRITE_2, "not implemented: write(%s)", - file); - } - return rc; +bool ReConfig::write(const char* file){ + bool rc = false; + if (m_readOnly) + m_logger->log(LOG_ERROR, LOC_WRITE_1, "cannot write: (readonly"); + else{ + m_logger->logv(LOG_ERROR, LOC_WRITE_2, "not implemented: write(%s)", + file); + } + return rc; } diff --git a/base/ReConfig.hpp b/base/ReConfig.hpp index 70fa36e..d022162 100644 --- a/base/ReConfig.hpp +++ b/base/ReConfig.hpp @@ -1,37 +1,40 @@ /* - * Licence: + * ReConfig.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #ifndef RECONFIG_HPP #define RECONFIG_HPP -class ReConfig : public ReConfigurator, public QHash { +class ReConfig: public ReConfigurator, public QHash { public: - ReConfig(const char* file = NULL, bool readOnly = true, - ReLogger* logger = NULL); - virtual ~ReConfig(); + ReConfig(const char* file = NULL, bool readOnly = true, ReLogger* logger = + NULL); + virtual ~ReConfig(); public: - bool read(const char* file); - bool write(const char* file); - void clear(); - const QList& getLines() const; + bool read(const char* file); + bool write(const char* file); + void clear(); + const QList & getLines() const; - virtual bool asBool(const char* key, bool defaultValue) const; - virtual int asInt(const char* key, int defaultValue) const; - virtual QByteArray asString(const char* key, const char* defaultValue); + virtual bool asBool(const char* key, bool defaultValue) const; + virtual int asInt(const char* key, int defaultValue) const; + virtual QByteArray asString(const char* key, const char* defaultValue); private: - void initLogger(); + void initLogger(); private: - const char* m_file; - QList m_lineList; - bool m_readOnly; - ReLogger* m_logger; - // true: the logger must be destroyed in the destructor - bool m_ownLogger; + const char* m_file; + QList m_lineList; + bool m_readOnly; + ReLogger* m_logger; + // true: the logger must be destroyed in the destructor + bool m_ownLogger; }; #endif // RECONFIG_HPP diff --git a/base/ReConfigurator.hpp b/base/ReConfigurator.hpp index ab201bc..49adc42 100644 --- a/base/ReConfigurator.hpp +++ b/base/ReConfigurator.hpp @@ -1,18 +1,21 @@ /* - * Licence: + * ReConfigurator.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #ifndef RECONFIGURATOR_HPP #define RECONFIGURATOR_HPP class ReConfigurator { public: - virtual int asInt(const char* key, int defaultValue) const = 0; - virtual bool asBool(const char* key, bool defaultValue) const = 0; - virtual QByteArray asString(const char* key, const char* defaultValue) = 0; + virtual int asInt(const char* key, int defaultValue) const = 0; + virtual bool asBool(const char* key, bool defaultValue) const = 0; + virtual QByteArray asString(const char* key, const char* defaultValue) = 0; }; #endif // RECONFIGURATOR_HPP diff --git a/base/ReContainer.cpp b/base/ReContainer.cpp index 9e8e251..6b7e5bf 100644 --- a/base/ReContainer.cpp +++ b/base/ReContainer.cpp @@ -1,9 +1,12 @@ /* - * Licence: + * ReContainer.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #include "base/rebase.hpp" @@ -44,16 +47,16 @@ */ enum { - // 11000 - LOC_FILL_1 = LOC_CONTAINER * 1000, - LOC_FILL_2, - LOC_FILL_3, - LOC_NEXT_BAG_1, - LOC_NEXT_ITEM_1, - LOC_NEXT_ITEM_2 = 11005, - LOC_NEXT_INT_1, - LOC_NEXT_ITEM_3, - LOC_NEXT_BAG_2, + // 11000 + LOC_FILL_1 = LOC_CONTAINER * 1000, + LOC_FILL_2, + LOC_FILL_3, + LOC_NEXT_BAG_1, + LOC_NEXT_ITEM_1, + LOC_NEXT_ITEM_2 = 11005, + LOC_NEXT_INT_1, + LOC_NEXT_ITEM_3, + LOC_NEXT_BAG_2, }; const char* ReContainer::MAGIC_1 = "Rpl&1"; @@ -64,20 +67,20 @@ const char* ReContainer::MAGIC_1 = "Rpl&1"; * @param sizeHint Probable length of the container */ ReContainer::ReContainer(size_t sizeHint) : - m_data(""), - m_countBags(0), - m_typeList(""), - m_ixItem(0), - m_ixBag(0), - m_readPosition(NULL) { - if (sizeHint > 0) - m_data.reserve(sizeHint); + m_data(""), + m_countBags(0), + m_typeList(""), + m_ixItem(0), + m_ixBag(0), + m_readPosition(NULL){ + if (sizeHint > 0) + m_data.reserve(sizeHint); } /** * @brief Destructor. */ -ReContainer::~ReContainer() { +ReContainer::~ReContainer(){ } /** @@ -85,57 +88,57 @@ ReContainer::~ReContainer() { * * @param tag the type tag */ -void ReContainer::addType(type_tag_t tag) { - if(m_countBags == 0) - startBag(); - if(m_countBags == 1) - m_typeList.append((char) tag); +void ReContainer::addType(type_tag_t tag){ + if (m_countBags == 0) + startBag(); + if (m_countBags == 1) + m_typeList.append((char) tag); } /** * @brief Starts a new bag. */ -void ReContainer::startBag() { - m_countBags++; - m_ixBag = 0; +void ReContainer::startBag(){ + m_countBags++; + m_ixBag = 0; } /** * @brief Adds a character to the current bag. * * @param value value to insert */ -void ReContainer::addChar(char value) { - addType(TAG_CHAR); - //if (m_typeList.at(m_ixBag) != TAG_INT) - // ReLogger::logAndThrow(LOG_ERROR, __FILE__, __LINE__, 1, "unexpected type: %c instead of c", m_typeList.at(m_ixBag)); - m_data.append(value); +void ReContainer::addChar(char value){ + addType(TAG_CHAR); + //if (m_typeList.at(m_ixBag) != TAG_INT) + // ReLogger::logAndThrow(LOG_ERROR, __FILE__, __LINE__, 1, "unexpected type: %c instead of c", m_typeList.at(m_ixBag)); + m_data.append(value); } /** * @brief Adds an integer to the current bag. * * @param value value to add */ -void ReContainer::addInt(int value) { - addType(TAG_INT); - char buffer[64]; - char* ptr = buffer; - if(value < 0) { - *ptr++ = '-'; - value = - value; - } - qsnprintf(ptr, sizeof buffer - 1, "%x ", value); - m_data.append(buffer); +void ReContainer::addInt(int value){ + addType(TAG_INT); + char buffer[64]; + char* ptr = buffer; + if (value < 0){ + *ptr++ = '-'; + value = -value; + } + qsnprintf(ptr, sizeof buffer - 1, "%x ", value); + m_data.append(buffer); } /** * @brief Adds an integer to the current bag. * * @param value value to add */ -void ReContainer::addInt(int64_t value) { - addType(TAG_INT); - char buffer[128]; - qsnprintf(buffer, sizeof buffer, "%llx ", value); - m_data.append(buffer); +void ReContainer::addInt(int64_t value){ + addType(TAG_INT); + char buffer[128]; + qsnprintf(buffer, sizeof buffer, "%llx ", value); + m_data.append(buffer); } /** @@ -143,10 +146,10 @@ void ReContainer::addInt(int64_t value) { * * @param value value to add */ -void ReContainer::addString(const char* value) { - addType(TAG_STRING); - // store with trailing '\0' - m_data.append(value, strlen(value) + 1); +void ReContainer::addString(const char* value){ + addType(TAG_STRING); + // store with trailing '\0' + m_data.append(value, strlen(value) + 1); } /** * @brief Adds binary data to the current bag. @@ -154,24 +157,24 @@ void ReContainer::addString(const char* value) { * @param value binary data * @param size size of the binary data in bytes */ -void ReContainer::addData(uint8_t* value, size_t size) { - if(size <= 255) { - addType(TAG_DATA255); - m_data.append((char) size); - } else if(size <= 0xffff) { - addType(TAG_DATA64K); - m_data.append((char)(size / 256)); - m_data.append((char)(size % 256)); - m_data.append((const char*) value, size); - } else { - addType(TAG_DATA4G); - m_data.append((char)(size / 256 / 256 / 256)); - m_data.append((char)(size / 256 / 256 % 256)); - m_data.append((char)(size / 256 % 256)); - m_data.append((char)(size % 256)); - m_data.append((const char*) value, size); - } - addType(TAG_DATA255); +void ReContainer::addData(uint8_t* value, size_t size){ + if (size <= 255){ + addType(TAG_DATA255); + m_data.append((char) size); + }else if (size <= 0xffff){ + addType(TAG_DATA64K); + m_data.append((char) (size / 256)); + m_data.append((char) (size % 256)); + m_data.append((const char*) value, size); + }else{ + addType(TAG_DATA4G); + m_data.append((char) (size / 256 / 256 / 256)); + m_data.append((char) (size / 256 / 256 % 256)); + m_data.append((char) (size / 256 % 256)); + m_data.append((char) (size % 256)); + m_data.append((const char*) value, size); + } + addType(TAG_DATA255); } @@ -180,18 +183,18 @@ void ReContainer::addData(uint8_t* value, size_t size) { * * @return the container as a byte array */ -const QByteArray& ReContainer::getData() { - if(m_typeList.length() != 0) { - char buffer[128]; - // RPL&1 0a b5[2]cis: !12 - qsnprintf(buffer, sizeof buffer, "%x[%d]%s:", (unsigned int) m_data.length(), - m_countBags, m_typeList.data()); - char header[128+8]; - qsnprintf(header, sizeof header, "%s%02x%s", MAGIC_1, - (unsigned int) strlen(buffer), buffer); - m_data.insert(0, header); - } - return m_data; +const QByteArray& ReContainer::getData(){ + if (m_typeList.length() != 0){ + char buffer[128]; + // RPL&1 0a b5[2]cis: !12 + qsnprintf(buffer, sizeof buffer, "%x[%d]%s:", + (unsigned int) m_data.length(), m_countBags, m_typeList.data()); + char header[128 + 8]; + qsnprintf(header, sizeof header, "%s%02x%s", MAGIC_1, + (unsigned int) strlen(buffer), buffer); + m_data.insert(0, header); + } + return m_data; } /** @@ -199,36 +202,35 @@ const QByteArray& ReContainer::getData() { * * @param data the container as a byte array */ -void ReContainer::fill(const QByteArray& data) { - m_data = data; - const char* ptr = m_data.data(); - if(strncmp(ptr, MAGIC_1, strlen(MAGIC_1)) != 0) - throw RplInvalidDataException(LOG_ERROR, LOC_FILL_1, "container has no magic", - data.data(), data.length()); - ptr += strlen(MAGIC_1); - unsigned int headerSize = 0; - if(sscanf(ptr, "%02x", &headerSize) != 1) - throw RplInvalidDataException(LOG_ERROR, LOC_FILL_2, - "container has no header size", ptr, 2); - ptr += 2; - - unsigned int dataSize = 0; - unsigned int countBags = 0; - if(sscanf(ptr, "%x[%x]", &dataSize, &countBags) != 2) - throw RplInvalidDataException(LOG_ERROR, LOC_FILL_2, - "container has no data_size[bag_count]", ptr, 16); - m_countBags = countBags; - ptr = strchr(ptr, ']') + 1; - const char* end = ptr + strspn(ptr, "cisdDX!"); - if(end == ptr || *end != ':') { - throw RplInvalidDataException(LOG_ERROR, LOC_FILL_2, - "container has no valid typelist", ptr, 16); - } - m_typeList.clear(); - m_typeList.append(ptr, end - ptr); - m_ixBag = -1; - m_readPosition = (uint8_t*) end + 1; +void ReContainer::fill(const QByteArray& data){ + m_data = data; + const char* ptr = m_data.data(); + if (strncmp(ptr, MAGIC_1, strlen(MAGIC_1)) != 0) + throw RplInvalidDataException(LOG_ERROR, LOC_FILL_1, + "container has no magic", data.data(), data.length()); + ptr += strlen(MAGIC_1); + unsigned int headerSize = 0; + if (sscanf(ptr, "%02x", &headerSize) != 1) + throw RplInvalidDataException(LOG_ERROR, LOC_FILL_2, + "container has no header size", ptr, 2); + ptr += 2; + unsigned int dataSize = 0; + unsigned int countBags = 0; + if (sscanf(ptr, "%x[%x]", &dataSize, &countBags) != 2) + throw RplInvalidDataException(LOG_ERROR, LOC_FILL_2, + "container has no data_size[bag_count]", ptr, 16); + m_countBags = countBags; + ptr = strchr(ptr, ']') + 1; + const char* end = ptr + strspn(ptr, "cisdDX!"); + if (end == ptr || *end != ':'){ + throw RplInvalidDataException(LOG_ERROR, LOC_FILL_2, + "container has no valid typelist", ptr, 16); + } + m_typeList.clear(); + m_typeList.append(ptr, end - ptr); + m_ixBag = -1; + m_readPosition = (uint8_t*) end + 1; } /** @@ -236,48 +238,48 @@ void ReContainer::fill(const QByteArray& data) { * * @return the number of bags */ -int ReContainer::getCountBags() const { - return m_countBags; +int ReContainer::getCountBags() const{ + return m_countBags; } /** * @brief Sets the begin of the new bag. */ -void ReContainer::nextBag() { - if(m_ixItem < m_typeList.length() && m_ixItem != -1) - throw ReException(LOG_ERROR, LOC_NEXT_BAG_1, NULL, - "end of bag not reached: remaining items: %s", - m_typeList.data() + m_ixItem); - m_ixItem = 0; - m_ixBag++; - if(m_ixBag >= m_countBags) - throw ReException(LOG_ERROR, LOC_NEXT_BAG_2, NULL, - "no more bags: %d", m_ixBag); +void ReContainer::nextBag(){ + if (m_ixItem < m_typeList.length() && m_ixItem != -1) + throw ReException(LOG_ERROR, LOC_NEXT_BAG_1, NULL, + "end of bag not reached: remaining items: %s", + m_typeList.data() + m_ixItem); + m_ixItem = 0; + m_ixBag++; + if (m_ixBag >= m_countBags) + throw ReException(LOG_ERROR, LOC_NEXT_BAG_2, NULL, "no more bags: %d", + m_ixBag); } /** * @brief Sets the next item. * * @param expected the expected data type */ -void ReContainer::nextItem(type_tag_t expected) { - if(m_ixBag < 0) { - m_ixBag = 0; - m_ixItem = 0; - } - if(m_ixItem >= m_typeList.length()) - throw ReException(LOG_ERROR, LOC_NEXT_ITEM_1, "no more items in the bag"); - type_tag_t current = (type_tag_t) m_typeList.at(m_ixItem); - // Unify all data types: - if(current == TAG_DATA4G || current == TAG_DATA64K) - current = TAG_DATA255; - if(current != expected) - throw ReException(LOG_ERROR, LOC_NEXT_ITEM_2, NULL, - "current item is a %c, not a %c", - (char) m_typeList.at(m_ixItem), (char) expected); - m_ixItem++; - if(m_readPosition > (uint8_t*)(m_data.data() + m_data.length())) - throw ReException(LOG_ERROR, LOC_NEXT_ITEM_3, NULL, - "container size too small. Bag: %d of %d Item: %d of %d", - 1 + m_ixBag, m_countBags, 1 + m_ixItem, m_typeList.length()); +void ReContainer::nextItem(type_tag_t expected){ + if (m_ixBag < 0){ + m_ixBag = 0; + m_ixItem = 0; + } + if (m_ixItem >= m_typeList.length()) + throw ReException(LOG_ERROR, LOC_NEXT_ITEM_1, "no more items in the bag"); + type_tag_t current = (type_tag_t) m_typeList.at(m_ixItem); + // Unify all data types: + if (current == TAG_DATA4G || current == TAG_DATA64K) + current = TAG_DATA255; + if (current != expected) + throw ReException(LOG_ERROR, LOC_NEXT_ITEM_2, NULL, + "current item is a %c, not a %c", (char) m_typeList.at(m_ixItem), + (char) expected); + m_ixItem++; + if (m_readPosition > (uint8_t*) (m_data.data() + m_data.length())) + throw ReException(LOG_ERROR, LOC_NEXT_ITEM_3, NULL, + "container size too small. Bag: %d of %d Item: %d of %d", 1 + m_ixBag, + m_countBags, 1 + m_ixItem, m_typeList.length()); } /** @@ -285,10 +287,10 @@ void ReContainer::nextItem(type_tag_t expected) { * * @return the next char from the container */ -char ReContainer::nextChar() { - nextItem(TAG_CHAR); - char rc = *m_readPosition++; - return rc; +char ReContainer::nextChar(){ + nextItem(TAG_CHAR); + char rc = *m_readPosition++; + return rc; } /** @@ -296,38 +298,38 @@ char ReContainer::nextChar() { * * @return the next integer from the container */ -int ReContainer::nextInt() { - nextItem(TAG_INT); - bool isNegativ = *m_readPosition == '-'; - if(isNegativ) - m_readPosition++; - unsigned int value = 0; - if(sscanf((const char*) m_readPosition, "%x ", &value) != 1) - throw RplInvalidDataException(LOG_ERROR, LOC_NEXT_INT_1, - "not a hex_number", m_readPosition, 16); - m_readPosition = (uint8_t*) strchr((const char*) m_readPosition, ' ') + 1; - if(isNegativ) - value = - value; - return value; +int ReContainer::nextInt(){ + nextItem(TAG_INT); + bool isNegativ = *m_readPosition == '-'; + if (isNegativ) + m_readPosition++; + unsigned int value = 0; + if (sscanf((const char*) m_readPosition, "%x ", &value) != 1) + throw RplInvalidDataException(LOG_ERROR, LOC_NEXT_INT_1, + "not a hex_number", m_readPosition, 16); + m_readPosition = (uint8_t*) strchr((const char*) m_readPosition, ' ') + 1; + if (isNegativ) + value = -value; + return value; } /** * @brief Reads the next integer from the current item in the current bag. * * @return the next integer from the container */ -int64_t ReContainer::nextInt64() { - nextItem(TAG_INT); - bool isNegativ = *m_readPosition == '-'; - if(isNegativ) - m_readPosition++; - uint64_t value = 0; - if(sscanf((const char*) m_readPosition, "%llx ", &value) != 1) - throw RplInvalidDataException(LOG_ERROR, LOC_NEXT_INT_1, - "not a hex_number", m_readPosition, 16); - m_readPosition = (uint8_t*) strchr((const char*) m_readPosition, ' ') + 1; - if(isNegativ) - value = - value; - return (int64_t) value; +int64_t ReContainer::nextInt64(){ + nextItem(TAG_INT); + bool isNegativ = *m_readPosition == '-'; + if (isNegativ) + m_readPosition++; + uint64_t value = 0; + if (sscanf((const char*) m_readPosition, "%llx ", &value) != 1) + throw RplInvalidDataException(LOG_ERROR, LOC_NEXT_INT_1, + "not a hex_number", m_readPosition, 16); + m_readPosition = (uint8_t*) strchr((const char*) m_readPosition, ' ') + 1; + if (isNegativ) + value = -value; + return (int64_t) value; } /** @@ -335,11 +337,11 @@ int64_t ReContainer::nextInt64() { * * @return the next '\0' delimited string from the container */ -const char* ReContainer::nextString() { - nextItem(TAG_STRING); - const char* rc = (const char*) m_readPosition; - m_readPosition += strlen(rc) + 1; - return rc; +const char* ReContainer::nextString(){ + nextItem(TAG_STRING); + const char* rc = (const char*) m_readPosition; + m_readPosition += strlen(rc) + 1; + return rc; } /** @@ -350,36 +352,34 @@ const char* ReContainer::nextString() { * false: data contains the item data only * @return the size of the read data */ -size_t ReContainer::nextData(QByteArray& data, bool append) { - nextItem(TAG_DATA255); - type_tag_t tag = (type_tag_t) m_typeList.at(m_ixItem - 1); - size_t length = 0; - switch(tag) { - case TAG_DATA4G: - for(int ix = 3; ix >= 0; ix--) { - length = 256 * length + m_readPosition[ix]; - } - m_readPosition += 4; - break; - case TAG_DATA64K: - length = *m_readPosition++ * 256; - length += *m_readPosition++; - break; - case TAG_DATA255: - length = *m_readPosition++; - break; - default: - break; - } - if(! append) - data.clear(); - data.append((const char*) m_readPosition, length); - m_readPosition += length; - return length; +size_t ReContainer::nextData(QByteArray& data, bool append){ + nextItem(TAG_DATA255); + type_tag_t tag = (type_tag_t) m_typeList.at(m_ixItem - 1); + size_t length = 0; + switch (tag) { + case TAG_DATA4G: + for (int ix = 3; ix >= 0; ix--){ + length = 256 * length + m_readPosition[ix]; + } + m_readPosition += 4; + break; + case TAG_DATA64K: + length = *m_readPosition++ * 256; + length += *m_readPosition++; + break; + case TAG_DATA255: + length = *m_readPosition++; + break; + default: + break; + } + if (!append) + data.clear(); + data.append((const char*) m_readPosition, length); + m_readPosition += length; + return length; } - - /** * @brief Dumps a container as a human readable string. * @@ -390,64 +390,67 @@ size_t ReContainer::nextData(QByteArray& data, bool append) { * @param separatorItems separator between two items, e.g. '\\n' or '|' * @return a human readable string describing the container */ -QByteArray ReContainer::dump(const char* title, - int maxBags, int maxStringLength, int maxBlobLength, - char separatorItems) { - QByteArray rc; - rc.reserve(64000); - rc.append("=== ").append(title).append('\n'); - rc.append("Bags: ").append(ReStringUtil::toNumber(m_countBags)); - rc.append(" Types: ").append(m_typeList).append('\n'); - // save the current state: - int safeIxBag = m_ixBag; - int safeIxItem = m_ixItem; - m_ixBag = -1; - m_ixItem = 0; - int iValue; - QByteArray sValue; - if(maxBags > m_countBags) - maxBags = m_countBags; - for(int ixBag = 0; ixBag < maxBags; ixBag++) { - rc.append("--- bag ").append(ReStringUtil::toNumber(ixBag)).append(":\n"); - nextBag(); - QByteArray item; - int maxLength; - for(int ixItem = 0; ixItem < m_typeList.length(); ixItem++) { - type_tag_t currentType = (type_tag_t) m_typeList.at(ixItem); - switch(currentType) { - case TAG_CHAR: - rc.append(" c: ").append(nextChar()).append(separatorItems); - break; - case TAG_INT: - iValue = nextInt(); - rc.append(" i: ").append(ReStringUtil::toNumber(iValue)).append(" / "); - rc.append(ReStringUtil::toNumber(iValue, "%x")).append(separatorItems); - break; - case TAG_STRING: - sValue = nextString(); - if(sValue.length() > maxStringLength) - sValue = sValue.left(maxStringLength); - rc.append(" s: ").append(sValue).append(separatorItems); - break; - case TAG_DATA255: - case TAG_DATA64K: - case TAG_DATA4G: - nextData(item, false); - rc.append(' ').append((char) currentType).append(": ["); - rc.append(ReStringUtil::toNumber(item.length())).append("] "); - maxLength = item.length() < maxBlobLength ? item.length() : maxBlobLength; - rc.append(ReStringUtil::hexDump(item.data(), maxLength, - 16)).append(separatorItems); - break; - default: - break; - } - } - } +QByteArray ReContainer::dump(const char* title, int maxBags, + int maxStringLength, int maxBlobLength, char separatorItems){ + QByteArray rc; + rc.reserve(64000); + rc.append("=== ").append(title).append('\n'); + rc.append("Bags: ").append(ReStringUtil::toNumber(m_countBags)); + rc.append(" Types: ").append(m_typeList).append('\n'); + // save the current state: + int safeIxBag = m_ixBag; + int safeIxItem = m_ixItem; + m_ixBag = -1; + m_ixItem = 0; + int iValue; + QByteArray sValue; + if (maxBags > m_countBags) + maxBags = m_countBags; + for (int ixBag = 0; ixBag < maxBags; ixBag++){ + rc.append("--- bag ").append(ReStringUtil::toNumber(ixBag)).append(":\n"); + nextBag(); + QByteArray item; + int maxLength; + for (int ixItem = 0; ixItem < m_typeList.length(); ixItem++){ + type_tag_t currentType = (type_tag_t) m_typeList.at(ixItem); + switch (currentType) { + case TAG_CHAR: + rc.append(" c: ").append(nextChar()).append(separatorItems); + break; + case TAG_INT: + iValue = nextInt(); + rc.append(" i: ").append(ReStringUtil::toNumber(iValue)).append( + " / "); + rc.append(ReStringUtil::toNumber(iValue, "%x")).append( + separatorItems); + break; + case TAG_STRING: + sValue = nextString(); + if (sValue.length() > maxStringLength) + sValue = sValue.left(maxStringLength); + rc.append(" s: ").append(sValue).append(separatorItems); + break; + case TAG_DATA255: + case TAG_DATA64K: + case TAG_DATA4G: + nextData(item, false); + rc.append(' ').append((char) currentType).append(": ["); + rc.append(ReStringUtil::toNumber(item.length())).append("] "); + maxLength = + item.length() < maxBlobLength ? + item.length() : maxBlobLength; + rc.append(ReStringUtil::hexDump(item.data(), maxLength, 16)).append( + separatorItems); + break; + default: + break; + } + } + } - // restore the current state: - m_ixBag = safeIxBag; - m_ixItem = safeIxItem; - return rc; + // restore the current state: + m_ixBag = safeIxBag; + m_ixItem = safeIxItem; + return rc; } diff --git a/base/ReContainer.hpp b/base/ReContainer.hpp index 5a08aca..8d1dcc2 100644 --- a/base/ReContainer.hpp +++ b/base/ReContainer.hpp @@ -1,9 +1,12 @@ /* - * Licence: + * ReContainer.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #ifndef RECONTAINER_HPP #define RECONTAINER_HPP @@ -15,68 +18,67 @@ #endif class ReContainer { public: - typedef enum { + typedef enum { - TAG_CHAR = 'c', ///< one character - TAG_INT = 'i', ///< an integer number, up to 64 bit - TAG_STRING = 's', ///< a string ending with a '\\0' - TAG_DATA255 = 'd', ///< binary data, up to 255 bytes long - TAG_DATA64K = 'D', ///< binary data, up to 64 KiBytes long - TAG_DATA4G = 'X', ///< binary data, up to 4 GiBytes long - TAG_CONTAINER = '!' ///< a container (recursion) - } type_tag_t; - static const char* MAGIC_1; + TAG_CHAR = 'c', ///< one character + TAG_INT = 'i', ///< an integer number, up to 64 bit + TAG_STRING = 's', ///< a string ending with a '\\0' + TAG_DATA255 = 'd', ///< binary data, up to 255 bytes long + TAG_DATA64K = 'D', ///< binary data, up to 64 KiBytes long + TAG_DATA4G = 'X', ///< binary data, up to 4 GiBytes long + TAG_CONTAINER = '!' ///< a container (recursion) + } type_tag_t; + static const char* MAGIC_1; public: - ReContainer(size_t sizeHint); - virtual ~ReContainer(); + ReContainer(size_t sizeHint); + virtual ~ReContainer(); private: - // No copy constructor: no implementation! - ReContainer(const ReContainer& source); - // Prohibits assignment operator: no implementation! - ReContainer& operator =(const ReContainer& source); + // No copy constructor: no implementation! + ReContainer(const ReContainer& source); + // Prohibits assignment operator: no implementation! + ReContainer& operator =(const ReContainer& source); public: - // Building the container: - void addType(type_tag_t tag); - void startBag(); - void addChar(char cc); - void addInt(int value); - void addInt(int64_t value); - void addString(const char* value); - void addData(uint8_t* value, size_t size); - const QByteArray& getData(); + // Building the container: + void addType(type_tag_t tag); + void startBag(); + void addChar(char cc); + void addInt(int value); + void addInt(int64_t value); + void addString(const char* value); + void addData(uint8_t* value, size_t size); + const QByteArray& getData(); - // Getting data from the container: - void fill(const QByteArray& data); - int getCountBags() const; - const char* getTypeList() const; - void nextBag(); - char nextChar(); - int nextInt(); - int64_t nextInt64(); - const char* nextString(); - size_t nextData(QByteArray& data, bool append = false); + // Getting data from the container: + void fill(const QByteArray& data); + int getCountBags() const; + const char* getTypeList() const; + void nextBag(); + char nextChar(); + int nextInt(); + int64_t nextInt64(); + const char* nextString(); + size_t nextData(QByteArray& data, bool append = false); - QByteArray dump(const char* title, - int maxBags, int maxStringLength = 80, int maxBlobLength = 16, - char separatorItems = '\n'); + QByteArray dump(const char* title, int maxBags, int maxStringLength = 80, + int maxBlobLength = 16, char separatorItems = '\n'); private: - void nextItem(type_tag_t expected); + void nextItem(type_tag_t expected); private: - // the complete data of the container - QByteArray m_data; - // the number of elements in the container - int m_countBags; - // a string with the data types of a bag - QByteArray m_typeList; + // the complete data of the container + QByteArray m_data; + // the number of elements in the container + int m_countBags; + // a string with the data types of a bag + QByteArray m_typeList; - // Getting data from the container: + // Getting data from the container: - // current read position in m_typeList - int m_ixItem; - // the index of the current current bag: - int m_ixBag; - // read position in m_data: - const uint8_t* m_readPosition; + // current read position in m_typeList + int m_ixItem; + // the index of the current current bag: + int m_ixBag; + // read position in m_data: + const uint8_t* m_readPosition; }; #endif // RECONTAINER_HPP diff --git a/base/ReException.cpp b/base/ReException.cpp index 0af373d..024acbd 100644 --- a/base/ReException.cpp +++ b/base/ReException.cpp @@ -1,9 +1,12 @@ /* - * Licence: + * ReException.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ /** @mainpage * @@ -36,6 +39,9 @@ */ #include "base/rebase.hpp" +enum { + LOC_NOT_IMPLEMENTED_1 = LOC_FIRST_OF(LOC_EXCEPTION), +}; /** @class ReException ReException.hpp "base/ReException.hpp" * * @brief A generally usable exception with or without logging. @@ -45,15 +51,13 @@ */ class ReException; - /** * @brief Constructor. * * For derived classes only! */ ReException::ReException() : - m_message("") -{ + m_message(""){ } /** @@ -63,13 +67,13 @@ ReException::ReException() : * @param ... the values for the placeholders in the format. */ ReException::ReException(const char* format, ...) : - m_message("") { - char buffer[64000]; - va_list ap; - va_start(ap, format); - qvsnprintf(buffer, sizeof buffer, format, ap); - va_end(ap); - m_message = buffer; + m_message(""){ + char buffer[64000]; + va_list ap; + va_start(ap, format); + qvsnprintf(buffer, sizeof buffer, format, ap); + va_end(ap); + m_message = buffer; } /** @@ -87,21 +91,20 @@ ReException::ReException(const char* format, ...) : * in format * @param logger if NULL the global logger will be used */ -ReException::ReException(ReLoggerLevel level, int location, - ReLogger* logger, const char* format, ...) : - m_message("") { - char buffer[64000]; - va_list ap; - va_start(ap, format); - qvsnprintf(buffer, sizeof buffer, format, ap); - va_end(ap); - m_message = buffer; - if(logger == NULL) - logger = ReLogger::globalLogger(); - logger->log(level, location, buffer); +ReException::ReException(ReLoggerLevel level, int location, ReLogger* logger, + const char* format, ...) : + m_message(""){ + char buffer[64000]; + va_list ap; + va_start(ap, format); + qvsnprintf(buffer, sizeof buffer, format, ap); + va_end(ap); + m_message = buffer; + if (logger == NULL) + logger = ReLogger::globalLogger(); + logger->log(level, location, buffer); } - /** @class RplRangeException rplexception.hpp "rplcore/rplexception.hpp" * * @brief An exception for integer range errors. @@ -132,18 +135,17 @@ ReException::ReException(ReLoggerLevel level, int location, */ ReRangeException::ReRangeException(ReLoggerLevel level, int location, - size_t current, - size_t lbound, size_t ubound, const char* message, ReLogger* logger) : - ReException("") { - char buffer[64000]; - if(message == NULL) - message = "value outside limits"; - qsnprintf(buffer, sizeof buffer, "%s: %lu [%lu, %lu]", - message == NULL ? "" : message, - current, lbound, ubound); - if(logger == NULL) - logger = ReLogger::globalLogger(); - logger->log(level, location, buffer); + size_t current, size_t lbound, size_t ubound, const char* message, + ReLogger* logger) : + ReException(""){ + char buffer[64000]; + if (message == NULL) + message = "value outside limits"; + qsnprintf(buffer, sizeof buffer, "%s: %lu [%lu, %lu]", + message == NULL ? "" : message, current, lbound, ubound); + if (logger == NULL) + logger = ReLogger::globalLogger(); + logger->log(level, location, buffer); } /** @class RplInvalidDataException rplexception.hpp "rplcore/rplexception.hpp" @@ -173,32 +175,42 @@ ReRangeException::ReRangeException(ReLoggerLevel level, int location, * @param logger if NULL the global logger will be used */ RplInvalidDataException::RplInvalidDataException(ReLoggerLevel level, - int location, - const char* message, const void* data, - size_t dataSize, ReLogger* logger) : - ReException("") { - char buffer[64000]; - if(message == NULL) - message = "invalid data: "; - if(data == NULL) - data = ""; - if(dataSize > 16) - dataSize = 16; - size_t ix; - char* ptr = buffer + strlen(buffer); - for(ix = 0; ix < dataSize; ix++) { - qsnprintf(ptr, sizeof(buffer) - (ptr - buffer) - 1, "%02x ", - ((unsigned char*) data)[ix]); - ptr += strlen(ptr); - } - for(ix = 0; ix < dataSize; ix++) { - char cc = ((char*) data)[ix]; - if(cc > ' ' && cc <= '~') - *ptr++ = cc; - else - *ptr++ = '.'; - } - if(logger == NULL) - logger = ReLogger::globalLogger(); - logger->log(level, location, buffer); + int location, const char* message, const void* data, size_t dataSize, + ReLogger* logger) : + ReException(""){ + char buffer[64000]; + if (message == NULL) + message = "invalid data: "; + if (data == NULL) + data = ""; + if (dataSize > 16) + dataSize = 16; + size_t ix; + char* ptr = buffer + strlen(buffer); + for (ix = 0; ix < dataSize; ix++){ + qsnprintf(ptr, sizeof(buffer) - (ptr - buffer) - 1, "%02x ", + ((unsigned char*) data)[ix]); + ptr += strlen(ptr); + } + for (ix = 0; ix < dataSize; ix++){ + char cc = ((char*) data)[ix]; + if (cc > ' ' && cc <= '~') + *ptr++ = cc; + else + *ptr++ = '.'; + } + if (logger == NULL) + logger = ReLogger::globalLogger(); + logger->log(level, location, buffer); +} + +/** + * @brief Constructor. + * + * @param message describes what is not implemented + */ +ReNotImplementedException::ReNotImplementedException(const char* message) : + ReException("not implemented: ", message){ + ReLogger::globalLogger()->log(LOG_ERROR, LOC_NOT_IMPLEMENTED_1, + getMessage()); } diff --git a/base/ReException.hpp b/base/ReException.hpp index 8fb8113..03d3909 100644 --- a/base/ReException.hpp +++ b/base/ReException.hpp @@ -1,9 +1,12 @@ /* - * Licence: + * ReException.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #ifndef REEXCEPTION_HPP #define REEXCEPTION_HPP @@ -15,31 +18,37 @@ class ReException { protected: - ReException(); + ReException(); public: - ReException(const char* message, ...); - ReException(ReLoggerLevel level, int location, const char* message, - ReLogger* logger = NULL); - ReException(ReLoggerLevel level, int location, ReLogger* logger, - const char* message, ...); - const QByteArray& getMessage() const { - return m_message; - } + ReException(const char* message, ...); + ReException(ReLoggerLevel level, int location, const char* message, + ReLogger* logger = NULL); + ReException(ReLoggerLevel level, int location, ReLogger* logger, + const char* message, ...); + const QByteArray& getMessage() const{ + return m_message; + } protected: - QByteArray m_message; + QByteArray m_message; }; -class ReRangeException : public ReException { +class ReRangeException: public ReException { public: - ReRangeException(ReLoggerLevel level, int location, size_t current, - size_t lbound, size_t ubound, - const char* message = NULL, ReLogger* logger = NULL); + ReRangeException(ReLoggerLevel level, int location, size_t current, + size_t lbound, size_t ubound, const char* message = NULL, + ReLogger* logger = NULL); }; -class RplInvalidDataException : public ReException { +class RplInvalidDataException: public ReException { public: - RplInvalidDataException(ReLoggerLevel level, int location, const char* message, - const void* data = NULL, size_t dataSize = 0, ReLogger* logger = NULL); + RplInvalidDataException(ReLoggerLevel level, int location, + const char* message, const void* data = NULL, size_t dataSize = 0, + ReLogger* logger = NULL); +}; + +class ReNotImplementedException: public ReException { +public: + ReNotImplementedException(const char* message); }; #endif // REEXCEPTION_HPP diff --git a/base/ReLogger.cpp b/base/ReLogger.cpp index 0e913f7..777b0aa 100644 --- a/base/ReLogger.cpp +++ b/base/ReLogger.cpp @@ -1,9 +1,12 @@ /* - * Licence: + * ReLogger.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ /** @file @@ -18,7 +21,7 @@ #include enum { - LOC_ADD_APPENDER_1 = LOC_FIRST_OF(LOC_LOGGER), // 10101 + LOC_ADD_APPENDER_1 = LOC_FIRST_OF(LOC_LOGGER), // 10101 }; ReLogger* ReLogger::m_globalLogger = NULL; @@ -30,19 +33,19 @@ ReLogger* ReLogger::m_globalLogger = NULL; * * @return the global logger */ -ReLogger* ReLogger::globalLogger() { - if(m_globalLogger == NULL) { - m_globalLogger = new ReLogger(); - m_globalLogger->buildStandardAppender("globallogger"); - } - return m_globalLogger; +ReLogger* ReLogger::globalLogger(){ + if (m_globalLogger == NULL){ + m_globalLogger = new ReLogger(); + m_globalLogger->buildStandardAppender("globallogger"); + } + return m_globalLogger; } /** * @brief Frees the resources of the global logger. */ -void ReLogger::destroyGlobalLogger() { - delete m_globalLogger; - m_globalLogger = NULL; +void ReLogger::destroyGlobalLogger(){ + delete m_globalLogger; + m_globalLogger = NULL; } /** @class ReAppender rpllogger.hpp "rplcore/rpllogger.hpp" @@ -58,14 +61,13 @@ void ReLogger::destroyGlobalLogger() { * @param name identifies the logger. Useful for ReLogger::findLogger() */ ReAppender::ReAppender(const QByteArray& name) : - m_name(name), - m_level(LOG_INFO) { + m_name(name), m_level(LOG_INFO){ } /** * @brief Destructor. */ -ReAppender::~ReAppender() { +ReAppender::~ReAppender(){ } /** @@ -73,8 +75,8 @@ ReAppender::~ReAppender() { * * @return the name of the instance */ -const char* ReAppender::getName() const { - return m_name.data(); +const char* ReAppender::getName() const{ + return m_name.data(); } /** @@ -82,16 +84,16 @@ const char* ReAppender::getName() const { * * @param level */ -void ReAppender::setLevel(ReLoggerLevel level) { - m_level = level; +void ReAppender::setLevel(ReLoggerLevel level){ + m_level = level; } /** * @brief Returns the level. * * @return the level */ -ReLoggerLevel ReAppender::getLevel() const { - return m_level; +ReLoggerLevel ReAppender::getLevel() const{ + return m_level; } /** * @brief Checks whether the current location should be logged. @@ -99,8 +101,8 @@ ReLoggerLevel ReAppender::getLevel() const { * @param level the level of the location. * @return true: the location level is greater or equals to the appender's level */ -bool ReAppender::isActive(ReLoggerLevel level) { - return level <= m_level; +bool ReAppender::isActive(ReLoggerLevel level){ + return level <= m_level; } /** @@ -108,8 +110,8 @@ bool ReAppender::isActive(ReLoggerLevel level) { * * @param onNotOff the state of the auto deletion */ -void ReAppender::setAutoDelete(bool onNotOff) { - m_autoDelete = onNotOff; +void ReAppender::setAutoDelete(bool onNotOff){ + m_autoDelete = onNotOff; } /** @@ -117,8 +119,8 @@ void ReAppender::setAutoDelete(bool onNotOff) { * * @return true: the logger destroys the instance */ -bool ReAppender::isAutoDelete() const { - return m_autoDelete; +bool ReAppender::isAutoDelete() const{ + return m_autoDelete; } /** @class ReLogger rpllogger.hpp "rplcore/rpllogger.hpp" @@ -144,25 +146,25 @@ bool ReAppender::isAutoDelete() const { * @brief Constructor. */ ReLogger::ReLogger() : - // m_appenders(), - m_countAppenders(0), - m_stdPrefix(), - m_mutex(), - m_withLocking(false) { - memset(m_appenders, 0, sizeof m_appenders); + // m_appenders(), + m_countAppenders(0), + m_stdPrefix(), + m_mutex(), + m_withLocking(false){ + memset(m_appenders, 0, sizeof m_appenders); } /** * @brief Destructor. */ -ReLogger::~ReLogger() { - for(size_t ix = 0; ix < m_countAppenders; ix++) { - ReAppender* appender = m_appenders[ix]; - if(appender->isAutoDelete()) { - delete appender; - } - m_appenders[ix] = NULL; - } +ReLogger::~ReLogger(){ + for (size_t ix = 0; ix < m_countAppenders; ix++){ + ReAppender* appender = m_appenders[ix]; + if (appender->isAutoDelete()){ + delete appender; + } + m_appenders[ix] = NULL; + } } /** * @brief Returns the first char of a logging line displaying the logging level. @@ -170,26 +172,26 @@ ReLogger::~ReLogger() { * @param level the level to "convert" * @return the assigned prefix char */ -char ReLogger::getPrefixOfLevel(ReLoggerLevel level) const { - char rc = ' '; - switch(level) { - case LOG_ERROR: - rc = '!'; - break; - case LOG_WARNING: - rc = '+'; - break; - case LOG_INFO: - rc = ' '; - break; - case LOG_DEBUG: - rc = '='; - break; - default: - rc = '?'; - break; - } - return rc; +char ReLogger::getPrefixOfLevel(ReLoggerLevel level) const{ + char rc = ' '; + switch (level) { + case LOG_ERROR: + rc = '!'; + break; + case LOG_WARNING: + rc = '+'; + break; + case LOG_INFO: + rc = ' '; + break; + case LOG_DEBUG: + rc = '='; + break; + default: + rc = '?'; + break; + } + return rc; } /** @@ -199,16 +201,16 @@ char ReLogger::getPrefixOfLevel(ReLoggerLevel level) const { * @return false: all appenders are not activated by this level
* true: otherwise */ -bool ReLogger::isActive(ReLoggerLevel level) const { - bool rc = false; - for(size_t ix = 0; ix < m_countAppenders; ix++) { - ReAppender* appender = m_appenders[ix]; - if(appender->isActive(level)) { - rc = true; - break; - } - } - return rc; +bool ReLogger::isActive(ReLoggerLevel level) const{ + bool rc = false; + for (size_t ix = 0; ix < m_countAppenders; ix++){ + ReAppender* appender = m_appenders[ix]; + if (appender->isActive(level)){ + rc = true; + break; + } + } + return rc; } /** @@ -216,11 +218,11 @@ bool ReLogger::isActive(ReLoggerLevel level) const { * * @param level level to set */ -void ReLogger::setLevel(ReLoggerLevel level) { - for(size_t ix = 0; ix < m_countAppenders; ix++) { - ReAppender* appender = m_appenders[ix]; - appender->setLevel(level); - } +void ReLogger::setLevel(ReLoggerLevel level){ + for (size_t ix = 0; ix < m_countAppenders; ix++){ + ReAppender* appender = m_appenders[ix]; + appender->setLevel(level); + } } /** @@ -229,8 +231,8 @@ void ReLogger::setLevel(ReLoggerLevel level) { * @param onNotOff true: the logger is thread save.
* false: not thread save */ -void ReLogger::setWithLocking(bool onNotOff) { - m_withLocking = onNotOff; +void ReLogger::setWithLocking(bool onNotOff){ + m_withLocking = onNotOff; } /** @@ -242,10 +244,10 @@ void ReLogger::setWithLocking(bool onNotOff) { * @param location an unique identifier of the location * @return the standard logging line prefix */ -const QByteArray& ReLogger::getStdPrefix(ReLoggerLevel level, int location) { - if(m_stdPrefix.isEmpty()) - m_stdPrefix = buildStdPrefix(level, location); - return m_stdPrefix; +const QByteArray& ReLogger::getStdPrefix(ReLoggerLevel level, int location){ + if (m_stdPrefix.isEmpty()) + m_stdPrefix = buildStdPrefix(level, location); + return m_stdPrefix; } /** @@ -256,20 +258,20 @@ const QByteArray& ReLogger::getStdPrefix(ReLoggerLevel level, int location) { * @param message the logging message * @return true: for chaining */ -bool ReLogger::log(ReLoggerLevel level, int location, const char* message) { - m_stdPrefix = ""; - bool first = true; - for(size_t ix = 0; ix < m_countAppenders; ix++) { - ReAppender* appender = m_appenders[ix]; - if(appender->isActive(level)) { - if(first && m_withLocking) - m_mutex.lock(); - appender->log(level, location, message, this); - } - } - if(! first && m_withLocking) - m_mutex.unlock(); - return true; +bool ReLogger::log(ReLoggerLevel level, int location, const char* message){ + m_stdPrefix = ""; + bool first = true; + for (size_t ix = 0; ix < m_countAppenders; ix++){ + ReAppender* appender = m_appenders[ix]; + if (appender->isActive(level)){ + if (first && m_withLocking) + m_mutex.lock(); + appender->log(level, location, message, this); + } + } + if (!first && m_withLocking) + m_mutex.unlock(); + return true; } /** * @brief Logs (or not) the calling location. @@ -280,8 +282,8 @@ bool ReLogger::log(ReLoggerLevel level, int location, const char* message) { * @return true: for chaining */ bool ReLogger::log(ReLoggerLevel level, int location, - const QByteArray& message) { - return log(level, location, message.data()); + const QByteArray& message){ + return log(level, location, message.data()); } /** @@ -292,9 +294,8 @@ bool ReLogger::log(ReLoggerLevel level, int location, * @param message the logging message * @return true: for chaining */ -bool ReLogger::log(ReLoggerLevel level, int location, - const ReString& message) { - return log(level, location, message.toUtf8().data()); +bool ReLogger::log(ReLoggerLevel level, int location, const ReString& message){ + return log(level, location, message.toUtf8().data()); } /** @@ -306,14 +307,13 @@ bool ReLogger::log(ReLoggerLevel level, int location, * @param ... the values of the placeholders (varargs) * @return true: for chaining */ -bool ReLogger::logv(ReLoggerLevel level, int location, const char* format, - ...) { - char buffer[64000]; - va_list ap; - va_start(ap, format); - qvsnprintf(buffer, sizeof buffer, format, ap); - va_end(ap); - return log(level, location, buffer); +bool ReLogger::logv(ReLoggerLevel level, int location, const char* format, ...){ + char buffer[64000]; + va_list ap; + va_start(ap, format); + qvsnprintf(buffer, sizeof buffer, format, ap); + va_end(ap); + return log(level, location, buffer); } /** @@ -325,14 +325,14 @@ bool ReLogger::logv(ReLoggerLevel level, int location, const char* format, * @param ... the values of the placeholders (varargs) * @return true: for chaining */ -bool ReLogger::logv(ReLoggerLevel level, int location, - const QByteArray& format, ...) { - char buffer[64000]; - va_list ap; - va_start(ap, format); - qvsnprintf(buffer, sizeof buffer, format, ap); - va_end(ap); - return log(level, location, buffer); +bool ReLogger::logv(ReLoggerLevel level, int location, const QByteArray& format, + ...){ + char buffer[64000]; + va_list ap; + va_start(ap, format); + qvsnprintf(buffer, sizeof buffer, format, ap); + va_end(ap); + return log(level, location, buffer); } /** @@ -345,10 +345,10 @@ bool ReLogger::logv(ReLoggerLevel level, int location, * @return true: for chaining */ bool ReLogger::log(ReLoggerLevel level, int location, const char* format, - va_list& varlist) { - char buffer[64000]; - qvsnprintf(buffer, sizeof buffer, format, varlist); - return log(level, location, buffer); + va_list& varlist){ + char buffer[64000]; + qvsnprintf(buffer, sizeof buffer, format, varlist); + return log(level, location, buffer); } /** @@ -357,20 +357,14 @@ bool ReLogger::log(ReLoggerLevel level, int location, const char* format, * @param level the level of the location * @param location an unique identifier of the location */ -QByteArray ReLogger::buildStdPrefix(ReLoggerLevel level, int location) { - time_t now = time(NULL); - struct tm* now2 = localtime(&now); - char buffer[64]; - qsnprintf(buffer, sizeof buffer, "%c%d.%02d.%02d %02d:%02d:%02d (%d): ", - getPrefixOfLevel(level), - now2->tm_year + 1900, - now2->tm_mon + 1, - now2->tm_mday, - now2->tm_hour, - now2->tm_min, - now2->tm_sec, - location); - return QByteArray(buffer); +QByteArray ReLogger::buildStdPrefix(ReLoggerLevel level, int location){ + time_t now = time(NULL); + struct tm* now2 = localtime(&now); + char buffer[64]; + qsnprintf(buffer, sizeof buffer, "%c%d.%02d.%02d %02d:%02d:%02d (%d): ", + getPrefixOfLevel(level), now2->tm_year + 1900, now2->tm_mon + 1, + now2->tm_mday, now2->tm_hour, now2->tm_min, now2->tm_sec, location); + return QByteArray(buffer); } /** @@ -378,12 +372,12 @@ QByteArray ReLogger::buildStdPrefix(ReLoggerLevel level, int location) { * * @param appender appender to add */ -void ReLogger::addAppender(ReAppender* appender) { - if(m_countAppenders < sizeof m_appenders / sizeof m_appenders[0]) { - m_appenders[m_countAppenders++] = appender; - } else { - log(LOG_ERROR, LOC_ADD_APPENDER_1, "too many appenders"); - } +void ReLogger::addAppender(ReAppender* appender){ + if (m_countAppenders < sizeof m_appenders / sizeof m_appenders[0]){ + m_appenders[m_countAppenders++] = appender; + }else{ + log(LOG_ERROR, LOC_ADD_APPENDER_1, "too many appenders"); + } } /** @@ -394,16 +388,16 @@ void ReLogger::addAppender(ReAppender* appender) { * @return NULL: no appender with this name is registered
* otherwise: the wanted appender */ -ReAppender* ReLogger::findAppender(const char* name) const { - ReAppender* rc = NULL; - for(size_t ix = 0; ix < m_countAppenders; ix++) { - ReAppender* current = m_appenders[ix]; - if(strcmp(name, current->getName()) == 0) { - rc = current; - break; - } - } - return rc; +ReAppender* ReLogger::findAppender(const char* name) const{ + ReAppender* rc = NULL; + for (size_t ix = 0; ix < m_countAppenders; ix++){ + ReAppender* current = m_appenders[ix]; + if (strcmp(name, current->getName()) == 0){ + rc = current; + break; + } + } + return rc; } /** @@ -416,25 +410,24 @@ ReAppender* ReLogger::findAppender(const char* name) const { * the prefix of the log file if no entry in the * configuration file */ -void ReLogger::buildStandardAppender(ReConfig* config, - const char* prefix, - const char* defaultLogfilePrefix) { - QByteArray sPrefix(prefix); - QByteArray logFilePrefix = config->asString(sPrefix + "name", - defaultLogfilePrefix); +void ReLogger::buildStandardAppender(ReConfig* config, const char* prefix, + const char* defaultLogfilePrefix){ + QByteArray sPrefix(prefix); + QByteArray logFilePrefix = config->asString(sPrefix + "name", + defaultLogfilePrefix); - int maxSize = config->asInt( + "maxsize", 10100100); - int maxCount = config->asInt(sPrefix + "maxfiles", 5); - buildStandardAppender(logFilePrefix, maxSize, maxCount); - QByteArray sLevel = config->asString(sPrefix + "level", "info"); - ReLoggerLevel level = LOG_INFO; - if (strcasecmp(sLevel.constData(), "error") == 0) - level = LOG_ERROR; - else if (strcasecmp(sLevel, "warning") == 0) - level = LOG_WARNING; - else if (strcasecmp(sLevel, "debug") == 0) - level = LOG_DEBUG; - setLevel(level); + int maxSize = config->asInt(+"maxsize", 10100100); + int maxCount = config->asInt(sPrefix + "maxfiles", 5); + buildStandardAppender(logFilePrefix, maxSize, maxCount); + QByteArray sLevel = config->asString(sPrefix + "level", "info"); + ReLoggerLevel level = LOG_INFO; + if (strcasecmp(sLevel.constData(), "error") == 0) + level = LOG_ERROR; + else if (strcasecmp(sLevel, "warning") == 0) + level = LOG_WARNING; + else if (strcasecmp(sLevel, "debug") == 0) + level = LOG_DEBUG; + setLevel(level); } /** @@ -445,13 +438,13 @@ void ReLogger::buildStandardAppender(ReConfig* config, * @param maxCount the maximal count of files. If neccessary the oldest file will be deleted */ void ReLogger::buildStandardAppender(const QByteArray& prefix, int maxSize, - int maxCount) { - ReStreamAppender* streamAppender = new ReStreamAppender(stderr); - streamAppender->setAutoDelete(true); - addAppender((ReAppender*) streamAppender); - ReFileAppender* fileAppender = new ReFileAppender(prefix, maxSize, maxCount); - fileAppender->setAutoDelete(true); - addAppender((ReAppender*) fileAppender); + int maxCount){ + ReStreamAppender* streamAppender = new ReStreamAppender(stderr); + streamAppender->setAutoDelete(true); + addAppender((ReAppender*) streamAppender); + ReFileAppender* fileAppender = new ReFileAppender(prefix, maxSize, maxCount); + fileAppender->setAutoDelete(true); + addAppender((ReAppender*) fileAppender); } /** @class ReStreamAppender rpllogger.hpp "rplcore/rpllogger.hpp" @@ -461,23 +454,20 @@ void ReLogger::buildStandardAppender(const QByteArray& prefix, int maxSize, * The possible streams are std::stdout or std::stderr */ - /** * @brief Constructor. */ ReStreamAppender::ReStreamAppender(FILE* file, const char* appenderName) : - ReAppender(QByteArray(appenderName)), - m_fp(file) { + ReAppender(QByteArray(appenderName)), m_fp(file){ } /** * @brief Destructor. */ -ReStreamAppender::~ReStreamAppender() { - fflush(m_fp); +ReStreamAppender::~ReStreamAppender(){ + fflush(m_fp); } - /** * @brief Logs (or not) the current location. * @@ -487,16 +477,15 @@ ReStreamAppender::~ReStreamAppender() { * @param logger the calling logger */ void ReStreamAppender::log(ReLoggerLevel level, int location, - const char* message, ReLogger* logger) { - const QByteArray& prefix = logger->getStdPrefix(level, location); - fputs(prefix, m_fp); - fputs(message, m_fp); - fputc('\n', m_fp); - fflush(m_fp); + const char* message, ReLogger* logger){ + const QByteArray& prefix = logger->getStdPrefix(level, location); + fputs(prefix, m_fp); + fputs(message, m_fp); + fputc('\n', m_fp); + fflush(m_fp); } #pragma GCC diagnostic warning "-Wunused-parameter" - /** @class ReFileAppender rpllogger.hpp "rplcore/rpllogger.hpp" * * @brief Puts the logging info to a file. @@ -518,43 +507,43 @@ void ReStreamAppender::log(ReLoggerLevel level, int location, * @param appenderName the name of the appender. @see ReLogger::findAppender() */ ReFileAppender::ReFileAppender(const QByteArray& prefix, int maxSize, - int maxCount, const char* appenderName) : - ReAppender(QByteArray(appenderName)), - m_prefix(prefix), - m_maxSize(maxSize), - m_maxCount(maxCount), - m_currentSize(0), - m_currentNo(0), - m_fp(NULL) { - open(); + int maxCount, const char* appenderName) : + ReAppender(QByteArray(appenderName)), + m_prefix(prefix), + m_maxSize(maxSize), + m_maxCount(maxCount), + m_currentSize(0), + m_currentNo(0), + m_fp(NULL){ + open(); } /** * @brief Destructor. */ -ReFileAppender::~ReFileAppender() { - if(m_fp != NULL) { - fclose(m_fp); - m_fp = NULL; - } +ReFileAppender::~ReFileAppender(){ + if (m_fp != NULL){ + fclose(m_fp); + m_fp = NULL; + } } /** * @brief Opens the next log file. */ -void ReFileAppender::open() { - if(m_fp != NULL) - fclose(m_fp); - char fullName[512]; - qsnprintf(fullName, sizeof fullName, "%s.%03d.log", m_prefix.data(), - ++m_currentNo); - m_fp = fopen(fullName, "a"); - if(m_fp == NULL) - fprintf(stderr, "cannot open: %s\n", fullName); - else { - //@ToDo - m_currentSize = 0; - } +void ReFileAppender::open(){ + if (m_fp != NULL) + fclose(m_fp); + char fullName[512]; + qsnprintf(fullName, sizeof fullName, "%s.%03d.log", m_prefix.data(), + ++m_currentNo); + m_fp = fopen(fullName, "a"); + if (m_fp == NULL) + fprintf(stderr, "cannot open: %s\n", fullName); + else{ + //@ToDo + m_currentSize = 0; + } } /** @@ -566,16 +555,15 @@ void ReFileAppender::open() { * @param logger the calling logger */ #pragma GCC diagnostic ignored "-Wunused-parameter" -void ReFileAppender::log(ReLoggerLevel level, int location, - const char* message, - ReLogger* logger) { - if(m_fp != NULL) { - const QByteArray& prefix = logger->getStdPrefix(level, location); - fputs(prefix, m_fp); - fputs(message, m_fp); - fputc('\n', m_fp); - fflush(m_fp); - } +void ReFileAppender::log(ReLoggerLevel level, int location, const char* message, + ReLogger* logger){ + if (m_fp != NULL){ + const QByteArray& prefix = logger->getStdPrefix(level, location); + fputs(prefix, m_fp); + fputs(message, m_fp); + fputc('\n', m_fp); + fflush(m_fp); + } } #pragma GCC diagnostic warning "-Wunused-parameter" @@ -594,18 +582,17 @@ void ReFileAppender::log(ReLoggerLevel level, int location, * @param appenderName NULL or the name of the appender */ ReMemoryAppender::ReMemoryAppender(int maxLines, const char* appenderName) : - ReAppender(appenderName), - m_lines(), - m_maxLines(maxLines), - m_addPrefix(true) -{ - m_lines.reserve(maxLines); + ReAppender(appenderName), + m_lines(), + m_maxLines(maxLines), + m_addPrefix(true){ + m_lines.reserve(maxLines); } /** * @brief Destructor. */ -ReMemoryAppender::~ReMemoryAppender() { +ReMemoryAppender::~ReMemoryAppender(){ } /** @@ -618,17 +605,16 @@ ReMemoryAppender::~ReMemoryAppender() { */ #pragma GCC diagnostic ignored "-Wunused-parameter" void ReMemoryAppender::log(ReLoggerLevel level, int location, - const char* message, - ReLogger* logger) { - if(m_lines.size() >= m_maxLines) - m_lines.removeFirst(); - if (! m_addPrefix) - m_lines.append(message); - else { - QByteArray msg(logger->getStdPrefix(level, location)); - msg += message; - m_lines.append(msg); - } + const char* message, ReLogger* logger){ + if (m_lines.size() >= m_maxLines) + m_lines.removeFirst(); + if (!m_addPrefix) + m_lines.append(message); + else{ + QByteArray msg(logger->getStdPrefix(level, location)); + msg += message; + m_lines.append(msg); + } } #pragma GCC diagnostic warning "-Wunused-parameter" @@ -637,13 +623,13 @@ void ReMemoryAppender::log(ReLoggerLevel level, int location, * * @return the line list */ -const QList& ReMemoryAppender::getLines() const { - return m_lines; +const QList & ReMemoryAppender::getLines() const{ + return m_lines; } /** * @brief Deletes all log lines. */ -void ReMemoryAppender::clear() { - m_lines.clear(); +void ReMemoryAppender::clear(){ + m_lines.clear(); } diff --git a/base/ReLogger.hpp b/base/ReLogger.hpp index 125a6f6..310eb47 100644 --- a/base/ReLogger.hpp +++ b/base/ReLogger.hpp @@ -1,9 +1,12 @@ /* - * Licence: + * ReLogger.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #ifndef RELOGGER_HPP #define RELOGGER_HPP @@ -21,148 +24,148 @@ class ReConfig; * the logging is done. */ enum ReLoggerLevel { - LOG_ERROR = 10, ///< marks an error. - LOG_WARNING = 15, ///< marks a warning - LOG_INFO = 20, ///< marks an information - LOG_DEBUG = 25 ///< for debug purpose only + LOG_ERROR = 10, ///< marks an error. + LOG_WARNING = 15, ///< marks a warning + LOG_INFO = 20, ///< marks an information + LOG_DEBUG = 25 ///< for debug purpose only }; class ReAppender { public: - ReAppender(const QByteArray& name); - virtual ~ReAppender(); + ReAppender(const QByteArray& name); + virtual ~ReAppender(); private: - // No copy constructor: no implementation! - ReAppender(const ReAppender& source); - // Prohibits assignment operator: no implementation! - ReAppender& operator =(const ReAppender& source); + // No copy constructor: no implementation! + ReAppender(const ReAppender& source); + // Prohibits assignment operator: no implementation! + ReAppender& operator =(const ReAppender& source); public: - virtual void log(ReLoggerLevel level, int location, const char* message, - ReLogger* logger) = 0; - bool isActive(ReLoggerLevel level); - void setLevel(ReLoggerLevel level); - void setAutoDelete(bool onNotOff); - bool isAutoDelete() const; - ReLoggerLevel getLevel() const; - const char* getName() const; + virtual void log(ReLoggerLevel level, int location, const char* message, + ReLogger* logger) = 0; + bool isActive(ReLoggerLevel level); + void setLevel(ReLoggerLevel level); + void setAutoDelete(bool onNotOff); + bool isAutoDelete() const; + ReLoggerLevel getLevel() const; + const char* getName() const; private: - // Name of the appender. Used to find the appender in a list of appenders - QByteArray m_name; - // only locations with a lower or equal level will be logged - ReLoggerLevel m_level; - // true: the logger destroys the instance. false: the deletion must be done outside of the logger - bool m_autoDelete; + // Name of the appender. Used to find the appender in a list of appenders + QByteArray m_name; + // only locations with a lower or equal level will be logged + ReLoggerLevel m_level; + // true: the logger destroys the instance. false: the deletion must be done outside of the logger + bool m_autoDelete; }; class ReLogger { public: - static ReLogger* globalLogger(); - static void destroyGlobalLogger(); + static ReLogger* globalLogger(); + static void destroyGlobalLogger(); private: - // the standard logger, can be called (with globalLogger()) from each location - static ReLogger* m_globalLogger; + // the standard logger, can be called (with globalLogger()) from each location + static ReLogger* m_globalLogger; public: - ReLogger(); - virtual ~ReLogger(); + ReLogger(); + virtual ~ReLogger(); private: - // No copy constructor: no implementation! - ReLogger(const ReLogger& source); - // Prohibits assignment operator: no implementation! - ReLogger& operator =(const ReLogger& source); + // No copy constructor: no implementation! + ReLogger(const ReLogger& source); + // Prohibits assignment operator: no implementation! + ReLogger& operator =(const ReLogger& source); public: - bool log(ReLoggerLevel level, int location, const char* message); - bool log(ReLoggerLevel level, int location, const QByteArray& message); - bool log(ReLoggerLevel level, int location, const ReString& message); - bool logv(ReLoggerLevel level, int location, const char* format, ...); - bool logv(ReLoggerLevel level, int location, const QByteArray& format, ...); - bool log(ReLoggerLevel level, int location, const char* format, - va_list& varlist); - void addAppender(ReAppender* appender); - ReAppender* findAppender(const char* name) const; - void buildStandardAppender(ReConfig* config, const char* prefix = "logfile.", - const char* defaultLoggerName = "logger"); - void buildStandardAppender(const QByteArray& prefix, int maxSize = 10*1024*1024, - int maxCount = 5); - QByteArray buildStdPrefix(ReLoggerLevel level, int location); - const QByteArray& getStdPrefix(ReLoggerLevel level, int location); - char getPrefixOfLevel(ReLoggerLevel level) const; - bool isActive(ReLoggerLevel level) const; - void setLevel(ReLoggerLevel level); - void setWithLocking(bool onNotOff); + bool log(ReLoggerLevel level, int location, const char* message); + bool log(ReLoggerLevel level, int location, const QByteArray& message); + bool log(ReLoggerLevel level, int location, const ReString& message); + bool logv(ReLoggerLevel level, int location, const char* format, ...); + bool logv(ReLoggerLevel level, int location, const QByteArray& format, ...); + bool log(ReLoggerLevel level, int location, const char* format, + va_list& varlist); + void addAppender(ReAppender* appender); + ReAppender* findAppender(const char* name) const; + void buildStandardAppender(ReConfig* config, const char* prefix = "logfile.", + const char* defaultLoggerName = "logger"); + void buildStandardAppender(const QByteArray& prefix, + int maxSize = 10 * 1024 * 1024, int maxCount = 5); + QByteArray buildStdPrefix(ReLoggerLevel level, int location); + const QByteArray& getStdPrefix(ReLoggerLevel level, int location); + char getPrefixOfLevel(ReLoggerLevel level) const; + bool isActive(ReLoggerLevel level) const; + void setLevel(ReLoggerLevel level); + void setWithLocking(bool onNotOff); private: - // the assigned appenders: - ReAppender* m_appenders[16]; - // the number of appenders in m_appenders: - size_t m_countAppenders; - // "" or the cache of the prefix of the current logging line: This can be reused by any appender. - QByteArray m_stdPrefix; - QMutex m_mutex; - bool m_withLocking; + // the assigned appenders: + ReAppender* m_appenders[16]; + // the number of appenders in m_appenders: + size_t m_countAppenders; + // "" or the cache of the prefix of the current logging line: This can be reused by any appender. + QByteArray m_stdPrefix; + QMutex m_mutex; + bool m_withLocking; }; /** * Implements an appender which puts the messages to a standard stream: stdout or stderr */ -class ReStreamAppender : public ReAppender { +class ReStreamAppender: public ReAppender { public: - ReStreamAppender(FILE* stream, const char* appenderName = "FileAppender"); - virtual ~ReStreamAppender(); + ReStreamAppender(FILE* stream, const char* appenderName = "FileAppender"); + virtual ~ReStreamAppender(); public: - virtual void log(ReLoggerLevel level, int location, const char* message, - ReLogger* logger); + virtual void log(ReLoggerLevel level, int location, const char* message, + ReLogger* logger); private: - // stdout or stderr: - FILE* m_fp; + // stdout or stderr: + FILE* m_fp; }; /** * Implements an appender which puts the messages to a file */ -class ReFileAppender : public ReAppender { +class ReFileAppender: public ReAppender { public: - ReFileAppender(const QByteArray& name, int maxSize, int maxCount, - const char* appenderName = "FileAppender"); - virtual ~ReFileAppender(); + ReFileAppender(const QByteArray& name, int maxSize, int maxCount, + const char* appenderName = "FileAppender"); + virtual ~ReFileAppender(); public: - void open(); - virtual void log(ReLoggerLevel level, int location, const char* message, - ReLogger* logger); + void open(); + virtual void log(ReLoggerLevel level, int location, const char* message, + ReLogger* logger); private: - // prefix of the log file name. Will be appended by "..log" - QByteArray m_prefix; - // maximal size of a logging file: - int m_maxSize; - // maximal count of logging files. If neccessary the oldest file will be deleted. - int m_maxCount; - // the size of the current log file: - int m_currentSize; - // the number of the current log file: - int m_currentNo; - // the current log file: - FILE* m_fp; + // prefix of the log file name. Will be appended by "..log" + QByteArray m_prefix; + // maximal size of a logging file: + int m_maxSize; + // maximal count of logging files. If neccessary the oldest file will be deleted. + int m_maxCount; + // the size of the current log file: + int m_currentSize; + // the number of the current log file: + int m_currentNo; + // the current log file: + FILE* m_fp; }; /** * Stores the log messages in a list. */ -class ReMemoryAppender : public ReAppender { +class ReMemoryAppender: public ReAppender { public: - ReMemoryAppender(int maxLines = 1024, - const char* appenderName = "MemoryAppender"); - ~ReMemoryAppender(); + ReMemoryAppender(int maxLines = 1024, const char* appenderName = + "MemoryAppender"); + ~ReMemoryAppender(); public: - virtual void log(ReLoggerLevel level, int location, const char* message, - ReLogger* logger); - const QList& getLines() const; - void clear(); + virtual void log(ReLoggerLevel level, int location, const char* message, + ReLogger* logger); + const QList & getLines() const; + void clear(); private: - QList m_lines; - // maximum count of m_lines. If larger the oldest lines will be deleted. - int m_maxLines; - // true: standard prefix (level + datetime) will be stored too. - bool m_addPrefix; + QList m_lines; + // maximum count of m_lines. If larger the oldest lines will be deleted. + int m_maxLines; + // true: standard prefix (level + datetime) will be stored too. + bool m_addPrefix; }; #endif // RELOGGER_HPP diff --git a/base/ReQString.cpp b/base/ReQString.cpp index 171401b..a57930b 100644 --- a/base/ReQString.cpp +++ b/base/ReQString.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * ReQString.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * @brief Missed operation for ReStrings. @@ -15,7 +18,6 @@ */ #include "base/rebase.hpp" - /** * @brief Determines the length and vlaue of an integer. * @@ -27,47 +29,46 @@ * @return <=0: no integer found * otherwise: the length of the integer */ -int ReQString::lengthOfUInt64(const ReString& text, int start, - int radix, quint64* pValue) -{ - int inputLength = text.size(); - int64_t value = 0; - int ix = start; - int cc; - if (radix == 10){ - while (ix < inputLength){ - if ( (cc = text[ix].unicode()) >= '0' && cc <= '9') - value = value * 10 + cc - '0'; - else - break; - ix++; - } - } else if (radix == 16){ - while (ix < inputLength){ - if ( (cc = text[ix].unicode()) >= '0' && cc <= '9') - value = value * 16 + cc - '0'; - else if (cc >= 'A' && cc <= 'F') - value = value * 16 + cc - 'A' + 10; - else if (cc >= 'a' && cc <= 'f') - value = value * 16 + cc - 'a' + 10; - else - break; - ix++; - } - } else if (radix == 8){ - while (ix < inputLength){ - if ( (cc = text[ix].unicode()) >= '0' && cc <= '7') - value = value * 8 + cc - '0'; - else - break; - ix++; - } - } else { - throw ReException("ReQString::lengthOfInt(): wrong radix: %d", radix); - } - if (pValue != NULL) - *pValue = value; - return ix - start; +int ReQString::lengthOfUInt64(const ReString& text, int start, int radix, + quint64* pValue){ + int inputLength = text.size(); + int64_t value = 0; + int ix = start; + int cc; + if (radix == 10){ + while (ix < inputLength){ + if ((cc = text[ix].unicode()) >= '0' && cc <= '9') + value = value * 10 + cc - '0'; + else + break; + ix++; + } + }else if (radix == 16){ + while (ix < inputLength){ + if ((cc = text[ix].unicode()) >= '0' && cc <= '9') + value = value * 16 + cc - '0'; + else if (cc >= 'A' && cc <= 'F') + value = value * 16 + cc - 'A' + 10; + else if (cc >= 'a' && cc <= 'f') + value = value * 16 + cc - 'a' + 10; + else + break; + ix++; + } + }else if (radix == 8){ + while (ix < inputLength){ + if ((cc = text[ix].unicode()) >= '0' && cc <= '7') + value = value * 8 + cc - '0'; + else + break; + ix++; + } + }else{ + throw ReException("ReQString::lengthOfInt(): wrong radix: %d", radix); + } + if (pValue != NULL) + *pValue = value; + return ix - start; } /** * @brief Determines the length and value of an unsigned integer. @@ -80,14 +81,13 @@ int ReQString::lengthOfUInt64(const ReString& text, int start, * @return 0: no integer found * otherwise: the length of the integer */ -int ReQString::lengthOfUInt(const ReString& text, int start, - int radix, uint* pValue) -{ - quint64 value; - int rc = lengthOfUInt64(text, start, radix, &value); - if (pValue != NULL) - *pValue = (uint) value; - return rc; +int ReQString::lengthOfUInt(const ReString& text, int start, int radix, + uint* pValue){ + quint64 value; + int rc = lengthOfUInt64(text, start, radix, &value); + if (pValue != NULL) + *pValue = (uint) value; + return rc; } /** @@ -100,64 +100,63 @@ int ReQString::lengthOfUInt(const ReString& text, int start, * @return <=0: no real number found * otherwise: the length of the floating point number */ -int ReQString::lengthOfReal(const ReString& text, int start, qreal* pValue) -{ - int inputLength = text.size(); - qreal value = 0.0; - int cc; - int ix = start; - while (ix < inputLength){ - if ( (cc = text[ix].unicode()) >= '0' && cc <= '9') - value = value * 10 + (cc - '0'); - else - break; - ix++; - } - // found: a digit has been found (in front of or behind the '.' - bool found = ix > start; - if (ix < inputLength && text[ix].unicode() == '.'){ - ix++; - } - if (ix < inputLength && text[ix].isDigit()){ - found = true; - qreal divisor = 1; - qreal precision = 0; - while ( ix < inputLength && (cc = text[ix].unicode()) >= '0' && cc <= '9'){ - divisor *= 10; - precision = precision*10 + cc - '0'; - ix++; - } - value += precision / divisor; - } else if (! found){ - ix = start; - } - if (found && ix + 1 < inputLength && toupper(text[ix].unicode()) == 'E'){ - int savePoint = ix; - ix++; - bool negative = false; - if ( (cc = text[ix].unicode()) == '+') - ix++; - else if (cc == '-'){ +int ReQString::lengthOfReal(const ReString& text, int start, qreal* pValue){ + int inputLength = text.size(); + qreal value = 0.0; + int cc; + int ix = start; + while (ix < inputLength){ + if ((cc = text[ix].unicode()) >= '0' && cc <= '9') + value = value * 10 + (cc - '0'); + else + break; + ix++; + } + // found: a digit has been found (in front of or behind the '.' + bool found = ix > start; + if (ix < inputLength && text[ix].unicode() == '.'){ + ix++; + } + if (ix < inputLength && text[ix].isDigit()){ + found = true; + qreal divisor = 1; + qreal precision = 0; + while (ix < inputLength && (cc = text[ix].unicode()) >= '0' && cc <= '9'){ + divisor *= 10; + precision = precision * 10 + cc - '0'; + ix++; + } + value += precision / divisor; + }else if (!found){ + ix = start; + } + if (found && ix + 1 < inputLength && toupper(text[ix].unicode()) == 'E'){ + int savePoint = ix; + ix++; + bool negative = false; + if ((cc = text[ix].unicode()) == '+') + ix++; + else if (cc == '-'){ + ix++; + negative = true; + } + if (ix >= inputLength || !text[ix].isDigit()) + ix = savePoint; + else{ + int exponent = 0; + while (ix < inputLength && text[ix].isDigit()){ + exponent = exponent * 10 + text[ix].unicode() - '0'; ix++; - negative = true; - } - if (ix >= inputLength || ! text[ix].isDigit()) - ix = savePoint; - else{ - int exponent = 0; - while (ix < inputLength && text[ix].isDigit()){ - exponent = exponent * 10 + text[ix].unicode() - '0'; - ix++; - } - if (negative) - value /= qPow(10, exponent); - else - value *= qPow(10, exponent); - } - } - if (pValue) - *pValue = value; - return found ? ix - start : 0; + } + if (negative) + value /= qPow(10, exponent); + else + value *= qPow(10, exponent); + } + } + if (pValue) + *pValue = value; + return found ? ix - start : 0; } /** @@ -171,12 +170,11 @@ int ReQString::lengthOfReal(const ReString& text, int start, qreal* pValue) * @param bufferSize size of the target buffer * @return buffer */ -char*ReQString::utf8(const ReString& source, char buffer[], size_t bufferSize) -{ - QByteArray val = source.toUtf8(); - if (val.length() < (int) bufferSize) - bufferSize = val.length() + 1; - memcpy(buffer, val.constData(), bufferSize - 1); - buffer[bufferSize - 1] = '\0'; - return buffer; +char*ReQString::utf8(const ReString& source, char buffer[], size_t bufferSize){ + QByteArray val = source.toUtf8(); + if (val.length() < (int) bufferSize) + bufferSize = val.length() + 1; + memcpy(buffer, val.constData(), bufferSize - 1); + buffer[bufferSize - 1] = '\0'; + return buffer; } diff --git a/base/ReQtring.hpp b/base/ReQtring.hpp index 3a3bcf5..77e1e94 100644 --- a/base/ReQtring.hpp +++ b/base/ReQtring.hpp @@ -1,37 +1,38 @@ /* - * Licence: + * ReQtring.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ - + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #ifndef RPLQSTRING_HPP #define RPLQSTRING_HPP -class ReQString -{ +class ReQString { public: - static int lengthOfUInt64(const ReString& text, int start = 0, - int radix = 10, quint64* value = NULL); - static int lengthOfUInt(const ReString& text, int start, int radix, - uint* pValue); - static int lengthOfReal(const ReString& text, int start = 0, - qreal* value = NULL); - /** - * @brief Returns the value of a hexadecimal digit. - * - * @param digit a (unicode) character - * @return -1: not a hexadecimal digit
- * otherwise: the value, e.g. 10 for 'a' - */ - inline static int valueOfHexDigit(int digit){ - return digit >= '0' && digit <= '9' ? digit - '0' - : digit >= 'A' && digit <= 'F' ? digit - 'A' + 10 - : digit >= 'a' && digit <= 'f' ? digit - 'a' + 10 : -1; - } - static char* utf8(const ReString& source, char buffer[], size_t bufferSize); + static int lengthOfUInt64(const ReString& text, int start = 0, + int radix = 10, quint64* value = NULL); + static int lengthOfUInt(const ReString& text, int start, int radix, + uint* pValue); + static int lengthOfReal(const ReString& text, int start = 0, qreal* value = + NULL); + /** + * @brief Returns the value of a hexadecimal digit. + * + * @param digit a (unicode) character + * @return -1: not a hexadecimal digit
+ * otherwise: the value, e.g. 10 for 'a' + */ + inline static int valueOfHexDigit(int digit){ + return digit >= '0' && digit <= '9' ? digit - '0' : + digit >= 'A' && digit <= 'F' ? digit - 'A' + 10 : + digit >= 'a' && digit <= 'f' ? digit - 'a' + 10 : -1; + } + static char* utf8(const ReString& source, char buffer[], size_t bufferSize); }; #endif // RPLQSTRING_HPP diff --git a/base/ReStringUtil.cpp b/base/ReStringUtil.cpp index 0afebec..5abe0e0 100644 --- a/base/ReStringUtil.cpp +++ b/base/ReStringUtil.cpp @@ -1,9 +1,12 @@ /* - * Licence: + * ReStringUtil.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ /** @file * @brief Missed operations for QByteArrays. @@ -28,15 +31,14 @@ * @param cc the char to count * @return the number of cc in the text */ -int ReStringUtil::countChar(const char* line, char cc) -{ - const char* ptr = line; - int rc = 0; - while( (ptr = strchr(ptr, cc)) != NULL){ - rc++; - ptr++; - } - return rc; +int ReStringUtil::countChar(const char* line, char cc){ + const char* ptr = line; + int rc = 0; + while ((ptr = strchr(ptr, cc)) != NULL){ + rc++; + ptr++; + } + return rc; } /** * Counts the occurrences of a string in a string. @@ -45,21 +47,21 @@ int ReStringUtil::countChar(const char* line, char cc) * @param item this item will be searched * @return the count of occurrences */ -int ReStringUtil::count(const char* source, const char* item) { - const char* end = source; - int rc = 0; - int lengthItem = strlen(item); - while(true) { - const char* start = end; - end = strstr(start, item); - if(end == NULL) - break; - else { - rc++; - end += lengthItem; - } - } - return rc; +int ReStringUtil::count(const char* source, const char* item){ + const char* end = source; + int rc = 0; + int lengthItem = strlen(item); + while (true){ + const char* start = end; + end = strstr(start, item); + if (end == NULL) + break; + else{ + rc++; + end += lengthItem; + } + } + return rc; } /** @@ -73,15 +75,16 @@ int ReStringUtil::count(const char* source, const char* item) { * @return source: the source is enough short
* the prefix of source with the given length */ -const QByteArray& ReStringUtil::cutString(const QByteArray& source, int maxLength, - QByteArray& buffer, const char* appendix) { - QByteArray& rc = source.length() <= maxLength ? (QByteArray&) source : buffer; - if(source.length() > maxLength) { - buffer = source.left(maxLength); - if(appendix != NULL && appendix[0] != '\0') - buffer.append(appendix); - } - return rc; +const QByteArray& ReStringUtil::cutString(const QByteArray& source, + int maxLength, QByteArray& buffer, const char* appendix){ + QByteArray& rc = + source.length() <= maxLength ? (QByteArray&) source : buffer; + if (source.length() > maxLength){ + buffer = source.left(maxLength); + if (appendix != NULL && appendix[0] != '\0') + buffer.append(appendix); + } + return rc; } static char s_fileSeparator = 0; @@ -90,7 +93,7 @@ static char s_fileSeparator = 0; * @return the file path separator, e.g. "/" for linux */ const char* ReStringUtil::fileSeparator(){ - return fileSeparatorChar() == '/' ? "/" : "\\"; + return fileSeparatorChar() == '/' ? "/" : "\\"; } /** @@ -98,19 +101,20 @@ const char* ReStringUtil::fileSeparator(){ * @return the file path separator, e.g. '/' for linux */ char ReStringUtil::fileSeparatorChar(){ - if (s_fileSeparator == 0){ - const char* path = getenv("PATH"); - if (path != NULL){ - s_fileSeparator = strchr(path, ';') != NULL - || strchr(path, '\\') != NULL ? '\\' : '/'; - } else { - if (getenv("windows") != NULL) - s_fileSeparator = '\\'; - else - s_fileSeparator = '/'; - } - } - return s_fileSeparator; + if (s_fileSeparator == 0){ + const char* path = getenv("PATH"); + if (path != NULL){ + s_fileSeparator = + strchr(path, ';') != NULL || strchr(path, '\\') != NULL ? + '\\' : '/'; + }else{ + if (getenv("windows") != NULL) + s_fileSeparator = '\\'; + else + s_fileSeparator = '/'; + } + } + return s_fileSeparator; } /** @@ -125,48 +129,47 @@ char ReStringUtil::fileSeparatorChar(){ * @param bytesPerLine one line containes so many bytes of data * @return the hex dump */ -QByteArray ReStringUtil::hexDump(uint8_t* data, int length, int bytesPerLine) { - QByteArray rc; - int fullLines = length / bytesPerLine; - int expectedLength = (bytesPerLine * 4 + 2) * (fullLines + 1); - rc.reserve(expectedLength + 100); - int ixData = 0; - int col; - char buffer[16]; - for(int lineNo = 0; lineNo < fullLines; lineNo++) { - for(col = 0; col < bytesPerLine; col++) { - qsnprintf(buffer, sizeof buffer, "%02x ", data[ixData + col]); - rc.append(buffer); - } - rc.append(' '); - for(col = 0; col < bytesPerLine; col++) { - uint8_t cc = data[ixData + col]; - rc.append(cc > ' ' && cc < 128 ? (char) cc : '.'); - } - ixData += bytesPerLine; - rc.append('\n'); - } - // incomplete last line: - int restBytes = length - ixData; - if(restBytes > 0) { - for(col = 0; col < restBytes; col++) { - qsnprintf(buffer, sizeof buffer, "%02x ", data[ixData + col]); - rc.append(buffer); - } - for(col = restBytes; col < bytesPerLine; col++) { - rc.append(" "); - } - rc.append(' '); - for(col = 0; col < restBytes; col++) { - uint8_t cc = data[ixData + col]; - rc.append(cc > ' ' && cc < 128 ? (char) cc : '.'); - } - rc.append('\n'); - } - return rc; +QByteArray ReStringUtil::hexDump(uint8_t* data, int length, int bytesPerLine){ + QByteArray rc; + int fullLines = length / bytesPerLine; + int expectedLength = (bytesPerLine * 4 + 2) * (fullLines + 1); + rc.reserve(expectedLength + 100); + int ixData = 0; + int col; + char buffer[16]; + for (int lineNo = 0; lineNo < fullLines; lineNo++){ + for (col = 0; col < bytesPerLine; col++){ + qsnprintf(buffer, sizeof buffer, "%02x ", data[ixData + col]); + rc.append(buffer); + } + rc.append(' '); + for (col = 0; col < bytesPerLine; col++){ + uint8_t cc = data[ixData + col]; + rc.append(cc > ' ' && cc < 128 ? (char) cc : '.'); + } + ixData += bytesPerLine; + rc.append('\n'); + } + // incomplete last line: + int restBytes = length - ixData; + if (restBytes > 0){ + for (col = 0; col < restBytes; col++){ + qsnprintf(buffer, sizeof buffer, "%02x ", data[ixData + col]); + rc.append(buffer); + } + for (col = restBytes; col < bytesPerLine; col++){ + rc.append(" "); + } + rc.append(' '); + for (col = 0; col < restBytes; col++){ + uint8_t cc = data[ixData + col]; + rc.append(cc > ' ' && cc < 128 ? (char) cc : '.'); + } + rc.append('\n'); + } + return rc; } - /** * Reads a file into a string. * @@ -175,37 +178,37 @@ QByteArray ReStringUtil::hexDump(uint8_t* data, int length, int bytesPerLine) { * the result will not contain this * @return the file's content */ -QByteArray ReStringUtil::read(const char* file, bool removeLastNewline) { - QByteArray rc; - struct stat info; - size_t size; - if(stat(file, &info) == 0 && (size = info.st_size) > 0) { - FILE* fp = fopen(file, "r"); - if(fp != NULL) { - rc.resize(info.st_size); - fread(rc.data(), 1, size, fp); - fclose(fp); - if(removeLastNewline && rc.at(size - 1) == '\n') { - rc.resize(size - 1); - } - } - } - return rc; +QByteArray ReStringUtil::read(const char* file, bool removeLastNewline){ + QByteArray rc; + struct stat info; + size_t size; + if (stat(file, &info) == 0 && (size = info.st_size) > 0){ + FILE* fp = fopen(file, "r"); + if (fp != NULL){ + rc.resize(info.st_size); + fread(rc.data(), 1, size, fp); + fclose(fp); + if (removeLastNewline && rc.at(size - 1) == '\n'){ + rc.resize(size - 1); + } + } + } + return rc; } QByteArray ReStringUtil::replaceNode(const char* source, const char* newNode){ - char sep = fileSeparatorChar(); - const char* ptr = strrchr(source, sep); - QByteArray rc; - rc.reserve(strlen(source) + strlen(newNode) + 1); - if (ptr == NULL){ - rc.append(source).append(sep).append(newNode); - } else if (ptr[0] == '\0'){ - rc.append(source).append(newNode); - } else { - rc.append(source, ptr - source + 1).append(newNode); - } - return rc; + char sep = fileSeparatorChar(); + const char* ptr = strrchr(source, sep); + QByteArray rc; + rc.reserve(strlen(source) + strlen(newNode) + 1); + if (ptr == NULL){ + rc.append(source).append(sep).append(newNode); + }else if (ptr[0] == '\0'){ + rc.append(source).append(newNode); + }else{ + rc.append(source, ptr - source + 1).append(newNode); + } + return rc; } /** @@ -215,66 +218,65 @@ QByteArray ReStringUtil::replaceNode(const char* source, const char* newNode){ * @param separator the separator between the items to split * @return an array with the splitted source */ -QList ReStringUtil::toArray(const char* source, - const char* separator) { - const char* end = source; - QList rc; - rc.reserve(count(source, separator) + 1); - int lengthItem = strlen(separator); - while(*end != '\0') { - const char* start = end; - end = strstr(start, separator); - if(end == NULL) { - end = start + strlen(start); - } - rc.append(QByteArray(start, end - start)); - if(end[0] != '\0') - end += lengthItem; - } - return rc; +QList ReStringUtil::toArray(const char* source, + const char* separator){ + const char* end = source; + QList < QByteArray > rc; + rc.reserve(count(source, separator) + 1); + int lengthItem = strlen(separator); + while (*end != '\0'){ + const char* start = end; + end = strstr(start, separator); + if (end == NULL){ + end = start + strlen(start); + } + rc.append(QByteArray(start, end - start)); + if (end[0] != '\0') + end += lengthItem; + } + return rc; } QByteArray ReStringUtil::toCString(const char* source, int maxLength){ - if (maxLength <= 0) - maxLength = strlen(source); - int binaries = 0; - int ix; - for (ix = 0; ix < maxLength; ix++) - if (source[ix] < ' '){ - binaries++; - } - QByteArray rc; - rc.reserve(maxLength + 3 * binaries + 1); - char cc; - for (ix = 0; ix < maxLength; ix++) - if ( (cc = source[ix]) >= ' '){ - rc += source[ix]; - } else { - switch(cc){ - case '\0': - // stop looping: - ix = maxLength; - break; - case '\n': - rc += "\\n"; - break; - case '\r': - rc += "\\r"; - break; - case '\t': - rc += "\\t"; - break; - default: - { - char buffer[5]; - qsnprintf(buffer, sizeof buffer, "\\x%02x", - ((unsigned int) cc) % 0xff); - rc += buffer; - break; - } - } - } - return rc; + if (maxLength <= 0) + maxLength = strlen(source); + int binaries = 0; + int ix; + for (ix = 0; ix < maxLength; ix++) + if (source[ix] < ' '){ + binaries++; + } + QByteArray rc; + rc.reserve(maxLength + 3 * binaries + 1); + char cc; + for (ix = 0; ix < maxLength; ix++) + if ((cc = source[ix]) >= ' '){ + rc += source[ix]; + }else{ + switch (cc) { + case '\0': + // stop looping: + ix = maxLength; + break; + case '\n': + rc += "\\n"; + break; + case '\r': + rc += "\\r"; + break; + case '\t': + rc += "\\t"; + break; + default: { + char buffer[5]; + qsnprintf(buffer, sizeof buffer, "\\x%02x", + ((unsigned int) cc) % 0xff); + rc += buffer; + break; + } + } + } + return rc; } /** @@ -284,10 +286,10 @@ QByteArray ReStringUtil::toCString(const char* source, int maxLength){ * @param format format like in sprintf() * @return the ascii form of the value */ -QByteArray ReStringUtil::toNumber(int value, const char* format) { - char buffer[128]; - qsnprintf(buffer, sizeof buffer, format, value); - return QByteArray(buffer); +QByteArray ReStringUtil::toNumber(int value, const char* format){ + char buffer[128]; + qsnprintf(buffer, sizeof buffer, format, value); + return QByteArray(buffer); } /** @@ -299,13 +301,14 @@ QByteArray ReStringUtil::toNumber(int value, const char* format) { * @return true: successful
* false: error occurred */ -bool ReStringUtil::write(const char* file, const char* content, const char* mode) { - FILE* fp = fopen(file, mode); - if(fp != NULL) { - fputs(content, fp); - fclose(fp); - } - return fp != NULL; +bool ReStringUtil::write(const char* file, const char* content, + const char* mode){ + FILE* fp = fopen(file, mode); + if (fp != NULL){ + fputs(content, fp); + fclose(fp); + } + return fp != NULL; } /** * @brief Returns the length of the number string. @@ -317,44 +320,44 @@ bool ReStringUtil::write(const char* file, const char* content, const char* mode * otherwise: the length of the number string */ int ReStringUtil::lengthOfNumber(const char* text, bool skipTrailingSpaces){ - int rc = 0; - bool found = false; - const char* ptr = text; - while(isspace(*ptr)) - ptr++; - if ( (*ptr == '+' || *ptr == '-')) - ptr++; - found = isdigit(*ptr); - while(isdigit(*ptr)){ - ptr++; - } - if (*ptr == '.'){ - ptr++; - if (isdigit(*ptr)){ - found = true; - while(isdigit(*ptr)) - ptr++; - } - } - if (found && toupper(*ptr) == 'E'){ - const char* ptrToE = ptr; - ptr++; - if (*ptr == '+' || *ptr == '-') + int rc = 0; + bool found = false; + const char* ptr = text; + while (isspace(*ptr)) + ptr++; + if ((*ptr == '+' || *ptr == '-')) + ptr++; + found = isdigit(*ptr); + while (isdigit(*ptr)){ + ptr++; + } + if (*ptr == '.'){ + ptr++; + if (isdigit(*ptr)){ + found = true; + while (isdigit(*ptr)) ptr++; - if (! isdigit(*ptr)) - ptr = ptrToE; - else { - while(isdigit(*ptr)) - ptr++; - } - } - if (found && skipTrailingSpaces){ - while(isspace(*ptr)){ + } + } + if (found && toupper(*ptr) == 'E'){ + const char* ptrToE = ptr; + ptr++; + if (*ptr == '+' || *ptr == '-') + ptr++; + if (!isdigit(*ptr)) + ptr = ptrToE; + else{ + while (isdigit(*ptr)) ptr++; - } - } - rc = ! found ? 0 : ptr - text; - return rc; + } + } + if (found && skipTrailingSpaces){ + while (isspace(*ptr)){ + ptr++; + } + } + rc = !found ? 0 : ptr - text; + return rc; } /** * @brief Adds the count of the possible separators. @@ -365,12 +368,11 @@ int ReStringUtil::lengthOfNumber(const char* text, bool skipTrailingSpaces){ * @param countBlanks IN/OUT: number of ' ' */ static void addSeparators(const char* line, int& commas, int& semicolons, - int& pipes, int& blanks) -{ - commas += ReStringUtil::countChar(line, ','); - semicolons += ReStringUtil::countChar(line, ';'); - pipes += ReStringUtil::countChar(line, '|'); - blanks += ReStringUtil::countChar(line, ' '); + int& pipes, int& blanks){ + commas += ReStringUtil::countChar(line, ','); + semicolons += ReStringUtil::countChar(line, ';'); + pipes += ReStringUtil::countChar(line, '|'); + blanks += ReStringUtil::countChar(line, ' '); } /** @@ -386,39 +388,39 @@ static void addSeparators(const char* line, int& commas, int& semicolons, * @param bufferSize the size of buffer[] */ char ReStringUtil::findCsvSeparator(FILE* fp, char* buffer, size_t bufferSize){ - char rc = '\0'; - int lineNo = 0; - int maxLines = 5; - const char* line; - int commas = 0; - int semicolons = 0; - int pipes = 0; - int blanks = 0; - while(++lineNo < maxLines && (line = fgets(buffer, bufferSize, fp)) != NULL){ - if (strchr(line, '\t') != NULL){ - rc = '\t'; - break; - } - addSeparators(line, commas, semicolons, pipes, blanks); - } - fseek(fp, 0, SEEK_SET); - if (rc != '\t'){ - if (semicolons > 0 && commas > 0){ - // if ',' is decimal separator and ';' is the column separator: - // Add one semicolon per line because of number of values is - // 1 greater than the number of separators - semicolons += lineNo; - } - if (commas + semicolons + pipes == 0) { - rc = blanks > 0 ? ' ' : '\0'; - } else if (semicolons >= commas && semicolons >= pipes) - rc = ';'; - else if (commas > semicolons && commas > pipes) - rc = ','; - else if (pipes > commas && pipes > semicolons) - rc = '|'; - } - return rc; + char rc = '\0'; + int lineNo = 0; + int maxLines = 5; + const char* line; + int commas = 0; + int semicolons = 0; + int pipes = 0; + int blanks = 0; + while (++lineNo < maxLines && (line = fgets(buffer, bufferSize, fp)) != NULL){ + if (strchr(line, '\t') != NULL){ + rc = '\t'; + break; + } + addSeparators(line, commas, semicolons, pipes, blanks); + } + fseek(fp, 0, SEEK_SET); + if (rc != '\t'){ + if (semicolons > 0 && commas > 0){ + // if ',' is decimal separator and ';' is the column separator: + // Add one semicolon per line because of number of values is + // 1 greater than the number of separators + semicolons += lineNo; + } + if (commas + semicolons + pipes == 0){ + rc = blanks > 0 ? ' ' : '\0'; + }else if (semicolons >= commas && semicolons >= pipes) + rc = ';'; + else if (commas > semicolons && commas > pipes) + rc = ','; + else if (pipes > commas && pipes > semicolons) + rc = '|'; + } + return rc; } /** @@ -431,42 +433,41 @@ char ReStringUtil::findCsvSeparator(FILE* fp, char* buffer, size_t bufferSize){ * @return <=0: no integer found * otherwise: the length of the integer */ -int ReStringUtil::lengthOfUInt64(const char* text, int radix, quint64* pValue) -{ - int64_t value = 0; - int length = 0; - int cc; - if (radix == 10){ - while ( (cc = text[length]) >= '0' && cc <= '9'){ - value = value * 10 + cc - '0'; - length++; - } - } else if (radix == 16){ - while (true){ - if ( (cc = text[length]) >= '0' && cc <= '9') - value = value * 16 + cc - '0'; - else if (cc >= 'A' && cc <= 'F') - value = value * 16 + cc - 'A' + 10; - else if (cc >= 'a' && cc <= 'f') - value = value * 16 + cc - 'a' + 10; - else - break; - length++; - } - } else if (radix == 8){ - while (true){ - if ( (cc = text[length]) >= '0' && cc <= '7') - value = value * 8 + cc - '0'; - else - break; - length++; - } - } else { - throw ReException("ReStringUtil::lengthOfInt(): wrong radix: %d", radix); - } - if (pValue != NULL) - *pValue = value; - return length; +int ReStringUtil::lengthOfUInt64(const char* text, int radix, quint64* pValue){ + int64_t value = 0; + int length = 0; + int cc; + if (radix == 10){ + while ((cc = text[length]) >= '0' && cc <= '9'){ + value = value * 10 + cc - '0'; + length++; + } + }else if (radix == 16){ + while (true){ + if ((cc = text[length]) >= '0' && cc <= '9') + value = value * 16 + cc - '0'; + else if (cc >= 'A' && cc <= 'F') + value = value * 16 + cc - 'A' + 10; + else if (cc >= 'a' && cc <= 'f') + value = value * 16 + cc - 'a' + 10; + else + break; + length++; + } + }else if (radix == 8){ + while (true){ + if ((cc = text[length]) >= '0' && cc <= '7') + value = value * 8 + cc - '0'; + else + break; + length++; + } + }else{ + throw ReException("ReStringUtil::lengthOfInt(): wrong radix: %d", radix); + } + if (pValue != NULL) + *pValue = value; + return length; } /** @@ -478,62 +479,61 @@ int ReStringUtil::lengthOfUInt64(const char* text, int radix, quint64* pValue) * @return <=0: no real number found * otherwise: the length of the floating point number */ -int ReStringUtil::lengthOfReal(const char* text, qreal* pValue) -{ - qreal value = 0.0; - int cc; - int length = 0; - while (true){ - if ( (cc = text[length]) >= '0' && cc <= '9') - value = value * 10 + (cc - '0'); - else - break; - length++; - } - // found: a digit has been found (in front of or behind the '.' - bool found = length > 0; - if (text[length] == '.'){ - length++; - } - if (isdigit(text[length])){ - found = true; - qreal divisor = 1; - qreal precision = 0; - while ( (cc = text[length]) >= '0' && cc <= '9'){ - divisor *= 10; - precision = precision*10 + cc - '0'; - length++; - } - value += precision / divisor; - } else if (! found){ - length = 0; - } - if (found && toupper(text[length]) == 'E'){ - int savePoint = length; - length++; - bool negative = false; - if ( (cc = text[length]) == '+') - length++; - else if (cc == '-'){ +int ReStringUtil::lengthOfReal(const char* text, qreal* pValue){ + qreal value = 0.0; + int cc; + int length = 0; + while (true){ + if ((cc = text[length]) >= '0' && cc <= '9') + value = value * 10 + (cc - '0'); + else + break; + length++; + } + // found: a digit has been found (in front of or behind the '.' + bool found = length > 0; + if (text[length] == '.'){ + length++; + } + if (isdigit(text[length])){ + found = true; + qreal divisor = 1; + qreal precision = 0; + while ((cc = text[length]) >= '0' && cc <= '9'){ + divisor *= 10; + precision = precision * 10 + cc - '0'; + length++; + } + value += precision / divisor; + }else if (!found){ + length = 0; + } + if (found && toupper(text[length]) == 'E'){ + int savePoint = length; + length++; + bool negative = false; + if ((cc = text[length]) == '+') + length++; + else if (cc == '-'){ + length++; + negative = true; + } + if (!isdigit(text[length])) + length = savePoint; + else{ + int exponent = 0; + while (isdigit(text[length])){ + exponent = exponent * 10 + text[length] - '0'; length++; - negative = true; - } - if (! isdigit(text[length])) - length = savePoint; - else{ - int exponent = 0; - while (isdigit(text[length])){ - exponent = exponent * 10 + text[length] - '0'; - length++; - } - if (negative) - value /= qPow(10, exponent); - else - value *= qPow(10, exponent); - } - } - if (pValue) - *pValue = value; - return found ? length : 0; + } + if (negative) + value /= qPow(10, exponent); + else + value *= qPow(10, exponent); + } + } + if (pValue) + *pValue = value; + return found ? length : 0; } diff --git a/base/ReStringUtil.hpp b/base/ReStringUtil.hpp index 831503c..b0929d7 100644 --- a/base/ReStringUtil.hpp +++ b/base/ReStringUtil.hpp @@ -1,36 +1,40 @@ /* - * Licence: + * ReStringUtil.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #ifndef RPLSTRING_HPP #define RPLSTRING_HPP class ReStringUtil { public: - static int countChar(const char* line, char cc); - static int count(const char* source, const char* item); - static const QByteArray& cutString(const QByteArray& source, int maxLength, - QByteArray& buffer, const char* appendix = "..."); - static const char* fileSeparator(); - static char fileSeparatorChar(); - static QByteArray hexDump(uint8_t* data, int length, int bytesPerLine = 16); - static QByteArray hexDump(const void* data, int length, int bytesPerLine = 16) { - return hexDump((uint8_t*) data, length, bytesPerLine); - } - static QByteArray read(const char* file, bool removeLastNewline = true); - static QByteArray replaceNode(const char* source, const char* newNode); - static bool write(const char* file, const char* content = NULL, - const char* mode = "w"); - static QList toArray(const char* source, const char* separator); - static QByteArray toCString(const char* source, int maxLength = -1); - static QByteArray toNumber(int value, const char* format = "%d"); - static int lengthOfNumber(const char* text, bool skipTrailingSpaces = false); - static char findCsvSeparator(FILE* fp, char* buffer, size_t bufferSize); - static int lengthOfUInt64(const char* text, int radix, quint64* pValue); - static int lengthOfReal(const char* text, qreal* pValue); + static int countChar(const char* line, char cc); + static int count(const char* source, const char* item); + static const QByteArray& cutString(const QByteArray& source, int maxLength, + QByteArray& buffer, const char* appendix = "..."); + static const char* fileSeparator(); + static char fileSeparatorChar(); + static QByteArray hexDump(uint8_t* data, int length, int bytesPerLine = 16); + static QByteArray hexDump(const void* data, int length, + int bytesPerLine = 16){ + return hexDump((uint8_t*) data, length, bytesPerLine); + } + static QByteArray read(const char* file, bool removeLastNewline = true); + static QByteArray replaceNode(const char* source, const char* newNode); + static bool write(const char* file, const char* content = NULL, + const char* mode = "w"); + static QList toArray(const char* source, const char* separator); + static QByteArray toCString(const char* source, int maxLength = -1); + static QByteArray toNumber(int value, const char* format = "%d"); + static int lengthOfNumber(const char* text, bool skipTrailingSpaces = false); + static char findCsvSeparator(FILE* fp, char* buffer, size_t bufferSize); + static int lengthOfUInt64(const char* text, int radix, quint64* pValue); + static int lengthOfReal(const char* text, qreal* pValue); }; #endif // RPLSTRING_HPP diff --git a/base/ReTerminator.cpp b/base/ReTerminator.cpp index 45f46d1..87804fb 100644 --- a/base/ReTerminator.cpp +++ b/base/ReTerminator.cpp @@ -1,9 +1,12 @@ /* - * Licence: + * ReTerminator.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ /** @file * @brief Implements a thread stopper. @@ -14,7 +17,7 @@ #include "base/rebase.hpp" enum { - LOC_CAUSE_TERMINATION_1 = LOC_FIRST_OF(LOC_TERMINATOR), // 10901 + LOC_CAUSE_TERMINATION_1 = LOC_FIRST_OF(LOC_TERMINATOR), // 10901 }; /** @@ -35,14 +38,13 @@ enum { * @param logger NULL or the logger. Used to protocol the termination */ ReTerminator::ReTerminator(ReLogger* logger) : - m_stop(false), - m_logger(logger) { + m_stop(false), m_logger(logger){ } /** * @brief Destructor. */ -ReTerminator::~ReTerminator() { +ReTerminator::~ReTerminator(){ } /** @@ -55,16 +57,16 @@ ReTerminator::~ReTerminator() { * @param location 0 or the location of the caller */ void ReTerminator::causeTermination(const char* reason, const char* file, - int lineNo, ReLoggerLevel level, int location) { - if(m_logger != NULL) { - QByteArray message(reason); - if(file != NULL) { - message.append(" [").append(file).append(lineNo).append("]"); - } - m_logger->log(level, location == 0 ? LOC_CAUSE_TERMINATION_1 : location, - message); - } - m_stop = true; + int lineNo, ReLoggerLevel level, int location){ + if (m_logger != NULL){ + QByteArray message(reason); + if (file != NULL){ + message.append(" [").append(file).append(lineNo).append("]"); + } + m_logger->log(level, location == 0 ? LOC_CAUSE_TERMINATION_1 : location, + message); + } + m_stop = true; } /** @@ -72,7 +74,7 @@ void ReTerminator::causeTermination(const char* reason, const char* file, * @return true: the thread should be stopped.
* false: otherwise */ -bool ReTerminator::isStopped() const { - return m_stop; +bool ReTerminator::isStopped() const{ + return m_stop; } diff --git a/base/ReTerminator.hpp b/base/ReTerminator.hpp index e96ff27..d72d627 100644 --- a/base/ReTerminator.hpp +++ b/base/ReTerminator.hpp @@ -1,29 +1,32 @@ /* - * Licence: + * ReTerminator.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #ifndef RPLTERMINATOR_HPP #define RPLTERMINATOR_HPP class ReTerminator { public: - ReTerminator(ReLogger* logger = NULL); - virtual ~ReTerminator(); + ReTerminator(ReLogger* logger = NULL); + virtual ~ReTerminator(); private: - // No copy constructor: no implementation! - ReTerminator(const ReTerminator& source); - // Prohibits assignment operator: no implementation! - ReTerminator& operator =(const ReTerminator& source); + // No copy constructor: no implementation! + ReTerminator(const ReTerminator& source); + // Prohibits assignment operator: no implementation! + ReTerminator& operator =(const ReTerminator& source); public: - void causeTermination(const char* reason, const char* file = NULL, - int lineNo = 0, ReLoggerLevel level = LOG_ERROR, int location = 0); - bool isStopped() const; + void causeTermination(const char* reason, const char* file = NULL, + int lineNo = 0, ReLoggerLevel level = LOG_ERROR, int location = 0); + bool isStopped() const; private: - bool m_stop; - ReLogger* m_logger; + bool m_stop; + ReLogger* m_logger; }; #endif // RPLTERMINATOR_HPP diff --git a/base/ReTest.cpp b/base/ReTest.cpp index 1bccfe3..22253b4 100644 --- a/base/ReTest.cpp +++ b/base/ReTest.cpp @@ -1,9 +1,12 @@ /* - * Licence: + * ReTest.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ /** @file * @brief A testing tool like JUnit. @@ -30,35 +33,34 @@ class ReTest; * @param name */ ReTest::ReTest(const char* name) : - m_errors(0), - m_name(name), - m_logger(), - m_memoryAppender(1024), - m_memoryLogger() -{ - m_memoryAppender.setAutoDelete(false); - m_logger.buildStandardAppender(getTempDir("rpltest")); - log(QByteArray("Start of ") + m_name); - m_memoryLogger.addAppender(&m_memoryAppender); - try { - run(); - } catch(ReException e) { - error("unexpected RplException: %s", e.getMessage().constData()); - } catch(...){ - error("unknown Exception"); - } + m_errors(0), + m_name(name), + m_logger(), + m_memoryAppender(1024), + m_memoryLogger(){ + m_memoryAppender.setAutoDelete(false); + m_logger.buildStandardAppender(getTempDir("rpltest")); + log(QByteArray("Start of ") + m_name); + m_memoryLogger.addAppender(&m_memoryAppender); + try{ + run(); + } catch (ReException e){ + error("unexpected RplException: %s", e.getMessage().constData()); + } catch (...){ + error("unknown Exception"); + } - if(m_errors > 0) { - error("Unit %s has %d error(s)", m_name.data(), m_errors); - // error() increments, we decrement: - m_errors--; - } + if (m_errors > 0){ + error("Unit %s has %d error(s)", m_name.data(), m_errors); + // error() increments, we decrement: + m_errors--; + } } /** * @brief Destructor. */ -ReTest::~ReTest() { +ReTest::~ReTest(){ } /** @@ -73,11 +75,11 @@ ReTest::~ReTest() { * @return true: equal */ bool ReTest::assertEquals(int expected, int current, const char* file, - int lineNo) { - if(expected != current) - error("%s-%d: error: %d != %d / %x != %x)", file, lineNo, expected, current, - (unsigned int) expected, (unsigned int) current); - return expected == current; + int lineNo){ + if (expected != current) + error("%s-%d: error: %d != %d / %x != %x)", file, lineNo, expected, + current, (unsigned int) expected, (unsigned int) current); + return expected == current; } /** @@ -92,14 +94,13 @@ bool ReTest::assertEquals(int expected, int current, const char* file, * @return true: equal */ bool ReTest::assertEquals(int64_t expected, int64_t current, const char* file, - int lineNo) { - if(expected != current) - error("%s-%d: error: %lld != %lld / %llx != %llx)", file, lineNo, - expected, current, (quint64) expected, (quint64) current); - return expected == current; + int lineNo){ + if (expected != current) + error("%s-%d: error: %lld != %lld / %llx != %llx)", file, lineNo, + expected, current, (quint64) expected, (quint64) current); + return expected == current; } - /** * Tests the equality of two values. * @@ -112,11 +113,11 @@ bool ReTest::assertEquals(int64_t expected, int64_t current, const char* file, * @return true: equal */ bool ReTest::assertEquals(qreal expected, qreal current, const char* file, - int lineNo) { - if(expected != current) - error("%s-%d: error: %d != %d / %x != %x)", file, lineNo, expected, current, - (unsigned int) expected, (unsigned int) current); - return expected == current; + int lineNo){ + if (expected != current) + error("%s-%d: error: %d != %d / %x != %x)", file, lineNo, expected, + current, (unsigned int) expected, (unsigned int) current); + return expected == current; } /** @@ -131,10 +132,10 @@ bool ReTest::assertEquals(qreal expected, qreal current, const char* file, * @return true: equal */ bool ReTest::assertEquals(const char* expected, const ReString& current, - const char* file, int lineNo) { - bool equal = assertEquals(expected, current.toUtf8().constData(), file, - lineNo); - return equal; + const char* file, int lineNo){ + bool equal = assertEquals(expected, current.toUtf8().constData(), file, + lineNo); + return equal; } /** @@ -149,13 +150,12 @@ bool ReTest::assertEquals(const char* expected, const ReString& current, * @return true: equal */ bool ReTest::assertEquals(const ReString& expected, const ReString& current, - const char* file, int lineNo) { - bool equal = assertEquals(expected.toUtf8().constData(), - current.toUtf8().constData(), file, lineNo); - return equal; + const char* file, int lineNo){ + bool equal = assertEquals(expected.toUtf8().constData(), + current.toUtf8().constData(), file, lineNo); + return equal; } - /** * @brief Tests the equality of two values. * @@ -168,36 +168,34 @@ bool ReTest::assertEquals(const ReString& expected, const ReString& current, * @return true: equal */ bool ReTest::assertEquals(const char* expected, const char* current, - const char* file, int lineNo) { - bool equal = strcmp(expected, current) == 0; - if(! equal) { - if(strchr(expected, '\n') != NULL || strchr(current, '\n')) { - QList exp = ReStringUtil::toArray(expected, "\n"); - QList cur = ReStringUtil::toArray(current, "\n"); - equal = assertEquals(exp, cur, file, lineNo); - } else { - int ix = 0; - while(expected[ix] == current[ix] && expected[ix] != '\0') - ix++; - char pointer[12+1]; - char* ptr = pointer; - int maxIx = ix > 10 ? 10 : ix; - for(int ii = 0; ii < maxIx - 1; ii++) - *ptr++ = '-'; - *ptr++ = '^'; - *ptr = '\0'; - if(ix < 10) - error("%s-%d: error: diff at index %d\n%s\n%s\n%s", - file, lineNo, ix, expected, current, pointer); - else - error("%s-%d: error: diff at index %d\n%s\n...%s\n...%s\n%s", - file, lineNo, ix, current, - expected + ix - 10 + 3, - current + ix - 10 + 3, - pointer); - } - } - return equal; + const char* file, int lineNo){ + bool equal = strcmp(expected, current) == 0; + if (!equal){ + if (strchr(expected, '\n') != NULL || strchr(current, '\n')){ + QList < QByteArray > exp = ReStringUtil::toArray(expected, "\n"); + QList < QByteArray > cur = ReStringUtil::toArray(current, "\n"); + equal = assertEquals(exp, cur, file, lineNo); + }else{ + int ix = 0; + while (expected[ix] == current[ix] && expected[ix] != '\0') + ix++; + char pointer[12 + 1]; + char* ptr = pointer; + int maxIx = ix > 10 ? 10 : ix; + for (int ii = 0; ii < maxIx - 1; ii++) + *ptr++ = '-'; + *ptr++ = '^'; + *ptr = '\0'; + if (ix < 10) + error("%s-%d: error: diff at index %d\n%s\n%s\n%s", file, lineNo, + ix, expected, current, pointer); + else + error("%s-%d: error: diff at index %d\n%s\n...%s\n...%s\n%s", file, + lineNo, ix, current, expected + ix - 10 + 3, + current + ix - 10 + 3, pointer); + } + } + return equal; } /** @@ -211,31 +209,31 @@ bool ReTest::assertEquals(const char* expected, const char* current, * @param lineNo the line number containing the test * @return true: equal */ -bool ReTest::assertEquals(const QList& expected, - const QList& current, const char* file, int lineNo) { - int nMax = expected.size(); - bool rc = true; - if(current.size() < nMax) - nMax = current.size(); - for(int ix = 0; ix < nMax; ix++) { - if(expected.at(ix) != current.at(ix)) { - error("%s-%d: difference in line %d", file, lineNo, ix+1); - m_errors--; - assertEquals(expected.at(ix).constData(), current.at(ix).constData(), - file, lineNo); - rc = false; - break; - } - } - if(rc) { - if(expected.size() > nMax) - error("%s-%d: less lines than expected (%d):\n%s", - file, lineNo, nMax, expected.at(nMax).constData()); - else if(expected.size() < nMax) - error("%s-%d: more lines than expected (%d):\n%s", - file, lineNo, nMax, current.at(nMax).constData()); - } - return rc; +bool ReTest::assertEquals(const QList & expected, + const QList & current, const char* file, int lineNo){ + int nMax = expected.size(); + bool rc = true; + if (current.size() < nMax) + nMax = current.size(); + for (int ix = 0; ix < nMax; ix++){ + if (expected.at(ix) != current.at(ix)){ + error("%s-%d: difference in line %d", file, lineNo, ix + 1); + m_errors--; + assertEquals(expected.at(ix).constData(), current.at(ix).constData(), + file, lineNo); + rc = false; + break; + } + } + if (rc){ + if (expected.size() > nMax) + error("%s-%d: less lines than expected (%d):\n%s", file, lineNo, nMax, + expected.at(nMax).constData()); + else if (expected.size() < nMax) + error("%s-%d: more lines than expected (%d):\n%s", file, lineNo, nMax, + current.at(nMax).constData()); + } + return rc; } /** * @brief Tests the equality of two values. @@ -248,9 +246,9 @@ bool ReTest::assertEquals(const QList& expected, * @param lineNo the line number containing the test * @return true: equal */ -bool ReTest::assertEquals(const QByteArray& expected, - const QByteArray& current, const char* file, int lineNo) { - return assertEquals(expected.data(), current.data(), file, lineNo); +bool ReTest::assertEquals(const QByteArray& expected, const QByteArray& current, + const char* file, int lineNo){ + return assertEquals(expected.data(), current.data(), file, lineNo); } /** @@ -265,8 +263,8 @@ bool ReTest::assertEquals(const QByteArray& expected, * @return true: equal */ bool ReTest::assertEquals(const char* expected, const QByteArray& current, - const char* file, int lineNo) { - return assertEquals(expected, current.constData(), file, lineNo); + const char* file, int lineNo){ + return assertEquals(expected, current.constData(), file, lineNo); } /** @@ -279,10 +277,10 @@ bool ReTest::assertEquals(const char* expected, const QByteArray& current, * @param lineNo the line number containing the test * @return condition */ -bool ReTest::assertTrue(bool condition, const char* file, int lineNo) { - if(! condition) - error("%s-%d: not TRUE", file, lineNo); - return condition; +bool ReTest::assertTrue(bool condition, const char* file, int lineNo){ + if (!condition) + error("%s-%d: not TRUE", file, lineNo); + return condition; } /** @@ -295,10 +293,10 @@ bool ReTest::assertTrue(bool condition, const char* file, int lineNo) { * @param lineNo the line number containing the test * @return ! condition */ -bool ReTest::assertFalse(bool condition, const char* file, int lineNo) { - if(condition) - error("%s-%d: not FALSE", file, lineNo); - return ! condition; +bool ReTest::assertFalse(bool condition, const char* file, int lineNo){ + if (condition) + error("%s-%d: not FALSE", file, lineNo); + return !condition; } /** @@ -311,10 +309,10 @@ bool ReTest::assertFalse(bool condition, const char* file, int lineNo) { * @param lineNo the line number containing the test * @return true: ptr is NULL */ -bool ReTest::assertNull(const void* ptr, const char* file, int lineNo) { - if(ptr != NULL) - error("%s-%d: not NULL", file, lineNo); - return ptr == NULL; +bool ReTest::assertNull(const void* ptr, const char* file, int lineNo){ + if (ptr != NULL) + error("%s-%d: not NULL", file, lineNo); + return ptr == NULL; } /** @@ -327,10 +325,10 @@ bool ReTest::assertNull(const void* ptr, const char* file, int lineNo) { * @param lineNo the line number containing the test * @return true: ptr is not NULL */ -bool ReTest::assertNotNull(const void* ptr, const char* file, int lineNo) { - if(ptr == NULL) - error("%s-%d: is NULL", file, lineNo); - return ptr != NULL; +bool ReTest::assertNotNull(const void* ptr, const char* file, int lineNo){ + if (ptr == NULL) + error("%s-%d: is NULL", file, lineNo); + return ptr != NULL; } /** @@ -344,27 +342,26 @@ bool ReTest::assertNotNull(const void* ptr, const char* file, int lineNo) { * false: otherwise */ bool ReTest::assertEqualFiles(const char* expected, const char* current, - const char* file, int lineNo) -{ - bool rc = false; - QByteArray expectedContent = ReStringUtil::read(expected, true); - QByteArray currentContent = ReStringUtil::read(current, true); - if (expectedContent.isEmpty()){ - char buffer[512]; - qsnprintf(buffer, sizeof buffer, "%s has no content. Does it exist?", - expected); - error(buffer); - } else if (currentContent.isEmpty()){ - char buffer[512]; - qsnprintf(buffer, sizeof buffer, "%s has no content. Does it exist?", - current); - error(buffer); - } else { - QList expLines = expectedContent.split('\n'); - QList curLines = currentContent.split('\n'); - rc = assertEquals(expLines, curLines, file, lineNo); - } - return rc; + const char* file, int lineNo){ + bool rc = false; + QByteArray expectedContent = ReStringUtil::read(expected, true); + QByteArray currentContent = ReStringUtil::read(current, true); + if (expectedContent.isEmpty()){ + char buffer[512]; + qsnprintf(buffer, sizeof buffer, "%s has no content. Does it exist?", + expected); + error(buffer); + }else if (currentContent.isEmpty()){ + char buffer[512]; + qsnprintf(buffer, sizeof buffer, "%s has no content. Does it exist?", + current); + error(buffer); + }else{ + QList < QByteArray > expLines = expectedContent.split('\n'); + QList < QByteArray > curLines = currentContent.split('\n'); + rc = assertEquals(expLines, curLines, file, lineNo); + } + return rc; } /** @@ -373,12 +370,11 @@ bool ReTest::assertEqualFiles(const char* expected, const char* current, * @param message message to show * @return true (for chaining) */ -bool ReTest::log(const char* message) { - m_logger.log(LOG_INFO, 0, message); - return true; +bool ReTest::log(const char* message){ + m_logger.log(LOG_INFO, 0, message); + return true; } - /** * @brief Writes an error. * @@ -386,13 +382,13 @@ bool ReTest::log(const char* message) { * @param ... the values for the placeholders in format * @return false (for chaining) */ -bool ReTest::error(const char* format, ...) { - m_errors++; - va_list ap; - va_start(ap, format); - m_logger.log(LOG_ERROR, 0, format, ap); - va_end(ap); - return false; +bool ReTest::error(const char* format, ...){ + m_errors++; + va_list ap; + va_start(ap, format); + m_logger.log(LOG_ERROR, 0, format, ap); + va_end(ap); + return false; } /** @@ -402,21 +398,20 @@ bool ReTest::error(const char* format, ...) { * @return true: pattern has been found
* false: otherwise */ -bool ReTest::logContains(const char* pattern) -{ - const QList& lines = m_memoryAppender.getLines(); - QRegularExpression rexpr(pattern); - bool rc = false; - QRegularExpressionMatch match; - for (int ii = 0; ii < lines.size(); ii++){ - const QByteArray& line = lines.at(ii); - match = rexpr.match(line); - if (match.hasMatch()){ - rc = true; - break; - } - } - return rc; +bool ReTest::logContains(const char* pattern){ + const QList & lines = m_memoryAppender.getLines(); + QRegularExpression rexpr(pattern); + bool rc = false; + QRegularExpressionMatch match; + for (int ii = 0; ii < lines.size(); ii++){ + const QByteArray& line = lines.at(ii); + match = rexpr.match(line); + if (match.hasMatch()){ + rc = true; + break; + } + } + return rc; } /** @@ -430,34 +425,34 @@ bool ReTest::logContains(const char* pattern) * @return the name of an existing directory */ QByteArray ReTest::getTempDir(const char* node, const char* parent, - bool withSeparator) { - QByteArray temp("c:\\temp"); - struct stat info; - const char* ptr; - if((ptr = getenv("TMP")) != NULL) - temp = ptr; - else if((ptr = getenv("TEMP")) != NULL) - temp = ptr; - else if(stat("/tmp", &info) == 0) - temp = "/tmp"; - char sep = m_separator = temp.indexOf('/') >= 0 ? '/' : '\\'; - if(temp.at(temp.length() - 1) != sep) - temp += sep; - if(parent != NULL) { - temp += parent; - if(stat(temp.constData(), &info) != 0) - mkdir(temp.constData(), (-1)); - temp += sep; - } - if(node != NULL) { - temp += node; - temp += sep; - if(stat(temp.data(), &info) != 0) - mkdir(temp.data(), -1); - } - if(! withSeparator) - temp.resize(temp.length() - 1); - return temp; + bool withSeparator){ + QByteArray temp("c:\\temp"); + struct stat info; + const char* ptr; + if ((ptr = getenv("TMP")) != NULL) + temp = ptr; + else if ((ptr = getenv("TEMP")) != NULL) + temp = ptr; + else if (stat("/tmp", &info) == 0) + temp = "/tmp"; + char sep = m_separator = temp.indexOf('/') >= 0 ? '/' : '\\'; + if (temp.at(temp.length() - 1) != sep) + temp += sep; + if (parent != NULL){ + temp += parent; + if (stat(temp.constData(), &info) != 0) + mkdir(temp.constData(), (-1)); + temp += sep; + } + if (node != NULL){ + temp += node; + temp += sep; + if (stat(temp.data(), &info) != 0) + mkdir(temp.data(), -1); + } + if (!withSeparator) + temp.resize(temp.length() - 1); + return temp; } /** @@ -469,14 +464,14 @@ QByteArray ReTest::getTempDir(const char* node, const char* parent, * @return the full name of a temporary file */ QByteArray ReTest::getTempFile(const char* node, const char* parent, - bool deleteIfExists) { - QByteArray dir = getTempDir(parent); - QByteArray rc = dir; - if (! rc.endsWith(m_separator)) - rc += m_separator; - rc += node; - struct stat info; - if(deleteIfExists && stat(rc.constData(), &info) == 0) - unlink(rc.constData()); - return rc; + bool deleteIfExists){ + QByteArray dir = getTempDir(parent); + QByteArray rc = dir; + if (!rc.endsWith(m_separator)) + rc += m_separator; + rc += node; + struct stat info; + if (deleteIfExists && stat(rc.constData(), &info) == 0) + unlink(rc.constData()); + return rc; } diff --git a/base/ReTest.hpp b/base/ReTest.hpp index ec04340..9b27d01 100644 --- a/base/ReTest.hpp +++ b/base/ReTest.hpp @@ -1,9 +1,12 @@ /* - * Licence: + * ReTest.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #ifndef RETEST_HPP #define RETEST_HPP @@ -11,52 +14,54 @@ // the sources generated from QT include this file directly: class ReTest { public: - ReTest(const char* name); - virtual ~ReTest(); + ReTest(const char* name); + virtual ~ReTest(); private: - // No copy constructor: no implementation! - ReTest(const ReTest& source); - // Prohibits assignment operator: no implementation! - ReTest& operator =(const ReTest& source); + // No copy constructor: no implementation! + ReTest(const ReTest& source); + // Prohibits assignment operator: no implementation! + ReTest& operator =(const ReTest& source); public: - bool assertEquals(int expected, int current, const char* file, int lineNo); - bool assertEquals(int64_t expected, int64_t current, const char* file, int lineNo); - bool assertEquals(qreal expected, qreal current, const char* file, int lineNo); - bool assertEquals(const char* expected, const ReString& current, - const char* file, int lineNo); - bool assertEquals(const ReString& expected, const ReString& current, - const char* file, int lineNo); - bool assertEquals(const char* expected, const char* current, - const char* file, int lineNo); - bool assertEquals(const QByteArray& expected, const QByteArray& current, - const char* file, int lineNo); - bool assertEquals(const char* expected, const QByteArray& current, - const char* file, int lineNo); - bool assertEquals(const QList& expected, - const QList& current, const char* file, int lineNo); - bool assertTrue(bool condition, const char* file, int lineNo); - bool assertFalse(bool condition, const char* file, int lineNo); - bool assertNull(const void* ptr, const char* file, int lineNo); - bool assertNotNull(const void* ptr, const char* file, int lineNo); - bool assertEqualFiles(const char* expected, const char* current, - const char* file, int lineNo); - bool log(const char* message); - bool error(const char* message, ...); - QByteArray getTempDir(const char* node, const char* parent = NULL, - bool withSeparator = true); - QByteArray getTempFile(const char* node, const char* parent = NULL, - bool deleteIfExists = true); - bool logContains(const char* pattern); - virtual void run(void) = 0; + bool assertEquals(int expected, int current, const char* file, int lineNo); + bool assertEquals(int64_t expected, int64_t current, const char* file, + int lineNo); + bool assertEquals(qreal expected, qreal current, const char* file, + int lineNo); + bool assertEquals(const char* expected, const ReString& current, + const char* file, int lineNo); + bool assertEquals(const ReString& expected, const ReString& current, + const char* file, int lineNo); + bool assertEquals(const char* expected, const char* current, + const char* file, int lineNo); + bool assertEquals(const QByteArray& expected, const QByteArray& current, + const char* file, int lineNo); + bool assertEquals(const char* expected, const QByteArray& current, + const char* file, int lineNo); + bool assertEquals(const QList & expected, + const QList & current, const char* file, int lineNo); + bool assertTrue(bool condition, const char* file, int lineNo); + bool assertFalse(bool condition, const char* file, int lineNo); + bool assertNull(const void* ptr, const char* file, int lineNo); + bool assertNotNull(const void* ptr, const char* file, int lineNo); + bool assertEqualFiles(const char* expected, const char* current, + const char* file, int lineNo); + bool log(const char* message); + bool error(const char* message, ...); + QByteArray getTempDir(const char* node, const char* parent = NULL, + bool withSeparator = true); + QByteArray getTempFile(const char* node, const char* parent = NULL, + bool deleteIfExists = true); + bool logContains(const char* pattern); + virtual void run(void) = 0; protected: - int m_errors; - QByteArray m_name; - ReLogger m_logger; - // for testing of logging code: - ReMemoryAppender m_memoryAppender; - ReLogger m_memoryLogger; - char m_separator; + int m_errors; + QByteArray m_name; + ReLogger m_logger; + // for testing of logging code: + ReMemoryAppender m_memoryAppender; + ReLogger m_memoryLogger; + char m_separator; }; #define checkEqu(expected, current) assertEquals(expected, current, __FILE__, __LINE__) #define checkT(current) assertTrue(current, __FILE__, __LINE__) diff --git a/base/ReWriter.cpp b/base/ReWriter.cpp index ecfb73d..d3d827c 100644 --- a/base/ReWriter.cpp +++ b/base/ReWriter.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * ReWriter.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * @brief A writer to an output media. @@ -18,7 +21,8 @@ */ #include "base/rebase.hpp" -const char* ReWriter::m_tabs = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; +const char* ReWriter::m_tabs = + "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; int ReWriter::m_maxIndention = strlen(ReWriter::m_tabs); /** @class ReWriter ReWriter.hpp "rplcore/ReWriter.hpp" @@ -33,9 +37,8 @@ int ReWriter::m_maxIndention = strlen(ReWriter::m_tabs); * Closes the output medium. * Ensures that the destructors of the derived classes are virtual. */ -ReWriter::~ReWriter() -{ - close(); +ReWriter::~ReWriter(){ + close(); } /** @@ -45,19 +48,17 @@ ReWriter::~ReWriter() * * @note The method must be designed so that it can be called multiple times. */ -void ReWriter::close() -{ +void ReWriter::close(){ } /** * @brief Puts a given count of "\t" to the output medium. * * @param indent indention level, number of "\t" */ -void ReWriter::indent(int indent) -{ - if (indent > m_maxIndention) - indent = m_maxIndention; - format("%.*s", indent, m_tabs); +void ReWriter::indent(int indent){ + if (indent > m_maxIndention) + indent = m_maxIndention; + format("%.*s", indent, m_tabs); } /** @@ -66,12 +67,11 @@ void ReWriter::indent(int indent) * @param format format string with placeholders like sprintf() * @param ... variable arguments, values for the placeholders */ -void ReWriter::format(const char* format, ...) -{ - va_list ap; - va_start(ap, format); - write(ap, format); - va_end(ap); +void ReWriter::format(const char* format, ...){ + va_list ap; + va_start(ap, format); + write(ap, format); + va_end(ap); } /** * @brief Formats a line and write it to the output medium. @@ -79,14 +79,13 @@ void ReWriter::format(const char* format, ...) * @param format format string with placeholders like sprintf() * @param ... variable arguments, values for the placeholders */ -void ReWriter::formatLine(const char* format, ...) -{ - char buffer[64000]; - va_list ap; - va_start(ap, format); - qvsnprintf(buffer, sizeof buffer, format, ap); - va_end(ap); - writeLine(buffer); +void ReWriter::formatLine(const char* format, ...){ + char buffer[64000]; + va_list ap; + va_start(ap, format); + qvsnprintf(buffer, sizeof buffer, format, ap); + va_end(ap); + writeLine(buffer); } /** @@ -95,11 +94,10 @@ void ReWriter::formatLine(const char* format, ...) * @param ap variable argument list (like in vsprintf) * @param format format string with placeholders */ -void ReWriter::write(va_list ap, const char* format) -{ - char buffer[64000]; - qvsnprintf(buffer, sizeof buffer, format, ap); - write(buffer); +void ReWriter::write(va_list ap, const char* format){ + char buffer[64000]; + qvsnprintf(buffer, sizeof buffer, format, ap); + write(buffer); } /** @@ -108,10 +106,9 @@ void ReWriter::write(va_list ap, const char* format) * @param indent indention level. Indention is limited to 20 * @param line the line to write */ -void ReWriter::writeIndented(int indent, const char* line) -{ - ReWriter::indent(indent); - writeLine(line); +void ReWriter::writeIndented(int indent, const char* line){ + ReWriter::indent(indent); + writeLine(line); } /** @@ -121,16 +118,15 @@ void ReWriter::writeIndented(int indent, const char* line) * @param format format string with placeholders like sprintf * @param ... the values for the placeholders (variable arguments) */ -void ReWriter::formatIndented(int indent, const char* format, ...) -{ - ReWriter::indent(indent); +void ReWriter::formatIndented(int indent, const char* format, ...){ + ReWriter::indent(indent); - char buffer[64000]; - va_list ap; - va_start(ap, format); - qvsnprintf(buffer, sizeof buffer, format, ap); - va_end(ap); - writeLine(buffer); + char buffer[64000]; + va_list ap; + va_start(ap, format); + qvsnprintf(buffer, sizeof buffer, format, ap); + va_end(ap); + writeLine(buffer); } /** @class ReWriter rplwriter.hpp "rplcore/rplwriter.hpp" @@ -149,52 +145,48 @@ void ReWriter::formatIndented(int indent, const char* format, ...) * @param eoln line end: "\n" or "\r\n" */ ReFileWriter::ReFileWriter(const char* filename, const char* mode, - FILE* additionalStream, const char* eoln) : - m_fp(fopen(filename, mode)), - m_name(filename), - m_eoln(eoln), - m_additionalStream(additionalStream) -{ + FILE* additionalStream, const char* eoln) : + m_fp(fopen(filename, mode)), + m_name(filename), + m_eoln(eoln), + m_additionalStream(additionalStream){ } /** * @brief Writes a string to the file. * @param message the string to write */ -void ReFileWriter::write(const char* message) -{ - if (m_fp != NULL) - fputs(message, m_fp); - if (m_additionalStream != NULL) - fputs(message, m_additionalStream); +void ReFileWriter::write(const char* message){ + if (m_fp != NULL) + fputs(message, m_fp); + if (m_additionalStream != NULL) + fputs(message, m_additionalStream); } /** * @brief Writes a line to the file. * @param line the line to write. If NULL an empty line will be written */ -void ReFileWriter::writeLine(const char* line) -{ - if (m_fp != NULL){ - if (line != NULL) - fputs(line, m_fp); - fputs(m_eoln, m_fp); - } - if (m_additionalStream != NULL){ - if (line != NULL) - fputs(line, m_additionalStream); - fputc('\n', m_additionalStream); - } +void ReFileWriter::writeLine(const char* line){ + if (m_fp != NULL){ + if (line != NULL) + fputs(line, m_fp); + fputs(m_eoln, m_fp); + } + if (m_additionalStream != NULL){ + if (line != NULL) + fputs(line, m_additionalStream); + fputc('\n', m_additionalStream); + } } /** * @brief Closes the output file. */ -void ReFileWriter::close() -{ - if (m_fp != NULL){ - fclose(m_fp); - m_fp = NULL; - } - m_additionalStream = NULL; +void ReFileWriter::close(){ + if (m_fp != NULL){ + fclose(m_fp); + m_fp = NULL; + } + m_additionalStream = NULL; } diff --git a/base/ReWriter.hpp b/base/ReWriter.hpp index a53120b..2a8c005 100644 --- a/base/ReWriter.hpp +++ b/base/ReWriter.hpp @@ -1,59 +1,59 @@ /* - * Licence: + * ReWriter.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ - + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #ifndef REWRITER_HPP #define REWRITER_HPP -class ReWriter -{ +class ReWriter { public: - virtual ~ReWriter(); + virtual ~ReWriter(); public: - /** - * @brief Writes a text to the output medium. - * - * @param message the message - */ - virtual void write(const char* message) = 0; - /** - * @brief Writes a text line to the output medium. - * - * @param line the text line. If NULL an empty line will be written - */ - virtual void writeLine(const char* line = NULL) = 0; - virtual void close(); + /** + * @brief Writes a text to the output medium. + * + * @param message the message + */ + virtual void write(const char* message) = 0; + /** + * @brief Writes a text line to the output medium. + * + * @param line the text line. If NULL an empty line will be written + */ + virtual void writeLine(const char* line = NULL) = 0; + virtual void close(); public: - void indent(int indent); - void format(const char* format, ...); - void formatLine(const char* format, ...); - void write(va_list ap, const char* format); - void writeIndented(int indent, const char* line); - void formatIndented(int indent, const char* format, ...); + void indent(int indent); + void format(const char* format, ...); + void formatLine(const char* format, ...); + void write(va_list ap, const char* format); + void writeIndented(int indent, const char* line); + void formatIndented(int indent, const char* format, ...); protected: - static const char* m_tabs; - static int m_maxIndention; + static const char* m_tabs; + static int m_maxIndention; }; -class ReFileWriter : public ReWriter -{ +class ReFileWriter: public ReWriter { public: - ReFileWriter(const char* filename, const char* mode = "w", - FILE* additionalStream = NULL, const char* eoln = "\n"); + ReFileWriter(const char* filename, const char* mode = "w", + FILE* additionalStream = NULL, const char* eoln = "\n"); public: - virtual void write(const char* line); - virtual void writeLine(const char* line = NULL); - virtual void close(); + virtual void write(const char* line); + virtual void writeLine(const char* line = NULL); + virtual void close(); protected: - FILE* m_fp; - QByteArray m_name; - QByteArray m_eoln; - FILE* m_additionalStream; + FILE* m_fp; + QByteArray m_name; + QByteArray m_eoln; + FILE* m_additionalStream; }; #endif // REWRITER_HPP diff --git a/base/rebase.hpp b/base/rebase.hpp index a415c98..b7cb676 100644 --- a/base/rebase.hpp +++ b/base/rebase.hpp @@ -1,9 +1,12 @@ /* - * Licence: + * rebase.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #ifndef RECORE_HPP #define RECORE_HPP @@ -37,7 +40,7 @@ typedef qint32 int32_t; typedef quint32 uint32_t; typedef qreal real_t; typedef QString ReString; -#define RPL_UNUSED(x) (void)(x) +#define RE_UNUSED(x) (void)(x) #include "remodules.hpp" #include "base/ReByteStorage.hpp" diff --git a/base/testrplexample.cpp b/base/testrplexample.cpp index 0c89591..a220646 100644 --- a/base/testrplexample.cpp +++ b/base/testrplexample.cpp @@ -1,50 +1,55 @@ /* - * Licence: + * testrplexample.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ include "project.hpp" #include "base/base.hpp" // Code to test: -int add(int a, int b) { - return a+b; +int add(int a, int b){ + return a+b; } -QByteArray concat(const char* a, const char* b) { - return QByteArray(a) + " " + b; +QByteArray concat(const char* a, const char* b){ + return QByteArray(a) + " " + b; } -const char* firstDot(const char* s) { - return strchr(s, '.'); +const char* firstDot(const char* s){ + return strchr(s, '.'); } /** * @brief Example for usage of the class ReTest. */ -class TestRplExample : public ReTest { +class TestRplExample: public ReTest { public: - TestRplExample() : ReTest("RplExample") {} + TestRplExample() : + ReTest("RplExample"){ + } public: - void testInt() { - log("testing add..."); - // compare 2 integers: - checkEqu(2, add(1, 1)); - } - void testString() { - // compare 2 strings: - checkEqu("Be good", concat("Be", "good")); - // test for not NULL: - checkN(firstDot("Hi.")); - // test for NULL: - checkNN(firstDot("Hi")); - } - virtual void doIt() { - testInt(); - testString(); - } + void testInt(){ + log("testing add..."); + // compare 2 integers: + checkEqu(2, add(1, 1)); + } + void testString(){ + // compare 2 strings: + checkEqu("Be good", concat("Be", "good")); + // test for not NULL: + checkN(firstDot("Hi.")); + // test for NULL: + checkNN(firstDot("Hi")); + } + virtual void doIt(){ + testInt(); + testString(); + } }; -void testRplExample() { - TestRplExample test; - test.run(); +void testRplExample(){ + TestRplExample test; + test.run(); } diff --git a/cunit/cuReConfig.cpp b/cunit/cuReConfig.cpp index 76fa172..535347d 100644 --- a/cunit/cuReConfig.cpp +++ b/cunit/cuReConfig.cpp @@ -1,11 +1,12 @@ /* * cuReConfig.cpp - * - * Licence: + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #include "base/rebase.hpp" diff --git a/cunit/cuReContainer.cpp b/cunit/cuReContainer.cpp index 8b3b38e..e418b4e 100644 --- a/cunit/cuReContainer.cpp +++ b/cunit/cuReContainer.cpp @@ -1,11 +1,12 @@ /* * cuReContainer.cpp - * - * Licence: + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #include "base/rebase.hpp" /** diff --git a/cunit/cuReEnigma.cpp b/cunit/cuReEnigma.cpp index 6688df5..44912aa 100644 --- a/cunit/cuReEnigma.cpp +++ b/cunit/cuReEnigma.cpp @@ -1,9 +1,12 @@ /* - * Licence: + * cuReEnigma.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #include "base/rebase.hpp" /** diff --git a/cunit/main.cpp b/cunit/main.cpp index 56bafc5..0922b20 100644 --- a/cunit/main.cpp +++ b/cunit/main.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * main.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #include "../rplcore/rplcore.hpp" #include "../rplmath/rplmath.hpp" diff --git a/cunit/rplastree_test.cpp b/cunit/rplastree_test.cpp index 2f03043..0a98a23 100644 --- a/cunit/rplastree_test.cpp +++ b/cunit/rplastree_test.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * rplastree_test.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * @brief Unit test of the abstract syntax tree. diff --git a/cunit/rplbench.cpp b/cunit/rplbench.cpp index 74dc740..31f0e8a 100644 --- a/cunit/rplbench.cpp +++ b/cunit/rplbench.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * rplbench.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * @brief Unit test of the abstract syntax tree. diff --git a/cunit/rplbytestorage_test.cpp b/cunit/rplbytestorage_test.cpp index 52437d2..0f40bc6 100644 --- a/cunit/rplbytestorage_test.cpp +++ b/cunit/rplbytestorage_test.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * rplbytestorage_test.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * @brief Unit test of the byte and C string storage. */ diff --git a/cunit/rplcharptrmap_test.cpp b/cunit/rplcharptrmap_test.cpp index 8ad1d78..0643b9e 100644 --- a/cunit/rplcharptrmap_test.cpp +++ b/cunit/rplcharptrmap_test.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * rplcharptrmap_test.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #include "base/rebase.hpp" #include "rplcore/rpltest.hpp" diff --git a/cunit/rplexception_test.cpp b/cunit/rplexception_test.cpp index 57293cb..f219850 100644 --- a/cunit/rplexception_test.cpp +++ b/cunit/rplexception_test.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * rplexception_test.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #include "base/rebase.hpp" #include "rplcore/rpltest.hpp" /** @file diff --git a/cunit/rpllexer_test.cpp b/cunit/rpllexer_test.cpp index 060e824..72f133e 100644 --- a/cunit/rpllexer_test.cpp +++ b/cunit/rpllexer_test.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * rpllexer_test.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * @brief Unit test of the syntax symbol extractor. diff --git a/cunit/rplmatrix_test.cpp b/cunit/rplmatrix_test.cpp index d1507e4..2b30e7a 100644 --- a/cunit/rplmatrix_test.cpp +++ b/cunit/rplmatrix_test.cpp @@ -1,8 +1,12 @@ /* - * Matrix_test.cpp - * - * Created on: 29.05.2014 - * Author: hm + * rplmatrix_test.cpp + * + * License: Public Domain + * You can use and modify this file without any restriction. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ /** @file diff --git a/cunit/rplmfparser_test.cpp b/cunit/rplmfparser_test.cpp index 6cb4ede..a234542 100644 --- a/cunit/rplmfparser_test.cpp +++ b/cunit/rplmfparser_test.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * rplmfparser_test.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * @brief Unit test of the parser for the language "MF". */ diff --git a/cunit/rplqstring_test.cpp b/cunit/rplqstring_test.cpp index 8f9db55..d6116f5 100644 --- a/cunit/rplqstring_test.cpp +++ b/cunit/rplqstring_test.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * rplqstring_test.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * @brief Unit test of the ReString tools. */ diff --git a/cunit/rplsource_test.cpp b/cunit/rplsource_test.cpp index e78a9c3..83fd0ec 100644 --- a/cunit/rplsource_test.cpp +++ b/cunit/rplsource_test.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * rplsource_test.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * @brief Unit test of the input media reader. diff --git a/cunit/rplstring_test.cpp b/cunit/rplstring_test.cpp index 313ae58..c2e7dc8 100644 --- a/cunit/rplstring_test.cpp +++ b/cunit/rplstring_test.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * rplstring_test.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * @brief Unit test of the QByteArray tools. diff --git a/cunit/rplvm_test.cpp b/cunit/rplvm_test.cpp index bb58cd2..39df487 100644 --- a/cunit/rplvm_test.cpp +++ b/cunit/rplvm_test.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * rplvm_test.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #include "base/rebase.hpp" #include "expr/reexpr.hpp" diff --git a/cunit/rplwriter_test.cpp b/cunit/rplwriter_test.cpp index 0922749..71de3b6 100644 --- a/cunit/rplwriter_test.cpp +++ b/cunit/rplwriter_test.cpp @@ -1,11 +1,13 @@ /* - * - * Licence: + * rplwriter_test.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * @brief Unit test of the output media writers. diff --git a/expr/ReASClasses.cpp b/expr/ReASClasses.cpp new file mode 100644 index 0000000..c740600 --- /dev/null +++ b/expr/ReASClasses.cpp @@ -0,0 +1,1102 @@ +/* + * ReAsClasses.cpp + * + * License: Public Domain + * You can use and modify this file without any restriction. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ + +/** @file + * @brief Predefined classes of the virtual machine, e.g ReASInteger. + */ +/** @file rplexpr/rplasclasses.hpp + * + * @brief Definitions for predefined classes of the virtual machine. + */ + +#include "base/rebase.hpp" +#include "expr/reexpr.hpp" + +ReASList* ReASList::m_instance = NULL; +ReASMap* ReASMap::m_instance = NULL; +ReASFloat* ReASFloat::m_instance = NULL; +ReASInteger* ReASInteger::m_instance = NULL; +ReASString* ReASString::m_instance = NULL; +ReASBoolean* ReASBoolean::m_instance = NULL; +ReASVoid* ReASVoid::m_instance = NULL; +ReASFormula* ReASFormula::m_instance = NULL; + +/** @class ReSymbolSpace rplastree.hpp "rplexpr/rplastree.hpp" + * + * @brief Implements a symbol space for the parser. + * + * A symbol space is a container of the classes and variables which can be used + * at a given moment while compiling. + * + * A symbol space could have a parent which is a symbol space too and extends + * the visible classes / variables. + * + * If an entry exists more than one time in a symbol space chain only the first + * can be seen. + * + * The "last" parent is named "global" and exists always. It contains the + * core classes like String, List and Map and methods like print. + * + * Each module hit by the compiler builds its own symbol space with global as parent. + * + * Each class defines a symbol space and takes the symbol space of the superclass + * as its parent. If there is no superclass the module's symbol space will be taken. + * + * Each method defines its own symbol space. The parent may be the symbol space + * of the module or of the class. + */ +/** + * @brief Constructor, only for the global symbol space. + * + * @param name the symbol space's name + * @param parent the parent of the symbol space + */ +ReSymbolSpace::ReSymbolSpace(ReASTree& tree) : + m_type(SST_GLOBAL), + m_name("$global"), + m_variables(), + m_classes(), + m_parent(NULL), + m_body(NULL), + m_listOfVars(), + m_tree(tree){ +} +/** + * @brief Constructor. + * + * @param type the type of the symbol space: SST_MODULE, ... + * @param name the symbol space's name + * @param parent the parent of the symbol space + */ +ReSymbolSpace::ReSymbolSpace(ReSymbolSpace::SymbolSpaceType type, + const QByteArray& name, ReSymbolSpace* parent) : + m_type(type), + m_name(name), + m_variables(), + m_classes(), + m_parent(parent), + m_body(NULL), + m_listOfVars(), + m_tree(parent->m_tree){ +} + +/** + * @brief Destructor. + */ +ReSymbolSpace::~ReSymbolSpace(){ + ClassMap::iterator it; + for (it = m_classes.begin(); it != m_classes.end(); it++){ + delete it.value(); + } + MethodMap::iterator it2; + for (it2 = m_methods.begin(); it2 != m_methods.end(); it2++){ + delete it2.value(); + } +} + +/** + * @brief Starts a scope. + * + * A scope is an "area" where variables can be defined. + * A variable "lives" in a scope. + * + * Saves the status to restore it in finishScope(). + * + * @param scope OUT: status info + */ +void ReSymbolSpace::startScope(ReASScope& scope){ + scope.m_varNoAtStart = m_listOfVars.size(); +} + +/** + * @brief Finishes a scope. + * + * Finishes the "live" of the variables created in the ending scope. + * + * @param endOfScope line (inside the current source unit) which finishes the + * scope + * @param scope the status of the scope at start. + */ +void ReSymbolSpace::finishScope(int endOfScope, ReASScope& scope){ + // in methods/classes not needed: + int ix = scope.m_varNoAtStart - scope.m_builtInVars; + int last = m_listOfVars.size(); + for (; ix < last; ix++){ + ReASVarDefinition* var = m_listOfVars[ix]; + var->setEndOfScope(endOfScope); + const QByteArray& name = var->name(); + if (m_variables.contains(name)) + m_variables.remove(name); + } +} + +/** + * @brief Search a variable in the symbol space. + * + * @param name variable to find + * + * @return NULL: not found
+ * otherwise: the variable + */ +ReASVarDefinition* ReSymbolSpace::findVariable(const QByteArray& name) const{ + ReASVarDefinition* rc = NULL; + if (m_variables.contains(name)) + rc = m_variables[name]; + else if (m_parent != NULL) + rc = m_parent->findVariable(name); + return rc; +} + +/** + * @brief Search the class in the symbol space hierarchy. + * + * @param name Name of the class + * @return NULL: not found
+ * otherwise: the class + */ +ReASClass* ReSymbolSpace::findClass(const QByteArray& name) const{ + ReASClass* rc = NULL; + if (m_classes.contains(name)) + rc = m_classes[name]; + else if (m_parent != NULL) + rc = m_parent->findClass(name); + return rc; +} + +/** + * @brief Find a method in the instance. + * + * @param name the method's name + * @return NULL: method not found + * otherwise: the method description + */ +ReASMethod* ReSymbolSpace::findMethod(const QByteArray& name) const{ + ReASMethod* rc = NULL; + if (m_methods.contains(name)) + rc = m_methods[name]; + return rc; +} + +/** + * @brief Writes the content of the instance into a file. + * + * @param writer writes to output + * @param indent nesting level: so many tabs will be used as prefix + * @param header NULL or the headline + */ +void ReSymbolSpace::dump(ReWriter& writer, int indent, const char* header){ + if (header != NULL) + writer.writeLine(header); + writer.formatIndented(indent, "= %s (%s) parent: %s", m_name.constData(), + spaceTypeName(m_type), + m_parent == NULL ? "" : m_parent->name().constData()); + QList < QByteArray > sorted; + if (m_classes.size() > 0){ + writer.writeIndented(indent, "== Classes:"); + sorted.reserve(m_classes.size()); + ClassMap::iterator it; + for (it = m_classes.begin(); it != m_classes.end(); it++){ + sorted.append(it.key()); + } + qSort(sorted.begin(), sorted.end(), qLess ()); + QList ::iterator it2; + for (it2 = sorted.begin(); it2 != sorted.end(); it2++){ + ReASClass* clazz = m_classes[*it2]; + clazz->dump(writer, indent); + } + } + if (m_methods.size() > 0){ + writer.writeIndented(indent, "== Methods:"); + sorted.clear(); + sorted.reserve(m_variables.size()); + MethodMap::iterator it3; + for (it3 = m_methods.begin(); it3 != m_methods.end(); it3++){ + sorted.append(it3.key()); + } + qSort(sorted.begin(), sorted.end(), qLess ()); + QList ::iterator it4; + for (it4 = sorted.begin(); it4 != sorted.end(); it4++){ + ReASMethod* method = m_methods[*it4]; + do{ + method->dump(writer, indent); + method = method->sibling(); + }while (method != NULL); + } + } + + if (m_listOfVars.size() > 0){ + writer.writeIndented(indent, "== Variables:"); + QList ::iterator it6; + for (int ix = 0; ix < m_listOfVars.size(); ix++){ + ReASVarDefinition* var = m_listOfVars[ix]; + var->dump(writer, indent); + } + } + if (m_body != NULL){ + writer.writeIndented(indent, "== Body:"); + ReASNode1::dumpStatements(writer, indent, m_body); + } +} + +/** + * @brief Returns the name of a space type. + * + * @param type type to inspect + * @return the name of the type + */ +const char*ReSymbolSpace::spaceTypeName(ReSymbolSpace::SymbolSpaceType type){ + const char* rc = NULL; + switch (type) { + case SST_UNDEF: + rc = "undef"; + break; + case SST_GLOBAL: + rc = "global"; + break; + case SST_MODULE: + rc = "module"; + break; + case SST_CLASS: + rc = "class"; + break; + case SST_METHOD: + rc = "method"; + break; + default: + rc = "?"; + break; + } + return rc; +} + +/** + * @brief Initilizes the global symbol space. + * + * @param tree the abstract syntax tree + * @return the global symbol space + */ +ReSymbolSpace* ReSymbolSpace::createGlobal(ReASTree& tree){ + ReSymbolSpace* rc = new ReSymbolSpace(tree); + rc->m_tree = tree; + ReASInteger::m_instance = new ReASInteger(tree); + rc->m_classes[ReASInteger::m_instance->name()] = ReASInteger::m_instance; + ReASBoolean::m_instance = new ReASBoolean(tree); + rc->m_classes[ReASBoolean::m_instance->name()] = ReASBoolean::m_instance; + ReASFloat::m_instance = new ReASFloat(tree); + rc->m_classes[ReASFloat::m_instance->name()] = ReASFloat::m_instance; + ReASString::m_instance = new ReASString(tree); + rc->m_classes[ReASString::m_instance->name()] = ReASString::m_instance; + ReASList::m_instance = new ReASList(tree); + rc->m_classes[ReASList::m_instance->name()] = ReASList::m_instance; + ReASMap::m_instance = new ReASMap(tree); + rc->m_classes[ReASMap::m_instance->name()] = ReASMap::m_instance; + ReASVoid::m_instance = new ReASVoid(tree); + rc->m_classes[ReASVoid::m_instance->name()] = ReASVoid::m_instance; + ReASFormula::m_instance = new ReASFormula(tree); + rc->m_classes[ReASFormula::m_instance->name()] = ReASFormula::m_instance; + return rc; +} +/** + * @brief Returns the list of the variables. + * + * @return the list of the variables + */ +ReSymbolSpace::VariableList ReSymbolSpace::listOfVars() const{ + return m_listOfVars; +} + +/** + * @brief Returns the parent of the symbol space. + * + * @return the symbolspace of the object (module, method, class..) containing + * the object belonging to the instance + */ +ReSymbolSpace* ReSymbolSpace::parent() const{ + return m_parent; +} + +/** + * @brief Returns the body (an abstract syntax tree) of the symbol space. + * + * @return NULL: no body available
+ * othewise: the body of the instance + */ +ReASItem* ReSymbolSpace::body() const{ + return m_body; +} + +/** + * @brief Sets the body (an abstract syntax tree) of the symbol space. + * + * @param body the new body + */ +void ReSymbolSpace::setBody(ReASItem* body){ + m_body = body; +} + +/** + * @brief Adds a variable to the symbol space. + * + * @param variable the variable to add + * @param varNo OUT: variable number, current number in the symbol space + * @return NULL: success
+ * otherwise: the already defined variable/method + */ +ReASItem* ReSymbolSpace::addVariable(ReASVarDefinition* variable, int& varNo){ + ReASItem* rc = NULL; + const QByteArray& name = variable->name(); + if (m_variables.contains(name)) + rc = m_variables[name]; + else if (m_methods.contains(name)) + rc = m_methods[name]; + else{ + m_variables[name] = variable; + varNo = m_listOfVars.size(); + m_listOfVars.append(variable); + } + return rc; +} + +/** + * @brief Adds a method to the symbol space. + * + * @param method the method to add + * @return NULL: success
+ * otherwise: the already defined variable/method + */ +ReASItem* ReSymbolSpace::addMethod(ReASMethod* method){ + ReASItem* rc = NULL; + const QByteArray& name = method->name(); + if (m_variables.contains(name)) + rc = m_variables[name]; + else if (!m_methods.contains(name)){ + m_methods[name] = method; + }else{ + ReASMethod* first = m_methods[name]; + ReASMethod* oldMethod = first; + do{ + if (oldMethod->equalSignature(*method)) + rc = oldMethod; + else + oldMethod = oldMethod->sibling(); + }while (rc == NULL && oldMethod != NULL); + if (rc == NULL){ + method->setChild(first); + m_methods[name] = method; + } + } + return rc; +} +/** + * @brief Adds a class to the instance. + * + * @param clazz the class to add + * @return NULL: success
+ * otherwise: the already defined class + */ +ReASUserClass* ReSymbolSpace::addClass(ReASUserClass* clazz){ + ReASUserClass* rc = NULL; + const QByteArray& name = clazz->name(); + if (m_classes.contains(name)){ + rc = dynamic_cast (m_classes[name]); + }else{ + m_classes[name] = clazz; + } + return rc; +} + +/** + * @brief Returns the name of the symbol space. + * + * @return the name + */ +const QByteArray& ReSymbolSpace::name() const{ + return m_name; +} + +/** @class ReASBoolean rplastree.hpp "rplexpr/rplastree.hpp" + * + * @brief Implements the class of a Boolean. + * + * A Boolean is a real value. + */ +/** + * @brief Constructor. + */ +ReASBoolean::ReASBoolean(ReASTree& tree) : + ReASClass("Bool", tree){ +} +/** + * @brief Creates a value object (used in ReASVariant). + * + * For Booleans nothing is to do! + * + * @param source NULL or a source to copy + * @return NULL + */ +void* ReASBoolean::newValueInstance(void*) const{ + return NULL; +} + +/** + * @brief Destroys the given object. + * + * For Booleans nothing is to do! + * + * @param object object to destroy + */ +void ReASBoolean::destroyValueInstance(void*) const{ +} + +/** + * @brief Calculates the boolean value of an class specific object. + * + * This method should never be called. + * + * @param object the object to test (with type QList*) + * @return false + */ +bool ReASBoolean::boolValueOf(void*) const{ + return false; +} + +/** + * @brief Returns a string representation of an instance. + * + * @param object the object to convert + * @param maxLength not used + * @return a string describing the object + */ +QByteArray ReASBoolean::toString(void* object, int) const{ + return ((ReASVariant*) object)->asBool() ? "True" : "False"; +} + +/** @class ReASNumber rplastree.hpp "rplexpr/rplastree.hpp" + * + * @brief Implements the class of a Boolean. + * + * A Boolean is one of the values true and false. + */ +/** + * @brief Constructor. + */ +ReASFloat::ReASFloat(ReASTree& tree) : + ReASClass("Float", tree){ +} + +ReASFloat::ReASFloat(const QByteArray& name, ReASTree& tree) : + ReASClass(name, tree){ + m_superClass = ReASFloat::m_instance; +} +/** + * @brief Creates a value object (used in ReASVariant). + * + * For Booleans nothing is to do! + * + * @param source NULL or a source to copy + * @return NULL + */ +void* ReASFloat::newValueInstance(void*) const{ + return NULL; +} + +/** + * @brief Destroys the given object. + * + * For Booleans nothing is to do! + * + * @param object object to destroy + */ +void ReASFloat::destroyValueInstance(void*) const{ +} + +/** + * @brief Calculates the boolean value of an class specific object. + * + * This method should never be called. + * + * @param object the object to test + * @return false + */ +bool ReASFloat::boolValueOf(void*) const{ + return false; +} + +/** + * @brief Returns a string representation of an instance. + * + * @param object the object to convert + * @param maxLength not used + * @return a string describing the object + */ +QByteArray ReASFloat::toString(void* object, int) const{ + char buffer[256]; + + qsnprintf(buffer, sizeof buffer, "%f", ((ReASVariant *) object)->asFloat()); + return buffer; +} + +/** @class ReASInteger rplastree.hpp "rplexpr/rplastree.hpp" + * + * @brief Implements the class of a Boolean. + * + * A Boolean is a one of the values true and false. + */ +/** + * @brief Constructor. + */ +ReASInteger::ReASInteger(ReASTree& tree) : + ReASFloat("Int", tree){ +} + +/** + * @brief Calculates the boolean value of an class specific object. + * + * This method should never be called. + * + * @param object the object to test + * @return false + */ +bool ReASInteger::boolValueOf(void*) const{ + return false; +} + +/** + * @brief Returns a string representation of an instance. + * + * @param object the object to convert + * @param maxLength the maximum length of the result + * @return a string describing the object + */ +QByteArray ReASInteger::toString(void* object, int maxLength) const{ + char buffer[64]; + qsnprintf(buffer, sizeof buffer, "%.*d", maxLength, + ((ReASVariant *) object)->asInt()); + return buffer; +} + +/** @class ReASString rplastree.hpp "rplexpr/rplastree.hpp" + * + * @brief Implements the class of a string. + * + * A string is a mutable character sequence. + */ +/** + * @brief Constructor. + */ +ReASString::ReASString(ReASTree& tree) : + ReASClass("Str", tree){ +} +/** + * @brief Creates a value object (used in ReASVariant). + * + * @param source NULL or a source to copy + * @return a new value object (specific for the class) + */ +void* ReASString::newValueInstance(void* source) const{ + QByteArray* rc = + source == NULL ? + new QByteArray() : new QByteArray(*(QByteArray*) source); + return (void*) rc; +} + +/** + * @brief Destroys the given object. + * + * The object must be created by newValueInstance(). + * + * @param object object to destroy + */ +void ReASString::destroyValueInstance(void* object) const{ + delete (QByteArray*) object; +} + +/** + * @brief Calculates the boolean value of an class specific object. + * + * This method should never be called. + * + * @param object the object to test (a QByteArray* instance) + * @return false: the string is empty + * true: otherwise + */ +bool ReASString::boolValueOf(void* object) const{ + bool rc = false; + if (object != NULL){ + QByteArray* string = static_cast (object); + if (string == NULL) + throw ReException("ReASString.boolValueOf(): not a string"); + rc = !string->isEmpty(); + } + return rc; +} + +/** + * @brief Returns a string representation of an instance. + * + * @param object the object to convert + * @param maxLength the maximum length of the result + * @return a string describing the object + */ +QByteArray ReASString::toString(void* object, int maxLength) const{ + QByteArray rc; + QByteArray* string = reinterpret_cast (object); + int length = string->size(); + if (length + 2 > maxLength) + length = maxLength - 2; + rc.reserve(length); + rc += "'"; + if (string->size() < maxLength - 2){ + rc += *string; + }else{ + rc += string->mid(0, maxLength - 2 - 3); + rc += "..."; + } + rc += "'"; + return rc; +} + +/** @class ReASList rplastree.hpp "rplexpr/rplastree.hpp" + * + * @brief Implements the class of a list. + * + * A list is a container of any values. Values can be selected by the index. + */ +/** + * @brief Constructor. + */ +ReASList::ReASList(ReASTree& tree) : + ReASClass("List", tree){ +} + +/** + * @brief Creates a value object (used in ReASVariant). + * + * @param source NULL or a source to copy + * @return a new value object (specific for the class) + */ +void* ReASList::newValueInstance(void* source) const{ + ReASListOfVariants* rc = new ReASListOfVariants(); + if (source != NULL){ + ReASListOfVariants* source2 = (ReASListOfVariants*) source; + rc->reserve(source2->size()); + ReASListOfVariants::iterator it; + for (it = source2->begin(); it != source2->end(); it++){ + // deleting in destroyValue(): + rc->append(new ReASVariant(*(*it))); + } + } + return (void*) rc; +} + +/** + * @brief Destroys the given object. + * + * The object must be created by newValueInstance(). + * + * @param object object to destroy + */ +void ReASList::destroyValueInstance(void* object) const{ + delete static_cast (object); +} + +/** + * @brief Calculates the boolean value of an class specific object. + * + * @param object the object to test (with type QList*) + * @return false: the list is empty
+ * true: otherwise + */ +bool ReASList::boolValueOf(void* object) const{ + bool rc = false; + if (object != NULL){ + ReASListOfVariants* list = static_cast (object); + if (list == NULL) + throw ReException("ReASList.boolValueOf(): not a list"); + rc = !list->empty(); + } + return rc; +} + +/** + * @brief Returns a string representation of an instance. + * + * @param object the object to convert + * @param maxLength unused + * @return a string describing the object + */ +QByteArray ReASList::toString(void* object, int maxLength) const{ + QByteArray rc; + rc.reserve(maxLength); + rc += "["; + ReASListOfVariants* list = reinterpret_cast (object); + ReASListOfVariants::iterator it; + bool first = true; + for (it = list->begin(); it != list->end(); it++){ + if (first) + first = false; + else + rc += ","; + QByteArray part = (*it)->toString(maxLength - rc.size() - 5); + if (maxLength - rc.size() - 5 - part.size() <= 0){ + rc += "..."; + break; + }else{ + rc += part; + } + + } + rc += "]"; + return rc; +} + +/** @class ReASMap rplastree.hpp "rplexpr/rplastree.hpp" + * + * @brief Implements the class of a map. + * + * A map is a container of (key, value) pairs. + * Values can be selected by the key. + */ +/** + * @brief Constructor. + */ +ReASMap::ReASMap(ReASTree& tree) : + ReASClass("Map", tree){ +} +/** + * @brief Creates a value object (used in ReASVariant). + * + * @param source NULL or a source to copy + * @return a new value object (specific for the class) + */ +void* ReASMap::newValueInstance(void* source) const{ + ReASMapOfVariants* rc = new ReASMapOfVariants(); + if (source != NULL){ + ReASMapOfVariants* source2 = static_cast (source); + // rc->reserve(source2->size()); + ReASMapOfVariants::iterator it; + for (it = source2->begin(); it != source2->end(); it++){ + // deleting in destroyValue(): + const QByteArray& key = it.key(); + ReASVariant* value = new ReASVariant(*it.value()); + (*rc)[key] = value; + } + } + return (void*) rc; +} + +/** + * @brief Destroys the given object. + * + * The object must be created by newValueInstance(). + * + * @param object object to destroy + */ +void ReASMap::destroyValueInstance(void* object) const{ + delete (ReASMapOfVariants*) object; +} + +/** + * @brief Calculates the boolean value of an class specific object. + * + * @param object the object to test (with type QMap*) + * @return + */ +bool ReASMap::boolValueOf(void* object) const{ + bool rc = false; + if (object != NULL){ + ReASMapOfVariants* map = reinterpret_cast (object); + if (map == NULL) + throw ReException("ReASMap.boolValueOf(): not a map"); + rc = map->empty() > 0; + } + return rc; +} + +/** + * @brief Returns a string representation of an instance. + * + * @param object the object to convert + * @param maxLength maximal length of the result + * @return a string describing the object + */ +QByteArray ReASMap::toString(void* object, int maxLength) const{ + QByteArray rc; + rc.reserve(maxLength); + rc += "["; + ReASMapOfVariants* map = reinterpret_cast (object); + ReASMapOfVariants::iterator it; + bool first = true; + for (it = map->begin(); it != map->end(); it++){ + if (first) + first = false; + else + rc += ","; + if (maxLength - rc.size() - 5 - 2 - it.key().size() <= 0){ + rc += "..."; + break; + }else{ + rc += "'"; + rc += it.key(); + rc += "':"; + } + QByteArray part = it.value()->toString(maxLength - rc.size() - 5); + if (maxLength - rc.size() - 5 - part.size() <= 0){ + rc += "..."; + break; + }else{ + rc += part; + } + + } + rc += "}"; + return rc; +} + +/** @class ReVariable rplastree.hpp "rplexpr/rplastree.hpp" + * + * @brief Implements a variable of a symbol space. + */ + +/** + * @brief Constructor. + */ +ReVariable::ReVariable(const QByteArray& name) : + m_name(name), m_namespace(NULL), m_value(), m_type(NULL){ + +} + +/** + * @brief Writes the content of the instance into an output media. + * + * @param writer writes to output + * @param indent nesting level: so many tabs will be used as prefix + */ +void ReVariable::dump(ReWriter& writer, int indent){ + const char* name1 = m_type == NULL ? "NoneType" : m_type->name().constData(); + QByteArray val = m_value.toString(); + writer.formatIndented(indent, "%s %s: value: %s", name1, m_name.constData(), + val.constData()); +} +/** + * @brief Returns the data type of the variable. + * + * @return the class of the variable + */ +ReASClass* ReVariable::type() const{ + return m_type; +} + +/** + * @brief Sets the data type. + * @param type the class of the variable + */ +void ReVariable::setType(ReASClass* type){ + m_type = type; +} +/** + * @brief Returns the name of the variable. + * + * @return the name + */ +const QByteArray& ReVariable::name() const{ + return m_name; +} + +/** @class ReVariable rplastree.hpp "rplexpr/rplastree.hpp" + * + * @brief Implements a data type representing a none type. + */ +ReASVoid::ReASVoid(ReASTree& tree) : + ReASClass("Void", tree){ +} + +/** + * @brief Instantiates a new object. + * + * In this case we do nothing. + * + * @param source ignored + * @return + */ +void*ReASVoid::newValueInstance(void*) const{ + return NULL; +} + +/** + * @brief Destroys an object created by newValueInstance. + * + * In this case we do nothing. + * + * @param object not used + */ +void ReASVoid::destroyValueInstance(void*) const{ +} + +/** + * @brief Returns the bool value of the given object + * @param object ignored + * @return false + */ +bool ReASVoid::boolValueOf(void*) const{ + return false; +} + +/** + * @brief Converts the object into a string. + * + * @param object ignored + * @param maxLength ignored + * @return the empty string + */ +QByteArray ReASVoid::toString(void*, int) const{ + return QByteArray(""); +} + +/** @class ReASFormula rplastree.hpp "rplexpr/rplastree.hpp" + * + * @brief Implements a data type representing a calculated value. + */ + +/** + * @brief Constructor. + * + * @param tree the abstract syntax tree + */ +ReASFormula::ReASFormula(ReASTree& tree) : + ReASClass("Formula", tree){ +} + +/** + * @brief Instantiates a new object. + * + * In this case we do nothing. + * + * @param expr the result + * @return + */ +void* ReASFormula::newValueInstance(void* expr) const{ + return expr; +} + +/** + * @brief Destroys an object created by newValueInstance. + * + * In this case we do nothing. + * + * @param object not used + */ +void ReASFormula::destroyValueInstance(void*) const{ +} + +/** + * @brief Returns the bool value of the given object + * @param object ignored + * @return false + */ +bool ReASFormula::boolValueOf(void*) const{ + return false; +} + +/** + * @brief Converts the object into a string. + * + * @param object ignored + * @param maxLength ignored + * @return the empty string + */ +QByteArray ReASFormula::toString(void* object, int) const{ + ReASExprStatement* expr = static_cast (object); + + char buffer[64]; + qsnprintf(buffer, sizeof buffer, "", expr->id()); + return buffer; +} + +/** @class ReASUserClass rplastree.hpp "rplexpr/rplastree.hpp" + * + * @brief Implements a data type representing an user defined class. + */ + +/** + * @brief Constructor. + * + * @param name name of the user defined class + * @param position the position of the class definition + * @param tree the abstract syntax tree + */ +ReASUserClass::ReASUserClass(const QByteArray& name, + const ReSourcePosition* position, ReASTree& tree) : + ReASClass(name, tree), m_position(position){ +} + +/** + * @brief Creates an instance of an user defined class. + * + * @param source the type (user defined class) of the result + * @return an instance of an user defined class + */ +void*ReASUserClass::newValueInstance(void* source) const{ + ReASUserClass* clazz = static_cast (source); + ReASUserObject* rc = new ReASUserObject(clazz); + return static_cast (rc); +} + +void ReASUserClass::destroyValueInstance(void* object) const{ + ReASUserObject* obj = static_cast (object); + delete obj; +} + +/** + * @brief Returns the bool value of the object. + * + * @param object object to test + * @return true: object != NULL
+ * false: object == NULL + */ +bool ReASUserClass::boolValueOf(void* object) const{ + return object != NULL; +} + +/** + * @brief Returns a string representation an instance of a user defined class. + * + * @param object object to convert + * @param maxLength maximum length of the string + * @return + */ +QByteArray ReASUserClass::toString(void*, int) const{ + return m_name; +} +/** + * @brief Returns the source position of the instance. + * + * @return the source position + */ +const ReSourcePosition* ReASUserClass::position() const{ + return m_position; +} + +/** @class ReASUserObject rplastree.hpp "rplexpr/rplastree.hpp" + * + * @brief Implements an instance of an user defined class. + */ +ReASUserObject::ReASUserObject(ReASUserClass* clazz) : + m_class(clazz), m_fields(NULL){ +} + +/** + * @brief Destructor. + */ +ReASUserObject::~ReASUserObject(){ + delete[] m_fields; + m_fields = NULL; +} diff --git a/expr/ReASClasses.hpp b/expr/ReASClasses.hpp new file mode 100644 index 0000000..d99bee4 --- /dev/null +++ b/expr/ReASClasses.hpp @@ -0,0 +1,210 @@ +/* + * ReAsClasses.hpp + * + * License: Public Domain + * You can use and modify this file without any restriction. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ + +#ifndef RPLASCLASSES_HPP +#define RPLASCLASSES_HPP + +class ReSymbolSpace; +class ReVariable { +public: + ReVariable(const QByteArray& name); +public: + void dump(ReWriter& writer, int indent); + + ReASClass* type() const; + void setType(ReASClass* type); + const QByteArray& name() const; + +protected: + QByteArray m_name; + // NULL for "simple" variables (int, float, bool) + ReSymbolSpace* m_namespace; + ReASVariant m_value; + ReASClass* m_type; +}; + +class ReASScope { +public: + int m_builtInVars; + int m_varNoAtStart; +}; + +class ReASUserClass; +class ReASTree; +class ReSymbolSpace { +public: + enum SymbolSpaceType { + SST_UNDEF, SST_GLOBAL, SST_MODULE, SST_CLASS, SST_METHOD + }; + +public: + typedef QMap VariableMap; + typedef QMap ClassMap; + typedef QMap MethodMap; + typedef QList VariableList; +private: + ReSymbolSpace(ReASTree& tree); +public: + ReSymbolSpace(SymbolSpaceType type, const QByteArray& name, + ReSymbolSpace* parent); + virtual ~ReSymbolSpace(); +public: + void startScope(ReASScope& scope); + void finishScope(int endOfScope, ReASScope& scope); + ReASVarDefinition* findVariable(const QByteArray& name) const; + ReASClass* findClass(const QByteArray& name) const; + ReASMethod* findMethod(const QByteArray& name) const; + void dump(ReWriter& writer, int indent, const char* header = NULL); + const QByteArray& name() const; + ReASItem* body() const; + void setBody(ReASItem* body); + ReASItem* addVariable(ReASVarDefinition* variable, int& varNo); + ReASItem* addMethod(ReASMethod* method); + ReASUserClass* addClass(ReASUserClass* clazz); + ReSymbolSpace* parent() const; + VariableList listOfVars() const; +public: + static const char* spaceTypeName(SymbolSpaceType type); + static ReSymbolSpace* createGlobal(ReASTree& tree); +private: + SymbolSpaceType m_type; + QByteArray m_name; + VariableMap m_variables; + ClassMap m_classes; + MethodMap m_methods; + ReSymbolSpace* m_parent; + ReASItem* m_body; + VariableList m_listOfVars; + ReASTree& m_tree; +}; + +class ReASBoolean: public ReASClass { +public: + ReASBoolean(ReASTree& tree); +public: + void* newValueInstance(void* source = NULL) const; + void destroyValueInstance(void* object) const; + virtual bool boolValueOf(void* object) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; +public: + static ReASBoolean* m_instance; +}; + +class ReASFloat: public ReASClass { +public: + ReASFloat(ReASTree& tree); + ReASFloat(const QByteArray& name, ReASTree& tree); +public: + void* newValueInstance(void* source = NULL) const; + void destroyValueInstance(void* object) const; + virtual bool boolValueOf(void* object) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; +public: + static ReASFloat* m_instance; +}; + +class ReASInteger: public ReASFloat { +public: + ReASInteger(ReASTree& tree); +public: + virtual bool boolValueOf(void* object) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; +public: + static ReASInteger* m_instance; +}; + +class ReASString: public ReASClass { +public: + ReASString(ReASTree& tree); +public: + void* newValueInstance(void* source = NULL) const; + void destroyValueInstance(void* object) const; + virtual bool boolValueOf(void* object) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; +public: + static ReASString* m_instance; +}; + +class ReASList: public ReASClass { +public: + ReASList(ReASTree& tree); +public: + void* newValueInstance(void* source = NULL) const; + void destroyValueInstance(void* object) const; + virtual bool boolValueOf(void* object) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; +public: + static ReASList* m_instance; +}; + +class ReASMap: public ReASClass { +public: + ReASMap(ReASTree& tree); +public: + void* newValueInstance(void* source = NULL) const; + void destroyValueInstance(void* object) const; + virtual bool boolValueOf(void* object) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; +public: + static ReASMap* m_instance; +}; + +class ReASVoid: public ReASClass { +public: + ReASVoid(ReASTree& tree); +public: + void* newValueInstance(void* source = NULL) const; + void destroyValueInstance(void* object) const; + virtual bool boolValueOf(void* object) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; +public: + static ReASVoid* m_instance; +}; + +class ReASFormula: public ReASClass { +public: + ReASFormula(ReASTree& tree); +public: + void* newValueInstance(void* source = NULL) const; + void destroyValueInstance(void* object) const; + virtual bool boolValueOf(void* object) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; +public: + static ReASFormula* m_instance; +}; + +class ReASUserClass: public ReASClass { +public: + ReASUserClass(const QByteArray& name, const ReSourcePosition* position, + ReASTree& tree); +public: + void* newValueInstance(void* source = NULL) const; + void destroyValueInstance(void* object) const; + virtual bool boolValueOf(void* object) const; + virtual QByteArray toString(void *object, int maxLength = 80) const; + const ReSourcePosition* position() const; + +private: + const ReSourcePosition* m_position; +}; + +class ReASUserObject { +public: + ReASUserObject(ReASUserClass* clazz); + ~ReASUserObject(); +public: + void callMember(); +private: + ReASUserClass* m_class; + ReASVariant* m_fields; +}; + +#endif // RPLASCLASSES_HPP diff --git a/expr/ReASTree.cpp b/expr/ReASTree.cpp index 593a67a..d87ffac 100644 --- a/expr/ReASTree.cpp +++ b/expr/ReASTree.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * ReASTree.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * * @brief Implementation of an Abstract Syntax Tree. @@ -16,47 +19,44 @@ * */ -#include "../base/rebase.hpp" +#include "base/rebase.hpp" #include "expr/reexpr.hpp" enum { - LOC_VARDEF_EXEC_1 = LOC_FIRST_OF(LOC_ASTREE), // 11001 - LOC_UNOP_CALC_1, - LOC_UNARY_CHECK_1, - LOC_UNARY_CHECK_2, - LOC_UNARY_CHECK_3, // 11005 - LOC_BINOP_1, - LOC_BINOP_CALC_1, - LOC_BINOP_CALC_2, - LOC_BINOP_CALC_3, - LOC_BINOP_CALC_4, // 11010 - LOC_BINOP_CALC_5, - LOC_BINOP_CALC_6, - LOC_BINOP_CALC_7, - LOC_BINOP_CALC_8, - LOC_BINOP_CALC_9, // 11015 - LOC_BINOP_CALC_10, - LOC_BINOP_CALC_11, - LOC_BINOP_CALC_12, - LOC_VARDEF_CHECK_1, - LOC_VARDEF_CHECK_2, // 11020 - LOC_ITEM_STATEM_LIST_1, - LOC_CONV_CHECK_1, - LOC_CONV_TRY_1, - LOC_ITEM_FORCE_ERROR_1, - LOC_UNARY_CHECK_4, // 11025 - LOC_IF_CHECK_1, - LOC_IF_CHECK_2, - LOC_FORC_CHECK_1, - LOC_FORC_CHECK_2, - LOC_FORC_CHECK_3, // 11030 - LOC_ITEM_AS_INT_1, - LOC_ITEM_AS_INT_2, - LOC_METHOD_CALL_CHECK_1, - LOC_MEHTOD_CALL_CHECK_2, - LOC_MEHTOD_CALL_CHECK_3, // 11035 - LOC_MEHTOD_CALL_CHECK_4, - LOC_COUNT + LOC_VARDEF_EXEC_1 = LOC_FIRST_OF(LOC_ASTREE), // 11001 + LOC_UNOP_CALC_1, LOC_UNARY_CHECK_1, LOC_UNARY_CHECK_2, LOC_UNARY_CHECK_3, // 11005 + LOC_BINOP_1, + LOC_BINOP_CALC_1, + LOC_BINOP_CALC_2, + LOC_BINOP_CALC_3, + LOC_BINOP_CALC_4, // 11010 + LOC_BINOP_CALC_5, + LOC_BINOP_CALC_6, + LOC_BINOP_CALC_7, + LOC_BINOP_CALC_8, + LOC_BINOP_CALC_9, // 11015 + LOC_BINOP_CALC_10, + LOC_BINOP_CALC_11, + LOC_BINOP_CALC_12, + LOC_VARDEF_CHECK_1, + LOC_VARDEF_CHECK_2, // 11020 + LOC_ITEM_STATEM_LIST_1, + LOC_CONV_CHECK_1, + LOC_CONV_TRY_1, + LOC_ITEM_FORCE_ERROR_1, + LOC_UNARY_CHECK_4, // 11025 + LOC_IF_CHECK_1, + LOC_IF_CHECK_2, + LOC_FORC_CHECK_1, + LOC_FORC_CHECK_2, + LOC_FORC_CHECK_3, // 11030 + LOC_ITEM_AS_INT_1, + LOC_ITEM_AS_INT_2, + LOC_METHOD_CALL_CHECK_1, + LOC_MEHTOD_CALL_CHECK_2, + LOC_MEHTOD_CALL_CHECK_3, // 11035 + LOC_MEHTOD_CALL_CHECK_4, + LOC_COUNT }; unsigned int ReASItem::m_nextId = 1; @@ -75,28 +75,27 @@ unsigned int ReASItem::m_nextId = 1; * @param map map to dump * @param withEndOfLine true: '\n' will be written at the end */ -void dumpMap(ReWriter& writer, ReASMapOfVariants& map, bool withEndOfLine) -{ - QList sorted; - sorted.reserve(map.size()); - ReASMapOfVariants::iterator it; - for (it = map.begin(); it != map.end(); it++){ - sorted.append(it.key()); - } - qSort(sorted.begin(), sorted.end(), qLess()); - QList::iterator it2; - bool first = true; - for (it2 = sorted.begin(); it2 != sorted.end(); it2++){ - ReASVariant* value = map[*it2]; - writer.format("%c'%s':%s", first ? '{' : ',', (*it2).constData(), - value->toString().constData()); - first = false; - } - if (first) - writer.write("{"); - writer.write("}"); - if (withEndOfLine) - writer.writeLine(); +void dumpMap(ReWriter& writer, ReASMapOfVariants& map, bool withEndOfLine){ + QList < QByteArray > sorted; + sorted.reserve(map.size()); + ReASMapOfVariants::iterator it; + for (it = map.begin(); it != map.end(); it++){ + sorted.append(it.key()); + } + qSort(sorted.begin(), sorted.end(), qLess ()); + QList ::iterator it2; + bool first = true; + for (it2 = sorted.begin(); it2 != sorted.end(); it2++){ + ReASVariant* value = map[*it2]; + writer.format("%c'%s':%s", first ? '{' : ',', (*it2).constData(), + value->toString().constData()); + first = false; + } + if (first) + writer.write("{"); + writer.write("}"); + if (withEndOfLine) + writer.writeLine(); } /** @class ReASException rplastree.hpp "rplexpr/rplastree.hpp" @@ -111,16 +110,15 @@ void dumpMap(ReWriter& writer, ReASMapOfVariants& map, bool withEndOfLine) * @param format the reason of the exception * @param varList the values for the placeholders in the format. */ -void ReASException::build(const ReSourcePosition* position, - const char* format, va_list varList) -{ - char buffer[64000]; - if (position != NULL){ - m_message = position->toString().toUtf8(); - m_message += ": "; - } - qvsnprintf(buffer, sizeof buffer, format, varList); - m_message += buffer; +void ReASException::build(const ReSourcePosition* position, const char* format, + va_list varList){ + char buffer[64000]; + if (position != NULL){ + m_message = position->toString().toUtf8(); + m_message += ": "; + } + qvsnprintf(buffer, sizeof buffer, format, varList); + m_message += buffer; } /** @@ -131,21 +129,19 @@ void ReASException::build(const ReSourcePosition* position, * @param ... the values for the placeholders in the format. */ ReASException::ReASException(const ReSourcePosition* position, - const char* format, ...) : - ReException("") -{ - va_list ap; - va_start(ap, format); - build(position, format, ap); - va_end(ap); + const char* format, ...) : + ReException(""){ + va_list ap; + va_start(ap, format); + build(position, format, ap); + va_end(ap); } /** * @brief Constructor. */ ReASException::ReASException() : - ReException("") -{ + ReException(""){ } /** @class ReASVariant rplastree.hpp "rplexpr/rplastree.hpp" @@ -159,32 +155,27 @@ ReASException::ReASException() : * @brief Constructor. */ ReASVariant::ReASVariant() : - m_variantType(VT_UNDEF), - m_flags(VF_UNDEF), - // m_value(), - m_class(NULL) -{ + m_variantType(VT_UNDEF), m_flags(VF_UNDEF), + // m_value(), + m_class(NULL){ } /** * @brief Destructor. */ -ReASVariant::~ReASVariant() -{ - destroyValue(); - m_variantType = VT_UNDEF; +ReASVariant::~ReASVariant(){ + destroyValue(); + m_variantType = VT_UNDEF; } /** * @brief Copy constructor. * @param source the source to copy */ -ReASVariant::ReASVariant(const ReASVariant& source): - m_variantType(source.m_variantType), - m_flags(source.m_flags), - // m_value - m_class(source.m_class) -{ - copyValue(source); +ReASVariant::ReASVariant(const ReASVariant& source) : + m_variantType(source.m_variantType), m_flags(source.m_flags), + // m_value + m_class(source.m_class){ + copyValue(source); } /** @@ -193,74 +184,68 @@ ReASVariant::ReASVariant(const ReASVariant& source): * @param source the source to copy * @return the instance itself */ -ReASVariant&ReASVariant::operator=(const ReASVariant& source) -{ - destroyValue(); - m_variantType = source.m_variantType; - m_flags = source.m_flags; - m_class = source.m_class; - copyValue(source); - return *this; +ReASVariant&ReASVariant::operator=(const ReASVariant& source){ + destroyValue(); + m_variantType = source.m_variantType; + m_flags = source.m_flags; + m_class = source.m_class; + copyValue(source); + return *this; } /** * @brief Copies the value. * @param source the source to copy */ -void ReASVariant::copyValue(const ReASVariant& source) -{ - destroyValue(); - m_variantType = source.m_variantType; - m_class = source.m_class; - - switch(source.m_variantType) - { - case VT_BOOL: - m_value.m_bool = source.m_value.m_bool; - break; - case VT_FLOAT: - m_value.m_float = source.m_value.m_float; - break; - case VT_INTEGER: - m_value.m_int = source.m_value.m_int; - break; - case VT_UNDEF: - break; - default: - m_value.m_object = m_class->newValueInstance(source.m_value.m_object); - break; - } - m_flags = source.m_flags; +void ReASVariant::copyValue(const ReASVariant& source){ + destroyValue(); + m_variantType = source.m_variantType; + m_class = source.m_class; + + switch (source.m_variantType) { + case VT_BOOL: + m_value.m_bool = source.m_value.m_bool; + break; + case VT_FLOAT: + m_value.m_float = source.m_value.m_float; + break; + case VT_INTEGER: + m_value.m_int = source.m_value.m_int; + break; + case VT_UNDEF: + break; + default: + m_value.m_object = m_class->newValueInstance(source.m_value.m_object); + break; + } + m_flags = source.m_flags; } /** * @brief Frees the resources of the instance. */ -void ReASVariant::destroyValue() -{ - switch(m_variantType) - { - case VT_BOOL: - case VT_FLOAT: - case VT_INTEGER: - case VT_UNDEF: - break; - default: - if ((m_flags & VF_IS_COPY) == 0) - m_class->destroyValueInstance(m_value.m_object); - m_value.m_object = NULL; - break; - } - m_variantType = VT_UNDEF; +void ReASVariant::destroyValue(){ + switch (m_variantType) { + case VT_BOOL: + case VT_FLOAT: + case VT_INTEGER: + case VT_UNDEF: + break; + default: + if ((m_flags & VF_IS_COPY) == 0) + m_class->destroyValueInstance(m_value.m_object); + m_value.m_object = NULL; + break; + } + m_variantType = VT_UNDEF; } /** * @brief Returns the variantType of the instance. * * @return the variant type */ -ReASVariant::VariantType ReASVariant::variantType() const -{ - return m_variantType; +ReASVariant::VariantType ReASVariant::variantType() const{ + return m_variantType; } /** @@ -268,29 +253,28 @@ ReASVariant::VariantType ReASVariant::variantType() const * * @return the type as string */ -const char*ReASVariant::nameOfType() const -{ - const char* rc = "?"; - switch(m_variantType){ - case VT_UNDEF: - rc = ""; - break; - case VT_FLOAT: - rc = "Float"; - break; - case VT_INTEGER: - rc = "Int"; - break; - case VT_BOOL: - rc = "Bool"; - break; - case VT_OBJECT: - rc = "Obj"; - break; - default: - break; - } - return rc; +const char*ReASVariant::nameOfType() const{ + const char* rc = "?"; + switch (m_variantType) { + case VT_UNDEF: + rc = ""; + break; + case VT_FLOAT: + rc = "Float"; + break; + case VT_INTEGER: + rc = "Int"; + break; + case VT_BOOL: + rc = "Bool"; + break; + case VT_OBJECT: + rc = "Obj"; + break; + default: + break; + } + return rc; } /** @@ -298,12 +282,10 @@ const char*ReASVariant::nameOfType() const * * @return the variant type */ -const ReASClass* ReASVariant::getClass() const -{ - return m_class; +const ReASClass* ReASVariant::getClass() const{ + return m_class; } - /** * @brief Returns the numeric value. * @@ -311,12 +293,11 @@ const ReASClass* ReASVariant::getClass() const * @throw RplException the instance is not a numberic value * */ -qreal ReASVariant::asFloat() const -{ - if (m_variantType != VT_FLOAT) - throw ReException("ReASVariant::asNumber: not a number: %d", - m_variantType); - return m_value.m_float; +qreal ReASVariant::asFloat() const{ + if (m_variantType != VT_FLOAT) + throw ReException("ReASVariant::asNumber: not a number: %d", + m_variantType); + return m_value.m_float; } /** * @brief Returns the numeric value. @@ -325,12 +306,11 @@ qreal ReASVariant::asFloat() const * @throw RplException the instance is not a numberic value * */ -int ReASVariant::asInt() const -{ - if (m_variantType != VT_INTEGER) - throw ReException("ReASVariant::asInt: not an integer: %d", - m_variantType); - return m_value.m_int; +int ReASVariant::asInt() const{ + if (m_variantType != VT_INTEGER) + throw ReException("ReASVariant::asInt: not an integer: %d", + m_variantType); + return m_value.m_int; } /** @@ -340,12 +320,11 @@ int ReASVariant::asInt() const * @throw RplException the instance is not a boolean value * */ -bool ReASVariant::asBool() const -{ - if (m_variantType != VT_BOOL) - throw ReException("ReASVariant::asBool: not a boolean: %d", - m_variantType); - return m_value.m_bool; +bool ReASVariant::asBool() const{ + if (m_variantType != VT_BOOL) + throw ReException("ReASVariant::asBool: not a boolean: %d", + m_variantType); + return m_value.m_bool; } /** @@ -356,14 +335,13 @@ bool ReASVariant::asBool() const * @throw RplException the instance is not a boolean value * */ -void* ReASVariant::asObject(const ReASClass** clazz) const -{ - if (m_variantType != VT_OBJECT) - throw ReException("ReASVariant::asObject: not an object: %d", - m_variantType); - if (clazz != NULL) - *clazz = m_class; - return m_value.m_object; +void* ReASVariant::asObject(const ReASClass** clazz) const{ + if (m_variantType != VT_OBJECT) + throw ReException("ReASVariant::asObject: not an object: %d", + m_variantType); + if (clazz != NULL) + *clazz = m_class; + return m_value.m_object; } /** @@ -372,16 +350,15 @@ void* ReASVariant::asObject(const ReASClass** clazz) const * @return the value as string * @throw RplException the instance is not a string value */ -const QByteArray* ReASVariant::asString() const -{ - const ReASClass* clazz; - const QByteArray* rc = static_cast(asObject(&clazz)); - if (clazz != ReASString::m_instance){ - const QByteArray& name = clazz->name(); - throw ReException("ReASVariant::asString: not a string: %s", - name.constData()); - } - return rc; +const QByteArray* ReASVariant::asString() const{ + const ReASClass* clazz; + const QByteArray* rc = static_cast (asObject(&clazz)); + if (clazz != ReASString::m_instance){ + const QByteArray& name = clazz->name(); + throw ReException("ReASVariant::asString: not a string: %s", + name.constData()); + } + return rc; } /** @@ -389,12 +366,11 @@ const QByteArray* ReASVariant::asString() const * * @param number the numeric value. */ -void ReASVariant::setFloat(qreal number) -{ - destroyValue(); - m_variantType = VT_FLOAT; - m_value.m_float = number; - m_class = ReASFloat::m_instance; +void ReASVariant::setFloat(qreal number){ + destroyValue(); + m_variantType = VT_FLOAT; + m_value.m_float = number; + m_class = ReASFloat::m_instance; } /** @@ -402,12 +378,11 @@ void ReASVariant::setFloat(qreal number) * * @param integer the numeric value. */ -void ReASVariant::setInt(int integer) -{ - destroyValue(); - m_variantType = VT_INTEGER; - m_value.m_int = integer; - m_class = ReASInteger::m_instance; +void ReASVariant::setInt(int integer){ + destroyValue(); + m_variantType = VT_INTEGER; + m_value.m_int = integer; + m_class = ReASInteger::m_instance; } /** @@ -415,12 +390,11 @@ void ReASVariant::setInt(int integer) * * @param value the boolean value. */ -void ReASVariant::setBool(bool value) -{ - destroyValue(); - m_variantType = VT_BOOL; - m_value.m_bool = value; - m_class = ReASBoolean::m_instance; +void ReASVariant::setBool(bool value){ + destroyValue(); + m_variantType = VT_BOOL; + m_value.m_bool = value; + m_class = ReASBoolean::m_instance; } /** @@ -428,10 +402,9 @@ void ReASVariant::setBool(bool value) * * @param string the string value. */ -void ReASVariant::setString(const QByteArray& string) -{ - // deletion in ReASVariant::destroyValue(): - setObject(new QByteArray(string), ReASString::m_instance); +void ReASVariant::setString(const QByteArray& string){ + // deletion in ReASVariant::destroyValue(): + setObject(new QByteArray(string), ReASString::m_instance); } /** @@ -440,32 +413,30 @@ void ReASVariant::setString(const QByteArray& string) * @param maxLength the maximum length of the result * @return the value as string */ -QByteArray ReASVariant::toString(int maxLength) const -{ - QByteArray rc; - char buffer[256]; - switch(m_variantType) - { - case VT_BOOL: - rc = m_value.m_bool ? "True" : "False"; - break; - case VT_FLOAT: - qsnprintf(buffer, sizeof buffer, "%f", m_value.m_float); - rc = buffer; - break; - case VT_INTEGER: - qsnprintf(buffer, sizeof buffer, "%lld", m_value.m_int); - rc = buffer; - break; - case VT_OBJECT: - rc = m_class->toString(m_value.m_object, maxLength); - break; - default: - case VT_UNDEF: - rc = "None"; - break; - } - return rc; +QByteArray ReASVariant::toString(int maxLength) const{ + QByteArray rc; + char buffer[256]; + switch (m_variantType) { + case VT_BOOL: + rc = m_value.m_bool ? "True" : "False"; + break; + case VT_FLOAT: + qsnprintf(buffer, sizeof buffer, "%f", m_value.m_float); + rc = buffer; + break; + case VT_INTEGER: + qsnprintf(buffer, sizeof buffer, "%lld", m_value.m_int); + rc = buffer; + break; + case VT_OBJECT: + rc = m_class->toString(m_value.m_object, maxLength); + break; + default: + case VT_UNDEF: + rc = "None"; + break; + } + return rc; } /** @@ -474,15 +445,13 @@ QByteArray ReASVariant::toString(int maxLength) const * @param object the class specific value object. * @param clazz the data type of the object */ -void ReASVariant::setObject(void* object, const ReASClass* clazz) -{ - destroyValue(); - m_variantType = VT_OBJECT; - m_value.m_object = object; - m_class = clazz; +void ReASVariant::setObject(void* object, const ReASClass* clazz){ + destroyValue(); + m_variantType = VT_OBJECT; + m_value.m_object = object; + m_class = clazz; } - /** @class ReASItem rplastree.hpp "rplexpr/rplastree.hpp" * * @brief Implements the abstract base class of all entries of an AST. @@ -495,18 +464,13 @@ void ReASVariant::setObject(void* object, const ReASClass* clazz) * @param type the type of the instance */ ReASItem::ReASItem(ReASItemType type) : - m_id(m_nextId++), - m_nodeType(type), - m_flags(0), - m_position(NULL) -{ + m_id(m_nextId++), m_nodeType(type), m_flags(0), m_position(NULL){ } /** * @brief Destructor. */ -ReASItem::~ReASItem() -{ +ReASItem::~ReASItem(){ } /** @@ -519,22 +483,22 @@ ReASItem::~ReASItem() * false: otherwise */ bool ReASItem::checkAsCalculable(const char* description, - ReASClass* expectedClass, ReParser& parser) -{ - bool rc = true; - if (! check(parser)) - rc = false; - if (rc){ - ReASCalculable* expr = dynamic_cast(this); - if (expr == NULL) - rc = error(LOC_ITEM_AS_INT_1, parser, "%s not calculable: %s", - description, nameOfItemType()); - else if (expr->clazz() != ReASInteger::m_instance) - rc = error(LOC_ITEM_AS_INT_2, parser, - "%s: wrong type %s instead of integer", - description, expr->clazz()->name().constData()); - } - return rc; + ReASClass* expectedClass, ReParser& parser){ + RE_UNUSED(expectedClass); + bool rc = true; + if (!check(parser)) + rc = false; + if (rc){ + ReASCalculable* expr = dynamic_cast (this); + if (expr == NULL) + rc = error(LOC_ITEM_AS_INT_1, parser, "%s not calculable: %s", + description, nameOfItemType()); + else if (expr->clazz() != ReASInteger::m_instance) + rc = error(LOC_ITEM_AS_INT_2, parser, + "%s: wrong type %s instead of integer", description, + expr->clazz()->name().constData()); + } + return rc; } /** @@ -542,9 +506,8 @@ bool ReASItem::checkAsCalculable(const char* description, * * @return the position of the item */ -const ReSourcePosition* ReASItem::position() const -{ - return m_position; +const ReSourcePosition* ReASItem::position() const{ + return m_position; } /** @@ -552,9 +515,8 @@ const ReSourcePosition* ReASItem::position() const * * @param position the position to store */ -void ReASItem::setPosition(const ReSourcePosition* position) -{ - m_position = position; +void ReASItem::setPosition(const ReSourcePosition* position){ + m_position = position; } /** @@ -562,9 +524,8 @@ void ReASItem::setPosition(const ReSourcePosition* position) * * @return the id */ -unsigned int ReASItem::id() const -{ - return m_id; +unsigned int ReASItem::id() const{ + return m_id; } /** @@ -574,12 +535,11 @@ unsigned int ReASItem::id() const * @param bufferSize size of the target buffer * @return buffer */ -char* ReASItem::positionStr(char buffer[], size_t bufferSize) const -{ - char* rc = (char*) ""; - if (m_position != NULL) - rc = m_position->utf8(buffer, bufferSize); - return rc; +char* ReASItem::positionStr(char buffer[], size_t bufferSize) const{ + char* rc = (char*) ""; + if (m_position != NULL) + rc = m_position->utf8(buffer, bufferSize); + return rc; } /** @@ -590,26 +550,24 @@ char* ReASItem::positionStr(char buffer[], size_t bufferSize) const * @param format string with placeholders (optional) like sprintf() * @param ... values for the placeholders */ -void ReASItem::error(ReLogger* logger, int location, const char* format, ...) -{ - char buffer[1024]; - int halfBufferSize = (sizeof buffer) / 2; - qsnprintf(buffer, halfBufferSize, "id: %d [%s]:", m_id, - positionStr(buffer + halfBufferSize, halfBufferSize)); - int length = strlen(buffer); - va_list ap; - va_start(ap, format); - qvsnprintf(buffer + length, (sizeof buffer) - length, format, ap); - va_end(ap); - logger->log(LOG_ERROR, location, buffer); +void ReASItem::error(ReLogger* logger, int location, const char* format, ...){ + char buffer[1024]; + int halfBufferSize = (sizeof buffer) / 2; + qsnprintf(buffer, halfBufferSize, "id: %d [%s]:", m_id, + positionStr(buffer + halfBufferSize, halfBufferSize)); + int length = strlen(buffer); + va_list ap; + va_start(ap, format); + qvsnprintf(buffer + length, (sizeof buffer) - length, format, ap); + va_end(ap); + logger->log(LOG_ERROR, location, buffer); } /** * @brief Resets the static id counter. */ -void ReASItem::reset() -{ - m_nextId = 1; +void ReASItem::reset(){ + m_nextId = 1; } /** * @brief Calculates an integer value. @@ -618,13 +576,12 @@ void ReASItem::reset() * @param thread the execution unit * @return the value described by the node expr */ -int ReASItem::calcAsInteger(ReASItem* expr, ReVMThread& thread) -{ - ReASCalculable* expr2 = dynamic_cast(expr); - expr2->calc(thread); - ReASVariant& value = thread.popValue(); - int rc = value.asInt(); - return rc; +int ReASItem::calcAsInteger(ReASItem* expr, ReVMThread& thread){ + ReASCalculable* expr2 = dynamic_cast (expr); + expr2->calc(thread); + ReASVariant& value = thread.popValue(); + int rc = value.asInt(); + return rc; } /** @@ -634,13 +591,12 @@ int ReASItem::calcAsInteger(ReASItem* expr, ReVMThread& thread) * @param thread the execution unit * @return the value described by the node expr */ -bool ReASItem::calcAsBoolean(ReASItem* expr, ReVMThread& thread) -{ - ReASCalculable* expr2 = dynamic_cast(expr); - expr2->calc(thread); - ReASVariant& value = thread.popValue(); - bool rc = value.asBool(); - return rc; +bool ReASItem::calcAsBoolean(ReASItem* expr, ReVMThread& thread){ + ReASCalculable* expr2 = dynamic_cast (expr); + expr2->calc(thread); + ReASVariant& value = thread.popValue(); + bool rc = value.asBool(); + return rc; } /** * @brief Checks the correctness of a statement list. @@ -650,35 +606,33 @@ bool ReASItem::calcAsBoolean(ReASItem* expr, ReVMThread& thread) * @return true: all statements are correct
* false: otherwise */ -bool ReASItem::checkStatementList(ReASItem* list, ReParser& parser) -{ - bool rc = true; - - while(list != NULL){ - if (! list->check(parser)) - rc = false; - if (dynamic_cast(list) == NULL) - rc = list->error(LOC_ITEM_STATEM_LIST_1, parser, "not a statement: %s", - list->nameOfItemType()); - ReASNode1* node = dynamic_cast(list); - if (node == NULL){ - list->error(LOC_ITEM_STATEM_LIST_1, parser, "not a node: %s", - list->nameOfItemType()); - list = NULL; - } else { - list = node->child(); - } - } - return rc; +bool ReASItem::checkStatementList(ReASItem* list, ReParser& parser){ + bool rc = true; + + while (list != NULL){ + if (!list->check(parser)) + rc = false; + if (dynamic_cast (list) == NULL) + rc = list->error(LOC_ITEM_STATEM_LIST_1, parser, "not a statement: %s", + list->nameOfItemType()); + ReASNode1* node = dynamic_cast (list); + if (node == NULL){ + list->error(LOC_ITEM_STATEM_LIST_1, parser, "not a node: %s", + list->nameOfItemType()); + list = NULL; + }else{ + list = node->child(); + } + } + return rc; } /** * @brief Returns the node type. * * @return the node type */ -ReASItemType ReASItem::nodeType() const -{ - return m_nodeType; +ReASItemType ReASItem::nodeType() const{ + return m_nodeType; } /** @@ -686,110 +640,107 @@ ReASItemType ReASItem::nodeType() const * * @return the node type as string */ -const char*ReASItem::nameOfItemType() const -{ - const char* rc = "?"; - switch(m_nodeType){ - case AST_CONSTANT: - rc = "constant"; - break; - case AST_LIST_CONSTANT: - rc = "list"; - break; - case AST_LIST_ENTRY: - rc = "listEntry"; - break; - case AST_MAP_CONSTANT: - rc = "map"; - break; - case AST_MAP_ENTRY: - rc = "mapEntry"; - break; - case AST_NAMED_VALUE: - rc = "namedValue"; - break; - case AST_INDEXED_VALUE: - rc = "indexedValue"; - break; - case AST_FIELD: - rc = "field"; - break; - case AST_VAR_DEFINITION: - rc = "varDef"; - break; - case AST_EXPR_STATEMENT: - rc = "exprStatement"; - break; - case AST_METHOD: - rc = "method"; - break; - case AST_ARGUMENT: - rc = "arg"; - break; - case AST_INTRINSIC_METHOD: - rc = "intrinsicMethod"; - break; - case AST_PRE_UNARY_OP: - rc = "preUnary"; - break; - case AST_POST_UNARY_OP: - rc = "postUnary"; - break; - case AST_BINARY_OP: - rc = "binOp"; - break; - case AST_METHOD_CALL: - rc = "methodCall"; - break; - case AST_WHILE: - rc = "while"; - break; - case AST_REPEAT: - rc = "repeat"; - break; - case AST_IF: - rc = "if"; - break; - case AST_CONDITION: - rc = "condition"; - break; - case AST_ITERATED_FOR: - rc = "iFor"; - break; - case AST_COUNTED_FOR: - rc = "cFor"; - break; - case AST_SWITCH: - rc = "switch"; - break; - case AST_LEAVE: - rc = "leave"; - break; - case AST_CONTINUE: - rc = "continue"; - break; - default: - break; - } - return rc; +const char*ReASItem::nameOfItemType() const{ + const char* rc = "?"; + switch (m_nodeType) { + case AST_CONSTANT: + rc = "constant"; + break; + case AST_LIST_CONSTANT: + rc = "list"; + break; + case AST_LIST_ENTRY: + rc = "listEntry"; + break; + case AST_MAP_CONSTANT: + rc = "map"; + break; + case AST_MAP_ENTRY: + rc = "mapEntry"; + break; + case AST_NAMED_VALUE: + rc = "namedValue"; + break; + case AST_INDEXED_VALUE: + rc = "indexedValue"; + break; + case AST_FIELD: + rc = "field"; + break; + case AST_VAR_DEFINITION: + rc = "varDef"; + break; + case AST_EXPR_STATEMENT: + rc = "exprStatement"; + break; + case AST_METHOD: + rc = "method"; + break; + case AST_ARGUMENT: + rc = "arg"; + break; + case AST_INTRINSIC_METHOD: + rc = "intrinsicMethod"; + break; + case AST_PRE_UNARY_OP: + rc = "preUnary"; + break; + case AST_POST_UNARY_OP: + rc = "postUnary"; + break; + case AST_BINARY_OP: + rc = "binOp"; + break; + case AST_METHOD_CALL: + rc = "methodCall"; + break; + case AST_WHILE: + rc = "while"; + break; + case AST_REPEAT: + rc = "repeat"; + break; + case AST_IF: + rc = "if"; + break; + case AST_CONDITION: + rc = "condition"; + break; + case AST_ITERATED_FOR: + rc = "iFor"; + break; + case AST_COUNTED_FOR: + rc = "cFor"; + break; + case AST_SWITCH: + rc = "switch"; + break; + case AST_LEAVE: + rc = "leave"; + break; + case AST_CONTINUE: + rc = "continue"; + break; + default: + break; + } + return rc; } /** * @brief Returns the flags of the node. * * @return the bitmask with the flags */ -int ReASItem::flags() const -{ - return m_flags; +int ReASItem::flags() const{ + return m_flags; } /** * @brief Sets the flags of the node. * * @param flags the new value of the bitmask */ -void ReASItem::setFlags(int flags) -{ - m_flags = flags; +void ReASItem::setFlags(int flags){ + m_flags = flags; } /** @@ -800,13 +751,13 @@ void ReASItem::setFlags(int flags) * false: otherwise */ bool ReASItem::typeCheck(ReASClass* class1, ReASClass* class2){ - bool rc; - if (class1 == NULL || class2 == NULL) - rc = false; - else - //@ToDo: subclasses - rc = class1 == class2; - return rc; + bool rc; + if (class1 == NULL || class2 == NULL) + rc = false; + else + //@ToDo: subclasses + rc = class1 == class2; + return rc; } /** @@ -818,13 +769,12 @@ bool ReASItem::typeCheck(ReASClass* class1, ReASClass* class2){ * @param ... the values for the placeholders * @return false (for chaining) */ -bool ReASItem::error(int location, ReParser& parser, const char* format, ...) -{ - va_list varList; - va_start(varList, format); - parser.addMessage(ReParser::LT_ERROR, location, m_position, format, varList); - va_end(varList); - return false; +bool ReASItem::error(int location, ReParser& parser, const char* format, ...){ + va_list varList; + va_start(varList, format); + parser.addMessage(ReParser::LT_ERROR, location, m_position, format, varList); + va_end(varList); + return false; } /** @@ -837,11 +787,11 @@ bool ReASItem::error(int location, ReParser& parser, const char* format, ...) * @param info additional info * @return false (for chaining) */ -bool ReASItem::ensureError(ReParser& parser, const char* info) -{ - if (parser.errors() == 0) - error(LOC_ITEM_FORCE_ERROR_1, parser, "lost error (internal error): %s"); - return false; +bool ReASItem::ensureError(ReParser& parser, const char* info){ + if (parser.errors() == 0) + error(LOC_ITEM_FORCE_ERROR_1, parser, "lost error (internal error): %s", + info); + return false; } /** @class ReASCalculable rplastree.hpp "rplexpr/rplastree.hpp" @@ -853,25 +803,22 @@ bool ReASItem::ensureError(ReParser& parser, const char* info) * @brief Constructor. */ ReASCalculable::ReASCalculable() : - m_class(NULL) -{ + m_class(NULL){ } /** * @brief Returns the class of the node * @return the class */ -ReASClass* ReASCalculable::clazz() const -{ - return m_class; +ReASClass* ReASCalculable::clazz() const{ + return m_class; } /** * @brief Sets the class of the node. * @param clazz the new class */ -void ReASCalculable::setClass(ReASClass* clazz) -{ - m_class = clazz; +void ReASCalculable::setClass(ReASClass* clazz){ + m_class = clazz; } /** @class ReASStorable rplastree.hpp "rplexpr/rplastree.hpp" @@ -891,9 +838,7 @@ void ReASCalculable::setClass(ReASClass* clazz) * */ ReASConstant::ReASConstant() : - ReASItem(AST_CONSTANT), - m_value() -{ + ReASItem(AST_CONSTANT), m_value(){ } /** @@ -901,10 +846,9 @@ ReASConstant::ReASConstant() : * * @param thread IN/OUT: the execution unit, a VM thread */ -void ReASConstant::calc(ReVMThread& thread) -{ - ReASVariant& value = thread.reserveValue(); - value.copyValue(m_value); +void ReASConstant::calc(ReVMThread& thread){ + ReASVariant& value = thread.reserveValue(); + value.copyValue(m_value); } /** @@ -913,9 +857,9 @@ void ReASConstant::calc(ReVMThread& thread) * @param parser for error processing * @return true: a constant is always correct */ -bool ReASConstant::check(ReParser& parser) -{ - return true; +bool ReASConstant::check(ReParser& parser){ + RE_UNUSED(&parser); + return true; } /** @@ -924,12 +868,10 @@ bool ReASConstant::check(ReParser& parser) * @param writer writes to output * @param indent nesting level */ -void ReASConstant::dump(ReWriter& writer, int indent) -{ - char buffer[256]; - writer.formatIndented(indent, "const id: %d value: %s %s", m_id, - m_value.toString().constData(), - positionStr(buffer, sizeof buffer)); +void ReASConstant::dump(ReWriter& writer, int indent){ + char buffer[256]; + writer.formatIndented(indent, "const id: %d value: %s %s", m_id, + m_value.toString().constData(), positionStr(buffer, sizeof buffer)); } /** @@ -942,9 +884,8 @@ void ReASConstant::dump(ReWriter& writer, int indent) * * @return the internal value */ -ReASVariant& ReASConstant::value() -{ - return m_value; +ReASVariant& ReASConstant::value(){ + return m_value; } /** @class ReASListConstant rplastree.hpp "rplexpr/rplastree.hpp" @@ -957,11 +898,9 @@ ReASVariant& ReASConstant::value() * @brief Constructor. */ ReASListConstant::ReASListConstant() : - ReASNode1(AST_LIST_CONSTANT), - ReASCalculable() -{ - m_value.setObject(ReASList::m_instance->newValueInstance(), - ReASList::m_instance); + ReASNode1(AST_LIST_CONSTANT), ReASCalculable(){ + m_value.setObject(ReASList::m_instance->newValueInstance(), + ReASList::m_instance); } /** * @brief Returns the list. @@ -969,9 +908,9 @@ ReASListConstant::ReASListConstant() : * @return the list */ ReASListOfVariants* ReASListConstant::list(){ - ReASListOfVariants* rc = static_cast - (m_value.asObject(NULL)); - return rc; + ReASListOfVariants* rc = static_cast (m_value.asObject( + NULL)); + return rc; } /** @@ -979,10 +918,9 @@ ReASListOfVariants* ReASListConstant::list(){ * * @param thread IN/OUT: the execution unit, a VM thread */ -void ReASListConstant::calc(ReVMThread& thread) -{ - ReASVariant& value = thread.reserveValue(); - value.copyValue(m_value); +void ReASListConstant::calc(ReVMThread& thread){ + ReASVariant& value = thread.reserveValue(); + value.copyValue(m_value); } /** @@ -991,9 +929,9 @@ void ReASListConstant::calc(ReVMThread& thread) * @param parser for error processing * @return true: a constant is always correct */ -bool ReASListConstant::check(ReParser& parser) -{ - return true; +bool ReASListConstant::check(ReParser& parser){ + RE_UNUSED(&parser); + return true; } /** @@ -1002,14 +940,13 @@ bool ReASListConstant::check(ReParser& parser) * @param writer writes to output * @param indent nesting level */ -void ReASListConstant::dump(ReWriter& writer, int indent) -{ - char buffer[256]; - writer.formatIndented(indent, "listConst id: %d %s", m_id, - positionStr(buffer, sizeof buffer)); +void ReASListConstant::dump(ReWriter& writer, int indent){ + char buffer[256]; + writer.formatIndented(indent, "listConst id: %d %s", m_id, + positionStr(buffer, sizeof buffer)); - QByteArray sValue = m_value.toString(8092); - writer.writeIndented(indent + 1, sValue.constData()); + QByteArray sValue = m_value.toString(8092); + writer.writeIndented(indent + 1, sValue.constData()); } /** @@ -1022,9 +959,8 @@ void ReASListConstant::dump(ReWriter& writer, int indent) * * @return the internal value */ -ReASVariant& ReASListConstant::value() -{ - return m_value; +ReASVariant& ReASListConstant::value(){ + return m_value; } /** @class ReASMapConstant rplastree.hpp "rplexpr/rplastree.hpp" @@ -1036,11 +972,8 @@ ReASVariant& ReASListConstant::value() * @brief ReASMapConstant::ReASMapConstant */ ReASMapConstant::ReASMapConstant() : - ReASNode1(AST_MAP_CONSTANT), - ReASCalculable(), - m_value() -{ - m_value.setObject(new ReASMapOfVariants, ReASMap::m_instance); + ReASNode1(AST_MAP_CONSTANT), ReASCalculable(), m_value(){ + m_value.setObject(new ReASMapOfVariants, ReASMap::m_instance); } /** @@ -1048,10 +981,9 @@ ReASMapConstant::ReASMapConstant() : * * @param thread IN/OUT: the execution unit, a VM thread */ -void ReASMapConstant::calc(ReVMThread& thread) -{ - ReASVariant& value = thread.reserveValue(); - value.copyValue(m_value); +void ReASMapConstant::calc(ReVMThread& thread){ + ReASVariant& value = thread.reserveValue(); + value.copyValue(m_value); } /** @@ -1060,8 +992,8 @@ void ReASMapConstant::calc(ReVMThread& thread) * @param parser for error processing * @return true: a constant is always correct */ -bool ReASMapConstant::check(ReParser& parser) -{ +bool ReASMapConstant::check(ReParser& parser){ + RE_UNUSED(&parser); return true; } /** @@ -1070,24 +1002,21 @@ bool ReASMapConstant::check(ReParser& parser) * @param writer writes to output * @param indent nesting level */ -void ReASMapConstant::dump(ReWriter& writer, int indent) -{ - char buffer[256]; - writer.formatIndented(indent, "mapConst id: %d %s", - m_id, positionStr(buffer, sizeof buffer)); - writer.indent(indent); - dumpMap(writer, *map(), true); +void ReASMapConstant::dump(ReWriter& writer, int indent){ + char buffer[256]; + writer.formatIndented(indent, "mapConst id: %d %s", m_id, + positionStr(buffer, sizeof buffer)); + writer.indent(indent); + dumpMap(writer, *map(), true); } - /** * @brief Returns the value of the constant, containing a map. * * @return the variant value */ -ReASVariant& ReASMapConstant::value() -{ - return m_value; +ReASVariant& ReASMapConstant::value(){ + return m_value; } /** @@ -1095,11 +1024,10 @@ ReASVariant& ReASMapConstant::value() * * @return the map of the constant */ -ReASMapOfVariants* ReASMapConstant::map() -{ - ReASMapOfVariants* rc = static_cast( - m_value.asObject(NULL)); - return rc; +ReASMapOfVariants* ReASMapConstant::map(){ + ReASMapOfVariants* rc = static_cast (m_value.asObject( + NULL)); + return rc; } /** @class ReASNamedValue rplastree.hpp "rplexpr/rplastree.hpp" @@ -1115,15 +1043,14 @@ ReASMapOfVariants* ReASMapConstant::map() * @param name the name of the variable * @param attributes the attributes of the variable */ -ReASNamedValue::ReASNamedValue(ReASClass* clazz,ReSymbolSpace* space, - const QByteArray& name, int attributes) : - ReASItem(AST_NAMED_VALUE), - m_name(name), - m_attributes(attributes), - m_symbolSpace(space), - m_variableNo(-1) -{ - m_class = clazz; +ReASNamedValue::ReASNamedValue(ReASClass* clazz, ReSymbolSpace* space, + const QByteArray& name, int attributes) : + ReASItem(AST_NAMED_VALUE), + m_name(name), + m_attributes(attributes), + m_symbolSpace(space), + m_variableNo(-1){ + m_class = clazz; } /** @@ -1131,9 +1058,8 @@ ReASNamedValue::ReASNamedValue(ReASClass* clazz,ReSymbolSpace* space, * * @return the name */ -const QByteArray& ReASNamedValue::name() const -{ - return m_name; +const QByteArray& ReASNamedValue::name() const{ + return m_name; } /** @@ -1141,23 +1067,20 @@ const QByteArray& ReASNamedValue::name() const * @param space * @param variableNo */ -void ReASNamedValue::setSymbolSpace(ReSymbolSpace* space, int variableNo) -{ - m_symbolSpace = space; - m_variableNo = variableNo; +void ReASNamedValue::setSymbolSpace(ReSymbolSpace* space, int variableNo){ + m_symbolSpace = space; + m_variableNo = variableNo; } /** * @brief Copies the value of the variable to the top of value stack. * * @param thread IN/OUT: the execution unit, a VM thread */ -void ReASNamedValue::calc(ReVMThread& thread) -{ - thread.valueToTop(m_symbolSpace, m_variableNo); - if (thread.tracing()) - thread.vm()->traceWriter()->format("nVal %s=%.80s", - m_name.constData(), - thread.topOfValues().toString().constData()); +void ReASNamedValue::calc(ReVMThread& thread){ + thread.valueToTop(m_symbolSpace, m_variableNo); + if (thread.tracing()) + thread.vm()->traceWriter()->format("nVal %s=%.80s", m_name.constData(), + thread.topOfValues().toString().constData()); } /** @@ -1167,9 +1090,9 @@ void ReASNamedValue::calc(ReVMThread& thread) * @return true: node is correct
* false: otherwise */ -bool ReASNamedValue::check(ReParser& parser) -{ - return true; +bool ReASNamedValue::check(ReParser& parser){ + RE_UNUSED(&parser); + return true; } /** * @brief Writes the internals into a file. @@ -1177,12 +1100,11 @@ bool ReASNamedValue::check(ReParser& parser) * @param writer writes to output * @param indent nesting level */ -void ReASNamedValue::dump(ReWriter& writer, int indent) -{ - char buffer[256]; - writer.formatIndented(indent, "namedValue %s id: %d attr: 0x%x %s", - m_name.constData(), m_id, m_attributes, - positionStr(buffer, sizeof buffer)); +void ReASNamedValue::dump(ReWriter& writer, int indent){ + char buffer[256]; + writer.formatIndented(indent, "namedValue %s id: %d attr: 0x%x %s", + m_name.constData(), m_id, m_attributes, + positionStr(buffer, sizeof buffer)); } /** @@ -1190,9 +1112,8 @@ void ReASNamedValue::dump(ReWriter& writer, int indent) * * @return the symbol space */ -ReSymbolSpace*ReASNamedValue::symbolSpace() const -{ - return m_symbolSpace; +ReSymbolSpace*ReASNamedValue::symbolSpace() const{ + return m_symbolSpace; } /** @@ -1200,20 +1121,17 @@ ReSymbolSpace*ReASNamedValue::symbolSpace() const * * @param variableNo the variable number */ -void ReASNamedValue::setVariableNo(int variableNo) -{ - m_variableNo = variableNo; +void ReASNamedValue::setVariableNo(int variableNo){ + m_variableNo = variableNo; } - /** * @brief Returns the variable no of the variable. * * @return the current number of the variable in the symbol space */ -int ReASNamedValue::variableNo() const -{ - return m_variableNo; +int ReASNamedValue::variableNo() const{ + return m_variableNo; } /** @class ReASConversion rplastree.hpp "rplexpr/rplastree.hpp" @@ -1227,11 +1145,9 @@ int ReASNamedValue::variableNo() const * @param expression the expression to convert */ ReASConversion::ReASConversion(ReASItem* expression) : - ReASNode1(AST_CONVERSION), - m_conversion(C_UNDEF) -{ - m_child = expression; - m_position = expression->position(); + ReASNode1(AST_CONVERSION), m_conversion(C_UNDEF){ + m_child = expression; + m_position = expression->position(); } /** @@ -1241,32 +1157,30 @@ ReASConversion::ReASConversion(ReASItem* expression) : * * @param thread execution value */ -void ReASConversion::calc(ReVMThread& thread) -{ - ReASCalculable* expr = dynamic_cast(m_child); - expr->calc(thread); - ReASVariant& value = thread.topOfValues(); - - switch(m_conversion){ - case C_INT_TO_FLOAT: - value.setFloat((qreal) value.asInt()); - break; - case C_FLOAT_TO_INT: - value.setInt((int) value.asFloat()); - break; - case C_BOOL_TO_INT: - value.setInt((int) value.asBool()); - break; - case C_BOOL_TO_FLOAT: - value.setFloat((qreal) value.asBool()); - break; - default: - break; - } - if (thread.tracing()) - thread.vm()->traceWriter()->format("(%s): %s", - m_class->name().constData(), - value.toString().constData()); +void ReASConversion::calc(ReVMThread& thread){ + ReASCalculable* expr = dynamic_cast (m_child); + expr->calc(thread); + ReASVariant& value = thread.topOfValues(); + + switch (m_conversion) { + case C_INT_TO_FLOAT: + value.setFloat((qreal) value.asInt()); + break; + case C_FLOAT_TO_INT: + value.setInt((int) value.asFloat()); + break; + case C_BOOL_TO_INT: + value.setInt((int) value.asBool()); + break; + case C_BOOL_TO_FLOAT: + value.setFloat((qreal) value.asBool()); + break; + default: + break; + } + if (thread.tracing()) + thread.vm()->traceWriter()->format("(%s): %s", + m_class->name().constData(), value.toString().constData()); } /** @@ -1279,24 +1193,23 @@ void ReASConversion::calc(ReVMThread& thread) * otherwise: the conversion type */ ReASConversion::Conversion ReASConversion::findConversion(ReASClass* from, - ReASClass* to) -{ - Conversion rc = C_UNDEF; - if (from == ReASFloat::m_instance){ - if (to == ReASInteger::m_instance) - rc = C_FLOAT_TO_INT; - } else if (from == ReASInteger::m_instance){ - if (to == ReASFloat::m_instance) - rc = C_INT_TO_FLOAT; - } else if (from == ReASBoolean::m_instance){ - if (to == ReASInteger::m_instance) - rc = C_BOOL_TO_INT; - else if (to == ReASInteger::m_instance) - rc = C_BOOL_TO_INT; - else if (to == ReASFloat::m_instance) - rc = C_BOOL_TO_FLOAT; - } - return rc; + ReASClass* to){ + Conversion rc = C_UNDEF; + if (from == ReASFloat::m_instance){ + if (to == ReASInteger::m_instance) + rc = C_FLOAT_TO_INT; + }else if (from == ReASInteger::m_instance){ + if (to == ReASFloat::m_instance) + rc = C_INT_TO_FLOAT; + }else if (from == ReASBoolean::m_instance){ + if (to == ReASInteger::m_instance) + rc = C_BOOL_TO_INT; + else if (to == ReASInteger::m_instance) + rc = C_BOOL_TO_INT; + else if (to == ReASFloat::m_instance) + rc = C_BOOL_TO_FLOAT; + } + return rc; } /** @@ -1306,24 +1219,22 @@ ReASConversion::Conversion ReASConversion::findConversion(ReASClass* from, * @return true: node is correct
* false: otherwise */ -bool ReASConversion::check(ReParser& parser) -{ - bool rc = m_child != NULL && m_child->check(parser); - ReASCalculable* expr = dynamic_cast(m_child); - if (! rc || expr == NULL) - ensureError(parser, "ReASConversion::check"); - else { - ReASClass* from = expr->clazz(); - m_conversion = findConversion(from, m_class); - if (m_conversion != C_UNDEF) - rc = true; - else - parser.error(LOC_CONV_CHECK_1, - "invalid data type conversion: %s -> %s", - from->name().constData(), - m_class->name().constData()); - } - return rc; +bool ReASConversion::check(ReParser& parser){ + bool rc = m_child != NULL && m_child->check(parser); + ReASCalculable* expr = dynamic_cast (m_child); + if (!rc || expr == NULL) + ensureError(parser, "ReASConversion::check"); + else{ + ReASClass* from = expr->clazz(); + m_conversion = findConversion(from, m_class); + if (m_conversion != C_UNDEF) + rc = true; + else + parser.error(LOC_CONV_CHECK_1, + "invalid data type conversion: %s -> %s", from->name().constData(), + m_class->name().constData()); + } + return rc; } /** @@ -1332,12 +1243,11 @@ bool ReASConversion::check(ReParser& parser) * @param writer writes to output * @param indent nesting level */ -void ReASConversion::dump(ReWriter& writer, int indent) -{ - char buffer[256]; - writer.formatIndented(indent, "conversion %s id: %d expr: %d %s", - m_class->name().constData(), m_id, m_child->id(), - positionStr(buffer, sizeof buffer)); +void ReASConversion::dump(ReWriter& writer, int indent){ + char buffer[256]; + writer.formatIndented(indent, "conversion %s id: %d expr: %d %s", + m_class->name().constData(), m_id, m_child->id(), + positionStr(buffer, sizeof buffer)); } /** @@ -1357,28 +1267,27 @@ void ReASConversion::dump(ReWriter& writer, int indent) * otherwise: a converter to the given type */ ReASConversion* ReASConversion::tryConversion(ReASClass* expected, - ReASItem* expr, ReParser& parser, bool& isCorrect) -{ - ReASConversion* rc = NULL; - if (! expr->check(parser)) - isCorrect = false; - else { - ReASCalculable* expr2 = dynamic_cast(expr); - if (expr2 != NULL){ - Conversion type = findConversion(expr2->clazz(), expected); - if (type == C_UNDEF){ - isCorrect = parser.error(LOC_CONV_TRY_1, - "invalid data type conversion: %s -> %s", - expr2->clazz()->name().constData(), - expected->name().constData()); - } else if (expr2->clazz() != expected){ - rc = new ReASConversion(expr); - rc->m_conversion = type; - rc->setClass(expected); - } - } - } - return rc; + ReASItem* expr, ReParser& parser, bool& isCorrect){ + ReASConversion* rc = NULL; + if (!expr->check(parser)) + isCorrect = false; + else{ + ReASCalculable* expr2 = dynamic_cast (expr); + if (expr2 != NULL){ + Conversion type = findConversion(expr2->clazz(), expected); + if (type == C_UNDEF){ + isCorrect = parser.error(LOC_CONV_TRY_1, + "invalid data type conversion: %s -> %s", + expr2->clazz()->name().constData(), + expected->name().constData()); + }else if (expr2->clazz() != expected){ + rc = new ReASConversion(expr); + rc->m_conversion = type; + rc->setClass(expected); + } + } + } + return rc; } /** @class ReASIndexedValue rplastree.hpp "rplexpr/rplastree.hpp" @@ -1389,8 +1298,7 @@ ReASConversion* ReASConversion::tryConversion(ReASClass* expected, * m_child2: the index expression */ ReASIndexedValue::ReASIndexedValue() : - ReASNode2(AST_INDEXED_VALUE) -{ + ReASNode2(AST_INDEXED_VALUE){ } /** @@ -1400,19 +1308,18 @@ ReASIndexedValue::ReASIndexedValue() : * * @param thread execution value */ -void ReASIndexedValue::calc(ReVMThread& thread) -{ - ReASCalculable* expr = dynamic_cast(m_child2); - expr->calc(thread); - ReASVariant& ixValue = thread.popValue(); - int ix = ixValue.asInt(); - ReASCalculable* list = dynamic_cast(m_child); - list->calc(thread); - ReASVariant& listValue = thread.popValue(); - //@ToDo: access to the lists element: assignment or to stack - if (thread.tracing()) - thread.vm()->traceWriter()->format("[%d]: %.80s", - ix, thread.topOfValues().toString().constData()); +void ReASIndexedValue::calc(ReVMThread& thread){ + ReASCalculable* expr = dynamic_cast (m_child2); + expr->calc(thread); + ReASVariant& ixValue = thread.popValue(); + int ix = ixValue.asInt(); + ReASCalculable* list = dynamic_cast (m_child); + list->calc(thread); + ReASVariant& listValue = thread.popValue(); + //@ToDo: access to the lists element: assignment or to stack + if (thread.tracing()) + thread.vm()->traceWriter()->format("[%d]: %.80s", ix, + thread.topOfValues().toString().constData()); } /** @@ -1422,26 +1329,25 @@ void ReASIndexedValue::calc(ReVMThread& thread) * @return true: node is correct
* false: otherwise */ -bool ReASIndexedValue::check(ReParser& parser) -{ - ReASCalculable* list = dynamic_cast(m_child); - bool rc = m_child != NULL && m_child->check(parser); - if (! rc || list == NULL) - ensureError(parser, "ReASIndexedValue::check"); - else { - // index value: - // tryConversion() calls m_child2->check()! - ReASConversion* converter = ReASConversion::tryConversion( - ReASInteger::m_instance, m_child2, parser, rc); - if (rc && converter != NULL) - m_child = converter; - if (rc){ - //@ToDo: dynamic subclass of list / map - m_class = ReASString::m_instance; - rc = m_class != NULL && m_class == ReASInteger::m_instance; - } - } - return rc; +bool ReASIndexedValue::check(ReParser& parser){ + ReASCalculable* list = dynamic_cast (m_child); + bool rc = m_child != NULL && m_child->check(parser); + if (!rc || list == NULL) + ensureError(parser, "ReASIndexedValue::check"); + else{ + // index value: + // tryConversion() calls m_child2->check()! + ReASConversion* converter = ReASConversion::tryConversion( + ReASInteger::m_instance, m_child2, parser, rc); + if (rc && converter != NULL) + m_child = converter; + if (rc){ + //@ToDo: dynamic subclass of list / map + m_class = ReASString::m_instance; + rc = m_class != NULL && m_class == ReASInteger::m_instance; + } + } + return rc; } /** @@ -1450,14 +1356,12 @@ bool ReASIndexedValue::check(ReParser& parser) * @param writer writes to output * @param indent nesting level */ -void ReASIndexedValue::dump(ReWriter& writer, int indent) -{ - char buffer[256]; - writer.formatIndented(indent, "indexedValue id: %d index: %d parent: %d %s", - m_id, m_child2->id(), m_child->id(), - positionStr(buffer, sizeof buffer)); - m_child2->dump(writer, indent + 1); - m_child->dump(writer, indent + 1); +void ReASIndexedValue::dump(ReWriter& writer, int indent){ + char buffer[256]; + writer.formatIndented(indent, "indexedValue id: %d index: %d parent: %d %s", + m_id, m_child2->id(), m_child->id(), positionStr(buffer, sizeof buffer)); + m_child2->dump(writer, indent + 1); + m_child->dump(writer, indent + 1); } /** @class RplVarDefinition rplastree.hpp "rplexpr/rplastree.hpp" @@ -1473,11 +1377,8 @@ void ReASIndexedValue::dump(ReWriter& writer, int indent) * @brief Constructor. */ ReASVarDefinition::ReASVarDefinition() : - ReASNode3(AST_VAR_DEFINITION), - ReASStatement(), - m_endOfScope(0) -{ - m_flags |= NF_STATEMENT; + ReASNode3(AST_VAR_DEFINITION), ReASStatement(), m_endOfScope(0){ + m_flags |= NF_STATEMENT; } /** @@ -1486,27 +1387,25 @@ ReASVarDefinition::ReASVarDefinition() : * @param writer writes to output * @param indent nesting level */ -void ReASVarDefinition::dump(ReWriter& writer, int indent) -{ - ReASNamedValue* namedValue = dynamic_cast(m_child2); - QByteArray name = namedValue->name(); - char endOfScope[32]; - endOfScope[0] = '\0'; - if (m_endOfScope > 0) - qsnprintf(endOfScope, sizeof endOfScope, "-%d:0", m_endOfScope); - char buffer[256]; - writer.formatIndented(indent, - "varDef %s %s id: %d namedValue: %d value: %d succ: %d %s%s", - clazz() == NULL ? "?" : clazz()->name().constData(), - name.constData(), m_id, - m_child2 == NULL ? 0 : m_child2->id(), - m_child3 == NULL ? 0 : m_child3->id(), - m_child == NULL ? 0 : m_child->id(), - positionStr(buffer, sizeof buffer), endOfScope); - if (m_child2 != NULL) - m_child2->dump(writer, indent + 1); - if (m_child3 != NULL) - m_child3->dump(writer, indent + 1); +void ReASVarDefinition::dump(ReWriter& writer, int indent){ + ReASNamedValue* namedValue = dynamic_cast (m_child2); + QByteArray name = namedValue->name(); + char endOfScope[32]; + endOfScope[0] = '\0'; + if (m_endOfScope > 0) + qsnprintf(endOfScope, sizeof endOfScope, "-%d:0", m_endOfScope); + char buffer[256]; + writer.formatIndented(indent, + "varDef %s %s id: %d namedValue: %d value: %d succ: %d %s%s", + clazz() == NULL ? "?" : clazz()->name().constData(), name.constData(), + m_id, m_child2 == NULL ? 0 : m_child2->id(), + m_child3 == NULL ? 0 : m_child3->id(), + m_child == NULL ? 0 : m_child->id(), positionStr(buffer, sizeof buffer), + endOfScope); + if (m_child2 != NULL) + m_child2->dump(writer, indent + 1); + if (m_child3 != NULL) + m_child3->dump(writer, indent + 1); } /** @@ -1514,11 +1413,10 @@ void ReASVarDefinition::dump(ReWriter& writer, int indent) * * @return the name */ -const QByteArray& ReASVarDefinition::name() const -{ - ReASNamedValue* namedValue = dynamic_cast(m_child2); - const QByteArray& rc = namedValue->name(); - return rc; +const QByteArray& ReASVarDefinition::name() const{ + ReASNamedValue* namedValue = dynamic_cast (m_child2); + const QByteArray& rc = namedValue->name(); + return rc; } /** @@ -1526,11 +1424,10 @@ const QByteArray& ReASVarDefinition::name() const * * @return the data type */ -ReASClass* ReASVarDefinition::clazz() const -{ - ReASNamedValue* namedValue = dynamic_cast(m_child2); - ReASClass* rc = namedValue == NULL ? NULL : namedValue->clazz(); - return rc; +ReASClass* ReASVarDefinition::clazz() const{ + ReASNamedValue* namedValue = dynamic_cast (m_child2); + ReASClass* rc = namedValue == NULL ? NULL : namedValue->clazz(); + return rc; } /** * @brief Returns the column of the scope end. @@ -1539,9 +1436,8 @@ ReASClass* ReASVarDefinition::clazz() const * * @return 0 or the column of the scope end */ -int ReASVarDefinition::endOfScope() const -{ - return m_endOfScope; +int ReASVarDefinition::endOfScope() const{ + return m_endOfScope; } /** @@ -1549,12 +1445,10 @@ int ReASVarDefinition::endOfScope() const * * @param endOfScope the column of the scope end */ -void ReASVarDefinition::setEndOfScope(int endOfScope) -{ - m_endOfScope = endOfScope; +void ReASVarDefinition::setEndOfScope(int endOfScope){ + m_endOfScope = endOfScope; } - /** * @brief Checks the correctness of the instance. * @@ -1562,30 +1456,27 @@ void ReASVarDefinition::setEndOfScope(int endOfScope) * @return true: node is correct
* false: otherwise */ -bool ReASVarDefinition::check(ReParser& parser) -{ - ReASNamedValue* var = dynamic_cast(m_child2); - - bool rc = var != NULL && (m_child3 == NULL || m_child3->check(parser)); - if (! rc) - ensureError(parser, "ReASVarDefinition::check"); - else { - if (m_child3 != NULL){ - // with initialization: - ReASCalculable* expr = dynamic_cast(m_child3); - if (expr == NULL) - rc = error(LOC_VARDEF_CHECK_1, parser, - "Not a calculable expression: %s", - m_child3->nameOfItemType()); - else if (! typeCheck(var->clazz(), expr->clazz())) - rc = error(LOC_VARDEF_CHECK_2, parser, - "data types are not compatible: %s/%s", - var->clazz()->name().constData(), - expr->clazz() == NULL ? "?" - : expr->clazz()->name().constData()); - } - } - return rc; +bool ReASVarDefinition::check(ReParser& parser){ + ReASNamedValue* var = dynamic_cast (m_child2); + + bool rc = var != NULL && (m_child3 == NULL || m_child3->check(parser)); + if (!rc) + ensureError(parser, "ReASVarDefinition::check"); + else{ + if (m_child3 != NULL){ + // with initialization: + ReASCalculable* expr = dynamic_cast (m_child3); + if (expr == NULL) + rc = error(LOC_VARDEF_CHECK_1, parser, + "Not a calculable expression: %s", m_child3->nameOfItemType()); + else if (!typeCheck(var->clazz(), expr->clazz())) + rc = error(LOC_VARDEF_CHECK_2, parser, + "data types are not compatible: %s/%s", + var->clazz()->name().constData(), + expr->clazz() == NULL ? "?" : expr->clazz()->name().constData()); + } + } + return rc; } /** @@ -1593,24 +1484,22 @@ bool ReASVarDefinition::check(ReParser& parser) * * @return 0: continue the current statement list
*/ -int ReASVarDefinition::execute(ReVMThread& thread) -{ - if (m_child3 != NULL){ - // has an initialization: - ReASNamedValue* var = dynamic_cast(m_child2); - ReASCalculable* expr = dynamic_cast(m_child3); - expr->calc(thread); - ReASVariant& value = thread.popValue(); - ReASVariant& destination = thread.valueOfVariable( - var->m_symbolSpace, var->m_variableNo); - if (thread.tracing()) - thread.vm()->traceWriter()->format("%s = %.80s [%.80s]", - var->m_name.constData(), - value.toString().constData(), - destination.toString().constData()); - destination.copyValue(value); - } - return 0; +int ReASVarDefinition::execute(ReVMThread& thread){ + if (m_child3 != NULL){ + // has an initialization: + ReASNamedValue* var = dynamic_cast (m_child2); + ReASCalculable* expr = dynamic_cast (m_child3); + expr->calc(thread); + ReASVariant& value = thread.popValue(); + ReASVariant& destination = thread.valueOfVariable(var->m_symbolSpace, + var->m_variableNo); + if (thread.tracing()) + thread.vm()->traceWriter()->format("%s = %.80s [%.80s]", + var->m_name.constData(), value.toString().constData(), + destination.toString().constData()); + destination.copyValue(value); + } + return 0; } /** @class ReASExprStatement rplastree.hpp "rplexpr/rplastree.hpp" @@ -1625,10 +1514,8 @@ int ReASVarDefinition::execute(ReVMThread& thread) * @brief Constructor. */ ReASExprStatement::ReASExprStatement() : - ReASNode2(AST_EXPR_STATEMENT), - ReASStatement() -{ - m_flags |= NF_STATEMENT; + ReASNode2(AST_EXPR_STATEMENT), ReASStatement(){ + m_flags |= NF_STATEMENT; } /** @@ -1638,31 +1525,29 @@ ReASExprStatement::ReASExprStatement() : * @return true: node is correct
* false: otherwise */ -bool ReASExprStatement::check(ReParser& parser) -{ - bool rc = m_child2->check(parser); - if (rc){ - ReASCalculable* expr = dynamic_cast (m_child2); - if (expr == NULL) - rc = ensureError(parser, "ReASExprStatement::check"); - } - return rc; +bool ReASExprStatement::check(ReParser& parser){ + bool rc = m_child2->check(parser); + if (rc){ + ReASCalculable* expr = dynamic_cast (m_child2); + if (expr == NULL) + rc = ensureError(parser, "ReASExprStatement::check"); + } + return rc; } /** * @brief Executes the statement. * * @return 0: continue the current statement list
*/ -int ReASExprStatement::execute(ReVMThread& thread) -{ - ReASCalculable* expr = dynamic_cast (m_child2); - expr->calc(thread); - ReASVariant& value = thread.popValue(); - if (thread.tracing()) - thread.vm()->traceWriter()->format("expr: %s", - value.toString().constData()); - value.destroyValue(); - return 0; +int ReASExprStatement::execute(ReVMThread& thread){ + ReASCalculable* expr = dynamic_cast (m_child2); + expr->calc(thread); + ReASVariant& value = thread.popValue(); + if (thread.tracing()) + thread.vm()->traceWriter()->format("expr: %s", + value.toString().constData()); + value.destroyValue(); + return 0; } /** @@ -1672,17 +1557,15 @@ int ReASExprStatement::execute(ReVMThread& thread) * @param indent nesting level */ -void ReASExprStatement::dump(ReWriter& writer, int indent) -{ - char buffer[256]; - if (m_id == 40) - m_id = 40; - writer.formatIndented(indent, "Expr id: %d expr: %d succ: %d %s", m_id, - m_child2 == NULL ? 0 : m_child2->id(), - m_child == NULL ? 0 : m_child->id(), - positionStr(buffer, sizeof buffer)); - if (m_child2 != NULL) - m_child2->dump(writer, indent + 1); +void ReASExprStatement::dump(ReWriter& writer, int indent){ + char buffer[256]; + if (m_id == 40) + m_id = 40; + writer.formatIndented(indent, "Expr id: %d expr: %d succ: %d %s", m_id, + m_child2 == NULL ? 0 : m_child2->id(), + m_child == NULL ? 0 : m_child->id(), positionStr(buffer, sizeof buffer)); + if (m_child2 != NULL) + m_child2->dump(writer, indent + 1); } /** @class ReASNode1 rplastree.hpp "rplexpr/rplastree.hpp" @@ -1697,34 +1580,29 @@ void ReASExprStatement::dump(ReWriter& writer, int indent) * @param type */ ReASNode1::ReASNode1(ReASItemType type) : - ReASItem(type), - m_child(NULL) -{ + ReASItem(type), m_child(NULL){ } /** * @brief Destructor. */ -ReASNode1::~ReASNode1() -{ - delete m_child; - m_child = NULL; +ReASNode1::~ReASNode1(){ + delete m_child; + m_child = NULL; } /** * @brief Returns the child. * * @return the child of the instance */ -ReASItem* ReASNode1::child() const -{ - return m_child; +ReASItem* ReASNode1::child() const{ + return m_child; } /** * @brief Sets the child. */ -void ReASNode1::setChild(ReASItem* child) -{ - m_child = child; +void ReASNode1::setChild(ReASItem* child){ + m_child = child; } /** @@ -1735,16 +1613,14 @@ void ReASNode1::setChild(ReASItem* child) * @param statements the chain of statements to dump */ void ReASNode1::dumpStatements(ReWriter& writer, int indent, - ReASItem* statements) -{ - ReASNode1* chain = dynamic_cast(statements); - while (chain != NULL){ - chain->dump(writer, indent); - chain = dynamic_cast(chain->m_child); - } + ReASItem* statements){ + ReASNode1* chain = dynamic_cast (statements); + while (chain != NULL){ + chain->dump(writer, indent); + chain = dynamic_cast (chain->m_child); + } } - /** @class ReASNode2 rplastree.hpp "rplexpr/rplastree.hpp" * * @brief Implements an inner node of the abstract syntax tree with two childs. @@ -1757,30 +1633,24 @@ void ReASNode1::dumpStatements(ReWriter& writer, int indent, * @param type */ ReASNode2::ReASNode2(ReASItemType type) : - ReASNode1(type), - m_child2(NULL) -{ + ReASNode1(type), m_child2(NULL){ } /** * @brief Destructor. */ -ReASNode2::~ReASNode2() -{ - delete m_child2; - m_child2 = NULL; +ReASNode2::~ReASNode2(){ + delete m_child2; + m_child2 = NULL; } -ReASItem* ReASNode2::child2() const -{ - return m_child2; +ReASItem* ReASNode2::child2() const{ + return m_child2; } -void ReASNode2::setChild2(ReASItem* child2) -{ - m_child2 = child2; +void ReASNode2::setChild2(ReASItem* child2){ + m_child2 = child2; } - /** @class ReASNode3 rplastree.hpp "rplexpr/rplastree.hpp" * * @brief Implements an inner node of the abstract syntax tree with 3 childs. @@ -1793,27 +1663,23 @@ void ReASNode2::setChild2(ReASItem* child2) * @param type */ ReASNode3::ReASNode3(ReASItemType type) : - ReASNode2(type), - m_child3(NULL) -{ + ReASNode2(type), m_child3(NULL){ } /** * @brief Destructor. */ -ReASNode3::~ReASNode3() -{ - delete m_child3; - m_child3 = NULL; +ReASNode3::~ReASNode3(){ + delete m_child3; + m_child3 = NULL; } /** * @brief Returns the child3. * * @return the child 3 */ -ReASItem* ReASNode3::child3() const -{ - return m_child3; +ReASItem* ReASNode3::child3() const{ + return m_child3; } /** @@ -1821,12 +1687,10 @@ ReASItem* ReASNode3::child3() const * * @param child3 the new child3 */ -void ReASNode3::setChild3(ReASItem* child3) -{ - m_child3 = child3; +void ReASNode3::setChild3(ReASItem* child3){ + m_child3 = child3; } - /** @class ReASNode4 rplastree.hpp "rplexpr/rplastree.hpp" * * @brief Implements an inner node of the abstract syntax tree with 3 childs. @@ -1839,18 +1703,15 @@ void ReASNode3::setChild3(ReASItem* child3) * @param type */ ReASNode4::ReASNode4(ReASItemType type) : - ReASNode3(type), - m_child4(NULL) -{ + ReASNode3(type), m_child4(NULL){ } /** * @brief Destructor. */ -ReASNode4::~ReASNode4() -{ - delete m_child4; - m_child4 = NULL; +ReASNode4::~ReASNode4(){ + delete m_child4; + m_child4 = NULL; } /** @@ -1858,9 +1719,8 @@ ReASNode4::~ReASNode4() * * @return the child 4 */ -ReASItem* ReASNode4::child4() const -{ - return m_child4; +ReASItem* ReASNode4::child4() const{ + return m_child4; } /** @@ -1868,12 +1728,10 @@ ReASItem* ReASNode4::child4() const * * @param child4 the new child3 */ -void ReASNode4::setChild4(ReASItem* child4) -{ - m_child4 = child4; +void ReASNode4::setChild4(ReASItem* child4){ + m_child4 = child4; } - /** @class ReASNode5 rplastree.hpp "rplexpr/rplastree.hpp" * * @brief Implements an inner node of the abstract syntax tree with 4 childs. @@ -1886,18 +1744,15 @@ void ReASNode4::setChild4(ReASItem* child4) * @param type */ ReASNode5::ReASNode5(ReASItemType type) : - ReASNode4(type), - m_child5(NULL) -{ + ReASNode4(type), m_child5(NULL){ } /** * @brief Destructor. */ -ReASNode5::~ReASNode5() -{ - delete m_child5; - m_child5 = NULL; +ReASNode5::~ReASNode5(){ + delete m_child5; + m_child5 = NULL; } /** @@ -1905,9 +1760,8 @@ ReASNode5::~ReASNode5() * * @return the child 5 */ -ReASItem* ReASNode5::child5() const -{ - return m_child5; +ReASItem* ReASNode5::child5() const{ + return m_child5; } /** @@ -1915,9 +1769,8 @@ ReASItem* ReASNode5::child5() const * * @param child5 the new child3 */ -void ReASNode5::setChild5(ReASItem* child5) -{ - m_child5 = child5; +void ReASNode5::setChild5(ReASItem* child5){ + m_child5 = child5; } /** @class ReASNode6 rplastree.hpp "rplexpr/rplastree.hpp" @@ -1932,18 +1785,15 @@ void ReASNode5::setChild5(ReASItem* child5) * @param type */ ReASNode6::ReASNode6(ReASItemType type) : - ReASNode5(type), - m_child6(NULL) -{ + ReASNode5(type), m_child6(NULL){ } /** * @brief Destructor. */ -ReASNode6::~ReASNode6() -{ - delete m_child6; - m_child6 = NULL; +ReASNode6::~ReASNode6(){ + delete m_child6; + m_child6 = NULL; } /** @@ -1951,9 +1801,8 @@ ReASNode6::~ReASNode6() * * @return the child 5 */ -ReASItem* ReASNode6::child6() const -{ - return m_child6; +ReASItem* ReASNode6::child6() const{ + return m_child6; } /** @@ -1961,9 +1810,8 @@ ReASItem* ReASNode6::child6() const * * @param child6 the new child6 */ -void ReASNode6::setChild6(ReASItem* child6) -{ - m_child6 = child6; +void ReASNode6::setChild6(ReASItem* child6){ + m_child6 = child6; } /** @class ReASUnaryOp rplastree.hpp "rplexpr/rplastree.hpp" @@ -1982,9 +1830,7 @@ void ReASNode6::setChild6(ReASItem* child6) * @param type the node type */ ReASUnaryOp::ReASUnaryOp(UnaryOp op, ReASItemType type) : - ReASNode1(type), - m_operator(op) -{ + ReASNode1(type), m_operator(op){ } /** @@ -1992,34 +1838,33 @@ ReASUnaryOp::ReASUnaryOp(UnaryOp op, ReASItemType type) : * * @param thread IN/OUT: the execution unit, a VM thread */ -void ReASUnaryOp::calc(ReVMThread& thread) -{ - ReASVariant& value = thread.topOfValues(); - switch(m_operator){ - case UOP_PLUS: - break; - case UOP_MINUS_INT: - value.setInt(- value.asInt()); - break; - case UOP_MINUS_FLOAT: - value.setFloat(- value.asFloat()); - break; - case UOP_NOT_BOOL: - value.setBool(! value.asBool()); - break; - case UOP_NOT_INT: - value.setInt(~value.asInt()); - break; - case UOP_DEC: - case UOP_INC: - default: - error(thread.logger(), LOC_UNOP_CALC_1, "unknown operator: %d", m_operator); - break; - } - if (thread.tracing()) - thread.vm()->traceWriter()->format("unary %s: %s", - nameOfOp(m_operator), - value.toString().constData()); +void ReASUnaryOp::calc(ReVMThread& thread){ + ReASVariant& value = thread.topOfValues(); + switch (m_operator) { + case UOP_PLUS: + break; + case UOP_MINUS_INT: + value.setInt(-value.asInt()); + break; + case UOP_MINUS_FLOAT: + value.setFloat(-value.asFloat()); + break; + case UOP_NOT_BOOL: + value.setBool(!value.asBool()); + break; + case UOP_NOT_INT: + value.setInt(~value.asInt()); + break; + case UOP_DEC: + case UOP_INC: + default: + error(thread.logger(), LOC_UNOP_CALC_1, "unknown operator: %d", + m_operator); + break; + } + if (thread.tracing()) + thread.vm()->traceWriter()->format("unary %s: %s", nameOfOp(m_operator), + value.toString().constData()); } /** @@ -2029,54 +1874,53 @@ void ReASUnaryOp::calc(ReVMThread& thread) * @return true: node is correct
* false: otherwise */ -bool ReASUnaryOp::check(ReParser& parser) -{ - bool rc = m_child->check(parser); - if (rc){ - ReASCalculable* expr = dynamic_cast(m_child); - ReASClass* clazz = expr == NULL ? NULL : expr->clazz(); - if (clazz == NULL){ - rc = ensureError(parser, "ReASUnaryOp::check"); - } else { - switch(m_operator){ - case UOP_PLUS: - if (clazz != ReASInteger::m_instance - && clazz != ReASFloat::m_instance) - rc = error(LOC_UNARY_CHECK_1, parser, - "wrong data type for unary operator '+': %s", - clazz->name().constData()); - break; - case UOP_MINUS_INT: - if (clazz != ReASFloat::m_instance) - m_operator = UOP_MINUS_FLOAT; - else if (clazz != ReASInteger::m_instance) - rc = error(LOC_UNARY_CHECK_2, parser, - "wrong data type for unary operator '-': %s", - clazz->name().constData()); - break; - case UOP_NOT_BOOL: - if (clazz != ReASBoolean::m_instance) - rc = error(LOC_UNARY_CHECK_3, parser, - "wrong data type for unary operator '!': %s", - clazz->name().constData()); - break; - case UOP_NOT_INT: - if (clazz != ReASInteger::m_instance) - rc = error(LOC_UNARY_CHECK_4, parser, - "wrong data type for unary operator '!': %s", - clazz->name().constData()); - break; - case UOP_DEC: - break; - case UOP_INC: - break; - default: - throw ReASException(position(), "unknown operator: %d", m_operator); - break; - } - } - } - return rc; +bool ReASUnaryOp::check(ReParser& parser){ + bool rc = m_child->check(parser); + if (rc){ + ReASCalculable* expr = dynamic_cast (m_child); + ReASClass* clazz = expr == NULL ? NULL : expr->clazz(); + if (clazz == NULL){ + rc = ensureError(parser, "ReASUnaryOp::check"); + }else{ + switch (m_operator) { + case UOP_PLUS: + if (clazz != ReASInteger::m_instance + && clazz != ReASFloat::m_instance) + rc = error(LOC_UNARY_CHECK_1, parser, + "wrong data type for unary operator '+': %s", + clazz->name().constData()); + break; + case UOP_MINUS_INT: + if (clazz != ReASFloat::m_instance) + m_operator = UOP_MINUS_FLOAT; + else if (clazz != ReASInteger::m_instance) + rc = error(LOC_UNARY_CHECK_2, parser, + "wrong data type for unary operator '-': %s", + clazz->name().constData()); + break; + case UOP_NOT_BOOL: + if (clazz != ReASBoolean::m_instance) + rc = error(LOC_UNARY_CHECK_3, parser, + "wrong data type for unary operator '!': %s", + clazz->name().constData()); + break; + case UOP_NOT_INT: + if (clazz != ReASInteger::m_instance) + rc = error(LOC_UNARY_CHECK_4, parser, + "wrong data type for unary operator '!': %s", + clazz->name().constData()); + break; + case UOP_DEC: + break; + case UOP_INC: + break; + default: + throw ReASException(position(), "unknown operator: %d", m_operator); + break; + } + } + } + return rc; } /** @@ -2084,9 +1928,8 @@ bool ReASUnaryOp::check(ReParser& parser) * * @return the operator */ -int ReASUnaryOp::getOperator() const -{ - return m_operator; +int ReASUnaryOp::getOperator() const{ + return m_operator; } /** @@ -2095,17 +1938,13 @@ int ReASUnaryOp::getOperator() const * @param writer writes to output * @param indent nesting level */ -void ReASUnaryOp::dump(ReWriter& writer, int indent) -{ - char buffer[256]; - writer.formatIndented(indent, "Unary %d op: %s (%d) expr: %d %s", - m_id, - nameOfOp(m_operator), - m_operator, - m_child == NULL ? 0 : m_child->id(), - positionStr(buffer, sizeof buffer) ); - if (m_child != NULL) - m_child->dump(writer, indent + 1); +void ReASUnaryOp::dump(ReWriter& writer, int indent){ + char buffer[256]; + writer.formatIndented(indent, "Unary %d op: %s (%d) expr: %d %s", m_id, + nameOfOp(m_operator), m_operator, m_child == NULL ? 0 : m_child->id(), + positionStr(buffer, sizeof buffer)); + if (m_child != NULL) + m_child->dump(writer, indent + 1); } /** * @brief Returns the name (a string) of an unary operator. @@ -2113,37 +1952,35 @@ void ReASUnaryOp::dump(ReWriter& writer, int indent) * @param op the operand to convert * @return the name of the operator */ -const char*ReASUnaryOp::nameOfOp(ReASUnaryOp::UnaryOp op) -{ - const char* rc; - switch (op){ - case UOP_PLUS: - rc="+"; - break; - case UOP_MINUS_INT: - case UOP_MINUS_FLOAT: - rc="-"; - break; - case UOP_NOT_BOOL: - rc="!"; - break; - case UOP_NOT_INT: - rc="~"; - break; - case UOP_INC: - rc="++"; - break; - case UOP_DEC: - rc="--"; - break; - default: - throw ReException("unknown unary operator: %d", (int) op); - break; - } - return rc; +const char*ReASUnaryOp::nameOfOp(ReASUnaryOp::UnaryOp op){ + const char* rc; + switch (op) { + case UOP_PLUS: + rc = "+"; + break; + case UOP_MINUS_INT: + case UOP_MINUS_FLOAT: + rc = "-"; + break; + case UOP_NOT_BOOL: + rc = "!"; + break; + case UOP_NOT_INT: + rc = "~"; + break; + case UOP_INC: + rc = "++"; + break; + case UOP_DEC: + rc = "--"; + break; + default: + throw ReException("unknown unary operator: %d", (int) op); + break; + } + return rc; } - /** @class ReASStatement rplastree.hpp "rplexpr/rplastree.hpp" * * @brief Implements a base class for all statements. @@ -2155,8 +1992,7 @@ const char*ReASUnaryOp::nameOfOp(ReASUnaryOp::UnaryOp op) /** * @brief Constructor. */ -ReASStatement::ReASStatement() -{ +ReASStatement::ReASStatement(){ } /** * @brief Executes the statements of a statement list. @@ -2167,17 +2003,15 @@ ReASStatement::ReASStatement() * n > 0: stop the n most inner statement lists (initialized by leave) * n < 0: stop the -n most inner statement lists (initialized by continue) */ -int ReASStatement::executeStatementList(ReASItem* list, ReVMThread& thread) -{ - int rc = 0; - while(rc == 0 && list != NULL){ - ReASStatement* statement = dynamic_cast(list); - rc =statement->execute(thread); - } - return rc; +int ReASStatement::executeStatementList(ReASItem* list, ReVMThread& thread){ + int rc = 0; + while (rc == 0 && list != NULL){ + ReASStatement* statement = dynamic_cast (list); + rc = statement->execute(thread); + } + return rc; } - /** @class ReASIf rplastree.hpp "rplexpr/rplastree.hpp" * * @brief Implements an if statement. @@ -2193,9 +2027,8 @@ int ReASStatement::executeStatementList(ReASItem* list, ReVMThread& thread) */ ReASIf::ReASIf() : - ReASNode4(AST_IF) -{ - m_flags |= NF_STATEMENT; + ReASNode4(AST_IF){ + m_flags |= NF_STATEMENT; } /** @@ -2205,19 +2038,18 @@ ReASIf::ReASIf() : * @return true: node is correct
* false: otherwise */ -bool ReASIf::check(ReParser& parser) -{ - bool rc = true; - if (m_child2 == NULL) - rc = ensureError(parser, "'if' misses condition"); - else if (m_child2->checkAsCalculable("condition", ReASBoolean::m_instance, - parser)) - rc = false; - if (m_child3 != NULL && ! checkStatementList(m_child3, parser)) - rc = false; - if (m_child4 != NULL && ! checkStatementList(m_child4, parser)) - rc = false; - return rc; +bool ReASIf::check(ReParser& parser){ + bool rc = true; + if (m_child2 == NULL) + rc = ensureError(parser, "'if' misses condition"); + else if (m_child2->checkAsCalculable("condition", ReASBoolean::m_instance, + parser)) + rc = false; + if (m_child3 != NULL && !checkStatementList(m_child3, parser)) + rc = false; + if (m_child4 != NULL && !checkStatementList(m_child4, parser)) + rc = false; + return rc; } /** @@ -2227,23 +2059,22 @@ bool ReASIf::check(ReParser& parser) * n > 0: stop the n most inner statement lists (initialized by leave) * n < 0: stop the -n most inner statement lists (initialized by continue) */ -int ReASIf::execute(ReVMThread& thread) -{ - int rc = 0; - bool condition = calcAsBoolean(m_child2, thread); - if (thread.tracing()) - thread.vm()->traceWriter()->format("if %s", condition ? "true" : "false"); +int ReASIf::execute(ReVMThread& thread){ + int rc = 0; + bool condition = calcAsBoolean(m_child2, thread); + if (thread.tracing()) + thread.vm()->traceWriter()->format("if %s", condition ? "true" : "false"); - ReASItem* list = condition ? m_child3 : m_child4; - if (list != NULL){ - if ( (rc = executeStatementList(list, thread)) != 0){ - if (rc < 0) - rc--; - else if (rc > 0) - rc++; - } - } - return rc; + ReASItem* list = condition ? m_child3 : m_child4; + if (list != NULL){ + if ((rc = executeStatementList(list, thread)) != 0){ + if (rc < 0) + rc--; + else if (rc > 0) + rc++; + } + } + return rc; } /** @@ -2252,22 +2083,19 @@ int ReASIf::execute(ReVMThread& thread) * @param writer writes to output * @param indent nesting level */ -void ReASIf::dump(ReWriter& writer, int indent) -{ - char buffer[256]; - writer.formatIndented(indent, - "If id: %d condition: %d then: %d else: %d succ: %d%s", - m_id, - m_child2 == NULL ? 0 : m_child2->id(), - m_child3 == NULL ? 0 : m_child3->id(), - m_child4 == NULL ? 0 : m_child4->id(), - m_child == NULL ? 0 : m_child->id(), - positionStr(buffer, sizeof buffer)); - m_child2->dump(writer, indent + 1); - if (m_child3 != NULL) - m_child3->dump(writer, indent + 1); - if (m_child4 != NULL) - m_child4->dump(writer, indent + 1); +void ReASIf::dump(ReWriter& writer, int indent){ + char buffer[256]; + writer.formatIndented(indent, + "If id: %d condition: %d then: %d else: %d succ: %d%s", m_id, + m_child2 == NULL ? 0 : m_child2->id(), + m_child3 == NULL ? 0 : m_child3->id(), + m_child4 == NULL ? 0 : m_child4->id(), + m_child == NULL ? 0 : m_child->id(), positionStr(buffer, sizeof buffer)); + m_child2->dump(writer, indent + 1); + if (m_child3 != NULL) + m_child3->dump(writer, indent + 1); + if (m_child4 != NULL) + m_child4->dump(writer, indent + 1); } /** @class ReASFor rplastree.hpp "rplexpr/rplastree.hpp" @@ -2292,11 +2120,9 @@ void ReASIf::dump(ReWriter& writer, int indent) * @param variable NULL or the iterator variable */ ReASForIterated::ReASForIterated(ReASVarDefinition* variable) : - ReASNode4(AST_ITERATED_FOR), - ReASStatement() -{ - m_flags |= NF_STATEMENT; - m_child2 = variable; + ReASNode4(AST_ITERATED_FOR), ReASStatement(){ + m_flags |= NF_STATEMENT; + m_child2 = variable; } /** @@ -2306,9 +2132,9 @@ ReASForIterated::ReASForIterated(ReASVarDefinition* variable) : * @return true: node is correct
* false: otherwise */ -bool ReASForIterated::check(ReParser& parser) -{ - return false; +bool ReASForIterated::check(ReParser& parser){ + RE_UNUSED(&parser); + return false; } /** @@ -2318,9 +2144,9 @@ bool ReASForIterated::check(ReParser& parser) * n > 0: stop the n most inner statement lists (initialized by leave) * n < 0: stop the -n most inner statement lists (initialized by continue) */ -int ReASForIterated::execute(ReVMThread& thread) -{ - return 0; +int ReASForIterated::execute(ReVMThread& thread){ + RE_UNUSED(&thread); + return 0; } /** @@ -2329,21 +2155,19 @@ int ReASForIterated::execute(ReVMThread& thread) * @param writer writes to output * @param indent nesting level */ -void ReASForIterated::dump(ReWriter& writer, int indent) -{ - char buffer[256]; - writer.formatIndented(indent, "forIt id: %d var: %d set: %d body: %d succ: %d %s", - m_id, - m_child3 == NULL ? 0 : m_child3->id(), - m_child4 == NULL ? 0 : m_child4->id(), - m_child2 == NULL ? 0 : m_child2->id(), - m_child == NULL ? 0 : m_child->id(), - positionStr(buffer, sizeof buffer)); - if (m_child3 != NULL) - m_child3->dump(writer, indent + 1); - if (m_child4 != NULL) - m_child4->dump(writer, indent + 1); - dumpStatements(writer, indent + 1, m_child2); +void ReASForIterated::dump(ReWriter& writer, int indent){ + char buffer[256]; + writer.formatIndented(indent, + "forIt id: %d var: %d set: %d body: %d succ: %d %s", m_id, + m_child3 == NULL ? 0 : m_child3->id(), + m_child4 == NULL ? 0 : m_child4->id(), + m_child2 == NULL ? 0 : m_child2->id(), + m_child == NULL ? 0 : m_child->id(), positionStr(buffer, sizeof buffer)); + if (m_child3 != NULL) + m_child3->dump(writer, indent + 1); + if (m_child4 != NULL) + m_child4->dump(writer, indent + 1); + dumpStatements(writer, indent + 1, m_child2); } /** @class ReASForCounted rplastree.hpp "rplexpr/rplastree.hpp" @@ -2371,11 +2195,9 @@ void ReASForIterated::dump(ReWriter& writer, int indent) * @param variable NULL or the counter variable */ ReASForCounted::ReASForCounted(ReASVarDefinition* variable) : - ReASNode6(AST_ITERATED_FOR), - ReASStatement() -{ - m_flags |= NF_STATEMENT; - m_child3 = variable; + ReASNode6(AST_ITERATED_FOR), ReASStatement(){ + m_flags |= NF_STATEMENT; + m_child3 = variable; } /** @@ -2385,31 +2207,32 @@ ReASForCounted::ReASForCounted(ReASVarDefinition* variable) : * @return true: node is correct
* false: otherwise */ -bool ReASForCounted::check(ReParser& parser) -{ - bool rc = true; - ReASNamedValue* var = NULL; - if (m_child3 != NULL){ - var = dynamic_cast(m_child3); - if (! m_child3->check(parser)) - rc = false; - if (var == NULL) - rc = error(LOC_FORC_CHECK_1, parser, "not a variable: %s", - m_child3->nameOfItemType()); - } - ReASCalculable* expr; - if (m_child4 != NULL && ! m_child4->checkAsCalculable("start value", - ReASInteger::m_instance, parser)) - rc = false; - if (m_child5 != NULL && ! m_child5->checkAsCalculable("end value", - ReASInteger::m_instance, parser)) - rc = false; - if (m_child6 != NULL && ! m_child6->checkAsCalculable("step value", - ReASInteger::m_instance, parser)) - rc = false; - if (m_child2 != NULL && ! checkStatementList(m_child2, parser)) - rc = false; - return rc; +bool ReASForCounted::check(ReParser& parser){ + bool rc = true; + ReASNamedValue* var = NULL; + if (m_child3 != NULL){ + var = dynamic_cast (m_child3); + if (!m_child3->check(parser)) + rc = false; + if (var == NULL) + rc = error(LOC_FORC_CHECK_1, parser, "not a variable: %s", + m_child3->nameOfItemType()); + } + if (m_child4 != NULL + && !m_child4->checkAsCalculable("start value", ReASInteger::m_instance, + parser)) + rc = false; + if (m_child5 != NULL + && !m_child5->checkAsCalculable("end value", ReASInteger::m_instance, + parser)) + rc = false; + if (m_child6 != NULL + && !m_child6->checkAsCalculable("step value", ReASInteger::m_instance, + parser)) + rc = false; + if (m_child2 != NULL && !checkStatementList(m_child2, parser)) + rc = false; + return rc; } /** @@ -2419,41 +2242,39 @@ bool ReASForCounted::check(ReParser& parser) * n > 0: stop the n most inner statement lists (initialized by leave) * n < 0: stop the -n most inner statement lists (initialized by continue) */ -int ReASForCounted::execute(ReVMThread& thread) -{ - int rc = 0; - ReASStatement* body = dynamic_cast(m_child2); - if (body == NULL) - throw ReASException(m_child2 == NULL ? m_position : m_child2->position(), - "forc statement: body is not a statement"); - int start = m_child4 == NULL ? 1 : calcAsInteger(m_child4, thread); - int end = m_child5 == NULL ? 0 : calcAsInteger(m_child5, thread); - int step = m_child6 == NULL ? 1 : calcAsInteger(m_child6, thread); - ReASNamedValue* var = m_child3 == NULL - ? NULL : dynamic_cast(m_child3); - if (thread.tracing()) - thread.vm()->traceWriter()->format("for %s from %d to %d step %d", - var == NULL ? "?" : var->name().constData(), - start, end, step); - - for(int ii = start; ii <= end; ii += step){ - //@ToDo: assign to the variable - int rc2 = body->execute(thread); - if (rc2 != 0){ - if (rc2 > 0){ - // rc comes from "break"; - rc = rc2 - 1; - } else { - // rc comes from "continue"; - if (rc2 == -1) - continue; - else - rc = rc2 + 1; - } - break; - } - } - return rc; +int ReASForCounted::execute(ReVMThread& thread){ + int rc = 0; + ReASStatement* body = dynamic_cast (m_child2); + if (body == NULL) + throw ReASException(m_child2 == NULL ? m_position : m_child2->position(), + "forc statement: body is not a statement"); + int start = m_child4 == NULL ? 1 : calcAsInteger(m_child4, thread); + int end = m_child5 == NULL ? 0 : calcAsInteger(m_child5, thread); + int step = m_child6 == NULL ? 1 : calcAsInteger(m_child6, thread); + ReASNamedValue* var = + m_child3 == NULL ? NULL : dynamic_cast (m_child3); + if (thread.tracing()) + thread.vm()->traceWriter()->format("for %s from %d to %d step %d", + var == NULL ? "?" : var->name().constData(), start, end, step); + + for (int ii = start; ii <= end; ii += step){ + //@ToDo: assign to the variable + int rc2 = body->execute(thread); + if (rc2 != 0){ + if (rc2 > 0){ + // rc comes from "break"; + rc = rc2 - 1; + }else{ + // rc comes from "continue"; + if (rc2 == -1) + continue; + else + rc = rc2 + 1; + } + break; + } + } + return rc; } /** @@ -2462,27 +2283,25 @@ int ReASForCounted::execute(ReVMThread& thread) * @param writer writes to output * @param indent nesting level */ -void ReASForCounted::dump(ReWriter& writer, int indent) -{ - char buffer[256]; - writer.formatIndented(indent, "forC id: %d var: %d from: %d to: %d step: %d body: %d succ: %d %s", - m_id, - m_child3 == NULL ? 0 : m_child3->id(), - m_child4 == NULL ? 0 : m_child4->id(), - m_child5 == NULL ? 0 : m_child5->id(), - m_child6 == NULL ? 0 : m_child6->id(), - m_child2 == NULL ? 0 : m_child2->id(), - m_child == NULL ? 0 : m_child->id(), - positionStr(buffer, sizeof buffer)); - if (m_child3 != NULL) - m_child3->dump(writer, indent + 1); - if (m_child4 != NULL) - m_child4->dump(writer, indent + 1); - if (m_child5 != NULL) - m_child5->dump(writer, indent + 1); - if (m_child6 != NULL) - m_child6->dump(writer, indent + 1); - dumpStatements(writer, indent + 1, m_child2); +void ReASForCounted::dump(ReWriter& writer, int indent){ + char buffer[256]; + writer.formatIndented(indent, + "forC id: %d var: %d from: %d to: %d step: %d body: %d succ: %d %s", m_id, + m_child3 == NULL ? 0 : m_child3->id(), + m_child4 == NULL ? 0 : m_child4->id(), + m_child5 == NULL ? 0 : m_child5->id(), + m_child6 == NULL ? 0 : m_child6->id(), + m_child2 == NULL ? 0 : m_child2->id(), + m_child == NULL ? 0 : m_child->id(), positionStr(buffer, sizeof buffer)); + if (m_child3 != NULL) + m_child3->dump(writer, indent + 1); + if (m_child4 != NULL) + m_child4->dump(writer, indent + 1); + if (m_child5 != NULL) + m_child5->dump(writer, indent + 1); + if (m_child6 != NULL) + m_child6->dump(writer, indent + 1); + dumpStatements(writer, indent + 1, m_child2); } /** @class ReASWhile rplastree.hpp "rplexpr/rplastree.hpp" @@ -2498,10 +2317,8 @@ void ReASForCounted::dump(ReWriter& writer, int indent) */ ReASWhile::ReASWhile() : - ReASNode3(AST_WHILE), - ReASStatement() -{ - m_flags |= NF_STATEMENT; + ReASNode3(AST_WHILE), ReASStatement(){ + m_flags |= NF_STATEMENT; } /** @@ -2511,17 +2328,16 @@ ReASWhile::ReASWhile() : * @return true: node is correct
* false: otherwise */ -bool ReASWhile::check(ReParser& parser) -{ - bool rc = true; - if (m_child2 == NULL) - ensureError(parser, "missing condition for 'while''"); - else - rc = m_child2->checkAsCalculable("condition", ReASBoolean::m_instance, - parser); - if (m_child3 != NULL && ! checkStatementList(m_child3, parser)) - rc = false; - return rc; +bool ReASWhile::check(ReParser& parser){ + bool rc = true; + if (m_child2 == NULL) + ensureError(parser, "missing condition for 'while''"); + else + rc = m_child2->checkAsCalculable("condition", ReASBoolean::m_instance, + parser); + if (m_child3 != NULL && !checkStatementList(m_child3, parser)) + rc = false; + return rc; } /** @@ -2531,29 +2347,28 @@ bool ReASWhile::check(ReParser& parser) * n > 0: stop the n most inner statement lists (initialized by leave) * n < 0: stop the -n most inner statement lists (initialized by continue) */ -int ReASWhile::execute(ReVMThread& thread) -{ - int rc = 0; - ReASStatement* body = dynamic_cast(m_child3); - if (thread.tracing()) - thread.vm()->traceWriter()->write("while"); - while(calcAsBoolean(m_child2, thread)){ - int rc2 = body->execute(thread); - if (rc2 != 0){ - if (rc2 > 0){ - // rc comes from "break"; - rc = rc2 - 1; - } else { - // rc comes from "continue"; - if (rc2 == -1) - continue; - else - rc = rc2 + 1; - } - break; - } - } - return rc; +int ReASWhile::execute(ReVMThread& thread){ + int rc = 0; + ReASStatement* body = dynamic_cast (m_child3); + if (thread.tracing()) + thread.vm()->traceWriter()->write("while"); + while (calcAsBoolean(m_child2, thread)){ + int rc2 = body->execute(thread); + if (rc2 != 0){ + if (rc2 > 0){ + // rc comes from "break"; + rc = rc2 - 1; + }else{ + // rc comes from "continue"; + if (rc2 == -1) + continue; + else + rc = rc2 + 1; + } + break; + } + } + return rc; } /** @@ -2562,19 +2377,17 @@ int ReASWhile::execute(ReVMThread& thread) * @param writer writes to output * @param indent nesting level */ -void ReASWhile::dump(ReWriter& writer, int indent) -{ +void ReASWhile::dump(ReWriter& writer, int indent){ - char buffer[256]; - writer.formatIndented(indent, "while id: %d condition: %d body: %d succ: %d %s", - m_id, - m_child2 == NULL ? 0 : m_child2->id(), - m_child3 == NULL ? 0 : m_child3->id(), - m_child == NULL ? 0 : m_child->id(), - positionStr(buffer, sizeof buffer)); - if (m_child2 != NULL) - m_child2->dump(writer, indent + 1); - dumpStatements(writer, indent + 1, m_child3); + char buffer[256]; + writer.formatIndented(indent, + "while id: %d condition: %d body: %d succ: %d %s", m_id, + m_child2 == NULL ? 0 : m_child2->id(), + m_child3 == NULL ? 0 : m_child3->id(), + m_child == NULL ? 0 : m_child->id(), positionStr(buffer, sizeof buffer)); + if (m_child2 != NULL) + m_child2->dump(writer, indent + 1); + dumpStatements(writer, indent + 1, m_child3); } /** @class ReASRepeat rplastree.hpp "rplexpr/rplastree.hpp" @@ -2590,10 +2403,8 @@ void ReASWhile::dump(ReWriter& writer, int indent) */ ReASRepeat::ReASRepeat() : - ReASNode3(AST_REPEAT), - ReASStatement() -{ - m_flags |= NF_STATEMENT; + ReASNode3(AST_REPEAT), ReASStatement(){ + m_flags |= NF_STATEMENT; } /** @@ -2603,17 +2414,16 @@ ReASRepeat::ReASRepeat() : * @return true: node is correct
* false: otherwise */ -bool ReASRepeat::check(ReParser& parser) -{ - bool rc = true; - if (m_child3 != NULL && ! checkStatementList(m_child3, parser)) - rc = false; - if (m_child2 == NULL) - ensureError(parser, "missing condition for 'repeat''"); - else if (! m_child2->checkAsCalculable("condition", ReASBoolean::m_instance, - parser)) - rc = false; - return rc; +bool ReASRepeat::check(ReParser& parser){ + bool rc = true; + if (m_child3 != NULL && !checkStatementList(m_child3, parser)) + rc = false; + if (m_child2 == NULL) + ensureError(parser, "missing condition for 'repeat''"); + else if (!m_child2->checkAsCalculable("condition", ReASBoolean::m_instance, + parser)) + rc = false; + return rc; } /** @@ -2623,29 +2433,28 @@ bool ReASRepeat::check(ReParser& parser) * m_child: body * m_child2: condition */ -int ReASRepeat::execute(ReVMThread& thread) -{ - int rc = 0; - ReASStatement* body = dynamic_cast(m_child3); - if (thread.tracing()) - thread.vm()->traceWriter()->write("repeat"); - do { - int rc2 = body->execute(thread); - if (rc2 != 0){ - if (rc2 > 0){ - // rc comes from "break"; - rc = rc2 - 1; - } else { - // rc comes from "continue"; - if (rc2 == -1) - continue; - else - rc = rc2 + 1; - } - break; - } - } while(! calcAsBoolean(m_child2, thread)); - return rc; +int ReASRepeat::execute(ReVMThread& thread){ + int rc = 0; + ReASStatement* body = dynamic_cast (m_child3); + if (thread.tracing()) + thread.vm()->traceWriter()->write("repeat"); + do{ + int rc2 = body->execute(thread); + if (rc2 != 0){ + if (rc2 > 0){ + // rc comes from "break"; + rc = rc2 - 1; + }else{ + // rc comes from "continue"; + if (rc2 == -1) + continue; + else + rc = rc2 + 1; + } + break; + } + }while (!calcAsBoolean(m_child2, thread)); + return rc; } /** @@ -2654,18 +2463,16 @@ int ReASRepeat::execute(ReVMThread& thread) * @param writer writes to output * @param indent nesting level */ -void ReASRepeat::dump(ReWriter& writer, int indent) -{ - char buffer[256]; - writer.formatIndented(indent, "repeat id: %d condition: %d body: %d succ: %d %s", - m_id, - m_child2 == NULL ? 0 : m_child2->id(), - m_child3 == NULL ? 0 : m_child3->id(), - m_child == NULL ? 0 : m_child->id(), - positionStr(buffer, sizeof buffer)); - if (m_child2 != NULL) - m_child2->dump(writer, indent + 1); - dumpStatements(writer, indent + 1, m_child3); +void ReASRepeat::dump(ReWriter& writer, int indent){ + char buffer[256]; + writer.formatIndented(indent, + "repeat id: %d condition: %d body: %d succ: %d %s", m_id, + m_child2 == NULL ? 0 : m_child2->id(), + m_child3 == NULL ? 0 : m_child3->id(), + m_child == NULL ? 0 : m_child->id(), positionStr(buffer, sizeof buffer)); + if (m_child2 != NULL) + m_child2->dump(writer, indent + 1); + dumpStatements(writer, indent + 1, m_child3); } /** @class ReASClass rplastree.hpp "rplexpr/rplastree.hpp" @@ -2678,11 +2485,7 @@ void ReASRepeat::dump(ReWriter& writer, int indent) * @brief Constructor. */ ReASClass::ReASClass(const QByteArray& name, ReASTree& tree) : - m_name(name), - m_symbols(NULL), - m_superClass(NULL), - m_tree(tree) -{ + m_name(name), m_symbols(NULL), m_superClass(NULL), m_tree(tree){ } /** @@ -2691,8 +2494,7 @@ ReASClass::ReASClass(const QByteArray& name, ReASTree& tree) : * Does nothing but forces a virtual destructor of all derived classes. * */ -ReASClass::~ReASClass() -{ +ReASClass::~ReASClass(){ } @@ -2701,9 +2503,8 @@ ReASClass::~ReASClass() * * @return the class name */ -const QByteArray& ReASClass::name() const -{ - return m_name; +const QByteArray& ReASClass::name() const{ + return m_name; } /** @@ -2712,20 +2513,17 @@ const QByteArray& ReASClass::name() const * @param writer writes to output * @param indent nesting level */ -void ReASClass::dump(ReWriter& writer, int indent) -{ - writer.formatIndented(indent, "class %s super: %s", m_name.constData(), - m_superClass == NULL - ? "" : m_superClass->name().constData()); - m_symbols->dump(writer, indent); +void ReASClass::dump(ReWriter& writer, int indent){ + writer.formatIndented(indent, "class %s super: %s", m_name.constData(), + m_superClass == NULL ? "" : m_superClass->name().constData()); + m_symbols->dump(writer, indent); } /** * @brief Sets the symbol space from the current in the tree. */ -void ReASClass::setSymbols() -{ - m_symbols = m_tree.currentSpace(); +void ReASClass::setSymbols(){ + m_symbols = m_tree.currentSpace(); } /** @class ReASTree rplastree.hpp "rplexpr/rplastree.hpp" @@ -2739,21 +2537,19 @@ void ReASClass::setSymbols() * @brief Constructor. */ ReASTree::ReASTree() : - m_global(NULL), - m_modules(), - m_symbolSpaces(), - m_currentSpace(NULL), - m_store(128*1024) -{ - init(); + m_global(NULL), + m_modules(), + m_symbolSpaces(), + m_currentSpace(NULL), + m_store(128 * 1024){ + init(); } /** * @brief Destructor. */ -ReASTree::~ReASTree() -{ - destroy(); +ReASTree::~ReASTree(){ + destroy(); } /** @@ -2761,32 +2557,29 @@ ReASTree::~ReASTree() * * Used in the constructor and in clear. */ -void ReASTree::init() -{ - m_global = ReSymbolSpace::createGlobal(*this); - m_symbolSpaces.append(m_global); - m_currentSpace = m_global; +void ReASTree::init(){ + m_global = ReSymbolSpace::createGlobal(*this); + m_symbolSpaces.append(m_global); + m_currentSpace = m_global; } /** * @brief Frees the resources of the instance. */ -void ReASTree::destroy() -{ - SymbolSpaceMap::iterator it; - for (it = m_symbolSpaceHeap.begin(); it != m_symbolSpaceHeap.end(); it++){ - delete it.value(); - } - m_symbolSpaceHeap.clear(); +void ReASTree::destroy(){ + SymbolSpaceMap::iterator it; + for (it = m_symbolSpaceHeap.begin(); it != m_symbolSpaceHeap.end(); it++){ + delete it.value(); + } + m_symbolSpaceHeap.clear(); } /** * @brief Returns the string storage of the instance. * * @return the efficient allocator for C strings */ -ReByteStorage& ReASTree::store() -{ - return m_store; +ReByteStorage& ReASTree::store(){ + return m_store; } /** @@ -2796,19 +2589,18 @@ ReByteStorage& ReASTree::store() * @return true: the module is new
* false: the module is yet known */ -bool ReASTree::startModule(ReSourceUnitName name) -{ - bool rc = m_modules.contains(name); - if (! rc){ - // freed in ~ReASTree() - ReSymbolSpace* space = new ReSymbolSpace(ReSymbolSpace::SST_MODULE, - name, m_global); - m_symbolSpaceHeap[name] = space; - m_modules[name] = space; - m_symbolSpaces.append(space); - m_currentSpace = space; - } - return rc; +bool ReASTree::startModule(ReSourceUnitName name){ + bool rc = m_modules.contains(name); + if (!rc){ + // freed in ~ReASTree() + ReSymbolSpace* space = new ReSymbolSpace(ReSymbolSpace::SST_MODULE, name, + m_global); + m_symbolSpaceHeap[name] = space; + m_modules[name] = space; + m_symbolSpaces.append(space); + m_currentSpace = space; + } + return rc; } /** * @brief Search for the symbol space of a given module. @@ -2817,27 +2609,25 @@ bool ReASTree::startModule(ReSourceUnitName name) * @return NULL: not found
* otherwise: the symbol space of the module */ -ReSymbolSpace* ReASTree::findmodule(const QByteArray& name) -{ - ReSymbolSpace* rc = m_modules.contains(name) ? m_modules[name] : NULL; - return rc; +ReSymbolSpace* ReASTree::findmodule(const QByteArray& name){ + ReSymbolSpace* rc = m_modules.contains(name) ? m_modules[name] : NULL; + return rc; } /** * @brief Handles the end of a module. * @param name the module's name */ -void ReASTree::finishModule(ReSourceUnitName name) -{ - ReSymbolSpace* top = m_symbolSpaces.at(m_symbolSpaces.size() - 1); - if (top->name() != name) - throw ReException("ReASTree::finishModule(): module is not top: %s", - name); - else { - m_symbolSpaces.removeLast(); - // "global" is always the bottom: - m_currentSpace = m_symbolSpaces.at(m_symbolSpaces.size() - 1); - } +void ReASTree::finishModule(ReSourceUnitName name){ + ReSymbolSpace* top = m_symbolSpaces.at(m_symbolSpaces.size() - 1); + if (top->name() != name) + throw ReException("ReASTree::finishModule(): module is not top: %s", + name); + else{ + m_symbolSpaces.removeLast(); + // "global" is always the bottom: + m_currentSpace = m_symbolSpaces.at(m_symbolSpaces.size() - 1); + } } /** @@ -2847,17 +2637,16 @@ void ReASTree::finishModule(ReSourceUnitName name) * @return the new symbol space */ ReSymbolSpace* ReASTree::startClassOrMethod(const QByteArray& name, - ReSymbolSpace::SymbolSpaceType type) -{ - // the stack m_modules is never empty because of "global" and modules. - ReSymbolSpace* parent = m_symbolSpaces[m_symbolSpaces.size() - 1]; - QByteArray fullName = parent->name() + "." + name; - // freed in ~ReASTree() - ReSymbolSpace* space = new ReSymbolSpace(type, fullName, parent); - m_symbolSpaceHeap[fullName] = space; - m_symbolSpaces.append(space); - m_currentSpace = space; - return space; + ReSymbolSpace::SymbolSpaceType type){ + // the stack m_modules is never empty because of "global" and modules. + ReSymbolSpace* parent = m_symbolSpaces[m_symbolSpaces.size() - 1]; + QByteArray fullName = parent->name() + "." + name; + // freed in ~ReASTree() + ReSymbolSpace* space = new ReSymbolSpace(type, fullName, parent); + m_symbolSpaceHeap[fullName] = space; + m_symbolSpaces.append(space); + m_currentSpace = space; + return space; } /** @@ -2865,17 +2654,16 @@ ReSymbolSpace* ReASTree::startClassOrMethod(const QByteArray& name, * * @param name the name of the class (short form) */ -void ReASTree::finishClassOrMethod(const QByteArray& name) -{ - ReSymbolSpace* top = m_symbolSpaces.at(m_symbolSpaces.size() - 1); - if (! top->name().endsWith("." + name)) - throw ReException("ReASTree::finishModule(): class is not top: %s", - name.constData()); - else { - m_symbolSpaces.removeLast(); - // "global" is the bottom always! - m_currentSpace = m_symbolSpaces.at(m_symbolSpaces.size() - 1); - } +void ReASTree::finishClassOrMethod(const QByteArray& name){ + ReSymbolSpace* top = m_symbolSpaces.at(m_symbolSpaces.size() - 1); + if (!top->name().endsWith("." + name)) + throw ReException("ReASTree::finishModule(): class is not top: %s", + name.constData()); + else{ + m_symbolSpaces.removeLast(); + // "global" is the bottom always! + m_currentSpace = m_symbolSpaces.at(m_symbolSpaces.size() - 1); + } } /** @@ -2883,30 +2671,27 @@ void ReASTree::finishClassOrMethod(const QByteArray& name) * * @return the stack with the active symbol spaces */ -ReASTree::SymbolSpaceStack& ReASTree::symbolSpaces() -{ - return m_symbolSpaces; +ReASTree::SymbolSpaceStack& ReASTree::symbolSpaces(){ + return m_symbolSpaces; } /** * @brief Returns the current symbol space (top of the stack). * * @return the current symbol space */ -ReSymbolSpace* ReASTree::currentSpace() const -{ - return m_currentSpace; +ReSymbolSpace* ReASTree::currentSpace() const{ + return m_currentSpace; } /** * @brief Removes all content from the abstract syntax tree. */ -void ReASTree::clear() -{ - destroy(); - //m_global->clear(); - m_modules.clear(); - m_symbolSpaces.clear(); - init(); +void ReASTree::clear(){ + destroy(); + //m_global->clear(); + m_modules.clear(); + m_symbolSpaces.clear(); + init(); } /** @@ -2916,29 +2701,28 @@ void ReASTree::clear() * @param flags what to dump: sum of DMP_... flags * @param header NULL or a text put on the top */ -void ReASTree::dump(const char* filename, int flags, const char* header) -{ - ReFileWriter writer(filename); - if (header != NULL) - writer.writeLine(header); - if (flags & DMP_GLOBALS){ - m_global->dump(writer, 0, "=== Globals:"); - } - if (flags & DMP_MODULES){ - QList sorted; - sorted.reserve(m_modules.size()); - SymbolSpaceMap::iterator it; - for (it = m_modules.begin(); it != m_modules.end(); it++){ - sorted.append(it.key()); - } - qSort(sorted.begin(), sorted.end(), qLess()); - QList::iterator it2; - for (it2 = sorted.begin(); it2 != sorted.end(); it2++){ - ReSymbolSpace* space = m_modules[*it2]; - space->dump(writer, 0); - } - } - writer.close(); +void ReASTree::dump(const char* filename, int flags, const char* header){ + ReFileWriter writer(filename); + if (header != NULL) + writer.writeLine(header); + if (flags & DMP_GLOBALS){ + m_global->dump(writer, 0, "=== Globals:"); + } + if (flags & DMP_MODULES){ + QList < QByteArray > sorted; + sorted.reserve(m_modules.size()); + SymbolSpaceMap::iterator it; + for (it = m_modules.begin(); it != m_modules.end(); it++){ + sorted.append(it.key()); + } + qSort(sorted.begin(), sorted.end(), qLess ()); + QList ::iterator it2; + for (it2 = sorted.begin(); it2 != sorted.end(); it2++){ + ReSymbolSpace* space = m_modules[*it2]; + space->dump(writer, 0); + } + } + writer.close(); } /** @class ReASMethodCall rplastree.hpp "rplexpr/rplastree.hpp" @@ -2958,13 +2742,12 @@ void ReASTree::dump(const char* filename, int flags, const char* header) */ ReASMethodCall::ReASMethodCall(const QByteArray& name, ReASItem* parent) : - ReASNode3(AST_METHOD_CALL), - ReASStatement(), - m_name(name), - m_method(NULL) -{ - m_flags |= NF_STATEMENT; - m_child3 = parent; + ReASNode3(AST_METHOD_CALL), + ReASStatement(), + m_name(name), + m_method(NULL){ + m_flags |= NF_STATEMENT; + m_child3 = parent; } /** @@ -2974,69 +2757,65 @@ ReASMethodCall::ReASMethodCall(const QByteArray& name, ReASItem* parent) : * @return true: node is correct
* false: otherwise */ -bool ReASMethodCall::check(ReParser& parser) -{ - bool rc = true; - ReASExprStatement* args = dynamic_cast(m_child2); - int argCount = 0; - ReASMethod* method = m_method; - ReASVarDefinition* params = dynamic_cast(method->child2()); - while (args != NULL && params != NULL){ - argCount++; - ReASCalculable* argExpr = dynamic_cast - (args->child2()); - if (argExpr == NULL) - rc = error(LOC_METHOD_CALL_CHECK_1, parser, - "argument %d misses expr", argCount); - else { - ReASNamedValue* var; - ReASItem* param = params->child2(); - if (param == NULL - || (var = dynamic_cast(param)) == NULL) - rc = error(LOC_MEHTOD_CALL_CHECK_2, parser, - "parameter %d misses named value: %s", argCount, - param == NULL ? "" : param->nameOfItemType()); - else { - // tryConversion() calls args->args->child2()->check()! - ReASConversion* converter = ReASConversion::tryConversion( - var->clazz(), args->child2(), parser, rc); - if (rc && converter != NULL) - args->setChild2(converter); - - } - } - args = dynamic_cast(args->child()); - params = dynamic_cast(params->child()); - } - if (args != NULL && params == NULL) - rc = error(LOC_MEHTOD_CALL_CHECK_3, parser, - "too many arguments: %d are enough", argCount); - else if (args == NULL && params != NULL && params->child3() != NULL) - rc = error(LOC_MEHTOD_CALL_CHECK_4, parser, - "too few arguments: %d are not enough", argCount); - return rc; +bool ReASMethodCall::check(ReParser& parser){ + bool rc = true; + ReASExprStatement* args = dynamic_cast (m_child2); + int argCount = 0; + ReASMethod* method = m_method; + ReASVarDefinition* params = + dynamic_cast (method->child2()); + while (args != NULL && params != NULL){ + argCount++; + ReASCalculable* argExpr = dynamic_cast (args->child2()); + if (argExpr == NULL) + rc = error(LOC_METHOD_CALL_CHECK_1, parser, "argument %d misses expr", + argCount); + else{ + ReASNamedValue* var; + ReASItem* param = params->child2(); + if (param == NULL + || (var = dynamic_cast (param)) == NULL) + rc = error(LOC_MEHTOD_CALL_CHECK_2, parser, + "parameter %d misses named value: %s", argCount, + param == NULL ? "" : param->nameOfItemType()); + else{ + // tryConversion() calls args->args->child2()->check()! + ReASConversion* converter = ReASConversion::tryConversion( + var->clazz(), args->child2(), parser, rc); + if (rc && converter != NULL) + args->setChild2(converter); + + } + } + args = dynamic_cast (args->child()); + params = dynamic_cast (params->child()); + } + if (args != NULL && params == NULL) + rc = error(LOC_MEHTOD_CALL_CHECK_3, parser, + "too many arguments: %d are enough", argCount); + else if (args == NULL && params != NULL && params->child3() != NULL) + rc = error(LOC_MEHTOD_CALL_CHECK_4, parser, + "too few arguments: %d are not enough", argCount); + return rc; } - /** * @brief Writes the internals into a file. * * @param writer writes to output * @param indent nesting level */ -void ReASMethodCall::dump(ReWriter& writer, int indent) -{ - char buffer[256]; - writer.formatIndented(indent, "call %s Id: %d args: %d parent: %d succ: %d %s", - m_name.constData(), m_id, - m_child2 == NULL ? 0 : m_child2->id(), - m_child3 == NULL ? 0 : m_child3->id(), - m_child == NULL ? 0 : m_child->id(), - positionStr(buffer, sizeof buffer)); - if (m_child2 != NULL) - m_child2->dump(writer, indent + 1); - if (m_child3 != NULL) - m_child3->dump(writer, indent + 1); +void ReASMethodCall::dump(ReWriter& writer, int indent){ + char buffer[256]; + writer.formatIndented(indent, + "call %s Id: %d args: %d parent: %d succ: %d %s", m_name.constData(), + m_id, m_child2 == NULL ? 0 : m_child2->id(), + m_child3 == NULL ? 0 : m_child3->id(), + m_child == NULL ? 0 : m_child->id(), positionStr(buffer, sizeof buffer)); + if (m_child2 != NULL) + m_child2->dump(writer, indent + 1); + if (m_child3 != NULL) + m_child3->dump(writer, indent + 1); } /** @@ -3044,39 +2823,34 @@ void ReASMethodCall::dump(ReWriter& writer, int indent) * * @return 0: continue the current statement list */ -int ReASMethodCall::execute(ReVMThread& thread) -{ - int rc = 0; - ReASMethod* method = m_method; - ReStackFrame frame(this, m_method->symbols()); - thread.pushFrame(&frame); - ReASExprStatement* args = dynamic_cast(m_child2); - int ixArg = -1; - while (args != NULL){ - ixArg++; - ReASCalculable* argExpr = dynamic_cast - (args->child2()); - argExpr->calc(thread); - ReASVariant& value = thread.popValue(); - ReASVariant& varValue = frame.valueOfVariable(ixArg); - varValue.copyValue(value); - } - thread.popFrame(); - return rc; -} - -ReASMethod* ReASMethodCall::method() const -{ - return m_method; +int ReASMethodCall::execute(ReVMThread& thread){ + int rc = 0; + ReStackFrame frame(this, m_method->symbols()); + thread.pushFrame(&frame); + ReASExprStatement* args = dynamic_cast (m_child2); + int ixArg = -1; + while (args != NULL){ + ixArg++; + ReASCalculable* argExpr = dynamic_cast (args->child2()); + argExpr->calc(thread); + ReASVariant& value = thread.popValue(); + ReASVariant& varValue = frame.valueOfVariable(ixArg); + varValue.copyValue(value); + } + thread.popFrame(); + return rc; +} + +ReASMethod* ReASMethodCall::method() const{ + return m_method; } /** * @brief Sets the method. * @param method method to set */ -void ReASMethodCall::setMethod(ReASMethod* method) -{ - m_method = method; +void ReASMethodCall::setMethod(ReASMethod* method){ + m_method = method; } /** @@ -3084,9 +2858,8 @@ void ReASMethodCall::setMethod(ReASMethod* method) * * @return the first element of an argument list */ -ReASExprStatement* ReASMethodCall::arg1() const -{ - return dynamic_cast(m_child2); +ReASExprStatement* ReASMethodCall::arg1() const{ + return dynamic_cast (m_child2); } /** @class ReASException rplastree.hpp "rplexpr/rplastree.hpp" @@ -3108,9 +2881,7 @@ ReASExprStatement* ReASMethodCall::arg1() const * @brief Constructor. */ ReASBinaryOp::ReASBinaryOp() : - ReASNode2(AST_BINARY_OP), - m_operator(BOP_UNDEF) -{ + ReASNode2(AST_BINARY_OP), m_operator(BOP_UNDEF){ } /** @@ -3118,178 +2889,177 @@ ReASBinaryOp::ReASBinaryOp() : * * @param thread IN/OUT: the bool value of the condition */ -void ReASBinaryOp::calc(ReVMThread& thread) -{ - if (isAssignment()) - assign(thread); - else{ - ReASCalculable* op1 = dynamic_cast(m_child); - ReASCalculable* op2 = dynamic_cast(m_child2); - if (op1 == NULL || op2 == NULL) - error(thread.logger(), LOC_BINOP_CALC_1, "operand is null: %d / %d", - m_child == NULL ? 0 : m_child->id(), - m_child2 == NULL ? 0 : m_child2->id()); - else{ - op1->calc(thread); - op2->calc(thread); - ReASVariant& val1 = thread.top2OfValues(); - ReASVariant& val2 = thread.topOfValues(); - switch(m_operator){ - case BOP_PLUS: - switch(val1.variantType()){ - case ReASVariant::VT_FLOAT: - val1.setFloat(val1.asFloat() + val2.asFloat()); - break; - case ReASVariant::VT_INTEGER: - val1.setInt(val1.asInt() + val2.asInt()); - break; - case ReASVariant::VT_OBJECT: - //if (val1.getClass() == ReASString::m_instance) - default: - error(thread.logger(), LOC_BINOP_CALC_2, "invalid type for '+': %s", - val1.nameOfType()); - break; - } - break; - case BOP_MINUS: - switch(val1.variantType()){ - case ReASVariant::VT_FLOAT: - val1.setFloat(val1.asFloat() - val2.asFloat()); - break; - case ReASVariant::VT_INTEGER: - val1.setInt(val1.asInt() - val2.asInt()); - break; - default: - error(thread.logger(), LOC_BINOP_CALC_3, "invalid type for '-': %s", - val1.nameOfType()); - break; - } - break; - case BOP_TIMES: - switch(val1.variantType()){ - case ReASVariant::VT_FLOAT: - val1.setFloat(val1.asFloat() * val2.asFloat()); - break; - case ReASVariant::VT_INTEGER: - val1.setInt(val1.asInt() * val2.asInt()); - break; - default: - error(thread.logger(), LOC_BINOP_CALC_4, "invalid type for '*': %s", - val1.nameOfType()); - break; - } - break; - case BOP_DIV: - switch(val1.variantType()){ - case ReASVariant::VT_FLOAT: - val1.setFloat(val1.asFloat() / val2.asFloat()); - break; - case ReASVariant::VT_INTEGER: - val1.setInt(val1.asInt() / val2.asInt()); - break; - default: - error(thread.logger(), LOC_BINOP_CALC_5, "invalid type for '/': %s", - val1.nameOfType()); - break; - } - break; - case BOP_MOD: - switch(val1.variantType()){ - case ReASVariant::VT_FLOAT: - val1.setFloat(fmod(val1.asFloat(), val2.asFloat())); - break; - case ReASVariant::VT_INTEGER: - val1.setInt(val1.asInt() % val2.asInt()); - break; - default: - error(thread.logger(), LOC_BINOP_CALC_6, "invalid type for '%': %s", - val1.nameOfType()); - break; - } - break; - case BOP_POWER: - switch(val1.variantType()){ - case ReASVariant::VT_FLOAT: - val1.setFloat(fmod(val1.asFloat(), val2.asFloat())); - break; - default: - error(thread.logger(), LOC_BINOP_CALC_7, "invalid type for '**': %s", - val1.nameOfType()); - break; - } - break; - case BOP_LOG_OR: - switch(val1.variantType()){ - case ReASVariant::VT_BOOL: - val1.setBool(val1.asBool() || val2.asBool()); - break; - default: - error(thread.logger(), LOC_BINOP_CALC_8, "invalid type for '||': %s", - val1.nameOfType()); - break; - } - break; - case BOP_LOG_AND: - switch(val1.variantType()){ - case ReASVariant::VT_BOOL: - val1.setBool(val1.asBool() && val2.asBool()); - break; - default: - error(thread.logger(), LOC_BINOP_CALC_9, "invalid type for '&&': %s", - val1.nameOfType()); - break; - } - break; - case BOP_LOG_XOR: - switch(val1.variantType()){ - case ReASVariant::VT_BOOL: - val1.setBool(val1.asBool() != val2.asBool()); - break; - default: - error(thread.logger(), LOC_BINOP_CALC_9, "invalid type for '^^': %s", - val1.nameOfType()); - break; - } - break; - case BOP_BIT_OR: - switch(val1.variantType()){ - case ReASVariant::VT_INTEGER: - val1.setInt(val1.asInt() | val2.asInt()); - break; - default: - error(thread.logger(), LOC_BINOP_CALC_10, "invalid type for '|': %s", - val1.nameOfType()); - break; - } - break; - case BOP_BIT_AND: - switch(val1.variantType()){ - case ReASVariant::VT_INTEGER: - val1.setInt(val1.asInt() & val2.asInt()); - break; - default: - error(thread.logger(), LOC_BINOP_CALC_11, "invalid type for '&': %s", - val1.nameOfType()); - break; - } - break; - case BOP_BIT_XOR: - switch(val1.variantType()){ - case ReASVariant::VT_INTEGER: - val1.setInt(val1.asInt() ^ val2.asInt()); - break; - default: - error(thread.logger(), LOC_BINOP_CALC_12, "invalid type for '^': %s", - val1.nameOfType()); - break; - } - break; +void ReASBinaryOp::calc(ReVMThread& thread){ + if (isAssignment()) + assign(thread); + else{ + ReASCalculable* op1 = dynamic_cast (m_child); + ReASCalculable* op2 = dynamic_cast (m_child2); + if (op1 == NULL || op2 == NULL) + error(thread.logger(), LOC_BINOP_CALC_1, "operand is null: %d / %d", + m_child == NULL ? 0 : m_child->id(), + m_child2 == NULL ? 0 : m_child2->id()); + else{ + op1->calc(thread); + op2->calc(thread); + ReASVariant& val1 = thread.top2OfValues(); + ReASVariant& val2 = thread.topOfValues(); + switch (m_operator) { + case BOP_PLUS: + switch (val1.variantType()) { + case ReASVariant::VT_FLOAT: + val1.setFloat(val1.asFloat() + val2.asFloat()); + break; + case ReASVariant::VT_INTEGER: + val1.setInt(val1.asInt() + val2.asInt()); + break; + case ReASVariant::VT_OBJECT: + //if (val1.getClass() == ReASString::m_instance) + default: + error(thread.logger(), LOC_BINOP_CALC_2, + "invalid type for '+': %s", val1.nameOfType()); + break; + } + break; + case BOP_MINUS: + switch (val1.variantType()) { + case ReASVariant::VT_FLOAT: + val1.setFloat(val1.asFloat() - val2.asFloat()); + break; + case ReASVariant::VT_INTEGER: + val1.setInt(val1.asInt() - val2.asInt()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_3, + "invalid type for '-': %s", val1.nameOfType()); + break; + } + break; + case BOP_TIMES: + switch (val1.variantType()) { + case ReASVariant::VT_FLOAT: + val1.setFloat(val1.asFloat() * val2.asFloat()); + break; + case ReASVariant::VT_INTEGER: + val1.setInt(val1.asInt() * val2.asInt()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_4, + "invalid type for '*': %s", val1.nameOfType()); + break; + } + break; + case BOP_DIV: + switch (val1.variantType()) { + case ReASVariant::VT_FLOAT: + val1.setFloat(val1.asFloat() / val2.asFloat()); + break; + case ReASVariant::VT_INTEGER: + val1.setInt(val1.asInt() / val2.asInt()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_5, + "invalid type for '/': %s", val1.nameOfType()); + break; + } + break; + case BOP_MOD: + switch (val1.variantType()) { + case ReASVariant::VT_FLOAT: + val1.setFloat(fmod(val1.asFloat(), val2.asFloat())); + break; + case ReASVariant::VT_INTEGER: + val1.setInt(val1.asInt() % val2.asInt()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_6, + "invalid type for '%': %s", val1.nameOfType()); + break; + } + break; + case BOP_POWER: + switch (val1.variantType()) { + case ReASVariant::VT_FLOAT: + val1.setFloat(fmod(val1.asFloat(), val2.asFloat())); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_7, + "invalid type for '**': %s", val1.nameOfType()); + break; + } + break; + case BOP_LOG_OR: + switch (val1.variantType()) { + case ReASVariant::VT_BOOL: + val1.setBool(val1.asBool() || val2.asBool()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_8, + "invalid type for '||': %s", val1.nameOfType()); + break; + } + break; + case BOP_LOG_AND: + switch (val1.variantType()) { + case ReASVariant::VT_BOOL: + val1.setBool(val1.asBool() && val2.asBool()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_9, + "invalid type for '&&': %s", val1.nameOfType()); + break; + } + break; + case BOP_LOG_XOR: + switch (val1.variantType()) { + case ReASVariant::VT_BOOL: + val1.setBool(val1.asBool() != val2.asBool()); + break; default: - break; + error(thread.logger(), LOC_BINOP_CALC_9, + "invalid type for '^^': %s", val1.nameOfType()); + break; } - thread.popValue(); - } - } + break; + case BOP_BIT_OR: + switch (val1.variantType()) { + case ReASVariant::VT_INTEGER: + val1.setInt(val1.asInt() | val2.asInt()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_10, + "invalid type for '|': %s", val1.nameOfType()); + break; + } + break; + case BOP_BIT_AND: + switch (val1.variantType()) { + case ReASVariant::VT_INTEGER: + val1.setInt(val1.asInt() & val2.asInt()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_11, + "invalid type for '&': %s", val1.nameOfType()); + break; + } + break; + case BOP_BIT_XOR: + switch (val1.variantType()) { + case ReASVariant::VT_INTEGER: + val1.setInt(val1.asInt() ^ val2.asInt()); + break; + default: + error(thread.logger(), LOC_BINOP_CALC_12, + "invalid type for '^': %s", val1.nameOfType()); + break; + } + break; + default: + break; + } + thread.popValue(); + } + } } /** @@ -3299,9 +3069,9 @@ void ReASBinaryOp::calc(ReVMThread& thread) * @return true: node is correct
* false: otherwise */ -bool ReASBinaryOp::check(ReParser& parser) -{ - return false; +bool ReASBinaryOp::check(ReParser& parser){ + RE_UNUSED(&parser); + return false; } /** @@ -3309,9 +3079,8 @@ bool ReASBinaryOp::check(ReParser& parser) * * @return the operator */ -ReASBinaryOp::BinOperator ReASBinaryOp::getOperator() const -{ - return m_operator; +ReASBinaryOp::BinOperator ReASBinaryOp::getOperator() const{ + return m_operator; } /** @@ -3319,9 +3088,8 @@ ReASBinaryOp::BinOperator ReASBinaryOp::getOperator() const * * @param op the operator */ -void ReASBinaryOp::setOperator(BinOperator op) -{ - m_operator = op; +void ReASBinaryOp::setOperator(BinOperator op){ + m_operator = op; } /** * @brief Writes the internals into a file. @@ -3329,21 +3097,19 @@ void ReASBinaryOp::setOperator(BinOperator op) * @param writer writes to output * @param indent nesting level */ -void ReASBinaryOp::dump(ReWriter& writer, int indent) -{ +void ReASBinaryOp::dump(ReWriter& writer, int indent){ - const QByteArray& opName = nameOfOp(m_operator); - char buffer[256]; - writer.formatIndented(indent, "BinOp id: %d op: %s (%d) left: %d right: %d %s", - m_id, - opName.constData(), m_operator, - m_child == NULL ? 0 : m_child->id(), - m_child2 == NULL ? 0 : m_child2->id(), - positionStr(buffer, sizeof buffer)); - if (indent < 32 && m_child != NULL) - m_child->dump(writer, indent + 1); - if (indent < 32 && m_child2 != NULL) - m_child2->dump(writer, indent + 1); + const QByteArray& opName = nameOfOp(m_operator); + char buffer[256]; + writer.formatIndented(indent, + "BinOp id: %d op: %s (%d) left: %d right: %d %s", m_id, + opName.constData(), m_operator, m_child == NULL ? 0 : m_child->id(), + m_child2 == NULL ? 0 : m_child2->id(), + positionStr(buffer, sizeof buffer)); + if (indent < 32 && m_child != NULL) + m_child->dump(writer, indent + 1); + if (indent < 32 && m_child2 != NULL) + m_child2->dump(writer, indent + 1); } /** @@ -3351,40 +3117,39 @@ void ReASBinaryOp::dump(ReWriter& writer, int indent) * * @param thread */ -void ReASBinaryOp::assign(ReVMThread& thread) -{ - ReASVariant& rValue = thread.lValue(m_child); - ReASCalculable* expr = dynamic_cast(m_child2); - if (expr == NULL) - error(thread.logger(), LOC_BINOP_1, "not a calculable: id: %d", - m_child2 == NULL ? 0 : m_child2->id()); - else { - ReASVariant& value = thread.popValue(); - switch(m_operator){ - case BOP_ASSIGN: - break; - case BOP_PLUS_ASSIGN: - //switch(value.variantType()){ - - //} - break; - case BOP_MINUS_ASSIGN: - case BOP_TIMES_ASSIGN: - case BOP_DIV_ASSIGN: - case BOP_MOD_ASSIGN: - case BOP_POWER_ASSIGN: - case BOP_LOG_OR_ASSIGN: - case BOP_LOG_AND_ASSIGN: - case BOP_LOG_XOR_ASSIGN: - case BOP_BIT_OR_ASSIGN: - case BOP_BIT_AND_ASSIGN: - case BOP_BIT_XOR_ASSIGN: - break; - default: - break; - } - rValue.copyValue(value); - } +void ReASBinaryOp::assign(ReVMThread& thread){ + ReASVariant& rValue = thread.lValue(m_child); + ReASCalculable* expr = dynamic_cast (m_child2); + if (expr == NULL) + error(thread.logger(), LOC_BINOP_1, "not a calculable: id: %d", + m_child2 == NULL ? 0 : m_child2->id()); + else{ + ReASVariant& value = thread.popValue(); + switch (m_operator) { + case BOP_ASSIGN: + break; + case BOP_PLUS_ASSIGN: + //switch(value.variantType()){ + + //} + break; + case BOP_MINUS_ASSIGN: + case BOP_TIMES_ASSIGN: + case BOP_DIV_ASSIGN: + case BOP_MOD_ASSIGN: + case BOP_POWER_ASSIGN: + case BOP_LOG_OR_ASSIGN: + case BOP_LOG_AND_ASSIGN: + case BOP_LOG_XOR_ASSIGN: + case BOP_BIT_OR_ASSIGN: + case BOP_BIT_AND_ASSIGN: + case BOP_BIT_XOR_ASSIGN: + break; + default: + break; + } + rValue.copyValue(value); + } } /** * @brief Returns the name (a string) of a binary operator. @@ -3393,124 +3158,124 @@ void ReASBinaryOp::assign(ReVMThread& thread) * * @return the name of the operator */ -const char* ReASBinaryOp::nameOfOp(ReASBinaryOp::BinOperator op) -{ - const char* rc; - switch (op){ - case BOP_ASSIGN: - rc = "="; - break; - case BOP_PLUS_ASSIGN: - rc = "+="; - break; - case BOP_MINUS_ASSIGN: - rc = "-="; - break; - case BOP_TIMES_ASSIGN: - rc = "*="; - break; - case BOP_DIV_ASSIGN: - rc = "/="; - break; - case BOP_MOD_ASSIGN: - rc = "%="; - break; - case BOP_POWER_ASSIGN: - rc = "**="; - break; - case BOP_LOG_OR_ASSIGN: - rc = "||="; - break; - case BOP_LOG_AND_ASSIGN: - rc = "&&="; - break; - case BOP_LOG_XOR_ASSIGN: - rc = "^^="; - break; - case BOP_BIT_OR_ASSIGN: - rc = "|="; - break; - case BOP_BIT_AND_ASSIGN: - rc = "&="; - break; - case BOP_BIT_XOR_ASSIGN: - rc = "^="; - break; - case BOP_LSHIFT_ASSIGN: - rc = "<<="; - break; - case BOP_LOG_RSHIFT_ASSIGN: - rc = ">>="; - break; - case BOP_ARTITH_RSHIFT_ASSIGN: - rc = ">>>="; - break; - case BOP_PLUS: - rc = "+"; - break; - case BOP_MINUS: - rc = "-"; - break; - case BOP_TIMES: - rc = "*"; - break; - case BOP_DIV: - rc = "/"; - break; - case BOP_MOD: - rc = "%"; - break; - case BOP_POWER: - rc = "**"; - break; - case BOP_LOG_OR: - rc = "||"; - break; - case BOP_LOG_AND: - rc = "&&"; - break; - case BOP_LOG_XOR: - rc = "^^"; - break; - case BOP_BIT_OR: - rc = "|"; - break; - case BOP_BIT_AND: - rc = "&"; - break; - case BOP_BIT_XOR: - rc = "^"; - break; - case BOP_LSHIFT: - rc = ""; break; - case BOP_LOG_RSHIFT: - rc = ">>"; - break; - case BOP_ARTITH_RSHIFT: - rc = ">>>"; - break; - case BOP_EQ: - rc = "=="; - break; - case BOP_NE: - rc = "!="; - break; - case BOP_LE: - rc = "<="; - break; - case BOP_LT: - rc = "<"; - break; - case BOP_GE: - rc = ">="; - break; - case BOP_GT: - rc = ">"; - break; - default: - throw ReException("unknown binary op %d", (int) op); - } - return rc; +const char* ReASBinaryOp::nameOfOp(ReASBinaryOp::BinOperator op){ + const char* rc; + switch (op) { + case BOP_ASSIGN: + rc = "="; + break; + case BOP_PLUS_ASSIGN: + rc = "+="; + break; + case BOP_MINUS_ASSIGN: + rc = "-="; + break; + case BOP_TIMES_ASSIGN: + rc = "*="; + break; + case BOP_DIV_ASSIGN: + rc = "/="; + break; + case BOP_MOD_ASSIGN: + rc = "%="; + break; + case BOP_POWER_ASSIGN: + rc = "**="; + break; + case BOP_LOG_OR_ASSIGN: + rc = "||="; + break; + case BOP_LOG_AND_ASSIGN: + rc = "&&="; + break; + case BOP_LOG_XOR_ASSIGN: + rc = "^^="; + break; + case BOP_BIT_OR_ASSIGN: + rc = "|="; + break; + case BOP_BIT_AND_ASSIGN: + rc = "&="; + break; + case BOP_BIT_XOR_ASSIGN: + rc = "^="; + break; + case BOP_LSHIFT_ASSIGN: + rc = "<<="; + break; + case BOP_LOG_RSHIFT_ASSIGN: + rc = ">>="; + break; + case BOP_ARTITH_RSHIFT_ASSIGN: + rc = ">>>="; + break; + case BOP_PLUS: + rc = "+"; + break; + case BOP_MINUS: + rc = "-"; + break; + case BOP_TIMES: + rc = "*"; + break; + case BOP_DIV: + rc = "/"; + break; + case BOP_MOD: + rc = "%"; + break; + case BOP_POWER: + rc = "**"; + break; + case BOP_LOG_OR: + rc = "||"; + break; + case BOP_LOG_AND: + rc = "&&"; + break; + case BOP_LOG_XOR: + rc = "^^"; + break; + case BOP_BIT_OR: + rc = "|"; + break; + case BOP_BIT_AND: + rc = "&"; + break; + case BOP_BIT_XOR: + rc = "^"; + break; + case BOP_LSHIFT: + rc = ""; + break; + case BOP_LOG_RSHIFT: + rc = ">>"; + break; + case BOP_ARTITH_RSHIFT: + rc = ">>>"; + break; + case BOP_EQ: + rc = "=="; + break; + case BOP_NE: + rc = "!="; + break; + case BOP_LE: + rc = "<="; + break; + case BOP_LT: + rc = "<"; + break; + case BOP_GE: + rc = ">="; + break; + case BOP_GT: + rc = ">"; + break; + default: + throw ReException("unknown binary op %d", (int) op); + } + return rc; } /** @class ReASMethod rplastree.hpp "rplexpr/rplastree.hpp" @@ -3529,14 +3294,13 @@ const char* ReASBinaryOp::nameOfOp(ReASBinaryOp::BinOperator op) * @param tree the abstract syntax tree */ ReASMethod::ReASMethod(const QByteArray& name, ReASTree& tree) : - ReASNode2(AST_METHOD), - m_name(name), - m_resultType(NULL), - m_symbols(NULL), - m_sibling(NULL), - m_tree(tree), - firstParamWithDefault(-1) -{ + ReASNode2(AST_METHOD), + m_name(name), + m_resultType(NULL), + m_symbols(NULL), + m_sibling(NULL), + m_tree(tree), + firstParamWithDefault(-1){ } /** @@ -3546,9 +3310,9 @@ ReASMethod::ReASMethod(const QByteArray& name, ReASTree& tree) : * @return true: node is correct
* false: otherwise */ -bool ReASMethod::check(ReParser& parser) -{ - return false; +bool ReASMethod::check(ReParser& parser){ + RE_UNUSED(&parser); + return false; } /** @@ -3556,62 +3320,56 @@ bool ReASMethod::check(ReParser& parser) * * This method will be never called. Must exit: Otherwise the class is abstract. */ -int ReASMethod::execute(ReVMThread& thread) -{ - return 0; +int ReASMethod::execute(ReVMThread& thread){ + RE_UNUSED(&thread); + return 0; } - /** * @brief Writes the internals of the instance into a file. * * @param writer writes to output * @param indent nesting level */ -void ReASMethod::dump(ReWriter& writer, int indent) -{ - - char buffer[256]; - writer.indent(indent); - writer.format("Method %s %s(", - m_resultType == NULL ? "" : m_resultType->name().constData(), - m_name.constData()); - ReSymbolSpace* parent = m_symbols->parent(); - writer.formatLine(") id: %d parent: %s args: %d body: %d %s", m_id, - parent == NULL ? "" : parent->name().constData(), - m_child2 == NULL ? 0 : m_child2->id(), - m_child->id(), - positionStr(buffer, sizeof buffer)); - if (m_child2 != NULL) - m_child2->dump(writer, indent + 1); - dumpStatements(writer, indent + 1, m_child); - m_symbols->dump(writer, indent + 1); +void ReASMethod::dump(ReWriter& writer, int indent){ + + char buffer[256]; + writer.indent(indent); + writer.format("Method %s %s(", + m_resultType == NULL ? "" : m_resultType->name().constData(), + m_name.constData()); + ReSymbolSpace* parent = m_symbols->parent(); + writer.formatLine(") id: %d parent: %s args: %d body: %d %s", m_id, + parent == NULL ? "" : parent->name().constData(), + m_child2 == NULL ? 0 : m_child2->id(), m_child->id(), + positionStr(buffer, sizeof buffer)); + if (m_child2 != NULL) + m_child2->dump(writer, indent + 1); + dumpStatements(writer, indent + 1, m_child); + m_symbols->dump(writer, indent + 1); } /** * @brief Returns the symbol space of the instance. * * @return the symbol space */ -ReSymbolSpace* ReASMethod::symbols() const -{ - return m_symbols; +ReSymbolSpace* ReASMethod::symbols() const{ + return m_symbols; } /** * @brief Sets the symbol space from the current of the tree. */ -void ReASMethod::setSymbols() -{ - m_symbols = m_tree.currentSpace(); +void ReASMethod::setSymbols(){ + m_symbols = m_tree.currentSpace(); } /** * @brief Returns the name of the method * @return the name */ -const QByteArray& ReASMethod::name() const -{ - return m_name; +const QByteArray& ReASMethod::name() const{ + return m_name; } /** @@ -3620,23 +3378,25 @@ const QByteArray& ReASMethod::name() const * @return true: same signature
* false: otherwise */ -bool ReASMethod::equalSignature(ReASMethod& other) const -{ - bool rc = true; - ReASExprStatement* args = dynamic_cast(m_child2); - ReASExprStatement* otherArgs = dynamic_cast(other.child2()); - - while(rc && (args != NULL || otherArgs != NULL)){ - if (args == NULL || otherArgs == NULL) +bool ReASMethod::equalSignature(ReASMethod& other) const{ + bool rc = true; + ReASExprStatement* args = dynamic_cast (m_child2); + ReASExprStatement* otherArgs = + dynamic_cast (other.child2()); + + while (rc && (args != NULL || otherArgs != NULL)){ + if (args == NULL || otherArgs == NULL) + rc = false; + else{ + ReASVarDefinition* def = + dynamic_cast (args->child2()); + ReASVarDefinition* defOther = + dynamic_cast (otherArgs->child2()); + if (def->clazz() != defOther->clazz()) rc = false; - else { - ReASVarDefinition* def = dynamic_cast(args->child2()); - ReASVarDefinition* defOther = dynamic_cast(otherArgs->child2()); - if (def->clazz() != defOther->clazz()) - rc = false; - } - } - return rc; + } + } + return rc; } /** * @brief Returns the next overloaded method. @@ -3644,9 +3404,8 @@ bool ReASMethod::equalSignature(ReASMethod& other) const * @return NULL: no other method available
* otherwise: the next method with the same name but another signature */ -ReASMethod* ReASMethod::sibling() const -{ - return m_sibling; +ReASMethod* ReASMethod::sibling() const{ + return m_sibling; } /** @@ -3654,9 +3413,8 @@ ReASMethod* ReASMethod::sibling() const * * @param sibling another method with the same name but another signature */ -void ReASMethod::setSibling(ReASMethod* sibling) -{ - m_sibling = sibling; +void ReASMethod::setSibling(ReASMethod* sibling){ + m_sibling = sibling; } /** * @brief Returns the index of the first parameter with a default value. @@ -3664,21 +3422,17 @@ void ReASMethod::setSibling(ReASMethod* sibling) * @return -1: no parameter has a default value
* otherwise: the index of the first parameter with a default */ -int ReASMethod::getFirstParamWithDefault() const -{ - return firstParamWithDefault; +int ReASMethod::getFirstParamWithDefault() const{ + return firstParamWithDefault; } /** * @brief Sets the index of the first parameter with default value * @param value */ -void ReASMethod::setFirstParamWithDefault(int value) -{ - firstParamWithDefault = value; +void ReASMethod::setFirstParamWithDefault(int value){ + firstParamWithDefault = value; } - - /** @class ReASField rplastree.hpp "rplexpr/rplastree.hpp" * * @brief Implements an class field for the Abstract Syntax Tree. @@ -3692,9 +3446,7 @@ void ReASMethod::setFirstParamWithDefault(int value) * @param name name of the field */ ReASField::ReASField(const QByteArray& name) : - ReASNode1(AST_FIELD), - m_name(name) -{ + ReASNode1(AST_FIELD), m_name(name){ } /** @@ -3704,9 +3456,9 @@ ReASField::ReASField(const QByteArray& name) : * @return true: node is correct
* false: otherwise */ -bool ReASField::check(ReParser& parser) -{ - return false; +bool ReASField::check(ReParser& parser){ + RE_UNUSED(&parser); + return false; } /** @@ -3715,14 +3467,11 @@ bool ReASField::check(ReParser& parser) * @param writer writes to output * @param indent nesting level */ -void ReASField::dump(ReWriter& writer, int indent) -{ - char buffer[256]; - writer.formatIndented(indent, "field %s id: %d parent: %d succ: %s", - m_name.constData(), m_id, - m_child == NULL ? 0 : m_child->id(), - positionStr(buffer, sizeof buffer)); - m_child->dump(writer, indent + 1); +void ReASField::dump(ReWriter& writer, int indent){ + char buffer[256]; + writer.formatIndented(indent, "field %s id: %d parent: %d succ: %s", + m_name.constData(), m_id, m_child == NULL ? 0 : m_child->id(), + positionStr(buffer, sizeof buffer)); + m_child->dump(writer, indent + 1); } - diff --git a/expr/ReASTree.hpp b/expr/ReASTree.hpp index f7ec9f1..5f6fa9c 100644 --- a/expr/ReASTree.hpp +++ b/expr/ReASTree.hpp @@ -1,53 +1,55 @@ /* - * Licence: + * ReASTree.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtwriterl.net/. - * The original sources can be found on https://github.com/republib. -*/ - + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #ifndef RPLASTREE_HPP #define RPLASTREE_HPP enum ReASItemType { - AST_UNDEF, - AST_CONSTANT, - AST_LIST_CONSTANT, - AST_LIST_ENTRY, - AST_MAP_CONSTANT, - AST_MAP_ENTRY, - AST_NAMED_VALUE, - AST_CONVERSION, - AST_INDEXED_VALUE, - AST_FIELD, - AST_VAR_DEFINITION, - AST_EXPR_STATEMENT, - AST_METHOD, - AST_ARGUMENT, - AST_INTRINSIC_METHOD, - AST_PRE_UNARY_OP, - AST_POST_UNARY_OP, - AST_BINARY_OP, - AST_METHOD_CALL, - AST_WHILE, - AST_REPEAT, - AST_IF, - AST_CONDITION, - AST_ITERATED_FOR, - AST_COUNTED_FOR, - AST_SWITCH, - AST_LEAVE, - AST_CONTINUE -}; - -class ReASException : public ReException { -public: - ReASException(); - ReASException(const ReSourcePosition* position, const char* format, ...); + AST_UNDEF, + AST_CONSTANT, + AST_LIST_CONSTANT, + AST_LIST_ENTRY, + AST_MAP_CONSTANT, + AST_MAP_ENTRY, + AST_NAMED_VALUE, + AST_CONVERSION, + AST_INDEXED_VALUE, + AST_FIELD, + AST_VAR_DEFINITION, + AST_EXPR_STATEMENT, + AST_METHOD, + AST_ARGUMENT, + AST_INTRINSIC_METHOD, + AST_PRE_UNARY_OP, + AST_POST_UNARY_OP, + AST_BINARY_OP, + AST_METHOD_CALL, + AST_WHILE, + AST_REPEAT, + AST_IF, + AST_CONDITION, + AST_ITERATED_FOR, + AST_COUNTED_FOR, + AST_SWITCH, + AST_LEAVE, + AST_CONTINUE +}; + +class ReASException: public ReException { +public: + ReASException(); + ReASException(const ReSourcePosition* position, const char* format, ...); protected: - void build(const ReSourcePosition* position, const char* format, - va_list varList); + void build(const ReSourcePosition* position, const char* format, + va_list varList); }; class ReASClass; @@ -56,704 +58,663 @@ class ReASItem; class ReASCondition; class ReASVariant { - /* The VM uses some tricks (performance): Therefore this class + /* The VM uses some tricks (performance): Therefore this class * must not be virtual! */ public: - enum VariantType { - VT_UNDEF, - VT_FLOAT, - VT_INTEGER, - VT_BOOL, - VT_OBJECT - }; - enum VariantFlags { - VF_UNDEF, - /// if DT_OBJECT: object is a copy, don't free at method end - VF_IS_COPY = 1 << 1, - /// debugger: action if changed - VF_WATCH_POINT = 1 << 2 - }; - - friend class ReASCondition; -public: - ReASVariant(); - ~ReASVariant(); - ReASVariant(const ReASVariant& source); - ReASVariant& operator=(const ReASVariant& source); - qreal asFloat() const; - int asInt() const; - bool asBool() const; - void* asObject(const ReASClass** clazz) const; - const QByteArray* asString() const; - void setFloat(qreal number); - void setInt(int integer); - void setBool(bool value); - void setObject(void* object, const ReASClass* clazz); - void setString(const QByteArray& string); - QByteArray toString(int maxLength = 80) const; - VariantType variantType() const; - const char* nameOfType() const; - const ReASClass* getClass() const; - void copyValue(const ReASVariant& source); - void destroyValue(); + enum VariantType { + VT_UNDEF, VT_FLOAT, VT_INTEGER, VT_BOOL, VT_OBJECT + }; + enum VariantFlags { + VF_UNDEF, + /// if DT_OBJECT: object is a copy, don't free at method end + VF_IS_COPY = 1 << 1, + /// debugger: action if changed + VF_WATCH_POINT = 1 << 2 + }; + + friend class ReASCondition; +public: + ReASVariant(); + ~ReASVariant(); + ReASVariant(const ReASVariant& source); + ReASVariant& operator=(const ReASVariant& source); + qreal asFloat() const; + int asInt() const; + bool asBool() const; + void* asObject(const ReASClass** clazz) const; + const QByteArray* asString() const; + void setFloat(qreal number); + void setInt(int integer); + void setBool(bool value); + void setObject(void* object, const ReASClass* clazz); + void setString(const QByteArray& string); + QByteArray toString(int maxLength = 80) const; + VariantType variantType() const; + const char* nameOfType() const; + const ReASClass* getClass() const; + void copyValue(const ReASVariant& source); + void destroyValue(); private: - VariantType m_variantType:8; - /// bitmap of VF_... flags: - int m_flags:8; - union { - qreal m_float; - int m_int; - bool m_bool; - void* m_object; - } m_value; - const ReASClass* m_class; + VariantType m_variantType :8; + /// bitmap of VF_... flags: + int m_flags :8; + union { + qreal m_float; + int m_int; + bool m_bool; + void* m_object; + } m_value; + const ReASClass* m_class; }; class ReASTree; class ReParser; class ReVMThread; -class ReASItem -{ -public: - enum NodeFlags { - NF_UNDEF, - /// the node calculates a value: - NF_CALCULABLE = 1 << 1, - /// the node calculates a value: - NF_STATEMENT = 1 << 2, - /// the tree under this node is complete checked for data type correctness - NF_TYPECHECK_COMPLETE = 1 << 3, - /// debugger: this node is a breakpoint - NF_BREAKPOINT = 1 << 5 - }; - -public: - friend class ReASTree; - ReASItem(ReASItemType type); - virtual ~ReASItem(); -public: - virtual bool check(ReParser& parser) = 0; -public: - bool checkAsCalculable(const char* description, ReASClass* expectedClass, - ReParser& parser); - const ReSourcePosition* position() const; - void setPosition(const ReSourcePosition* position); - unsigned int id() const; - char* positionStr(char buffer[], size_t bufferSize) const; - void error(ReLogger* logger, int location, const char* format, ...); -public: - /** - * @brief Writes the content of the instance into an output medium. - * - * @param writer writes to output media - * @param indent nesting level: so many tabs will be used as prefix - */ - virtual void dump(ReWriter& writer,int indent) = 0; -public: - static void reset(); - static bool checkStatementList(ReASItem* list, ReParser& parser); - static int calcAsInteger(ReASItem* expr, ReVMThread& thread); - static bool calcAsBoolean(ReASItem* expr, ReVMThread& thread); -public: - ReASItemType nodeType() const; - const char* nameOfItemType() const; - - int flags() const; - void setFlags(int flags); - - bool typeCheck(ReASClass* clazz1, ReASClass* clazz2); - bool error(int location, ReParser& parser, const char* format, ...); - bool ensureError(ReParser& parser, const char* info); +class ReASItem { +public: + enum NodeFlags { + NF_UNDEF, + /// the node calculates a value: + NF_CALCULABLE = 1 << 1, + /// the node calculates a value: + NF_STATEMENT = 1 << 2, + /// the tree under this node is complete checked for data type correctness + NF_TYPECHECK_COMPLETE = 1 << 3, + /// debugger: this node is a breakpoint + NF_BREAKPOINT = 1 << 5 + }; + +public: + friend class ReASTree; + ReASItem(ReASItemType type); + virtual ~ReASItem(); +public: + virtual bool check(ReParser& parser) = 0; +public: + bool checkAsCalculable(const char* description, ReASClass* expectedClass, + ReParser& parser); + const ReSourcePosition* position() const; + void setPosition(const ReSourcePosition* position); + unsigned int id() const; + char* positionStr(char buffer[], size_t bufferSize) const; + void error(ReLogger* logger, int location, const char* format, ...); +public: + /** + * @brief Writes the content of the instance into an output medium. + * + * @param writer writes to output media + * @param indent nesting level: so many tabs will be used as prefix + */ + virtual void dump(ReWriter& writer, int indent) = 0; +public: + static void reset(); + static bool checkStatementList(ReASItem* list, ReParser& parser); + static int calcAsInteger(ReASItem* expr, ReVMThread& thread); + static bool calcAsBoolean(ReASItem* expr, ReVMThread& thread); +public: + ReASItemType nodeType() const; + const char* nameOfItemType() const; + + int flags() const; + void setFlags(int flags); + + bool typeCheck(ReASClass* clazz1, ReASClass* clazz2); + bool error(int location, ReParser& parser, const char* format, ...); + bool ensureError(ReParser& parser, const char* info); protected: - unsigned int m_id:16; - ReASItemType m_nodeType:8; - int m_flags:5; - int m_dataType: 3; - const ReSourcePosition* m_position; + unsigned int m_id :16; + ReASItemType m_nodeType :8; + int m_flags :5; + int m_dataType :3; + const ReSourcePosition* m_position; private: - static unsigned int m_nextId; + static unsigned int m_nextId; }; class ReASNode1; -class ReASCalculable -{ +class ReASCalculable { public: - ReASCalculable(); + ReASCalculable(); public: - virtual void calc(ReVMThread& thread) = 0; + virtual void calc(ReVMThread& thread) = 0; public: - ReASClass* clazz() const; - void setClass(ReASClass* clazz); + ReASClass* clazz() const; + void setClass(ReASClass* clazz); protected: - ReASClass* m_class; + ReASClass* m_class; }; class ReStackFrame; -class ReASStorable : public ReASCalculable { +class ReASStorable: public ReASCalculable { }; class ReVMThread; -class ReASConstant : public ReASItem, public ReASCalculable -{ +class ReASConstant: public ReASItem, public ReASCalculable { public: - ReASConstant(); + ReASConstant(); public: - virtual void calc(ReVMThread& thread); - virtual bool check(ReParser& parser); + virtual void calc(ReVMThread& thread); + virtual bool check(ReParser& parser); public: - virtual void dump(ReWriter& writer,int indent); - ReASVariant& value(); + virtual void dump(ReWriter& writer, int indent); + ReASVariant& value(); private: - ReASVariant m_value; + ReASVariant m_value; }; - -class ReASNode1 : public ReASItem -{ +class ReASNode1: public ReASItem { public: - ReASNode1(ReASItemType type); - virtual ~ReASNode1(); + ReASNode1(ReASItemType type); + virtual ~ReASNode1(); public: - ReASItem* child() const; - void setChild(ReASItem* child); + ReASItem* child() const; + void setChild(ReASItem* child); public: - static void dumpStatements(ReWriter& writer, int indent, ReASItem* statements); + static void dumpStatements(ReWriter& writer, int indent, + ReASItem* statements); protected: - ReASItem* m_child; + ReASItem* m_child; }; -class ReASNode2 : public ReASNode1 -{ +class ReASNode2: public ReASNode1 { public: - ReASNode2(ReASItemType type); - virtual ~ReASNode2(); + ReASNode2(ReASItemType type); + virtual ~ReASNode2(); public: - ReASItem* child2() const; - void setChild2(ReASItem* child2); + ReASItem* child2() const; + void setChild2(ReASItem* child2); protected: - ReASItem* m_child2; + ReASItem* m_child2; }; -class ReASNode3 : public ReASNode2 -{ +class ReASNode3: public ReASNode2 { public: - ReASNode3(ReASItemType type); - virtual ~ReASNode3(); + ReASNode3(ReASItemType type); + virtual ~ReASNode3(); public: - ReASItem* child3() const; - void setChild3(ReASItem* child3); + ReASItem* child3() const; + void setChild3(ReASItem* child3); protected: - ReASItem* m_child3; + ReASItem* m_child3; }; -class ReASNode4 : public ReASNode3 -{ +class ReASNode4: public ReASNode3 { public: - ReASNode4(ReASItemType type); - virtual ~ReASNode4(); + ReASNode4(ReASItemType type); + virtual ~ReASNode4(); public: - ReASItem* child4() const; - void setChild4(ReASItem* child4); + ReASItem* child4() const; + void setChild4(ReASItem* child4); protected: - ReASItem* m_child4; + ReASItem* m_child4; }; -class ReASNode5 : public ReASNode4 -{ +class ReASNode5: public ReASNode4 { public: - ReASNode5(ReASItemType type); - virtual ~ReASNode5(); + ReASNode5(ReASItemType type); + virtual ~ReASNode5(); public: - ReASItem*child5() const; - void setChild5(ReASItem* child5); + ReASItem*child5() const; + void setChild5(ReASItem* child5); protected: - ReASItem* m_child5; + ReASItem* m_child5; }; -class ReASNode6 : public ReASNode5 -{ +class ReASNode6: public ReASNode5 { public: - ReASNode6(ReASItemType type); - virtual ~ReASNode6(); + ReASNode6(ReASItemType type); + virtual ~ReASNode6(); public: - ReASItem*child6() const; - void setChild6(ReASItem* child5); + ReASItem*child6() const; + void setChild6(ReASItem* child5); protected: - ReASItem* m_child6; + ReASItem* m_child6; }; -typedef QList ReASListOfVariants; -typedef QMap ReASMapOfVariants; +typedef QList ReASListOfVariants; +typedef QMap ReASMapOfVariants; -class ReASListConstant : public ReASNode1, public ReASCalculable -{ +class ReASListConstant: public ReASNode1, public ReASCalculable { public: - ReASListConstant(); + ReASListConstant(); public: - virtual void calc(ReVMThread& thread); - virtual bool check(ReParser& parser); + virtual void calc(ReVMThread& thread); + virtual bool check(ReParser& parser); public: - virtual void dump(ReWriter& writer,int indent); - ReASVariant& value(); - ReASListOfVariants* list(); + virtual void dump(ReWriter& writer, int indent); + ReASVariant& value(); + ReASListOfVariants* list(); private: - ReASVariant m_value; + ReASVariant m_value; }; -class ReASMapConstant : public ReASNode1, public ReASCalculable -{ +class ReASMapConstant: public ReASNode1, public ReASCalculable { public: - ReASMapConstant(); + ReASMapConstant(); public: - virtual void calc(ReVMThread& thread); - virtual bool check(ReParser& parser); + virtual void calc(ReVMThread& thread); + virtual bool check(ReParser& parser); public: - virtual void dump(ReWriter& writer,int indent); - ReASVariant& value(); - ReASMapOfVariants* map(); + virtual void dump(ReWriter& writer, int indent); + ReASVariant& value(); + ReASMapOfVariants* map(); private: - ReASVariant m_value; + ReASVariant m_value; }; class ReSymbolSpace; -class ReASNamedValue : public ReASItem, public ReASStorable -{ - friend class ReASVarDefinition; -public: - enum Attributes { - A_NONE, - /// the value cannot be changed. - A_CONST = 1<<1, - /// the variable/constant is found in the global namespace, not in a method - A_GLOBAL = 1<<2, - /// the variable/constant is found in the module namespace, not in a method - A_MODULE_STATIC = 1<<3, - /// the evaluation should be lazy - A_LAZY = 1<<4, - /// parameter of a method - A_PARAM = 1<<5, - /// a automatic variable in counted for loops: - A_LOOP = 1<<6 - }; - -public: - ReASNamedValue(ReASClass* clazz, ReSymbolSpace* space, - const QByteArray& name, int attributes); -public: - virtual void calc(ReVMThread& thread); - virtual bool check(ReParser& parser); -public: - const QByteArray& name() const; - void setSymbolSpace(ReSymbolSpace* space, int variableNo); - void dump(ReWriter& writer, int indent); - ReSymbolSpace* symbolSpace() const; - int variableNo() const; - void setVariableNo(int variableNo); +class ReASNamedValue: public ReASItem, public ReASStorable { + friend class ReASVarDefinition; +public: + enum Attributes { + A_NONE, + /// the value cannot be changed. + A_CONST = 1 << 1, + /// the variable/constant is found in the global namespace, not in a method + A_GLOBAL = 1 << 2, + /// the variable/constant is found in the module namespace, not in a method + A_MODULE_STATIC = 1 << 3, + /// the evaluation should be lazy + A_LAZY = 1 << 4, + /// parameter of a method + A_PARAM = 1 << 5, + /// a automatic variable in counted for loops: + A_LOOP = 1 << 6 + }; + +public: + ReASNamedValue(ReASClass* clazz, ReSymbolSpace* space, + const QByteArray& name, int attributes); +public: + virtual void calc(ReVMThread& thread); + virtual bool check(ReParser& parser); +public: + const QByteArray& name() const; + void setSymbolSpace(ReSymbolSpace* space, int variableNo); + void dump(ReWriter& writer, int indent); + ReSymbolSpace* symbolSpace() const; + int variableNo() const; + void setVariableNo(int variableNo); protected: - QByteArray m_name; - int m_attributes; - ReSymbolSpace* m_symbolSpace; - int m_variableNo; + QByteArray m_name; + int m_attributes; + ReSymbolSpace* m_symbolSpace; + int m_variableNo; }; -class ReASConversion : public ReASNode1, public ReASCalculable { +class ReASConversion: public ReASNode1, public ReASCalculable { public: - enum Conversion { - C_UNDEF, - C_INT_TO_FLOAT, - C_FLOAT_TO_INT, - C_BOOL_TO_INT, - C_BOOL_TO_FLOAT - }; + enum Conversion { + C_UNDEF, C_INT_TO_FLOAT, C_FLOAT_TO_INT, C_BOOL_TO_INT, C_BOOL_TO_FLOAT + }; public: - ReASConversion(ReASItem* expression); + ReASConversion(ReASItem* expression); public: - virtual void calc(ReVMThread& thread); - virtual bool check(ReParser& parser); - virtual void dump(ReWriter& writer,int indent); + virtual void calc(ReVMThread& thread); + virtual bool check(ReParser& parser); + virtual void dump(ReWriter& writer, int indent); public: - static ReASConversion* tryConversion(ReASClass* expected, ReASItem* expr, - ReParser& parser, bool& isCorrect); - static Conversion findConversion(ReASClass* from, ReASClass* to); + static ReASConversion* tryConversion(ReASClass* expected, ReASItem* expr, + ReParser& parser, bool& isCorrect); + static Conversion findConversion(ReASClass* from, ReASClass* to); private: - Conversion m_conversion; + Conversion m_conversion; }; -class ReASIndexedValue : public ReASNode2, public ReASCalculable { +class ReASIndexedValue: public ReASNode2, public ReASCalculable { public: - ReASIndexedValue(); + ReASIndexedValue(); public: - virtual void calc(ReVMThread& thread); - virtual bool check(ReParser& parser); + virtual void calc(ReVMThread& thread); + virtual bool check(ReParser& parser); public: - void dump(ReWriter& writer, int indent); + void dump(ReWriter& writer, int indent); }; -class ReASStatement -{ +class ReASStatement { public: - ReASStatement(); + ReASStatement(); public: - virtual int execute(ReVMThread& thread) = 0; + virtual int execute(ReVMThread& thread) = 0; public: - static int executeStatementList(ReASItem* list, ReVMThread& thread); + static int executeStatementList(ReASItem* list, ReVMThread& thread); }; - -class ReASVarDefinition : public ReASNode3, public ReASStatement -{ +class ReASVarDefinition: public ReASNode3, public ReASStatement { public: - ReASVarDefinition(); + ReASVarDefinition(); public: - virtual bool check(ReParser& parser); - virtual int execute(ReVMThread& thread); + virtual bool check(ReParser& parser); + virtual int execute(ReVMThread& thread); public: - void dump(ReWriter& writer, int indent); - const QByteArray& name() const; - int endOfScope() const; - void setEndOfScope(int endOfScope); - ReASClass* clazz() const; + void dump(ReWriter& writer, int indent); + const QByteArray& name() const; + int endOfScope() const; + void setEndOfScope(int endOfScope); + ReASClass* clazz() const; private: - /// the column of the blockend containing the definition. - /// if 0: end is end of method or end of class - /// Note: the source unit is stored in ReASItem::m_sourcePosition - int m_endOfScope; + /// the column of the blockend containing the definition. + /// if 0: end is end of method or end of class + /// Note: the source unit is stored in ReASItem::m_sourcePosition + int m_endOfScope; }; -class ReASExprStatement : public ReASNode2, public ReASStatement -{ +class ReASExprStatement: public ReASNode2, public ReASStatement { public: - ReASExprStatement(); + ReASExprStatement(); public: - virtual bool check(ReParser& parser); - virtual int execute(ReVMThread& thread); + virtual bool check(ReParser& parser); + virtual int execute(ReVMThread& thread); public: - void dump(ReWriter& writer, int indent); + void dump(ReWriter& writer, int indent); }; -class ReASUnaryOp : public ReASNode1, ReASCalculable -{ +class ReASUnaryOp: public ReASNode1, ReASCalculable { public: - enum UnaryOp { - UOP_UNDEF, - UOP_PLUS, - UOP_MINUS_INT, - UOP_MINUS_FLOAT, - UOP_NOT_BOOL, - UOP_NOT_INT, - UOP_INC, - UOP_DEC - }; + enum UnaryOp { + UOP_UNDEF, + UOP_PLUS, + UOP_MINUS_INT, + UOP_MINUS_FLOAT, + UOP_NOT_BOOL, + UOP_NOT_INT, + UOP_INC, + UOP_DEC + }; public: - ReASUnaryOp(UnaryOp op, ReASItemType type); + ReASUnaryOp(UnaryOp op, ReASItemType type); public: - virtual void calc(ReVMThread& thread); - virtual bool check(ReParser& parser); + virtual void calc(ReVMThread& thread); + virtual bool check(ReParser& parser); public: - int getOperator() const; - void dump(ReWriter& writer, int indent); + int getOperator() const; + void dump(ReWriter& writer, int indent); public: - static const char* nameOfOp(UnaryOp op); + static const char* nameOfOp(UnaryOp op); private: - UnaryOp m_operator; -}; -class ReASBinaryOp : public ReASNode2, public ReASCalculable -{ -public: - enum BinOperator { - BOP_UNDEF, - BOP_ASSIGN, - BOP_PLUS_ASSIGN, - BOP_MINUS_ASSIGN, - BOP_TIMES_ASSIGN, - BOP_DIV_ASSIGN, - BOP_MOD_ASSIGN, - BOP_POWER_ASSIGN, - BOP_LOG_OR_ASSIGN, - BOP_LOG_AND_ASSIGN, - BOP_LOG_XOR_ASSIGN, - BOP_BIT_OR_ASSIGN, - BOP_BIT_AND_ASSIGN, - BOP_BIT_XOR_ASSIGN, - BOP_LSHIFT_ASSIGN, - BOP_LOG_RSHIFT_ASSIGN, - BOP_ARTITH_RSHIFT_ASSIGN, - BOP_PLUS, - BOP_MINUS, - BOP_TIMES, - BOP_DIV, - BOP_MOD, - BOP_POWER, - BOP_LOG_OR, - BOP_LOG_AND, - BOP_LOG_XOR, - BOP_BIT_OR, - BOP_BIT_AND, - BOP_BIT_XOR, - BOP_LSHIFT, - BOP_LOG_RSHIFT, - BOP_ARTITH_RSHIFT, - BOP_EQ, - BOP_NE, - BOP_LE, - BOP_LT, - BOP_GE, - BOP_GT, - BOB_COUNT - }; + UnaryOp m_operator; +}; +class ReASBinaryOp: public ReASNode2, public ReASCalculable { +public: + enum BinOperator { + BOP_UNDEF, + BOP_ASSIGN, + BOP_PLUS_ASSIGN, + BOP_MINUS_ASSIGN, + BOP_TIMES_ASSIGN, + BOP_DIV_ASSIGN, + BOP_MOD_ASSIGN, + BOP_POWER_ASSIGN, + BOP_LOG_OR_ASSIGN, + BOP_LOG_AND_ASSIGN, + BOP_LOG_XOR_ASSIGN, + BOP_BIT_OR_ASSIGN, + BOP_BIT_AND_ASSIGN, + BOP_BIT_XOR_ASSIGN, + BOP_LSHIFT_ASSIGN, + BOP_LOG_RSHIFT_ASSIGN, + BOP_ARTITH_RSHIFT_ASSIGN, + BOP_PLUS, + BOP_MINUS, + BOP_TIMES, + BOP_DIV, + BOP_MOD, + BOP_POWER, + BOP_LOG_OR, + BOP_LOG_AND, + BOP_LOG_XOR, + BOP_BIT_OR, + BOP_BIT_AND, + BOP_BIT_XOR, + BOP_LSHIFT, + BOP_LOG_RSHIFT, + BOP_ARTITH_RSHIFT, + BOP_EQ, + BOP_NE, + BOP_LE, + BOP_LT, + BOP_GE, + BOP_GT, + BOB_COUNT + }; private: - inline bool isAssignment() const { - return m_operator >= BOP_ASSIGN - && m_operator <= BOP_ARTITH_RSHIFT_ASSIGN; - } + inline bool isAssignment() const{ + return m_operator >= BOP_ASSIGN && m_operator <= BOP_ARTITH_RSHIFT_ASSIGN; + } public: - ReASBinaryOp(); + ReASBinaryOp(); public: - virtual void calc(ReVMThread& thread); - virtual bool check(ReParser& parser); + virtual void calc(ReVMThread& thread); + virtual bool check(ReParser& parser); public: - BinOperator getOperator() const; - void setOperator(BinOperator op); - void dump(ReWriter& writer, int indent); + BinOperator getOperator() const; + void setOperator(BinOperator op); + void dump(ReWriter& writer, int indent); private: - void assign(ReVMThread& thread); + void assign(ReVMThread& thread); public: - static const char* nameOfOp(BinOperator op); + static const char* nameOfOp(BinOperator op); private: - BinOperator m_operator; + BinOperator m_operator; }; -class ReASIf : public ReASNode4, public ReASStatement -{ +class ReASIf: public ReASNode4, public ReASStatement { public: - ReASIf(); + ReASIf(); public: - virtual bool check(ReParser& parser); - virtual int execute(ReVMThread& thread); - virtual void dump(ReWriter& writer, int indent); + virtual bool check(ReParser& parser); + virtual int execute(ReVMThread& thread); + virtual void dump(ReWriter& writer, int indent); }; -class ReASForIterated : public ReASNode4, public ReASStatement -{ +class ReASForIterated: public ReASNode4, public ReASStatement { public: - ReASForIterated(ReASVarDefinition* variable); + ReASForIterated(ReASVarDefinition* variable); public: - virtual bool check(ReParser& parser); - virtual int execute(ReVMThread& thread); - virtual void dump(ReWriter& writer, int indent); + virtual bool check(ReParser& parser); + virtual int execute(ReVMThread& thread); + virtual void dump(ReWriter& writer, int indent); }; -class ReASForCounted : public ReASNode6, public ReASStatement -{ +class ReASForCounted: public ReASNode6, public ReASStatement { public: - ReASForCounted(ReASVarDefinition* variable); + ReASForCounted(ReASVarDefinition* variable); public: - virtual bool check(ReParser& parser); - virtual int execute(ReVMThread& thread); - virtual void dump(ReWriter& writer, int indent); + virtual bool check(ReParser& parser); + virtual int execute(ReVMThread& thread); + virtual void dump(ReWriter& writer, int indent); }; -class ReASWhile : public ReASNode3, public ReASStatement -{ +class ReASWhile: public ReASNode3, public ReASStatement { public: - ReASWhile(); + ReASWhile(); public: - virtual bool check(ReParser& parser); - virtual int execute(ReVMThread& thread); - virtual void dump(ReWriter& writer, int indent); + virtual bool check(ReParser& parser); + virtual int execute(ReVMThread& thread); + virtual void dump(ReWriter& writer, int indent); }; -class ReASRepeat : public ReASNode3, public ReASStatement -{ +class ReASRepeat: public ReASNode3, public ReASStatement { public: - ReASRepeat(); + ReASRepeat(); public: - virtual bool check(ReParser& parser); - virtual int execute(ReVMThread& thread); - virtual void dump(ReWriter& writer, int indent); + virtual bool check(ReParser& parser); + virtual int execute(ReVMThread& thread); + virtual void dump(ReWriter& writer, int indent); }; class ReASMethod; -class ReASMethodCall : public ReASNode3, public ReASStatement -{ +class ReASMethodCall: public ReASNode3, public ReASStatement { public: - ReASMethodCall(const QByteArray& name, ReASItem* parent); + ReASMethodCall(const QByteArray& name, ReASItem* parent); public: - virtual bool check(ReParser& parser); - virtual int execute(ReVMThread& thread); + virtual bool check(ReParser& parser); + virtual int execute(ReVMThread& thread); public: - void dump(ReWriter& writer, int indent); + void dump(ReWriter& writer, int indent); public: - ReASMethod* method() const; - void setMethod(ReASMethod* method); + ReASMethod* method() const; + void setMethod(ReASMethod* method); - ReASExprStatement* arg1() const; + ReASExprStatement* arg1() const; private: - QByteArray m_name; - ReASMethod* m_method; + QByteArray m_name; + ReASMethod* m_method; }; -class RplParameter : ReASItem -{ +class RplParameter: ReASItem { public: - RplParameter(); - virtual ~RplParameter(); + RplParameter(); + virtual ~RplParameter(); private: - QByteArray m_name; - ReASNamedValue* m_default; + QByteArray m_name; + ReASNamedValue* m_default; }; -class ReASField : public ReASNode1 -{ +class ReASField: public ReASNode1 { public: - ReASField(const QByteArray& name); + ReASField(const QByteArray& name); public: - virtual bool check(ReParser& parser); + virtual bool check(ReParser& parser); public: - void dump(ReWriter& writer, int indent); + void dump(ReWriter& writer, int indent); private: - QByteArray m_name; + QByteArray m_name; }; - class ReASClass; class ReSymbolSpace; -class ReASMethod : public ReASNode2 -{ +class ReASMethod: public ReASNode2 { public: - ReASMethod(const QByteArray& name, ReASTree& tree); + ReASMethod(const QByteArray& name, ReASTree& tree); public: - virtual bool check(ReParser& parser); - virtual int execute(ReVMThread& thread); + virtual bool check(ReParser& parser); + virtual int execute(ReVMThread& thread); public: - void dump(ReWriter& writer, int indent); - ReSymbolSpace* symbols() const; - void setSymbols(); - const QByteArray& name() const; - bool equalSignature(ReASMethod& other) const; - ReASMethod* sibling() const; - void setSibling(ReASMethod* sibling); - int getFirstParamWithDefault() const; - void setFirstParamWithDefault(int value); + void dump(ReWriter& writer, int indent); + ReSymbolSpace* symbols() const; + void setSymbols(); + const QByteArray& name() const; + bool equalSignature(ReASMethod& other) const; + ReASMethod* sibling() const; + void setSibling(ReASMethod* sibling); + int getFirstParamWithDefault() const; + void setFirstParamWithDefault(int value); private: - QByteArray m_name; - ReASClass* m_resultType; - ReSymbolSpace* m_symbols; - // chain over all overloaded methods (same name, other signature): - ReASMethod* m_sibling; - ReASTree& m_tree; - // -1: no parameter with default value. >= 0: index of the first - int firstParamWithDefault; + QByteArray m_name; + ReASClass* m_resultType; + ReSymbolSpace* m_symbols; + // chain over all overloaded methods (same name, other signature): + ReASMethod* m_sibling; + ReASTree& m_tree; + // -1: no parameter with default value. >= 0: index of the first + int firstParamWithDefault; }; class ReASClass { public: - typedef QMap MethodMap; -public: - ReASClass(const QByteArray& name, ReASTree& m_tree); - virtual ~ReASClass(); -public: - /** - * @brief Creates a value object (used in ReASVariant). - * - * @param source NULL or a source to copy - * @return a new value object (specific for the class) - */ - virtual void* newValueInstance(void* source = NULL) const = 0; - /** - * @brief Destroys the given object. - * - * The object must be created by newValueInstance(). - * - * @param object object to destroy - */ - virtual void destroyValueInstance(void* object) const = 0; - /** - * @brief Returns the boolean value of a class specific value. - * - * Example: the boolean value of an the empty string is false - * - * @param object object to test - * @return false: the object represents the false value
- * true: otherwise - */ - virtual bool boolValueOf(void* object) const = 0; - /** - * @brief Returns a string representation of an instance. - * - * @param object the object to convert - * @param maxLength the maximum length of the result (string) - * @return a string describing the object - */ - virtual QByteArray toString(void *object, int maxLength = 80) const = 0; -public: - const QByteArray& name() const; - virtual void dump(ReWriter& writer, int indent); - void setSymbols(); + typedef QMap MethodMap; +public: + ReASClass(const QByteArray& name, ReASTree& m_tree); + virtual ~ReASClass(); +public: + /** + * @brief Creates a value object (used in ReASVariant). + * + * @param source NULL or a source to copy + * @return a new value object (specific for the class) + */ + virtual void* newValueInstance(void* source = NULL) const = 0; + /** + * @brief Destroys the given object. + * + * The object must be created by newValueInstance(). + * + * @param object object to destroy + */ + virtual void destroyValueInstance(void* object) const = 0; + /** + * @brief Returns the boolean value of a class specific value. + * + * Example: the boolean value of an the empty string is false + * + * @param object object to test + * @return false: the object represents the false value
+ * true: otherwise + */ + virtual bool boolValueOf(void* object) const = 0; + /** + * @brief Returns a string representation of an instance. + * + * @param object the object to convert + * @param maxLength the maximum length of the result (string) + * @return a string describing the object + */ + virtual QByteArray toString(void *object, int maxLength = 80) const = 0; +public: + const QByteArray& name() const; + virtual void dump(ReWriter& writer, int indent); + void setSymbols(); protected: - QByteArray m_name; - ReSymbolSpace* m_symbols; - const ReASClass* m_superClass; - ReASTree& m_tree; + QByteArray m_name; + ReSymbolSpace* m_symbols; + const ReASClass* m_superClass; + ReASTree& m_tree; }; -#include "rplexpr/rplasclasses.hpp" +#include "expr/ReASClasses.hpp" #include "ReParser.hpp" class ReSymbolSpace; -class ReASTree -{ -public: - enum { - DMP_NONE, - DMP_GLOBALS = 1<<1, - DMP_MODULES = 1<<2, - DMP_SPACE_STACK = 1<<3, - DMP_SPACE_HEAP = 1<<4, - DMP_ALL = DMP_GLOBALS | DMP_MODULES | DMP_SPACE_STACK | DMP_SPACE_HEAP, - DMP_NO_GLOBALS = DMP_MODULES | DMP_SPACE_STACK | DMP_SPACE_HEAP - }; - typedef QMap SymbolSpaceMap; - typedef QList SymbolSpaceStack; -public: - ReASTree(); - ~ReASTree(); -public: - bool startModule(ReSourceUnitName name); - void finishModule(ReSourceUnitName name); - ReSymbolSpace* startClassOrMethod(const QByteArray& name, - ReSymbolSpace::SymbolSpaceType type); - void finishClassOrMethod(const QByteArray& name); - SymbolSpaceStack& symbolSpaces(); - ReSymbolSpace* currentSpace() const; - ReASClass* findClass(const QByteArray& name); - void clear(); - void dump(const char* filename, int flags = DMP_ALL, - const char* header = NULL); - ReSymbolSpace*findmodule(const QByteArray& name); - ReSourcePosition* copyPosition(); - ReByteStorage& store(); +class ReASTree { +public: + enum { + DMP_NONE, DMP_GLOBALS = 1 << 1, DMP_MODULES = 1 << 2, DMP_SPACE_STACK = 1 + << 3, DMP_SPACE_HEAP = 1 << 4, DMP_ALL = DMP_GLOBALS | DMP_MODULES + | DMP_SPACE_STACK | DMP_SPACE_HEAP, DMP_NO_GLOBALS = DMP_MODULES + | DMP_SPACE_STACK | DMP_SPACE_HEAP + }; + typedef QMap SymbolSpaceMap; + typedef QList SymbolSpaceStack; +public: + ReASTree(); + ~ReASTree(); +public: + bool startModule(ReSourceUnitName name); + void finishModule(ReSourceUnitName name); + ReSymbolSpace* startClassOrMethod(const QByteArray& name, + ReSymbolSpace::SymbolSpaceType type); + void finishClassOrMethod(const QByteArray& name); + SymbolSpaceStack& symbolSpaces(); + ReSymbolSpace* currentSpace() const; + ReASClass* findClass(const QByteArray& name); + void clear(); + void dump(const char* filename, int flags = DMP_ALL, const char* header = + NULL); + ReSymbolSpace*findmodule(const QByteArray& name); + ReSourcePosition* copyPosition(); + ReByteStorage& store(); protected: - void init(); - void destroy(); + void init(); + void destroy(); private: - // the mother of all symbol spaces. - ReSymbolSpace* m_global; - // contains all hit modules - SymbolSpaceMap m_modules; - // nested modules (import), classes and methods build this stack: - SymbolSpaceStack m_symbolSpaces; - // top of the stack: - ReSymbolSpace* m_currentSpace; - // contain all ever built symbol spaces: - SymbolSpaceMap m_symbolSpaceHeap; - ReByteStorage m_store; + // the mother of all symbol spaces. + ReSymbolSpace* m_global; + // contains all hit modules + SymbolSpaceMap m_modules; + // nested modules (import), classes and methods build this stack: + SymbolSpaceStack m_symbolSpaces; + // top of the stack: + ReSymbolSpace* m_currentSpace; + // contain all ever built symbol spaces: + SymbolSpaceMap m_symbolSpaceHeap; + ReByteStorage m_store; }; #endif // RPLASTREE_HPP diff --git a/expr/ReAsClasses.cpp b/expr/ReAsClasses.cpp deleted file mode 100644 index 2d607b5..0000000 --- a/expr/ReAsClasses.cpp +++ /dev/null @@ -1,1186 +0,0 @@ -/* - * Licence: - * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ - -/** @file - * @brief Predefined classes of the virtual machine, e.g ReASInteger. - */ -/** @file rplexpr/rplasclasses.hpp - * - * @brief Definitions for predefined classes of the virtual machine. - */ - -#include "base/rebase.hpp" -#include "expr/ReExpr.hpp" - -ReASList* ReASList::m_instance = NULL; -ReASMap* ReASMap::m_instance = NULL; -ReASFloat* ReASFloat::m_instance = NULL; -ReASInteger* ReASInteger::m_instance = NULL; -ReASString* ReASString::m_instance = NULL; -ReASBoolean* ReASBoolean::m_instance = NULL; -ReASVoid* ReASVoid::m_instance = NULL; -ReASFormula* ReASFormula::m_instance = NULL; - -/** @class ReSymbolSpace rplastree.hpp "rplexpr/rplastree.hpp" - * - * @brief Implements a symbol space for the parser. - * - * A symbol space is a container of the classes and variables which can be used - * at a given moment while compiling. - * - * A symbol space could have a parent which is a symbol space too and extends - * the visible classes / variables. - * - * If an entry exists more than one time in a symbol space chain only the first - * can be seen. - * - * The "last" parent is named "global" and exists always. It contains the - * core classes like String, List and Map and methods like print. - * - * Each module hit by the compiler builds its own symbol space with global as parent. - * - * Each class defines a symbol space and takes the symbol space of the superclass - * as its parent. If there is no superclass the module's symbol space will be taken. - * - * Each method defines its own symbol space. The parent may be the symbol space - * of the module or of the class. - */ -/** - * @brief Constructor, only for the global symbol space. - * - * @param name the symbol space's name - * @param parent the parent of the symbol space - */ -ReSymbolSpace::ReSymbolSpace(ReASTree& tree) : - m_type(SST_GLOBAL), - m_name("$global"), - m_variables(), - m_classes(), - m_parent(NULL), - m_body(NULL), - m_listOfVars(), - m_tree(tree) -{ -} -/** - * @brief Constructor. - * - * @param type the type of the symbol space: SST_MODULE, ... - * @param name the symbol space's name - * @param parent the parent of the symbol space - */ -ReSymbolSpace::ReSymbolSpace(ReSymbolSpace::SymbolSpaceType type, - const QByteArray& name, - ReSymbolSpace* parent) : - m_type(type), - m_name(name), - m_variables(), - m_classes(), - m_parent(parent), - m_body(NULL), - m_listOfVars(), - m_tree(parent->m_tree) -{ -} - - -/** - * @brief Destructor. - */ -ReSymbolSpace::~ReSymbolSpace() -{ - ClassMap::iterator it; - for (it = m_classes.begin(); it != m_classes.end(); it++){ - delete it.value(); - } - MethodMap::iterator it2; - for (it2 = m_methods.begin(); it2 != m_methods.end(); it2++){ - delete it2.value(); - } -} - -/** - * @brief Starts a scope. - * - * A scope is an "area" where variables can be defined. - * A variable "lives" in a scope. - * - * Saves the status to restore it in finishScope(). - * - * @param scope OUT: status info - */ -void ReSymbolSpace::startScope(ReASScope& scope) -{ - scope.m_varNoAtStart = m_listOfVars.size(); -} - -/** - * @brief Finishes a scope. - * - * Finishes the "live" of the variables created in the ending scope. - * - * @param endOfScope line (inside the current source unit) which finishes the - * scope - * @param scope the status of the scope at start. - */ -void ReSymbolSpace::finishScope(int endOfScope, ReASScope& scope) -{ - // in methods/classes not needed: - int ix = scope.m_varNoAtStart - scope.m_builtInVars; - int last = m_listOfVars.size(); - for (; ix < last; ix++){ - ReASVarDefinition* var = m_listOfVars[ix]; - var->setEndOfScope(endOfScope); - const QByteArray& name = var->name(); - if (m_variables.contains(name)) - m_variables.remove(name); - } -} - -/** - * @brief Search a variable in the symbol space. - * - * @param name variable to find - * - * @return NULL: not found
- * otherwise: the variable - */ -ReASVarDefinition* ReSymbolSpace::findVariable(const QByteArray& name) const -{ - ReASVarDefinition* rc = NULL; - if (m_variables.contains(name)) - rc = m_variables[name]; - else if (m_parent != NULL) - rc = m_parent->findVariable(name); - return rc; -} - -/** - * @brief Search the class in the symbol space hierarchy. - * - * @param name Name of the class - * @return NULL: not found
- * otherwise: the class - */ -ReASClass* ReSymbolSpace::findClass(const QByteArray& name) const -{ - ReASClass* rc = NULL; - if (m_classes.contains(name)) - rc = m_classes[name]; - else if (m_parent != NULL) - rc = m_parent->findClass(name); - return rc; -} - -/** - * @brief Find a method in the instance. - * - * @param name the method's name - * @return NULL: method not found - * otherwise: the method description - */ -ReASMethod* ReSymbolSpace::findMethod(const QByteArray& name) const -{ - ReASMethod* rc = NULL; - if (m_methods.contains(name)) - rc = m_methods[name]; - return rc; -} - -/** - * @brief Writes the content of the instance into a file. - * - * @param writer writes to output - * @param indent nesting level: so many tabs will be used as prefix - * @param header NULL or the headline - */ -void ReSymbolSpace::dump(ReWriter& writer, int indent, const char* header) -{ - if (header != NULL) - writer.writeLine(header); - writer.formatIndented(indent, "= %s (%s) parent: %s", m_name.constData(), - spaceTypeName(m_type), - m_parent == NULL ? "" : m_parent->name().constData()); - QList sorted; - if (m_classes.size() > 0){ - writer.writeIndented(indent, "== Classes:"); - sorted.reserve(m_classes.size()); - ClassMap::iterator it; - for (it = m_classes.begin(); it != m_classes.end(); it++){ - sorted.append(it.key()); - } - qSort(sorted.begin(), sorted.end(), qLess()); - QList::iterator it2; - for (it2 = sorted.begin(); it2 != sorted.end(); it2++){ - ReASClass* clazz = m_classes[*it2]; - clazz->dump(writer, indent); - } - } - if (m_methods.size() > 0){ - writer.writeIndented(indent, "== Methods:"); - sorted.clear(); - sorted.reserve(m_variables.size()); - MethodMap::iterator it3; - for (it3 = m_methods.begin(); it3 != m_methods.end(); it3++){ - sorted.append(it3.key()); - } - qSort(sorted.begin(), sorted.end(), qLess()); - QList::iterator it4; - for (it4 = sorted.begin(); it4 != sorted.end(); it4++){ - ReASMethod* method = m_methods[*it4]; - do { - method->dump(writer, indent); - method = method->sibling(); - } while (method != NULL); - } - } - - if (m_listOfVars.size() > 0){ - writer.writeIndented(indent, "== Variables:"); - QList::iterator it6; - for (int ix = 0; ix < m_listOfVars.size(); ix++){ - ReASVarDefinition* var = m_listOfVars[ix]; - var->dump(writer, indent); - } - } - if (m_body != NULL){ - writer.writeIndented(indent, "== Body:"); - ReASNode1::dumpStatements(writer, indent, m_body); - } -} - -/** - * @brief Returns the name of a space type. - * - * @param type type to inspect - * @return the name of the type - */ -const char*ReSymbolSpace::spaceTypeName( - ReSymbolSpace::SymbolSpaceType type) -{ - const char* rc = NULL; - switch(type){ - case SST_UNDEF: - rc = "undef"; - break; - case SST_GLOBAL: - rc = "global"; - break; - case SST_MODULE: - rc = "module"; - break; - case SST_CLASS: - rc = "class"; - break; - case SST_METHOD: - rc = "method"; - break; - default: - rc = "?"; - break; - } - return rc; -} - -/** - * @brief Initilizes the global symbol space. - * - * @param tree the abstract syntax tree - * @return the global symbol space - */ -ReSymbolSpace* ReSymbolSpace::createGlobal(ReASTree& tree) -{ - ReSymbolSpace* rc = new ReSymbolSpace(tree); - rc->m_tree = tree; - ReASInteger::m_instance = new ReASInteger(tree); - rc->m_classes[ReASInteger::m_instance->name()] = ReASInteger::m_instance; - ReASBoolean::m_instance = new ReASBoolean(tree); - rc->m_classes[ReASBoolean::m_instance->name()] = ReASBoolean::m_instance; - ReASFloat::m_instance = new ReASFloat(tree); - rc->m_classes[ReASFloat::m_instance->name()] = ReASFloat::m_instance; - ReASString::m_instance = new ReASString(tree); - rc->m_classes[ReASString::m_instance->name()] = ReASString::m_instance; - ReASList::m_instance = new ReASList(tree); - rc->m_classes[ReASList::m_instance->name()] = ReASList::m_instance; - ReASMap::m_instance = new ReASMap(tree); - rc->m_classes[ReASMap::m_instance->name()] = ReASMap::m_instance; - ReASVoid::m_instance = new ReASVoid(tree); - rc->m_classes[ReASVoid::m_instance->name()] = ReASVoid::m_instance; - ReASFormula::m_instance = new ReASFormula(tree); - rc->m_classes[ReASFormula::m_instance->name()] = ReASFormula::m_instance; - return rc; -} -/** - * @brief Returns the list of the variables. - * - * @return the list of the variables - */ -ReSymbolSpace::VariableList ReSymbolSpace::listOfVars() const -{ - return m_listOfVars; -} - -/** - * @brief Returns the parent of the symbol space. - * - * @return the symbolspace of the object (module, method, class..) containing - * the object belonging to the instance - */ -ReSymbolSpace* ReSymbolSpace::parent() const -{ - return m_parent; -} - -/** - * @brief Returns the body (an abstract syntax tree) of the symbol space. - * - * @return NULL: no body available
- * othewise: the body of the instance - */ -ReASItem* ReSymbolSpace::body() const -{ - return m_body; -} - -/** - * @brief Sets the body (an abstract syntax tree) of the symbol space. - * - * @param body the new body - */ -void ReSymbolSpace::setBody(ReASItem* body) -{ - m_body = body; -} - -/** - * @brief Adds a variable to the symbol space. - * - * @param variable the variable to add - * @param varNo OUT: variable number, current number in the symbol space - * @return NULL: success
- * otherwise: the already defined variable/method - */ -ReASItem* ReSymbolSpace::addVariable(ReASVarDefinition* variable, int& varNo) -{ - ReASItem* rc = NULL; - const QByteArray& name = variable->name(); - if (m_variables.contains(name)) - rc = m_variables[name]; - else if (m_methods.contains(name)) - rc = m_methods[name]; - else { - m_variables[name] = variable; - varNo = m_listOfVars.size(); - m_listOfVars.append(variable); - } - return rc; -} - -/** - * @brief Adds a method to the symbol space. - * - * @param method the method to add - * @return NULL: success
- * otherwise: the already defined variable/method - */ -ReASItem* ReSymbolSpace::addMethod(ReASMethod* method) -{ - ReASItem* rc = NULL; - const QByteArray& name = method->name(); - if (m_variables.contains(name)) - rc = m_variables[name]; - else if (! m_methods.contains(name)){ - m_methods[name] = method; - } else { - ReASMethod* first = m_methods[name]; - ReASMethod* oldMethod = first; - do { - if (oldMethod->equalSignature(*method)) - rc = oldMethod; - else - oldMethod = oldMethod->sibling(); - } while (rc == NULL && oldMethod != NULL); - if (rc == NULL){ - method->setChild(first); - m_methods[name] = method; - } - } - return rc; -} -/** - * @brief Adds a class to the instance. - * - * @param clazz the class to add - * @return NULL: success
- * otherwise: the already defined class - */ -ReASUserClass* ReSymbolSpace::addClass(ReASUserClass* clazz) -{ - ReASUserClass* rc = NULL; - const QByteArray& name = clazz->name(); - if (m_classes.contains(name)){ - rc = dynamic_cast(m_classes[name]); - } else { - m_classes[name] = clazz; - } - return rc; -} - -/** - * @brief Returns the name of the symbol space. - * - * @return the name - */ -const QByteArray& ReSymbolSpace::name() const -{ - return m_name; -} - - -/** @class ReASBoolean rplastree.hpp "rplexpr/rplastree.hpp" - * - * @brief Implements the class of a Boolean. - * - * A Boolean is a real value. - */ -/** - * @brief Constructor. - */ -ReASBoolean::ReASBoolean(ReASTree& tree) : - ReASClass("Bool", tree) -{ -} -/** - * @brief Creates a value object (used in ReASVariant). - * - * For Booleans nothing is to do! - * - * @param source NULL or a source to copy - * @return NULL - */ -void* ReASBoolean::newValueInstance(void*) const -{ - return NULL; -} - -/** - * @brief Destroys the given object. - * - * For Booleans nothing is to do! - * - * @param object object to destroy - */ -void ReASBoolean::destroyValueInstance(void*) const -{ -} - -/** - * @brief Calculates the boolean value of an class specific object. - * - * This method should never be called. - * - * @param object the object to test (with type QList*) - * @return false - */ -bool ReASBoolean::boolValueOf(void*) const -{ - return false; -} - -/** - * @brief Returns a string representation of an instance. - * - * @param object the object to convert - * @param maxLength not used - * @return a string describing the object - */ -QByteArray ReASBoolean::toString(void* object, int) const -{ - return ((ReASVariant*) object)->asBool() ? "True" : "False"; -} - -/** @class ReASNumber rplastree.hpp "rplexpr/rplastree.hpp" - * - * @brief Implements the class of a Boolean. - * - * A Boolean is one of the values true and false. - */ -/** - * @brief Constructor. - */ -ReASFloat::ReASFloat(ReASTree& tree) : - ReASClass("Float", tree) -{ -} - -ReASFloat::ReASFloat(const QByteArray& name, ReASTree& tree) : - ReASClass(name, tree) -{ - m_superClass = ReASFloat::m_instance; -} -/** - * @brief Creates a value object (used in ReASVariant). - * - * For Booleans nothing is to do! - * - * @param source NULL or a source to copy - * @return NULL - */ -void* ReASFloat::newValueInstance(void*) const -{ - return NULL; -} - -/** - * @brief Destroys the given object. - * - * For Booleans nothing is to do! - * - * @param object object to destroy - */ -void ReASFloat::destroyValueInstance(void*) const -{ -} - -/** - * @brief Calculates the boolean value of an class specific object. - * - * This method should never be called. - * - * @param object the object to test - * @return false - */ -bool ReASFloat::boolValueOf(void*) const -{ - return false; -} - -/** - * @brief Returns a string representation of an instance. - * - * @param object the object to convert - * @param maxLength not used - * @return a string describing the object - */ -QByteArray ReASFloat::toString(void* object, int) const -{ - char buffer[256]; - - qsnprintf(buffer, sizeof buffer, "%f", ((ReASVariant *) object)->asFloat()); - return buffer; -} - -/** @class ReASInteger rplastree.hpp "rplexpr/rplastree.hpp" - * - * @brief Implements the class of a Boolean. - * - * A Boolean is a one of the values true and false. - */ -/** - * @brief Constructor. - */ -ReASInteger::ReASInteger(ReASTree& tree) : - ReASFloat("Int", tree) -{ -} - -/** - * @brief Calculates the boolean value of an class specific object. - * - * This method should never be called. - * - * @param object the object to test - * @return false - */ -bool ReASInteger::boolValueOf(void*) const -{ - return false; -} - -/** - * @brief Returns a string representation of an instance. - * - * @param object the object to convert - * @param maxLength the maximum length of the result - * @return a string describing the object - */ -QByteArray ReASInteger::toString(void* object, int maxLength) const -{ - char buffer[64]; - qsnprintf(buffer, sizeof buffer, "%.*d", maxLength, - ((ReASVariant *) object)->asInt()); - return buffer; -} - - -/** @class ReASString rplastree.hpp "rplexpr/rplastree.hpp" - * - * @brief Implements the class of a string. - * - * A string is a mutable character sequence. - */ -/** - * @brief Constructor. - */ -ReASString::ReASString(ReASTree& tree) : - ReASClass("Str", tree) -{ -} -/** - * @brief Creates a value object (used in ReASVariant). - * - * @param source NULL or a source to copy - * @return a new value object (specific for the class) - */ -void* ReASString::newValueInstance(void* source) const -{ - QByteArray* rc = source == NULL ? new QByteArray() : new QByteArray(*(QByteArray*) source); - return (void*) rc; -} - -/** - * @brief Destroys the given object. - * - * The object must be created by newValueInstance(). - * - * @param object object to destroy - */ -void ReASString::destroyValueInstance(void* object) const -{ - delete (QByteArray*) object; -} - -/** - * @brief Calculates the boolean value of an class specific object. - * - * This method should never be called. - * - * @param object the object to test (a QByteArray* instance) - * @return false: the string is empty - * true: otherwise - */ -bool ReASString::boolValueOf(void* object) const -{ - bool rc = false; - if (object != NULL){ - QByteArray* string = static_cast(object); - if (string == NULL) - throw ReException("ReASString.boolValueOf(): not a string"); - rc = ! string->isEmpty(); - } - return rc; -} - -/** - * @brief Returns a string representation of an instance. - * - * @param object the object to convert - * @param maxLength the maximum length of the result - * @return a string describing the object - */ -QByteArray ReASString::toString(void* object, int maxLength) const -{ - QByteArray rc; - QByteArray* string = reinterpret_cast (object); - int length = string->size(); - if (length + 2 > maxLength) - length = maxLength - 2; - rc.reserve(length); - rc += "'"; - if (string->size() < maxLength - 2) { - rc += *string; - } else { - rc += string->mid(0, maxLength - 2 - 3); - rc += "..."; - } - rc += "'"; - return rc; -} - -/** @class ReASList rplastree.hpp "rplexpr/rplastree.hpp" - * - * @brief Implements the class of a list. - * - * A list is a container of any values. Values can be selected by the index. - */ -/** - * @brief Constructor. - */ -ReASList::ReASList(ReASTree& tree) : - ReASClass("List", tree) -{ -} - -/** - * @brief Creates a value object (used in ReASVariant). - * - * @param source NULL or a source to copy - * @return a new value object (specific for the class) - */ -void* ReASList::newValueInstance(void* source) const -{ - ReASListOfVariants* rc = new ReASListOfVariants(); - if (source != NULL){ - ReASListOfVariants* source2 = (ReASListOfVariants*) source; - rc->reserve(source2->size()); - ReASListOfVariants::iterator it; - for (it = source2->begin(); - it != source2->end(); - it++){ - // deleting in destroyValue(): - rc->append(new ReASVariant(*(*it))); - } - } - return (void*) rc; -} - -/** - * @brief Destroys the given object. - * - * The object must be created by newValueInstance(). - * - * @param object object to destroy - */ -void ReASList::destroyValueInstance(void* object) const -{ - delete static_cast(object); -} - -/** - * @brief Calculates the boolean value of an class specific object. - * - * @param object the object to test (with type QList*) - * @return false: the list is empty
- * true: otherwise - */ -bool ReASList::boolValueOf(void* object) const -{ - bool rc = false; - if (object != NULL){ - ReASListOfVariants* list = static_cast(object); - if (list == NULL) - throw ReException("ReASList.boolValueOf(): not a list"); - rc = ! list->empty(); - } - return rc; -} - -/** - * @brief Returns a string representation of an instance. - * - * @param object the object to convert - * @param maxLength unused - * @return a string describing the object - */ -QByteArray ReASList::toString(void* object, int maxLength) const -{ - QByteArray rc; - rc.reserve(maxLength); - rc += "["; - ReASListOfVariants* list = reinterpret_cast(object); - ReASListOfVariants::iterator it; - bool first = true; - for(it = list->begin(); it != list->end(); it++){ - if (first) - first = false; - else - rc += ","; - QByteArray part = (*it)->toString(maxLength - rc.size() - 5); - if (maxLength - rc.size() - 5 - part.size() <= 0){ - rc += "..."; - break; - } else { - rc += part; - } - - } - rc += "]"; - return rc; -} - -/** @class ReASMap rplastree.hpp "rplexpr/rplastree.hpp" - * - * @brief Implements the class of a map. - * - * A map is a container of (key, value) pairs. - * Values can be selected by the key. - */ -/** - * @brief Constructor. - */ -ReASMap::ReASMap(ReASTree& tree) : - ReASClass("Map", tree) -{ -} -/** - * @brief Creates a value object (used in ReASVariant). - * - * @param source NULL or a source to copy - * @return a new value object (specific for the class) - */ -void* ReASMap::newValueInstance(void* source) const -{ - ReASMapOfVariants* rc = new ReASMapOfVariants(); - if (source != NULL){ - ReASMapOfVariants* source2 = - static_cast(source); - // rc->reserve(source2->size()); - ReASMapOfVariants::iterator it; - for (it = source2->begin(); it != source2->end(); it++){ - // deleting in destroyValue(): - const QByteArray& key = it.key(); - ReASVariant* value = new ReASVariant(*it.value()); - (*rc)[key] = value; - } - } - return (void*) rc; -} - -/** - * @brief Destroys the given object. - * - * The object must be created by newValueInstance(). - * - * @param object object to destroy - */ -void ReASMap::destroyValueInstance(void* object) const -{ - delete (ReASMapOfVariants*) object; -} - -/** - * @brief Calculates the boolean value of an class specific object. - * - * @param object the object to test (with type QMap*) - * @return - */ -bool ReASMap::boolValueOf(void* object) const -{ - bool rc = false; - if (object != NULL){ - ReASMapOfVariants* map = reinterpret_cast(object); - if (map == NULL) - throw ReException("ReASMap.boolValueOf(): not a map"); - rc = map->empty() > 0; - } - return rc; -} - -/** - * @brief Returns a string representation of an instance. - * - * @param object the object to convert - * @param maxLength maximal length of the result - * @return a string describing the object - */ -QByteArray ReASMap::toString(void* object, int maxLength) const -{ - QByteArray rc; - rc.reserve(maxLength); - rc += "["; - ReASMapOfVariants* map = reinterpret_cast(object); - ReASMapOfVariants::iterator it; - bool first = true; - for(it = map->begin(); it != map->end(); it++){ - if (first) - first = false; - else - rc += ","; - if (maxLength - rc.size() - 5 - 2 - it.key().size() <= 0){ - rc += "..."; - break; - } else { - rc += "'"; - rc += it.key(); - rc += "':"; - } - QByteArray part = it.value()->toString(maxLength - rc.size() - 5); - if (maxLength - rc.size() - 5 - part.size() <= 0){ - rc += "..."; - break; - } else { - rc += part; - } - - } - rc += "}"; - return rc; -} - - -/** @class ReVariable rplastree.hpp "rplexpr/rplastree.hpp" - * - * @brief Implements a variable of a symbol space. - */ - -/** - * @brief Constructor. - */ -ReVariable::ReVariable(const QByteArray& name) : - m_name(name), - m_namespace(NULL), - m_value(), - m_type(NULL) -{ - -} - -/** - * @brief Writes the content of the instance into an output media. - * - * @param writer writes to output - * @param indent nesting level: so many tabs will be used as prefix - */ -void ReVariable::dump(ReWriter& writer, int indent) -{ - const char* name1 = m_type == NULL ? "NoneType" : m_type->name().constData(); - QByteArray val = m_value.toString(); - writer.formatIndented(indent, "%s %s: value: %s", - name1, m_name.constData(), val.constData()); -} -/** - * @brief Returns the data type of the variable. - * - * @return the class of the variable - */ -ReASClass* ReVariable::type() const -{ - return m_type; -} - -/** - * @brief Sets the data type. - * @param type the class of the variable - */ -void ReVariable::setType(ReASClass* type) -{ - m_type = type; -} -/** - * @brief Returns the name of the variable. - * - * @return the name - */ -const QByteArray& ReVariable::name() const -{ - return m_name; -} - -/** @class ReVariable rplastree.hpp "rplexpr/rplastree.hpp" - * - * @brief Implements a data type representing a none type. - */ -ReASVoid::ReASVoid(ReASTree& tree) : - ReASClass("Void", tree) -{ -} - -/** - * @brief Instantiates a new object. - * - * In this case we do nothing. - * - * @param source ignored - * @return - */ -void*ReASVoid::newValueInstance(void*) const -{ - return NULL; -} - -/** - * @brief Destroys an object created by newValueInstance. - * - * In this case we do nothing. - * - * @param object not used - */ -void ReASVoid::destroyValueInstance(void*) const -{ -} - -/** - * @brief Returns the bool value of the given object - * @param object ignored - * @return false - */ -bool ReASVoid::boolValueOf(void*) const -{ - return false; -} - -/** - * @brief Converts the object into a string. - * - * @param object ignored - * @param maxLength ignored - * @return the empty string - */ -QByteArray ReASVoid::toString(void*, int) const -{ - return QByteArray(""); -} - -/** @class ReASFormula rplastree.hpp "rplexpr/rplastree.hpp" - * - * @brief Implements a data type representing a calculated value. - */ - -/** - * @brief Constructor. - * - * @param tree the abstract syntax tree - */ -ReASFormula::ReASFormula(ReASTree& tree) : - ReASClass("Formula", tree) -{ -} - -/** - * @brief Instantiates a new object. - * - * In this case we do nothing. - * - * @param expr the result - * @return - */ -void* ReASFormula::newValueInstance(void* expr) const -{ - return expr; -} - -/** - * @brief Destroys an object created by newValueInstance. - * - * In this case we do nothing. - * - * @param object not used - */ -void ReASFormula::destroyValueInstance(void*) const -{ -} - -/** - * @brief Returns the bool value of the given object - * @param object ignored - * @return false - */ -bool ReASFormula::boolValueOf(void*) const -{ - return false; -} - -/** - * @brief Converts the object into a string. - * - * @param object ignored - * @param maxLength ignored - * @return the empty string - */ -QByteArray ReASFormula::toString(void* object, int) const -{ - ReASExprStatement* expr = static_cast(object); - - char buffer[64]; - qsnprintf(buffer, sizeof buffer, "", expr->id()); - return buffer; -} - -/** @class ReASUserClass rplastree.hpp "rplexpr/rplastree.hpp" - * - * @brief Implements a data type representing an user defined class. - */ - - -/** - * @brief Constructor. - * - * @param name name of the user defined class - * @param position the position of the class definition - * @param tree the abstract syntax tree - */ -ReASUserClass::ReASUserClass(const QByteArray& name, - const ReSourcePosition* position, - ReASTree& tree) : - ReASClass(name, tree), - m_position(position) -{ -} - -/** - * @brief Creates an instance of an user defined class. - * - * @param source the type (user defined class) of the result - * @return an instance of an user defined class - */ -void*ReASUserClass::newValueInstance(void* source) const -{ - ReASUserClass* clazz = static_cast(source); - ReASUserObject* rc = new ReASUserObject(clazz); - return static_cast(rc); -} - -void ReASUserClass::destroyValueInstance(void* object) const -{ - ReASUserObject* obj = static_cast(object); - delete obj; -} - -/** - * @brief Returns the bool value of the object. - * - * @param object object to test - * @return true: object != NULL
- * false: object == NULL - */ -bool ReASUserClass::boolValueOf(void* object) const -{ - return object != NULL; -} - -/** - * @brief Returns a string representation an instance of a user defined class. - * - * @param object object to convert - * @param maxLength maximum length of the string - * @return - */ -QByteArray ReASUserClass::toString(void*, int) const -{ - return m_name; -} -/** - * @brief Returns the source position of the instance. - * - * @return the source position - */ -const ReSourcePosition* ReASUserClass::position() const -{ - return m_position; -} - - - -/** @class ReASUserObject rplastree.hpp "rplexpr/rplastree.hpp" - * - * @brief Implements an instance of an user defined class. - */ -ReASUserObject::ReASUserObject(ReASUserClass* clazz) : - m_class(clazz), - m_fields(NULL) -{ -} - -/** - * @brief Destructor. - */ -ReASUserObject::~ReASUserObject() -{ - delete[] m_fields; - m_fields = NULL; -} diff --git a/expr/ReAsClasses.hpp b/expr/ReAsClasses.hpp deleted file mode 100644 index 53f3f90..0000000 --- a/expr/ReAsClasses.hpp +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Licence: - * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ - - -#ifndef RPLASCLASSES_HPP -#define RPLASCLASSES_HPP - -class ReSymbolSpace; -class ReVariable { -public: - ReVariable(const QByteArray& name); -public: - void dump(ReWriter& writer, int indent); - - ReASClass* type() const; - void setType(ReASClass* type); - const QByteArray& name() const; - -protected: - QByteArray m_name; - // NULL for "simple" variables (int, float, bool) - ReSymbolSpace* m_namespace; - ReASVariant m_value; - ReASClass* m_type; -}; - -class ReASScope -{ -public: - int m_builtInVars; - int m_varNoAtStart; -}; - -class ReASUserClass; -class ReASTree; -class ReSymbolSpace -{ -public: - enum SymbolSpaceType { - SST_UNDEF, - SST_GLOBAL, - SST_MODULE, - SST_CLASS, - SST_METHOD - }; - -public: - typedef QMap VariableMap; - typedef QMap ClassMap; - typedef QMap MethodMap; - typedef QList VariableList; -private: - ReSymbolSpace(ReASTree& tree); -public: - ReSymbolSpace(SymbolSpaceType type, const QByteArray& name, - ReSymbolSpace* parent); - virtual ~ReSymbolSpace(); -public: - void startScope(ReASScope& scope); - void finishScope(int endOfScope, ReASScope& scope); - ReASVarDefinition* findVariable(const QByteArray& name) const; - ReASClass* findClass(const QByteArray& name) const; - ReASMethod* findMethod(const QByteArray& name) const; - void dump(ReWriter& writer, int indent, const char* header = NULL); - const QByteArray& name() const; - ReASItem* body() const; - void setBody(ReASItem* body); - ReASItem* addVariable(ReASVarDefinition* variable, int& varNo); - ReASItem* addMethod(ReASMethod* method); - ReASUserClass* addClass(ReASUserClass* clazz); - ReSymbolSpace* parent() const; - VariableList listOfVars() const; -public: - static const char* spaceTypeName(SymbolSpaceType type); - static ReSymbolSpace* createGlobal(ReASTree& tree); -private: - SymbolSpaceType m_type; - QByteArray m_name; - VariableMap m_variables; - ClassMap m_classes; - MethodMap m_methods; - ReSymbolSpace* m_parent; - ReASItem* m_body; - VariableList m_listOfVars; - ReASTree& m_tree; -}; - -class ReASBoolean : public ReASClass { -public: - ReASBoolean(ReASTree& tree); -public: - void* newValueInstance(void* source = NULL) const; - void destroyValueInstance(void* object) const; - virtual bool boolValueOf(void* object) const; - virtual QByteArray toString(void *object, int maxLength = 80) const; -public: - static ReASBoolean* m_instance; -}; - -class ReASFloat : public ReASClass { -public: - ReASFloat(ReASTree& tree); - ReASFloat(const QByteArray& name, ReASTree& tree); -public: - void* newValueInstance(void* source = NULL) const; - void destroyValueInstance(void* object) const; - virtual bool boolValueOf(void* object) const; - virtual QByteArray toString(void *object, int maxLength = 80) const; -public: - static ReASFloat* m_instance; -}; - -class ReASInteger : public ReASFloat { -public: - ReASInteger(ReASTree& tree); -public: - virtual bool boolValueOf(void* object) const; - virtual QByteArray toString(void *object, int maxLength = 80) const; -public: - static ReASInteger* m_instance; -}; - -class ReASString : public ReASClass { -public: - ReASString(ReASTree& tree); -public: - void* newValueInstance(void* source = NULL) const; - void destroyValueInstance(void* object) const; - virtual bool boolValueOf(void* object) const; - virtual QByteArray toString(void *object, int maxLength = 80) const; -public: - static ReASString* m_instance; -}; - -class ReASList : public ReASClass { -public: - ReASList(ReASTree& tree); -public: - void* newValueInstance(void* source = NULL) const; - void destroyValueInstance(void* object) const; - virtual bool boolValueOf(void* object) const; - virtual QByteArray toString(void *object, int maxLength = 80) const; -public: - static ReASList* m_instance; -}; - -class ReASMap : public ReASClass { -public: - ReASMap(ReASTree& tree); -public: - void* newValueInstance(void* source = NULL) const; - void destroyValueInstance(void* object) const; - virtual bool boolValueOf(void* object) const; - virtual QByteArray toString(void *object, int maxLength = 80) const; -public: - static ReASMap* m_instance; -}; - -class ReASVoid : public ReASClass { -public: - ReASVoid(ReASTree& tree); -public: - void* newValueInstance(void* source = NULL) const; - void destroyValueInstance(void* object) const; - virtual bool boolValueOf(void* object) const; - virtual QByteArray toString(void *object, int maxLength = 80) const; -public: - static ReASVoid* m_instance; -}; - -class ReASFormula : public ReASClass { -public: - ReASFormula(ReASTree& tree); -public: - void* newValueInstance(void* source = NULL) const; - void destroyValueInstance(void* object) const; - virtual bool boolValueOf(void* object) const; - virtual QByteArray toString(void *object, int maxLength = 80) const; -public: - static ReASFormula* m_instance; -}; - -class ReASUserClass : public ReASClass { -public: - ReASUserClass(const QByteArray& name, const ReSourcePosition* position, - ReASTree& tree); -public: - void* newValueInstance(void* source = NULL) const; - void destroyValueInstance(void* object) const; - virtual bool boolValueOf(void* object) const; - virtual QByteArray toString(void *object, int maxLength = 80) const; - const ReSourcePosition* position() const; - -private: - const ReSourcePosition* m_position; -}; - -class ReASUserObject { -public: - ReASUserObject(ReASUserClass* clazz); - ~ReASUserObject(); -public: - void callMember(); -private: - ReASUserClass* m_class; - ReASVariant* m_fields; -}; - -#endif // RPLASCLASSES_HPP diff --git a/expr/ReLexer.cpp b/expr/ReLexer.cpp index 986ebc6..3aab121 100644 --- a/expr/ReLexer.cpp +++ b/expr/ReLexer.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * ReLexer.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * @brief Configurable scanner, which separates syntactic symbols from an input media. */ @@ -17,7 +20,6 @@ #define CHAR_INFO_SIZE (int(sizeof m_charInfo / sizeof m_charInfo[0])) - /** @class ReToken ReLexer.hpp "expr/ReLexer.hpp" * * @brief Implements specific exception for the lexer. @@ -32,16 +34,15 @@ * @param ... the values for the placeholders in the format. */ ReLexException::ReLexException(const ReSourcePosition& position, - const char* format, ...) : - ReException("") -{ - char buffer[64000]; - m_message = position.toString().toUtf8(); - va_list ap; - va_start(ap, format); - qvsnprintf(buffer, sizeof buffer, format, ap); - va_end(ap); - m_message += buffer; + const char* format, ...) : + ReException(""){ + char buffer[64000]; + m_message = position.toString().toUtf8(); + va_list ap; + va_start(ap, format); + qvsnprintf(buffer, sizeof buffer, format, ap); + va_end(ap); + m_message += buffer; } /** @class ReToken ReLexer.hpp "expr/ReLexer.hpp" @@ -54,19 +55,16 @@ ReLexException::ReLexException(const ReSourcePosition& position, * @param type token type */ ReToken::ReToken(RplTokenType type) : - m_tokenType(type), - m_string(), - m_printableString() - // m_value + m_tokenType(type), m_string(), m_printableString() +// m_value { - memset(&m_value, 0, sizeof m_value); + memset(&m_value, 0, sizeof m_value); } /** * @brief Destructor. */ -ReToken::~ReToken() -{ +ReToken::~ReToken(){ } /** * @brief Copy constructor. @@ -74,11 +72,10 @@ ReToken::~ReToken() * @param source source to copy */ ReToken::ReToken(const ReToken& source) : - m_tokenType(source.m_tokenType), - m_string(source.m_string), - m_printableString(source.m_printableString), - m_value(source.m_value) -{ + m_tokenType(source.m_tokenType), + m_string(source.m_string), + m_printableString(source.m_printableString), + m_value(source.m_value){ } /** * @brief Assignment operator. @@ -86,21 +83,19 @@ ReToken::ReToken(const ReToken& source) : * @param source source to copy * @return */ -ReToken& ReToken::operator =(const ReToken& source) -{ - m_tokenType = source.m_tokenType; - m_string = source.m_string; - m_value = source.m_value; - return *this; +ReToken& ReToken::operator =(const ReToken& source){ + m_tokenType = source.m_tokenType; + m_string = source.m_string; + m_value = source.m_value; + return *this; } /** * @brief Returns the string representation of the instance * @return a string representing the instance */ -const QByteArray& ReToken::toString() -{ - return m_string; +const QByteArray& ReToken::toString(){ + return m_string; } /** @@ -110,9 +105,8 @@ const QByteArray& ReToken::toString() * * @return the value of the token as integer */ -int ReToken::asInteger() const -{ - return (int) m_value.m_integer; +int ReToken::asInteger() const{ + return (int) m_value.m_integer; } /** @@ -122,9 +116,8 @@ int ReToken::asInteger() const * * @return the value of the token as unsigned integer (64 bit) */ -quint64 ReToken::asUInt64() const -{ - return m_value.m_integer; +quint64 ReToken::asUInt64() const{ + return m_value.m_integer; } /** @@ -134,9 +127,8 @@ quint64 ReToken::asUInt64() const * * @return the value of the token as floating point value */ -qreal ReToken::asReal() const -{ - return m_value.m_real; +qreal ReToken::asReal() const{ + return m_value.m_real; } /** @@ -146,9 +138,8 @@ qreal ReToken::asReal() const * * @return the value of the token as floating point value */ -const QByteArray& ReToken::rawString() const -{ - return m_printableString; +const QByteArray& ReToken::rawString() const{ + return m_printableString; } /** * @brief Returns the id of the token. @@ -159,17 +150,15 @@ const QByteArray& ReToken::rawString() const * * @return the id of the token */ -int ReToken::id() const -{ - return m_value.m_id; +int ReToken::id() const{ + return m_value.m_id; } /** * @brief Returns the token type. * @return the token type */ -RplTokenType ReToken::tokenType() const -{ - return m_tokenType; +RplTokenType ReToken::tokenType() const{ + return m_tokenType; } /** @@ -180,9 +169,8 @@ RplTokenType ReToken::tokenType() const * @return true: the expected type is the current
* false: otherwise */ -bool ReToken::isTokenType(RplTokenType expected) const -{ - return m_tokenType == expected; +bool ReToken::isTokenType(RplTokenType expected) const{ + return m_tokenType == expected; } /** @@ -194,10 +182,9 @@ bool ReToken::isTokenType(RplTokenType expected) const * @return true: the instance is an operator and the expected or the alternative
* false: otherwise */ -bool ReToken::isOperator(int expected, int alternative) const -{ - return m_tokenType == TOKEN_OPERATOR && (m_value.m_id == expected - || m_value.m_id == alternative); +bool ReToken::isOperator(int expected, int alternative) const{ + return m_tokenType == TOKEN_OPERATOR + && (m_value.m_id == expected || m_value.m_id == alternative); } /** @@ -210,21 +197,19 @@ bool ReToken::isOperator(int expected, int alternative) const * false: otherwise */ -bool ReToken::isKeyword(int expected, int alternative) const -{ - return m_tokenType == TOKEN_KEYWORD && (m_value.m_id == expected - || m_value.m_id == alternative); +bool ReToken::isKeyword(int expected, int alternative) const{ + return m_tokenType == TOKEN_KEYWORD + && (m_value.m_id == expected || m_value.m_id == alternative); } /** * @brief Makes all members undefined. */ -void ReToken::clear() -{ - m_string.clear(); - m_printableString.clear(); - m_tokenType = TOKEN_UNDEF; - m_value.m_integer = 0; +void ReToken::clear(){ + m_string.clear(); + m_printableString.clear(); + m_tokenType = TOKEN_UNDEF; + m_value.m_integer = 0; } /** @@ -233,11 +218,10 @@ void ReToken::clear() * @return true: the token is an id and the first char is an upper case char
* false: otherwise */ -bool ReToken::isCapitalizedId() const -{ - bool rc = m_tokenType == TOKEN_ID && isupper(m_string.at(0)) - && (m_string.length() == 1 || islower(m_string.at(1))); - return rc; +bool ReToken::isCapitalizedId() const{ + bool rc = m_tokenType == TOKEN_ID && isupper(m_string.at(0)) + && (m_string.length() == 1 || islower(m_string.at(1))); + return rc; } /** @@ -245,102 +229,98 @@ bool ReToken::isCapitalizedId() const * * @return a description of the instance */ -QByteArray ReToken::dump() const -{ - QByteArray rc; - rc = nameOfType(m_tokenType); - rc.append(": ").append(this->asUtf8()); - return rc; +QByteArray ReToken::dump() const{ + QByteArray rc; + rc = nameOfType(m_tokenType); + rc.append(": ").append(this->asUtf8()); + return rc; } -QByteArray ReToken::asUtf8() const -{ - char buffer[4096]; - buffer[0] = '\0'; +QByteArray ReToken::asUtf8() const{ + char buffer[4096]; + buffer[0] = '\0'; - switch(m_tokenType){ - case TOKEN_UNDEF: - break; - case TOKEN_STRING: - qsnprintf(buffer, sizeof buffer, "'%.*s'", int(sizeof buffer) - 1, - m_printableString.constData()); - break; - case TOKEN_NUMBER: - qsnprintf(buffer, sizeof buffer, "%lld", m_value.m_integer); - break; - case TOKEN_REAL: - qsnprintf(buffer, sizeof buffer, "%f", m_value.m_real); - break; - case TOKEN_KEYWORD: - case TOKEN_OPERATOR: - qsnprintf(buffer, sizeof buffer, "%lld", (int) m_value.m_id); - break; - case TOKEN_ID: - qsnprintf(buffer, sizeof buffer, "'%.*s'", int(sizeof buffer) - 1, - m_string.constData()); - break; - case TOKEN_COMMENT_REST_OF_LINE: - case TOKEN_COMMENT_START: - case TOKEN_COMMENT_END: - case TOKEN_SPACE: - case TOKEN_END_OF_SOURCE: - default: - break; - } - return buffer; + switch (m_tokenType) { + case TOKEN_UNDEF: + break; + case TOKEN_STRING: + qsnprintf(buffer, sizeof buffer, "'%.*s'", int(sizeof buffer) - 1, + m_printableString.constData()); + break; + case TOKEN_NUMBER: + qsnprintf(buffer, sizeof buffer, "%lld", m_value.m_integer); + break; + case TOKEN_REAL: + qsnprintf(buffer, sizeof buffer, "%f", m_value.m_real); + break; + case TOKEN_KEYWORD: + case TOKEN_OPERATOR: + qsnprintf(buffer, sizeof buffer, "%lld", (int) m_value.m_id); + break; + case TOKEN_ID: + qsnprintf(buffer, sizeof buffer, "'%.*s'", int(sizeof buffer) - 1, + m_string.constData()); + break; + case TOKEN_COMMENT_REST_OF_LINE: + case TOKEN_COMMENT_START: + case TOKEN_COMMENT_END: + case TOKEN_SPACE: + case TOKEN_END_OF_SOURCE: + default: + break; + } + return buffer; } /** * @brief Returns then name of a token type. * @param type the type to convert * @return the token type name */ -const char* ReToken::nameOfType(RplTokenType type) -{ - const char* rc = "?"; +const char* ReToken::nameOfType(RplTokenType type){ + const char* rc = "?"; - switch(type){ - case TOKEN_UNDEF: - rc = "undef"; - break; - case TOKEN_STRING: - rc = "String"; - break; - case TOKEN_NUMBER: - rc = "Number"; - break; - case TOKEN_REAL: - rc = "Real"; - break; - case TOKEN_KEYWORD: - rc = "Keyword"; - break; - case TOKEN_OPERATOR: - rc = "Operator"; - break; - case TOKEN_ID: - rc = "Id"; - break; - case TOKEN_COMMENT_REST_OF_LINE: - rc = "Comment-1-line"; - break; - case TOKEN_COMMENT_START: - rc = "Comment-m-line"; - break; - case TOKEN_COMMENT_END: - rc = "end of comment"; - break; - case TOKEN_SPACE: - rc = "space"; - break; - case TOKEN_END_OF_SOURCE: - rc = "end of source"; - break; - default: - break; - } - return rc; + switch (type) { + case TOKEN_UNDEF: + rc = "undef"; + break; + case TOKEN_STRING: + rc = "String"; + break; + case TOKEN_NUMBER: + rc = "Number"; + break; + case TOKEN_REAL: + rc = "Real"; + break; + case TOKEN_KEYWORD: + rc = "Keyword"; + break; + case TOKEN_OPERATOR: + rc = "Operator"; + break; + case TOKEN_ID: + rc = "Id"; + break; + case TOKEN_COMMENT_REST_OF_LINE: + rc = "Comment-1-line"; + break; + case TOKEN_COMMENT_START: + rc = "Comment-m-line"; + break; + case TOKEN_COMMENT_END: + rc = "end of comment"; + break; + case TOKEN_SPACE: + rc = "space"; + break; + case TOKEN_END_OF_SOURCE: + rc = "end of source"; + break; + default: + break; + } + return rc; } - /** @class ReLexer ReLexer.hpp "expr/ReLexer.hpp" * * @brief Implements a lexical analyser. @@ -351,66 +331,63 @@ const char* ReToken::nameOfType(RplTokenType type) */ static void itemsToVector(const char* items, ReLexer::StringList& vector, - int firstCharFlag, int secondCharFlag, - int thirdCharFlag, int restCharFlag, - int charInfo[]) -{ - QByteArray array2(items); - QList list = array2.split(' '); - QList::iterator it; - int id = 0; - for (it = list.begin(); it < list.end(); it++){ - QByteArray& item2 = *it; - QByteArray item(item2); - id++; - item.append(' ').append(id % 256).append(id / 256); - vector.append(item); - unsigned char cc = item2.at(0); - if (cc < 128) - charInfo[cc] |= firstCharFlag; - if(item2.size() > 1){ - cc = item2.at(1); - if (cc < 128) - charInfo[cc] |= secondCharFlag; - } - if(item2.size() > 2){ - cc = item2.at(2); + int firstCharFlag, int secondCharFlag, int thirdCharFlag, int restCharFlag, + int charInfo[]){ + QByteArray array2(items); + QList < QByteArray > list = array2.split(' '); + QList ::iterator it; + int id = 0; + for (it = list.begin(); it < list.end(); it++){ + QByteArray& item2 = *it; + QByteArray item(item2); + id++; + item.append(' ').append(id % 256).append(id / 256); + vector.append(item); + unsigned char cc = item2.at(0); + if (cc < 128) + charInfo[cc] |= firstCharFlag; + if (item2.size() > 1){ + cc = item2.at(1); + if (cc < 128) + charInfo[cc] |= secondCharFlag; + } + if (item2.size() > 2){ + cc = item2.at(2); + if (cc < 128) + charInfo[cc] |= thirdCharFlag; + } + if (item2.size() > 3){ + const char* ptr = item2.constData() + 3; + while ((cc = *ptr++) != '\0'){ if (cc < 128) - charInfo[cc] |= thirdCharFlag; - } - if(item2.size() > 3){ - const char* ptr = item2.constData() + 3; - while( (cc = *ptr++) != '\0'){ - if (cc < 128) - charInfo[cc] |= restCharFlag; - } - } - } - qSort(vector.begin(), vector.end(), qLess()); + charInfo[cc] |= restCharFlag; + } + } + } + qSort(vector.begin(), vector.end(), qLess ()); } static void charClassToCharInfo(const char* charClass, int flag, - int charInfo[]) -{ - for (int ix = 0; charClass[ix] != '\0'; ix++){ - unsigned char cc = (unsigned char) charClass[ix]; - if (cc < 128) - charInfo[cc] |= flag; - if (charClass[ix+1] == '-'){ - unsigned char ubound = charClass[ix+2]; - if (ubound == '\0') - charInfo['-'] |= flag; - else if (cc >= ubound) - throw new ReException("wrong character class range: %c-%c (%s)", - cc, ubound, charClass); - else { - for (int ii = cc + 1; ii <= ubound; ii++){ - charInfo[ii] |= flag; - } + int charInfo[]){ + for (int ix = 0; charClass[ix] != '\0'; ix++){ + unsigned char cc = (unsigned char) charClass[ix]; + if (cc < 128) + charInfo[cc] |= flag; + if (charClass[ix + 1] == '-'){ + unsigned char ubound = charClass[ix + 2]; + if (ubound == '\0') + charInfo['-'] |= flag; + else if (cc >= ubound) + throw new ReException("wrong character class range: %c-%c (%s)", cc, + ubound, charClass); + else{ + for (int ii = cc + 1; ii <= ubound; ii++){ + charInfo[ii] |= flag; } - ix += 2; - } - } + } + ix += 2; + } + } } /** @@ -438,60 +415,56 @@ static void charClassToCharInfo(const char* charClass, int flag, * @param storageFlags describes the things which should be stored, e.g. * S_ORG_STRINGS | S_COMMENTS | S_BLANKS */ -ReLexer::ReLexer(ReSource* source, - const char* keywords, - const char* operators, const char* rightAssociatives, - const char* comments, - const char* firstCharsId, const char* restCharsId, int numericTypes, - int stringFeatures, int storageFlags) : - m_source(source), - m_keywords(), - m_operators(), - m_commentStarts(), - m_commentEnds(), - //m_charInfo() - m_idFirstRare(), - m_idRestRare(), - m_numericTypes(numericTypes), - m_idRest2(), - m_currentToken(&m_token1), - m_waitingToken(NULL), - m_waitingToken2(NULL), - m_token1(TOKEN_UNDEF), - m_token2(TOKEN_UNDEF), - m_currentPosition(NULL), - m_waitingPosition1(NULL), - m_waitingPosition2(NULL), - m_maxTokenLength(64), - m_input(), - m_currentCol(0), - m_hasMoreInput(false), - m_stringFeatures(stringFeatures), - m_storageFlags(storageFlags), - // m_prioOfOp - // m_assocOfOp - #if defined (RPL_LEXER_TRACE) - m_trace(true), - #endif - m_opNames() -{ - memset(m_prioOfOp, 0, sizeof m_prioOfOp); - memset(m_assocOfOp, 0, sizeof m_assocOfOp); +ReLexer::ReLexer(ReSource* source, const char* keywords, const char* operators, + const char* rightAssociatives, const char* comments, + const char* firstCharsId, const char* restCharsId, int numericTypes, + int stringFeatures, int storageFlags) : + m_source(source), + m_keywords(), + m_operators(), + m_commentStarts(), + m_commentEnds(), + //m_charInfo() + m_idFirstRare(), + m_idRestRare(), + m_numericTypes(numericTypes), + m_idRest2(), + m_currentToken(&m_token1), + m_waitingToken(NULL), + m_waitingToken2(NULL), + m_token1(TOKEN_UNDEF), + m_token2(TOKEN_UNDEF), + m_currentPosition(NULL), + m_waitingPosition1(NULL), + m_waitingPosition2(NULL), + m_maxTokenLength(64), + m_input(), + m_currentCol(0), + m_hasMoreInput(false), + m_stringFeatures(stringFeatures), + m_storageFlags(storageFlags), + // m_prioOfOp + // m_assocOfOp +#if defined (RPL_LEXER_TRACE) + m_trace(true), +#endif + m_opNames(){ + memset(m_prioOfOp, 0, sizeof m_prioOfOp); + memset(m_assocOfOp, 0, sizeof m_assocOfOp); - memset(m_charInfo, 0, sizeof m_charInfo); - itemsToVector(keywords, m_keywords, CC_FIRST_KEYWORD, CC_2nd_KEYWORD, - CC_3rd_KEYWORD, CC_REST_KEYWORD, m_charInfo); - prepareOperators(operators, rightAssociatives); - charClassToCharInfo(firstCharsId, CC_FIRST_ID, m_charInfo); - charClassToCharInfo(restCharsId, CC_REST_ID, m_charInfo); - initializeComments(comments); - m_input.reserve(m_maxTokenLength*2); + memset(m_charInfo, 0, sizeof m_charInfo); + itemsToVector(keywords, m_keywords, CC_FIRST_KEYWORD, CC_2nd_KEYWORD, + CC_3rd_KEYWORD, CC_REST_KEYWORD, m_charInfo); + prepareOperators(operators, rightAssociatives); + charClassToCharInfo(firstCharsId, CC_FIRST_ID, m_charInfo); + charClassToCharInfo(restCharsId, CC_REST_ID, m_charInfo); + initializeComments(comments); + m_input.reserve(m_maxTokenLength * 2); } /** * @brief Destructor. */ -ReLexer::~ReLexer() -{ +ReLexer::~ReLexer(){ } /** @@ -502,13 +475,13 @@ ReLexer::~ReLexer() * @return the count of blanks */ int countBlanks(const char* start, const char* end){ - int rc = 0; - while(start != end){ - if (*start++ == ' '){ - rc++; - } - } - return rc; + int rc = 0; + while (start != end){ + if (*start++ == ' '){ + rc++; + } + } + return rc; } /** @@ -519,85 +492,84 @@ int countBlanks(const char* start, const char* end){ * Lower position means lower priority */ void ReLexer::prepareOperators(const char* operators, - const char* rightAssociatives){ - QByteArray op2(operators); - QByteArray rightAssociatives2(" "); - rightAssociatives2 += rightAssociatives; - op2.replace("\n", " "); - itemsToVector(op2.constData(), m_operators, CC_FIRST_OP, CC_2nd_OP, - CC_3rd_OP, CC_REST_OP, m_charInfo); - // m_operators is now sorted: - // test whether the successor of 1 char operators is starting with this char: - // if not this operator will be marked with CC_OP_1_ONLY: - for (int ix = 0; ix < m_operators.size() - 1; ix++){ - // the entries of m_operators end with ' ' and id: - if (m_operators.at(ix).size() == 1 + 2 - && m_operators.at(ix).at(0) != m_operators.at(ix+1).at(0)){ - int cc = (char) m_operators[ix].at(0); - m_charInfo[cc] |= CC_OP_1_ONLY; - } + const char* rightAssociatives){ + QByteArray op2(operators); + QByteArray rightAssociatives2(" "); + rightAssociatives2 += rightAssociatives; + op2.replace("\n", " "); + itemsToVector(op2.constData(), m_operators, CC_FIRST_OP, CC_2nd_OP, + CC_3rd_OP, CC_REST_OP, m_charInfo); + // m_operators is now sorted: + // test whether the successor of 1 char operators is starting with this char: + // if not this operator will be marked with CC_OP_1_ONLY: + for (int ix = 0; ix < m_operators.size() - 1; ix++){ + // the entries of m_operators end with ' ' and id: + if (m_operators.at(ix).size() == 1 + 2 + && m_operators.at(ix).at(0) != m_operators.at(ix + 1).at(0)){ + int cc = (char) m_operators[ix].at(0); + m_charInfo[cc] |= CC_OP_1_ONLY; + } - } - m_opNames.reserve(m_operators.size() + 1); - op2 = " " + op2; - m_opNames = op2.split(' '); - QByteArray rAssoc = QByteArray(" ") + rightAssociatives + " "; - for (int opId = m_opNames.size() - 1; opId >= 1; opId--){ - QByteArray item = " " + m_opNames[opId] + " "; - if (rAssoc.indexOf(item) >= 0) - m_assocOfOp[opId] = true; - } - const char* start = operators; - const char* end; - int prio = 0; - int endId = 0; - int startId = 1; - bool again = true; - while (again){ - if ( (end = strchr(start, '\n')) == NULL){ - end = strchr(start, '\0'); - again = false; - } - prio++; - endId = startId + countBlanks(start, end) + 1 - 1; - while(startId <= endId){ - m_prioOfOp[startId++] = prio; - } - start = end + 1; - } + } + m_opNames.reserve(m_operators.size() + 1); + op2 = " " + op2; + m_opNames = op2.split(' '); + QByteArray rAssoc = QByteArray(" ") + rightAssociatives + " "; + for (int opId = m_opNames.size() - 1; opId >= 1; opId--){ + QByteArray item = " " + m_opNames[opId] + " "; + if (rAssoc.indexOf(item) >= 0) + m_assocOfOp[opId] = true; + } + const char* start = operators; + const char* end; + int prio = 0; + int endId = 0; + int startId = 1; + bool again = true; + while (again){ + if ((end = strchr(start, '\n')) == NULL){ + end = strchr(start, '\0'); + again = false; + } + prio++; + endId = startId + countBlanks(start, end) + 1 - 1; + while (startId <= endId){ + m_prioOfOp[startId++] = prio; + } + start = end + 1; + } } -void ReLexer::initializeComments(const char* comments) -{ - if (comments != NULL) - { - QByteArray starters; - QByteArray comments2(comments); - int ix = comments2.indexOf(" "); - if (ix >= 0) - throw ReException("more than one blank between comment pair(s): col %d %s", - ix + 1, comments + ix); - // the index of m_commentEnds is the position number: we need a dummy entry: - m_commentEnds.append(""); +void ReLexer::initializeComments(const char* comments){ + if (comments != NULL){ + QByteArray starters; + QByteArray comments2(comments); + int ix = comments2.indexOf(" "); + if (ix >= 0) + throw ReException( + "more than one blank between comment pair(s): col %d %s", ix + 1, + comments + ix); + // the index of m_commentEnds is the position number: we need a dummy entry: + m_commentEnds.append(""); - QList items = comments2.split(' '); - QList::iterator it; - ix = 0; - for (it = items.begin(); it != items.end(); it++, ix++){ - if (ix % 2 == 0){ - if (ix > 0) - starters += " "; - starters += *it; - }else{ - m_commentEnds.append(*it); - } - } - if (ix % 2 != 0) - throw ReException("not only pairs in the comment list"); - itemsToVector(starters, m_commentStarts, CC_FIRST_COMMENT_START, - CC_2nd_COMMENT_START, CC_3rd_COMMENT_START, CC_REST_COMMENT_START, - m_charInfo); - } + QList < QByteArray > items = comments2.split(' '); + QList ::iterator it; + ix = 0; + for (it = items.begin(); it != items.end(); it++, ix++){ + if (ix % 2 == 0){ + if (ix > 0) + starters += " "; + starters += *it; + }else{ + m_commentEnds.append(*it); + } + } + if (ix % 2 != 0) + throw ReException("not only pairs in the comment list"); + itemsToVector(starters, m_commentStarts, CC_FIRST_COMMENT_START, + CC_2nd_COMMENT_START, CC_3rd_COMMENT_START, CC_REST_COMMENT_START, + m_charInfo); + } } /** * @brief Searches the prefix of m_input in the vector. @@ -608,40 +580,39 @@ void ReLexer::initializeComments(const char* comments) * @param id the id of the entry in the vector. Only set if found * @return */ -int ReLexer::findInVector(int tokenLength, const StringList& vector) -{ - int id = 0; - int lbound = 0; - int ubound = vector.size() - 1; - // binary search over the sorted vector: - while(lbound <= ubound){ - int half = (ubound + lbound) / 2; - int compareRc = 0; - int ix = 0; - const QByteArray& current = vector[half]; - // vector items end with ' ' and id (2 byte): - int currentLength = current.size() - 3; - while(ix < tokenLength && compareRc == 0){ - if (ix >= currentLength) - // current is shorter: - compareRc = 1; - else - compareRc = m_input.at(ix) - (int) current.at(ix); - ix++; - } - if (compareRc == 0 && current.at(ix) != ' ') - // token.size() < current.size(): - compareRc = -1; - if (compareRc < 0) - ubound = half - 1; - else if (compareRc > 0) - lbound = half + 1; - else { - id = current[currentLength + 1] + current[currentLength + 2] * 256; - break; - } - } - return id; +int ReLexer::findInVector(int tokenLength, const StringList& vector){ + int id = 0; + int lbound = 0; + int ubound = vector.size() - 1; + // binary search over the sorted vector: + while (lbound <= ubound){ + int half = (ubound + lbound) / 2; + int compareRc = 0; + int ix = 0; + const QByteArray& current = vector[half]; + // vector items end with ' ' and id (2 byte): + int currentLength = current.size() - 3; + while (ix < tokenLength && compareRc == 0){ + if (ix >= currentLength) + // current is shorter: + compareRc = 1; + else + compareRc = m_input.at(ix) - (int) current.at(ix); + ix++; + } + if (compareRc == 0 && current.at(ix) != ' ') + // token.size() < current.size(): + compareRc = -1; + if (compareRc < 0) + ubound = half - 1; + else if (compareRc > 0) + lbound = half + 1; + else{ + id = current[currentLength + 1] + current[currentLength + 2] * 256; + break; + } + } + return id; } /** * @brief Reads data until enough data are available for one token. @@ -653,22 +624,21 @@ int ReLexer::findInVector(int tokenLength, const StringList& vector) * @return false: no more input is available
* true: data are available */ -bool ReLexer::fillInput() -{ - if (m_hasMoreInput){ - if (m_input.size() < m_maxTokenLength){ - m_source->currentReader()->fillBuffer(m_maxTokenLength, m_input, - m_hasMoreInput); - } - } +bool ReLexer::fillInput(){ + if (m_hasMoreInput){ + if (m_input.size() < m_maxTokenLength){ + m_source->currentReader()->fillBuffer(m_maxTokenLength, m_input, + m_hasMoreInput); + } + } - while (m_input.size() == 0 && m_source->currentReader() != NULL){ - if (m_source->currentReader()->nextLine(m_maxTokenLength, - m_input, m_hasMoreInput)){ - m_currentCol = 0; - } - } - return m_input.size() > 0; + while (m_input.size() == 0 && m_source->currentReader() != NULL){ + if (m_source->currentReader()->nextLine(m_maxTokenLength, m_input, + m_hasMoreInput)){ + m_currentCol = 0; + } + } + return m_input.size() > 0; } /** @@ -683,58 +653,56 @@ bool ReLexer::fillInput() * otherwise: the token */ ReToken* ReLexer::findTokenWithId(RplTokenType tokenType, int flag2, - StringList& names) -{ - int length = 1; - int inputLength = m_input.size(); - int cc; - if (inputLength > 1){ - cc = m_input[1]; - if (cc < CHAR_INFO_SIZE && (m_charInfo[cc] & flag2)){ - length++; - if (inputLength > 2){ - cc = m_input[2]; - // the 3rd char flag is the "successor" of the 2nd char flag: - int flag = (flag2 << 1); - if (cc < CHAR_INFO_SIZE && (m_charInfo[cc] & flag)){ - length++; - // the rest char flag is the "successor" of the 3nd char flag: - flag <<= 1; - while (length < inputLength){ - cc = m_input[length]; - if (cc < CHAR_INFO_SIZE && (m_charInfo[cc] & flag)) - length++; - else - break; - } - } + StringList& names){ + int length = 1; + int inputLength = m_input.size(); + int cc; + if (inputLength > 1){ + cc = m_input[1]; + if (cc < CHAR_INFO_SIZE && (m_charInfo[cc] & flag2)){ + length++; + if (inputLength > 2){ + cc = m_input[2]; + // the 3rd char flag is the "successor" of the 2nd char flag: + int flag = (flag2 << 1); + if (cc < CHAR_INFO_SIZE && (m_charInfo[cc] & flag)){ + length++; + // the rest char flag is the "successor" of the 3nd char flag: + flag <<= 1; + while (length < inputLength){ + cc = m_input[length]; + if (cc < CHAR_INFO_SIZE && (m_charInfo[cc] & flag)) + length++; + else + break; + } } - } - } - ReToken* rc = NULL; - if (! (tokenType == TOKEN_KEYWORD && length < inputLength - && (cc = m_input[length]) < CHAR_INFO_SIZE - && (m_charInfo[cc] & CC_REST_ID))) { - int id; - // the length could be too long: the CC_2nd_.. flag could be ambigous - while( (id = findInVector(length, names)) <= 0){ - if (length == 1 || tokenType == TOKEN_KEYWORD){ - break; - } - length--; - } - if (id > 0){ - rc = m_currentToken; - rc->m_tokenType = tokenType; - rc->m_value.m_id = id; - if (tokenType == TOKEN_COMMENT_START - && (m_storageFlags & STORE_COMMENT) != 0) - rc->m_string.append(m_input.mid(0, length)); - m_input.remove(0, length); - m_currentCol += length; - } - } - return rc; + } + } + } + ReToken* rc = NULL; + if (!(tokenType == TOKEN_KEYWORD && length < inputLength && (cc = + m_input[length]) < CHAR_INFO_SIZE && (m_charInfo[cc] & CC_REST_ID))){ + int id; + // the length could be too long: the CC_2nd_.. flag could be ambigous + while ((id = findInVector(length, names)) <= 0){ + if (length == 1 || tokenType == TOKEN_KEYWORD){ + break; + } + length--; + } + if (id > 0){ + rc = m_currentToken; + rc->m_tokenType = tokenType; + rc->m_value.m_id = id; + if (tokenType == TOKEN_COMMENT_START + && (m_storageFlags & STORE_COMMENT) != 0) + rc->m_string.append(m_input.mid(0, length)); + m_input.remove(0, length); + m_currentCol += length; + } + } + return rc; } /** @@ -742,150 +710,147 @@ ReToken* ReLexer::findTokenWithId(RplTokenType tokenType, int flag2, * * @return the token with the number */ -ReToken* ReLexer::scanNumber() -{ - int inputLength = m_input.size(); - int cc; - int length; - quint64 value = 0; - if ( (cc = m_input[0]) == '0' && inputLength > 1 - && (m_numericTypes & NUMTYPE_HEXADECIMAL) - && (m_input[1] == 'x' || m_input[1] == 'X')){ - length = ReStringUtil::lengthOfUInt64(m_input.constData() + 2, 16, &value); - if (length > 0) - length += 2; - else - throw ReException("invalid hexadecimal number: no digit behind 'x"); - } else if (cc == '0' && (m_numericTypes & NUMTYPE_OCTAL) - && inputLength > 1){ - length = 1; - while (length < inputLength){ - if ( (cc = m_input[length]) >= '0' && cc <= '7') - value = value * 8 + cc - '0'; - else if (cc >= '8' && cc <= '9') - throw ReLexException(*m_currentPosition, - "invalid octal digit: %c", cc); - else - break; - length++; - } - } else { - length = 1; - value = cc - '0'; - while (length < inputLength){ - if ( (cc = m_input[length]) >= '0' && cc <= '9') - value = value * 10 + cc - '0'; - else - break; - length++; - } - } - m_currentToken->m_value.m_integer = value; - m_currentToken->m_tokenType = TOKEN_NUMBER; - if (length + 1 < inputLength - && ((cc = m_input[length]) == '.' || toupper(cc) == 'E')){ - qreal realValue; - int realLength = ReStringUtil::lengthOfReal(m_input.constData(), &realValue); - if (realLength > length){ - m_currentToken->m_tokenType = TOKEN_REAL; - m_currentToken->m_value.m_real = realValue; - length = realLength; - } - } - m_input.remove(0, length); - m_currentCol += length; - return m_currentToken; +ReToken* ReLexer::scanNumber(){ + int inputLength = m_input.size(); + int cc; + int length; + quint64 value = 0; + if ((cc = m_input[0]) == '0' && inputLength > 1 + && (m_numericTypes & NUMTYPE_HEXADECIMAL) + && (m_input[1] == 'x' || m_input[1] == 'X')){ + length = ReStringUtil::lengthOfUInt64(m_input.constData() + 2, 16, + &value); + if (length > 0) + length += 2; + else + throw ReException("invalid hexadecimal number: no digit behind 'x"); + }else if (cc == '0' && (m_numericTypes & NUMTYPE_OCTAL) && inputLength > 1){ + length = 1; + while (length < inputLength){ + if ((cc = m_input[length]) >= '0' && cc <= '7') + value = value * 8 + cc - '0'; + else if (cc >= '8' && cc <= '9') + throw ReLexException(*m_currentPosition, "invalid octal digit: %c", + cc); + else + break; + length++; + } + }else{ + length = 1; + value = cc - '0'; + while (length < inputLength){ + if ((cc = m_input[length]) >= '0' && cc <= '9') + value = value * 10 + cc - '0'; + else + break; + length++; + } + } + m_currentToken->m_value.m_integer = value; + m_currentToken->m_tokenType = TOKEN_NUMBER; + if (length + 1 < inputLength + && ((cc = m_input[length]) == '.' || toupper(cc) == 'E')){ + qreal realValue; + int realLength = ReStringUtil::lengthOfReal(m_input.constData(), + &realValue); + if (realLength > length){ + m_currentToken->m_tokenType = TOKEN_REAL; + m_currentToken->m_value.m_real = realValue; + length = realLength; + } + } + m_input.remove(0, length); + m_currentCol += length; + return m_currentToken; } /** * @brief Reads a string into the internal data. * @return the token with the string */ -ReToken*ReLexer::scanString() -{ - int delim = m_input[0]; - int inputLength = m_input.size(); - int cc; - int length = 1; - m_currentToken->m_tokenType = TOKEN_STRING; - m_currentToken->m_value.m_id = delim; - bool again = false; - do { - while(length < inputLength && (cc = m_input[length]) != delim){ - length++; - if (cc != '\\' - || (m_stringFeatures - & (SF_C_ESCAPING | SF_C_HEX_CHARS | SF_C_SPECIAL)) == 0){ - m_currentToken->m_string.append(QChar(cc)); - } else { - if (length >= inputLength) - throw ReLexException(*m_currentPosition, - "backslash without following character"); - cc = m_input[length++]; - if ( (m_stringFeatures & SF_C_HEX_CHARS) && toupper(cc) == 'X'){ - if (length >= inputLength) - throw ReLexException(*m_currentPosition, - "missing hexadecimal digit behind \\x"); - cc = m_input[length++]; - int hexVal = ReQString::valueOfHexDigit(cc); - if (hexVal < 0) - throw ReLexException(*m_currentPosition, - "not a hexadecimal digit behind \\x: %lc", - QChar(cc)); - if (length < inputLength){ - cc = m_input[length]; - int nibble = ReQString::valueOfHexDigit(cc); - if (nibble >= 0){ - length++; - hexVal = hexVal * 16 + nibble; - } - } - m_currentToken->m_string.append(QChar(hexVal)); - } else if ( (m_stringFeatures & SF_C_SPECIAL)){ - switch(cc){ - case 'r': - cc = '\r'; - break; - case 'n': - cc = '\n'; - break; - case 't': - cc = '\t'; - break; - case 'a': - cc = '\a'; - break; - case 'v': - cc = '\v'; - break; - case 'f': - cc = '\f'; - break; - default: - break; - } - m_currentToken->m_string.append(QChar(cc)); - } else { - m_currentToken->m_string.append(QChar(cc)); - } +ReToken*ReLexer::scanString(){ + int delim = m_input[0]; + int inputLength = m_input.size(); + int cc; + int length = 1; + m_currentToken->m_tokenType = TOKEN_STRING; + m_currentToken->m_value.m_id = delim; + bool again = false; + do{ + while (length < inputLength && (cc = m_input[length]) != delim){ + length++; + if (cc != '\\' + || (m_stringFeatures + & (SF_C_ESCAPING | SF_C_HEX_CHARS | SF_C_SPECIAL)) == 0){ + m_currentToken->m_string.append(QChar(cc)); + }else{ + if (length >= inputLength) + throw ReLexException(*m_currentPosition, + "backslash without following character"); + cc = m_input[length++]; + if ((m_stringFeatures & SF_C_HEX_CHARS) && toupper(cc) == 'X'){ + if (length >= inputLength) + throw ReLexException(*m_currentPosition, + "missing hexadecimal digit behind \\x"); + cc = m_input[length++]; + int hexVal = ReQString::valueOfHexDigit(cc); + if (hexVal < 0) + throw ReLexException(*m_currentPosition, + "not a hexadecimal digit behind \\x: %lc", QChar(cc)); + if (length < inputLength){ + cc = m_input[length]; + int nibble = ReQString::valueOfHexDigit(cc); + if (nibble >= 0){ + length++; + hexVal = hexVal * 16 + nibble; + } + } + m_currentToken->m_string.append(QChar(hexVal)); + }else if ((m_stringFeatures & SF_C_SPECIAL)){ + switch (cc) { + case 'r': + cc = '\r'; + break; + case 'n': + cc = '\n'; + break; + case 't': + cc = '\t'; + break; + case 'a': + cc = '\a'; + break; + case 'v': + cc = '\v'; + break; + case 'f': + cc = '\f'; + break; + default: + break; + } + m_currentToken->m_string.append(QChar(cc)); + }else{ + m_currentToken->m_string.append(QChar(cc)); } - } - if (cc == delim){ - length++; - } - if ( (m_stringFeatures & SF_DOUBLE_DELIM) && length < inputLength - && m_input[length] == (char) delim){ - m_currentToken->m_printableString.append(delim); - length++; - again = true; - } - } - while(again); - if (m_storageFlags & STORE_ORG_STRING) - m_currentToken->m_printableString.append(m_input.mid(0, length)); - m_input.remove(0, length); - m_currentCol += length; - return m_currentToken; + } + } + if (cc == delim){ + length++; + } + if ((m_stringFeatures & SF_DOUBLE_DELIM) && length < inputLength + && m_input[length] == (char) delim){ + m_currentToken->m_printableString.append(delim); + length++; + again = true; + } + }while (again); + if (m_storageFlags & STORE_ORG_STRING) + m_currentToken->m_printableString.append(m_input.mid(0, length)); + m_input.remove(0, length); + m_currentCol += length; + return m_currentToken; } /** @@ -893,44 +858,41 @@ ReToken*ReLexer::scanString() * * precondition: the current token is prepared yet */ -void ReLexer::scanComment() -{ - int inputLength = m_input.size(); - int length = 1; - QByteArray& commentEnd = m_commentEnds[m_currentToken->id()]; - int ix; - if (commentEnd[0] == '\n'){ - // single line comment: - if (m_storageFlags & STORE_COMMENT) +void ReLexer::scanComment(){ + int inputLength = m_input.size(); + int length = 1; + QByteArray& commentEnd = m_commentEnds[m_currentToken->id()]; + int ix; + if (commentEnd[0] == '\n'){ + // single line comment: + if (m_storageFlags & STORE_COMMENT) + m_currentToken->m_string.append(m_input); + length = inputLength; + }else{ + // multiline comment: + while ((ix = m_input.indexOf(commentEnd)) < 0){ + if (m_storageFlags & STORE_COMMENT) m_currentToken->m_string.append(m_input); - length = inputLength; - } else { - // multiline comment: - while( (ix = m_input.indexOf(commentEnd)) < 0){ - if (m_storageFlags & STORE_COMMENT) - m_currentToken->m_string.append(m_input); - m_input.clear(); - if (! fillInput()) - throw ReLexException(*m_currentPosition, - "comment end not found"); - } - length = ix + commentEnd.size(); - if (m_storageFlags & STORE_COMMENT) - m_currentToken->m_string - .append(m_input.mid(0, length)); - } - m_input.remove(0, length); - m_currentCol += length; + m_input.clear(); + if (!fillInput()) + throw ReLexException(*m_currentPosition, "comment end not found"); + } + length = ix + commentEnd.size(); + if (m_storageFlags & STORE_COMMENT) + m_currentToken->m_string.append(m_input.mid(0, length)); + } + m_input.remove(0, length); + m_currentCol += length; } #if defined (RPL_LEXER_TRACE) bool ReLexer::trace() const { - return m_trace; + return m_trace; } void ReLexer::setTrace(bool trace) { - m_trace = trace; + m_trace = trace; } #endif /** @@ -938,9 +900,8 @@ void ReLexer::setTrace(bool trace) * * @return the current token */ -ReToken* ReLexer::currentToken() const -{ - return m_currentToken; +ReToken* ReLexer::currentToken() const{ + return m_currentToken; } /** @@ -948,9 +909,8 @@ ReToken* ReLexer::currentToken() const * * @return the current source code position */ -const ReSourcePosition* ReLexer::currentPosition() const -{ - return m_currentPosition; +const ReSourcePosition* ReLexer::currentPosition() const{ + return m_currentPosition; } /** @@ -958,136 +918,132 @@ const ReSourcePosition* ReLexer::currentPosition() const * * @return the next token */ -ReToken* ReLexer::nextToken() -{ - ReToken* rc = NULL; - int ix; - if (m_waitingToken != NULL){ - rc = m_currentToken = m_waitingToken; - m_waitingToken = m_waitingToken2; - m_waitingToken2 = NULL; - m_currentPosition = m_waitingPosition1; - m_waitingPosition1 = m_waitingPosition2; - m_waitingPosition2 = NULL; - } else { - m_currentToken->clear(); - ReReader* reader = m_source->currentReader(); - if (reader == NULL) +ReToken* ReLexer::nextToken(){ + ReToken* rc = NULL; + int ix; + if (m_waitingToken != NULL){ + rc = m_currentToken = m_waitingToken; + m_waitingToken = m_waitingToken2; + m_waitingToken2 = NULL; + m_currentPosition = m_waitingPosition1; + m_waitingPosition1 = m_waitingPosition2; + m_waitingPosition2 = NULL; + }else{ + m_currentToken->clear(); + ReReader* reader = m_source->currentReader(); + if (reader == NULL) + m_currentToken->m_tokenType = TOKEN_END_OF_SOURCE; + else{ + m_waitingPosition2 = m_waitingPosition1; + m_waitingPosition1 = m_currentPosition; + m_currentPosition = m_source->newPosition(m_currentCol); + if (!fillInput()){ m_currentToken->m_tokenType = TOKEN_END_OF_SOURCE; - else { - m_waitingPosition2 = m_waitingPosition1; - m_waitingPosition1 = m_currentPosition; - m_currentPosition = m_source->newPosition(m_currentCol); - if (! fillInput()){ - m_currentToken->m_tokenType = TOKEN_END_OF_SOURCE; - } else { - int cc = m_input.at(0); - if (isspace(cc)){ - //waitingPosition = m_currentPosition; - m_currentToken->m_tokenType = TOKEN_SPACE; - ix = 1; - while(ix < m_input.size() && isspace(m_input.at(ix))) - ix++; - if (m_storageFlags & STORE_BLANK){ - m_currentToken->m_string.append(m_input.mid(0, ix)); - } - m_currentCol += ix; - m_input.remove(0, ix); - rc = m_currentToken; - } else if (isdigit(cc)){ - rc = scanNumber(); - } else if ( (cc == '"' && (m_stringFeatures & SF_QUOTE) != 0) - || (cc == '\'' && (m_stringFeatures & SF_TICK) != 0)){ - rc = scanString(); - } else { - if (cc >= CHAR_INFO_SIZE) - throw ReLexException(*m_currentPosition, - "no lexical symbol can start with this char: %lc", - cc); - else - { - if (rc == NULL && (m_charInfo[cc] & CC_FIRST_COMMENT_START)){ - rc = findTokenWithId(TOKEN_COMMENT_START, - CC_2nd_COMMENT_START, m_commentStarts); - if (rc != NULL) - scanComment(); - //waitingPosition = m_currentPosition; - } + }else{ + int cc = m_input.at(0); + if (isspace(cc)){ + //waitingPosition = m_currentPosition; + m_currentToken->m_tokenType = TOKEN_SPACE; + ix = 1; + while (ix < m_input.size() && isspace(m_input.at(ix))) + ix++; + if (m_storageFlags & STORE_BLANK){ + m_currentToken->m_string.append(m_input.mid(0, ix)); + } + m_currentCol += ix; + m_input.remove(0, ix); + rc = m_currentToken; + }else if (isdigit(cc)){ + rc = scanNumber(); + }else if ((cc == '"' && (m_stringFeatures & SF_QUOTE) != 0) + || (cc == '\'' && (m_stringFeatures & SF_TICK) != 0)){ + rc = scanString(); + }else{ + if (cc >= CHAR_INFO_SIZE) + throw ReLexException(*m_currentPosition, + "no lexical symbol can start with this char: %lc", cc); + else{ + if (rc == NULL && (m_charInfo[cc] & CC_FIRST_COMMENT_START)){ + rc = findTokenWithId(TOKEN_COMMENT_START, + CC_2nd_COMMENT_START, m_commentStarts); + if (rc != NULL) + scanComment(); + //waitingPosition = m_currentPosition; + } - if (rc == NULL && (m_charInfo[cc] & CC_FIRST_OP)){ - if ( (m_charInfo[cc] & CC_OP_1_ONLY) == 0){ - rc = findTokenWithId(TOKEN_OPERATOR, - CC_2nd_OP, m_operators); - } else { - rc = m_currentToken; - rc->m_tokenType = TOKEN_OPERATOR; - rc->m_value.m_id = findInVector(1, m_operators); - m_input.remove(0, 1); - m_currentCol += 1; - } - } - if (rc == NULL && (m_charInfo[cc] & CC_FIRST_KEYWORD)){ - rc = findTokenWithId(TOKEN_KEYWORD, - CC_2nd_KEYWORD, m_keywords); - } - if (rc == NULL && (m_charInfo[cc] & CC_FIRST_ID)){ - int length = 1; - while(length < m_input.size() - && (cc = m_input[length]) < CHAR_INFO_SIZE - && (m_charInfo[cc] & CC_REST_ID) != 0) - length++; - rc = m_currentToken; - rc->m_tokenType = TOKEN_ID; - rc->m_string.append(m_input.mid(0, length)); - m_input.remove(0, length); - m_currentCol += length; - } + if (rc == NULL && (m_charInfo[cc] & CC_FIRST_OP)){ + if ((m_charInfo[cc] & CC_OP_1_ONLY) == 0){ + rc = findTokenWithId(TOKEN_OPERATOR, CC_2nd_OP, + m_operators); + }else{ + rc = m_currentToken; + rc->m_tokenType = TOKEN_OPERATOR; + rc->m_value.m_id = findInVector(1, m_operators); + m_input.remove(0, 1); + m_currentCol += 1; + } + } + if (rc == NULL && (m_charInfo[cc] & CC_FIRST_KEYWORD)){ + rc = findTokenWithId(TOKEN_KEYWORD, CC_2nd_KEYWORD, + m_keywords); + } + if (rc == NULL && (m_charInfo[cc] & CC_FIRST_ID)){ + int length = 1; + while (length < m_input.size() + && (cc = m_input[length]) < CHAR_INFO_SIZE + && (m_charInfo[cc] & CC_REST_ID) != 0) + length++; + rc = m_currentToken; + rc->m_tokenType = TOKEN_ID; + rc->m_string.append(m_input.mid(0, length)); + m_input.remove(0, length); + m_currentCol += length; + } - } - } + } } - } - } - if (rc == NULL || rc->tokenType() == TOKEN_UNDEF){ - if (m_input.size() == 0){ - rc = m_currentToken; - rc->m_tokenType = TOKEN_END_OF_SOURCE; - } else { - QByteArray symbol = m_input.mid(0, qMin(20, m_input.size()-1)); - throw ReLexException(*m_currentPosition, - "unknown lexical symbol: %s", symbol.constData()); - } - } + } + } + } + if (rc == NULL || rc->tokenType() == TOKEN_UNDEF){ + if (m_input.size() == 0){ + rc = m_currentToken; + rc->m_tokenType = TOKEN_END_OF_SOURCE; + }else{ + QByteArray symbol = m_input.mid(0, qMin(20, m_input.size() - 1)); + throw ReLexException(*m_currentPosition, "unknown lexical symbol: %s", + symbol.constData()); + } + } #if defined (RPL_LEXER_TRACE) - if (m_trace){ - char buffer[256]; - printf("token: %s pos: %s\n", m_currentToken->dump().constData(), + if (m_trace){ + char buffer[256]; + printf("token: %s pos: %s\n", m_currentToken->dump().constData(), m_currentPosition->utf8(buffer, sizeof buffer)); - if (strstr(buffer, "0:28") != NULL) - buffer[0] = 0; - } + if (strstr(buffer, "0:28") != NULL) + buffer[0] = 0; + } #endif - return rc; + return rc; } /** * @brief Reverses the last nextToken(). * * Makes that nextToken() returns the current token again. */ -void ReLexer::undoLastToken() -{ - m_waitingToken = m_currentToken; - m_currentToken = m_currentToken == &m_token1 ? &m_token2 : &m_token1; - m_waitingPosition1 = m_currentPosition; +void ReLexer::undoLastToken(){ + m_waitingToken = m_currentToken; + m_currentToken = m_currentToken == &m_token1 ? &m_token2 : &m_token1; + m_waitingPosition1 = m_currentPosition; #if defined (RPL_LEXER_TRACE) - if (m_trace){ - char buffer[256]; - printf("undo last token: waiting-token: %s pos: %s\n", + if (m_trace){ + char buffer[256]; + printf("undo last token: waiting-token: %s pos: %s\n", m_waitingToken->dump().constData(), m_waitingPosition1->utf8(buffer, sizeof buffer)); - if (strcmp(buffer, ":2:6") == 0) - buffer[0] = 0; - } + if (strcmp(buffer, ":2:6") == 0) + buffer[0] = 0; + } #endif } @@ -1096,12 +1052,11 @@ void ReLexer::undoLastToken() * * Makes that nextToken() returns the current token again. */ -void ReLexer::undoLastToken2() -{ - m_waitingToken2 = m_currentToken; - m_waitingToken = m_currentToken == &m_token1 ? &m_token2 : &m_token1; - m_waitingPosition2 = m_waitingPosition1; - m_waitingPosition1 = m_currentPosition; +void ReLexer::undoLastToken2(){ + m_waitingToken2 = m_currentToken; + m_waitingToken = m_currentToken == &m_token1 ? &m_token2 : &m_token1; + m_waitingPosition2 = m_waitingPosition1; + m_waitingPosition1 = m_currentPosition; } /** @@ -1115,10 +1070,9 @@ void ReLexer::undoLastToken2() * * Then token1 and token2 contains the wanted content. */ -void ReLexer::saveLastToken() -{ - if (m_waitingToken == NULL) - m_currentToken = m_currentToken == &m_token1 ? &m_token2 : &m_token1; +void ReLexer::saveLastToken(){ + if (m_waitingToken == NULL) + m_currentToken = m_currentToken == &m_token1 ? &m_token2 : &m_token1; } /** @@ -1126,19 +1080,17 @@ void ReLexer::saveLastToken() * * @return the next token which is not a space/comment */ -ReToken*ReLexer::peekNonSpaceToken() -{ - ReToken* token = nextNonSpaceToken(); - undoLastToken(); - return token; +ReToken*ReLexer::peekNonSpaceToken(){ + ReToken* token = nextNonSpaceToken(); + undoLastToken(); + return token; } /** * @brief Returns the maximal length of a token * @return the maximal length of a token */ -size_t ReLexer::maxTokenLength() const -{ - return m_maxTokenLength; +size_t ReLexer::maxTokenLength() const{ + return m_maxTokenLength; } /** @@ -1146,25 +1098,23 @@ size_t ReLexer::maxTokenLength() const * * @param maxTokenLength the new maximal length of a token */ -void ReLexer::setMaxTokenLength(size_t maxTokenLength) -{ - m_maxTokenLength = maxTokenLength; +void ReLexer::setMaxTokenLength(size_t maxTokenLength){ + m_maxTokenLength = maxTokenLength; } /** * @brief ReLexer::nextNonSpaceToken * @return */ -ReToken* ReLexer::nextNonSpaceToken() -{ - ReToken* rc = NULL; - RplTokenType type; - do{ - rc = nextToken(); - } while( (type = m_currentToken->tokenType()) == TOKEN_SPACE - || type == TOKEN_COMMENT_START || type == TOKEN_COMMENT_END - || type == TOKEN_COMMENT_REST_OF_LINE); - return rc; +ReToken* ReLexer::nextNonSpaceToken(){ + ReToken* rc = NULL; + RplTokenType type; + do{ + rc = nextToken(); + }while ((type = m_currentToken->tokenType()) == TOKEN_SPACE + || type == TOKEN_COMMENT_START || type == TOKEN_COMMENT_END + || type == TOKEN_COMMENT_REST_OF_LINE); + return rc; } /** @@ -1177,18 +1127,16 @@ ReToken* ReLexer::nextNonSpaceToken() * * @param unit the new source unit */ -void ReLexer::startUnit(ReSourceUnitName unit) -{ - m_source->startUnit(unit, *m_currentPosition); +void ReLexer::startUnit(ReSourceUnitName unit){ + m_source->startUnit(unit, *m_currentPosition); } /** * @brief Returns the source of the instance. * * @return the source of the instance */ -ReSource* ReLexer::source() -{ - return m_source; +ReSource* ReLexer::source(){ + return m_source; } /** @@ -1197,11 +1145,10 @@ ReSource* ReLexer::source() * @param op the operator * @return the priority of the op */ -int ReLexer::prioOfOp(int op) const -{ - int rc = op > 0 && (unsigned) op < sizeof m_prioOfOp / sizeof m_prioOfOp[0] - ? m_prioOfOp[op] : 0; - return rc; +int ReLexer::prioOfOp(int op) const{ + int rc = op > 0 && (unsigned) op < sizeof m_prioOfOp / sizeof m_prioOfOp[0] ? + m_prioOfOp[op] : 0; + return rc; } /** @@ -1210,10 +1157,9 @@ int ReLexer::prioOfOp(int op) const * @param op the operator id * @return the name of the operator */ -const QByteArray&ReLexer::nameOfOp(int op) const -{ - const QByteArray& rc = m_opNames.at(op); - return rc; +const QByteArray&ReLexer::nameOfOp(int op) const{ + const QByteArray& rc = m_opNames.at(op); + return rc; } /** @@ -1222,13 +1168,11 @@ const QByteArray&ReLexer::nameOfOp(int op) const * @return true: the operator is right associative
* false: otherwise */ -bool ReLexer::isRightAssociative(int op) const -{ - bool rc = false; - if (op >= 0 && (unsigned) op < sizeof m_assocOfOp / sizeof m_assocOfOp[0]){ - rc = m_assocOfOp[op]; - } - return rc; +bool ReLexer::isRightAssociative(int op) const{ + bool rc = false; + if (op >= 0 && (unsigned) op < sizeof m_assocOfOp / sizeof m_assocOfOp[0]){ + rc = m_assocOfOp[op]; + } + return rc; } - diff --git a/expr/ReLexer.hpp b/expr/ReLexer.hpp index fea3b0d..2757780 100644 --- a/expr/ReLexer.hpp +++ b/expr/ReLexer.hpp @@ -1,11 +1,13 @@ /* - * Licence: + * ReLexer.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ - + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #ifndef RPLLEXER_HPP #define RPLLEXER_HPP @@ -13,235 +15,229 @@ //#define RPL_LEXER_TRACE enum RplTokenType { - TOKEN_UNDEF, - TOKEN_STRING, - TOKEN_NUMBER, - TOKEN_REAL, - TOKEN_KEYWORD, - TOKEN_OPERATOR, - TOKEN_ID, - TOKEN_COMMENT_REST_OF_LINE, - TOKEN_COMMENT_START, - TOKEN_COMMENT_END, - TOKEN_SPACE, - TOKEN_END_OF_SOURCE, - TOKEN_COUNT + TOKEN_UNDEF, + TOKEN_STRING, + TOKEN_NUMBER, + TOKEN_REAL, + TOKEN_KEYWORD, + TOKEN_OPERATOR, + TOKEN_ID, + TOKEN_COMMENT_REST_OF_LINE, + TOKEN_COMMENT_START, + TOKEN_COMMENT_END, + TOKEN_SPACE, + TOKEN_END_OF_SOURCE, + TOKEN_COUNT }; -class ReLexException : public ReException { +class ReLexException: public ReException { public: - ReLexException(const ReSourcePosition& position, const char* message, ...); + ReLexException(const ReSourcePosition& position, const char* message, ...); }; class ReLexer; class ReToken { public: - ReToken(RplTokenType type); - ~ReToken(); - ReToken(const ReToken& source); - ReToken& operator =(const ReToken& source); + ReToken(RplTokenType type); + ~ReToken(); + ReToken(const ReToken& source); + ReToken& operator =(const ReToken& source); public: - friend class ReLexer; - const QByteArray& toString(); - bool isInteger(); - int asInteger() const; - quint64 asUInt64() const; - qreal asReal() const; - const QByteArray& rawString() const; - int id() const; - RplTokenType tokenType() const; - bool isTokenType(RplTokenType expected) const; - bool isOperator(int expected, int alternative = 0) const; - bool isKeyword(int expected, int alternative = 0) const; - void clear(); - bool isCapitalizedId() const; - QByteArray dump() const; - static const char* nameOfType(RplTokenType type); - QByteArray asUtf8() const; + friend class ReLexer; + const QByteArray& toString(); + bool isInteger(); + int asInteger() const; + quint64 asUInt64() const; + qreal asReal() const; + const QByteArray& rawString() const; + int id() const; + RplTokenType tokenType() const; + bool isTokenType(RplTokenType expected) const; + bool isOperator(int expected, int alternative = 0) const; + bool isKeyword(int expected, int alternative = 0) const; + void clear(); + bool isCapitalizedId() const; + QByteArray dump() const; + static const char* nameOfType(RplTokenType type); + QByteArray asUtf8() const; protected: - RplTokenType m_tokenType; - QByteArray m_string; - // only for TOKEN_STRING: copy from source but with escaped chars like "\\n" - QByteArray m_printableString; - union { - // only for TOKEN_KEYWORD and TOKEN_OPERATOR - int m_id; - quint64 m_integer; - qreal m_real; - } m_value; + RplTokenType m_tokenType; + QByteArray m_string; + // only for TOKEN_STRING: copy from source but with escaped chars like "\\n" + QByteArray m_printableString; + union { + // only for TOKEN_KEYWORD and TOKEN_OPERATOR + int m_id; + quint64 m_integer; + qreal m_real; + } m_value; }; - class ReSource; -class ReLexer -{ +class ReLexer { public: - typedef QList StringList; - enum NumericType { - NUMTYPE_UNDEF, - NUMTYPE_DECIMAL = 1 << 0, - NUMTYPE_OCTAL = 1 << 1, - NUMTYPE_HEXADECIMAL = 1 << 2, - NUMTYPE_FLOAT = 1 << 3, - /// - NUMTYPE_ALL_INTEGER = NUMTYPE_DECIMAL | NUMTYPE_OCTAL |NUMTYPE_HEXADECIMAL, - NUMTYPE_ALL = NUMTYPE_ALL_INTEGER | NUMTYPE_FLOAT - }; - enum CharClassTag { - CC_UNDEF = 0, - /// this char is possible as first char of an id - CC_FIRST_ID = 1 << 0, - /// this char is possible as 2nd char of an id - CC_2nd_ID = 1 << 1, - /// this char is possible as 3rd char of an id - CC_3rd_ID = 1 << 2, - /// this char is possible as 4th... char of an id - CC_REST_ID = 1 << 3, - /// this char can start a comment - CC_FIRST_COMMENT_START = 1 << 4, - /// this char can be the 2nd char of a comment start - CC_2nd_COMMENT_START = 1 << 5, - /// this char can be the 3rd char of a comment start - CC_3rd_COMMENT_START = 1 << 6, - /// this char can be the 4th ... of a comment start - CC_REST_COMMENT_START = 1 << 7, - /// this char can start a keyword - CC_FIRST_KEYWORD = 1 << 8, - /// this char can be the 2nd char of a keyword - CC_2nd_KEYWORD = 1 << 9, - /// this char can be the 3rd char of a keyword - CC_3rd_KEYWORD = 1 << 10, - /// this char can be the 4th... char of a keyword - CC_REST_KEYWORD = 1 << 11, - /// this char can be the 1st char of an operator - CC_FIRST_OP = 1 << 12, - /// this char can be the 2nd char of an operator - CC_2nd_OP = 1 << 13, - /// this char can be the 3rd char of an operator - CC_3rd_OP = 1 << 14, - /// this char can be the 4th... char of an operator - CC_REST_OP = 1 << 15, - /// there is an operator with exactly this char - /// and there is no other operator starting with this char - CC_OP_1_ONLY = 1 << 16 - }; - enum StringFeatures { - SF_UNDEF, - /// ' can be a string delimiter - SF_TICK = 1 << 1, - /// " can be a string delimiter - SF_QUOTE = 1 << 2, - /// character escaping like in C: "\x" is "x" - SF_C_ESCAPING = 1 << 3, - /// special characters like in C: "\r" "\f" "\n" "\t" "\a" - SF_C_SPECIAL = 1 << 4, - /// characters can be written in hexadecimal notation: "\x20" is " " - SF_C_HEX_CHARS = 1 << 5, - /// A delimiter inside a string must be doubled (like in Pascal) - SF_DOUBLE_DELIM = 1 << 6, - // Redefinitions for better reading: - SF_LIKE_C = SF_TICK | SF_QUOTE | SF_C_ESCAPING | SF_C_SPECIAL - | SF_C_HEX_CHARS - }; - enum StorageFlags { - S_UNDEF, - /// the original string will be stored in m_string too - /// (not only m_rawString) - STORE_ORG_STRING = 1 << 1, - /// comments will be stored in m_string - STORE_COMMENT = 1 << 2, - /// blanks will be stored in m_string - STORE_BLANK = 1 << 3, - /// redefinitions for better reading: - STORE_NOTHING = 0, - STORE_ALL = STORE_ORG_STRING | STORE_COMMENT | STORE_BLANK - }; + typedef QList StringList; + enum NumericType { + NUMTYPE_UNDEF, + NUMTYPE_DECIMAL = 1 << 0, + NUMTYPE_OCTAL = 1 << 1, + NUMTYPE_HEXADECIMAL = 1 << 2, + NUMTYPE_FLOAT = 1 << 3, + /// + NUMTYPE_ALL_INTEGER = NUMTYPE_DECIMAL | NUMTYPE_OCTAL + | NUMTYPE_HEXADECIMAL, + NUMTYPE_ALL = NUMTYPE_ALL_INTEGER | NUMTYPE_FLOAT + }; + enum CharClassTag { + CC_UNDEF = 0, + /// this char is possible as first char of an id + CC_FIRST_ID = 1 << 0, + /// this char is possible as 2nd char of an id + CC_2nd_ID = 1 << 1, + /// this char is possible as 3rd char of an id + CC_3rd_ID = 1 << 2, + /// this char is possible as 4th... char of an id + CC_REST_ID = 1 << 3, + /// this char can start a comment + CC_FIRST_COMMENT_START = 1 << 4, + /// this char can be the 2nd char of a comment start + CC_2nd_COMMENT_START = 1 << 5, + /// this char can be the 3rd char of a comment start + CC_3rd_COMMENT_START = 1 << 6, + /// this char can be the 4th ... of a comment start + CC_REST_COMMENT_START = 1 << 7, + /// this char can start a keyword + CC_FIRST_KEYWORD = 1 << 8, + /// this char can be the 2nd char of a keyword + CC_2nd_KEYWORD = 1 << 9, + /// this char can be the 3rd char of a keyword + CC_3rd_KEYWORD = 1 << 10, + /// this char can be the 4th... char of a keyword + CC_REST_KEYWORD = 1 << 11, + /// this char can be the 1st char of an operator + CC_FIRST_OP = 1 << 12, + /// this char can be the 2nd char of an operator + CC_2nd_OP = 1 << 13, + /// this char can be the 3rd char of an operator + CC_3rd_OP = 1 << 14, + /// this char can be the 4th... char of an operator + CC_REST_OP = 1 << 15, + /// there is an operator with exactly this char + /// and there is no other operator starting with this char + CC_OP_1_ONLY = 1 << 16 + }; + enum StringFeatures { + SF_UNDEF, + /// ' can be a string delimiter + SF_TICK = 1 << 1, + /// " can be a string delimiter + SF_QUOTE = 1 << 2, + /// character escaping like in C: "\x" is "x" + SF_C_ESCAPING = 1 << 3, + /// special characters like in C: "\r" "\f" "\n" "\t" "\a" + SF_C_SPECIAL = 1 << 4, + /// characters can be written in hexadecimal notation: "\x20" is " " + SF_C_HEX_CHARS = 1 << 5, + /// A delimiter inside a string must be doubled (like in Pascal) + SF_DOUBLE_DELIM = 1 << 6, + // Redefinitions for better reading: + SF_LIKE_C = SF_TICK | SF_QUOTE | SF_C_ESCAPING | SF_C_SPECIAL + | SF_C_HEX_CHARS + }; + enum StorageFlags { + S_UNDEF, + /// the original string will be stored in m_string too + /// (not only m_rawString) + STORE_ORG_STRING = 1 << 1, + /// comments will be stored in m_string + STORE_COMMENT = 1 << 2, + /// blanks will be stored in m_string + STORE_BLANK = 1 << 3, + /// redefinitions for better reading: + STORE_NOTHING = 0, + STORE_ALL = STORE_ORG_STRING | STORE_COMMENT | STORE_BLANK + }; public: - ReLexer(ReSource* source, - const char* keywords, - const char* operators, - const char* rightAssociatives, - const char* comments, - const char* firstCharsId = "a-zA-Z_", - const char* restCharsId = "a-zA-Z0-9_", - int numericTypes = NUMTYPE_DECIMAL | NUMTYPE_HEXADECIMAL | NUMTYPE_FLOAT, - int stringFeatures = SF_TICK | SF_QUOTE | SF_C_ESCAPING | SF_C_SPECIAL - | SF_C_HEX_CHARS, - int storageFlags = STORE_NOTHING); - virtual ~ReLexer(); + ReLexer(ReSource* source, const char* keywords, const char* operators, + const char* rightAssociatives, const char* comments, + const char* firstCharsId = "a-zA-Z_", const char* restCharsId = + "a-zA-Z0-9_", + int numericTypes = NUMTYPE_DECIMAL | NUMTYPE_HEXADECIMAL | NUMTYPE_FLOAT, + int stringFeatures = SF_TICK | SF_QUOTE | SF_C_ESCAPING | SF_C_SPECIAL + | SF_C_HEX_CHARS, int storageFlags = STORE_NOTHING); + virtual ~ReLexer(); public: - ReToken* nextToken(); - void undoLastToken(); - void undoLastToken2(); - void saveLastToken(); - ReToken* peekNonSpaceToken(); - ReToken* nextNonSpaceToken(); - size_t maxTokenLength() const; - void setMaxTokenLength(size_t maxTokenLength); - void startUnit(ReSourceUnitName unit); - ReSource* source(); - int prioOfOp(int op) const; - const QByteArray& nameOfOp(int op) const; - bool isRightAssociative(int op) const; - const ReSourcePosition* currentPosition() const; - ReToken* currentToken() const; + ReToken* nextToken(); + void undoLastToken(); + void undoLastToken2(); + void saveLastToken(); + ReToken* peekNonSpaceToken(); + ReToken* nextNonSpaceToken(); + size_t maxTokenLength() const; + void setMaxTokenLength(size_t maxTokenLength); + void startUnit(ReSourceUnitName unit); + ReSource* source(); + int prioOfOp(int op) const; + const QByteArray& nameOfOp(int op) const; + bool isRightAssociative(int op) const; + const ReSourcePosition* currentPosition() const; + ReToken* currentToken() const; #if defined RPL_LEXER_TRACE - bool trace() const; - void setTrace(bool trace); + bool trace() const; + void setTrace(bool trace); #endif private: - void prepareOperators(const char* operators, const char* rightAssociatives); - void initializeComments(const char* comments); - bool fillInput(); - int findInVector(int tokenLength, const StringList& vector); - ReToken* findTokenWithId(RplTokenType tokenType, int flag2, - StringList& names); - ReToken* scanNumber(); - ReToken* scanString(); - void scanComment(); + void prepareOperators(const char* operators, const char* rightAssociatives); + void initializeComments(const char* comments); + bool fillInput(); + int findInVector(int tokenLength, const StringList& vector); + ReToken* findTokenWithId(RplTokenType tokenType, int flag2, + StringList& names); + ReToken* scanNumber(); + ReToken* scanString(); + void scanComment(); protected: - ReSource* m_source; - /// sorted, string ends with the id of the keyword - StringList m_keywords; - // sorted, string ends with the id of the operator - StringList m_operators; - // sorted, each entry ends with the id of the comment start - StringList m_commentStarts; - // index: id content: comment_end - StringList m_commentEnds; - // index: ord(char) content: a sum of CharClassTags - int m_charInfo[128]; - // a list of QChars with ord(cc) > 127 and which can be the first char - QByteArray m_idFirstRare; - // index: ord(char) content: chr(ix) can be the non first char of an id - QByteArray m_idRestRare; - // a list of QChars with ord(cc) > 127 and which can be the first char - int m_numericTypes; - QByteArray m_idRest2; - ReToken* m_currentToken; - ReToken* m_waitingToken; - ReToken* m_waitingToken2; - ReToken m_token1; - ReToken m_token2; - const ReSourcePosition* m_currentPosition; - const ReSourcePosition* m_waitingPosition1; - const ReSourcePosition* m_waitingPosition2; - int m_maxTokenLength; - QByteArray m_input; - int m_currentCol; - bool m_hasMoreInput; - int m_stringFeatures; - int m_storageFlags; - /// priority of the operators: index: id of the operator. content: prio - char m_prioOfOp[128]; - char m_assocOfOp[128]; - QList m_opNames; + ReSource* m_source; + /// sorted, string ends with the id of the keyword + StringList m_keywords; + // sorted, string ends with the id of the operator + StringList m_operators; + // sorted, each entry ends with the id of the comment start + StringList m_commentStarts; + // index: id content: comment_end + StringList m_commentEnds; + // index: ord(char) content: a sum of CharClassTags + int m_charInfo[128]; + // a list of QChars with ord(cc) > 127 and which can be the first char + QByteArray m_idFirstRare; + // index: ord(char) content: chr(ix) can be the non first char of an id + QByteArray m_idRestRare; + // a list of QChars with ord(cc) > 127 and which can be the first char + int m_numericTypes; + QByteArray m_idRest2; + ReToken* m_currentToken; + ReToken* m_waitingToken; + ReToken* m_waitingToken2; + ReToken m_token1; + ReToken m_token2; + const ReSourcePosition* m_currentPosition; + const ReSourcePosition* m_waitingPosition1; + const ReSourcePosition* m_waitingPosition2; + int m_maxTokenLength; + QByteArray m_input; + int m_currentCol; + bool m_hasMoreInput; + int m_stringFeatures; + int m_storageFlags; + /// priority of the operators: index: id of the operator. content: prio + char m_prioOfOp[128]; + char m_assocOfOp[128]; + QList m_opNames; #if defined (RPL_LEXER_TRACE) - bool m_trace; + bool m_trace; #endif }; - #endif // RPLLEXER_HPP diff --git a/expr/ReMFParser.cpp b/expr/ReMFParser.cpp index 38475da..27c0fe6 100644 --- a/expr/ReMFParser.cpp +++ b/expr/ReMFParser.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * ReMFParser.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * @brief A parser for the language ML. @@ -16,58 +19,58 @@ #include "base/rebase.hpp" #include "expr/reexpr.hpp" -enum MFLocations{ - L_PARSE_OPERAND_RPARENTH = 2001, - L_PARSE_OPERAND_RPARENTH_INFO, - L_TERM_WRONG_STRING, - L_TERM_WRONG_NUMBER, - L_PARSE_OPERAND_WRONG = 2005, - L_DEFINITION_NO_ID, - L_DEFINITION_WRONG_ID, - L_DEFINITION_UNKNOWN_CLASS, - L_DEFINITION_MISSING_ID, - L_DEFINITION_NO_OP = 2010, - L_DEFINITION_NO_SEMICOLON, - L_PARSE_IF_NO_THEN, - L_PARSE_IF_NO_ELSE, - L_PARSE_IF_NO_FI, - L_PARSE_WHILE_NO_DO = 2015, - L_PARSE_WHILE_NO_OD, - L_PARSE_REPEAT_NO_UNTIL, - L_PARSE_REPEAT_NO_SEMI, - L_PARSE_BODY_WRONG_ITEM, - L_PARSE_FOR_NO_TO = 2020, - L_PARSE_LIST_NO_COMMA, - L_PARSE_MAP_BOOL, - L_PARSE_MAP_NONE, - L_PARSE_MAP_NUMERIC, - L_PARSE_MAP_EXPR = 2025, - L_PARSE_MAP_EXPR2, - L_PARSE_MAP_NO_COLON, - L_PARSE_MAP_NO_COMMA, - L_PARSE_OPERAND_NOT_OPERAND = 2030, - L_PARSE_BODY_NO_START, - L_PARSE_OPERAND_NO_BRACKET, - L_PARSE_ARGS_NO_COMMA_OR_PARENT, - L_PARSE_OPERAND_NO_FIELD2, - L_PARSE_OPERAND_NO_BRACKET2 = 2035, - L_PARSE_OPERAND_NO_FIELD, - L_PARSE_METH_NO_CLASS, - L_PARSE_METH_NO_CLASS2, - L_PARSE_METH_NO_NAME, - L_PARSE_METH_NO_NAME2 = 2040, - L_PARSE_METH_NO_LPARENTH, - L_PARSE_METH_NO_COLON, - L_PARSE_PARAMLIST_NO_PARENTH, - L_PARSE_PARAMLIST_NO_PARENTH2, - L_PARSE_METH_NO_END = 2045, - L_PARSE_METH_NO_END2, - L_PARSE_VAR_DEF_ALREADY_DEFINED, - L_PARSE_VAR_DEF_ALREADY_DEFINED2, - L_PARSE_CLASS_NO_NAME, - L_PARSE_CLASS_LOWERCASE = 2050, - L_PARSE_CLASS_ALREADY_DEFINED, - L_PARSE_CLASS_ALREADY_DEFINED2 +enum MFLocations { + L_PARSE_OPERAND_RPARENTH = 2001, + L_PARSE_OPERAND_RPARENTH_INFO, + L_TERM_WRONG_STRING, + L_TERM_WRONG_NUMBER, + L_PARSE_OPERAND_WRONG = 2005, + L_DEFINITION_NO_ID, + L_DEFINITION_WRONG_ID, + L_DEFINITION_UNKNOWN_CLASS, + L_DEFINITION_MISSING_ID, + L_DEFINITION_NO_OP = 2010, + L_DEFINITION_NO_SEMICOLON, + L_PARSE_IF_NO_THEN, + L_PARSE_IF_NO_ELSE, + L_PARSE_IF_NO_FI, + L_PARSE_WHILE_NO_DO = 2015, + L_PARSE_WHILE_NO_OD, + L_PARSE_REPEAT_NO_UNTIL, + L_PARSE_REPEAT_NO_SEMI, + L_PARSE_BODY_WRONG_ITEM, + L_PARSE_FOR_NO_TO = 2020, + L_PARSE_LIST_NO_COMMA, + L_PARSE_MAP_BOOL, + L_PARSE_MAP_NONE, + L_PARSE_MAP_NUMERIC, + L_PARSE_MAP_EXPR = 2025, + L_PARSE_MAP_EXPR2, + L_PARSE_MAP_NO_COLON, + L_PARSE_MAP_NO_COMMA, + L_PARSE_OPERAND_NOT_OPERAND = 2030, + L_PARSE_BODY_NO_START, + L_PARSE_OPERAND_NO_BRACKET, + L_PARSE_ARGS_NO_COMMA_OR_PARENT, + L_PARSE_OPERAND_NO_FIELD2, + L_PARSE_OPERAND_NO_BRACKET2 = 2035, + L_PARSE_OPERAND_NO_FIELD, + L_PARSE_METH_NO_CLASS, + L_PARSE_METH_NO_CLASS2, + L_PARSE_METH_NO_NAME, + L_PARSE_METH_NO_NAME2 = 2040, + L_PARSE_METH_NO_LPARENTH, + L_PARSE_METH_NO_COLON, + L_PARSE_PARAMLIST_NO_PARENTH, + L_PARSE_PARAMLIST_NO_PARENTH2, + L_PARSE_METH_NO_END = 2045, + L_PARSE_METH_NO_END2, + L_PARSE_VAR_DEF_ALREADY_DEFINED, + L_PARSE_VAR_DEF_ALREADY_DEFINED2, + L_PARSE_CLASS_NO_NAME, + L_PARSE_CLASS_LOWERCASE = 2050, + L_PARSE_CLASS_ALREADY_DEFINED, + L_PARSE_CLASS_ALREADY_DEFINED2 }; @@ -81,80 +84,75 @@ enum MFLocations{ */ ReMFParser::ReMFParser(ReSource& source, ReASTree& abstractSyntaxTree) : - ReParser(m_lexer, abstractSyntaxTree), - m_lexer(&source, - MF_KEYWORDS, MF_OPERATORS, MF_RIGHT_ASSOCIATIVES, - "/* */ // \n", - "a-zA-Z_", "a-zA-Z0-9_", - ReLexer::NUMTYPE_ALL, ReLexer::SF_LIKE_C) -{ + ReParser(m_lexer, abstractSyntaxTree), + m_lexer(&source, + MF_KEYWORDS, MF_OPERATORS, MF_RIGHT_ASSOCIATIVES, "/* */ // \n", + "a-zA-Z_", "a-zA-Z0-9_", ReLexer::NUMTYPE_ALL, + ReLexer::SF_LIKE_C){ } /** * @brief Parses an if statement. */ -ReASItem* ReMFParser::parseIf() -{ - ReASIf* rc = new ReASIf(); - rc->setPosition(m_lexer.currentPosition()); +ReASItem* ReMFParser::parseIf(){ + ReASIf* rc = new ReASIf(); + rc->setPosition(m_lexer.currentPosition()); - ReASItem* condition = parseExpr(0); - if (! m_lexer.currentToken()->isKeyword(K_THEN)) - syntaxError(L_PARSE_IF_NO_THEN, "'then' expected"); - rc->setChild2(condition); - ReASItem* body = parseBody(K_ELSE, K_FI); - rc->setChild3(body); - if (! m_lexer.currentToken()->isKeyword(K_ELSE, K_FI)) - syntaxError(L_PARSE_IF_NO_ELSE, "'else' or 'fi' expected"); - if ( m_lexer.currentToken()->isKeyword(K_ELSE)){ - ReASItem* body = parseBody(K_FI); - rc->setChild4(body); - } - if (! m_lexer.currentToken()->isKeyword(K_FI)) - syntaxError(L_PARSE_IF_NO_FI, "'fi' expected"); - m_lexer.nextNonSpaceToken(); - return rc; + ReASItem* condition = parseExpr(0); + if (!m_lexer.currentToken()->isKeyword(K_THEN)) + syntaxError(L_PARSE_IF_NO_THEN, "'then' expected"); + rc->setChild2(condition); + ReASItem* body = parseBody(K_ELSE, K_FI); + rc->setChild3(body); + if (!m_lexer.currentToken()->isKeyword(K_ELSE, K_FI)) + syntaxError(L_PARSE_IF_NO_ELSE, "'else' or 'fi' expected"); + if (m_lexer.currentToken()->isKeyword(K_ELSE)){ + ReASItem* body = parseBody(K_FI); + rc->setChild4(body); + } + if (!m_lexer.currentToken()->isKeyword(K_FI)) + syntaxError(L_PARSE_IF_NO_FI, "'fi' expected"); + m_lexer.nextNonSpaceToken(); + return rc; } /** * @brief Parses a while statement. */ -ReASItem* ReMFParser::parseWhile() -{ - ReASWhile* rc = new ReASWhile(); - rc->setPosition(m_lexer.currentPosition()); +ReASItem* ReMFParser::parseWhile(){ + ReASWhile* rc = new ReASWhile(); + rc->setPosition(m_lexer.currentPosition()); - ReASItem* condition = parseExpr(0); - if (! m_lexer.currentToken()->isKeyword(K_DO)) - syntaxError(L_PARSE_WHILE_NO_DO, "'do' expected"); - rc->setChild2(condition); - ReASItem* body = parseBody(K_OD); - rc->setChild3(body); - if (! m_lexer.currentToken()->isKeyword(K_OD)) - syntaxError(L_PARSE_WHILE_NO_OD, "'od' expected"); - m_lexer.nextNonSpaceToken(); - return rc; + ReASItem* condition = parseExpr(0); + if (!m_lexer.currentToken()->isKeyword(K_DO)) + syntaxError(L_PARSE_WHILE_NO_DO, "'do' expected"); + rc->setChild2(condition); + ReASItem* body = parseBody(K_OD); + rc->setChild3(body); + if (!m_lexer.currentToken()->isKeyword(K_OD)) + syntaxError(L_PARSE_WHILE_NO_OD, "'od' expected"); + m_lexer.nextNonSpaceToken(); + return rc; } /** * @brief Parses a repeat statement. */ -ReASItem* ReMFParser::parseRepeat() -{ - ReASRepeat* rc = new ReASRepeat(); - rc->setPosition(m_lexer.currentPosition()); +ReASItem* ReMFParser::parseRepeat(){ + ReASRepeat* rc = new ReASRepeat(); + rc->setPosition(m_lexer.currentPosition()); - ReASItem* body = parseBody(K_UNTIL); - rc->setChild3(body); - if (! m_lexer.currentToken()->isKeyword(K_UNTIL)) - syntaxError(L_PARSE_REPEAT_NO_UNTIL, "'until' expected"); + ReASItem* body = parseBody(K_UNTIL); + rc->setChild3(body); + if (!m_lexer.currentToken()->isKeyword(K_UNTIL)) + syntaxError(L_PARSE_REPEAT_NO_UNTIL, "'until' expected"); - ReASItem* condition = parseExpr(0); - if (! m_lexer.currentToken()->isOperator(O_SEMICOLON)) - syntaxError(L_PARSE_REPEAT_NO_SEMI, "';' expected"); - rc->setChild2(condition); - m_lexer.nextNonSpaceToken(); - return rc; + ReASItem* condition = parseExpr(0); + if (!m_lexer.currentToken()->isOperator(O_SEMICOLON)) + syntaxError(L_PARSE_REPEAT_NO_SEMI, "';' expected"); + rc->setChild2(condition); + m_lexer.nextNonSpaceToken(); + return rc; } /** @@ -162,16 +160,15 @@ ReASItem* ReMFParser::parseRepeat() * @param var the basic variable data * @return */ -ReASVarDefinition* ReMFParser::buildVarDef(ReASNamedValue* var) -{ - ReASVarDefinition* rc = new ReASVarDefinition(); - rc->setPosition(var->position()); - rc->setChild2(var); - ReSymbolSpace* symbols = m_tree.currentSpace(); - int varNo; - symbols->addVariable(rc, varNo); - var->setVariableNo(varNo); - return rc; +ReASVarDefinition* ReMFParser::buildVarDef(ReASNamedValue* var){ + ReASVarDefinition* rc = new ReASVarDefinition(); + rc->setPosition(var->position()); + rc->setChild2(var); + ReSymbolSpace* symbols = m_tree.currentSpace(); + int varNo; + symbols->addVariable(rc, varNo); + var->setVariableNo(varNo); + return rc; } /** @@ -186,60 +183,57 @@ ReASVarDefinition* ReMFParser::buildVarDef(ReASNamedValue* var) * @post the token behind the do is read * @return the abstract syntax tree of the for statement */ -ReASItem* ReMFParser::parseFor() -{ - int builtinVars = 1; - ReASNode2* rc = NULL; - const ReSourcePosition* startPosition = m_lexer.currentPosition(); - ReToken* token = m_lexer.nextNonSpaceToken(); - ReASNamedValue* var = NULL; - if (token->isTokenType(TOKEN_ID)){ - var = new ReASNamedValue(ReASInteger::m_instance, - m_tree.currentSpace(), token->toString(), - ReASNamedValue::A_LOOP); - var->setPosition(m_lexer.currentPosition()); - token = m_lexer.nextNonSpaceToken(); - } - if (token->isKeyword(K_IN)){ - ReASVarDefinition* varDef = buildVarDef(var); - ReASForIterated* node = new ReASForIterated(varDef); - rc = node; - node->setPosition(startPosition); - node->setChild3(var); - ReASItem* iterable = parseExpr(0); - node->setChild4(iterable); - } else { - if (var == NULL){ - char name[32]; - // Build a unique name inside the scope: - qsnprintf(name, sizeof name, "$%d_%d", startPosition->lineNo(), - startPosition->column()); - var = new ReASNamedValue(ReASInteger::m_instance, - m_tree.currentSpace(), name, - ReASNamedValue::A_LOOP); - var->setPosition(startPosition); - } - ReASVarDefinition* varDef = buildVarDef(var); - ReASForCounted* node = new ReASForCounted(varDef); - rc = node; - node->setPosition(startPosition); - node->setChild3(var); - if (token->isKeyword(K_FROM)){ - node->setChild4(parseExpr(0)); - } - if (! m_lexer.currentToken()->isKeyword(K_TO)){ - syntaxError(L_PARSE_FOR_NO_TO, "'to' expected"); - } - node->setChild5(parseExpr(0)); - if (m_lexer.currentToken()->isKeyword(K_STEP)){ - node->setChild6(parseExpr(0)); - } - } - if (! m_lexer.currentToken()->isKeyword(K_DO)) - syntaxError(L_PARSE_FOR_NO_TO, "'to' expected"); - rc->setChild2(parseBody(K_OD, K_UNDEF, builtinVars)); - m_lexer.nextNonSpaceToken(); - return rc; +ReASItem* ReMFParser::parseFor(){ + int builtinVars = 1; + ReASNode2* rc = NULL; + const ReSourcePosition* startPosition = m_lexer.currentPosition(); + ReToken* token = m_lexer.nextNonSpaceToken(); + ReASNamedValue* var = NULL; + if (token->isTokenType(TOKEN_ID)){ + var = new ReASNamedValue(ReASInteger::m_instance, m_tree.currentSpace(), + token->toString(), ReASNamedValue::A_LOOP); + var->setPosition(m_lexer.currentPosition()); + token = m_lexer.nextNonSpaceToken(); + } + if (token->isKeyword(K_IN)){ + ReASVarDefinition* varDef = buildVarDef(var); + ReASForIterated* node = new ReASForIterated(varDef); + rc = node; + node->setPosition(startPosition); + node->setChild3(var); + ReASItem* iterable = parseExpr(0); + node->setChild4(iterable); + }else{ + if (var == NULL){ + char name[32]; + // Build a unique name inside the scope: + qsnprintf(name, sizeof name, "$%d_%d", startPosition->lineNo(), + startPosition->column()); + var = new ReASNamedValue(ReASInteger::m_instance, + m_tree.currentSpace(), name, ReASNamedValue::A_LOOP); + var->setPosition(startPosition); + } + ReASVarDefinition* varDef = buildVarDef(var); + ReASForCounted* node = new ReASForCounted(varDef); + rc = node; + node->setPosition(startPosition); + node->setChild3(var); + if (token->isKeyword(K_FROM)){ + node->setChild4(parseExpr(0)); + } + if (!m_lexer.currentToken()->isKeyword(K_TO)){ + syntaxError(L_PARSE_FOR_NO_TO, "'to' expected"); + } + node->setChild5(parseExpr(0)); + if (m_lexer.currentToken()->isKeyword(K_STEP)){ + node->setChild6(parseExpr(0)); + } + } + if (!m_lexer.currentToken()->isKeyword(K_DO)) + syntaxError(L_PARSE_FOR_NO_TO, "'to' expected"); + rc->setChild2(parseBody(K_OD, K_UNDEF, builtinVars)); + m_lexer.nextNonSpaceToken(); + return rc; } /** @@ -255,56 +249,54 @@ ReASItem* ReMFParser::parseFor() * @return a variable/parameter definition */ ReASVarDefinition* ReMFParser::parseVarDefinition( - ReASNamedValue::Attributes attribute) -{ - int attributes = attribute; - ReToken* token = m_lexer.currentToken(); - while(token->isKeyword(K_CONST, K_LAZY)){ - switch(token->id()){ - case K_CONST: - attributes += ReASNamedValue::A_CONST; - break; - case K_LAZY: - attributes += ReASNamedValue::A_LAZY; - break; - default: - break; - } - token = m_lexer.nextNonSpaceToken(); - } - if (! token->isTokenType(TOKEN_ID)) - syntaxError(L_DEFINITION_NO_ID, "class name expected, but no id found"); - if (! token->isCapitalizedId()) - syntaxError(L_DEFINITION_WRONG_ID, - "a class name must start with an upper case character"); - ReASClass* clazz = m_tree.currentSpace()->findClass(token->toString()); - if (clazz == NULL) - syntaxError(L_DEFINITION_UNKNOWN_CLASS, "unknown class"); - token = m_lexer.nextNonSpaceToken(); - if (! token->isTokenType(TOKEN_ID)) - syntaxError(L_DEFINITION_MISSING_ID, "variable name expected"); - ReSymbolSpace* symbols = m_tree.currentSpace(); - // freed in the destructor of the nodes: - ReASNamedValue* namedValue = new ReASNamedValue(clazz, symbols, - token->toString(), - attributes); - namedValue->setPosition(m_lexer.currentPosition()); - ReASVarDefinition* rc = new ReASVarDefinition(); - rc->setPosition(m_lexer.currentPosition()); - rc->setChild2(namedValue); - token = m_lexer.nextNonSpaceToken(); - if (token->id() == O_ASSIGN){ - ReASItem* value = parseExpr(0); - rc->setChild3(value); - token = m_lexer.currentToken(); - } - int varNo = 0; - ReASItem* oldSymbol = symbols->addVariable(rc, varNo); - if (oldSymbol != NULL) - error(L_PARSE_VAR_DEF_ALREADY_DEFINED, oldSymbol->position(), - "symbol already defined", "previous definition"); - namedValue->setVariableNo(varNo); - return rc; + ReASNamedValue::Attributes attribute){ + int attributes = attribute; + ReToken* token = m_lexer.currentToken(); + while (token->isKeyword(K_CONST, K_LAZY)){ + switch (token->id()) { + case K_CONST: + attributes += ReASNamedValue::A_CONST; + break; + case K_LAZY: + attributes += ReASNamedValue::A_LAZY; + break; + default: + break; + } + token = m_lexer.nextNonSpaceToken(); + } + if (!token->isTokenType(TOKEN_ID)) + syntaxError(L_DEFINITION_NO_ID, "class name expected, but no id found"); + if (!token->isCapitalizedId()) + syntaxError(L_DEFINITION_WRONG_ID, + "a class name must start with an upper case character"); + ReASClass* clazz = m_tree.currentSpace()->findClass(token->toString()); + if (clazz == NULL) + syntaxError(L_DEFINITION_UNKNOWN_CLASS, "unknown class"); + token = m_lexer.nextNonSpaceToken(); + if (!token->isTokenType(TOKEN_ID)) + syntaxError(L_DEFINITION_MISSING_ID, "variable name expected"); + ReSymbolSpace* symbols = m_tree.currentSpace(); + // freed in the destructor of the nodes: + ReASNamedValue* namedValue = new ReASNamedValue(clazz, symbols, + token->toString(), attributes); + namedValue->setPosition(m_lexer.currentPosition()); + ReASVarDefinition* rc = new ReASVarDefinition(); + rc->setPosition(m_lexer.currentPosition()); + rc->setChild2(namedValue); + token = m_lexer.nextNonSpaceToken(); + if (token->id() == O_ASSIGN){ + ReASItem* value = parseExpr(0); + rc->setChild3(value); + token = m_lexer.currentToken(); + } + int varNo = 0; + ReASItem* oldSymbol = symbols->addVariable(rc, varNo); + if (oldSymbol != NULL) + error(L_PARSE_VAR_DEF_ALREADY_DEFINED, oldSymbol->position(), + "symbol already defined", "previous definition"); + namedValue->setVariableNo(varNo); + return rc; } /** @@ -315,21 +307,20 @@ ReASVarDefinition* ReMFParser::parseVarDefinition( * the new expression is chained into the parent * @return the variant containing the formula */ -ReASVariant* ReMFParser::createFormula(ReASNode1* parent) -{ - ReASVariant* variant = NULL; - m_lexer.undoLastToken2(); - ReASExprStatement* expr = dynamic_cast - (parseExprStatement(false)); - if (expr != NULL){ - // chaining per m_child (= next statement) is for freeing while destruction: - expr->setChild(parent->child()); - parent->setChild(expr); - // freed in the destructor of varList (~ReASVariant()): - variant = new ReASVariant(); - variant->setObject(expr, ReASFormula::m_instance); - } - return variant; +ReASVariant* ReMFParser::createFormula(ReASNode1* parent){ + ReASVariant* variant = NULL; + m_lexer.undoLastToken2(); + ReASExprStatement* expr = + dynamic_cast (parseExprStatement(false)); + if (expr != NULL){ + // chaining per m_child (= next statement) is for freeing while destruction: + expr->setChild(parent->child()); + parent->setChild(expr); + // freed in the destructor of varList (~ReASVariant()): + variant = new ReASVariant(); + variant->setObject(expr, ReASFormula::m_instance); + } + return variant; } /** @@ -345,50 +336,49 @@ ReASVariant* ReMFParser::createFormula(ReASNode1* parent) * @param parent the parent node of the expression * @return the variant with the token's content */ -ReASVariant* ReMFParser::tokenToVariant(ReToken* token, - bool endsWithComma, ReASNode1* parent) -{ - ReASVariant* variant = NULL; - if (endsWithComma){ - switch(token->tokenType()){ - case TOKEN_NUMBER: +ReASVariant* ReMFParser::tokenToVariant(ReToken* token, bool endsWithComma, + ReASNode1* parent){ + ReASVariant* variant = NULL; + if (endsWithComma){ + switch (token->tokenType()) { + case TOKEN_NUMBER: + // freed in the destructor of varList (~ReASVariant()): + variant = new ReASVariant(); + variant->setInt(token->asInteger()); + break; + case TOKEN_STRING: + // freed in the destructor of varList (~ReASVariant()): + variant = new ReASVariant(); + variant->setString(token->toString()); + break; + case TOKEN_REAL: + // freed in the destructor of varList (~ReASVariant()): + variant = new ReASVariant(); + variant->setFloat(token->asReal()); + break; + case TOKEN_KEYWORD: + switch (token->id()) { + case K_TRUE: + case K_FALSE: // freed in the destructor of varList (~ReASVariant()): variant = new ReASVariant(); - variant->setInt(token->asInteger()); + variant->setBool(token->id() == K_TRUE); break; - case TOKEN_STRING: + case K_NONE: // freed in the destructor of varList (~ReASVariant()): variant = new ReASVariant(); - variant->setString(token->toString()); break; - case TOKEN_REAL: - // freed in the destructor of varList (~ReASVariant()): - variant = new ReASVariant(); - variant->setFloat(token->asReal()); + default: break; - case TOKEN_KEYWORD: - switch(token->id()){ - case K_TRUE: - case K_FALSE: - // freed in the destructor of varList (~ReASVariant()): - variant = new ReASVariant(); - variant->setBool(token->id() == K_TRUE); - break; - case K_NONE: - // freed in the destructor of varList (~ReASVariant()): - variant = new ReASVariant(); - break; - default: - break; - } - break; - default: - break; - } - } - if (variant == NULL) - variant = createFormula(parent); - return variant; + } + break; + default: + break; + } + } + if (variant == NULL) + variant = createFormula(parent); + return variant; } /** @@ -401,42 +391,40 @@ ReASVariant* ReMFParser::tokenToVariant(ReToken* token, * @post the token behind the ']' is read * @return a node of the abstract syntax tree */ -ReASItem* ReMFParser::parseList() -{ - ReASListConstant* rc = new ReASListConstant(); - ReASVariant& varList = rc->value(); - ReASListOfVariants* list = static_cast - (varList.asObject(NULL)); - rc->setPosition(m_lexer.currentPosition()); - ReASVariant* variant; - bool again = true; - ReToken* token; - ReToken* token2; - // read the token behind '[': - token = m_lexer.nextNonSpaceToken(); - if (token->isOperator(O_RBRACKET)){ - // read token behind ']': - m_lexer.nextNonSpaceToken(); - } else{ - while(again){ - m_lexer.saveLastToken(); - token2 = m_lexer.nextNonSpaceToken(); - variant = tokenToVariant(token, token2->isOperator(O_COMMA), rc); - token = m_lexer.currentToken(); - if (token->isOperator(O_RBRACKET)) - again = false; - else if (! token->isOperator(O_COMMA)) - syntaxError(L_PARSE_LIST_NO_COMMA, "',' or ']' expected"); - // read token behind ',' or ']' - token = m_lexer.nextNonSpaceToken(); - if (variant != NULL) - list->append(variant); - } - } - return rc; +ReASItem* ReMFParser::parseList(){ + ReASListConstant* rc = new ReASListConstant(); + ReASVariant& varList = rc->value(); + ReASListOfVariants* list = + static_cast (varList.asObject(NULL)); + rc->setPosition(m_lexer.currentPosition()); + ReASVariant* variant; + bool again = true; + ReToken* token; + ReToken* token2; + // read the token behind '[': + token = m_lexer.nextNonSpaceToken(); + if (token->isOperator(O_RBRACKET)){ + // read token behind ']': + m_lexer.nextNonSpaceToken(); + }else{ + while (again){ + m_lexer.saveLastToken(); + token2 = m_lexer.nextNonSpaceToken(); + variant = tokenToVariant(token, token2->isOperator(O_COMMA), rc); + token = m_lexer.currentToken(); + if (token->isOperator(O_RBRACKET)) + again = false; + else if (!token->isOperator(O_COMMA)) + syntaxError(L_PARSE_LIST_NO_COMMA, "',' or ']' expected"); + // read token behind ',' or ']' + token = m_lexer.nextNonSpaceToken(); + if (variant != NULL) + list->append(variant); + } + } + return rc; } - /** * @brief Parses a map. * @@ -447,76 +435,75 @@ ReASItem* ReMFParser::parseList() * @post the token behind the '}' is read * @return a node of the abstract syntax tree */ -ReASItem* ReMFParser::parseMap() -{ - ReASMapConstant* rc = new ReASMapConstant(); - ReASVariant& varMap = rc->value(); - ReASMapOfVariants* map = static_cast - (varMap.asObject(NULL)); - rc->setPosition(m_lexer.currentPosition()); - ReASVariant* variant; - bool again = true; - ReToken* token; - ReToken* token2; - QByteArray key; - while(again){ - token = m_lexer.nextNonSpaceToken(); - if (token->isOperator(O_RBRACE)) - again = false; - else{ - key.clear(); - switch(token->tokenType()){ - case TOKEN_STRING: - // freed in the destructor of varList (~ReASVariant()): - key = token->toString(); - break; - case TOKEN_KEYWORD: - switch(token->id()){ - case K_TRUE: - case K_FALSE: - syntaxError(L_PARSE_MAP_BOOL, - "boolean value not allowed as key type. Use a string"); - break; - case K_NONE: - syntaxError(L_PARSE_MAP_NONE, - "'none' is not allowed as key type. Use a string"); - break; - default: - syntaxError(L_PARSE_MAP_EXPR, - "a non constant expression is not allowed as key type. Use a string"); - break; - } - break; - case TOKEN_NUMBER: - case TOKEN_REAL: - syntaxError(L_PARSE_MAP_NUMERIC, - "numeric values not allowed as key type. Use a string"); - break; +ReASItem* ReMFParser::parseMap(){ + ReASMapConstant* rc = new ReASMapConstant(); + ReASVariant& varMap = rc->value(); + ReASMapOfVariants* map = static_cast (varMap.asObject( + NULL)); + rc->setPosition(m_lexer.currentPosition()); + ReASVariant* variant; + bool again = true; + ReToken* token; + ReToken* token2; + QByteArray key; + while (again){ + token = m_lexer.nextNonSpaceToken(); + if (token->isOperator(O_RBRACE)) + again = false; + else{ + key.clear(); + switch (token->tokenType()) { + case TOKEN_STRING: + // freed in the destructor of varList (~ReASVariant()): + key = token->toString(); + break; + case TOKEN_KEYWORD: + switch (token->id()) { + case K_TRUE: + case K_FALSE: + syntaxError(L_PARSE_MAP_BOOL, + "boolean value not allowed as key type. Use a string"); + break; + case K_NONE: + syntaxError(L_PARSE_MAP_NONE, + "'none' is not allowed as key type. Use a string"); + break; default: - syntaxError(L_PARSE_MAP_EXPR2, - "a non constant expression is not allowed as key type. Use a string"); - break; + syntaxError(L_PARSE_MAP_EXPR, + "a non constant expression is not allowed as key type. Use a string"); + break; } + break; + case TOKEN_NUMBER: + case TOKEN_REAL: + syntaxError(L_PARSE_MAP_NUMERIC, + "numeric values not allowed as key type. Use a string"); + break; + default: + syntaxError(L_PARSE_MAP_EXPR2, + "a non constant expression is not allowed as key type. Use a string"); + break; + } + token = m_lexer.nextNonSpaceToken(); + if (!token->isOperator(O_COLON)){ + syntaxError(L_PARSE_MAP_NO_COLON, "':' expected"); + }else{ token = m_lexer.nextNonSpaceToken(); - if (! token->isOperator(O_COLON)){ - syntaxError(L_PARSE_MAP_NO_COLON, "':' expected"); - } else { - token = m_lexer.nextNonSpaceToken(); - m_lexer.saveLastToken(); - token2 = m_lexer.nextNonSpaceToken(); - variant = tokenToVariant(token, token2->isOperator(O_COMMA), rc); - (*map)[key] = variant; - variant = NULL; - token = m_lexer.currentToken(); - if (token->isOperator(O_RBRACE)) - again = false; - else if (! token->isOperator(O_COMMA)) - syntaxError(L_PARSE_MAP_NO_COMMA, "',' or '}' expected"); - } - } - } - m_lexer.nextNonSpaceToken(); - return rc; + m_lexer.saveLastToken(); + token2 = m_lexer.nextNonSpaceToken(); + variant = tokenToVariant(token, token2->isOperator(O_COMMA), rc); + (*map)[key] = variant; + variant = NULL; + token = m_lexer.currentToken(); + if (token->isOperator(O_RBRACE)) + again = false; + else if (!token->isOperator(O_COMMA)) + syntaxError(L_PARSE_MAP_NO_COMMA, "',' or '}' expected"); + } + } + } + m_lexer.nextNonSpaceToken(); + return rc; } /** @@ -530,26 +517,25 @@ ReASItem* ReMFParser::parseMap() * ReASNamedValue instance */ ReASItem* ReMFParser::buildVarOrField(const QByteArray& name, - const ReSourcePosition* position, ReASItem* parent) -{ - ReASItem* rc = NULL; - if (parent == NULL){ - ReSymbolSpace* space = m_tree.currentSpace(); - ReASVarDefinition* var = space->findVariable(name); - ReASClass* clazz = NULL; - if (var != NULL) - clazz = var->clazz(); - ReASNamedValue* var2 = new ReASNamedValue(clazz, space, - name, ReASNamedValue::A_NONE); - var2->setPosition(position); - rc = var2; - } else { - ReASField* field = new ReASField(name); - field->setPosition(position); - rc = field; - field->setChild(parent); - } - return rc; + const ReSourcePosition* position, ReASItem* parent){ + ReASItem* rc = NULL; + if (parent == NULL){ + ReSymbolSpace* space = m_tree.currentSpace(); + ReASVarDefinition* var = space->findVariable(name); + ReASClass* clazz = NULL; + if (var != NULL) + clazz = var->clazz(); + ReASNamedValue* var2 = new ReASNamedValue(clazz, space, name, + ReASNamedValue::A_NONE); + var2->setPosition(position); + rc = var2; + }else{ + ReASField* field = new ReASField(name); + field->setPosition(position); + rc = field; + field->setChild(parent); + } + return rc; } /** * @brief Converts a MF specific unary operator into one of AST. @@ -558,33 +544,32 @@ ReASItem* ReMFParser::buildVarOrField(const QByteArray& name, * * @return operator known by the abstract syntax tree */ -ReASUnaryOp::UnaryOp ReMFParser::convertUnaryOp(int op) -{ - ReASUnaryOp::UnaryOp rc; - switch(op){ - case O_PLUS: - rc = ReASUnaryOp::UOP_PLUS; - break; - case O_MINUS: - rc = ReASUnaryOp::UOP_MINUS_INT; - break; - case O_NOT: - rc = ReASUnaryOp::UOP_NOT_BOOL; - break; - case O_BIT_NOT: - rc = ReASUnaryOp::UOP_NOT_INT; - break; - case O_INC: - rc = ReASUnaryOp::UOP_INC; - break; - case O_DEC: - rc = ReASUnaryOp::UOP_DEC; - break; - default: - throw ReException("unknown unary operator %d", op); - break; - } - return rc; +ReASUnaryOp::UnaryOp ReMFParser::convertUnaryOp(int op){ + ReASUnaryOp::UnaryOp rc; + switch (op) { + case O_PLUS: + rc = ReASUnaryOp::UOP_PLUS; + break; + case O_MINUS: + rc = ReASUnaryOp::UOP_MINUS_INT; + break; + case O_NOT: + rc = ReASUnaryOp::UOP_NOT_BOOL; + break; + case O_BIT_NOT: + rc = ReASUnaryOp::UOP_NOT_INT; + break; + case O_INC: + rc = ReASUnaryOp::UOP_INC; + break; + case O_DEC: + rc = ReASUnaryOp::UOP_DEC; + break; + default: + throw ReException("unknown unary operator %d", op); + break; + } + return rc; } /** @@ -596,143 +581,136 @@ ReASUnaryOp::UnaryOp ReMFParser::convertUnaryOp(int op) * @post the token behind the operand is read * @return the node with the operand */ -ReASItem* ReMFParser::parseOperand(int level, ReASItem* parent) -{ - ReToken* token = m_lexer.nextNonSpaceToken(); - const ReSourcePosition* startPosition = m_lexer.currentPosition(); - ReASItem* rc = NULL; - bool readNext = true; - switch(token->tokenType()){ - case TOKEN_OPERATOR: - { - Operator opId = (Operator) token->id(); - if (parent != NULL && opId != O_LBRACKET) - syntaxError(L_PARSE_OPERAND_NO_FIELD, - "field expected (behind a '.')"); - if (opId == O_LBRACKET){ - if (parent == NULL){ - rc = parseList(); - readNext = false; - } else { - ReASIndexedValue* value = new ReASIndexedValue(); - value->setPosition(startPosition); - value->setChild(parent); - rc = value; - value->setChild2(parseExpr(level + 1)); - if (! m_lexer.currentToken()->isOperator(O_RBRACKET)) - syntaxError(L_PARSE_OPERAND_NO_BRACKET2, - "']' expected"); - } - } else if (opId == O_LBRACE){ - rc = parseMap(); +ReASItem* ReMFParser::parseOperand(int level, ReASItem* parent){ + ReToken* token = m_lexer.nextNonSpaceToken(); + const ReSourcePosition* startPosition = m_lexer.currentPosition(); + ReASItem* rc = NULL; + bool readNext = true; + switch (token->tokenType()) { + case TOKEN_OPERATOR: { + Operator opId = (Operator) token->id(); + if (parent != NULL && opId != O_LBRACKET) + syntaxError(L_PARSE_OPERAND_NO_FIELD, "field expected (behind a '.')"); + if (opId == O_LBRACKET){ + if (parent == NULL){ + rc = parseList(); readNext = false; - } else if (opId == O_LPARENTH){ - rc = parseExpr(level + 1); - token = m_lexer.currentToken(); - if(! token->isOperator(O_RPARENTH)){ - // this call never comes back (exception!) - syntaxError(L_PARSE_OPERAND_RPARENTH, - "')' expected", "(", startPosition); + }else{ + ReASIndexedValue* value = new ReASIndexedValue(); + value->setPosition(startPosition); + value->setChild(parent); + rc = value; + value->setChild2(parseExpr(level + 1)); + if (!m_lexer.currentToken()->isOperator(O_RBRACKET)) + syntaxError(L_PARSE_OPERAND_NO_BRACKET2, "']' expected"); + } + }else if (opId == O_LBRACE){ + rc = parseMap(); + readNext = false; + }else if (opId == O_LPARENTH){ + rc = parseExpr(level + 1); + token = m_lexer.currentToken(); + if (!token->isOperator(O_RPARENTH)){ + // this call never comes back (exception!) + syntaxError(L_PARSE_OPERAND_RPARENTH, "')' expected", "(", + startPosition); + } + }else if (IS_UNARY_OP(opId)){ + ReASUnaryOp* op = new ReASUnaryOp(convertUnaryOp(token->id()), + AST_PRE_UNARY_OP); + op->setPosition(m_lexer.currentPosition()); + op->setChild(parseOperand(level)); + readNext = false; + rc = op; + }else + syntaxError(L_PARSE_OPERAND_NOT_OPERAND, + "operand expected, not an operator"); + break; + } + case TOKEN_STRING: + case TOKEN_NUMBER: + case TOKEN_REAL: { + if (parent != NULL) + syntaxError(L_PARSE_OPERAND_NO_FIELD2, + "field expected (behind a '.')"); + ReASConstant* constant = new ReASConstant(); + constant->setPosition(m_lexer.currentPosition()); + rc = constant; + switch (token->tokenType()) { + case TOKEN_STRING: + constant->value().setString(token->toString()); + break; + case TOKEN_NUMBER: + constant->value().setInt(token->asInteger()); + break; + case TOKEN_REAL: + constant->value().setFloat(token->asReal()); + break; + default: + break; + } + break; + } + case TOKEN_ID: { + QByteArray name = token->toString(); + if (name == "a") + name = "a"; + token = m_lexer.nextNonSpaceToken(); + startPosition = m_lexer.currentPosition(); + if (token->tokenType() != TOKEN_OPERATOR){ + rc = buildVarOrField(name, startPosition, parent); + readNext = false; + }else{ + if (token->id() == O_LPARENTH){ + ReASMethodCall* call = new ReASMethodCall(name, parent); + call->setPosition(startPosition); + + rc = call; + token = m_lexer.nextNonSpaceToken(); + if (!token->isOperator(O_RPARENTH)){ + m_lexer.undoLastToken(); + ReASExprStatement* args = parseArguments(); + call->setChild2(args); + readNext = false; } - } else if (IS_UNARY_OP(opId)){ - ReASUnaryOp* op = new ReASUnaryOp(convertUnaryOp(token->id()), - AST_PRE_UNARY_OP); - op->setPosition(m_lexer.currentPosition()); - op->setChild(parseOperand(level)); - readNext = false; - rc = op; - } else - syntaxError(L_PARSE_OPERAND_NOT_OPERAND, - "operand expected, not an operator"); - break; - } - case TOKEN_STRING: - case TOKEN_NUMBER: - case TOKEN_REAL: - { - if (parent != NULL) - syntaxError(L_PARSE_OPERAND_NO_FIELD2, - "field expected (behind a '.')"); - ReASConstant* constant = new ReASConstant(); - constant->setPosition(m_lexer.currentPosition()); - rc = constant; - switch(token->tokenType()){ - case TOKEN_STRING: - constant->value().setString(token->toString()); - break; - case TOKEN_NUMBER: - constant->value().setInt(token->asInteger()); - break; - case TOKEN_REAL: - constant->value().setFloat(token->asReal()); - break; - default: - break; - } - break; - } - case TOKEN_ID: - { - QByteArray name = token->toString(); - if (name == "a") - name = "a"; - token = m_lexer.nextNonSpaceToken(); - startPosition = m_lexer.currentPosition(); - if (token->tokenType() != TOKEN_OPERATOR){ + }else{ rc = buildVarOrField(name, startPosition, parent); - readNext = false; - } else { - if (token->id() == O_LPARENTH){ - ReASMethodCall* call = new ReASMethodCall(name, parent); - call->setPosition(startPosition); - - rc = call; - token = m_lexer.nextNonSpaceToken(); - if (! token->isOperator(O_RPARENTH)){ - m_lexer.undoLastToken(); - ReASExprStatement* args = parseArguments(); - call->setChild2(args); - readNext = false; - } - } else { - rc = buildVarOrField(name, startPosition, parent); - if (token->id() == O_LBRACKET){ - ReASItem* indexExpr = parseExpr(0); - if (! m_lexer.currentToken()->isOperator(O_RBRACKET)) - syntaxError(L_PARSE_OPERAND_NO_BRACKET, "']' expected"); - dynamic_cast(rc)->setChild(indexExpr); - } else { - if (token->id() == O_INC || token->id() == O_DEC){ - ReASUnaryOp* op = new ReASUnaryOp(convertUnaryOp( - token->id()), - AST_POST_UNARY_OP); - op->setChild(rc); - rc = op; - } else { - readNext = false; - } - } + if (token->id() == O_LBRACKET){ + ReASItem* indexExpr = parseExpr(0); + if (!m_lexer.currentToken()->isOperator(O_RBRACKET)) + syntaxError(L_PARSE_OPERAND_NO_BRACKET, "']' expected"); + dynamic_cast (rc)->setChild(indexExpr); + }else{ + if (token->id() == O_INC || token->id() == O_DEC){ + ReASUnaryOp* op = new ReASUnaryOp(convertUnaryOp(token->id()), + AST_POST_UNARY_OP); + op->setChild(rc); + rc = op; + }else{ + readNext = false; + } } - } - break; - } - case TOKEN_END_OF_SOURCE: - readNext = false; - break; - default: - // this call never comes back (exception!) - syntaxError(L_PARSE_OPERAND_WRONG, - "unexpected symbol detected. Operand expected"); - break; - } - if (readNext) - m_lexer.nextNonSpaceToken(); - if (m_lexer.currentToken()->isOperator(O_DOT, O_LBRACKET)){ - if (m_lexer.currentToken()->asInteger() == O_LBRACKET) - m_lexer.undoLastToken(); - rc = parseOperand(level, rc); - } - return rc; + } + } + break; + } + case TOKEN_END_OF_SOURCE: + readNext = false; + break; + default: + // this call never comes back (exception!) + syntaxError(L_PARSE_OPERAND_WRONG, + "unexpected symbol detected. Operand expected"); + break; + } + if (readNext) + m_lexer.nextNonSpaceToken(); + if (m_lexer.currentToken()->isOperator(O_DOT, O_LBRACKET)){ + if (m_lexer.currentToken()->asInteger() == O_LBRACKET) + m_lexer.undoLastToken(); + rc = parseOperand(level, rc); + } + return rc; } /** * @brief Converts a MF specific binary operator into one of AST. @@ -742,109 +720,109 @@ ReASItem* ReMFParser::parseOperand(int level, ReASItem* parent) * @return operator known by the abstract syntax tree */ ReASBinaryOp::BinOperator ReMFParser::convertBinaryOp(int op){ - ReASBinaryOp::BinOperator rc; - switch(op){ - case ReMFParser::O_ASSIGN: - rc = ReASBinaryOp::BOP_ASSIGN; - break; - case ReMFParser::O_PLUS_ASSIGN: - rc = ReASBinaryOp::BOP_PLUS_ASSIGN; - break; - case ReMFParser::O_MINUS_ASSIGN: - rc = ReASBinaryOp::BOP_MINUS_ASSIGN; - break; - case ReMFParser::O_DIV_ASSIGN: - rc = ReASBinaryOp::BOP_DIV_ASSIGN; - break; - case ReMFParser::O_TIMES_ASSIGN: - rc = ReASBinaryOp::BOP_TIMES_ASSIGN; - break; - case ReMFParser::O_MOD_ASSIGN: - rc = ReASBinaryOp::BOP_MOD_ASSIGN; - break; - case ReMFParser::O_POWER_ASSIGN: - rc = ReASBinaryOp::BOP_POWER_ASSIGN; - break; - case ReMFParser::O_OR_ASSIGN: - rc = ReASBinaryOp::BOP_LOG_OR_ASSIGN; - break; - case ReMFParser::O_AND_ASSIGN: - rc = ReASBinaryOp::BOP_LOG_AND_ASSIGN; - break; - case ReMFParser::O_LSHIFT_ASSIGN: - rc = ReASBinaryOp::BOP_LSHIFT_ASSIGN; - break; - case ReMFParser::O_RSHIFT_ASSIGN: - rc = ReASBinaryOp::BOP_LOG_RSHIFT_ASSIGN; - break; - case ReMFParser::O_RSHIFT2_ASSIGN: - rc = ReASBinaryOp::BOP_ARTITH_RSHIFT_ASSIGN; - break; - case ReMFParser::O_OR: - rc = ReASBinaryOp::BOP_LOG_OR; - break; - case ReMFParser::O_AND: - rc = ReASBinaryOp::BOP_LOG_AND; - break; - case ReMFParser::O_EQ: - rc = ReASBinaryOp::BOP_EQ; - break; - case ReMFParser::O_NE: - rc = ReASBinaryOp::BOP_NE; - break; - case ReMFParser::O_LT: - rc = ReASBinaryOp::BOP_LT; - break; - case ReMFParser::O_GT: - rc = ReASBinaryOp::BOP_GT; - break; - case ReMFParser::O_LE: - rc = ReASBinaryOp::BOP_LE; - break; - case ReMFParser::O_GE: - rc = ReASBinaryOp::BOP_GE; - break; - case ReMFParser::O_PLUS: - rc = ReASBinaryOp::BOP_PLUS; - break; - case ReMFParser::O_MINUS: - rc = ReASBinaryOp::BOP_MINUS; - break; - case ReMFParser::O_DIV: - rc = ReASBinaryOp::BOP_DIV; - break; - case ReMFParser::O_MOD: - rc = ReASBinaryOp::BOP_MOD; - break; - case ReMFParser::O_TIMES: - rc = ReASBinaryOp::BOP_TIMES; - break; - case ReMFParser::O_POWER: - rc = ReASBinaryOp::BOP_POWER; - break; - case ReMFParser::O_XOR: - rc = ReASBinaryOp::BOP_LOG_XOR; - break; - case ReMFParser::O_BIT_OR: - rc = ReASBinaryOp::BOP_BIT_OR; - break; - case ReMFParser::O_BIT_AND: - rc = ReASBinaryOp::BOP_BIT_AND; - break; - case ReMFParser::O_LSHIFT: - rc = ReASBinaryOp::BOP_LSHIFT; - break; - case ReMFParser::O_RSHIFT: - rc = ReASBinaryOp::BOP_LOG_RSHIFT; - break; - case ReMFParser::O_RSHIFT2: - rc = ReASBinaryOp::BOP_ARTITH_RSHIFT; - break; - default: - throw ReException("unknown binary operator %d", op); - break; - } - return rc; + ReASBinaryOp::BinOperator rc; + switch (op) { + case ReMFParser::O_ASSIGN: + rc = ReASBinaryOp::BOP_ASSIGN; + break; + case ReMFParser::O_PLUS_ASSIGN: + rc = ReASBinaryOp::BOP_PLUS_ASSIGN; + break; + case ReMFParser::O_MINUS_ASSIGN: + rc = ReASBinaryOp::BOP_MINUS_ASSIGN; + break; + case ReMFParser::O_DIV_ASSIGN: + rc = ReASBinaryOp::BOP_DIV_ASSIGN; + break; + case ReMFParser::O_TIMES_ASSIGN: + rc = ReASBinaryOp::BOP_TIMES_ASSIGN; + break; + case ReMFParser::O_MOD_ASSIGN: + rc = ReASBinaryOp::BOP_MOD_ASSIGN; + break; + case ReMFParser::O_POWER_ASSIGN: + rc = ReASBinaryOp::BOP_POWER_ASSIGN; + break; + case ReMFParser::O_OR_ASSIGN: + rc = ReASBinaryOp::BOP_LOG_OR_ASSIGN; + break; + case ReMFParser::O_AND_ASSIGN: + rc = ReASBinaryOp::BOP_LOG_AND_ASSIGN; + break; + case ReMFParser::O_LSHIFT_ASSIGN: + rc = ReASBinaryOp::BOP_LSHIFT_ASSIGN; + break; + case ReMFParser::O_RSHIFT_ASSIGN: + rc = ReASBinaryOp::BOP_LOG_RSHIFT_ASSIGN; + break; + case ReMFParser::O_RSHIFT2_ASSIGN: + rc = ReASBinaryOp::BOP_ARTITH_RSHIFT_ASSIGN; + break; + case ReMFParser::O_OR: + rc = ReASBinaryOp::BOP_LOG_OR; + break; + case ReMFParser::O_AND: + rc = ReASBinaryOp::BOP_LOG_AND; + break; + case ReMFParser::O_EQ: + rc = ReASBinaryOp::BOP_EQ; + break; + case ReMFParser::O_NE: + rc = ReASBinaryOp::BOP_NE; + break; + case ReMFParser::O_LT: + rc = ReASBinaryOp::BOP_LT; + break; + case ReMFParser::O_GT: + rc = ReASBinaryOp::BOP_GT; + break; + case ReMFParser::O_LE: + rc = ReASBinaryOp::BOP_LE; + break; + case ReMFParser::O_GE: + rc = ReASBinaryOp::BOP_GE; + break; + case ReMFParser::O_PLUS: + rc = ReASBinaryOp::BOP_PLUS; + break; + case ReMFParser::O_MINUS: + rc = ReASBinaryOp::BOP_MINUS; + break; + case ReMFParser::O_DIV: + rc = ReASBinaryOp::BOP_DIV; + break; + case ReMFParser::O_MOD: + rc = ReASBinaryOp::BOP_MOD; + break; + case ReMFParser::O_TIMES: + rc = ReASBinaryOp::BOP_TIMES; + break; + case ReMFParser::O_POWER: + rc = ReASBinaryOp::BOP_POWER; + break; + case ReMFParser::O_XOR: + rc = ReASBinaryOp::BOP_LOG_XOR; + break; + case ReMFParser::O_BIT_OR: + rc = ReASBinaryOp::BOP_BIT_OR; + break; + case ReMFParser::O_BIT_AND: + rc = ReASBinaryOp::BOP_BIT_AND; + break; + case ReMFParser::O_LSHIFT: + rc = ReASBinaryOp::BOP_LSHIFT; + break; + case ReMFParser::O_RSHIFT: + rc = ReASBinaryOp::BOP_LOG_RSHIFT; + break; + case ReMFParser::O_RSHIFT2: + rc = ReASBinaryOp::BOP_ARTITH_RSHIFT; + break; + default: + throw ReException("unknown binary operator %d", op); + break; + } + return rc; } /** @@ -865,60 +843,57 @@ ReASBinaryOp::BinOperator ReMFParser::convertBinaryOp(int op){ * @return the abstract syntax tree representing the parsed expression */ ReASItem* ReMFParser::parseExpr(int depth){ - ReToken* token; - ReASItem* top = parseOperand(depth); - if (top != NULL){ - int lastPrio = INT_MAX; - bool again = true; - do { - token = m_lexer.currentToken(); - switch(token->tokenType()){ - case TOKEN_OPERATOR: - { - Operator opId = (Operator) token->id(); - if (IS_BINARY_OP(opId)){ - ReASBinaryOp* op = new ReASBinaryOp(); - op->setPosition(m_lexer.currentPosition()); - op->setOperator(convertBinaryOp(opId)); + ReToken* token; + ReASItem* top = parseOperand(depth); + if (top != NULL){ + int lastPrio = INT_MAX; + bool again = true; + do{ + token = m_lexer.currentToken(); + switch (token->tokenType()) { + case TOKEN_OPERATOR: { + Operator opId = (Operator) token->id(); + if (IS_BINARY_OP(opId)){ + ReASBinaryOp* op = new ReASBinaryOp(); + op->setPosition(m_lexer.currentPosition()); + op->setOperator(convertBinaryOp(opId)); - int prio = m_lexer.prioOfOp(token->id()); - if (prio < lastPrio - || (prio == lastPrio - && ! m_lexer.isRightAssociative(opId))){ - op->setChild(top); - top = op; - } else { - // right assoc or higher priority: - ReASBinaryOp* top2 = dynamic_cast(top); - op->setChild(top2->child2()); - top2->setChild2(op); - } - lastPrio = prio; - op->setChild2(parseOperand(depth)); - } else - again = false; - break; - } - case TOKEN_STRING: - syntaxError(L_TERM_WRONG_STRING, "Operator expected, not a string"); - break; - case TOKEN_NUMBER: - case TOKEN_REAL: - syntaxError(L_TERM_WRONG_NUMBER, "Operator expected, not a number"); - break; - case TOKEN_KEYWORD: - case TOKEN_ID: - case TOKEN_END_OF_SOURCE: - default: - again = false; - break; - } - } while(again); - } - return top; + int prio = m_lexer.prioOfOp(token->id()); + if (prio < lastPrio + || (prio == lastPrio && !m_lexer.isRightAssociative(opId))){ + op->setChild(top); + top = op; + }else{ + // right assoc or higher priority: + ReASBinaryOp* top2 = dynamic_cast (top); + op->setChild(top2->child2()); + top2->setChild2(op); + } + lastPrio = prio; + op->setChild2(parseOperand(depth)); + }else + again = false; + break; + } + case TOKEN_STRING: + syntaxError(L_TERM_WRONG_STRING, "Operator expected, not a string"); + break; + case TOKEN_NUMBER: + case TOKEN_REAL: + syntaxError(L_TERM_WRONG_NUMBER, "Operator expected, not a number"); + break; + case TOKEN_KEYWORD: + case TOKEN_ID: + case TOKEN_END_OF_SOURCE: + default: + again = false; + break; + } + }while (again); + } + return top; } - /** * @brief Parses an expression as a statement. * @@ -928,18 +903,17 @@ ReASItem* ReMFParser::parseExpr(int depth){ * @param eatSemicolon true: a trailing ';' will be read * @return the abstract syntax tree of the expression statement */ -ReASItem* ReMFParser::parseExprStatement(bool eatSemicolon) -{ - ReASItem* item = parseExpr(0); - ReASExprStatement* statement = NULL; - if (item != NULL){ - statement = new ReASExprStatement(); - statement->setPosition(item->position()); - statement->setChild2(item); - } - if (eatSemicolon && m_lexer.currentToken()->isOperator(O_SEMICOLON)) - m_lexer.nextNonSpaceToken(); - return statement; +ReASItem* ReMFParser::parseExprStatement(bool eatSemicolon){ + ReASItem* item = parseExpr(0); + ReASExprStatement* statement = NULL; + if (item != NULL){ + statement = new ReASExprStatement(); + statement->setPosition(item->position()); + statement->setChild2(item); + } + if (eatSemicolon && m_lexer.currentToken()->isOperator(O_SEMICOLON)) + m_lexer.nextNonSpaceToken(); + return statement; } /** @@ -948,8 +922,8 @@ ReASItem* ReMFParser::parseExprStatement(bool eatSemicolon) * @return the variable definition */ ReASItem* ReMFParser::parseLocalVar(){ - ReASItem* rc = parseVarDefinition(ReASNamedValue::A_NONE); - return rc; + ReASItem* rc = parseVarDefinition(ReASNamedValue::A_NONE); + return rc; } /** @@ -963,136 +937,133 @@ ReASItem* ReMFParser::parseLocalVar(){ * @return the first element of the statement list */ ReASItem* ReMFParser::parseBody(Keyword keywordStop, Keyword keywordStop2, - int builtinVars) -{ - ReToken* token = m_lexer.nextNonSpaceToken(); - ReASItem* item = NULL; - ReASItem* body = NULL; - ReASNode1* lastStatement = NULL; - ReASScope scope; - m_tree.currentSpace()->startScope(scope); - scope.m_builtInVars = builtinVars; - bool again = true; - const ReSourcePosition* lastPos = NULL; - do { - token = m_lexer.currentToken(); - if (lastPos == m_lexer.currentPosition()) - syntaxError(L_PARSE_BODY_NO_START, "no statement starts with this symbol"); - lastPos = m_lexer.currentPosition(); - // eat a superflous ';' - if (token->isOperator(O_SEMICOLON)) - token = m_lexer.nextNonSpaceToken(); - try { - switch(token->tokenType()) - { - case TOKEN_OPERATOR: - case TOKEN_STRING: - case TOKEN_NUMBER: - case TOKEN_REAL: - m_lexer.undoLastToken(); - item = parseExprStatement(); - break; - case TOKEN_KEYWORD: - switch (token->id()){ - case K_IF: - item = parseIf(); - break; - case K_WHILE: - item = parseWhile(); - break; - case K_REPEAT: - item = parseRepeat(); - break; - case K_FOR: - item = parseFor(); - break; - case K_CLASS: - parseClass(); - item = NULL; - break; - case K_FUNCTION: - case K_GENERATOR: - parseMethod(); - item = NULL; - break; - case K_IMPORT: - parseImport(); - item = NULL; - break; - case K_CONST: - case K_LAZY: - item = parseLocalVar(); - break; - default: - if (token->isKeyword(keywordStop, keywordStop2)) - again = false; - break; - } - break; - case TOKEN_ID: - { - if (token->isCapitalizedId()){ - item = parseLocalVar(); - } else { - m_lexer.undoLastToken(); - item = parseExprStatement(); - } - break; - } - case TOKEN_END_OF_SOURCE: - again = false; - break; + int builtinVars){ + ReToken* token = m_lexer.nextNonSpaceToken(); + ReASItem* item = NULL; + ReASItem* body = NULL; + ReASNode1* lastStatement = NULL; + ReASScope scope; + m_tree.currentSpace()->startScope(scope); + scope.m_builtInVars = builtinVars; + bool again = true; + const ReSourcePosition* lastPos = NULL; + do{ + token = m_lexer.currentToken(); + if (lastPos == m_lexer.currentPosition()) + syntaxError(L_PARSE_BODY_NO_START, + "no statement starts with this symbol"); + lastPos = m_lexer.currentPosition(); + // eat a superflous ';' + if (token->isOperator(O_SEMICOLON)) + token = m_lexer.nextNonSpaceToken(); + try{ + switch (token->tokenType()) { + case TOKEN_OPERATOR: + case TOKEN_STRING: + case TOKEN_NUMBER: + case TOKEN_REAL: + m_lexer.undoLastToken(); + item = parseExprStatement(); + break; + case TOKEN_KEYWORD: + switch (token->id()) { + case K_IF: + item = parseIf(); + break; + case K_WHILE: + item = parseWhile(); + break; + case K_REPEAT: + item = parseRepeat(); + break; + case K_FOR: + item = parseFor(); + break; + case K_CLASS: + parseClass(); + item = NULL; + break; + case K_FUNCTION: + case K_GENERATOR: + parseMethod(); + item = NULL; + break; + case K_IMPORT: + parseImport(); + item = NULL; + break; + case K_CONST: + case K_LAZY: + item = parseLocalVar(); + break; default: - break; + if (token->isKeyword(keywordStop, keywordStop2)) + again = false; + break; } - if (again && item != NULL){ - if (body == NULL){ - body = item; - } else { - lastStatement->setChild(item); - } - lastStatement = dynamic_cast(item); - if (lastStatement == NULL) - error(L_PARSE_BODY_WRONG_ITEM, "wrong item type: %d", - item == NULL ? 0 : item->nodeType()); - token = m_lexer.currentToken(); - if (keywordStop != K_UNDEF - && token->isKeyword(keywordStop, keywordStop2)) - again = false; + break; + case TOKEN_ID: { + if (token->isCapitalizedId()){ + item = parseLocalVar(); + }else{ + m_lexer.undoLastToken(); + item = parseExprStatement(); + } + break; + } + case TOKEN_END_OF_SOURCE: + again = false; + break; + default: + break; + } + if (again && item != NULL){ + if (body == NULL){ + body = item; + }else{ + lastStatement->setChild(item); } - } catch(RSyntaxError exc){ - // we look for the end of the statement: + lastStatement = dynamic_cast (item); + if (lastStatement == NULL) + error(L_PARSE_BODY_WRONG_ITEM, "wrong item type: %d", + item == NULL ? 0 : item->nodeType()); token = m_lexer.currentToken(); - RplTokenType type; - Operator op; - Keyword key; - while( (type = token->tokenType()) != TOKEN_END_OF_SOURCE) - if (type == TOKEN_OPERATOR - && ((op = Operator(token->id())) == O_SEMICOLON - || op == O_SEMI_SEMICOLON)) - break; - else if (type == TOKEN_KEYWORD){ - key = Keyword(token->id()); - if (key == K_ENDC || key == K_ENDF){ - // we need the token again! - m_lexer.undoLastToken(); - break; - } else if (key == K_FI || key == K_OD){ - break; - } else { - token = m_lexer.nextNonSpaceToken(); - } - } else { - token = m_lexer.nextNonSpaceToken(); - } - } - } while(again); + if (keywordStop != K_UNDEF + && token->isKeyword(keywordStop, keywordStop2)) + again = false; + } + } catch (ReSyntaxError exc){ + // we look for the end of the statement: + token = m_lexer.currentToken(); + RplTokenType type; + Operator op; + Keyword key; + while ((type = token->tokenType()) != TOKEN_END_OF_SOURCE) + if (type == TOKEN_OPERATOR + && ((op = Operator(token->id())) == O_SEMICOLON + || op == O_SEMI_SEMICOLON)) + break; + else if (type == TOKEN_KEYWORD){ + key = Keyword(token->id()); + if (key == K_ENDC || key == K_ENDF){ + // we need the token again! + m_lexer.undoLastToken(); + break; + }else if (key == K_FI || key == K_OD){ + break; + }else{ + token = m_lexer.nextNonSpaceToken(); + } + }else{ + token = m_lexer.nextNonSpaceToken(); + } + } + }while (again); - if (keywordStop != K_ENDF && keywordStop != K_ENDC - && keywordStop != K_UNDEF) - m_tree.currentSpace()->finishScope(m_lexer.currentPosition()->lineNo(), - scope); - return body; + if (keywordStop != K_ENDF && keywordStop != K_ENDC && keywordStop != K_UNDEF) + m_tree.currentSpace()->finishScope(m_lexer.currentPosition()->lineNo(), + scope); + return body; } /** @@ -1103,25 +1074,25 @@ ReASItem* ReMFParser::parseBody(Keyword keywordStop, Keyword keywordStop2, * @return */ ReASVarDefinition* ReMFParser::parseParameterList(){ - ReASVarDefinition* rc = NULL; - ReASVarDefinition* last = NULL; - const ReSourcePosition* startPos = m_lexer.currentPosition(); - ReASItem* definition = NULL; - do { - if (definition != NULL) - m_lexer.nextNonSpaceToken(); - ReASVarDefinition* current = parseVarDefinition(ReASNamedValue::A_PARAM); - if (rc == NULL){ - rc = current; - } else { - last->setChild(current); - } - last = current; - } while(m_lexer.currentToken()->isOperator(O_COMMA)); - if (! m_lexer.currentToken()->isOperator(O_RPARENTH)) - syntaxError(L_PARSE_PARAMLIST_NO_PARENTH, ") expected", ")", startPos); - m_lexer.nextNonSpaceToken(); - return rc; + ReASVarDefinition* rc = NULL; + ReASVarDefinition* last = NULL; + const ReSourcePosition* startPos = m_lexer.currentPosition(); + ReASItem* definition = NULL; + do{ + if (definition != NULL) + m_lexer.nextNonSpaceToken(); + ReASVarDefinition* current = parseVarDefinition(ReASNamedValue::A_PARAM); + if (rc == NULL){ + rc = current; + }else{ + last->setChild(current); + } + last = current; + }while (m_lexer.currentToken()->isOperator(O_COMMA)); + if (!m_lexer.currentToken()->isOperator(O_RPARENTH)) + syntaxError(L_PARSE_PARAMLIST_NO_PARENTH, ") expected", ")", startPos); + m_lexer.nextNonSpaceToken(); + return rc; } /** @@ -1133,53 +1104,52 @@ ReASVarDefinition* ReMFParser::parseParameterList(){ * @post token behind "endf" is read * @return NULL */ -void ReMFParser::parseMethod() -{ - ReASMethod* method = NULL; - const ReSourcePosition* startPos = m_lexer.currentPosition(); - ReToken* token = m_lexer.nextNonSpaceToken(); - if (! token->isTokenType(TOKEN_ID)) - syntaxError(L_PARSE_METH_NO_CLASS, "type name expected"); - QByteArray type = token->toString(); - if (! isupper(type.at(0))) - syntaxError(L_PARSE_METH_NO_CLASS2, - "type name expected (must start with an upper case character)"); - token = m_lexer.nextNonSpaceToken(); - if (! token->isTokenType(TOKEN_ID)) - syntaxError(L_PARSE_METH_NO_NAME, "method name expected"); - QByteArray name = token->toString(); - if (! isupper(type.at(0))) - syntaxError(L_PARSE_METH_NO_CLASS2, - "method name expected (must start with an lower case character)"); - token = m_lexer.nextNonSpaceToken(); - if (! token->isOperator(O_LPARENTH, O_COLON)) - syntaxError(L_PARSE_METH_NO_LPARENTH, "'(' or ':' expected"); +void ReMFParser::parseMethod(){ + ReASMethod* method = NULL; + const ReSourcePosition* startPos = m_lexer.currentPosition(); + ReToken* token = m_lexer.nextNonSpaceToken(); + if (!token->isTokenType(TOKEN_ID)) + syntaxError(L_PARSE_METH_NO_CLASS, "type name expected"); + QByteArray type = token->toString(); + if (!isupper(type.at(0))) + syntaxError(L_PARSE_METH_NO_CLASS2, + "type name expected (must start with an upper case character)"); + token = m_lexer.nextNonSpaceToken(); + if (!token->isTokenType(TOKEN_ID)) + syntaxError(L_PARSE_METH_NO_NAME, "method name expected"); + QByteArray name = token->toString(); + if (!isupper(type.at(0))) + syntaxError(L_PARSE_METH_NO_CLASS2, + "method name expected (must start with an lower case character)"); + token = m_lexer.nextNonSpaceToken(); + if (!token->isOperator(O_LPARENTH, O_COLON)) + syntaxError(L_PARSE_METH_NO_LPARENTH, "'(' or ':' expected"); - ReASVarDefinition* parameterList = NULL; - method = new ReASMethod(name, m_tree); - method->setPosition(startPos); - ReSymbolSpace* symbols = m_tree.currentSpace(); - symbols->addMethod(method); - m_tree.startClassOrMethod(name, ReSymbolSpace::SST_METHOD); - method->setSymbols(); - if (token->isOperator(O_LPARENTH)){ + ReASVarDefinition* parameterList = NULL; + method = new ReASMethod(name, m_tree); + method->setPosition(startPos); + ReSymbolSpace* symbols = m_tree.currentSpace(); + symbols->addMethod(method); + m_tree.startClassOrMethod(name, ReSymbolSpace::SST_METHOD); + method->setSymbols(); + if (token->isOperator(O_LPARENTH)){ token = m_lexer.nextNonSpaceToken(); if (token->isOperator(O_RPARENTH)){ - token = m_lexer.nextNonSpaceToken(); - } else { - parameterList = parseParameterList(); - method->setChild2(parameterList); + token = m_lexer.nextNonSpaceToken(); + }else{ + parameterList = parseParameterList(); + method->setChild2(parameterList); } - } - if (! token->isOperator(O_COLON)) - syntaxError(L_PARSE_METH_NO_COLON, "':' expected"); + } + if (!token->isOperator(O_COLON)) + syntaxError(L_PARSE_METH_NO_COLON, "':' expected"); - method->setChild(parseBody(K_ENDF)); - if (! m_lexer.currentToken()->isKeyword(K_ENDF)) - syntaxError(L_PARSE_METH_NO_END, "end of function not found", "endf", - startPos); - m_lexer.nextNonSpaceToken(); - m_tree.finishClassOrMethod(name); + method->setChild(parseBody(K_ENDF)); + if (!m_lexer.currentToken()->isKeyword(K_ENDF)) + syntaxError(L_PARSE_METH_NO_END, "end of function not found", "endf", + startPos); + m_lexer.nextNonSpaceToken(); + m_tree.finishClassOrMethod(name); } /** @@ -1188,33 +1158,32 @@ void ReMFParser::parseMethod() * @pre "class" is read * @post token behind "endc" is read */ -void ReMFParser::parseClass() -{ - const ReSourcePosition* startPos = m_lexer.currentPosition(); - ReToken* token = m_lexer.nextNonSpaceToken(); - if (! token->isTokenType(TOKEN_ID)) - syntaxError(L_PARSE_CLASS_NO_NAME, "class name expected"); - if (! token->isCapitalizedId()) - syntaxError(L_PARSE_CLASS_LOWERCASE, "class name must start with an uppercase character"); - QByteArray name = token->toString(); - ReASUserClass* clazz = new ReASUserClass(name, startPos, m_tree); - ReSymbolSpace* parent = m_tree.currentSpace(); - ReASUserClass* alreadyDefined = parent->addClass(clazz); - if (alreadyDefined != NULL){ - error(L_PARSE_CLASS_ALREADY_DEFINED, alreadyDefined->position(), - "class already defined", "previous defined class"); - } - m_tree.startClassOrMethod(name, ReSymbolSpace::SST_CLASS); - clazz->setSymbols(); +void ReMFParser::parseClass(){ + const ReSourcePosition* startPos = m_lexer.currentPosition(); + ReToken* token = m_lexer.nextNonSpaceToken(); + if (!token->isTokenType(TOKEN_ID)) + syntaxError(L_PARSE_CLASS_NO_NAME, "class name expected"); + if (!token->isCapitalizedId()) + syntaxError(L_PARSE_CLASS_LOWERCASE, + "class name must start with an uppercase character"); + QByteArray name = token->toString(); + ReASUserClass* clazz = new ReASUserClass(name, startPos, m_tree); + ReSymbolSpace* parent = m_tree.currentSpace(); + ReASUserClass* alreadyDefined = parent->addClass(clazz); + if (alreadyDefined != NULL){ + error(L_PARSE_CLASS_ALREADY_DEFINED, alreadyDefined->position(), + "class already defined", "previous defined class"); + } + m_tree.startClassOrMethod(name, ReSymbolSpace::SST_CLASS); + clazz->setSymbols(); - m_tree.finishClassOrMethod(name); + m_tree.finishClassOrMethod(name); } /** * @brief Parses a the import statement */ -void ReMFParser::parseImport() -{ +void ReMFParser::parseImport(){ } @@ -1226,30 +1195,28 @@ void ReMFParser::parseImport() * * @param name the name of the module (without path) */ -ReASItem* ReMFParser::parseModule(ReSourceUnitName name) -{ - m_tree.startModule(name); - // parse until EOF: - ReASItem* body = parseBody(K_UNDEF); - m_tree.finishModule(name); - return body; +ReASItem* ReMFParser::parseModule(ReSourceUnitName name){ + m_tree.startModule(name); + // parse until EOF: + ReASItem* body = parseBody(K_UNDEF); + m_tree.finishModule(name); + return body; } /** * @brief Parse the input given by the source. */ -void ReMFParser::parse() -{ - ReSource* source = m_lexer.source(); - ReSourceUnit* mainModule = source->currentReader()->currentSourceUnit(); - ReSourceUnitName mainModuleName = mainModule->name(); - try { - ReASItem* body = parseModule(mainModuleName); - ReSymbolSpace* module = m_tree.findmodule(mainModuleName); - if (module != NULL) - module->setBody(body); - } catch(RplParserStop exc){ - printf("compiling aborted: %s\n", exc.reason()); - } +void ReMFParser::parse(){ + ReSource* source = m_lexer.source(); + ReSourceUnit* mainModule = source->currentReader()->currentSourceUnit(); + ReSourceUnitName mainModuleName = mainModule->name(); + try{ + ReASItem* body = parseModule(mainModuleName); + ReSymbolSpace* module = m_tree.findmodule(mainModuleName); + if (module != NULL) + module->setBody(body); + } catch (RplParserStop exc){ + printf("compiling aborted: %s\n", exc.reason()); + } } /** @@ -1259,28 +1226,27 @@ void ReMFParser::parse() * @post the token behind the ')' is read * @return the first element of the argument list */ -ReASExprStatement* ReMFParser::parseArguments() -{ - ReASExprStatement* first = NULL; - ReASExprStatement* last = NULL; - bool again = false; - do { - ReASItem* expr = parseExpr(0); - if (! m_lexer.currentToken()->isOperator(O_COMMA, O_RPARENTH)) - syntaxError(L_PARSE_ARGS_NO_COMMA_OR_PARENT, "',' or ')' expected"); - again = m_lexer.currentToken()->isOperator(O_COMMA); - ReASExprStatement* current = new ReASExprStatement(); - current->setPosition(expr->position()); - current->setChild2(expr); - if (first == NULL) - first = last = current; - else{ - last->setChild(current); - last = current; - } - } while (again); - // skip ')': - m_lexer.nextNonSpaceToken(); - return first; +ReASExprStatement* ReMFParser::parseArguments(){ + ReASExprStatement* first = NULL; + ReASExprStatement* last = NULL; + bool again = false; + do{ + ReASItem* expr = parseExpr(0); + if (!m_lexer.currentToken()->isOperator(O_COMMA, O_RPARENTH)) + syntaxError(L_PARSE_ARGS_NO_COMMA_OR_PARENT, "',' or ')' expected"); + again = m_lexer.currentToken()->isOperator(O_COMMA); + ReASExprStatement* current = new ReASExprStatement(); + current->setPosition(expr->position()); + current->setChild2(expr); + if (first == NULL) + first = last = current; + else{ + last->setChild(current); + last = current; + } + }while (again); + // skip ')': + m_lexer.nextNonSpaceToken(); + return first; } diff --git a/expr/ReMFParser.hpp b/expr/ReMFParser.hpp index fb5aeca..e8f6c42 100644 --- a/expr/ReMFParser.hpp +++ b/expr/ReMFParser.hpp @@ -1,49 +1,99 @@ /* - * Licence: + * ReMFParser.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ - + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #ifndef REMFPARSER_HPP #define REMFPARSER_HPP -class ReMFParser : public ReParser -{ +class ReMFParser: public ReParser { public: - enum Keyword { - K_UNDEF, K_IF, K_THEN, K_ELSE, K_FI, K_WHILE, // 5 - K_DO, K_OD, K_REPEAT, K_UNTIL, K_FOR, // 10 - K_FROM, K_TO, K_STEP, K_IN, K_CASE, // 15 - K_OF, K_ESAC, K_LEAVE, K_CONTINUE, K_PASS, // 20 - K_CLASS, K_ENDC, K_ENDF, K_FUNCTION, K_GENERATOR, // 25 - K_IMPORT, K_CONST, K_LAZY, K_NONE, K_TRUE, // 30 - K_FALSE - }; + enum Keyword { + K_UNDEF, K_IF, K_THEN, K_ELSE, K_FI, K_WHILE, // 5 + K_DO, + K_OD, + K_REPEAT, + K_UNTIL, + K_FOR, // 10 + K_FROM, + K_TO, + K_STEP, + K_IN, + K_CASE, // 15 + K_OF, + K_ESAC, + K_LEAVE, + K_CONTINUE, + K_PASS, // 20 + K_CLASS, + K_ENDC, + K_ENDF, + K_FUNCTION, + K_GENERATOR, // 25 + K_IMPORT, + K_CONST, + K_LAZY, + K_NONE, + K_TRUE, // 30 + K_FALSE + }; #define MF_KEYWORDS "if then else fi while do od repeat until" \ " for from to step in case of esac leave continue pass" \ " class endc endf func generator import" \ " const lazy none true false" - enum Operator { - O_UNDEF, O_SEMI_SEMICOLON, O_SEMICOLON, O_COMMA, O_COLON, // 4 - O_ASSIGN, O_PLUS_ASSIGN, O_MINUS_ASSIGN, O_DIV_ASSIGN, O_TIMES_ASSIGN, // 8 - O_MOD_ASSIGN, O_POWER_ASSIGN, O_OR_ASSIGN, O_AND_ASSIGN, // 13 - O_LSHIFT_ASSIGN, O_RSHIFT_ASSIGN, O_RSHIFT2_ASSIGN, // 16 - O_OR, O_AND, // 18 - O_EQ, O_NE, // 20 - O_LT, O_GT, O_LE, O_GE, // 24 - O_QUESTION, // 25 - O_PLUS, O_MINUS, // 27 - O_DIV, O_MOD, O_TIMES, // 30 - O_POWER, // 31 - O_XOR, O_BIT_OR, O_BIT_AND, // 34 - O_LSHIFT, O_RSHIFT, O_RSHIFT2, // 37 - O_NOT, O_BIT_NOT, // 39 - O_INC, O_DEC, // 41 - O_DOT, O_LPARENTH, O_RPARENTH, O_LBRACKET, O_RBRACKET, O_LBRACE, O_RBRACE // 48 - }; + enum Operator { + O_UNDEF, O_SEMI_SEMICOLON, O_SEMICOLON, O_COMMA, O_COLON, // 4 + O_ASSIGN, + O_PLUS_ASSIGN, + O_MINUS_ASSIGN, + O_DIV_ASSIGN, + O_TIMES_ASSIGN, // 8 + O_MOD_ASSIGN, + O_POWER_ASSIGN, + O_OR_ASSIGN, + O_AND_ASSIGN, // 13 + O_LSHIFT_ASSIGN, + O_RSHIFT_ASSIGN, + O_RSHIFT2_ASSIGN, // 16 + O_OR, + O_AND, // 18 + O_EQ, + O_NE, // 20 + O_LT, + O_GT, + O_LE, + O_GE, // 24 + O_QUESTION, // 25 + O_PLUS, + O_MINUS, // 27 + O_DIV, + O_MOD, + O_TIMES, // 30 + O_POWER, // 31 + O_XOR, + O_BIT_OR, + O_BIT_AND, // 34 + O_LSHIFT, + O_RSHIFT, + O_RSHIFT2, // 37 + O_NOT, + O_BIT_NOT, // 39 + O_INC, + O_DEC, // 41 + O_DOT, + O_LPARENTH, + O_RPARENTH, + O_LBRACKET, + O_RBRACKET, + O_LBRACE, + O_RBRACE // 48 + }; #define IS_BINARY_OP(op) (Operator(op) >= O_ASSIGN && Operator(op) <= O_DOT) #define IS_UNARY_OP(op) (op==O_PLUS || op==O_MINUS || (op>=O_NOT && op<=O_DEC)) @@ -65,43 +115,42 @@ public: ". ( ) [ ] { }" #define MF_RIGHT_ASSOCIATIVES "= += -= /= *= %= **= |= &= <<= >>= >>>= ** ." public: - ReMFParser(ReSource& source, ReASTree& ast); + ReMFParser(ReSource& source, ReASTree& ast); public: - ReASItem* parseIf(); - ReASItem* parseWhile(); - ReASItem* parseRepeat(); - ReASItem* parseFor(); - ReASVarDefinition* parseVarDefinition(ReASNamedValue::Attributes attribute); - ReASItem* parseExpr(int depth); - ReASItem* parseBody(Keyword keywordStop, Keyword keywordStop2 = K_UNDEF, - int builtinVars = 0); - void parseMethod(); - void parseClass(); - void parseImport(); - ReASItem* parseModule(ReSourceUnitName name); - void parse(); - ReASItem*parseExprStatement(bool eatSemicolon = true); - ReASItem*parseList(); - ReASItem*parseMap(); + ReASItem* parseIf(); + ReASItem* parseWhile(); + ReASItem* parseRepeat(); + ReASItem* parseFor(); + ReASVarDefinition* parseVarDefinition(ReASNamedValue::Attributes attribute); + ReASItem* parseExpr(int depth); + ReASItem* parseBody(Keyword keywordStop, Keyword keywordStop2 = K_UNDEF, + int builtinVars = 0); + void parseMethod(); + void parseClass(); + void parseImport(); + ReASItem* parseModule(ReSourceUnitName name); + void parse(); + ReASItem*parseExprStatement(bool eatSemicolon = true); + ReASItem*parseList(); + ReASItem*parseMap(); protected: - ReASExprStatement* parseArguments(); - ReASItem* parseOperand(int level, ReASItem* parent = NULL); - ReASVariant* tokenToVariant(ReToken* token, bool endsWithComma, - ReASNode1* parent); - ReASVariant*createFormula(ReASNode1* parent); - ReASItem* buildVarOrField(const QByteArray& name, - const ReSourcePosition* position, - ReASItem* parent); - ReASVarDefinition* parseParameterList(); - ReASItem* parseLocalVar(); - ReASVarDefinition* buildVarDef(ReASNamedValue* var); + ReASExprStatement* parseArguments(); + ReASItem* parseOperand(int level, ReASItem* parent = NULL); + ReASVariant* tokenToVariant(ReToken* token, bool endsWithComma, + ReASNode1* parent); + ReASVariant*createFormula(ReASNode1* parent); + ReASItem* buildVarOrField(const QByteArray& name, + const ReSourcePosition* position, ReASItem* parent); + ReASVarDefinition* parseParameterList(); + ReASItem* parseLocalVar(); + ReASVarDefinition* buildVarDef(ReASNamedValue* var); protected: - static ReASBinaryOp::BinOperator convertBinaryOp(int op); - static ReASUnaryOp::UnaryOp convertUnaryOp(int op); + static ReASBinaryOp::BinOperator convertBinaryOp(int op); + static ReASUnaryOp::UnaryOp convertUnaryOp(int op); private: - ///syntax token builder. - /// Note: the super class contains a reference with the same name - ReLexer m_lexer; + ///syntax token builder. + /// Note: the super class contains a reference with the same name + ReLexer m_lexer; }; #endif // REMFPARSER_HPP diff --git a/expr/ReParser.cpp b/expr/ReParser.cpp index a0be1bb..b7d5ed2 100644 --- a/expr/ReParser.cpp +++ b/expr/ReParser.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * ReParser.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * @@ -18,8 +21,7 @@ #include "base/rebase.hpp" #include "expr/reexpr.hpp" - -/** @class RSyntaxError ReParser.hpp "expr/ReParser.hpp" +/** @class ReSyntaxError ReParser.hpp "expr/ReParser.hpp" * * @brief Implements an exception used for jumping out from many nested calls. * @@ -37,17 +39,15 @@ * @return */ ReSyntaxError::ReSyntaxError(const char* reason) : - m_reason(reason) -{ + m_reason(reason){ } /** * @brief Returns the description of the exception. * * @return the reason */ -const char* ReSyntaxError::reason() const -{ - return m_reason; +const char* ReSyntaxError::reason() const{ + return m_reason; } /** @class RplParserStop ReParser.hpp "expr/ReParser.hpp" @@ -64,8 +64,7 @@ const char* ReSyntaxError::reason() const * @param reason the reason of the exception */ RplParserStop::RplParserStop(const char* reason) : - ReSyntaxError(reason) -{ + ReSyntaxError(reason){ } /** @class ReParser ReParser.hpp "expr/ReParser.hpp" @@ -81,14 +80,13 @@ RplParserStop::RplParserStop(const char* reason) : * @param tree the abstract syntax tree */ ReParser::ReParser(ReLexer& lexer, ReASTree& tree) : - m_lexer(lexer), - m_tree(tree), - m_messages(), - m_errors(0), - m_warnings(0), - m_maxErrors(20), - m_maxWarnings(20) -{ + m_lexer(lexer), + m_tree(tree), + m_messages(), + m_errors(0), + m_warnings(0), + m_maxErrors(20), + m_maxWarnings(20){ } /** @@ -101,21 +99,19 @@ ReParser::ReParser(ReLexer& lexer, ReASTree& tree) : * @return false (for chaining) */ bool ReParser::addSimpleMessage(LevelTag prefix, int location, - const ReSourcePosition* position, - const char* message){ - char buffer[2048]; - QByteArray msg; - qsnprintf(buffer, sizeof buffer, "%c%04d %s:%d-%d: ", prefix, location, - position->sourceUnit()->name(), - position->lineNo(), position->column()); - int used = strlen(buffer); - int length = strlen(message); - if (length >= (int) sizeof buffer - used) - length = sizeof buffer - used - 1; - memcpy(buffer + used, message, length); - buffer[used + length] = '\0'; - m_messages.append(buffer); - return false; + const ReSourcePosition* position, const char* message){ + char buffer[2048]; + QByteArray msg; + qsnprintf(buffer, sizeof buffer, "%c%04d %s:%d-%d: ", prefix, location, + position->sourceUnit()->name(), position->lineNo(), position->column()); + int used = strlen(buffer); + int length = strlen(message); + if (length >= (int) sizeof buffer - used) + length = sizeof buffer - used - 1; + memcpy(buffer + used, message, length); + buffer[used + length] = '\0'; + m_messages.append(buffer); + return false; } /** @@ -129,11 +125,10 @@ bool ReParser::addSimpleMessage(LevelTag prefix, int location, * @return false (for chaining) */ bool ReParser::addMessage(LevelTag prefix, int location, - const ReSourcePosition* position, - const char* format, va_list varList){ - char buffer[2048]; - qvsnprintf(buffer, sizeof buffer, format, varList); - return addSimpleMessage(prefix, location, position, buffer); + const ReSourcePosition* position, const char* format, va_list varList){ + char buffer[2048]; + qvsnprintf(buffer, sizeof buffer, format, varList); + return addSimpleMessage(prefix, location, position, buffer); } /** @@ -145,10 +140,9 @@ bool ReParser::addMessage(LevelTag prefix, int location, * @param message error message */ -void ReParser::syntaxError(int location, const char* message) -{ - addSimpleMessage(LT_ERROR, location, m_lexer.currentPosition(), message); - throw RSyntaxError(message); +void ReParser::syntaxError(int location, const char* message){ + addSimpleMessage(LT_ERROR, location, m_lexer.currentPosition(), message); + throw ReSyntaxError(message); } /** @@ -167,18 +161,16 @@ void ReParser::syntaxError(int location, const char* message) */ void ReParser::syntaxError(int location, const char* message, - const char* symbol, - const ReSourcePosition* position) -{ - char buffer[256]; - char buffer2[512]; - qsnprintf(buffer2, sizeof buffer2, - "The starting symbol %s is located here. Missing point: %s", - symbol, m_lexer.currentPosition()->utf8(buffer, sizeof buffer)); - - addSimpleMessage(LT_ERROR, location, m_lexer.currentPosition(), message); - addSimpleMessage(LT_INFO, location + 1, position, buffer2); - throw RSyntaxError(message); + const char* symbol, const ReSourcePosition* position){ + char buffer[256]; + char buffer2[512]; + qsnprintf(buffer2, sizeof buffer2, + "The starting symbol %s is located here. Missing point: %s", symbol, + m_lexer.currentPosition()->utf8(buffer, sizeof buffer)); + + addSimpleMessage(LT_ERROR, location, m_lexer.currentPosition(), message); + addSimpleMessage(LT_INFO, location + 1, position, buffer2); + throw ReSyntaxError(message); } /** @@ -191,15 +183,14 @@ void ReParser::syntaxError(int location, const char* message, * @param ... optional: the variable argument list * @return false (for chaining) */ -bool ReParser::error(int location, const char* format, ...) -{ - va_list ap; - va_start(ap, format); - addMessage(LT_ERROR, location, m_lexer.currentPosition(), format, ap); - va_end(ap); - if (++m_errors >= m_maxErrors) - throw RplParserStop("too many errors"); - return false; +bool ReParser::error(int location, const char* format, ...){ + va_list ap; + va_start(ap, format); + addMessage(LT_ERROR, location, m_lexer.currentPosition(), format, ap); + va_end(ap); + if (++m_errors >= m_maxErrors) + throw RplParserStop("too many errors"); + return false; } /** * @brief Adds an error message with an additional info message. @@ -214,13 +205,12 @@ bool ReParser::error(int location, const char* format, ...) * @return false (for chaining) */ bool ReParser::error(int location, const ReSourcePosition* position, - const char* message, const char* message2) -{ - addSimpleMessage(LT_ERROR, location, m_lexer.currentPosition(), message); - addSimpleMessage(LT_INFO, location + 1, position, message2); - if (++m_errors >= m_maxErrors) - throw RplParserStop("too many errors"); - return false; + const char* message, const char* message2){ + addSimpleMessage(LT_ERROR, location, m_lexer.currentPosition(), message); + addSimpleMessage(LT_INFO, location + 1, position, message2); + if (++m_errors >= m_maxErrors) + throw RplParserStop("too many errors"); + return false; } /** @@ -232,32 +222,28 @@ bool ReParser::error(int location, const ReSourcePosition* position, * @param format message with placeholdes like sprintf() * @param ... optional: the variable argument list */ -void ReParser::warning(int location, const char* format, ...) -{ - va_list ap; - va_start(ap, format); - addMessage(LT_WARNING, location, m_lexer.currentPosition(), format, ap); - va_end(ap); - if (++m_warnings >= m_maxWarnings) - throw RplParserStop("too many warnings"); +void ReParser::warning(int location, const char* format, ...){ + va_list ap; + va_start(ap, format); + addMessage(LT_WARNING, location, m_lexer.currentPosition(), format, ap); + va_end(ap); + if (++m_warnings >= m_maxWarnings) + throw RplParserStop("too many warnings"); } /** * @brief Return the number of errors. * * @return the count of errors occurred until now */ -int ReParser::errors() const -{ - return m_errors; +int ReParser::errors() const{ + return m_errors; } /** * @brief Return the number of warnings. * * @return the count of errors occurred until now */ -int ReParser::warnings() const -{ - return m_warnings; +int ReParser::warnings() const{ + return m_warnings; } - diff --git a/expr/ReParser.hpp b/expr/ReParser.hpp index 80b9f15..e0c655e 100644 --- a/expr/ReParser.hpp +++ b/expr/ReParser.hpp @@ -1,66 +1,63 @@ /* - * Licence: + * ReParser.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ - + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #ifndef REPARSER_HPP #define REPARSER_HPP -class ReSyntaxError -{ +class ReSyntaxError { public: - ReSyntaxError(const char* reason); + ReSyntaxError(const char* reason); public: - const char* reason() const; + const char* reason() const; private: - const char* m_reason; + const char* m_reason; }; -class RplParserStop : public ReSyntaxError { +class RplParserStop: public ReSyntaxError { public: - RplParserStop(const char* reason); + RplParserStop(const char* reason); }; class ReParser { public: - enum LevelTag { - LT_ERROR = 'E', - LT_WARNING = 'W', - LT_INFO = 'I' - }; + enum LevelTag { + LT_ERROR = 'E', LT_WARNING = 'W', LT_INFO = 'I' + }; public: - typedef QList MessageList; + typedef QList MessageList; public: - ReParser(ReLexer& lexer, ReASTree& ast); + ReParser(ReLexer& lexer, ReASTree& ast); public: - bool addSimpleMessage(LevelTag prefix, int location, - const ReSourcePosition* pos, - const char* message); - bool addMessage(LevelTag prefix, int location, - const ReSourcePosition* pos, - const char* format, va_list varList); - void syntaxError(int location, const char* message); - void syntaxError(int location, const char* message, const char* symbol, - const ReSourcePosition* position); - bool error(int location, const char* format, ...); - bool error(int location, const ReSourcePosition* position, - const char* message, const char* message2); - void warning(int location, const char* format, ...); - int errors() const; - int warnings() const; + bool addSimpleMessage(LevelTag prefix, int location, + const ReSourcePosition* pos, const char* message); + bool addMessage(LevelTag prefix, int location, const ReSourcePosition* pos, + const char* format, va_list varList); + void syntaxError(int location, const char* message); + void syntaxError(int location, const char* message, const char* symbol, + const ReSourcePosition* position); + bool error(int location, const char* format, ...); + bool error(int location, const ReSourcePosition* position, + const char* message, const char* message2); + void warning(int location, const char* format, ...); + int errors() const; + int warnings() const; protected: - ReLexer& m_lexer; - ReASTree& m_tree; - MessageList m_messages; - int m_errors; - int m_warnings; - int m_maxErrors; - int m_maxWarnings; + ReLexer& m_lexer; + ReASTree& m_tree; + MessageList m_messages; + int m_errors; + int m_warnings; + int m_maxErrors; + int m_maxWarnings; }; #endif // REPARSER_HPP diff --git a/expr/ReSource.cpp b/expr/ReSource.cpp index b9e21e9..3d1a936 100644 --- a/expr/ReSource.cpp +++ b/expr/ReSource.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * ReSource.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * @brief Reading from several input media. @@ -23,7 +26,6 @@ #include "base/rebase.hpp" #include "expr/reexpr.hpp" - /** @class ReSource ReSource.hpp "expr/ReSource.hpp" * * @brief Stores all source positions. @@ -43,23 +45,21 @@ * @param reader the reader which can read the unit */ ReSourceUnit::ReSourceUnit(ReSourceUnitName name, ReReader* reader) : - m_name(name), - m_lineNo(0), - m_reader(reader) { + m_name(name), m_lineNo(0), m_reader(reader){ } /** * @brief Destructor. */ -ReSourceUnit::~ReSourceUnit() { +ReSourceUnit::~ReSourceUnit(){ } /** * @brief Returns the name. * @return the name */ -ReSourceUnitName ReSourceUnit::name() const { - return m_name.constData(); +ReSourceUnitName ReSourceUnit::name() const{ + return m_name.constData(); } /** @@ -67,8 +67,8 @@ ReSourceUnitName ReSourceUnit::name() const { * * @return the line number */ -int ReSourceUnit::lineNo() const { - return m_lineNo; +int ReSourceUnit::lineNo() const{ + return m_lineNo; } /** @@ -76,16 +76,16 @@ int ReSourceUnit::lineNo() const { * * @param lineNo the new line number */ -void ReSourceUnit::setLineNo(int lineNo) { - m_lineNo = lineNo; +void ReSourceUnit::setLineNo(int lineNo){ + m_lineNo = lineNo; } /** * @brief Returns the reader of the instance. * * @return the reader belonging to the instance */ -ReReader* ReSourceUnit::reader() const { - return m_reader; +ReReader* ReSourceUnit::reader() const{ + return m_reader; } /** @class ReSourcePosition ReSource.hpp "expr/ReSource.hpp" @@ -105,11 +105,7 @@ ReReader* ReSourceUnit::reader() const { * @brief Constructor. */ ReSourcePosition::ReSourcePosition() : - m_sourceUnit(NULL), - m_lineNo(0), - m_column(0), - m_caller(NULL) -{ + m_sourceUnit(NULL), m_lineNo(0), m_column(0), m_caller(NULL){ } /** @@ -119,22 +115,17 @@ ReSourcePosition::ReSourcePosition() : * @param lineNo line number inside the input source * @param colNo distance to the line start */ -ReSourcePosition::ReSourcePosition(ReSourceUnit* unit, int lineNo, - int colNo) : - m_sourceUnit(unit), - m_lineNo(lineNo), - m_column(colNo), - m_caller(NULL) -{ - ReReader* reader = dynamic_cast(unit->reader()); - m_caller = reader->source().caller(); +ReSourcePosition::ReSourcePosition(ReSourceUnit* unit, int lineNo, int colNo) : + m_sourceUnit(unit), m_lineNo(lineNo), m_column(colNo), m_caller(NULL){ + ReReader* reader = dynamic_cast (unit->reader()); + m_caller = reader->source().caller(); } /** * @brief Destructor */ -ReSourcePosition::~ ReSourcePosition(){ - // That should never occure! - assert(false); +ReSourcePosition::~ReSourcePosition(){ + // That should never occure! + assert(false); } /** @@ -144,9 +135,8 @@ ReSourcePosition::~ ReSourcePosition(){ * @param buffer buffer for the instance * @return buffer */ -void*ReSourcePosition::operator new(size_t, void* buffer) -{ - return buffer; +void*ReSourcePosition::operator new(size_t, void* buffer){ + return buffer; } /** @@ -154,12 +144,11 @@ void*ReSourcePosition::operator new(size_t, void* buffer) * * @return a description of the instance */ -ReString ReSourcePosition::toString() const -{ - char buffer[512]; - utf8(buffer, sizeof buffer); +ReString ReSourcePosition::toString() const{ + char buffer[512]; + utf8(buffer, sizeof buffer); - return ReString(buffer); + return ReString(buffer); } /** @@ -169,21 +158,18 @@ ReString ReSourcePosition::toString() const * @param bufferSize the size of the buffer * @return buffer */ -char* ReSourcePosition::utf8(char buffer[], size_t bufferSize) const -{ - qsnprintf(buffer, bufferSize, "%s:%d:%d", - m_sourceUnit == NULL ? "" : m_sourceUnit->name(), - m_lineNo, m_column); - return buffer; +char* ReSourcePosition::utf8(char buffer[], size_t bufferSize) const{ + qsnprintf(buffer, bufferSize, "%s:%d:%d", + m_sourceUnit == NULL ? "" : m_sourceUnit->name(), m_lineNo, m_column); + return buffer; } /** * @brief Returns the line number. * @return the line number */ -int ReSourcePosition::lineNo() const -{ - return m_lineNo; +int ReSourcePosition::lineNo() const{ + return m_lineNo; } /** @@ -191,18 +177,16 @@ int ReSourcePosition::lineNo() const * * @param lineNo the new lineNo */ -void ReSourcePosition::setLineNo(int lineNo) -{ - m_lineNo = lineNo; +void ReSourcePosition::setLineNo(int lineNo){ + m_lineNo = lineNo; } /** * @brief Returns the column. * * @return the column of instance. */ -int ReSourcePosition::column() const -{ - return m_column; +int ReSourcePosition::column() const{ + return m_column; } /** @@ -210,9 +194,8 @@ int ReSourcePosition::column() const * * @param column the new column */ -void ReSourcePosition::setColumn(int column) -{ - m_column = column; +void ReSourcePosition::setColumn(int column){ + m_column = column; } /** @@ -220,9 +203,8 @@ void ReSourcePosition::setColumn(int column) * * @return the source unit of the instance */ -ReSourceUnit* ReSourcePosition::sourceUnit() const -{ - return m_sourceUnit; +ReSourceUnit* ReSourcePosition::sourceUnit() const{ + return m_sourceUnit; } /** @@ -230,50 +212,43 @@ ReSourceUnit* ReSourcePosition::sourceUnit() const * * @param sourceUnit the new source unit of the instance */ -void ReSourcePosition::setSourceUnit(ReSourceUnit* sourceUnit) -{ - m_sourceUnit = sourceUnit; - m_lineNo = sourceUnit->lineNo(); +void ReSourcePosition::setSourceUnit(ReSourceUnit* sourceUnit){ + m_sourceUnit = sourceUnit; + m_lineNo = sourceUnit->lineNo(); } - /** @class ReReader ReSource.hpp "expr/ReSource.hpp" * * @brief Implements a base class for readers of different media. */ - /** * @brief Constructor. * * @param source the parent */ ReReader::ReReader(ReSource& source) : - m_currentSourceUnit(NULL), - m_units(), - m_source(source) { + m_currentSourceUnit(NULL), m_units(), m_source(source){ } /** * @brief Destructor. */ -ReReader::~ReReader() -{ - clear(); +ReReader::~ReReader(){ + clear(); } /** * @brief Frees the resources. */ -void ReReader::clear() -{ - UnitMap::iterator it; - for(it = m_units.begin(); it != m_units.end(); it++) { - ReStringSourceUnit* unit = (ReStringSourceUnit*)(*it); - delete unit; - } - m_units.clear(); - m_currentSourceUnit = NULL; +void ReReader::clear(){ + UnitMap::iterator it; + for (it = m_units.begin(); it != m_units.end(); it++){ + ReStringSourceUnit* unit = (ReStringSourceUnit*) (*it); + delete unit; + } + m_units.clear(); + m_currentSourceUnit = NULL; } /** @@ -281,17 +256,16 @@ void ReReader::clear() * * @return the parent, a source instance */ -ReSource&ReReader::source() -{ - return m_source; +ReSource&ReReader::source(){ + return m_source; } /** * @brief Returns the current source unit. * * @return the source unit */ -ReSourceUnit* ReReader::currentSourceUnit() const { - return m_currentSourceUnit; +ReSourceUnit* ReReader::currentSourceUnit() const{ + return m_currentSourceUnit; } /** @@ -301,21 +275,22 @@ ReSourceUnit* ReReader::currentSourceUnit() const { * @return true: source unit exists
* false: source unit not found */ -bool ReReader::setCurrentSourceUnit(ReSourceUnitName& sourceUnit) { - bool rc = m_units.contains(sourceUnit); - if(rc) { - m_currentSourceUnit = m_units.value(sourceUnit); - m_source.pushSourceUnit(m_currentSourceUnit); - } - return rc; +bool ReReader::setCurrentSourceUnit(ReSourceUnitName& sourceUnit){ + bool rc = m_units.contains(sourceUnit); + if (rc){ + m_currentSourceUnit = m_units.value(sourceUnit); + m_source.pushSourceUnit(m_currentSourceUnit); + } + return rc; } /** * @brief Removes the "latest" sourceUnit. */ -void ReReader::removeSourceUnit() { +void ReReader::removeSourceUnit(){ - m_currentSourceUnit = m_source.popSourceUnit(this);; + m_currentSourceUnit = m_source.popSourceUnit(this); + ; } /** @class ReSourcePositionBlock ReSource.hpp "expr/ReSource.hpp" @@ -327,10 +302,10 @@ void ReReader::removeSourceUnit() { * Therefore a simple allocation is possible with blocks. */ ReSourcePositionBlock::ReSourcePositionBlock() : - m_successor(NULL) - // m_positions + m_successor(NULL) +// m_positions { - memset(m_positions, 0, sizeof m_positions); + memset(m_positions, 0, sizeof m_positions); } /** @class ReSource ReSource.hpp "expr/ReSource.hpp" @@ -344,42 +319,40 @@ ReSourcePositionBlock::ReSourcePositionBlock() : * @brief Constructor. */ ReSource::ReSource() : - m_sourcePositionStack(), - m_sourcePositionBlock(NULL), - m_countPositionBlock(RPL_POSITIONS_PER_BLOCK + 1), - m_readers(), - m_sourceUnits(), - m_unitStack(), - m_currentReader(NULL) -{ - // the stack should never be empty: - m_sourcePositionStack.push(NULL); + m_sourcePositionStack(), + m_sourcePositionBlock(NULL), + m_countPositionBlock(RPL_POSITIONS_PER_BLOCK + 1), + m_readers(), + m_sourceUnits(), + m_unitStack(), + m_currentReader(NULL){ + // the stack should never be empty: + m_sourcePositionStack.push(NULL); } /** * @brief Destructor. */ -ReSource::~ReSource() { - destroy(); +ReSource::~ReSource(){ + destroy(); } /** * @brief Frees the resources of the instance. */ -void ReSource::destroy() -{ - m_sourcePositionStack.clear(); - m_readers.clear(); - m_sourceUnits.clear(); - m_currentReader = NULL; - ReSourcePositionBlock* block = m_sourcePositionBlock; - m_sourcePositionBlock = NULL; - m_countPositionBlock = RPL_POSITIONS_PER_BLOCK + 1; - while(block != NULL){ - ReSourcePositionBlock* last = block; - block = block->m_successor; - delete last; - } +void ReSource::destroy(){ + m_sourcePositionStack.clear(); + m_readers.clear(); + m_sourceUnits.clear(); + m_currentReader = NULL; + ReSourcePositionBlock* block = m_sourcePositionBlock; + m_sourcePositionBlock = NULL; + m_countPositionBlock = RPL_POSITIONS_PER_BLOCK + 1; + while (block != NULL){ + ReSourcePositionBlock* last = block; + block = block->m_successor; + delete last; + } } /** @@ -392,8 +365,8 @@ void ReSource::destroy() * @param unit unit to find * @return a permanently valid unit name */ -ReSourceUnitName ReSource::permanentUnitName(ReSourceUnitName unit) { - return unit; +ReSourceUnitName ReSource::permanentUnitName(ReSourceUnitName unit){ + return unit; } /** @@ -401,17 +374,16 @@ ReSourceUnitName ReSource::permanentUnitName(ReSourceUnitName unit) { * * @return the stack */ -QStack ReSource::sourcePositionStack() const { - return m_sourcePositionStack; +QStack ReSource::sourcePositionStack() const{ + return m_sourcePositionStack; } /** * @brief Returns the source unit stack. * @return the stack of the source units */ -QStack& ReSource::sourceUnitStack() -{ - return m_unitStack; +QStack & ReSource::sourceUnitStack(){ + return m_unitStack; } /** @@ -419,10 +391,10 @@ QStack& ReSource::sourceUnitStack() * * @param reader the new reader. Will be freed in the destructor */ -void ReSource::addReader(ReReader* reader) { - m_readers.push_back(reader); - if (m_currentReader == NULL) - m_currentReader = reader; +void ReSource::addReader(ReReader* reader){ + m_readers.push_back(reader); + if (m_currentReader == NULL) + m_currentReader = reader; } /** @@ -430,8 +402,8 @@ void ReSource::addReader(ReReader* reader) { * * @param unit the new unit. Will be freed in the destructor */ -void ReSource::addSourceUnit(ReSourceUnit* unit) { - m_sourceUnits.push_back(unit); +void ReSource::addSourceUnit(ReSourceUnit* unit){ + m_sourceUnits.push_back(unit); } /** @@ -444,22 +416,19 @@ void ReSource::addSourceUnit(ReSourceUnit* unit) { * @param caller the position of the include * */ -bool ReSource::startUnit(ReSourceUnitName unit, - const ReSourcePosition& caller) { - m_sourcePositionStack.push_back(&caller); - ReReader* reader = NULL; - QList::iterator it; - for(it = m_readers.begin(); - reader == NULL && it != m_readers.end(); - it++) { - ReReader* current = *it; - if(current->openSourceUnit(unit)) { - reader = current; - m_currentReader = current; - break; - } - } - return reader != NULL; +bool ReSource::startUnit(ReSourceUnitName unit, const ReSourcePosition& caller){ + m_sourcePositionStack.push_back(&caller); + ReReader* reader = NULL; + QList ::iterator it; + for (it = m_readers.begin(); reader == NULL && it != m_readers.end(); it++){ + ReReader* current = *it; + if (current->openSourceUnit(unit)){ + reader = current; + m_currentReader = current; + break; + } + } + return reader != NULL; } /** @@ -467,8 +436,8 @@ bool ReSource::startUnit(ReSourceUnitName unit, * * @param unit the source unit */ -void ReSource::pushSourceUnit(ReSourceUnit* unit) { - m_unitStack.push(unit); +void ReSource::pushSourceUnit(ReSourceUnit* unit){ + m_unitStack.push(unit); } /** @@ -478,23 +447,23 @@ void ReSource::pushSourceUnit(ReSourceUnit* unit) { * @return NULL: the current reader does not have an open source unit
* otherwise: the last entry from the source unit stack */ -ReSourceUnit* ReSource::popSourceUnit(ReReader* reader) { - ReSourceUnit* rc = NULL; - if(m_unitStack.size() > 0) - m_unitStack.pop(); - m_currentReader = m_unitStack.size() <= 0 - ? NULL : m_unitStack.top()->reader(); - if(m_currentReader == reader) - rc = m_unitStack.top(); - else { - for(int ix = m_unitStack.size() - 2; ix >= 0; ix--){ - if(m_unitStack[ix]->reader() == reader){ - rc = m_unitStack[ix]; - break; - } - } - } - return rc; +ReSourceUnit* ReSource::popSourceUnit(ReReader* reader){ + ReSourceUnit* rc = NULL; + if (m_unitStack.size() > 0) + m_unitStack.pop(); + m_currentReader = + m_unitStack.size() <= 0 ? NULL : m_unitStack.top()->reader(); + if (m_currentReader == reader) + rc = m_unitStack.top(); + else{ + for (int ix = m_unitStack.size() - 2; ix >= 0; ix--){ + if (m_unitStack[ix]->reader() == reader){ + rc = m_unitStack[ix]; + break; + } + } + } + return rc; } /** @@ -503,8 +472,8 @@ ReSourceUnit* ReSource::popSourceUnit(ReReader* reader) { * @return NULL: no reader active
* otherwise: the current reader */ -ReReader* ReSource::currentReader() { - return m_currentReader; +ReReader* ReSource::currentReader(){ + return m_currentReader; } /** @@ -515,30 +484,28 @@ ReReader* ReSource::currentReader() { * @param colNo the column in the line * @return a new instance of a source position */ -const ReSourcePosition* ReSource::newPosition(int colNo) -{ - if (m_countPositionBlock >= RPL_POSITIONS_PER_BLOCK){ - ReSourcePositionBlock* newBlock = new ReSourcePositionBlock; - newBlock->m_successor = m_sourcePositionBlock; - m_sourcePositionBlock = newBlock; - m_countPositionBlock = 0; - } - unsigned offset = m_countPositionBlock * sizeof(ReSourcePosition); - m_countPositionBlock++; - char* posInBlock = &m_sourcePositionBlock->m_positions[offset]; - ReSourceUnit* unit = dynamic_cast( - m_currentReader->currentSourceUnit()); - ReSourcePosition* rc = new (posInBlock) ReSourcePosition( - unit, unit->lineNo(), colNo); - return rc; +const ReSourcePosition* ReSource::newPosition(int colNo){ + if (m_countPositionBlock >= RPL_POSITIONS_PER_BLOCK){ + ReSourcePositionBlock* newBlock = new ReSourcePositionBlock; + newBlock->m_successor = m_sourcePositionBlock; + m_sourcePositionBlock = newBlock; + m_countPositionBlock = 0; + } + unsigned offset = m_countPositionBlock * sizeof(ReSourcePosition); + m_countPositionBlock++; + char* posInBlock = &m_sourcePositionBlock->m_positions[offset]; + ReSourceUnit* unit = + dynamic_cast (m_currentReader->currentSourceUnit()); + ReSourcePosition* rc = new (posInBlock) ReSourcePosition(unit, + unit->lineNo(), colNo); + return rc; } /** * @brief Resets all states in the source. */ -void ReSource::clear() -{ - destroy(); +void ReSource::clear(){ + destroy(); } /** @@ -547,10 +514,8 @@ void ReSource::clear() * @return NULL: stack is empty
* the top of the source unit stack */ -const ReSourcePosition* ReSource::caller() const -{ - return m_sourcePositionStack.size() == 0 - ? NULL : m_sourcePositionStack.top(); +const ReSourcePosition* ReSource::caller() const{ + return m_sourcePositionStack.size() == 0 ? NULL : m_sourcePositionStack.top(); } /** @class ReStringSourceUnit ReSource.hpp "expr/ReSource.hpp" @@ -567,16 +532,14 @@ const ReSourcePosition* ReSource::caller() const * @param reader the parent */ ReStringSourceUnit::ReStringSourceUnit(ReSourceUnitName name, - const ReSourceUnitContent& content, ReStringReader* reader) : - ReSourceUnit(name, reader), - m_currentPosition(0), - m_content(content) { + const ReSourceUnitContent& content, ReStringReader* reader) : + ReSourceUnit(name, reader), m_currentPosition(0), m_content(content){ } /** * @brief Destructor. */ -ReStringSourceUnit::~ReStringSourceUnit() { +ReStringSourceUnit::~ReStringSourceUnit(){ } /** * @brief Returns the current read position. @@ -584,8 +547,8 @@ ReStringSourceUnit::~ReStringSourceUnit() { * @return the offset (count of QChars) of the end of the last read block * inside m_content */ -int ReStringSourceUnit::currentPosition() const { - return m_currentPosition; +int ReStringSourceUnit::currentPosition() const{ + return m_currentPosition; } /** @@ -594,16 +557,16 @@ int ReStringSourceUnit::currentPosition() const { * @param currentPosition the offset (count of QChars) of the end of * the last read block inside m_content */ -void ReStringSourceUnit::setCurrentPosition(int currentPosition) { - m_currentPosition = currentPosition; +void ReStringSourceUnit::setCurrentPosition(int currentPosition){ + m_currentPosition = currentPosition; } /** * @brief Returns the content of the source unit. * * @return the content */ -ReSourceUnitContent ReStringSourceUnit::content() const { - return m_content.constData(); +ReSourceUnitContent ReStringSourceUnit::content() const{ + return m_content.constData(); } /** @class ReStringReader ReSource.hpp "expr/ReSource.hpp" @@ -619,14 +582,14 @@ ReSourceUnitContent ReStringSourceUnit::content() const { * @param source the parent */ ReStringReader::ReStringReader(ReSource& source) : - ReReader(source) { + ReReader(source){ } /** * @brief Destructor. */ -ReStringReader::~ReStringReader() { - clear(); +ReStringReader::~ReStringReader(){ + clear(); } /** @@ -637,13 +600,13 @@ ReStringReader::~ReStringReader() { * otherwise: an instance of a sub class of * ReSourceUnit */ -ReSourceUnit* ReStringReader::openSourceUnit(ReSourceUnitName unit) { - ReSourceUnit* rc = NULL; - if(setCurrentSourceUnit(unit)) { - rc = m_currentSourceUnit; - ((ReStringSourceUnit*) rc)->setCurrentPosition(0); - } - return rc; +ReSourceUnit* ReStringReader::openSourceUnit(ReSourceUnitName unit){ + ReSourceUnit* rc = NULL; + if (setCurrentSourceUnit(unit)){ + rc = m_currentSourceUnit; + ((ReStringSourceUnit*) rc)->setCurrentPosition(0); + } + return rc; } /** * @brief Delivers the next line from the input medium or the first part of it. @@ -656,13 +619,13 @@ ReSourceUnit* ReStringReader::openSourceUnit(ReSourceUnitName unit) { * @return false: no more input available
* true: success */ -bool ReStringReader::nextLine(int maxSize, QByteArray& buffer, bool& hasMore) { - bool rc = m_currentSourceUnit != NULL; - if (rc){ - m_currentSourceUnit->setLineNo(m_currentSourceUnit->lineNo() + 1); - rc = fillBuffer(maxSize, buffer, hasMore); - } - return rc; +bool ReStringReader::nextLine(int maxSize, QByteArray& buffer, bool& hasMore){ + bool rc = m_currentSourceUnit != NULL; + if (rc){ + m_currentSourceUnit->setLineNo(m_currentSourceUnit->lineNo() + 1); + rc = fillBuffer(maxSize, buffer, hasMore); + } + return rc; } /** @@ -676,26 +639,26 @@ bool ReStringReader::nextLine(int maxSize, QByteArray& buffer, bool& hasMore) { * @return false: no more input available
* true: success */ -bool ReStringReader::fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore) { - ReStringSourceUnit* unit = (ReStringSourceUnit*) m_currentSourceUnit; - ReSourceUnitContent content = unit->content(); - int startPos = unit->currentPosition(); - const char* start = content + startPos; - const char* end = strchr(start, '\n'); - hasMore = false; - int size = end == NULL ? strlen(start) : end - start + 1; - hasMore = false; - if(size > maxSize) { - size = maxSize; - hasMore = true; - } - if(size > 0) { - buffer.append(start, size); - unit->setCurrentPosition(startPos + size); - } else { - removeSourceUnit(); - } - return size > 0; +bool ReStringReader::fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore){ + ReStringSourceUnit* unit = (ReStringSourceUnit*) m_currentSourceUnit; + ReSourceUnitContent content = unit->content(); + int startPos = unit->currentPosition(); + const char* start = content + startPos; + const char* end = strchr(start, '\n'); + hasMore = false; + int size = end == NULL ? strlen(start) : end - start + 1; + hasMore = false; + if (size > maxSize){ + size = maxSize; + hasMore = true; + } + if (size > 0){ + buffer.append(start, size); + unit->setCurrentPosition(startPos + size); + }else{ + removeSourceUnit(); + } + return size > 0; } /** @@ -705,11 +668,11 @@ bool ReStringReader::fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore) * @param content */ void ReStringReader::addSource(ReSourceUnitName name, - ReSourceUnitContent content) { - // Deletion in the destructor of the base class ReReader - ReStringSourceUnit* unit = new ReStringSourceUnit(name, content, this); - m_units.insert(m_units.begin(), unit->name(), unit); - m_currentSourceUnit = unit; + ReSourceUnitContent content){ + // Deletion in the destructor of the base class ReReader + ReStringSourceUnit* unit = new ReStringSourceUnit(name, content, this); + m_units.insert(m_units.begin(), unit->name(), unit); + m_currentSourceUnit = unit; } /** @@ -719,12 +682,12 @@ void ReStringReader::addSource(ReSourceUnitName name, * @param content new content */ void ReStringReader::replaceSource(ReSourceUnitName name, - ReSourceUnitContent content) -{ - if (m_units.contains(name)){ - ReStringSourceUnit* unit = dynamic_cast(m_units[name]); - unit->m_content = content; - } + ReSourceUnitContent content){ + if (m_units.contains(name)){ + ReStringSourceUnit* unit = + dynamic_cast (m_units[name]); + unit->m_content = content; + } } /** @class ReFileSourceUnit ReSource.hpp "expr/ReSource.hpp" @@ -734,29 +697,24 @@ void ReStringReader::replaceSource(ReSourceUnitName name, * This is the mostly used implementation of the ReSourceUnit/ReReader. */ - ReFileSourceUnit::ReFileSourceUnit(ReSourceUnitName filename, - ReFileReader* reader) : - ReSourceUnit(filename, reader), - m_currentPosition(0), - m_fp(fopen(filename, "r")), - m_textStream(m_fp, QIODevice::ReadOnly), - m_line() -{ + ReFileReader* reader) : + ReSourceUnit(filename, reader), + m_currentPosition(0), + m_fp(fopen(filename, "r")), + m_textStream(m_fp, QIODevice::ReadOnly), + m_line(){ } - /** * @brief Destructor. */ -ReFileSourceUnit::~ReFileSourceUnit() -{ - fclose(m_fp); +ReFileSourceUnit::~ReFileSourceUnit(){ + fclose(m_fp); } -bool ReFileSourceUnit::isOpen() const -{ - return m_fp != NULL; +bool ReFileSourceUnit::isOpen() const{ + return m_fp != NULL; } /** @class ReFileReader ReSource.hpp "expr/ReSource.hpp" * @@ -769,14 +727,13 @@ bool ReFileSourceUnit::isOpen() const * @brief Constructor. */ ReFileReader::ReFileReader(ReSource& source) : - ReReader(source) -{ + ReReader(source){ } /** * @brief Destructor. */ -ReFileReader::~ReFileReader() { +ReFileReader::~ReFileReader(){ } /** @@ -787,13 +744,13 @@ ReFileReader::~ReFileReader() { * otherwise: an instance of a sub class of * ReSourceUnit */ -ReSourceUnit* ReFileReader::openSourceUnit(ReSourceUnitName unit) { - ReSourceUnit* rc = NULL; - if(m_units.contains(unit)) { - rc = *m_units.find(unit); - m_currentSourceUnit = static_cast(rc); - } - return rc; +ReSourceUnit* ReFileReader::openSourceUnit(ReSourceUnitName unit){ + ReSourceUnit* rc = NULL; + if (m_units.contains(unit)){ + rc = *m_units.find(unit); + m_currentSourceUnit = static_cast (rc); + } + return rc; } /** * @brief Delivers the next line from the input medium or the first part of it. @@ -806,26 +763,25 @@ ReSourceUnit* ReFileReader::openSourceUnit(ReSourceUnitName unit) { * @return false: no more input available
* true: success */ -bool ReFileReader::nextLine(int maxSize, QByteArray& buffer, bool& hasMore) { - ReFileSourceUnit* unit = static_cast - (m_currentSourceUnit); - bool rc = ! feof(unit->m_fp); - if(! rc) { - m_source.popSourceUnit(this); - } else { - m_currentSourceUnit->setLineNo(m_currentSourceUnit->lineNo() + 1); - unit->m_currentPosition = 0; - QByteArray& line = unit->m_line; - line.reserve(maxSize+1); - if (fgets(line.data(), maxSize, unit->m_fp) == NULL) - rc = false; - else{ - line[maxSize] = '\0'; - line.resize(strlen(line.constData())); - rc = fillBuffer(maxSize, buffer, hasMore); - } - } - return rc; +bool ReFileReader::nextLine(int maxSize, QByteArray& buffer, bool& hasMore){ + ReFileSourceUnit* unit = static_cast (m_currentSourceUnit); + bool rc = !feof(unit->m_fp); + if (!rc){ + m_source.popSourceUnit(this); + }else{ + m_currentSourceUnit->setLineNo(m_currentSourceUnit->lineNo() + 1); + unit->m_currentPosition = 0; + QByteArray& line = unit->m_line; + line.reserve(maxSize + 1); + if (fgets(line.data(), maxSize, unit->m_fp) == NULL) + rc = false; + else{ + line[maxSize] = '\0'; + line.resize(strlen(line.constData())); + rc = fillBuffer(maxSize, buffer, hasMore); + } + } + return rc; } /** @@ -839,17 +795,17 @@ bool ReFileReader::nextLine(int maxSize, QByteArray& buffer, bool& hasMore) { * @return false: no more input available
* true: success */ -bool ReFileReader::fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore) { - ReFileSourceUnit* unit = static_cast(m_currentSourceUnit); - int start = unit->m_currentPosition; - QByteArray& content = unit->m_line; - int size = content.size() - start; - if(size > maxSize) - size = maxSize; - buffer += content.mid(start, size); - unit->m_currentPosition = (start += size); - hasMore = start < content.size(); - return size > 0; +bool ReFileReader::fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore){ + ReFileSourceUnit* unit = static_cast (m_currentSourceUnit); + int start = unit->m_currentPosition; + QByteArray& content = unit->m_line; + int size = content.size() - start; + if (size > maxSize) + size = maxSize; + buffer += content.mid(start, size); + unit->m_currentPosition = (start += size); + hasMore = start < content.size(); + return size > 0; } /** @@ -857,11 +813,10 @@ bool ReFileReader::fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore) { * * @param filename the file' name (relative or absolute) */ -void ReFileReader::addSource(ReSourceUnitName filename) { - // Deleting in ~ReSourceUnit(): - ReFileSourceUnit* unit = new ReFileSourceUnit(filename, this); - m_units.insert(m_units.begin(), unit->name(), unit); - m_currentSourceUnit = unit; +void ReFileReader::addSource(ReSourceUnitName filename){ + // Deleting in ~ReSourceUnit(): + ReFileSourceUnit* unit = new ReFileSourceUnit(filename, this); + m_units.insert(m_units.begin(), unit->name(), unit); + m_currentSourceUnit = unit; } - diff --git a/expr/ReSource.hpp b/expr/ReSource.hpp index cba5ea0..843f2c4 100644 --- a/expr/ReSource.hpp +++ b/expr/ReSource.hpp @@ -1,11 +1,13 @@ /* - * Licence: + * ReSource.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ - + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #ifndef RPLSOURCE_HPP #define RPLSOURCE_HPP @@ -13,215 +15,213 @@ // type of buffer names and filenames. Codec: UTF-8 typedef const char* ReSourceUnitName; -typedef const char* ReSourceUnitContent; +typedef const char* ReSourceUnitContent; class ReSource; class ReReader; class ReSourceUnit { public: - ReSourceUnit(const char* name, ReReader* reader); - virtual ~ReSourceUnit(); + ReSourceUnit(const char* name, ReReader* reader); + virtual ~ReSourceUnit(); public: - const char* name() const; - int lineNo() const; - void setLineNo(int lineNo); - ReReader* reader() const; + const char* name() const; + int lineNo() const; + void setLineNo(int lineNo); + ReReader* reader() const; protected: - QByteArray m_name; - int m_lineNo; - ReReader* m_reader; + QByteArray m_name; + int m_lineNo; + ReReader* m_reader; }; class ReSourcePosition { public: - ReSourcePosition(); - ReSourcePosition(ReSourceUnit* unit, int lineNo, int colNo); - ~ ReSourcePosition(); - void* operator new(size_t cbSize, void* buffer); + ReSourcePosition(); + ReSourcePosition(ReSourceUnit* unit, int lineNo, int colNo); + ~ ReSourcePosition(); + void* operator new(size_t cbSize, void* buffer); private: - /// forbid usage of the copy constructor! - ReSourcePosition(const ReSourcePosition& source); - /// forbid usage of the the assignment! - ReSourcePosition& operator=(const ReSourcePosition& source); + /// forbid usage of the copy constructor! + ReSourcePosition(const ReSourcePosition& source); + /// forbid usage of the the assignment! + ReSourcePosition& operator=(const ReSourcePosition& source); public: - ReString toString() const; - int lineNo() const; - void setLineNo(int lineNo); + ReString toString() const; + int lineNo() const; + void setLineNo(int lineNo); - int column() const; - void setColumn(int column); + int column() const; + void setColumn(int column); - ReSourceUnit* sourceUnit() const; - void setSourceUnit(ReSourceUnit* sourceUnit); - char*utf8(char buffer[], size_t bufferSize) const; + ReSourceUnit* sourceUnit() const; + void setSourceUnit(ReSourceUnit* sourceUnit); + char*utf8(char buffer[], size_t bufferSize) const; private: - ReSourceUnit* m_sourceUnit; - int m_lineNo; - int m_column; - const ReSourcePosition* m_caller; + ReSourceUnit* m_sourceUnit; + int m_lineNo; + int m_column; + const ReSourcePosition* m_caller; }; class ReReader { public: - typedef ReCharPtrMap UnitMap; -public: - ReReader(ReSource& source); - ~ReReader(); -public: - /** - * @brief Prepares the reading from a given source unit. - * - * @param unit name of the unit - * @return NULL: unit not known
- * otherwise: an instance with the state of the reader - * for the source. This is normally a sub class of - * ReSourceUnit - */ - virtual ReSourceUnit* openSourceUnit(const char* unit) = 0; - /** - * @brief Reads the first part of the next line into a given buffer. - * - * @param maxSize the maximum length of the read input. - * If a line is longer the next part must be read - * by fillBuffer() - * @param buffer IN/OUT: the read input will be appended here - * @param hasMore OUT: true: the line is longer than maxSize - * @return true: the read was successful
- * false: no more input is available - */ - virtual bool nextLine(int maxSize, QByteArray& buffer, bool& hasMore) = 0; - /** - * @brief Reads the next part of the current line into a given buffer. - * - * @param maxSize the maximum length of the read input. - * @param buffer IN/OUT: the read input will be appended here - * @param hasMore OUT: true: the rest of line is longer than maxSize - * @return true: the read was successful
- * false: no more input is available - */ - virtual bool fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore) = 0; -public: - virtual void clear(); - ReSource& source(); - ReSourceUnit* currentSourceUnit() const; - bool setCurrentSourceUnit(ReSourceUnitName& currentSourceUnit); + typedef ReCharPtrMap UnitMap; +public: + ReReader(ReSource& source); + ~ReReader(); +public: + /** + * @brief Prepares the reading from a given source unit. + * + * @param unit name of the unit + * @return NULL: unit not known
+ * otherwise: an instance with the state of the reader + * for the source. This is normally a sub class of + * ReSourceUnit + */ + virtual ReSourceUnit* openSourceUnit(const char* unit) = 0; + /** + * @brief Reads the first part of the next line into a given buffer. + * + * @param maxSize the maximum length of the read input. + * If a line is longer the next part must be read + * by fillBuffer() + * @param buffer IN/OUT: the read input will be appended here + * @param hasMore OUT: true: the line is longer than maxSize + * @return true: the read was successful
+ * false: no more input is available + */ + virtual bool nextLine(int maxSize, QByteArray& buffer, bool& hasMore) = 0; + /** + * @brief Reads the next part of the current line into a given buffer. + * + * @param maxSize the maximum length of the read input. + * @param buffer IN/OUT: the read input will be appended here + * @param hasMore OUT: true: the rest of line is longer than maxSize + * @return true: the read was successful
+ * false: no more input is available + */ + virtual bool fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore) = 0; +public: + virtual void clear(); + ReSource& source(); + ReSourceUnit* currentSourceUnit() const; + bool setCurrentSourceUnit(ReSourceUnitName& currentSourceUnit); protected: - void removeSourceUnit(); + void removeSourceUnit(); protected: - ReSourceUnit* m_currentSourceUnit; - /// name -> source - UnitMap m_units; - ReSource& m_source; + ReSourceUnit* m_currentSourceUnit; + /// name -> source + UnitMap m_units; + ReSource& m_source; }; #define RPL_POSITIONS_PER_BLOCK 512 -class ReSourcePositionBlock{ - friend class ReSource; +class ReSourcePositionBlock { + friend class ReSource; public: - ReSourcePositionBlock(); + ReSourcePositionBlock(); private: - ReSourcePositionBlock* m_successor; - char m_positions[RPL_POSITIONS_PER_BLOCK * sizeof(ReSourcePosition)]; + ReSourcePositionBlock* m_successor; + char m_positions[RPL_POSITIONS_PER_BLOCK * sizeof(ReSourcePosition)]; }; class ReSource { public: - ReSource(); - virtual ~ReSource(); -public: - virtual const char* permanentUnitName(const char* unit); - void finishSourceUnit(); - void addReader(ReReader* reader); - void addSourceUnit(ReSourceUnit* unit); - QStack sourcePositionStack() const; - QStack& sourceUnitStack(); - - bool startUnit(const char* unit, const ReSourcePosition& caller); - void pushSourceUnit(ReSourceUnit* unit); - ReSourceUnit* popSourceUnit(ReReader* reader); - ReReader* currentReader(); - const ReSourcePosition* newPosition(int colNo); - void clear(); - const ReSourcePosition* caller() const; + ReSource(); + virtual ~ReSource(); +public: + virtual const char* permanentUnitName(const char* unit); + void finishSourceUnit(); + void addReader(ReReader* reader); + void addSourceUnit(ReSourceUnit* unit); + QStack sourcePositionStack() const; + QStack & sourceUnitStack(); + + bool startUnit(const char* unit, const ReSourcePosition& caller); + void pushSourceUnit(ReSourceUnit* unit); + ReSourceUnit* popSourceUnit(ReReader* reader); + ReReader* currentReader(); + const ReSourcePosition* newPosition(int colNo); + void clear(); + const ReSourcePosition* caller() const; protected: - void destroy(); + void destroy(); protected: - // stack of the info about the stacked (open) source units: - QStack m_sourcePositionStack; - ReSourcePositionBlock* m_sourcePositionBlock; - int m_countPositionBlock; - QList m_readers; - QList m_sourceUnits; - // setCurrentSourceUnit() pushes one entry, removeSourceUnit() pops it - // (when end of input has been reached). - QStack m_unitStack; - ReReader* m_currentReader; + // stack of the info about the stacked (open) source units: + QStack m_sourcePositionStack; + ReSourcePositionBlock* m_sourcePositionBlock; + int m_countPositionBlock; + QList m_readers; + QList m_sourceUnits; + // setCurrentSourceUnit() pushes one entry, removeSourceUnit() pops it + // (when end of input has been reached). + QStack m_unitStack; + ReReader* m_currentReader; }; class ReStringReader; -class ReStringSourceUnit : public ReSourceUnit { - friend class ReStringReader; +class ReStringSourceUnit: public ReSourceUnit { + friend class ReStringReader; public: - ReStringSourceUnit(ReSourceUnitName name, - const ReSourceUnitContent& content, - ReStringReader* reader); - virtual ~ReStringSourceUnit(); + ReStringSourceUnit(ReSourceUnitName name, const ReSourceUnitContent& content, + ReStringReader* reader); + virtual ~ReStringSourceUnit(); public: - int currentPosition() const; - void setCurrentPosition(int currentPosition); - ReSourceUnitContent content() const; + int currentPosition() const; + void setCurrentPosition(int currentPosition); + ReSourceUnitContent content() const; private: - int m_currentPosition; - QByteArray m_content; + int m_currentPosition; + QByteArray m_content; }; -class ReStringReader : public ReReader{ +class ReStringReader: public ReReader { public: - ReStringReader(ReSource& source); - virtual ~ReStringReader(); - // ReReader interface + ReStringReader(ReSource& source); + virtual ~ReStringReader(); + // ReReader interface public: - virtual ReSourceUnit* openSourceUnit(ReSourceUnitName unit); - virtual bool nextLine(int maxSize, QByteArray& buffer, bool& hasMore); - virtual bool fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore); + virtual ReSourceUnit* openSourceUnit(ReSourceUnitName unit); + virtual bool nextLine(int maxSize, QByteArray& buffer, bool& hasMore); + virtual bool fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore); public: - void addSource(ReSourceUnitName name, ReSourceUnitContent content); - void replaceSource(ReSourceUnitName name, ReSourceUnitContent content); + void addSource(ReSourceUnitName name, ReSourceUnitContent content); + void replaceSource(ReSourceUnitName name, ReSourceUnitContent content); }; class ReFileReader; -class ReFileSourceUnit : public ReSourceUnit { - friend class ReFileReader; +class ReFileSourceUnit: public ReSourceUnit { + friend class ReFileReader; public: - ReFileSourceUnit(ReSourceUnitName filename, ReFileReader* reader); - virtual ~ReFileSourceUnit(); + ReFileSourceUnit(ReSourceUnitName filename, ReFileReader* reader); + virtual ~ReFileSourceUnit(); public: - bool isOpen() const; + bool isOpen() const; private: - int m_currentPosition; - FILE* m_fp; - QTextStream m_textStream; - QByteArray m_line; + int m_currentPosition; + FILE* m_fp; + QTextStream m_textStream; + QByteArray m_line; }; -class ReFileReader : public ReReader{ +class ReFileReader: public ReReader { public: - ReFileReader(ReSource& source); - virtual ~ReFileReader(); - // ReReader interface + ReFileReader(ReSource& source); + virtual ~ReFileReader(); + // ReReader interface public: - virtual ReSourceUnit* openSourceUnit(ReSourceUnitName unit); - virtual bool nextLine(int maxSize, QByteArray& buffer, bool& hasMore); - virtual bool fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore); + virtual ReSourceUnit* openSourceUnit(ReSourceUnitName unit); + virtual bool nextLine(int maxSize, QByteArray& buffer, bool& hasMore); + virtual bool fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore); public: - void addSource(ReSourceUnitName filename); + void addSource(ReSourceUnitName filename); }; - #endif // RPLSOURCE_HPP diff --git a/expr/ReVM.cpp b/expr/ReVM.cpp index 1a4e177..17ba66d 100644 --- a/expr/ReVM.cpp +++ b/expr/ReVM.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * ReVM.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ /** @file * @@ -20,13 +23,10 @@ #include "expr/reexpr.hpp" enum { - LOC_VAL_OF_VAR_1 = LOC_FIRST_OF(LOC_VM), // 11401 - LOC_UNOP_1, - LOC_UNOP_2, - LOC_UNOP_3, - LOC_UNOP_4, // 10005 - LOC_BINOP_1, - LOC_COUNT + LOC_VAL_OF_VAR_1 = LOC_FIRST_OF(LOC_VM), // 11401 + LOC_UNOP_1, LOC_UNOP_2, LOC_UNOP_3, LOC_UNOP_4, // 10005 + LOC_BINOP_1, + LOC_COUNT }; int ReVMThread::m_nextId = 1; @@ -42,14 +42,13 @@ int ReVMThread::m_nextId = 1; * @param ... the values for the placeholders */ ReVMException::ReVMException(const char* format, ...) : - ReException("") -{ - char buffer[16000]; - va_list ap; - va_start(ap, format); - qvsnprintf(buffer, sizeof buffer, format, ap); - va_end(ap); - m_message = buffer; + ReException(""){ + char buffer[16000]; + va_list ap; + va_start(ap, format); + qvsnprintf(buffer, sizeof buffer, format, ap); + va_end(ap); + m_message = buffer; } /** @class ReStackFrame ReVM.hpp "expr/ReVM.hpp" @@ -61,7 +60,6 @@ ReVMException::ReVMException(const char* format, ...) : * method. */ - /** * @brief Constructor. * @@ -69,22 +67,20 @@ ReVMException::ReVMException(const char* format, ...) : */ ReStackFrame::ReStackFrame(ReASItem* caller, ReSymbolSpace* symbols) : - m_countVariables(symbols->listOfVars().size()), - m_variables(NULL), - m_symbols(symbols), - m_caller(caller) -{ - if (m_countVariables > 0) - m_variables = new ReASVariant[m_countVariables]; + m_countVariables(symbols->listOfVars().size()), + m_variables(NULL), + m_symbols(symbols), + m_caller(caller){ + if (m_countVariables > 0) + m_variables = new ReASVariant[m_countVariables]; } /** * @brief Destructor. */ -ReStackFrame::~ReStackFrame() -{ - delete[] m_variables; - m_variables = NULL; +ReStackFrame::~ReStackFrame(){ + delete[] m_variables; + m_variables = NULL; } /** @@ -94,20 +90,18 @@ ReStackFrame::~ReStackFrame() * * @return the storage of the variable */ -ReASVariant& ReStackFrame::valueOfVariable(int index) -{ - if (index < 0 || index >= m_countVariables) - throw ReVMException("valueOfVariable(): invalid index: %d", index); - return m_variables[index]; +ReASVariant& ReStackFrame::valueOfVariable(int index){ + if (index < 0 || index >= m_countVariables) + throw ReVMException("valueOfVariable(): invalid index: %d", index); + return m_variables[index]; } /** * @brief Returns the symbol space of the frame. * * @return the symbol space */ -ReSymbolSpace* ReStackFrame::symbols() const -{ - return m_symbols; +ReSymbolSpace* ReStackFrame::symbols() const{ + return m_symbols; } /** @class ReVMThread ReVM.hpp "expr/ReVM.hpp" @@ -125,27 +119,28 @@ ReSymbolSpace* ReStackFrame::symbols() const * @param vm the parent, the virtual machine */ ReVMThread::ReVMThread(int maxStack, ReVirtualMachine* vm) : - m_id(m_nextId++), - m_debugMode(false), - m_singleStep(false), - m_tracing(false), - m_maxStack(maxStack), - m_frameStack(), - // the stack is never empty! - m_topOfFrames(0), - m_valueStack(), - // the stack is never empty! - m_topOfValues(0), - m_vm(vm), - m_logger(new ReLogger()) -{ - QByteArray prefix = "vm_thread_" + QByteArray::number(m_id); - m_logger->buildStandardAppender(prefix); - m_frameStack.reserve(maxStack); - // the stack is never empty! - m_frameStack.append(new ReStackFrame(vm->tree().symbolSpaces()[0])); - // the stack is never empty! - m_valueStack.append(new ReASVariant); + m_id(m_nextId++), + m_debugMode(false), + m_singleStep(false), + m_tracing(false), + m_maxStack(maxStack), + m_frameStack(), + // the stack is never empty! + m_topOfFrames(0), + m_valueStack(), + // the stack is never empty! + m_topOfValues(0), + m_vm(vm), + m_logger(new ReLogger()){ + QByteArray prefix = "vm_thread_" + QByteArray::number(m_id); + m_logger->buildStandardAppender(prefix); + m_frameStack.reserve(maxStack); + // the stack is never empty! + //@ToDo: + //m_frameStack.append(new ReStackFrame(vm->tree().symbolSpaces()[0])); + throw ReNotImplementedException("ReVMThread::ReVMThread"); + // the stack is never empty! + m_valueStack.append(new ReASVariant); } /** @@ -155,20 +150,20 @@ ReVMThread::ReVMThread(int maxStack, ReVirtualMachine* vm) : * m_child * @param space the current symbol space */ -void ReVMThread::execute(ReASNode1* statements, ReSymbolSpace* space) -{ - bool debugMode = m_debugMode; - ReASNode1 *next; - while(statements != NULL){ - if (debugMode - && (m_singleStep - || (statements->flags() & ReASItem::NF_BREAKPOINT) != 0)) - debug(statements); - ReASStatement* statement = dynamic_cast(statements); - if (statement != NULL) - statement->execute(*this); - statements = dynamic_cast(statements->child()); - } +void ReVMThread::execute(ReASNode1* statements, ReSymbolSpace* space){ + RE_UNUSED(space); + bool debugMode = m_debugMode; + ReASNode1 *next; + while (statements != NULL){ + if (debugMode + && (m_singleStep + || (statements->flags() & ReASItem::NF_BREAKPOINT) != 0)) + debug(statements); + ReASStatement* statement = dynamic_cast (statements); + if (statement != NULL) + statement->execute(*this); + statements = dynamic_cast (statements->child()); + } } /** @@ -176,8 +171,7 @@ void ReVMThread::execute(ReASNode1* statements, ReSymbolSpace* space) * * @param statement the current statement (not yet executed) */ -void ReVMThread::debug(ReASNode1* statement) -{ +void ReVMThread::debug(ReASNode1* statement){ } @@ -186,26 +180,24 @@ void ReVMThread::debug(ReASNode1* statement) * * @return the logger */ -ReLogger* ReVMThread::logger() const -{ - return m_logger; +ReLogger* ReVMThread::logger() const{ + return m_logger; } /** * @brief Reserves a value in the thread's value stack. * * @return the reserved value */ -ReASVariant&ReVMThread::reserveValue() -{ - ReASVariant* rc; - if (++m_topOfValues < m_valueStack.size()){ - rc = m_valueStack[m_topOfValues]; - rc->destroyValue(); - } else { - rc = new ReASVariant(); - m_valueStack.append(rc); - } - return *rc; +ReASVariant&ReVMThread::reserveValue(){ + ReASVariant* rc; + if (++m_topOfValues < m_valueStack.size()){ + rc = m_valueStack[m_topOfValues]; + rc->destroyValue(); + }else{ + rc = new ReASVariant(); + m_valueStack.append(rc); + } + return *rc; } /** @@ -213,22 +205,19 @@ ReASVariant&ReVMThread::reserveValue() * * @return the top of the value stack */ -ReASVariant& ReVMThread::topOfValues() -{ - ReASVariant& rc = *m_valueStack[m_topOfValues]; - return rc; +ReASVariant& ReVMThread::topOfValues(){ + ReASVariant& rc = *m_valueStack[m_topOfValues]; + return rc; } - /** * @brief Returns the entry under the top of the value stack. * * @return the 2nd value the value stack */ -ReASVariant& ReVMThread::top2OfValues() -{ - ReASVariant& rc = *m_valueStack[m_topOfValues-1]; - return rc; +ReASVariant& ReVMThread::top2OfValues(){ + ReASVariant& rc = *m_valueStack[m_topOfValues - 1]; + return rc; } /** @@ -236,12 +225,11 @@ ReASVariant& ReVMThread::top2OfValues() * * @return the old top of stack */ -ReASVariant& ReVMThread::popValue() -{ - ReASVariant& rc = *m_valueStack[m_topOfValues]; - if (m_topOfValues > 0) - m_topOfValues--; - return rc; +ReASVariant& ReVMThread::popValue(){ + ReASVariant& rc = *m_valueStack[m_topOfValues]; + if (m_topOfValues > 0) + m_topOfValues--; + return rc; } /** @@ -250,9 +238,8 @@ ReASVariant& ReVMThread::popValue() * @param symbolSpace the symbol space of the variable * @param variableNo the current no of the variable in the symbol space */ -void ReVMThread::valueToTop(ReSymbolSpace* symbolSpace, int variableNo) -{ - //@ToDo +void ReVMThread::valueToTop(ReSymbolSpace* symbolSpace, int variableNo){ + //@ToDo } /** @@ -260,20 +247,18 @@ void ReVMThread::valueToTop(ReSymbolSpace* symbolSpace, int variableNo) * @param item * @return */ -ReASVariant& ReVMThread::lValue(ReASItem* item) -{ - ReASVariant* rc; - switch(item->nodeType()){ - case AST_NAMED_VALUE: - { - ReASNamedValue* var = dynamic_cast(item); - rc = &valueOfVariable(var->symbolSpace(), var->variableNo()); - break; - } - default: - break; - } - return *rc; +ReASVariant& ReVMThread::lValue(ReASItem* item){ + ReASVariant* rc; + switch (item->nodeType()) { + case AST_NAMED_VALUE: { + ReASNamedValue* var = dynamic_cast (item); + rc = &valueOfVariable(var->symbolSpace(), var->variableNo()); + break; + } + default: + break; + } + return *rc; } /** @@ -284,32 +269,30 @@ ReASVariant& ReVMThread::lValue(ReASItem* item) * @return */ ReASVariant& ReVMThread::valueOfVariable(ReSymbolSpace* symbolSpace, - int variableNo) -{ - ReASVariant& rc = *m_valueStack[0]; - int ix = m_topOfFrames; - ReStackFrame* frame = NULL; - for(int ix = m_topOfFrames; ix >= 0; ix--){ - frame = m_frameStack[ix]; - if (frame->symbols() == symbolSpace){ - rc = frame->valueOfVariable(variableNo); - break; - } - } - if (frame == NULL) - m_logger->logv(LOG_ERROR, LOC_VAL_OF_VAR_1, "no frame has symbolspace %s", - symbolSpace->name().constData()); - - return rc; + int variableNo){ + ReASVariant& rc = *m_valueStack[0]; + int ix = m_topOfFrames; + ReStackFrame* frame = NULL; + for (int ix = m_topOfFrames; ix >= 0; ix--){ + frame = m_frameStack[ix]; + if (frame->symbols() == symbolSpace){ + rc = frame->valueOfVariable(variableNo); + break; + } + } + if (frame == NULL) + m_logger->logv(LOG_ERROR, LOC_VAL_OF_VAR_1, "no frame has symbolspace %s", + symbolSpace->name().constData()); + + return rc; } /** * @brief Returns whether each execution step should be dumped. * @return true: tracing is on
* false: otherwise */ -bool ReVMThread::tracing() const -{ - return m_tracing; +bool ReVMThread::tracing() const{ + return m_tracing; } /** @@ -317,9 +300,8 @@ bool ReVMThread::tracing() const * @param tracing true: tracing will be done
* false: tracing will not be done */ -void ReVMThread::setTracing(bool tracing) -{ - m_tracing = tracing; +void ReVMThread::setTracing(bool tracing){ + m_tracing = tracing; } /** @@ -327,9 +309,8 @@ void ReVMThread::setTracing(bool tracing) * * @return the virtual machine */ -ReVirtualMachine* ReVMThread::vm() const -{ - return m_vm; +ReVirtualMachine* ReVMThread::vm() const{ + return m_vm; } /** @@ -337,21 +318,19 @@ ReVirtualMachine* ReVMThread::vm() const * * @param frame frame to add */ -void ReVMThread::pushFrame(ReStackFrame* frame) -{ - if (m_frameStack.size() >= m_maxStack) - throw ReASException(NULL, "too deep recursion: %d", m_maxStack); - m_frameStack.push_back(frame); +void ReVMThread::pushFrame(ReStackFrame* frame){ + if (m_frameStack.size() >= m_maxStack) + throw ReASException(NULL, "too deep recursion: %d", m_maxStack); + m_frameStack.push_back(frame); } /** * @brief Removes the top of the frames from the stack. */ -void ReVMThread::popFrame() -{ - if (m_frameStack.size() <= 0) - throw ReASException(NULL, "frame stack is empty"); - m_frameStack.pop_back(); +void ReVMThread::popFrame(){ + if (m_frameStack.size() <= 0) + throw ReASException(NULL, "frame stack is empty"); + m_frameStack.pop_back(); } /** @class ReVirtualMachine ReVM.hpp "expr/ReVM.hpp" @@ -361,16 +340,15 @@ void ReVMThread::popFrame() * This is an execution unit which interprets an abstract syntax tree. */ ReVirtualMachine::ReVirtualMachine(ReASTree& tree, ReSource& source, - int maxStack) : - m_maxStack(maxStack), - m_threads(), - m_flags(VF_UNDEF), - m_source(source), - m_tree(tree), - m_trace() -{ - m_threads.reserve(8); - m_trace.reserve(1024); + int maxStack) : + m_maxStack(maxStack), + m_threads(), + m_flags(VF_UNDEF), + m_source(source), + m_tree(tree), + m_trace(){ + m_threads.reserve(8); + m_trace.reserve(1024); } /** @@ -378,20 +356,21 @@ ReVirtualMachine::ReVirtualMachine(ReASTree& tree, ReSource& source, * * @param module the module's name */ -void ReVirtualMachine::executeModule(const char* module) -{ - ReSymbolSpace* space = m_tree.findmodule(module); - if (space == NULL) - throw ReVMException("module not found: %s", module); - ReStackFrame frame(space); - ReSymbolSpace* mainSpace = NULL; - ReASItem* mainStatements = NULL; - ReASMethod* method = space->findMethod("main"); - if (method != NULL){ - mainStatements = method->child(); - mainSpace = method->symbols(); - } - addThread(space->body(), space, mainStatements, mainSpace); +void ReVirtualMachine::executeModule(const char* module){ + ReSymbolSpace* space = m_tree.findmodule(module); + if (space == NULL) + throw ReVMException("module not found: %s", module); + //@ToDo: + //ReStackFrame frame(space); + throw ReNotImplementedException("ReVirtualMachine::executeModule"); + ReSymbolSpace* mainSpace = NULL; + ReASItem* mainStatements = NULL; + ReASMethod* method = space->findMethod("main"); + if (method != NULL){ + mainStatements = method->child(); + mainSpace = method->symbols(); + } + addThread(space->body(), space, mainStatements, mainSpace); } /** @@ -407,20 +386,17 @@ void ReVirtualMachine::executeModule(const char* module) * <= 0: use the default */ void ReVirtualMachine::addThread(ReASItem* initialization, - ReSymbolSpace* spaceInitialization, - ReASItem* statements, - ReSymbolSpace* space, - int maxStack) -{ - ReVMThread* thread = new ReVMThread( - maxStack <= 0 ? m_maxStack : maxStack, this); - m_threads.append(thread); - if (initialization != NULL){ - thread->execute(dynamic_cast(initialization), - spaceInitialization); - } - if (statements != NULL) - thread->execute(dynamic_cast(statements), space); + ReSymbolSpace* spaceInitialization, ReASItem* statements, + ReSymbolSpace* space, int maxStack){ + ReVMThread* thread = new ReVMThread(maxStack <= 0 ? m_maxStack : maxStack, + this); + m_threads.append(thread); + if (initialization != NULL){ + thread->execute(dynamic_cast (initialization), + spaceInitialization); + } + if (statements != NULL) + thread->execute(dynamic_cast (statements), space); } /** * @brief Tests whether a given flag is set. @@ -429,10 +405,9 @@ void ReVirtualMachine::addThread(ReASItem* initialization, * @return true: the flag is set
* false: otherwise */ -bool ReVirtualMachine::hasFlag(ReVirtualMachine::VMFlag flag) const -{ - bool rc = (m_flags & flag) != 0; - return rc; +bool ReVirtualMachine::hasFlag(ReVirtualMachine::VMFlag flag) const{ + bool rc = (m_flags & flag) != 0; + return rc; } /** * @brief Adds a flag to the current flags. @@ -440,9 +415,8 @@ bool ReVirtualMachine::hasFlag(ReVirtualMachine::VMFlag flag) const * @param flag * @return */ -void ReVirtualMachine::setFlag(ReVirtualMachine::VMFlag flag) -{ - m_flags |= flag; +void ReVirtualMachine::setFlag(ReVirtualMachine::VMFlag flag){ + m_flags |= flag; } /** @@ -451,18 +425,16 @@ void ReVirtualMachine::setFlag(ReVirtualMachine::VMFlag flag) * @param flag * @return */ -void ReVirtualMachine::clearFlag(ReVirtualMachine::VMFlag flag) -{ - m_flags &= ~flag; +void ReVirtualMachine::clearFlag(ReVirtualMachine::VMFlag flag){ + m_flags &= ~flag; } /** * @brief Returns the trace writer. * @return the trace writer */ -ReWriter* ReVirtualMachine::traceWriter() const -{ - return m_traceWriter; +ReWriter* ReVirtualMachine::traceWriter() const{ + return m_traceWriter; } /** @@ -470,17 +442,15 @@ ReWriter* ReVirtualMachine::traceWriter() const * * @param traceWriter the new writer */ -void ReVirtualMachine::setTraceWriter(ReWriter* traceWriter) -{ - m_traceWriter = traceWriter; +void ReVirtualMachine::setTraceWriter(ReWriter* traceWriter){ + m_traceWriter = traceWriter; } /** * @brief Returns the abstract symbol tree. * * @return the abstract symbol tree */ -ReASTree& ReVirtualMachine::tree() const -{ - return m_tree; +ReASTree& ReVirtualMachine::tree() const{ + return m_tree; } diff --git a/expr/ReVM.hpp b/expr/ReVM.hpp index 938a1a4..86d0f92 100644 --- a/expr/ReVM.hpp +++ b/expr/ReVM.hpp @@ -1,114 +1,112 @@ /* - * Licence: + * ReVM.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ - + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #ifndef ReVM_HPP #define ReVM_HPP -class ReVMException : public ReException { +class ReVMException: public ReException { public: - ReVMException(const char* message, ...); + ReVMException(const char* message, ...); }; class ReStackFrame { public: - ReStackFrame(ReASItem* caller, ReSymbolSpace* symbols); - ~ReStackFrame(); + ReStackFrame(ReASItem* caller, ReSymbolSpace* symbols); + ~ReStackFrame(); public: - ReASVariant& valueOfVariable(int index); - ReSymbolSpace* symbols() const; + ReASVariant& valueOfVariable(int index); + ReSymbolSpace* symbols() const; private: - int m_countVariables; - ReASVariant* m_variables; - ReSymbolSpace* m_symbols; - ReASItem* m_caller; + int m_countVariables; + ReASVariant* m_variables; + ReSymbolSpace* m_symbols; + ReASItem* m_caller; }; class ReVirtualMachine; -class ReVMThread -{ - friend class ReASItem; - friend class ReASStatement; - friend class ReASCalculable; - friend class ReASCondition; +class ReVMThread { + friend class ReASItem; + friend class ReASStatement; + friend class ReASCalculable; + friend class ReASCondition; public: - typedef QList StackFrameList; + typedef QList StackFrameList; public: - ReVMThread(int maxStack, ReVirtualMachine* vm); + ReVMThread(int maxStack, ReVirtualMachine* vm); public: - void execute(ReASNode1* statements, ReSymbolSpace* space); - virtual void debug(ReASNode1* statement); - ReWriter* errorWriter() const; - void setErrorWriter(ReWriter* errorWriter); - ReLogger* logger() const; - ReASVariant& reserveValue(); - ReASVariant& topOfValues(); - ReASVariant& top2OfValues(); - ReASVariant& popValue(); - void valueToTop(ReSymbolSpace* symbolSpace, int variableNo); - ReASVariant& lValue(ReASItem* item); - ReASVariant& valueOfVariable(ReSymbolSpace* symbolSpace, int variableNo); - bool tracing() const; - void setTracing(bool tracing); - ReVirtualMachine* vm() const; - void pushFrame(ReStackFrame* frame); - void popFrame(); + void execute(ReASNode1* statements, ReSymbolSpace* space); + virtual void debug(ReASNode1* statement); + ReWriter* errorWriter() const; + void setErrorWriter(ReWriter* errorWriter); + ReLogger* logger() const; + ReASVariant& reserveValue(); + ReASVariant& topOfValues(); + ReASVariant& top2OfValues(); + ReASVariant& popValue(); + void valueToTop(ReSymbolSpace* symbolSpace, int variableNo); + ReASVariant& lValue(ReASItem* item); + ReASVariant& valueOfVariable(ReSymbolSpace* symbolSpace, int variableNo); + bool tracing() const; + void setTracing(bool tracing); + ReVirtualMachine* vm() const; + void pushFrame(ReStackFrame* frame); + void popFrame(); protected: - int m_id; - bool m_debugMode; - bool m_singleStep; - bool m_tracing; - int m_maxStack; - StackFrameList m_frameStack; - int m_topOfFrames; - QList m_valueStack; - int m_topOfValues; - ReVirtualMachine* m_vm; - ReLogger* m_logger; + int m_id; + bool m_debugMode; + bool m_singleStep; + bool m_tracing; + int m_maxStack; + StackFrameList m_frameStack; + int m_topOfFrames; + QList m_valueStack; + int m_topOfValues; + ReVirtualMachine* m_vm; + ReLogger* m_logger; private: - static int m_nextId; + static int m_nextId; }; -class ReVirtualMachine -{ +class ReVirtualMachine { public: - enum VMFlag { - VF_UNDEF, - VF_TRACE_STATEMENTS = 1<<1, - VF_TRACE_LOCALS = 1<<2, - VF_TRACE_AUTO_VARIABLES = 1<<3 + enum VMFlag { + VF_UNDEF, + VF_TRACE_STATEMENTS = 1 << 1, + VF_TRACE_LOCALS = 1 << 2, + VF_TRACE_AUTO_VARIABLES = 1 << 3 - }; - typedef QList LineList; + }; + typedef QList LineList; public: - ReVirtualMachine(ReASTree& tree, ReSource& source, int maxStack = 1024); + ReVirtualMachine(ReASTree& tree, ReSource& source, int maxStack = 1024); public: - void executeModule(const char* module); - void addThread(ReASItem* initialization, - ReSymbolSpace* spaceInitialization, - ReASItem* statements, ReSymbolSpace* space, - int maxStack = 0); - bool hasFlag(VMFlag flag) const; - void setFlag(VMFlag flag); - void clearFlag(VMFlag flag); - ReWriter* traceWriter() const; - void setTraceWriter(ReWriter* traceWriter); - ReASTree& tree() const; + void executeModule(const char* module); + void addThread(ReASItem* initialization, ReSymbolSpace* spaceInitialization, + ReASItem* statements, ReSymbolSpace* space, int maxStack = 0); + bool hasFlag(VMFlag flag) const; + void setFlag(VMFlag flag); + void clearFlag(VMFlag flag); + ReWriter* traceWriter() const; + void setTraceWriter(ReWriter* traceWriter); + ReASTree& tree() const; private: - int m_maxStack; - QList m_threads; - int m_flags; - ReSource& m_source; - ReASTree& m_tree; - LineList m_trace; - ReWriter* m_traceWriter; + int m_maxStack; + QList m_threads; + int m_flags; + ReSource& m_source; + ReASTree& m_tree; + LineList m_trace; + ReWriter* m_traceWriter; }; #endif // ReVM_HPP diff --git a/expr/reexpr.hpp b/expr/reexpr.hpp index 3cb43d5..e21c50a 100644 --- a/expr/reexpr.hpp +++ b/expr/reexpr.hpp @@ -1,11 +1,13 @@ /* - * Licence: + * reexpr.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ - + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #ifndef RPLEXPR_HPP #define RPLEXPR_HPP @@ -18,11 +20,11 @@ #include #include -#include "rplexpr/rplsource.hpp" -#include "rplexpr/rpllexer.hpp" -#include "rplexpr/rplastree.hpp" -#include "rplexpr/ReVM.hpp" -#include "rplexpr/rplparser.hpp" -#include "rplexpr/rplmfparser.hpp" +#include "expr/ReSource.hpp" +#include "expr/ReLexer.hpp" +#include "expr/ReASTree.hpp" +#include "expr/ReVM.hpp" +#include "expr/ReParser.hpp" +#include "expr/ReMFParser.hpp" #endif // RPLEXPR_HPP diff --git a/math/ReEnigma.cpp b/math/ReEnigma.cpp index f575f43..691f9e5 100644 --- a/math/ReEnigma.cpp +++ b/math/ReEnigma.cpp @@ -1,10 +1,12 @@ /* - * - * Licence: + * ReEnigma.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ /** @file * @@ -47,27 +49,28 @@ const char* ReEnigma::SET_DECIMALS = "0123456789"; const char* ReEnigma::SET_HEXDIGITS = "0123456789abcdef"; const char* ReEnigma::SET_ALPHANUM = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz_"; + "abcdefghijklmnopqrstuvwxyz_"; const char* ReEnigma::SET_FILENAME = " !^°$%&=+~#-.0123456789ABCDEFGHIJKLM" - "NOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_"; + "NOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_"; const char* ReEnigma::SET_32_127 = " !\"#$%&'()*+,-./0123456789:;<=>?@" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f"; -const char* ReEnigma::SET_32_255 = " !\"#$%&'()*+,-./0123456789:;<=>?@" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f" - "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" - "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" - "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" - "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"; + "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f"; +const char* ReEnigma::SET_32_255 = + " !\"#$%&'()*+,-./0123456789:;<=>?@" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f" + "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" + "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" + "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" + "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"; const char* ReEnigma::SET_PRINTABLE_127 = - "\t\r\n !\"#$%&'()*+,-./0123456789:;<=>?@" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f"; + "\t\r\n !\"#$%&'()*+,-./0123456789:;<=>?@" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f"; const char* ReEnigma::SET_PRINTABLE_255 = - "\t\r\n !\"#$%&'()*+,-./0123456789:;<=>?@" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f" - "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" - "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" - "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" - "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"; + "\t\r\n !\"#$%&'()*+,-./0123456789:;<=>?@" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f" + "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" + "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf" + "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf" + "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"; /** * @brief Constructor. @@ -75,25 +78,25 @@ const char* ReEnigma::SET_PRINTABLE_255 = * @param random pseudo random generator */ ReEnigma::ReEnigma(ReRandom* random) : - m_random(random), - m_ownsRandom(false), - m_secrets(), - m_randomCalls(0), - m_randomSource("4711") { - m_randomSource.reserve(8096); - if(random == NULL) { - m_random = new ReRandom(); - m_ownsRandom = true; - } + m_random(random), + m_ownsRandom(false), + m_secrets(), + m_randomCalls(0), + m_randomSource("4711"){ + m_randomSource.reserve(8096); + if (random == NULL){ + m_random = new ReRandom(); + m_ownsRandom = true; + } } /** * @brief Destructor. */ -ReEnigma::~ReEnigma() { - if(m_ownsRandom) { - delete m_random; - m_random = NULL; - } +ReEnigma::~ReEnigma(){ + if (m_ownsRandom){ + delete m_random; + m_random = NULL; + } } /** @@ -104,22 +107,22 @@ ReEnigma::~ReEnigma() { * @return empty string: error while reading
* otherwise: the certificate as byte array */ -QByteArray ReEnigma::readCertificate(const char* filename) { - QByteArray rc = "not implemented: readCertificate(): "; - rc += filename; - assert(rc.isEmpty()); - return rc; +QByteArray ReEnigma::readCertificate(const char* filename){ + QByteArray rc = "not implemented: readCertificate(): "; + rc += filename; + assert(rc.isEmpty()); + return rc; } -inline void buildBooster(QByteArray& booster, const char* charSet) { - int size = 257; - booster.fill(0, size); - int ix = 0; - unsigned char cc; - while((cc = (unsigned char) *charSet++) != '\0') { - booster[cc] = ++ix; - } - booster[0] = ix; +inline void buildBooster(QByteArray& booster, const char* charSet){ + int size = 257; + booster.fill(0, size); + int ix = 0; + unsigned char cc; + while ((cc = (unsigned char) *charSet++) != '\0'){ + booster[cc] = ++ix; + } + booster[0] = ix; } /** @@ -139,20 +142,20 @@ inline void buildBooster(QByteArray& booster, const char* charSet) { * OUT: ready for work */ void ReEnigma::encode(char* data, int size, const char* charSet, - QByteArray& booster) { - if(booster.length() == 0) { - buildBooster(booster, charSet); - } - int lengthOfCharSet = (int)(unsigned char) booster.at(0); - for(int ii = 0; ii < size; ii++) { - unsigned char cc = (unsigned char) data[ii]; - int ix = booster.at(cc); - if(ix != 0) { - int next = nextInt(lengthOfCharSet); - int ix2 = (ix - 1 + next) % lengthOfCharSet; - data[ii] = charSet[ix2]; - } - } + QByteArray& booster){ + if (booster.length() == 0){ + buildBooster(booster, charSet); + } + int lengthOfCharSet = (int) (unsigned char) booster.at(0); + for (int ii = 0; ii < size; ii++){ + unsigned char cc = (unsigned char) data[ii]; + int ix = booster.at(cc); + if (ix != 0){ + int next = nextInt(lengthOfCharSet); + int ix2 = (ix - 1 + next) % lengthOfCharSet; + data[ii] = charSet[ix2]; + } + } } /** @@ -172,20 +175,20 @@ void ReEnigma::encode(char* data, int size, const char* charSet, * OUT: ready for work */ void ReEnigma::decode(char* data, int size, const char* charSet, - QByteArray& booster) { - if(booster.length() == 0) { - buildBooster(booster, charSet); - } - int lengthOfCharSet = (int)(unsigned char) booster.at(0); - for(int ii = 0; ii < size; ii++) { - unsigned char cc = (unsigned char) data[ii]; - int ix = booster.at(cc); - if(ix != 0) { - int next = nextInt(lengthOfCharSet); - int ix2 = (lengthOfCharSet + ix -1 - next) % lengthOfCharSet; - data[ii] = charSet[ix2]; - } - } + QByteArray& booster){ + if (booster.length() == 0){ + buildBooster(booster, charSet); + } + int lengthOfCharSet = (int) (unsigned char) booster.at(0); + for (int ii = 0; ii < size; ii++){ + unsigned char cc = (unsigned char) data[ii]; + int ix = booster.at(cc); + if (ix != 0){ + int next = nextInt(lengthOfCharSet); + int ix2 = (lengthOfCharSet + ix - 1 - next) % lengthOfCharSet; + data[ii] = charSet[ix2]; + } + } } /** * @brief Encodes or decode a byte array. @@ -195,13 +198,13 @@ void ReEnigma::decode(char* data, int size, const char* charSet, * @param data IN: data to encode/decoded
* OUT: data encoded/decoded */ -void ReEnigma::change(QByteArray& data) { - int randomLength = m_randomSource.length(); - for(int ix = data.length() - 1; ix >= 0; ix--) { - char item = data.at(ix); - item = (item ^ nextInt(0xff) ^ m_randomSource.at(ix % randomLength)); - data[ix] = item; - } +void ReEnigma::change(QByteArray& data){ + int randomLength = m_randomSource.length(); + for (int ix = data.length() - 1; ix >= 0; ix--){ + char item = data.at(ix); + item = (item ^ nextInt(0xff) ^ m_randomSource.at(ix % randomLength)); + data[ix] = item; + } } /** @@ -212,45 +215,45 @@ void ReEnigma::change(QByteArray& data) { * * @param byteSecret a byte sequence which influences the random generation */ -void ReEnigma::addByteSecret(QByteArray byteSecret) { - // we expand it to a multiple of 64 bit: - int oldSize = byteSecret.length(); - int newSize = (oldSize + 7) / 8 * 8; - int ix; - if(newSize > oldSize) { - byteSecret.resize(newSize); - int sum = 0; - int start = oldSize > 8 ? oldSize - 8 : 0; - for(ix = start; ix < oldSize; ix++) { - sum += ix + byteSecret.at(ix); - } - for(ix = oldSize; ix < newSize; ix++) { - sum += ix + 7; - byteSecret[ix] = (char)(sum + byteSecret.at(ix-1)); - } - } - int count = newSize / 8; - secret_t* secret = new secret_t(); - secret->m_count = count; - secret->m_list = new uint64_t[count]; - m_secrets.append(secret); - for(ix = 0; ix < count; ix++) { - uint64_t value = 0; - for(int ix2 = 0; ix2 < 8; ix2++) - value = (value << 8) + byteSecret.at(ix * 8 + ix2); - secret->m_list[ix] = value; - } - QByteArray value; - QCryptographicHash hash(QCryptographicHash::Md5); - ReRandom rand; - hash.addData(m_randomSource.constData(), 4); - for(ix = 0; ix < byteSecret.length(); ix++) { - hash.addData(byteSecret.constData() + ix, 1); - QByteArray current = hash.result(); - int ix2 = rand.nextInt(0, m_randomSource.length() - 1); - m_randomSource[ix2] = (m_randomSource.at(ix2) ^ current.at(0)); - m_randomSource.insert(0, current); - } +void ReEnigma::addByteSecret(QByteArray byteSecret){ + // we expand it to a multiple of 64 bit: + int oldSize = byteSecret.length(); + int newSize = (oldSize + 7) / 8 * 8; + int ix; + if (newSize > oldSize){ + byteSecret.resize(newSize); + int sum = 0; + int start = oldSize > 8 ? oldSize - 8 : 0; + for (ix = start; ix < oldSize; ix++){ + sum += ix + byteSecret.at(ix); + } + for (ix = oldSize; ix < newSize; ix++){ + sum += ix + 7; + byteSecret[ix] = (char) (sum + byteSecret.at(ix - 1)); + } + } + int count = newSize / 8; + secret_t* secret = new secret_t(); + secret->m_count = count; + secret->m_list = new uint64_t[count]; + m_secrets.append(secret); + for (ix = 0; ix < count; ix++){ + uint64_t value = 0; + for (int ix2 = 0; ix2 < 8; ix2++) + value = (value << 8) + byteSecret.at(ix * 8 + ix2); + secret->m_list[ix] = value; + } + QByteArray value; + QCryptographicHash hash(QCryptographicHash::Md5); + ReRandom rand; + hash.addData(m_randomSource.constData(), 4); + for (ix = 0; ix < byteSecret.length(); ix++){ + hash.addData(byteSecret.constData() + ix, 1); + QByteArray current = hash.result(); + int ix2 = rand.nextInt(0, m_randomSource.length() - 1); + m_randomSource[ix2] = (m_randomSource.at(ix2) ^ current.at(0)); + m_randomSource.insert(0, current); + } } /** @@ -258,18 +261,18 @@ void ReEnigma::addByteSecret(QByteArray byteSecret) { * @param maxValue * @return */ -int ReEnigma::nextInt(int maxValue) { - uint64_t seed = 0; - QList::const_iterator it; - int ixSecret = m_randomCalls++; - int ix = ixSecret; - for(it = m_secrets.constBegin(); it != m_secrets.constEnd(); ++it) { - secret_t* secret = *it; - seed |= ((secret->m_list[ixSecret % secret->m_count]) >> (ix % 8)); - } - m_random->xorSeed(seed); - int rc = m_random->nextInt(0, maxValue); - return rc; +int ReEnigma::nextInt(int maxValue){ + uint64_t seed = 0; + QList ::const_iterator it; + int ixSecret = m_randomCalls++; + int ix = ixSecret; + for (it = m_secrets.constBegin(); it != m_secrets.constEnd(); ++it){ + secret_t* secret = *it; + seed |= ((secret->m_list[ixSecret % secret->m_count]) >> (ix % 8)); + } + m_random->xorSeed(seed); + int rc = m_random->nextInt(0, maxValue); + return rc; } /** @@ -277,8 +280,8 @@ int ReEnigma::nextInt(int maxValue) { * * @param seed the initial state */ -void ReEnigma::setSeed(uint64_t seed) { - m_random->setSeed(seed); - m_randomCalls = 0; +void ReEnigma::setSeed(uint64_t seed){ + m_random->setSeed(seed); + m_randomCalls = 0; } diff --git a/math/ReEnigma.hpp b/math/ReEnigma.hpp index 1f252c4..5ff7099 100644 --- a/math/ReEnigma.hpp +++ b/math/ReEnigma.hpp @@ -1,59 +1,69 @@ +/* + * ReEnigma.hpp + * + * License: Public Domain + * You can use and modify this file without any restriction. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #ifndef RPLENIGMA_HPP #define RPLENIGMA_HPP class ReEnigma { public: - ///> '0'..'9' - static const char* SET_DECIMALS; - ///> '0'..'9' 'a'..'f' - static const char* SET_HEXDIGITS; - ///> '0'..'9' 'A'..'Z' a'..'z' '_' - static const char* SET_ALPHANUM; - ///> '0'..'9' 'A'..'Z' z'..'z' '_' - static const char* SET_FILENAME; - ///> ' ' .. chr(127) - static const char* SET_32_127; - ///> ' ' .. chr(255) - static const char* SET_32_255; - ///> TAB, CR, NL, ' '..chr(127) - static const char* SET_PRINTABLE_127; - ///> TAB, CR, NL, ' '..chr(255) - static const char* SET_PRINTABLE_255; + ///> '0'..'9' + static const char* SET_DECIMALS; + ///> '0'..'9' 'a'..'f' + static const char* SET_HEXDIGITS; + ///> '0'..'9' 'A'..'Z' a'..'z' '_' + static const char* SET_ALPHANUM; + ///> '0'..'9' 'A'..'Z' z'..'z' '_' + static const char* SET_FILENAME; + ///> ' ' .. chr(127) + static const char* SET_32_127; + ///> ' ' .. chr(255) + static const char* SET_32_255; + ///> TAB, CR, NL, ' '..chr(127) + static const char* SET_PRINTABLE_127; + ///> TAB, CR, NL, ' '..chr(255) + static const char* SET_PRINTABLE_255; protected: - typedef struct { - int m_count; - uint64_t* m_list; - } secret_t; + typedef struct { + int m_count; + uint64_t* m_list; + } secret_t; public: - ReEnigma(ReRandom* random = NULL); - virtual ~ReEnigma(); + ReEnigma(ReRandom* random = NULL); + virtual ~ReEnigma(); private: - // No copy constructor: no implementation! - ReEnigma(const ReEnigma& source); - // Prohibits assignment operator: no implementation! - ReEnigma& operator =(const ReEnigma& source); + // No copy constructor: no implementation! + ReEnigma(const ReEnigma& source); + // Prohibits assignment operator: no implementation! + ReEnigma& operator =(const ReEnigma& source); public: - void encode(char* data, int size, const char* charSet, QByteArray& cache); - void decode(char* data, int size, const char* charSet, QByteArray& cache); - void change(QByteArray& data); - void addByteSecret(QByteArray byteSeed); - void setSeed(uint64_t seed); - QByteArray readCertificate(const char* filename); + void encode(char* data, int size, const char* charSet, QByteArray& cache); + void decode(char* data, int size, const char* charSet, QByteArray& cache); + void change(QByteArray& data); + void addByteSecret(QByteArray byteSeed); + void setSeed(uint64_t seed); + QByteArray readCertificate(const char* filename); protected: - int nextInt(int maxValue); + int nextInt(int maxValue); protected: - ///> a pseudo random generator - ReRandom* m_random; - ///> true: m_random must be destroyed (in the destructor). - bool m_ownsRandom; - ///> This values will be mixed with m_random' seed - QList m_secrets; - ///> each call of setSeed sets this value to 0. - int m_randomCalls; - ///> a byte sequence derived from the secrets - QByteArray m_randomSource; + ///> a pseudo random generator + ReRandom* m_random; + ///> true: m_random must be destroyed (in the destructor). + bool m_ownsRandom; + ///> This values will be mixed with m_random' seed + QList m_secrets; + ///> each call of setSeed sets this value to 0. + int m_randomCalls; + ///> a byte sequence derived from the secrets + QByteArray m_randomSource; }; #endif // RPLENIGMA_HPP diff --git a/math/ReMatrix.cpp b/math/ReMatrix.cpp index 626fe26..b22d747 100644 --- a/math/ReMatrix.cpp +++ b/math/ReMatrix.cpp @@ -1,8 +1,12 @@ /* - * RplMatrix.cpp - * - * Created on: 29.05.2014 - * Author: hm + * ReMatrix.cpp + * + * License: Public Domain + * You can use and modify this file without any restriction. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ /** @file @@ -17,29 +21,24 @@ #include "math/remath.hpp" RplMatrixException::RplMatrixException(const RplMatrix& RplMatrix, - const char* format, ...) : - ReException() -{ - if (! RplMatrix.getName().isEmpty()) - m_message = RplMatrix.getName() + ": "; - char buffer[16*1024]; + const char* format, ...) : + ReException(){ + if (!RplMatrix.getName().isEmpty()) + m_message = RplMatrix.getName() + ": "; + char buffer[16 * 1024]; - va_list args; - va_start(args, format); - qvsnprintf(buffer, sizeof buffer, format, args); - va_end(args); - m_message += buffer; + va_list args; + va_start(args, format); + qvsnprintf(buffer, sizeof buffer, format, args); + va_end(args); + m_message += buffer; } /** * Constructor. */ RplMatrix::RplMatrix(const char* name) : - m_rows(0), - m_cols(0), - m_values(NULL), - m_name(name) -{ + m_rows(0), m_cols(0), m_values(NULL), m_name(name){ } /** @@ -49,19 +48,18 @@ RplMatrix::RplMatrix(const char* name) : * @param cols number of columns * @param name the name of the matrix */ -RplMatrix::RplMatrix(int rows, int cols, const char* name): +RplMatrix::RplMatrix(int rows, int cols, const char* name) : m_rows(rows), m_cols(cols), - m_values(new MatVal[rows*cols]), - m_name(name) -{ + m_values(new MatVal[rows * cols]), + m_name(name){ } /** * Destructor. */ -RplMatrix::~RplMatrix() { - delete m_values; - m_values = NULL; +RplMatrix::~RplMatrix(){ + delete m_values; + m_values = NULL; } /** @@ -70,12 +68,11 @@ RplMatrix::~RplMatrix() { * @param source source to copy */ RplMatrix::RplMatrix(const RplMatrix& source) : - m_rows(0), - m_cols(0), - m_values(NULL), - m_name(source.m_name + QByteArray("-copy")) -{ - resize(source.m_rows, source.m_cols, source.m_values); + m_rows(0), + m_cols(0), + m_values(NULL), + m_name(source.m_name + QByteArray("-copy")){ + resize(source.m_rows, source.m_cols, source.m_values); } /** @@ -85,14 +82,13 @@ RplMatrix::RplMatrix(const RplMatrix& source) : * @param cols the column number * @throws RplMatrixException */ -void RplMatrix::checkDefinition(int rows, int cols) const -{ - if (rows < 0) - throw RplMatrixException(*this, "row number negative: %d", rows); - if (cols < 0) - throw RplMatrixException(*this, "column number negative: %d", cols); - if (double(rows) * cols > 1.0*1000*1000) - throw RplMatrixException(*this, "too many elements: %d*%d", rows, cols); +void RplMatrix::checkDefinition(int rows, int cols) const{ + if (rows < 0) + throw RplMatrixException(*this, "row number negative: %d", rows); + if (cols < 0) + throw RplMatrixException(*this, "column number negative: %d", cols); + if (double(rows) * cols > 1.0 * 1000 * 1000) + throw RplMatrixException(*this, "too many elements: %d*%d", rows, cols); } /** @@ -102,14 +98,13 @@ void RplMatrix::checkDefinition(int rows, int cols) const * @param col the RplMatrix column number: 0..M-1 * @throws RplMatrixException */ -void RplMatrix::check(int row, int col) const -{ - if (row < 0 || row >= m_rows) - throw RplMatrixException(*this, "invalid row: %d not in [0,%d[", row, - m_rows); - if (col < 0 || col >= m_cols) - throw RplMatrixException(*this, "invalid column: %d not in [0,%d[", col, - m_cols); +void RplMatrix::check(int row, int col) const{ + if (row < 0 || row >= m_rows) + throw RplMatrixException(*this, "invalid row: %d not in [0,%d[", row, + m_rows); + if (col < 0 || col >= m_cols) + throw RplMatrixException(*this, "invalid column: %d not in [0,%d[", col, + m_cols); } /** * Checks whether a given Matrix has the same dimensions. @@ -117,16 +112,14 @@ void RplMatrix::check(int row, int col) const * @param operand Matrix to compare * @throws RplMatrixException */ -void RplMatrix::checkSameDimension(const RplMatrix& operand) const -{ - if (m_rows != operand.getRows()) - throw RplMatrixException(*this, - "%s has a different row count: %d / %d", - operand.getName().constData(), m_rows, operand.getRows()); - if (m_cols != operand.getCols()) - throw RplMatrixException(*this, - "%s has a different column count: %d / %d", - operand.getName().constData(), m_cols, operand.getCols()); +void RplMatrix::checkSameDimension(const RplMatrix& operand) const{ + if (m_rows != operand.getRows()) + throw RplMatrixException(*this, "%s has a different row count: %d / %d", + operand.getName().constData(), m_rows, operand.getRows()); + if (m_cols != operand.getCols()) + throw RplMatrixException(*this, + "%s has a different column count: %d / %d", + operand.getName().constData(), m_cols, operand.getCols()); } /** @@ -134,10 +127,9 @@ void RplMatrix::checkSameDimension(const RplMatrix& operand) const * * @param source the source to copy */ -RplMatrix& RplMatrix::operator =(const RplMatrix& source) -{ - resize(source.m_rows, source.m_cols, source.m_values); - return *this; +RplMatrix& RplMatrix::operator =(const RplMatrix& source){ + resize(source.m_rows, source.m_cols, source.m_values); + return *this; } /** * Adds a Matrix to the instance. @@ -145,13 +137,12 @@ RplMatrix& RplMatrix::operator =(const RplMatrix& source) * @param operand Matrix to add * @return the instance itself */ -RplMatrix& RplMatrix::operator +=(const RplMatrix& operand) -{ - checkSameDimension(operand); - for (int ix = m_rows * m_cols - 1; ix >= 0; ix--){ - m_values[ix] += operand.m_values[ix]; - } - return *this; +RplMatrix& RplMatrix::operator +=(const RplMatrix& operand){ + checkSameDimension(operand); + for (int ix = m_rows * m_cols - 1; ix >= 0; ix--){ + m_values[ix] += operand.m_values[ix]; + } + return *this; } /** * Subtracts a matrix from the instance. @@ -159,13 +150,12 @@ RplMatrix& RplMatrix::operator +=(const RplMatrix& operand) * @param operand matrix to subtract * @return the instance itself */ -RplMatrix& RplMatrix::operator -=(const RplMatrix& operand) -{ - checkSameDimension(operand); - for (int ix = m_rows * m_cols - 1; ix >= 0; ix--){ - m_values[ix] -= operand.m_values[ix]; - } - return *this; +RplMatrix& RplMatrix::operator -=(const RplMatrix& operand){ + checkSameDimension(operand); + for (int ix = m_rows * m_cols - 1; ix >= 0; ix--){ + m_values[ix] -= operand.m_values[ix]; + } + return *this; } /** * Builds the sum of the instance and a given matrix. @@ -173,11 +163,10 @@ RplMatrix& RplMatrix::operator -=(const RplMatrix& operand) * @param operand RplMatrix to add * @return a new RplMatrix with the sum */ -RplMatrix RplMatrix::operator +(const RplMatrix& operand) -{ - RplMatrix rc(*this); - rc += operand; - return rc; +RplMatrix RplMatrix::operator +(const RplMatrix& operand){ + RplMatrix rc(*this); + rc += operand; + return rc; } /** * Builds the difference of the instance and a given matrix. @@ -185,11 +174,10 @@ RplMatrix RplMatrix::operator +(const RplMatrix& operand) * @param operand matrix to subtract * @return a new matrix with the difference */ -RplMatrix RplMatrix::operator -(const RplMatrix& operand) -{ - RplMatrix rc(*this); - rc -= operand; - return rc; +RplMatrix RplMatrix::operator -(const RplMatrix& operand){ + RplMatrix rc(*this); + rc -= operand; + return rc; } /** * Adds a scalar to the instance. @@ -197,12 +185,11 @@ RplMatrix RplMatrix::operator -(const RplMatrix& operand) * @param scalar scalar to add * @return the instance itself */ -RplMatrix& RplMatrix::operator +=(MatVal scalar) -{ - for (int ix = m_rows * m_cols - 1; ix >= 0; ix--){ - m_values[ix] += scalar; - } - return *this; +RplMatrix& RplMatrix::operator +=(MatVal scalar){ + for (int ix = m_rows * m_cols - 1; ix >= 0; ix--){ + m_values[ix] += scalar; + } + return *this; } /** * Adds a scalar to the instance. @@ -210,12 +197,11 @@ RplMatrix& RplMatrix::operator +=(MatVal scalar) * @param scalar scalar to add * @return the instance itself */ -RplMatrix& RplMatrix::operator -=(MatVal scalar) -{ - for (int ix = m_rows * m_cols - 1; ix >= 0; ix--){ - m_values[ix] -= scalar; - } - return *this; +RplMatrix& RplMatrix::operator -=(MatVal scalar){ + for (int ix = m_rows * m_cols - 1; ix >= 0; ix--){ + m_values[ix] -= scalar; + } + return *this; } /** * Builds the sum of the instance and a given scalar. @@ -223,11 +209,10 @@ RplMatrix& RplMatrix::operator -=(MatVal scalar) * @param scalar scalar to add * @return a new matrix with the sum */ -RplMatrix RplMatrix::operator +(MatVal scalar) -{ - RplMatrix rc(*this); - rc += scalar; - return rc; +RplMatrix RplMatrix::operator +(MatVal scalar){ + RplMatrix rc(*this); + rc += scalar; + return rc; } /** * Builds the difference of the instance and a given scalar. @@ -235,11 +220,10 @@ RplMatrix RplMatrix::operator +(MatVal scalar) * @param scalar scalar to subtract * @return a new matrix with the sum */ -RplMatrix RplMatrix::operator -(MatVal scalar) -{ - RplMatrix rc(*this); - rc -= scalar; - return rc; +RplMatrix RplMatrix::operator -(MatVal scalar){ + RplMatrix rc(*this); + rc -= scalar; + return rc; } /** * Tests the equiness of the instance with a given matrix. @@ -248,17 +232,16 @@ RplMatrix RplMatrix::operator -(MatVal scalar) * @return true: the matrices are equal
* false: otherwise */ -bool RplMatrix::operator ==(const RplMatrix& operand) const -{ - checkSameDimension(operand); - bool rc = true; - for (int ix = m_rows * m_cols - 1; ix >= 0; ix--){ - if (m_values[ix] != operand.m_values[ix]){ - rc = false; - break; - } - } - return rc; +bool RplMatrix::operator ==(const RplMatrix& operand) const{ + checkSameDimension(operand); + bool rc = true; + for (int ix = m_rows * m_cols - 1; ix >= 0; ix--){ + if (m_values[ix] != operand.m_values[ix]){ + rc = false; + break; + } + } + return rc; } /** * Compares the instance with a given scalar. @@ -267,63 +250,59 @@ bool RplMatrix::operator ==(const RplMatrix& operand) const * @return true: all elements are equal to the scalar
* false: otherwise */ -bool RplMatrix::operator ==(MatVal scalar) const -{ - bool rc = true; - for (int ix = m_rows * m_cols - 1; ix >= 0; ix--){ - if (m_values[ix] != scalar){ - rc = false; - break; - } - } - return rc; +bool RplMatrix::operator ==(MatVal scalar) const{ + bool rc = true; + for (int ix = m_rows * m_cols - 1; ix >= 0; ix--){ + if (m_values[ix] != scalar){ + rc = false; + break; + } + } + return rc; } /** * Sets a new row-column pair. */ RplMatrix& RplMatrix::resize(int rows, int cols, const MatVal values[], - MatVal defaultValue) -{ - checkDefinition(rows, cols); - if (rows != m_rows || cols != m_cols){ - delete m_values; - m_values = new MatVal[rows * cols]; - m_rows = rows; - m_cols = cols; - } - if (values == NULL) - { - for (int ix = rows*cols - 1; ix >= 0; ix--){ - m_values[ix] = defaultValue; - } - } else { - for (int ix = rows*cols - 1; ix >= 0; ix--){ - m_values[ix] = values[ix]; - } - } - return *this; + MatVal defaultValue){ + checkDefinition(rows, cols); + if (rows != m_rows || cols != m_cols){ + delete m_values; + m_values = new MatVal[rows * cols]; + m_rows = rows; + m_cols = cols; + } + if (values == NULL){ + for (int ix = rows * cols - 1; ix >= 0; ix--){ + m_values[ix] = defaultValue; + } + }else{ + for (int ix = rows * cols - 1; ix >= 0; ix--){ + m_values[ix] = values[ix]; + } + } + return *this; } /** * Returns the minimum and the maximum of the instance. * * @return a tuple with the minimum and the maximum */ -Tuple2 RplMatrix::minMax() const -{ +Tuple2 RplMatrix::minMax() const{ #ifndef DBL_MAX #define DBL_MAX std::numeric_limits::max() #define DBL_MIN std::numeric_limits::min() #endif - Tuple2 rc(DBL_MAX, DBL_MIN); + Tuple2 rc(DBL_MAX, DBL_MIN); - for (int ix = m_rows*m_cols - 1; ix >= 0; ix--){ - MatVal x; - if ( (x = m_values[ix]) < rc.m_value1) - rc.m_value1 = x; - if (x > rc.m_value2) - rc.m_value2 = x; - } - return rc; + for (int ix = m_rows * m_cols - 1; ix >= 0; ix--){ + MatVal x; + if ((x = m_values[ix]) < rc.m_value1) + rc.m_value1 = x; + if (x > rc.m_value2) + rc.m_value2 = x; + } + return rc; } /** @@ -331,51 +310,49 @@ Tuple2 RplMatrix::minMax() const * * @return the transposed matrix */ -RplMatrix RplMatrix::transpose() const -{ - RplMatrix rc(m_cols, m_rows); +RplMatrix RplMatrix::transpose() const{ + RplMatrix rc(m_cols, m_rows); - for (int row = 0; row < m_rows; row++){ - for (int col = 0; col < m_cols; col++){ - rc.m_values[m_rows*col + row] = m_values[row * m_cols + col]; - } - } - return rc; + for (int row = 0; row < m_rows; row++){ + for (int col = 0; col < m_cols; col++){ + rc.m_values[m_rows * col + row] = m_values[row * m_cols + col]; + } + } + return rc; } QByteArray RplMatrix::toString(const char* prefix, const char* format, - const char* rowSeparator, const char* colSeparator) const -{ - char buffer[128]; - Tuple2 minMaxi(minMax()); - QByteArray rc; - qsnprintf(buffer, sizeof buffer, format, minMaxi.m_value1); - int length = strlen(buffer); - qsnprintf(buffer, sizeof buffer, format, minMaxi.m_value2); - int length2 = strlen(buffer); - if (length < length2) - length = length2; - qsnprintf(buffer, sizeof buffer, format, - (minMaxi.m_value1 + minMaxi.m_value2) / 2); - length2 = strlen(buffer); - if (length < length2) - length = length2; - if (prefix == NULL) - prefix = ""; - length = m_rows * m_cols * (length + strlen(colSeparator)) - + m_rows * strlen(rowSeparator) + strlen(prefix) + 20; - rc.reserve(length); - rc += prefix; - rc += "["; - for (int row = 0; row < m_rows; row++){ - for (int col = 0; col < m_cols; col++){ - qsnprintf(buffer, sizeof buffer, format, m_values[m_cols*row + col]); - rc += buffer; - rc += colSeparator; - } - rc += rowSeparator; - } - rc += "]"; - return rc; + const char* rowSeparator, const char* colSeparator) const{ + char buffer[128]; + Tuple2 minMaxi(minMax()); + QByteArray rc; + qsnprintf(buffer, sizeof buffer, format, minMaxi.m_value1); + int length = strlen(buffer); + qsnprintf(buffer, sizeof buffer, format, minMaxi.m_value2); + int length2 = strlen(buffer); + if (length < length2) + length = length2; + qsnprintf(buffer, sizeof buffer, format, + (minMaxi.m_value1 + minMaxi.m_value2) / 2); + length2 = strlen(buffer); + if (length < length2) + length = length2; + if (prefix == NULL) + prefix = ""; + length = m_rows * m_cols * (length + strlen(colSeparator)) + + m_rows * strlen(rowSeparator) + strlen(prefix) + 20; + rc.reserve(length); + rc += prefix; + rc += "["; + for (int row = 0; row < m_rows; row++){ + for (int col = 0; col < m_cols; col++){ + qsnprintf(buffer, sizeof buffer, format, m_values[m_cols * row + col]); + rc += buffer; + rc += colSeparator; + } + rc += rowSeparator; + } + rc += "]"; + return rc; } /** * Finds the length of a column. @@ -385,28 +362,28 @@ QByteArray RplMatrix::toString(const char* prefix, const char* format, * @return the count of chars between start and the next separator */ static int lengthOfColumn(const char* text, char separator){ - const char* ptr = text; - while(*ptr == ' ') - ptr++; - char delimiter = 0; - if (*ptr == '"' || *ptr == '\''){ - delimiter = *ptr++; - } - while(*ptr){ - if (*ptr == '\\'){ + const char* ptr = text; + while (*ptr == ' ') + ptr++; + char delimiter = 0; + if (*ptr == '"' || *ptr == '\''){ + delimiter = *ptr++; + } + while (*ptr){ + if (*ptr == '\\'){ + ptr++; + if (*ptr != '\0') ptr++; - if (*ptr != '\0') - ptr++; - } else if (*ptr == separator) - break; - else if (*ptr != delimiter){ + }else if (*ptr == separator) + break; + else if (*ptr != delimiter){ + ptr++; + while (*ptr && *ptr != separator) ptr++; - while(*ptr && *ptr != separator) - ptr++; - } - } - int rc = ptr - text; - return rc; + } + } + int rc = ptr - text; + return rc; } /** * Skips all columns with a content other than a numeric value. @@ -415,16 +392,15 @@ static int lengthOfColumn(const char* text, char separator){ * @param separator the column separator * @return the start of a number or "" */ -static const char* skipNonNumbers(const char* line, char separator) -{ - int len1, len2 = 0; +static const char* skipNonNumbers(const char* line, char separator){ + int len1, len2 = 0; - while ( (len1 = ReStringUtil::lengthOfNumber(line)) == 0 - && (len2 = lengthOfColumn(line, separator)) > 0) - line += len2; - if (*line == separator) - line++; - return line; + while ((len1 = ReStringUtil::lengthOfNumber(line)) == 0 && (len2 = + lengthOfColumn(line, separator)) > 0) + line += len2; + if (*line == separator) + line++; + return line; } /** * Returns the count of numeric numbers in a CSV line. @@ -434,85 +410,81 @@ static const char* skipNonNumbers(const char* line, char separator) * otherwise: the count of numeric columns in the line */ static int countNumbers(const char* line, char separator){ - line = skipNonNumbers(line, separator); - bool again = true; - int rc = 0; - char cc; - while(again && (cc = *line) != '\0' && cc != '\n' && cc != '\r'){ - int length = ReStringUtil::lengthOfNumber(line, true); - if (length == 0){ - rc = 0; - again = false; - } else { - line += length; - rc++; - if (*line == separator) - line++; - } - } - return rc; + line = skipNonNumbers(line, separator); + bool again = true; + int rc = 0; + char cc; + while (again && (cc = *line) != '\0' && cc != '\n' && cc != '\r'){ + int length = ReStringUtil::lengthOfNumber(line, true); + if (length == 0){ + rc = 0; + again = false; + }else{ + line += length; + rc++; + if (*line == separator) + line++; + } + } + return rc; } /** * Reads a file with the CSV (comma separated values) format * into the instance. */ -void RplMatrix::readFromCvs(const char* filename, int maxLineLength) -{ - FILE* fp = fopen(filename, "r"); - if (fp == NULL) - throw RplMatrixException(*this, "Cannot open %s (%d)", filename, errno); - char* buffer = new char[maxLineLength + 1]; - const char* line; - char separator = ReStringUtil::findCsvSeparator(fp, buffer, maxLineLength); - int rows = 0; - int cols = 0; - int nCols; - // find the count of rows and columns: - while( (line = fgets(buffer, maxLineLength, fp)) != NULL) - { - if ( (nCols = countNumbers(line, separator)) > 0){ - rows++; - if (nCols > cols) - cols = nCols; - } - } - resize(rows, cols); - // find the values - fseek(fp, 0, SEEK_SET); - int row = -1; - while( (line = fgets(buffer, maxLineLength, fp)) != NULL) - { - int nCols; - if ( (nCols = countNumbers(line, separator)) > 0){ - row++; - line = skipNonNumbers(line, separator); - int col = -1; - int length; - const char* ptr; - while( (length = ReStringUtil::lengthOfNumber(line, true)) > 0){ - col++; - ptr = line; - line += length; - while(*ptr == ' ') - ptr++; - MatVal value = atof(ptr); - m_values[m_cols*row + col] = value; - if (*line == separator) - line++; - else - break; - } - } - } +void RplMatrix::readFromCvs(const char* filename, int maxLineLength){ + FILE* fp = fopen(filename, "r"); + if (fp == NULL) + throw RplMatrixException(*this, "Cannot open %s (%d)", filename, errno); + char* buffer = new char[maxLineLength + 1]; + const char* line; + char separator = ReStringUtil::findCsvSeparator(fp, buffer, maxLineLength); + int rows = 0; + int cols = 0; + int nCols; + // find the count of rows and columns: + while ((line = fgets(buffer, maxLineLength, fp)) != NULL){ + if ((nCols = countNumbers(line, separator)) > 0){ + rows++; + if (nCols > cols) + cols = nCols; + } + } + resize(rows, cols); + // find the values + fseek(fp, 0, SEEK_SET); + int row = -1; + while ((line = fgets(buffer, maxLineLength, fp)) != NULL){ + int nCols; + if ((nCols = countNumbers(line, separator)) > 0){ + row++; + line = skipNonNumbers(line, separator); + int col = -1; + int length; + const char* ptr; + while ((length = ReStringUtil::lengthOfNumber(line, true)) > 0){ + col++; + ptr = line; + line += length; + while (*ptr == ' ') + ptr++; + MatVal value = atof(ptr); + m_values[m_cols * row + col] = value; + if (*line == separator) + line++; + else + break; + } + } + } - fclose(fp); - delete buffer; + fclose(fp); + delete buffer; } void RplMatrix::readFromXml(const char* filename, const char* tagCol, - const char* tagRow, const char* tagTable, - int maxLineLength) -{ - throw RplMatrixException(*this, "readFromXml not implementes: %s %s %s %s %d", - filename, tagCol, tagRow, tagTable, maxLineLength); + const char* tagRow, const char* tagTable, int maxLineLength){ + throw RplMatrixException(*this, + "readFromXml not implementes: %s %s %s %s %d", filename, tagCol, tagRow, + tagTable, maxLineLength); } diff --git a/math/ReMatrix.hpp b/math/ReMatrix.hpp index d0f168d..c4b55c4 100644 --- a/math/ReMatrix.hpp +++ b/math/ReMatrix.hpp @@ -1,22 +1,24 @@ /* - * RplMatrix.hpp - * - * Created on: 29.05.2014 - * Author: hm + * ReMatrix.hpp + * + * License: Public Domain + * You can use and modify this file without any restriction. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #ifndef RplMatrix_HPP_ #define RplMatrix_HPP_ - class RplMatrix; /** * Implements a RplMatrix specific exception. */ -class RplMatrixException : public ReException -{ +class RplMatrixException: public ReException { public: - RplMatrixException(const RplMatrix& RplMatrix, const char* format, ...); + RplMatrixException(const RplMatrix& RplMatrix, const char* format, ...); }; /** @@ -26,71 +28,78 @@ typedef qreal MatVal; class Tuple2 { public: - Tuple2(MatVal value1, MatVal value2) : - m_value1(value1), - m_value2(value2) - {} + Tuple2(MatVal value1, MatVal value2) : + m_value1(value1), m_value2(value2){ + } public: - MatVal m_value1; - MatVal m_value2; + MatVal m_value1; + MatVal m_value2; }; /** * Implements a RplMatrix with 2 dimensions. */ class RplMatrix { public: - RplMatrix(const char* name = NULL); - RplMatrix(int rows, int cols, const char* name = NULL); - virtual ~RplMatrix(); - RplMatrix(const RplMatrix& source); - RplMatrix& operator =(const RplMatrix& source); + RplMatrix(const char* name = NULL); + RplMatrix(int rows, int cols, const char* name = NULL); + virtual ~RplMatrix(); + RplMatrix(const RplMatrix& source); + RplMatrix& operator =(const RplMatrix& source); public: - RplMatrix& operator +=(const RplMatrix& operand); - RplMatrix& operator -=(const RplMatrix& operand); - RplMatrix operator +(const RplMatrix& operand); - RplMatrix operator -(const RplMatrix& operand); - RplMatrix& operator +=(MatVal scalar); - RplMatrix& operator -=(MatVal scalar); - RplMatrix operator +(MatVal scalar); - RplMatrix operator -(MatVal scalar); - bool operator ==(const RplMatrix& operand) const; - bool operator ==(MatVal scalar) const; - inline bool operator !=(const RplMatrix& operand) const - { return ! (*this == operand); } - inline bool operator !=(MatVal operand) - { return ! (*this == operand); } + RplMatrix& operator +=(const RplMatrix& operand); + RplMatrix& operator -=(const RplMatrix& operand); + RplMatrix operator +(const RplMatrix& operand); + RplMatrix operator -(const RplMatrix& operand); + RplMatrix& operator +=(MatVal scalar); + RplMatrix& operator -=(MatVal scalar); + RplMatrix operator +(MatVal scalar); + RplMatrix operator -(MatVal scalar); + bool operator ==(const RplMatrix& operand) const; + bool operator ==(MatVal scalar) const; + inline bool operator !=(const RplMatrix& operand) const{ + return !(*this == operand); + } + inline bool operator !=(MatVal operand){ + return !(*this == operand); + } public: - inline const QByteArray& getName() const - { return m_name; } - inline MatVal get(int row, int col) const - { check(row, col); return m_values[row*m_cols + col]; } - inline RplMatrix& set(int row, int col, MatVal value) - { check(row, col); m_values[row*m_cols + col] = value; return *this; } - inline int getRows() const - { return m_rows; } - inline int getCols() const - { return m_cols; } + inline const QByteArray& getName() const{ + return m_name; + } + inline MatVal get(int row, int col) const{ + check(row, col); + return m_values[row * m_cols + col]; + } + inline RplMatrix& set(int row, int col, MatVal value){ + check(row, col); + m_values[row * m_cols + col] = value; + return *this; + } + inline int getRows() const{ + return m_rows; + } + inline int getCols() const{ + return m_cols; + } public: - void checkDefinition(int rows, int cols) const; - void check(int row, int col) const; - void checkSameDimension(const RplMatrix& operand) const; - RplMatrix& resize(int rows, int cols, const MatVal values[] = NULL, - MatVal defaultValue = 0.0); - Tuple2 minMax() const; - RplMatrix transpose() const; - QByteArray toString(const char* prefix = NULL, - const char* format = "%f", - const char* rowSeparator = "\n", - const char* colSeparator = ",") const; - void readFromCvs(const char* filename, int maxLineLength = 1024*1024); - void readFromXml(const char* filename, const char* tagCol, - const char* tagRow, const char* tagTable, - int maxLineLength = 1024*1024); + void checkDefinition(int rows, int cols) const; + void check(int row, int col) const; + void checkSameDimension(const RplMatrix& operand) const; + RplMatrix& resize(int rows, int cols, const MatVal values[] = NULL, + MatVal defaultValue = 0.0); + Tuple2 minMax() const; + RplMatrix transpose() const; + QByteArray toString(const char* prefix = NULL, const char* format = "%f", + const char* rowSeparator = "\n", const char* colSeparator = ",") const; + void readFromCvs(const char* filename, int maxLineLength = 1024 * 1024); + void readFromXml(const char* filename, const char* tagCol, + const char* tagRow, const char* tagTable, + int maxLineLength = 1024 * 1024); protected: - int m_rows; - int m_cols; - MatVal* m_values; - QByteArray m_name; + int m_rows; + int m_cols; + MatVal* m_values; + QByteArray m_name; }; #endif /* RplMatrix_HPP_ */ diff --git a/math/ReRandom.cpp b/math/ReRandom.cpp index 4d38a4f..2fab07e 100644 --- a/math/ReRandom.cpp +++ b/math/ReRandom.cpp @@ -1,9 +1,12 @@ /* - * Licence: + * ReRandom.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ /** @file @@ -27,13 +30,13 @@ * @brief Constructor. */ ReRandom::ReRandom() : - m_seed(0) { + m_seed(0){ } /** * @brief Destructor. */ -ReRandom::~ReRandom() { +ReRandom::~ReRandom(){ } /** @@ -41,26 +44,26 @@ ReRandom::~ReRandom() { * * @return the next random number. */ -uint64_t ReRandom::nextInt64() { - // Donald Knuth recommands (for 64-Bit): - m_seed = m_seed * 6364136223846793005L + 1442695040888963407L; - return m_seed; +uint64_t ReRandom::nextInt64(){ + // Donald Knuth recommands (for 64-Bit): + m_seed = m_seed * 6364136223846793005L + 1442695040888963407L; + return m_seed; } /** * @brief Sets the random seed. * * @param seed the new seed. */ -void ReRandom::setSeed(uint64_t seed) { - m_seed = seed; +void ReRandom::setSeed(uint64_t seed){ + m_seed = seed; } /** * @brief Modifies the seed. * * @param seed the XOR operand. */ -void ReRandom::xorSeed(uint64_t seed) { - m_seed ^= seed; +void ReRandom::xorSeed(uint64_t seed){ + m_seed ^= seed; } /** @@ -68,11 +71,11 @@ void ReRandom::xorSeed(uint64_t seed) { * * @return a pseudo random value 0..255 */ -uint8_t ReRandom::nextByte() { - uint64_t value = nextInt64(); - // forget the last 3 bits: - uint8_t rc = (uint8_t)(value >> 3) % 256; - return rc; +uint8_t ReRandom::nextByte(){ + uint64_t value = nextInt64(); + // forget the last 3 bits: + uint8_t rc = (uint8_t) (value >> 3) % 256; + return rc; } /** @@ -82,15 +85,15 @@ uint8_t ReRandom::nextByte() { * @param maxValue the maximal result (includeing) * @return the next integer */ -int ReRandom::nextInt(int minValue, int maxValue) { - uint64_t value = nextInt64(); - uint64_t diff = maxValue - minValue; - int rc; - if(diff <= 0) - rc = minValue; - else - rc = (int)(minValue + value % diff); - return rc; +int ReRandom::nextInt(int minValue, int maxValue){ + uint64_t value = nextInt64(); + uint64_t diff = maxValue - minValue; + int rc; + if (diff <= 0) + rc = minValue; + else + rc = (int) (minValue + value % diff); + return rc; } /** @@ -101,13 +104,13 @@ int ReRandom::nextInt(int minValue, int maxValue) { * @param maxChar all characters of the result are lower or equal than this value * @return a random string */ -QByteArray ReRandom::nextString(int length, char minChar, char maxChar) { - QByteArray rc; - rc.resize(length); - for(int ii = 0; ii < length; ii++) { - rc[ii] = nextInt(minChar, maxChar); - } - return rc; +QByteArray ReRandom::nextString(int length, char minChar, char maxChar){ + QByteArray rc; + rc.resize(length); + for (int ii = 0; ii < length; ii++){ + rc[ii] = nextInt(minChar, maxChar); + } + return rc; } /** @@ -117,13 +120,13 @@ QByteArray ReRandom::nextString(int length, char minChar, char maxChar) { * @param charSet a string with all allowed characters * @return a random string with characters from the given set */ -QByteArray ReRandom::nextString(int length, char* charSet) { - QByteArray rc; - rc.resize(length); - int ubound = strlen(charSet) - 1; - for(int ii = 0; ii < length; ii++) { - rc[ii] = charSet[nextInt(0, ubound)]; - } - return rc; +QByteArray ReRandom::nextString(int length, char* charSet){ + QByteArray rc; + rc.resize(length); + int ubound = strlen(charSet) - 1; + for (int ii = 0; ii < length; ii++){ + rc[ii] = charSet[nextInt(0, ubound)]; + } + return rc; } diff --git a/math/ReRandom.hpp b/math/ReRandom.hpp index 14e04f7..9fa8a08 100644 --- a/math/ReRandom.hpp +++ b/math/ReRandom.hpp @@ -1,26 +1,36 @@ +/* + * ReRandom.hpp + * + * License: Public Domain + * You can use and modify this file without any restriction. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #ifndef RERANDOM_HPP #define RERANDOM_HPP class ReRandom { public: - ReRandom(); - virtual ~ReRandom(); + ReRandom(); + virtual ~ReRandom(); private: - // No copy constructor: no implementation! - ReRandom(const ReRandom& source); - // Prohibits assignment operator: no implementation! - ReRandom& operator =(const ReRandom& source); + // No copy constructor: no implementation! + ReRandom(const ReRandom& source); + // Prohibits assignment operator: no implementation! + ReRandom& operator =(const ReRandom& source); public: - virtual uint64_t nextInt64(); - virtual void setSeed(uint64_t seed); - void xorSeed(uint64_t seed); - uint8_t nextByte(); - int nextInt(int minValue, int maxValue); - QByteArray nextString(int length = 8, char minChar = ' ', char maxChar = 127); - QByteArray nextString(int length, char* charSet); + virtual uint64_t nextInt64(); + virtual void setSeed(uint64_t seed); + void xorSeed(uint64_t seed); + uint8_t nextByte(); + int nextInt(int minValue, int maxValue); + QByteArray nextString(int length = 8, char minChar = ' ', + char maxChar = 127); + QByteArray nextString(int length, char* charSet); protected: - uint64_t m_seed; + uint64_t m_seed; }; - #endif // RERANDOM_HPP diff --git a/math/remath.hpp b/math/remath.hpp index 236f3fd..eaaef4a 100644 --- a/math/remath.hpp +++ b/math/remath.hpp @@ -1,9 +1,12 @@ /* - * Licence: + * remath.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #ifndef RPLMATH_HPP #define RPLMATH_HPP diff --git a/net/ReNetConfig.cpp b/net/ReNetConfig.cpp index da7bcc1..c7c495a 100644 --- a/net/ReNetConfig.cpp +++ b/net/ReNetConfig.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * ReNetConfig.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #include "base/rebase.hpp" #include "math/remath.hpp" diff --git a/net/ReNetConfig.hpp b/net/ReNetConfig.hpp index 9cef175..cf523f6 100644 --- a/net/ReNetConfig.hpp +++ b/net/ReNetConfig.hpp @@ -1,21 +1,22 @@ /* - * Licence: + * ReNetConfig.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ - + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #ifndef RPLNETCONFIG_HPP #define RPLNETCONFIG_HPP -class ReNetConfig -{ +class ReNetConfig { public: - static const char* IP; - static const char* PORT; - static const char* SLEEP_MILLISEC; + static const char* IP; + static const char* PORT; + static const char* SLEEP_MILLISEC; }; #endif // RPLNETCONFIG_HPP diff --git a/net/ReTCPClient.cpp b/net/ReTCPClient.cpp index 8912fe9..d9017d3 100644 --- a/net/ReTCPClient.cpp +++ b/net/ReTCPClient.cpp @@ -1,18 +1,20 @@ /* - * Licence: + * ReTCPClient.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #include "base/rebase.hpp" #include "math/remath.hpp" #include "net/renet.hpp" enum { - LOC_1 = LOC_FIRST_OF(LOC_TCPCLIENT), // 10701 - LOC_HANDLE_ERROR_1, - LOC_SET_REMOTE_ADDRESS_1, + LOC_1 = LOC_FIRST_OF(LOC_TCPCLIENT), // 10701 + LOC_HANDLE_ERROR_1, LOC_SET_REMOTE_ADDRESS_1, }; /** @class RplTcpClient rpltcpclient.hpp "rplnet/rpltcpclient.hpp" @@ -30,23 +32,23 @@ enum { * @param logger a logger */ RplTcpClient::RplTcpClient(ReConfigurator& configurator, QThread* thread, - ReTerminator* terminator, - ReLogger* logger) : - m_peer(new ReTCPPeer(configurator, thread, terminator, false, logger)), - m_logger(logger), - m_configurator(configurator){ - QByteArray ip = configurator.asString(ReNetConfig::IP, "localhost"); - int port = configurator.asInt(ReNetConfig::PORT, 12345); - if(! ip.isEmpty() && port != 0) - setRemoteAddress(ip.constData(), port); + ReTerminator* terminator, ReLogger* logger) : + m_peer( + new ReTCPPeer(configurator, thread, terminator, false, logger)), + m_logger(logger), + m_configurator(configurator){ + QByteArray ip = configurator.asString(ReNetConfig::IP, "localhost"); + int port = configurator.asInt(ReNetConfig::PORT, 12345); + if (!ip.isEmpty() && port != 0) + setRemoteAddress(ip.constData(), port); } /** * @brief Destructor. */ -RplTcpClient::~RplTcpClient() { - delete m_peer; - m_peer = NULL; +RplTcpClient::~RplTcpClient(){ + delete m_peer; + m_peer = NULL; } /** @@ -54,30 +56,30 @@ RplTcpClient::~RplTcpClient() { * @param ip NULL or the ip to connect * @param port 0 or the port to connect */ -void RplTcpClient::setRemoteAddress(const char* ip, int port) { - QTcpSocket* socket = (QTcpSocket*) m_peer->getSocket(); - delete socket; - if(ip == NULL || port == 0) - m_peer->setSocket(NULL); - else { - socket = new QTcpSocket(); - connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), - this, SLOT(handleError(QAbstractSocket::SocketError))); - m_peer->setSocket(socket); - m_peer->setAddress(ip, port); - m_logger->logv(LOG_INFO, LOC_SET_REMOTE_ADDRESS_1, - "connect with %s:%d", ip, port); - socket->connectToHost(ReString(ip), port); - socket->waitForConnected(); - } +void RplTcpClient::setRemoteAddress(const char* ip, int port){ + QTcpSocket* socket = (QTcpSocket*) m_peer->getSocket(); + delete socket; + if (ip == NULL || port == 0) + m_peer->setSocket(NULL); + else{ + socket = new QTcpSocket(); + connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, + SLOT(handleError(QAbstractSocket::SocketError))); + m_peer->setSocket(socket); + m_peer->setAddress(ip, port); + m_logger->logv(LOG_INFO, LOC_SET_REMOTE_ADDRESS_1, "connect with %s:%d", + ip, port); + socket->connectToHost(ReString(ip), port); + socket->waitForConnected(); + } } /** * @brief Returns the peer info. * @return the peer info */ -ReTCPPeer* RplTcpClient::getPeer() const { - return m_peer; +ReTCPPeer* RplTcpClient::getPeer() const{ + return m_peer; } /** @@ -85,10 +87,10 @@ ReTCPPeer* RplTcpClient::getPeer() const { * * @param socketError the error code */ -void RplTcpClient::handleError(QAbstractSocket::SocketError socketError) { - if (m_logger != NULL) - m_logger->logv(LOG_ERROR, LOC_HANDLE_ERROR_1, "Network error %d", - socketError); +void RplTcpClient::handleError(QAbstractSocket::SocketError socketError){ + if (m_logger != NULL) + m_logger->logv(LOG_ERROR, LOC_HANDLE_ERROR_1, "Network error %d", + socketError); } /** @class RplClientThread rpltcpclient.hpp "rplnet/rpltcpclient.hpp" @@ -105,40 +107,39 @@ void RplTcpClient::handleError(QAbstractSocket::SocketError socketError) { * @param configurator delivers some connection parameters * @param logger the logger. If NULL a default logger will be used */ -RplClientThread::RplClientThread(ReConfigurator& configurator, - ReLogger* logger) : - m_client(NULL), - m_logger(logger), - m_configurator(configurator), - m_ownsLogger(false) { - m_client = new RplTcpClient(configurator, this, NULL, logger); +RplClientThread::RplClientThread(ReConfigurator& configurator, ReLogger* logger) : + m_client(NULL), + m_logger(logger), + m_configurator(configurator), + m_ownsLogger(false){ + m_client = new RplTcpClient(configurator, this, NULL, logger); } /** * @brief Destructor. */ -RplClientThread::~RplClientThread() { - delete m_client; - m_client = NULL; - if(m_ownsLogger) { - delete m_logger; - m_logger = NULL; - } +RplClientThread::~RplClientThread(){ + delete m_client; + m_client = NULL; + if (m_ownsLogger){ + delete m_logger; + m_logger = NULL; + } } /** * @brief Returns the peer which can be used for sending and receiving messages. * * @return the peer */ -ReTCPPeer* RplClientThread::getPeer() const { - return m_client->getPeer(); +ReTCPPeer* RplClientThread::getPeer() const{ + return m_client->getPeer(); } /** * @brief Returns the logger of the thread. * @return the logger */ -ReLogger* RplClientThread::getLogger() const { - return m_logger; +ReLogger* RplClientThread::getLogger() const{ + return m_logger; } /** @@ -146,6 +147,6 @@ ReLogger* RplClientThread::getLogger() const { * * Calls doIt() for the real things. */ -void RplClientThread::run() { - doIt(); +void RplClientThread::run(){ + doIt(); } diff --git a/net/ReTCPClient.hpp b/net/ReTCPClient.hpp index 227df7c..7321dd3 100644 --- a/net/ReTCPClient.hpp +++ b/net/ReTCPClient.hpp @@ -1,72 +1,68 @@ /* - * Licence: + * ReTCPClient.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ -#ifndef RPLTCPCLIENT_HPP -#define RPLTCPCLIENT_HPP - -#ifndef RPLNET_HPP -#include "renet.hpp" -#endif +#ifndef RETCPCLIENT_HPP +#define RETCPCLIENT_HPP class ReTCPPeer; -class RplTcpClient : public QObject { - Q_OBJECT +class RplTcpClient: public QObject { + Q_OBJECT public: - RplTcpClient(ReConfigurator& configurator, QThread* thread, - ReTerminator* terminator, - ReLogger* logger = NULL); - virtual ~RplTcpClient(); + RplTcpClient(ReConfigurator& configurator, QThread* thread, + ReTerminator* terminator, ReLogger* logger = NULL); + virtual ~RplTcpClient(); private: - // No copy constructor: no implementation! - RplTcpClient(const RplTcpClient& source); - // Prohibits assignment operator: no implementation! - RplTcpClient& operator =(const RplTcpClient& source); + // No copy constructor: no implementation! + RplTcpClient(const RplTcpClient& source); + // Prohibits assignment operator: no implementation! + RplTcpClient& operator =(const RplTcpClient& source); public: - ReTCPPeer* getPeer() const; + ReTCPPeer* getPeer() const; private: - void setRemoteAddress(const char* ip, int port); -public slots: - void handleError(QAbstractSocket::SocketError socketError); + void setRemoteAddress(const char* ip, int port);public slots: + void handleError(QAbstractSocket::SocketError socketError); private: - ReTCPPeer* m_peer; - ReLogger* m_logger; - ReConfigurator& m_configurator; + ReTCPPeer* m_peer; + ReLogger* m_logger; + ReConfigurator& m_configurator; }; -class RplClientThread : public QThread { +class RplClientThread: public QThread { public: - RplClientThread(ReConfigurator& configurator, - ReLogger* logger = NULL); - virtual ~RplClientThread(); + RplClientThread(ReConfigurator& configurator, ReLogger* logger = NULL); + virtual ~RplClientThread(); private: - // No copy constructor: no implementation! - RplClientThread(const RplClientThread& source); - // Prohibits the assignment operator. Not implemented! - RplClientThread& operator=(const RplClientThread& source); + // No copy constructor: no implementation! + RplClientThread(const RplClientThread& source); + // Prohibits the assignment operator. Not implemented! + RplClientThread& operator=(const RplClientThread& source); public: - /** - * @brief Does the main task of the thread. - * - * Will be called from QThread::run(). - * The implementations of this abstract method should be call getPeer() - * to send and receive messages. - */ - virtual void doIt() = 0; - ReTCPPeer* getPeer() const; - ReLogger* getLogger() const; + /** + * @brief Does the main task of the thread. + * + * Will be called from QThread::run(). + * The implementations of this abstract method should be call getPeer() + * to send and receive messages. + */ + virtual void doIt() = 0; + ReTCPPeer* getPeer() const; + ReLogger* getLogger() const; private: - virtual void run(); + virtual void run(); protected: - RplTcpClient* m_client; - ReLogger* m_logger; - ReConfigurator& m_configurator; + RplTcpClient* m_client; + ReLogger* m_logger; + ReConfigurator& m_configurator; private: - bool m_ownsLogger; + bool m_ownsLogger; }; -#endif // RPLTCPCLIENT_HPP +#endif // RETCPCLIENT_HPP diff --git a/net/ReTCPPeer.cpp b/net/ReTCPPeer.cpp index cd8dcf6..20855fb 100644 --- a/net/ReTCPPeer.cpp +++ b/net/ReTCPPeer.cpp @@ -1,22 +1,25 @@ /* - * Licence: + * ReTCPPeer.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #include "base/rebase.hpp" #include "math/remath.hpp" #include "net/renet.hpp" enum { - LOC_SEND_1 = LOC_FIRST_OF(LOC_TCPPEER), // 10801 - LOC_READ_BYTES_1, - LOC_READ_BYTES_2, - LOC_READ_BYTES_3, - LOC_READ_BYTES_4, - LOC_HANDLE_ERROR_1, - LOC_SEND_2, + LOC_SEND_1 = LOC_FIRST_OF(LOC_TCPPEER), // 10801 + LOC_READ_BYTES_1, + LOC_READ_BYTES_2, + LOC_READ_BYTES_3, + LOC_READ_BYTES_4, + LOC_HANDLE_ERROR_1, + LOC_SEND_2, }; static int s_dummy = 0; @@ -52,11 +55,9 @@ static int s_dummy = 0; * @param logger logger. If Null the global logger will be taken (not thread safe!) * @return an instance of ReTCPPeer */ -ReTCPPeer* ReTCPPeer::createPeer(ReConfigurator& configurator, - QThread* thread, - ReTerminator* terminator, - ReLogger* logger) { - return new ReTCPPeer(configurator, thread, terminator, logger); +ReTCPPeer* ReTCPPeer::createPeer(ReConfigurator& configurator, QThread* thread, + ReTerminator* terminator, ReLogger* logger){ + return new ReTCPPeer(configurator, thread, terminator, logger); } /** @@ -69,28 +70,28 @@ ReTCPPeer* ReTCPPeer::createPeer(ReConfigurator& configurator, * @param logger logger. If Null the global logger will be taken (not thread safe!) */ ReTCPPeer::ReTCPPeer(ReConfigurator& configurator, QThread* thread, - ReTerminator* terminator, - bool isServer, - ReLogger* logger) : - m_socket(NULL), - m_logger(logger == NULL ? ReLogger::globalLogger() : logger), - m_thread(thread), - m_random(), - m_timeout(isServer ? 0 : configurator.asInt("connection.timeout", 60)), - m_terminator(terminator), - m_configurator(configurator), - m_isServer(isServer), - m_dataLocker(QMutex::NonRecursive), - m_waitForData() { - // Simulate a true random with time, and addresses from stack and code segment: - m_random.setSeed(time(NULL) + ((int64_t) this << 8) + ((int64_t) &s_dummy << 16) - + ((int64_t) &createPeer << 24)); + ReTerminator* terminator, bool isServer, ReLogger* logger) : + m_socket(NULL), + m_logger(logger == NULL ? ReLogger::globalLogger() : logger), + m_thread(thread), + m_random(), + m_timeout( + isServer ? 0 : configurator.asInt("connection.timeout", 60)), + m_terminator(terminator), + m_configurator(configurator), + m_isServer(isServer), + m_dataLocker(QMutex::NonRecursive), + m_waitForData(){ + // Simulate a true random with time, and addresses from stack and code segment: + m_random.setSeed( + time(NULL) + ((int64_t) this << 8) + ((int64_t) & s_dummy << 16) + + ((int64_t) & createPeer << 24)); } /** * @brief Destructor. */ -ReTCPPeer::~ReTCPPeer() { +ReTCPPeer::~ReTCPPeer(){ } @@ -103,54 +104,53 @@ ReTCPPeer::~ReTCPPeer() { * @return true: success
* false: error occurred */ -bool ReTCPPeer::send(qint8 flags, const char* command, - const QByteArray& data) { - bool rc = false; - QByteArray header; - QByteArray data2 = ReStringUtil::toCString(data.constData(), 20); - m_logger->logv(LOG_INFO, LOC_SEND_1, "send: flags: %x %s %s (%d)", - flags, command, data2.constData(), data.length()); - header.reserve(16); - header.append((char) flags); - if(flags & FLAG_ENCRYPT) { - header.append((char) m_random.nextByte()); - header.append((char) m_random.nextByte()); - header.append((char) m_random.nextByte()); - header.append((char) m_random.nextByte()); - } - unsigned int length = data.length(); - header.append(char(length % 256)); - header.append(char((length >> 8) % 256)); - if(flags & FLAG_4_BYTE_SIZE) { - header.append(char((length >> 16) % 256)); - header.append(char((length >> 24) % 256)); - } - length = strlen(command); - header.append(command, length < 5 ? length : 5); - while(length++ < 5) { - header.append(' '); - } - int64_t written = m_socket->write(header.constData(), header.length()); - int64_t written2 = m_socket->write(data); - m_socket->flush(); - int count = 0; - if(written != header.length() || written2 != data.length()) { - int endTime = time(NULL) + m_timeout; - // wait until the data are sent or timeout or external termination: - while(m_socket->bytesToWrite() > 0) { - m_thread->msleep(1); - if(++count % 20 == 0) { - if(m_terminator == NULL || m_terminator->isStopped() - || time(NULL) > endTime) - break; - } - } - } - if(m_logger->isActive(LOG_DEBUG)) - m_logger->logv(LOG_DEBUG, LOC_SEND_1, "send %s: %s len=%d loops=%d %s", - m_address.constData(), command, data.length(), count, - ReStringUtil::hexDump((const void*) data.constData(), 16, 16).constData()); - return rc; +bool ReTCPPeer::send(qint8 flags, const char* command, const QByteArray& data){ + bool rc = false; + QByteArray header; + QByteArray data2 = ReStringUtil::toCString(data.constData(), 20); + m_logger->logv(LOG_INFO, LOC_SEND_1, "send: flags: %x %s %s (%d)", flags, + command, data2.constData(), data.length()); + header.reserve(16); + header.append((char) flags); + if (flags & FLAG_ENCRYPT){ + header.append((char) m_random.nextByte()); + header.append((char) m_random.nextByte()); + header.append((char) m_random.nextByte()); + header.append((char) m_random.nextByte()); + } + unsigned int length = data.length(); + header.append(char(length % 256)); + header.append(char((length >> 8) % 256)); + if (flags & FLAG_4_BYTE_SIZE){ + header.append(char((length >> 16) % 256)); + header.append(char((length >> 24) % 256)); + } + length = strlen(command); + header.append(command, length < 5 ? length : 5); + while (length++ < 5){ + header.append(' '); + } + int64_t written = m_socket->write(header.constData(), header.length()); + int64_t written2 = m_socket->write(data); + m_socket->flush(); + int count = 0; + if (written != header.length() || written2 != data.length()){ + int endTime = time(NULL) + m_timeout; + // wait until the data are sent or timeout or external termination: + while (m_socket->bytesToWrite() > 0){ + m_thread->msleep(1); + if (++count % 20 == 0){ + if (m_terminator == NULL || m_terminator->isStopped() + || time(NULL) > endTime) + break; + } + } + } + if (m_logger->isActive(LOG_DEBUG)) + m_logger->logv(LOG_DEBUG, LOC_SEND_1, "send %s: %s len=%d loops=%d %s", + m_address.constData(), command, data.length(), count, + ReStringUtil::hexDump((const void*) data.constData(), 16, 16).constData()); + return rc; } /** @@ -163,55 +163,54 @@ bool ReTCPPeer::send(qint8 flags, const char* command, * @return "": read not successful: timeout or termination or error
* otherwise: the read bytes */ -QByteArray ReTCPPeer::readBytes(int bytes, time_t maxTime, int& loops) { - QAbstractSocket* socket = getSocket(); - bool success = true; - int64_t available; - long msec = m_configurator.asInt(ReNetConfig::SLEEP_MILLISEC, 1); - int divider = 1000L / (msec == 0 ? 1 : msec); - if (divider < 1) - divider = 1; - QMutexLocker locker(&m_dataLocker); - m_dataLocker.lock(); +QByteArray ReTCPPeer::readBytes(int bytes, time_t maxTime, int& loops){ + QAbstractSocket* socket = getSocket(); + bool success = true; + int64_t available; + long msec = m_configurator.asInt(ReNetConfig::SLEEP_MILLISEC, 1); + int divider = 1000L / (msec == 0 ? 1 : msec); + if (divider < 1) + divider = 1; + QMutexLocker locker(&m_dataLocker); + m_dataLocker.lock(); - while(! m_waitForData.wait(&m_dataLocker, 1000L)){ - if(loops == 0 && ! m_isServer) - maxTime = time(NULL) + m_timeout; - if(++loops % divider == 0 && ! m_isServer) { - if(time(NULL) > maxTime) { - m_logger->logv(LOG_ERROR, LOC_READ_BYTES_1, - "receive: timeout (%d)", m_timeout); - success = false; - break; - } - } - if(m_terminator != NULL && m_terminator->isStopped()) { - m_logger->log(LOG_ERROR, LOC_READ_BYTES_2, "receive: stopped"); - success = false; - break; - } - } - available = socket->bytesAvailable(); - m_logger->logv(LOG_DEBUG, LOC_READ_BYTES_4, - "readBytes(): available: %ld/%ld", available, bytes); - QByteArray rc; - if(success) { - rc = socket->read(bytes); - if(rc.length() != bytes) { - m_logger->logv(LOG_ERROR, LOC_READ_BYTES_3, - "receive: too few bytes: %d of %d", - rc.length(), bytes); - } - } - return rc; + while (!m_waitForData.wait(&m_dataLocker, 1000L)){ + if (loops == 0 && !m_isServer) + maxTime = time(NULL) + m_timeout; + if (++loops % divider == 0 && !m_isServer){ + if (time(NULL) > maxTime){ + m_logger->logv(LOG_ERROR, LOC_READ_BYTES_1, "receive: timeout (%d)", + m_timeout); + success = false; + break; + } + } + if (m_terminator != NULL && m_terminator->isStopped()){ + m_logger->log(LOG_ERROR, LOC_READ_BYTES_2, "receive: stopped"); + success = false; + break; + } + } + available = socket->bytesAvailable(); + m_logger->logv(LOG_DEBUG, LOC_READ_BYTES_4, + "readBytes(): available: %ld/%ld", available, bytes); + QByteArray rc; + if (success){ + rc = socket->read(bytes); + if (rc.length() != bytes){ + m_logger->logv(LOG_ERROR, LOC_READ_BYTES_3, + "receive: too few bytes: %d of %d", rc.length(), bytes); + } + } + return rc; } -int getInt(const QByteArray& data, int offset, int size) { - int rc = ((int)(unsigned char) data.at(offset++)); - while(--size > 0) { - rc = rc * 256 + (unsigned char) data.at(offset++); - } - return rc; +int getInt(const QByteArray& data, int offset, int size){ + int rc = ((int) (unsigned char) data.at(offset++)); + while (--size > 0){ + rc = rc * 256 + (unsigned char) data.at(offset++); + } + return rc; } /** @@ -222,43 +221,43 @@ int getInt(const QByteArray& data, int offset, int size) { * @return true: success
* false: error occurred */ -bool ReTCPPeer::receive(QByteArray& command, QByteArray& data) { - bool rc = true; - command.clear(); - data.clear(); - QByteArray header; - header.reserve(16); - int minHeaderSize = 8; - int loops = 0; - time_t maxTime = 0; - uint8_t flags = 0; - header = readBytes(minHeaderSize, maxTime, loops); - if(header.length() > 0) { - flags = header.at(0); - int headerSize = minHeaderSize; - if((flags & FLAG_4_BYTE_SIZE) != 0) - headerSize += 2; - if((flags & FLAG_ENCRYPT) != 0) - headerSize += 4; - if(headerSize != minHeaderSize) { - QByteArray restHeader = readBytes(headerSize - minHeaderSize, - maxTime, loops); - if(restHeader.length() == 0) - header.clear(); - else - header.append(restHeader); - } - } - rc = header.length() > 0; - if(rc) { - int offset = (flags & FLAG_ENCRYPT) == 0 ? 6 : 8; - int size = (flags & FLAG_4_BYTE_SIZE) == 0 ? 4 : 2; - int dataLength = getInt(header, offset, size); - command = header.mid(offset - 5, 5); - data = readBytes(dataLength, maxTime, loops); - rc = data.length() == dataLength; - } - return rc; +bool ReTCPPeer::receive(QByteArray& command, QByteArray& data){ + bool rc = true; + command.clear(); + data.clear(); + QByteArray header; + header.reserve(16); + int minHeaderSize = 8; + int loops = 0; + time_t maxTime = 0; + uint8_t flags = 0; + header = readBytes(minHeaderSize, maxTime, loops); + if (header.length() > 0){ + flags = header.at(0); + int headerSize = minHeaderSize; + if ((flags & FLAG_4_BYTE_SIZE) != 0) + headerSize += 2; + if ((flags & FLAG_ENCRYPT) != 0) + headerSize += 4; + if (headerSize != minHeaderSize){ + QByteArray restHeader = readBytes(headerSize - minHeaderSize, maxTime, + loops); + if (restHeader.length() == 0) + header.clear(); + else + header.append(restHeader); + } + } + rc = header.length() > 0; + if (rc){ + int offset = (flags & FLAG_ENCRYPT) == 0 ? 6 : 8; + int size = (flags & FLAG_4_BYTE_SIZE) == 0 ? 4 : 2; + int dataLength = getInt(header, offset, size); + command = header.mid(offset - 5, 5); + data = readBytes(dataLength, maxTime, loops); + rc = data.length() == dataLength; + } + return rc; } @@ -273,15 +272,14 @@ bool ReTCPPeer::receive(QByteArray& command, QByteArray& data) { * @return true: success
* false: error occurred */ -bool ReTCPPeer::sendAndReceive(uint8_t flags, char command [4], - QByteArray* data, QByteArray& answer, - QByteArray& answerData) { - answer.clear(); - answerData.clear(); - bool rc = send(flags, command, data == NULL ? QByteArray("") : *data); - if(rc) - rc = receive(answer, answerData); - return rc; +bool ReTCPPeer::sendAndReceive(uint8_t flags, char command[4], QByteArray* data, + QByteArray& answer, QByteArray& answerData){ + answer.clear(); + answerData.clear(); + bool rc = send(flags, command, data == NULL ? QByteArray("") : *data); + if (rc) + rc = receive(answer, answerData); + return rc; } /** @@ -289,17 +287,17 @@ bool ReTCPPeer::sendAndReceive(uint8_t flags, char command [4], * * @param socket the socket to set */ -void ReTCPPeer::setSocket(QAbstractSocket* socket) { - m_socket = socket; - if (socket != NULL) - connect( m_socket, SIGNAL(readyRead()), SLOT(readTcpData()) ); +void ReTCPPeer::setSocket(QAbstractSocket* socket){ + m_socket = socket; + if (socket != NULL) + connect(m_socket, SIGNAL(readyRead()), SLOT(readTcpData())); } /** * @brief Reads the (ready) data from the socket. */ -void ReTCPPeer::readTcpData() { - m_waitForData.wakeOne(); +void ReTCPPeer::readTcpData(){ + m_waitForData.wakeOne(); } /** @@ -307,22 +305,22 @@ void ReTCPPeer::readTcpData() { * * @param socketError the error code */ -void ReTCPPeer::handleError(QTcpSocket::SocketError socketError) { - m_logger->logv(LOG_ERROR, LOC_HANDLE_ERROR_1, "Network error %d", - socketError); +void ReTCPPeer::handleError(QTcpSocket::SocketError socketError){ + m_logger->logv(LOG_ERROR, LOC_HANDLE_ERROR_1, "Network error %d", + socketError); } /** * @brief Returns a human readable peer address. * @return a string with the peer address: e.g. "192.16.2.3:44335" */ -QByteArray ReTCPPeer::getPeerAddress() { - QByteArray rc; - if(m_socket == NULL) - rc = ""; - else - rc = m_socket->peerAddress().toString().toUtf8(); - return rc; +QByteArray ReTCPPeer::getPeerAddress(){ + QByteArray rc; + if (m_socket == NULL) + rc = ""; + else + rc = m_socket->peerAddress().toString().toUtf8(); + return rc; } /** @@ -330,8 +328,8 @@ QByteArray ReTCPPeer::getPeerAddress() { * * @return the socket */ -QAbstractSocket* ReTCPPeer::getSocket() const { - return m_socket; +QAbstractSocket* ReTCPPeer::getSocket() const{ + return m_socket; } /** @@ -339,8 +337,8 @@ QAbstractSocket* ReTCPPeer::getSocket() const { * @return the port of the peer. */ int ReTCPPeer::getPort(){ - int port = m_configurator.asInt(ReNetConfig::PORT, 12345); - return port; + int port = m_configurator.asInt(ReNetConfig::PORT, 12345); + return port; } /** * @brief Returns the ip address. @@ -348,15 +346,14 @@ int ReTCPPeer::getPort(){ * otherwise: the address (e.g. 127.0.0.1) */ QByteArray ReTCPPeer::getIp(){ - QByteArray ip = m_configurator.asString(ReNetConfig::IP, ""); - return ip; + QByteArray ip = m_configurator.asString(ReNetConfig::IP, ""); + return ip; } /** * @brief Sets the address (ip:port). * @param ip the ip address * @param port the port */ -void ReTCPPeer::setAddress(const char* ip, int port) -{ - m_address = QByteArray(ip) + ":" + QByteArray::number(port); +void ReTCPPeer::setAddress(const char* ip, int port){ + m_address = QByteArray(ip) + ":" + QByteArray::number(port); } diff --git a/net/ReTCPPeer.hpp b/net/ReTCPPeer.hpp index 51f7dea..578d196 100644 --- a/net/ReTCPPeer.hpp +++ b/net/ReTCPPeer.hpp @@ -1,84 +1,79 @@ /* - * Licence: + * ReTCPPeer.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #ifndef RPLTCPPEER_HPP #define RPLTCPPEER_HPP -#ifndef RPLNET_HPP -#include "renet.hpp" -#endif - -class ReTCPPeer : public QObject { - Q_OBJECT +class ReTCPPeer: public QObject { + Q_OBJECT public: - enum { - ///> standard behaviour - FLAG_UNDEF, - ///> if set: the size field is 4 byte (max. 4 GByte) instead of 2 byte (64kByte) - FLAG_4_BYTE_SIZE = 1, - ///> if set the data are compressed by the gzip algorithm - FLAG_GZIP = 2, - ///> if set the data are encrypted. In front of the size field a 4 byte salt field exists. - ///> In this case all data behind the salt field are encrypted. - FLAG_ENCRYPT = 4, - ///> connection initialization of - } flag_t; + enum { + ///> standard behaviour + FLAG_UNDEF, + ///> if set: the size field is 4 byte (max. 4 GByte) instead of 2 byte (64kByte) + FLAG_4_BYTE_SIZE = 1, + ///> if set the data are compressed by the gzip algorithm + FLAG_GZIP = 2, + ///> if set the data are encrypted. In front of the size field a 4 byte salt field exists. + ///> In this case all data behind the salt field are encrypted. + FLAG_ENCRYPT = 4, + ///> connection initialization of + } flag_t; public: - static ReTCPPeer* createPeer(ReConfigurator& configurator, - QThread* thread, - ReTerminator* terminator, - ReLogger* logger = NULL); + static ReTCPPeer* createPeer(ReConfigurator& configurator, QThread* thread, + ReTerminator* terminator, ReLogger* logger = NULL); public: - ReTCPPeer(ReConfigurator& configurator, QThread* thread, - ReTerminator* terminator, - bool isServer, - ReLogger* logger = NULL); - virtual ~ReTCPPeer(); + ReTCPPeer(ReConfigurator& configurator, QThread* thread, + ReTerminator* terminator, bool isServer, ReLogger* logger = NULL); + virtual ~ReTCPPeer(); private: - // No copy constructor: no implementation! - ReTCPPeer(const ReTCPPeer& source); - // No assignment operator: no implementation! - ReTCPPeer& operator =(const ReTCPPeer& source); + // No copy constructor: no implementation! + ReTCPPeer(const ReTCPPeer& source); + // No assignment operator: no implementation! + ReTCPPeer& operator =(const ReTCPPeer& source); public: - virtual bool send(qint8 flags, const char* command, const QByteArray& data); - virtual bool receive(QByteArray& command, QByteArray& data); - virtual bool sendAndReceive(uint8_t flags, char command [4], - QByteArray* data, QByteArray& answer, QByteArray& answerData); - void setSocket(QAbstractSocket* socket); - QAbstractSocket* getSocket() const; - QByteArray getPeerAddress(); - void handleError(QTcpSocket::SocketError socketError); - int getPort(); - QByteArray getIp(); - void setAddress(const char* ip, int port); + virtual bool send(qint8 flags, const char* command, const QByteArray& data); + virtual bool receive(QByteArray& command, QByteArray& data); + virtual bool sendAndReceive(uint8_t flags, char command[4], QByteArray* data, + QByteArray& answer, QByteArray& answerData); + void setSocket(QAbstractSocket* socket); + QAbstractSocket* getSocket() const; + QByteArray getPeerAddress(); + void handleError(QTcpSocket::SocketError socketError); + int getPort(); + QByteArray getIp(); + void setAddress(const char* ip, int port); private: - QByteArray readBytes(int bytes, time_t maxTime, int& loops); + QByteArray readBytes(int bytes, time_t maxTime, int& loops); public slots: - void readTcpData(); + void readTcpData(); private: - QAbstractSocket* m_socket; - // : - QByteArray m_address; - ReLogger* m_logger; - QByteArray m_received; - int m_expected; - QThread* m_thread; - // Only used for salt generation: - ReRandom m_random; - ///> maximum allowed time (in seconds) for sending/receiving one info unit - int m_timeout; - ///> for controlled termination - ReTerminator* m_terminator; - ReConfigurator& m_configurator; - bool m_isServer; - QMutex m_dataLocker; - QWaitCondition m_waitForData; + QAbstractSocket* m_socket; + // : + QByteArray m_address; + ReLogger* m_logger; + QByteArray m_received; + int m_expected; + QThread* m_thread; + // Only used for salt generation: + ReRandom m_random; + ///> maximum allowed time (in seconds) for sending/receiving one info unit + int m_timeout; + ///> for controlled termination + ReTerminator* m_terminator; + ReConfigurator& m_configurator; + bool m_isServer; + QMutex m_dataLocker; + QWaitCondition m_waitForData; }; #endif // RPLTCPPEER_HPP diff --git a/net/ReTCPServer.cpp b/net/ReTCPServer.cpp index 83a1326..0b8e3d1 100644 --- a/net/ReTCPServer.cpp +++ b/net/ReTCPServer.cpp @@ -1,19 +1,20 @@ /* - * Licence: + * ReTCPServer.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #include "base/rebase.hpp" #include "math/remath.hpp" #include "net/renet.hpp" enum { - LOC_RUN_1 = LOC_FIRST_OF(LOC_TCPSERVER), // 10601 - LOC_TCP_TREAD_RUN_1, - LOC_TCP_TREAD_RUN_2, - LOC_TCP_INCOMING_CONNECTION_1, + LOC_RUN_1 = LOC_FIRST_OF(LOC_TCPSERVER), // 10601 + LOC_TCP_TREAD_RUN_1, LOC_TCP_TREAD_RUN_2, LOC_TCP_INCOMING_CONNECTION_1, }; /** @class ReTCPThread rpltcpserver.hpp "rplcore/rpltcpserver.hpp" @@ -31,18 +32,17 @@ enum { * @param threadId an unique id for the thread * @param handler does the work */ -ReTCPThread::ReTCPThread(ReConfigurator& configurator, - qintptr socketDescriptor, int threadId, - ReTaskHandler* handler) : - m_threadId(threadId), - m_taskHandler(handler), - m_socketDescriptor(socketDescriptor), - m_configurator(configurator){ +ReTCPThread::ReTCPThread(ReConfigurator& configurator, qintptr socketDescriptor, + int threadId, ReTaskHandler* handler) : + m_threadId(threadId), + m_taskHandler(handler), + m_socketDescriptor(socketDescriptor), + m_configurator(configurator){ } /** * @brief Destructor. */ -ReTCPThread::~ReTCPThread() { +ReTCPThread::~ReTCPThread(){ } @@ -51,25 +51,25 @@ ReTCPThread::~ReTCPThread() { * * Initializes the socket and loops for incoming commands. */ -void ReTCPThread::run() { - QTcpSocket socket; - if(!socket.setSocketDescriptor(getSocketDescriptor())) { - emit error(socket.error()); - } else { - ReTCPPeer peer(m_configurator, this, m_taskHandler->getTerminator(), - true, m_taskHandler->getLogger()); - peer.setSocket(&socket); - QByteArray addr = peer.getPeerAddress(); - m_taskHandler->getLogger()->logv(LOG_DEBUG, LOC_TCP_TREAD_RUN_1, - "ReTCPThread::run(): start Peer: %s", addr.constData()); - while(m_taskHandler->handle(&peer)) { - // do nothing - } - socket.disconnectFromHost(); - socket.waitForDisconnected(); - m_taskHandler->getLogger()->logv(LOG_DEBUG, LOC_TCP_TREAD_RUN_1, - "ReTCPThread::run(): end Peer: %s", addr.constData()); - } +void ReTCPThread::run(){ + QTcpSocket socket; + if (!socket.setSocketDescriptor(getSocketDescriptor())){ + emit error(socket.error()); + }else{ + ReTCPPeer peer(m_configurator, this, m_taskHandler->getTerminator(), true, + m_taskHandler->getLogger()); + peer.setSocket(&socket); + QByteArray addr = peer.getPeerAddress(); + m_taskHandler->getLogger()->logv(LOG_DEBUG, LOC_TCP_TREAD_RUN_1, + "ReTCPThread::run(): start Peer: %s", addr.constData()); + while (m_taskHandler->handle(&peer)){ + // do nothing + } + socket.disconnectFromHost(); + socket.waitForDisconnected(); + m_taskHandler->getLogger()->logv(LOG_DEBUG, LOC_TCP_TREAD_RUN_1, + "ReTCPThread::run(): end Peer: %s", addr.constData()); + } } /** @@ -77,24 +77,24 @@ void ReTCPThread::run() { * * @return the thread id */ -int ReTCPThread::getThreadId() const { - return m_threadId; +int ReTCPThread::getThreadId() const{ + return m_threadId; } /** * @brief Returns the task handler. * * @return the task handler */ -ReTaskHandler* ReTCPThread::getTaskHandler() const { - return m_taskHandler; +ReTaskHandler* ReTCPThread::getTaskHandler() const{ + return m_taskHandler; } /** * @brief Returns the tcp socket of the served connection. * * @return the socket */ -qintptr ReTCPThread::getSocketDescriptor() const { - return m_socketDescriptor; +qintptr ReTCPThread::getSocketDescriptor() const{ + return m_socketDescriptor; } /** @class ReTCPServer rpltcpserver.hpp "rplcore/rpltcpserver" @@ -112,15 +112,13 @@ qintptr ReTCPThread::getSocketDescriptor() const { * @param parent NULL or the parent which deletes the childen */ ReTCPServer::ReTCPServer(ReConfigurator& configurator, - ReTaskHandler* taskHandler, - ReVMThreadFactory& threadFactory, - ReLogger* logger, - QObject* parent) : - QTcpServer(parent), - m_taskHandler(taskHandler), - m_threadId(0), - m_threadFactory(threadFactory), - m_configurator(configurator){ + ReTaskHandler* taskHandler, ReThreadFactory& threadFactory, ReLogger* logger, + QObject* parent) : + QTcpServer(parent), + m_taskHandler(taskHandler), + m_threadId(0), + m_threadFactory(threadFactory), + m_configurator(configurator){ } /** @@ -128,13 +126,13 @@ ReTCPServer::ReTCPServer(ReConfigurator& configurator, * * @param socketDescriptor the tcp socket */ -void ReTCPServer::incomingConnection(qintptr socketDescriptor) { - ReTCPThread* thread = m_threadFactory.create(m_configurator, - socketDescriptor, ++m_threadId, m_taskHandler); - m_taskHandler->getLogger()->log(LOG_DEBUG, LOC_TCP_INCOMING_CONNECTION_1, - "Connection detected"); - QTcpServer::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - thread->start(); +void ReTCPServer::incomingConnection(qintptr socketDescriptor){ + ReTCPThread* thread = m_threadFactory.create(m_configurator, + socketDescriptor, ++m_threadId, m_taskHandler); + m_taskHandler->getLogger()->log(LOG_DEBUG, LOC_TCP_INCOMING_CONNECTION_1, + "Connection detected"); + QTcpServer::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + thread->start(); } /** @class ReTCPThread rpltcpserver.hpp "rplcore/rpltcpserver.hpp" @@ -157,17 +155,17 @@ void ReTCPServer::incomingConnection(qintptr socketDescriptor) { * @param logger the logger */ ReTaskHandler::ReTaskHandler(ReConfigurator& configurator, - ReTerminator* terminator, ReLogger* logger) : - m_answerFlags(0), - m_logger(logger), - m_terminator(terminator), - m_configurator(configurator){ + ReTerminator* terminator, ReLogger* logger) : + m_answerFlags(0), + m_logger(logger), + m_terminator(terminator), + m_configurator(configurator){ } /** * @brief Destructor. */ -ReTaskHandler::~ReTaskHandler() { +ReTaskHandler::~ReTaskHandler(){ } /** @@ -177,19 +175,19 @@ ReTaskHandler::~ReTaskHandler() { * @return false: the application should stop
* true: processing remains */ -bool ReTaskHandler::handle(ReTCPPeer* peer) { - QByteArray command; - QByteArray data; - QByteArray answer; - QByteArray answerData; - bool rc = true; - if(peer->receive(command, data)) { - rc = process(command, data, answer, answerData); - if(answer.length() > 0) { - peer->send(m_answerFlags, answer, answerData); - } - } - return rc; +bool ReTaskHandler::handle(ReTCPPeer* peer){ + QByteArray command; + QByteArray data; + QByteArray answer; + QByteArray answerData; + bool rc = true; + if (peer->receive(command, data)){ + rc = process(command, data, answer, answerData); + if (answer.length() > 0){ + peer->send(m_answerFlags, answer, answerData); + } + } + return rc; } /** @@ -197,8 +195,8 @@ bool ReTaskHandler::handle(ReTCPPeer* peer) { * * @param id the thread id */ -void ReTaskHandler::setThreadId(int id) { - m_threadId = id; +void ReTaskHandler::setThreadId(int id){ + m_threadId = id; } /** @@ -206,8 +204,8 @@ void ReTaskHandler::setThreadId(int id) { * * @return the thread id */ -int ReTaskHandler::getThreadId() const { - return m_threadId; +int ReTaskHandler::getThreadId() const{ + return m_threadId; } /** @@ -215,8 +213,8 @@ int ReTaskHandler::getThreadId() const { * * @return the logger */ -ReLogger* ReTaskHandler::getLogger() const { - return m_logger; +ReLogger* ReTaskHandler::getLogger() const{ + return m_logger; } /** @@ -224,7 +222,7 @@ ReLogger* ReTaskHandler::getLogger() const { * * @return the termination controller */ -ReTerminator* ReTaskHandler::getTerminator() const { - return m_terminator; +ReTerminator* ReTaskHandler::getTerminator() const{ + return m_terminator; } diff --git a/net/ReTCPServer.hpp b/net/ReTCPServer.hpp index bcbe5d0..06c2fb8 100644 --- a/net/ReTCPServer.hpp +++ b/net/ReTCPServer.hpp @@ -1,9 +1,12 @@ /* - * Licence: + * ReTCPServer.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #ifndef RPLTCPSERVER_HPP #define RPLTCPSERVER_HPP @@ -16,102 +19,97 @@ class ReTCPPeer; class ReTaskHandler { public: - ReTaskHandler(ReConfigurator& configurator, - ReTerminator* terminator, - ReLogger* logger); - virtual ~ReTaskHandler(); + ReTaskHandler(ReConfigurator& configurator, ReTerminator* terminator, + ReLogger* logger); + virtual ~ReTaskHandler(); public: - virtual bool handle(ReTCPPeer* peer); - /** - * @brief Processes one data unit from the socket. - * - * @param command defines the meaning of the information unit - * @param data "" or the data of the information unit - * @param answer OUT: "" or the answer to send back - * @param answerData OUT: "" or the answer data to send back - * @return true: the receiving loop should be continued
- * false: the process should be stopped - */ - virtual bool process(const QByteArray& command, const QByteArray& data, - QByteArray& answer, QByteArray& answerData) = 0; - void setThreadId(int id); - int getThreadId() const; - ReLogger* getLogger() const; - ReTerminator* getTerminator() const; + virtual bool handle(ReTCPPeer* peer); + /** + * @brief Processes one data unit from the socket. + * + * @param command defines the meaning of the information unit + * @param data "" or the data of the information unit + * @param answer OUT: "" or the answer to send back + * @param answerData OUT: "" or the answer data to send back + * @return true: the receiving loop should be continued
+ * false: the process should be stopped + */ + virtual bool process(const QByteArray& command, const QByteArray& data, + QByteArray& answer, QByteArray& answerData) = 0; + void setThreadId(int id); + int getThreadId() const; + ReLogger* getLogger() const; + ReTerminator* getTerminator() const; protected: - uint8_t m_answerFlags; + uint8_t m_answerFlags; private: - int m_threadId; - ReLogger* m_logger; - ReTerminator* m_terminator; - ReConfigurator& m_configurator; + int m_threadId; + ReLogger* m_logger; + ReTerminator* m_terminator; + ReConfigurator& m_configurator; }; -class ReTCPThread : public QThread { - Q_OBJECT +class ReTCPThread: public QThread { + Q_OBJECT public: - ReTCPThread(ReConfigurator& m_configurator, - qintptr socketDescriptor, int threadId, - ReTaskHandler* handler); - virtual ~ReTCPThread(); + ReTCPThread(ReConfigurator& m_configurator, qintptr socketDescriptor, + int threadId, ReTaskHandler* handler); + virtual ~ReTCPThread(); private: - // No copy constructor: no implementation! - ReTCPThread(const ReTCPThread& source); - // No assignment operator: no implementation! - ReTCPThread& operator=(const ReTCPThread& source); + // No copy constructor: no implementation! + ReTCPThread(const ReTCPThread& source); + // No assignment operator: no implementation! + ReTCPThread& operator=(const ReTCPThread& source); public: - void run(); - int getThreadId() const; - ReTaskHandler* getTaskHandler() const; - qintptr getSocketDescriptor() const; + void run(); + int getThreadId() const; + ReTaskHandler* getTaskHandler() const; + qintptr getSocketDescriptor() const; -signals: - void error(QTcpSocket::SocketError socketError); + signals: + void error(QTcpSocket::SocketError socketError); private: - // a unique id for the thread - int m_threadId; - // this handler interprets the info from the TCP connection - ReTaskHandler* m_taskHandler; - // the assigned socket - qintptr m_socketDescriptor; - ReConfigurator& m_configurator; + // a unique id for the thread + int m_threadId; + // this handler interprets the info from the TCP connection + ReTaskHandler* m_taskHandler; + // the assigned socket + qintptr m_socketDescriptor; + ReConfigurator& m_configurator; }; class ReThreadFactory { public: - virtual ReTCPThread* create(ReConfigurator& configurator, - qintptr socketDescriptor, - int threadId, - ReTaskHandler* handler) = 0; + virtual ReTCPThread* create(ReConfigurator& configurator, + qintptr socketDescriptor, int threadId, ReTaskHandler* handler) = 0; }; class ReTCPPeer; -class ReTCPServer : public QTcpServer, public ReTerminator { - Q_OBJECT +class ReTCPServer: public QTcpServer, public ReTerminator { + Q_OBJECT public: - explicit ReTCPServer(ReConfigurator& configurator, - ReTaskHandler* taskHandler, - ReThreadFactory& threadFactory, - ReLogger* logger = NULL, QObject* parent = 0); + explicit ReTCPServer(ReConfigurator& configurator, + ReTaskHandler* taskHandler, ReThreadFactory& threadFactory, + ReLogger* logger = NULL, QObject* parent = 0); private: - // No copy constructor: no implementation! - ReTCPServer(const ReTCPServer& source); - // No assignment operator: no implementation! - ReTCPServer& operator=(const ReTCPServer& source); + // No copy constructor: no implementation! + ReTCPServer(const ReTCPServer& source); + // No assignment operator: no implementation! + ReTCPServer& operator=(const ReTCPServer& source); public: - ReTCPPeer* getPeer() const; - bool handleTask(); + ReTCPPeer* getPeer() const; + bool handleTask(); protected slots: - void incomingConnection(qintptr socketDescriptor); + void incomingConnection(qintptr socketDescriptor); private: - ReTaskHandler* m_taskHandler; - int m_threadId; - ReTCPPeer* m_peer; - ReThreadFactory& m_threadFactory; - ReConfigurator& m_configurator; + ReTaskHandler* m_taskHandler; + int m_threadId; + ReTCPPeer* m_peer; + ReThreadFactory& m_threadFactory; + ReConfigurator& m_configurator; }; #endif // RPLTCPSERVER_HPP diff --git a/net/renet.hpp b/net/renet.hpp index f151faa..70fcdbd 100644 --- a/net/renet.hpp +++ b/net/renet.hpp @@ -1,9 +1,12 @@ /* - * Licence: + * renet.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib */ #ifndef RPLNET_HPP #define RPLNET_HPP diff --git a/remodules.hpp b/remodules.hpp index 4cd4dc3..ea53cad 100644 --- a/remodules.hpp +++ b/remodules.hpp @@ -1,29 +1,34 @@ +/* + * remodules.hpp + * + * License: Public Domain + * You can use and modify this file without any restriction. + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #ifndef RPLMODULES_HPP #define RPLMODULES_HPP enum { - LOC_LOGGER = 101, - LOC_CONFIG, - LOC_CONTAINER, - LOC_EXCEPTION, - LOC_TEST, // 105 - LOC_TCPSERVER, - LOC_TCPCLIENT, - LOC_TCPPEER, - LOC_TERMINATOR, - LOC_ASTREE, // 110 - LOC_ASCLASSES, - LOC_LEXER, - LOC_SOURCE, - LOC_VM, - LOC_MFPARSER, // 115 + LOC_LOGGER = 101, LOC_CONFIG, LOC_CONTAINER, LOC_EXCEPTION, LOC_TEST, // 105 + LOC_TCPSERVER, + LOC_TCPCLIENT, + LOC_TCPPEER, + LOC_TERMINATOR, + LOC_ASTREE, // 110 + LOC_ASCLASSES, + LOC_LEXER, + LOC_SOURCE, + LOC_VM, + LOC_MFPARSER, // 115 }; #define LOC_FIRST_OF(moduleNo) (moduleNo*100+1) -class RplModules{ +class RplModules { public: - static int fileToNumber(const char* file); - static const char* numberToFile(int location); + static int fileToNumber(const char* file); + static const char* numberToFile(int location); }; - #endif // RPLMODULES_HPP diff --git a/static/getsrc.pl b/static/getsrc.pl new file mode 100644 index 0000000..7618a1f --- /dev/null +++ b/static/getsrc.pl @@ -0,0 +1,29 @@ +#! /usr/bin/perl + +use strict; + +my @rc; +push @rc, &oneDir("../rplcore/*.hpp"); +push @rc, &oneDir("../rplmath/*.hpp"); +push @rc, &oneDir("../rplnet/*.hpp"); +push @rc, "\n"; +push @rc, &oneDir("../rplcore/*.cpp"); +push @rc, &oneDir("../rplmath/*.cpp"); +push @rc, &oneDir("../rplnet/*.cpp"); + +print @rc; +exit 0; + +sub oneDir{ + my $pattern = shift; + my @rc; + open (my $INP, "ls -1 $pattern|") || die "ls -1 $pattern: $!"; + while(<$INP>) { + if (/(\S+)/){ + push(@rc, " $1 \\\n"); + } + } + return @rc; +} + + diff --git a/static/rplstaticlib.cpp b/static/rplstaticlib.cpp index dfb4013..0dc5255 100644 --- a/static/rplstaticlib.cpp +++ b/static/rplstaticlib.cpp @@ -1,10 +1,13 @@ /* - * Licence: + * rplstaticlib.cpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #include "../static/rplstaticlib.hpp" diff --git a/static/rplstaticlib.hpp b/static/rplstaticlib.hpp index 80a926b..ce4f2e3 100644 --- a/static/rplstaticlib.hpp +++ b/static/rplstaticlib.hpp @@ -1,10 +1,13 @@ /* - * Licence: + * rplstaticlib.hpp + * + * License: Public Domain * You can use and modify this file without any restriction. - * There is no warranty. - * You also can use the licence from http://www.wtfpl.net/. - * The original sources can be found on https://github.com/republib. -*/ + * Do what you want. + * No warranties and disclaimer of any damages. + * You also can use this license: http://www.wtfpl.net + * The latest sources: https://github.com/republib + */ #ifndef RPLSTATICLIB_HPP -- 2.39.5