* @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);
}
/**
* @param size of the new block (inclusive the trailing '\0')
* @return a new block with the <code>size</code> 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 <char*>(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<char*>(rc);
}
/**
* If < 0 <code>strlen(source)</code> 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;
}
/**
* @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;
}
/**
*
* @return a byte block (without a trailing '\0')
*/
-uint8_t* ReByteStorage::allocateBytes(int size){
- uint8_t* rc =
- size <= m_rest ?
- m_freePosition : reinterpret_cast <uint8_t*>(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<uint8_t*>(allocBuffer(size));
+ m_freePosition += size;
+ m_rest -= size;
+ return rc;
}
/**
*
* @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;
}
/**
* @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;
}
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
* not the content
*/
ReKeyCharPtr::ReKeyCharPtr(const char* ptr) :
- m_ptr(ptr){
+ m_ptr(ptr) {
}
/** @class ReCharPtrMap ReCharPtrMap.hpp "base/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 <code>ReKeyCharPtr</code>.
* @return true: op1 < op2<br>
* false: op1 >= op2
*/
-inline bool operator <(ReKeyCharPtr const& op1, ReKeyCharPtr const& op2){
- bool rc = strcmp(op1.m_ptr, op2.m_ptr) < 0;
- return rc;
+inline bool operator <(ReKeyCharPtr const& op1, ReKeyCharPtr const& op2) {
+ bool rc = strcmp(op1.m_ptr, op2.m_ptr) < 0;
+ return rc;
}
template<class ValueType>
-class ReCharPtrMap: public QMap <ReKeyCharPtr, ValueType> {
+class ReCharPtrMap: public QMap<ReKeyCharPtr, ValueType> {
};
#endif // RECHARPTRMAP_HPP
*/
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,
};
/**
* @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);
}
/**
*
* 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);
}
/**
* @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;
}
/**
* @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;
}
/**
* @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;
}
/**
* @return true: OK<br>
* 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;
}
/**
* @return true: OK<br>
* 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;
}
#ifndef RECONFIG_HPP
#define RECONFIG_HPP
-class ReConfig: public ReConfigurator, public QHash <QByteArray, QByteArray> {
+class ReConfig: public ReConfigurator, public QHash<QByteArray, QByteArray> {
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 <QByteArray>& getLines() const;
+ bool read(const char* file);
+ bool write(const char* file);
+ void clear();
+ const QList<QByteArray>& 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 <QByteArray> 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<QByteArray> m_lineList;
+ bool m_readOnly;
+ ReLogger* m_logger;
+ // true: the logger must be destroyed in the destructor
+ bool m_ownLogger;
};
#endif // RECONFIG_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
*/
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";
* @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() {
}
/**
*
* @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);
}
/**
*
* @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.
* @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);
}
*
* @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;
}
/**
*
* @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;
+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;
+ 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;
}
/**
*
* @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, ReLogger::globalLogger(),
- "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, ReLogger::globalLogger(),
+ "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());
}
/**
*
* @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;
}
/**
*
* @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<blank>", 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<blank>", 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<blank>", 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<blank>", m_readPosition, 16);
+ m_readPosition = (uint8_t*) strchr((const char*) m_readPosition, ' ') + 1;
+ if (isNegativ)
+ value = -value;
+ return (int64_t) value;
}
/**
*
* @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;
}
/**
* 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;
}
/**
* @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;
- }
- }
- }
+ 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;
}
#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
#include "base/rebase.hpp"
enum {
- LOC_NOT_IMPLEMENTED_1 = LOC_FIRST_OF(LOC_EXCEPTION),
+ LOC_NOT_IMPLEMENTED_1 = LOC_FIRST_OF(LOC_EXCEPTION),
};
/** @class ReException ReException.hpp "base/ReException.hpp"
*
* For derived classes only!
*/
ReException::ReException() :
- m_message(""){
+ m_message("") {
}
/**
* @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;
}
/**
* @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);
+ 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"
*/
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"
* @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);
}
/**
* @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());
+ ReException("not implemented: ", message) {
+ ReLogger::globalLogger()->log(LOG_ERROR, LOC_NOT_IMPLEMENTED_1,
+ getMessage());
}
/**
* @param message the description of the exception
*/
ReQException::ReQException(const QString message) :
- m_message(message){
+ m_message(message) {
}
/**
* Destructor.
*/
-ReQException::~ReQException(){
+ReQException::~ReQException() {
}
/**
*
* @return the description of the exception
*/
-QString ReQException::message() const{
- return m_message;
+QString ReQException::message() const {
+ return m_message;
}
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 {
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 {
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);
+ ReNotImplementedException(const char* message);
};
class ReQException {
public:
- ReQException(const QString message);
- ~ReQException();
+ ReQException(const QString message);
+ ~ReQException();
public:
- QString message() const;
+ QString message() const;
protected:
- QString m_message;
+ QString m_message;
};
#endif // REEXCEPTION_HPP
#include "base/rebase.hpp"
#if defined __linux__ || defined WIN32
-void* memichr(void* heap, int cc, size_t length){
- const char* heap2 = reinterpret_cast<const char*>(heap);
- int cc2 = tolower(cc);
- void* rc = NULL;
- while(length > 0){
- if (cc2 == tolower(*heap2++)){
- rc = (void*)(heap2 - 1);
- break;
- }
- }
- return rc;
+void* memichr(void* heap, int cc, size_t length) {
+ const char* heap2 = reinterpret_cast<const char*>(heap);
+ int cc2 = tolower(cc);
+ void* rc = NULL;
+ while(length > 0) {
+ if (cc2 == tolower(*heap2++)) {
+ rc = (void*)(heap2 - 1);
+ break;
+ }
+ }
+ return rc;
}
-int memicmp(const void* str1, const void* str2, size_t length){
- const char* str12 = reinterpret_cast<const char*>(str1);
- const char* str22 = reinterpret_cast<const char*>(str2);
- int rc = 0;
- for (size_t ix = 0; ix < length; ix++){
- int diff = tolower(*str12++) - tolower(*str22++);
- if (diff != 0){
- rc = diff;
- break;
- }
- }
- return rc;
+int memicmp(const void* str1, const void* str2, size_t length) {
+ const char* str12 = reinterpret_cast<const char*>(str1);
+ const char* str22 = reinterpret_cast<const char*>(str2);
+ int rc = 0;
+ for (size_t ix = 0; ix < length; ix++) {
+ int diff = tolower(*str12++) - tolower(*str22++);
+ if (diff != 0) {
+ rc = diff;
+ break;
+ }
+ }
+ return rc;
}
#endif /* __linux__ */
* Constructor.
*/
ReLines::ReLines() :
- QStringList(), m_empty(){
+ QStringList(),
+ m_empty() {
}
/**
* Destructor.
*/
-ReLines::~ReLines(){
+ReLines::~ReLines() {
}
/**
* @param text the text to insert. May contain line separators ('\n' or "\r\n").
* In this case the number of lines grows
*/
-void ReLines::insertText(int line, int col, const QString& text){
- if (line >= 0){
- if (line == length()){
- int beginOfLine = 0;
- int endOfLine = text.indexOf('\n');
- while (endOfLine >= 0){
- int nextBOL = endOfLine + 1;
- if (endOfLine > 0 && text.at(endOfLine - 1) == '\r')
- endOfLine--;
- append(text.mid(beginOfLine, endOfLine - beginOfLine));
- beginOfLine = nextBOL;
- endOfLine = text.indexOf('\n', beginOfLine);
- }
- if (beginOfLine < text.length())
- append(text.mid(beginOfLine));
- }else if (line < length()){
- QString oldLine = at(line);
- int length = oldLine.length();
- if (col < 0)
- col = 0;
- else if (col >= length)
- col = length - 1;
- QString tail;
- if (col < length - 1)
- tail = oldLine.mid(col);
- int endOfLine = text.indexOf('\n');
- if (endOfLine < 0){
- replace(line, oldLine.mid(0, col) + text + tail);
- }else{
- int beginOfLine = endOfLine + 1;
- if (endOfLine > 0 && text[endOfLine - 1] == '\r')
- endOfLine--;
- replace(line++, oldLine.mid(0, col) + text.mid(0, endOfLine));
- do{
- if ((endOfLine = text.indexOf('\n', beginOfLine)) < 0)
- break;
- int nextBOL = endOfLine + 1;
- if (endOfLine > 0 && text.at(endOfLine - 1) == '\r')
- endOfLine--;
- insert(line++, text.mid(beginOfLine, endOfLine - beginOfLine));
- beginOfLine = nextBOL;
- }while (true);
- if (tail.length() == 0){
- if (beginOfLine < text.length())
- insert(line, text.mid(beginOfLine));
- }else{
- if (beginOfLine >= text.length())
- insert(line, tail);
- else
- insert(line, text.mid(beginOfLine) + tail);
- }
- }
- }
- }
+void ReLines::insertText(int line, int col, const QString& text) {
+ if (line >= 0) {
+ if (line == length()) {
+ int beginOfLine = 0;
+ int endOfLine = text.indexOf('\n');
+ while (endOfLine >= 0) {
+ int nextBOL = endOfLine + 1;
+ if (endOfLine > 0 && text.at(endOfLine - 1) == '\r')
+ endOfLine--;
+ append(text.mid(beginOfLine, endOfLine - beginOfLine));
+ beginOfLine = nextBOL;
+ endOfLine = text.indexOf('\n', beginOfLine);
+ }
+ if (beginOfLine < text.length())
+ append(text.mid(beginOfLine));
+ } else if (line < length()) {
+ QString oldLine = at(line);
+ int length = oldLine.length();
+ if (col < 0)
+ col = 0;
+ else if (col >= length)
+ col = length - 1;
+ QString tail;
+ if (col < length - 1)
+ tail = oldLine.mid(col);
+ int endOfLine = text.indexOf('\n');
+ if (endOfLine < 0) {
+ replace(line, oldLine.mid(0, col) + text + tail);
+ } else {
+ int beginOfLine = endOfLine + 1;
+ if (endOfLine > 0 && text[endOfLine - 1] == '\r')
+ endOfLine--;
+ replace(line++, oldLine.mid(0, col) + text.mid(0, endOfLine));
+ do {
+ if ((endOfLine = text.indexOf('\n', beginOfLine)) < 0)
+ break;
+ int nextBOL = endOfLine + 1;
+ if (endOfLine > 0 && text.at(endOfLine - 1) == '\r')
+ endOfLine--;
+ insert(line++,
+ text.mid(beginOfLine, endOfLine - beginOfLine));
+ beginOfLine = nextBOL;
+ } while (true);
+ if (tail.length() == 0) {
+ if (beginOfLine < text.length())
+ insert(line, text.mid(beginOfLine));
+ } else {
+ if (beginOfLine >= text.length())
+ insert(line, tail);
+ else
+ insert(line, text.mid(beginOfLine) + tail);
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Joins a line and the following line into one line.
+ *
+ * @param first the line number of the first line
+ * @param <code>true</code>: the join has been done<br>
+ * <code>false</code>: wrong parameter (first)
+ */
+bool ReLines::joinLines(int first) {
+ bool rc = false;
+ if (first >= 0 && first < length() - 1) {
+ replace(first, at(first) + at(first + 1));
+ removeAt(first + 1);
+ rc = true;
+ }
+ return rc;
}
/**
* Removes a part of a line.
*
* @param line the line number (0..N-1) of the first position to delete
- * @param col the column number (0..M-1) of the first position to delete
+ * @param col -1: join the current line with the previous line.
+ * <line_length>: join the current line with the following
+ * the column number (0..M-1) of the first position to delete
* @param count the number of character to delete
+ * @return <code>true</code>: a join of 2 lines has been done
*/
-void ReLines::remove(int line, int pos, int count){
- if (pos >= 0 && line >= 0 && line < length()){
- const QString& current = at(line);
- int length = current.length();
- if (pos < length - 1){
- if (pos + count > length)
- count = length - pos;
- if (pos == 0)
- replace(line, current.mid(count));
- else if (pos + count >= length)
- replace(line, current.mid(0, pos));
- else
- replace(line, current.mid(0, pos) + current.mid(pos + count));
- }
- }
+bool ReLines::remove(int line, int pos, int count) {
+ bool rc = false;
+ if (line >= 0 && line < lineCount()){
+ const QString& current = at(line);
+ if (pos == -1) {
+ rc = joinLines(line - 1);
+ } else if (pos == current.length()) {
+ rc = joinLines(line);
+ } else if (pos >= 0) {
+ int length = current.length();
+ if (pos < length - 1) {
+ if (pos + count > length)
+ count = length - pos;
+ if (pos == 0)
+ replace(line, current.mid(count));
+ else if (pos + count >= length)
+ replace(line, current.mid(0, pos));
+ else
+ replace(line, current.mid(0, pos) + current.mid(pos + count));
+ }
+ }
+ }
+ return rc;
}
/**
* @param count the number of lines to delete
*/
-void ReLines::removeLines(int start, int count){
- if (start >= 0 && start < length()){
- if (start + count > length())
- count = length() - start;
- for (int ix = start + count - 1; ix >= 0; ix--)
- removeAt(ix);
- }
+void ReLines::removeLines(int start, int count) {
+ if (start >= 0 && start < length()) {
+ if (start + count > length())
+ count = length() - start;
+ for (int ix = start + count - 1; ix >= 0; ix--)
+ removeAt(ix);
+ }
}
/**
* @param filename name of the file
*/
ReFile::ReFile(const QString& filename, bool readOnly, ReLogger* logger) :
- ReLineSource(),
- ReLines(),
- m_endOfLine(),
- m_filename(filename),
- m_file(filename),
- m_block(NULL),
- // in 32-bit address space we allocate only 10 MByte, in 64-bit environments 100 GByte
- m_blocksize(
- sizeof(void*) <= 4 ?
- 10 * 1024 * 1024ll : 0x100ll * 0x10000 * 0x10000),
- m_blockOffset(0),
- m_filesize(0),
- m_startOfLine(NULL),
- m_lineLength(0),
- m_lineOffset(0),
- m_currentLineNo(0),
- m_maxLineLength(0x10000),
- m_content(),
- m_readOnly(readOnly),
- m_logger(logger){
+ ReLineSource(),
+ ReLines(),
+ m_endOfLine(),
+ m_filename(filename),
+ m_file(filename),
+ m_block(NULL),
+ // in 32-bit address space we allocate only 10 MByte, in 64-bit environments 100 GByte
+ m_blocksize(
+ sizeof(void*) <= 4 ?
+ 10 * 1024 * 1024ll : 0x100ll * 0x10000 * 0x10000),
+ m_blockOffset(0),
+ m_filesize(0),
+ m_startOfLine(NULL),
+ m_lineLength(0),
+ m_lineOffset(0),
+ m_currentLineNo(0),
+ m_maxLineLength(0x10000),
+ m_content(),
+ m_readOnly(readOnly),
+ m_logger(logger) {
#if defined __linux__
- setEndOfLine("\n");
+ setEndOfLine("\n");
#elif defined __WIN32__
- setEndOfLine("\r\n");
+ setEndOfLine("\r\n");
#endif
- if (readOnly){
- m_file.open(QIODevice::ReadOnly);
- m_filesize = m_file.size();
- }else{
- read();
- }
+ if (readOnly) {
+ m_file.open(QIODevice::ReadOnly);
+ m_filesize = m_file.size();
+ } else {
+ read();
+ }
}
/**
* Destructor.
*/
-ReFile::~ReFile(){
- close();
+ReFile::~ReFile() {
+ close();
}
/**
*
* @return the blocksize
*/
-int64_t ReFile::blocksize() const{
- return m_blocksize;
+int64_t ReFile::blocksize() const {
+ return m_blocksize;
}
/**
* Frees the resources.
*/
-void ReFile::close(){
- clear();
- m_file.close();
+void ReFile::close() {
+ clear();
+ m_file.close();
}
/**
*
* @return the filename (with path)
*/
-QString ReFile::filename() const
-{
- return m_filename;
+QString ReFile::filename() const {
+ return m_filename;
}
/**
* Finds the next line with the string.
* false: a line has not been found
*/
bool ReFile::findLine(const char* toFind, bool ignoreCase, int& lineNo,
- QString* line){
- bool rc = false;
- int length;
- int sourceLength = strlen(toFind);
- char* start;
+ QString* line) {
+ bool rc = false;
+ int length;
+ int sourceLength = strlen(toFind);
+ char* start;
- char first = toFind[0];
- while (!rc && (start = nextLine(length)) != NULL){
- const char* ptr = start;
- int restLength = length - sourceLength + 1;
- while (restLength > 0
- && (ptr = reinterpret_cast <const char*>(
- ignoreCase ?
- memchr(start, first, restLength) :
- memichr(start, first, restLength))) != NULL){
- if ((ignoreCase ?
- _memicmp(ptr, toFind, sourceLength) :
- memcmp(ptr, toFind, sourceLength)) == 0){
- rc = true;
- lineNo = m_currentLineNo;
- QByteArray buffer(m_startOfLine, m_lineLength);
- if (line == NULL)
- *line = QString::fromUtf8(buffer);
- break;
- }
- restLength = length - (ptr - start) - sourceLength + 1;
- }
- }
- return rc;
+ char first = toFind[0];
+ while (!rc && (start = nextLine(length)) != NULL) {
+ const char* ptr = start;
+ int restLength = length - sourceLength + 1;
+ while (restLength > 0
+ && (ptr = reinterpret_cast<const char*>(
+ ignoreCase ?
+ memchr(start, first, restLength) :
+ memichr(start, first, restLength))) != NULL) {
+ if ((
+ ignoreCase ?
+ _memicmp(ptr, toFind, sourceLength) :
+ memcmp(ptr, toFind, sourceLength)) == 0) {
+ rc = true;
+ lineNo = m_currentLineNo;
+ QByteArray buffer(m_startOfLine, m_lineLength);
+ if (line == NULL)
+ *line = QString::fromUtf8(buffer);
+ break;
+ }
+ restLength = length - (ptr - start) - sourceLength + 1;
+ }
+ }
+ return rc;
}
/**
* false: a line has not been found
*/
bool ReFile::findLine(const QString& includePattern, bool includeIsRegExpr,
- bool includeIgnoreCase, const QString& excludePattern, bool excludeIsRegExpr,
- bool excludeIgnoreCase, int& lineNo, QString* line){
- bool rc = false;
- if (line != NULL)
- *line = "";
- lineNo = 0;
- if (!includePattern.isEmpty()){
+ bool includeIgnoreCase, const QString& excludePattern,
+ bool excludeIsRegExpr, bool excludeIgnoreCase, int& lineNo, QString* line) {
+ bool rc = false;
+ if (line != NULL)
+ *line = "";
+ lineNo = 0;
+ if (!includePattern.isEmpty()) {
- }
- return rc;
+ }
+ return rc;
}
-int ReFile::hasMoreLines(int index){
- bool rc = false;
+int ReFile::hasMoreLines(int index) {
+ bool rc = false;
#if 0
- if (m_countLines >= 0){
- rc = index < m_countLines - 1;
- } else{
- seek(m_lastLineNo);
- while (index > m_lastLineNo + 1){
- if (! nextLine()){
- break;
- }
- }
- rc = index < m_lastLineNo;
- }
+ if (m_countLines >= 0) {
+ rc = index < m_countLines - 1;
+ } else {
+ seek(m_lastLineNo);
+ while (index > m_lastLineNo + 1) {
+ if (! nextLine()) {
+ break;
+ }
+ }
+ rc = index < m_lastLineNo;
+ }
#endif
- return rc;
+ return rc;
}
/**
* @return NULL: end of file reached<br>
* otherwise: the pointer to the next line
*/
-char* ReFile::nextLine(int& length){
- char* rc = NULL;
- length = 0;
- if (m_lineOffset + m_lineLength < m_filesize){
- int lineLength;
- if (m_currentLineNo == 65639)
- m_currentLineNo += 0;
- rc = m_startOfLine = remap(m_lineOffset += m_lineLength, m_maxLineLength,
- lineLength);
- const char* ptr = reinterpret_cast <const char*>(memchr(rc, '\n',
- lineLength));
- if (ptr != NULL)
- lineLength = ptr - rc + 1;
- length = m_lineLength = lineLength;
- m_currentLineNo++;
- }
- return rc;
+char* ReFile::nextLine(int& length) {
+ char* rc = NULL;
+ length = 0;
+ if (m_lineOffset + m_lineLength < m_filesize) {
+ int lineLength;
+ if (m_currentLineNo == 65639)
+ m_currentLineNo += 0;
+ rc = m_startOfLine = remap(m_lineOffset += m_lineLength,
+ m_maxLineLength, lineLength);
+ const char* ptr = reinterpret_cast<const char*>(memchr(rc, '\n',
+ lineLength));
+ if (ptr != NULL)
+ lineLength = ptr - rc + 1;
+ length = m_lineLength = lineLength;
+ m_currentLineNo++;
+ }
+ return rc;
}
/**
* @return NULL: begin of file reached<br>
* otherwise: the pointer to the previous line
*/
-char* ReFile::previousLine(int& length){
- char* rc = NULL;
- length = 0;
- if (m_lineOffset > 0){
- int lineLength;
- rc = remap(m_lineOffset - m_lineLength, m_maxLineLength, lineLength);
- m_startOfLine = rc + lineLength - 1;
- m_lineLength = 0;
- while (m_startOfLine > rc && m_startOfLine[-1] != '\n'){
- m_lineLength++;
- m_startOfLine--;
- }
- rc = m_startOfLine;
- length = m_lineLength;
- }
- return rc;
+char* ReFile::previousLine(int& length) {
+ char* rc = NULL;
+ length = 0;
+ if (m_lineOffset > 0) {
+ int lineLength;
+ rc = remap(m_lineOffset - m_lineLength, m_maxLineLength, lineLength);
+ m_startOfLine = rc + lineLength - 1;
+ m_lineLength = 0;
+ while (m_startOfLine > rc && m_startOfLine[-1] != '\n') {
+ m_lineLength++;
+ m_startOfLine--;
+ }
+ rc = m_startOfLine;
+ length = m_lineLength;
+ }
+ return rc;
}
/**
* @return <code>true</code>success<br>
* <code>false</code>file not readable
*/
-bool ReFile::read(const QString& filename){
- QFile inputFile(filename.isEmpty() ? m_filename : filename);
- bool rc = false;
- if (inputFile.open(QIODevice::ReadOnly)){
- rc = true;
- m_filesize = inputFile.size();
- reserve(m_filesize / 80 * 11 / 10);
- QTextStream in(&inputFile);
- int countCR = 0;
- while (!in.atEnd()){
- QByteArray line = inputFile.readLine();
- int len = line.length();
- if (len > 0 && line.at(len - 1) == '\n'){
- len--;
- line.remove(len, 1);
- if (len > 0 && line.at(len - 1) == '\r'){
- countCR++;
- line.remove(--len, 1);
- }
- }
- append(QString::fromUtf8(line));
- }
- if (countCR > lineCount() / 2)
- setEndOfLine("\r\n");
- else
- setEndOfLine("\n");
- inputFile.close();
- }
- return rc;
+bool ReFile::read(const QString& filename) {
+ QFile inputFile(filename.isEmpty() ? m_filename : filename);
+ bool rc = false;
+ if (inputFile.open(QIODevice::ReadOnly)) {
+ rc = true;
+ m_filesize = inputFile.size();
+ reserve(m_filesize / 80 * 11 / 10);
+ QTextStream in(&inputFile);
+ int countCR = 0;
+ while (!in.atEnd()) {
+ QByteArray line = inputFile.readLine();
+ int len = line.length();
+ if (len > 0 && line.at(len - 1) == '\n') {
+ len--;
+ line.remove(len, 1);
+ if (len > 0 && line.at(len - 1) == '\r') {
+ countCR++;
+ line.remove(--len, 1);
+ }
+ }
+ append(QString::fromUtf8(line));
+ }
+ if (countCR > lineCount() / 2)
+ setEndOfLine("\r\n");
+ else
+ setEndOfLine("\n");
+ inputFile.close();
+ }
+ return rc;
}
/**
* @param buffer OUT: the buffer to write
* @return <code>buffer</code> (for chaining)
*/
-QByteArray& ReFile::readFromFile(const char* filename, QByteArray& buffer){
- FILE* fp = fopen(filename, "r");
- if (fp != NULL){
- struct stat info;
- stat(filename, &info);
- buffer.resize(info.st_size);
- size_t newLength = fread(buffer.data(), 1, info.st_size, fp);
- if (newLength != (size_t) info.st_size)
- buffer.truncate(newLength == (size_t) - 1 ? 0 : newLength);
- fclose(fp);
- }
- return buffer;
+QByteArray& ReFile::readFromFile(const char* filename, QByteArray& buffer) {
+ FILE* fp = fopen(filename, "r");
+ if (fp != NULL) {
+ struct stat info;
+ stat(filename, &info);
+ buffer.resize(info.st_size);
+ size_t newLength = fread(buffer.data(), 1, info.st_size, fp);
+ if (newLength != (size_t) info.st_size)
+ buffer.truncate(newLength == (size_t) - 1 ? 0 : newLength);
+ fclose(fp);
+ }
+ return buffer;
}
/**
* @return NULL: wrong parameters<br>
* otherwise: a pointer to the block
*/
-char* ReFile::remap(int64_t offset, int size, int& length){
- char* rc = NULL;
- length = 0;
- // valid block?
- if (offset >= 0 && offset < m_filesize){
- if (size > m_blocksize)
- size = m_blocksize;
- if (offset + size > m_filesize)
- // fs=3, o=1, => s= 2 = fs - o
- size = m_filesize - offset;
- // Note: size <= m_blocksize
- if (m_block != NULL && offset >= m_blockOffset
- && offset + size <= m_blockOffset + m_blocksize){
- // new block is inside the internal block:
- // no remapping needed
- rc = m_block + (offset - m_blockOffset);
- length = size;
- }else{
- // the new block will be surrounded by the internal block
- m_blockOffset = offset - m_blocksize / 2;
- if (m_blockOffset < 0)
- m_blockOffset = 0;
- else if (m_blockOffset + m_blocksize > m_filesize)
- m_blockOffset = m_filesize - m_blocksize;
- if (m_block != NULL)
- m_file.unmap(reinterpret_cast <uchar*>(m_block));
- m_block = reinterpret_cast <char*>(m_file.map(m_blockOffset,
- m_blocksize));
- rc = m_block + (offset - m_blockOffset);
- length = m_blocksize - (rc - m_block);
- if (length > size)
- length = size;
- }
- }
- return rc;
+char* ReFile::remap(int64_t offset, int size, int& length) {
+ char* rc = NULL;
+ length = 0;
+ // valid block?
+ if (offset >= 0 && offset < m_filesize) {
+ if (size > m_blocksize)
+ size = m_blocksize;
+ if (offset + size > m_filesize)
+ // fs=3, o=1, => s= 2 = fs - o
+ size = m_filesize - offset;
+ // Note: size <= m_blocksize
+ if (m_block != NULL && offset >= m_blockOffset
+ && offset + size <= m_blockOffset + m_blocksize) {
+ // new block is inside the internal block:
+ // no remapping needed
+ rc = m_block + (offset - m_blockOffset);
+ length = size;
+ } else {
+ // the new block will be surrounded by the internal block
+ m_blockOffset = offset - m_blocksize / 2;
+ if (m_blockOffset < 0)
+ m_blockOffset = 0;
+ else if (m_blockOffset + m_blocksize > m_filesize)
+ m_blockOffset = m_filesize - m_blocksize;
+ if (m_block != NULL)
+ m_file.unmap(reinterpret_cast<uchar*>(m_block));
+ m_block = reinterpret_cast<char*>(m_file.map(m_blockOffset,
+ m_blocksize));
+ rc = m_block + (offset - m_blockOffset);
+ length = m_blocksize - (rc - m_block);
+ if (length > size)
+ length = size;
+ }
+ }
+ return rc;
}
/**
* Sets the read position prior to the begin of file.
*/
-void ReFile::rewind(){
- m_currentLineNo = 0;
- m_lineLength = 0;
- m_lineOffset = 0;
- m_startOfLine = NULL;
+void ReFile::rewind() {
+ m_currentLineNo = 0;
+ m_lineLength = 0;
+ m_lineOffset = 0;
+ m_startOfLine = NULL;
}
/**
*
* @param blocksize the blocksize to set
*/
-void ReFile::setBlocksize(const int64_t& blocksize){
- m_blocksize = blocksize;
- if (m_maxLineLength > blocksize / 2)
- m_maxLineLength = blocksize / 2;
+void ReFile::setBlocksize(const int64_t& blocksize) {
+ m_blocksize = blocksize;
+ if (m_maxLineLength > blocksize / 2)
+ m_maxLineLength = blocksize / 2;
}
/**
*
* @param filename the new filename
*/
-void ReFile::setFilename(const QString &filename)
-{
- m_filename = filename;
+void ReFile::setFilename(const QString &filename) {
+ m_filename = filename;
}
/**
* @return the name of an existing directory
*/
QByteArray ReFile::tempDir(const char* node, const char* parent,
- bool withSeparator){
+ bool withSeparator) {
#if defined __linux__
- QByteArray temp("/tmp");
- static const char* firstVar = "TMP";
- static const char* secondVar = "TEMP";
+ QByteArray temp("/tmp");
+ static const char* firstVar = "TMP";
+ static const char* secondVar = "TEMP";
#elif defined WIN32
- QByteArray temp("c:\\temp");
- static const char* firstVar = "TEMP";
- static const char* secondVar = "TMP";
+ QByteArray temp("c:\\temp");
+ static const char* firstVar = "TEMP";
+ static const char* secondVar = "TMP";
#endif
- struct stat info;
- const char* ptr;
- if ((ptr = getenv(firstVar)) != NULL)
- temp = ptr;
- else if ((ptr = getenv(secondVar)) != NULL)
- temp = ptr;
+ struct stat info;
+ const char* ptr;
+ if ((ptr = getenv(firstVar)) != NULL)
+ temp = ptr;
+ else if ((ptr = getenv(secondVar)) != NULL)
+ temp = ptr;
#if defined WIN32
- temp.replace('\\', '/');
+ temp.replace('\\', '/');
#endif
- if (temp.at(temp.length() - 1) != '/')
- temp += '/';
- if (parent != NULL){
- temp += parent;
- if (stat(temp.constData(), &info) != 0)
- _mkdir(temp.constData());
- temp += '/';
- }
- if (node != NULL){
- temp += node;
- if (stat(temp.data(), &info) != 0)
- _mkdir(temp.data());
- temp += '/';
- }
- if (!withSeparator)
- temp.resize(temp.length() - 1);
- return temp;
+ if (temp.at(temp.length() - 1) != '/')
+ temp += '/';
+ if (parent != NULL) {
+ temp += parent;
+ if (stat(temp.constData(), &info) != 0)
+ _mkdir(temp.constData());
+ temp += '/';
+ }
+ if (node != NULL) {
+ temp += node;
+ if (stat(temp.data(), &info) != 0)
+ _mkdir(temp.data());
+ temp += '/';
+ }
+ if (!withSeparator)
+ temp.resize(temp.length() - 1);
+ return temp;
}
/**
* @return the full name of a temporary file
*/
QByteArray ReFile::tempFile(const char* node, const char* parent,
- bool deleteIfExists){
- QByteArray rc(tempDir(parent));
- if (!rc.endsWith('/'))
- rc += '/';
- rc += node;
- struct stat info;
- if (deleteIfExists && stat(rc.constData(), &info) == 0)
- unlink(rc.constData());
- return rc;
+ bool deleteIfExists) {
+ QByteArray rc(tempDir(parent));
+ if (!rc.endsWith('/'))
+ rc += '/';
+ rc += node;
+ struct stat info;
+ if (deleteIfExists && stat(rc.constData(), &info) == 0)
+ unlink(rc.constData());
+ return rc;
}
/**
* @return <code>true</code>success<br>
* <code>false</code>file not readable
*/
-bool ReFile::write(const QString& filename){
- bool rc = false;
- if (!m_readOnly){
- QFile outputFile(filename.isEmpty() ? m_filename : filename);
- if (outputFile.open(QIODevice::WriteOnly)){
- QByteArray buffer;
- int maxIx = length() - 1;
- for (int ix = 0; ix <= maxIx; ix++){
- const QString& line = at(ix);
- buffer = line.toUtf8();
- outputFile.write(buffer.constData(), buffer.length());
- outputFile.write(m_endOfLine.constData(), m_endOfLine.length());
- }
- rc = true;
- outputFile.close();
- }
- }
- return rc;
+bool ReFile::write(const QString& filename) {
+ bool rc = false;
+ if (!m_readOnly) {
+ QFile outputFile(filename.isEmpty() ? m_filename : filename);
+ if (outputFile.open(QIODevice::WriteOnly)) {
+ QByteArray buffer;
+ int maxIx = length() - 1;
+ for (int ix = 0; ix <= maxIx; ix++) {
+ const QString& line = at(ix);
+ buffer = line.toUtf8();
+ outputFile.write(buffer.constData(), buffer.length());
+ outputFile.write(m_endOfLine.constData(), m_endOfLine.length());
+ }
+ rc = true;
+ outputFile.close();
+ }
+ }
+ return rc;
}
/**
* @param mode file write mode: "w" (write) or "a" (append)
*/
void ReFile::writeToFile(const char* filename, const char* content,
- size_t contentLength, const char* mode){
- FILE* fp = fopen(filename, mode);
- if (fp != NULL){
- if (contentLength == (size_t) - 1)
- contentLength = strlen(content);
- fwrite(content, 1, contentLength, fp);
- fclose(fp);
- }
+ size_t contentLength, const char* mode) {
+ FILE* fp = fopen(filename, mode);
+ if (fp != NULL) {
+ if (contentLength == (size_t) - 1)
+ contentLength = strlen(content);
+ fwrite(content, 1, contentLength, fp);
+ fclose(fp);
+ }
}
-
*/
class ReLines: protected QStringList {
public:
- ReLines();
- virtual ~ReLines();
+ ReLines();
+ virtual ~ReLines();
public:
- void insertText(int line, int col, const QString& text);
- /** Returns a line at a given position.
- * @param index the index of the line (0..N-1)
- * @return "": invalid index<br>
- * otherwise: the wanted line
- */
- inline const QString& lineAt(int index) const{
- return index >= 0 && index < length() ? at(index) : m_empty;
- }
- /** Return the number of lines.
- * @return the number of lines
- */
- inline
- int lineCount() const{
- return length();
- }
- virtual void remove(int line, int pos, int count);
- virtual void removeLines(int start, int count);
+ void insertText(int line, int col, const QString& text);
+ bool joinLines(int first);
+ /** Returns a line at a given position.
+ * @param index the index of the line (0..N-1)
+ * @return "": invalid index<br>
+ * otherwise: the wanted line
+ */
+ inline const QString& lineAt(int index) const {
+ return index >= 0 && index < length() ? at(index) : m_empty;
+ }
+ /** Return the number of lines.
+ * @return the number of lines
+ */
+ inline
+ int lineCount() const {
+ return length();
+ }
+ virtual bool remove(int line, int pos, int count);
+ virtual void removeLines(int start, int count);
protected:
- QString m_empty;
+ QString m_empty;
};
class ReLineSource {
public:
- virtual int hasMoreLines(int index) = 0;
+ virtual int hasMoreLines(int index) = 0;
};
class ReFile: public ReLineSource, public ReLines {
public:
- ReFile(const QString& filename, bool readOnly = true,
- ReLogger* logger = NULL);
- ~ReFile();
+ ReFile(const QString& filename, bool readOnly = true, ReLogger* logger =
+ NULL);
+ ~ReFile();
public:
- int64_t blocksize() const;
- void close();
+ int64_t blocksize() const;
+ void close();
/**
* Returns the current line number.
* @return the current line number
*/
- inline uint32_t currentLineNo() const{
+ inline uint32_t currentLineNo() const {
return m_currentLineNo;
}
/** Returns the end of line separator.
* @return the end of line separator. Default: windows: "\r\n" linux: "\n"
*/
- const QByteArray& endOfLine() const{
+ const QByteArray& endOfLine() const {
return m_endOfLine;
}
QString filename() const;
bool findLine(const char* toFind, bool ignoreCase, int& lineNo,
QString* line);
bool findLine(const QString& includePattern, bool includeIsRegExpr,
- bool includeIgnoreCase, const QString& excludePattern,
- bool excludeIsRegExpr, bool excludeIgnoreCase, int& lineNo,
- QString* line);
- virtual int hasMoreLines(int index);
- char* nextLine(int& length);
- char* previousLine(int& length);
- bool read(const QString& filename = "");
- char* remap(int64_t offset, int size, int& length);
- void rewind();
- void setBlocksize(const int64_t& blocksize);
+ bool includeIgnoreCase, const QString& excludePattern,
+ bool excludeIsRegExpr, bool excludeIgnoreCase, int& lineNo,
+ QString* line);
+ virtual int hasMoreLines(int index);
+ char* nextLine(int& length);
+ char* previousLine(int& length);
+ bool read(const QString& filename = "");
+ char* remap(int64_t offset, int size, int& length);
+ void rewind();
+ void setBlocksize(const int64_t& blocksize);
/**Sets the end of line separator.
* @param endOfLine the end of line separator, usually "\n" or "\r\n"
*/
- void setEndOfLine(const char* endOfLine){
+ void setEndOfLine(const char* endOfLine) {
m_endOfLine = endOfLine;
}
void setFilename(const QString &filename);
bool write(const QString& filename = "");
public:
- static QByteArray tempDir(const char* node, const char* parent = NULL,
- bool withSeparator = true);
- static QByteArray tempFile(const char* node, const char* parent = NULL,
- bool deleteIfExists = true);
- static QByteArray& readFromFile(const char* filename, QByteArray& buffer);
- static void writeToFile(const char* filename, const char* content,
- size_t contentLength = (size_t) - 1, const char* mode = "w");
+ static QByteArray tempDir(const char* node, const char* parent = NULL,
+ bool withSeparator = true);
+ static QByteArray tempFile(const char* node, const char* parent = NULL,
+ bool deleteIfExists = true);
+ static QByteArray& readFromFile(const char* filename, QByteArray& buffer);
+ static void writeToFile(const char* filename, const char* content,
+ size_t contentLength = (size_t) - 1, const char* mode = "w");
private:
QByteArray m_endOfLine;
QString m_filename;
QFile m_file;
- char* m_block;
- int64_t m_blocksize;
- int64_t m_blockOffset;
- int64_t m_filesize;
- char* m_startOfLine;
- int m_lineLength;
- int64_t m_lineOffset;
- uint32_t m_currentLineNo;
- int m_maxLineLength;
- QByteArray m_content;
- bool m_readOnly;
- ReLogger* m_logger;
+ char* m_block;
+ int64_t m_blocksize;
+ int64_t m_blockOffset;
+ int64_t m_filesize;
+ char* m_startOfLine;
+ int m_lineLength;
+ int64_t m_lineOffset;
+ uint32_t m_currentLineNo;
+ int m_maxLineLength;
+ QByteArray m_content;
+ bool m_readOnly;
+ ReLogger* m_logger;
};
#endif // REFILE_HPP
#include <iostream>
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;
*
* @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"
* @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() {
}
/**
*
* @return the name of the instance
*/
-const char* ReAppender::getName() const{
- return m_name.data();
+const char* ReAppender::getName() const {
+ return m_name.data();
}
/**
*
* @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.
* @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;
}
/**
*
* @param onNotOff the state of the auto deletion
*/
-void ReAppender::setAutoDelete(bool onNotOff){
- m_autoDelete = onNotOff;
+void ReAppender::setAutoDelete(bool onNotOff) {
+ m_autoDelete = 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"
* @param isGlobal <code>true</code>: the logger becomes the global logger
*/
ReLogger::ReLogger(bool isGlobal) :
- // m_appenders(),
- m_countAppenders(0),
- m_stdPrefix(),
- m_mutex(),
- m_withLocking(false){
- memset(m_appenders, 0, sizeof m_appenders);
- if (isGlobal){
- m_globalLogger = this;
- }
+ // m_appenders(),
+ m_countAppenders(0),
+ m_stdPrefix(),
+ m_mutex(),
+ m_withLocking(false) {
+ memset(m_appenders, 0, sizeof m_appenders);
+ if (isGlobal) {
+ m_globalLogger = this;
+ }
}
/**
* @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.
* @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;
}
/**
* @return false: all appenders are not activated by this level<br>
* 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;
}
/**
*
* @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);
+ }
}
/**
* @param onNotOff true: the logger is thread save.<br>
* false: not thread save
*/
-void ReLogger::setWithLocking(bool onNotOff){
- m_withLocking = onNotOff;
+void ReLogger::setWithLocking(bool onNotOff) {
+ m_withLocking = 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;
}
/**
* @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.
* @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());
}
/**
* @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());
}
/**
* @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);
}
/**
* @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);
+ ...) {
+ char buffer[64000];
+ va_list ap;
+ va_start(ap, format);
+ qvsnprintf(buffer, sizeof buffer, format, ap);
+ va_end(ap);
+ return log(level, location, buffer);
}
/**
* @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);
}
/**
* @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);
}
/**
*
* @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");
+ }
}
/**
* @return NULL: no appender with this name is registered<br>
* 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;
}
/**
* configuration file
*/
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);
+ 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);
}
/**
* @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"
* @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);
}
/**
* @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"
* @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;
+ }
}
/**
*/
#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);
- }
+ 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"
* @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() {
}
/**
*/
#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"
*
* @return the line list
*/
-const QList <QByteArray>& ReMemoryAppender::getLines() const{
- return m_lines;
+const QList<QByteArray>& ReMemoryAppender::getLines() const {
+ return m_lines;
}
/**
* @brief Deletes all log lines.
*/
-void ReMemoryAppender::clear(){
- m_lines.clear();
+void ReMemoryAppender::clear() {
+ m_lines.clear();
}
/**
* @param appenderName a name for the appender
*/
ReDebugAppender::ReDebugAppender(const char* appenderName) :
- ReAppender(appenderName){
+ ReAppender(appenderName) {
}
/**
* Destructor.
*/
-ReDebugAppender::~ReDebugAppender(){
+ReDebugAppender::~ReDebugAppender() {
}
/**
* @param logger the calling logger
*/
void ReDebugAppender::log(ReLoggerLevel level, int location,
- const char* message, ReLogger* logger){
- QByteArray msg(logger->getStdPrefix(level, location));
- qDebug("%s%s", msg.constData(), message);
+ const char* message, ReLogger* logger) {
+ QByteArray msg(logger->getStdPrefix(level, location));
+ qDebug("%s%s", msg.constData(), message);
}
* 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:
- ReLogger(bool isGlobal = true);
- virtual ~ReLogger();
+ ReLogger(bool isGlobal = true);
+ 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);
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;
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;
};
/**
*/
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;
};
/**
*/
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 ".<no>.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 ".<no>.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;
};
/**
*/
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 <QByteArray>& getLines() const;
- void clear();
+ virtual void log(ReLoggerLevel level, int location, const char* message,
+ ReLogger* logger);
+ const QList<QByteArray>& getLines() const;
+ void clear();
private:
- QList <QByteArray> 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<QByteArray> 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;
};
/**
*/
class ReDebugAppender: public ReAppender {
public:
- ReDebugAppender(const char* appenderName = "DebugAppender");
- ~ReDebugAppender();
+ ReDebugAppender(const char* appenderName = "DebugAppender");
+ ~ReDebugAppender();
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);
};
#endif // RELOGGER_HPP
* @param text text to inspect
* @return <code>text</code> without trailing '\n' and/or '\r'
*/
-ReString ReQStringUtil::chomp(const ReString& text){
- int last = text.length() - 1;
- while (last >= 0 && (text[last] == '\n' || text[last] == '\r')){
- last--;
- }
- return last == text.length() - 1 ? text : text.mid(0, last + 1);
+ReString ReQStringUtil::chomp(const ReString& text) {
+ int last = text.length() - 1;
+ while (last >= 0 && (text[last] == '\n' || text[last] == '\r')) {
+ last--;
+ }
+ return last == text.length() - 1 ? text : text.mid(0, last + 1);
}
/**
* @param value string to test
* @param lastChar the last character
*/
-QString& ReQStringUtil::ensureLastChar(QString& value, QChar lastChar){
- if (value.isEmpty() || value.at(value.length() - 1) != lastChar)
- value += lastChar;
- return value;
+QString& ReQStringUtil::ensureLastChar(QString& value, QChar lastChar) {
+ if (value.isEmpty() || value.at(value.length() - 1) != lastChar)
+ value += lastChar;
+ return value;
}
/**
* @return "": no extension found<br>
* otherwise: the extension of <code>filename</code>
*/
-ReString ReQStringUtil::extensionOf(const ReString& filename){
- QString rc;
- int index = filename.lastIndexOf('.');
- int index2 = 0;
- if (index > 0){
- index2 = filename.lastIndexOf('/');
- if (index2 >= 0){
- if (index > index2)
- rc = filename.mid(index);
- }else{
+ReString ReQStringUtil::extensionOf(const ReString& filename) {
+ QString rc;
+ int index = filename.lastIndexOf('.');
+ int index2 = 0;
+ if (index > 0) {
+ index2 = filename.lastIndexOf('/');
+ if (index2 >= 0) {
+ if (index > index2)
+ rc = filename.mid(index);
+ } else {
#if defined __linux__
- rc = filename.mid(index);
+ rc = filename.mid(index);
#elif defined WIN32
- index2 = filename.lastIndexOf('\\');
- if (index2 < 0 || index > index2)
- rc = filename.mid(index);
+ index2 = filename.lastIndexOf('\\');
+ if (index2 < 0 || index > index2)
+ rc = filename.mid(index);
#endif
- }
- }
- return rc;
+ }
+ }
+ return rc;
}
/**
* otherwise: the length of the integer
*/
int ReQStringUtil::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("ReQStringUtil::lengthOfInt(): wrong radix: %d", radix);
- }
- if (pValue != NULL)
- *pValue = value;
- return ix - start;
+ 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("ReQStringUtil::lengthOfInt(): wrong radix: %d",
+ radix);
+ }
+ if (pValue != NULL)
+ *pValue = value;
+ return ix - start;
}
/**
* @brief Determines the length and value of an unsigned integer.
* otherwise: the length of the integer
*/
int ReQStringUtil::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;
+ uint* pValue) {
+ quint64 value;
+ int rc = lengthOfUInt64(text, start, radix, &value);
+ if (pValue != NULL)
+ *pValue = (uint) value;
+ return rc;
}
/**
* @return 0: no date found<br>
* otherwise: the length of the date in the string
*/
-int ReQStringUtil::lengthOfDate(const ReString& text, int start, QDate* value){
- uint day = 0;
- uint month = 0;
- uint year = 0;
- int length = lengthOfUInt(text, start, 10, &year);
- switch (length) {
- case 1:
- case 2:
- day = year;
- year = 0;
- break;
- case 4:
- break;
- default:
- length = 0;
- break;
- }
- int length2;
- start += length;
- skipExpected(text, '.', start, length);
- if (length > 0){
- length2 = lengthOfUInt(text, start, 10, &month);
- if (length2 < 1 || length2 > 2)
- length = 0;
- else{
- start += length2;
- length += length2;
- }
- }
- skipExpected(text, '.', start, length);
- if (year > 0){
- length2 = lengthOfUInt(text, start, 10, &day);
- if (length2 < 1 || length2 > 2)
- length = 0;
- else{
- start += length2;
- length += length2;
- }
- }else{
- length2 = lengthOfUInt(text, start, 10, &year);
- if (length2 != 4)
- length = 0;
- else{
- start += length2;
- length += length2;
- }
- }
- if (day < 1 || day > 31 || month < 1 || month > 12 || year < 1970
- || year > 2100)
- length = 0;
- if (length != 0 && value != NULL)
- *value = QDate(year, month, day);
- return length;
+int ReQStringUtil::lengthOfDate(const ReString& text, int start, QDate* value) {
+ uint day = 0;
+ uint month = 0;
+ uint year = 0;
+ int length = lengthOfUInt(text, start, 10, &year);
+ switch (length) {
+ case 1:
+ case 2:
+ day = year;
+ year = 0;
+ break;
+ case 4:
+ break;
+ default:
+ length = 0;
+ break;
+ }
+ int length2;
+ start += length;
+ skipExpected(text, '.', start, length);
+ if (length > 0) {
+ length2 = lengthOfUInt(text, start, 10, &month);
+ if (length2 < 1 || length2 > 2)
+ length = 0;
+ else {
+ start += length2;
+ length += length2;
+ }
+ }
+ skipExpected(text, '.', start, length);
+ if (year > 0) {
+ length2 = lengthOfUInt(text, start, 10, &day);
+ if (length2 < 1 || length2 > 2)
+ length = 0;
+ else {
+ start += length2;
+ length += length2;
+ }
+ } else {
+ length2 = lengthOfUInt(text, start, 10, &year);
+ if (length2 != 4)
+ length = 0;
+ else {
+ start += length2;
+ length += length2;
+ }
+ }
+ if (day < 1 || day > 31 || month < 1 || month > 12 || year < 1970
+ || year > 2100)
+ length = 0;
+ if (length != 0 && value != NULL)
+ *value = QDate(year, month, day);
+ return length;
}
/**
* otherwise: the length of the date in the string
*/
int ReQStringUtil::lengthOfDateTime(const ReString& text, int start,
- bool allowDateOnly, bool allowTimeOnly, QDateTime* value){
- QDate date;
- QTime time;
- int length = lengthOfDate(text, start, &date);
- if (length == 0){
- if (allowTimeOnly){
- date = QDate::currentDate();
- length = lengthOfTime(text, start, &time);
- }
- }else{
- if (start + length + 1 + 3 <= text.length()){
- start += length;
- int length2 = 0;
- if (!text[start].isDigit()){
- QTime time2;
- length2 = lengthOfTime(text, start + 1, &time2);
- if (length2 == 0 && !allowDateOnly)
- length = 0;
- else if (length2 > 0){
- length += 1 + length2;
- time = time2;
- }
- }
- }
- }
- if (length > 0 && value != NULL)
- *value = QDateTime(date, time);
- return length;
+ bool allowDateOnly, bool allowTimeOnly, QDateTime* value) {
+ QDate date;
+ QTime time;
+ int length = lengthOfDate(text, start, &date);
+ if (length == 0) {
+ if (allowTimeOnly) {
+ date = QDate::currentDate();
+ length = lengthOfTime(text, start, &time);
+ }
+ } else {
+ if (start + length + 1 + 3 <= text.length()) {
+ start += length;
+ int length2 = 0;
+ if (!text[start].isDigit()) {
+ QTime time2;
+ length2 = lengthOfTime(text, start + 1, &time2);
+ if (length2 == 0 && !allowDateOnly)
+ length = 0;
+ else if (length2 > 0) {
+ length += 1 + length2;
+ time = time2;
+ }
+ }
+ }
+ }
+ if (length > 0 && value != NULL)
+ *value = QDateTime(date, time);
+ return length;
}
/**
* Returns the length of a time in a string.
* @return 0: no date found<br>
* otherwise: the length of the date in the string
*/
-int ReQStringUtil::lengthOfTime(const ReString& text, int start, QTime* value){
- uint hour = 0;
- uint minute = 0;
- uint sec = 0;
- int length = lengthOfUInt(text, start, 10, &hour);
- if (length > 0 && hour > 23)
- length = 0;
- if (length > 0){
- start += length;
- }
- int length2;
- skipExpected(text, ':', start, length);
- if (length > 0){
- length2 = lengthOfUInt(text, start, 10, &minute);
- if (length2 < 1 || length2 > 2 || minute >= 60)
- length = 0;
- else
- start += length2, length += length2;
- }
- if (length > 0 && start < text.length() && text[start] == ':'){
- length++;
- start++;
- length2 = lengthOfUInt(text, start, 10, &sec);
- if (length2 < 1 || length2 > 2 || sec >= 60)
- length = 0;
- else
- start += length2, length += length2;
- }
- if (length != 0 && value != NULL)
- *value = QTime(hour, minute, sec);
- return length;
+int ReQStringUtil::lengthOfTime(const ReString& text, int start, QTime* value) {
+ uint hour = 0;
+ uint minute = 0;
+ uint sec = 0;
+ int length = lengthOfUInt(text, start, 10, &hour);
+ if (length > 0 && hour > 23)
+ length = 0;
+ if (length > 0) {
+ start += length;
+ }
+ int length2;
+ skipExpected(text, ':', start, length);
+ if (length > 0) {
+ length2 = lengthOfUInt(text, start, 10, &minute);
+ if (length2 < 1 || length2 > 2 || minute >= 60)
+ length = 0;
+ else
+ start += length2, length += length2;
+ }
+ if (length > 0 && start < text.length() && text[start] == ':') {
+ length++;
+ start++;
+ length2 = lengthOfUInt(text, start, 10, &sec);
+ if (length2 < 1 || length2 > 2 || sec >= 60)
+ length = 0;
+ else
+ start += length2, length += length2;
+ }
+ if (length != 0 && value != NULL)
+ *value = QTime(hour, minute, sec);
+ return length;
}
/**
* @return <=0: no real number found
* otherwise: the length of the floating point number
*/
-int ReQStringUtil::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++;
- }
- if (negative)
- value /= qPow(10, exponent);
- else
- value *= qPow(10, exponent);
- }
- }
- if (pValue)
- *pValue = value;
- return found ? ix - start : 0;
+int ReQStringUtil::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++;
+ }
+ if (negative)
+ value /= qPow(10, exponent);
+ else
+ value *= qPow(10, exponent);
+ }
+ }
+ if (pValue)
+ *pValue = value;
+ return found ? ix - start : 0;
}
/**
* @param filename the filename (with or without path)
* @return the node of <code>filename</code>
*/
-ReString ReQStringUtil::nodeOf(const ReString& filename){
- QString rc;
+ReString ReQStringUtil::nodeOf(const ReString& filename) {
+ QString rc;
- int index = filename.lastIndexOf('/');
- if (index >= 0)
- rc = filename.mid(index + 1);
- else{
+ int index = filename.lastIndexOf('/');
+ if (index >= 0)
+ rc = filename.mid(index + 1);
+ else {
#if defined WIN32
- index = filename.lastIndexOf('\\');
- if (index < 0)
- rc = filename;
- else
- rc = filename.mid(index + 1);
+ index = filename.lastIndexOf('\\');
+ if (index < 0)
+ rc = filename;
+ else
+ rc = filename.mid(index + 1);
#endif
- }
- return rc;
+ }
+ return rc;
}
/**
* @param toAdd a relative path (relative to <code>base</code>)
* @return the combined path
*/
-QString ReQStringUtil::pathAppend(const QString& base, const QString& path){
- QString rc;
- if (!base.isEmpty())
- rc = QDir::cleanPath(base + QDir::separator() + path);
- else{
- rc = path;
- rc.replace("\\", "/");
- if (path.startsWith("/"))
- rc.remove(0, 1);
- }
- return rc;
+QString ReQStringUtil::pathAppend(const QString& base, const QString& path) {
+ QString rc;
+ if (!base.isEmpty())
+ rc = QDir::cleanPath(base + QDir::separator() + path);
+ else {
+ rc = path;
+ rc.replace("\\", "/");
+ if (path.startsWith("/"))
+ rc.remove(0, 1);
+ }
+ return rc;
}
/**
*/
QString ReQStringUtil::replaceExtension(const QString& path,
- const QString& ext){
- QString oldExt = extensionOf(path);
- QString rc;
- if (oldExt.isEmpty())
- rc = path + ext;
- else
- rc = path.mid(0, path.size() - oldExt.size()) + ext;
- return rc;
+ const QString& ext) {
+ QString oldExt = extensionOf(path);
+ QString rc;
+ if (oldExt.isEmpty())
+ rc = path + ext;
+ else
+ rc = path.mid(0, path.size() - oldExt.size()) + ext;
+ return rc;
}
/**
* Replaces placeholders by their values.
* <code>false</code>: unknown name found (not replaced)
*/
bool ReQStringUtil::replacePlaceholders(QString& text,
- const QMap <QString, QString>& placeholders, QString* error){
- int start = 0;
- bool rc = true;
- QString name;
- QMap <QString, QString>::const_iterator it;
- while (start >= 0){
- start = text.indexOf("${", start);
- if (start < 0)
- break;
- int end = text.indexOf('}', start + 1);
- if (end < 0)
- break;
- name = text.mid(start + 2, end - start - 2);
- it = placeholders.find(name);
- if (it == placeholders.end()){
- rc = false;
- if (error != NULL){
- *error = QObject::tr("unknown placeholder: ") + name;
- }
- }else{
- text = text.replace("${" + name + "}", *it);
- }
- start += (*it).length();
- }
- return rc;
+ const QMap<QString, QString>& placeholders, QString* error) {
+ int start = 0;
+ bool rc = true;
+ QString name;
+ QMap<QString, QString>::const_iterator it;
+ while (start >= 0) {
+ start = text.indexOf("${", start);
+ if (start < 0)
+ break;
+ int end = text.indexOf('}', start + 1);
+ if (end < 0)
+ break;
+ name = text.mid(start + 2, end - start - 2);
+ it = placeholders.find(name);
+ if (it == placeholders.end()) {
+ rc = false;
+ if (error != NULL) {
+ *error = QObject::tr("unknown placeholder: ") + name;
+ }
+ } else {
+ text = text.replace("${" + name + "}", *it);
+ }
+ start += (*it).length();
+ }
+ return rc;
}
/**
* otherwise: the length is incremented
*/
void ReQStringUtil::skipExpected(const ReString& text, QChar expected,
- int& index, int& length){
- if (length == 0){
- // error state, do nothing
- }else if (index >= text.length() || text[index] != expected){
- length = 0;
- }else{
- index++;
- length++;
- }
+ int& index, int& length) {
+ if (length == 0) {
+ // error state, do nothing
+ } else if (index >= text.length() || text[index] != expected) {
+ length = 0;
+ } else {
+ index++;
+ length++;
+ }
}
/**
* @return <code>buffer</code>
*/
char*ReQStringUtil::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;
+ 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;
}
class ReParserException: public ReException {
public:
- ReParserException(const QString& message) :
- ReException(), m_message(message){
- }
+ ReParserException(const QString& message) :
+ ReException(),
+ m_message(message) {
+ }
public:
- QString m_message;
+ QString m_message;
};
/**
* Constructor.
* example: "kibyte:1024;kbyte:1000;mibyte:1048576;mbyte:1000000"
*/
ReUnitParser::ReUnitParser(const QString& expr, const char* unitList,
- bool parseAtOnce) :
- m_result(0), m_expr(expr), m_message(), m_unitList(unitList){
- normalize();
- if (parseAtOnce)
- parse();
+ bool parseAtOnce) :
+ m_result(0),
+ m_expr(expr),
+ m_message(),
+ m_unitList(unitList) {
+ normalize();
+ if (parseAtOnce)
+ parse();
}
/**
* @return <code>defaultValue</code>: the result was not valid<br>
* the result as a 64 bit integer
*/
-int64_t ReUnitParser::asInt64(int64_t defaultValue){
- return m_message.isEmpty() ? m_result : defaultValue;
+int64_t ReUnitParser::asInt64(int64_t defaultValue) {
+ return m_message.isEmpty() ? m_result : defaultValue;
}
/**
* Returns the result of the expression as an integer.
* @return <code>defaultValue</code>: the result was not valid<br>
* the result as an integer
*/
-int ReUnitParser::asInt(int defaultValue){
- return m_message.isEmpty() ? (int) m_result : defaultValue;
+int ReUnitParser::asInt(int defaultValue) {
+ return m_message.isEmpty() ? (int) m_result : defaultValue;
}
/**
* Returns the result of the expression as floating point number.
* @return <code>defaultValue</code>: the result was not valid<br>
* the result as a floating point
*/
-real_t ReUnitParser::asReal(real_t defaultValue){
- return m_message.isEmpty() ? (real_t) m_result : defaultValue;
+real_t ReUnitParser::asReal(real_t defaultValue) {
+ return m_message.isEmpty() ? (real_t) m_result : defaultValue;
}
/**
* @return "": no error occurred<br>
* otherwise: the error message
*/
-const QString& ReUnitParser::errorMessage() const{
- return m_message;
+const QString& ReUnitParser::errorMessage() const {
+ return m_message;
}
/**
*
* @return <code>true</code>: the expression is valid, a result was calculated
*/
-bool ReUnitParser::isValid() const{
- return m_message.isEmpty();
+bool ReUnitParser::isValid() const {
+ return m_message.isEmpty();
}
/**
* @brief Normalizes the internal stored unit expression.
*/
-void ReUnitParser::normalize(){
- // Remove the blanks:
- for (int ii = m_expr.length() - 1; ii >= 0; ii--){
- if (m_expr[ii].isSpace())
- m_expr.remove(ii, 1);
- }
- // Replace the '-' operator by '+' as operator and '-' as sign:
- // This makes the syntax easier to parse: only one sum operator ('+').
- for (int ii = m_expr.length() - 1; ii > 0; ii--){
- if (m_expr[ii] == '-' && m_expr[ii - 1] != '+' && m_expr[ii - 1] != '*'){
- m_expr.insert(ii, '+');
- }
- }
+void ReUnitParser::normalize() {
+ // Remove the blanks:
+ for (int ii = m_expr.length() - 1; ii >= 0; ii--) {
+ if (m_expr[ii].isSpace())
+ m_expr.remove(ii, 1);
+ }
+ // Replace the '-' operator by '+' as operator and '-' as sign:
+ // This makes the syntax easier to parse: only one sum operator ('+').
+ for (int ii = m_expr.length() - 1; ii > 0; ii--) {
+ if (m_expr[ii] == '-' && m_expr[ii - 1] != '+'
+ && m_expr[ii - 1] != '*') {
+ m_expr.insert(ii, '+');
+ }
+ }
}
/**
* Evaluate the expression.
*/
-void ReUnitParser::parse(){
- QStringList addends = m_expr.split("+");
- QStringList::const_iterator it;
- try{
- m_result = 0;
- for (it = addends.begin(); it != addends.end(); ++it){
- QStringList factors = it->split("*");
- QStringList::const_iterator it2;
- int64_t product = 1;
- for (it2 = factors.begin(); it2 != factors.end(); ++it2){
- QStringList powerOperands = it2->split("^");
- if (powerOperands.count() > 2)
- throw ReParserException(
- QObject::tr("more than 2 power operators, e.g. '2^3^4'"));
- QStringList::const_iterator it3 = powerOperands.begin();
- QString op = *it3;
- bool isNeg = op.startsWith("-");
- if (isNeg)
- op = op.mid(1);
- uint64_t value = valueOf(op);
- if (powerOperands.count() > 1){
- uint64_t fac = value;
- uint64_t exponent = valueOf(*++it3);
- if (qLn(value) * qLn(exponent) >= qLn(qPow(2.0, 64)))
- throw ReParserException(
- QObject::tr("number overflow while power operation"));
- for (int ii = 1; ii < (int) exponent; ii++)
- value = value * fac;
- }
- product *= value;
- if (isNeg)
- product = -product;
- }
- m_result += product;
- }
+void ReUnitParser::parse() {
+ QStringList addends = m_expr.split("+");
+ QStringList::const_iterator it;
+ try {
+ m_result = 0;
+ for (it = addends.begin(); it != addends.end(); ++it) {
+ QStringList factors = it->split("*");
+ QStringList::const_iterator it2;
+ int64_t product = 1;
+ for (it2 = factors.begin(); it2 != factors.end(); ++it2) {
+ QStringList powerOperands = it2->split("^");
+ if (powerOperands.count() > 2)
+ throw ReParserException(
+ QObject::tr(
+ "more than 2 power operators, e.g. '2^3^4'"));
+ QStringList::const_iterator it3 = powerOperands.begin();
+ QString op = *it3;
+ bool isNeg = op.startsWith("-");
+ if (isNeg)
+ op = op.mid(1);
+ uint64_t value = valueOf(op);
+ if (powerOperands.count() > 1) {
+ uint64_t fac = value;
+ uint64_t exponent = valueOf(*++it3);
+ if (qLn(value) * qLn(exponent) >= qLn(qPow(2.0, 64)))
+ throw ReParserException(
+ QObject::tr(
+ "number overflow while power operation"));
+ for (int ii = 1; ii < (int) exponent; ii++)
+ value = value * fac;
+ }
+ product *= value;
+ if (isNeg)
+ product = -product;
+ }
+ m_result += product;
+ }
- } catch (ReParserException& e){
- m_message = e.m_message;
- }
+ } catch (ReParserException& e) {
+ m_message = e.m_message;
+ }
}
/**
* @return the value of the number multiplied by the factor given by the unit
* @throws ReParserException
*/
-uint64_t ReUnitParser::valueOf(const QString& value) const{
- uint64_t rc = 0;
- int ix = ReQStringUtil::lengthOfUInt64(value, 0, 10, &rc);
- if (ix == 0)
- throw ReParserException(QObject::tr("number expected: ") + value);
- QString unit = value.mid(ix);
- if (!unit.isEmpty()){
- QStringList units = QString(m_unitList).split(";");
- QStringList::const_iterator it;
- bool found = false;
- for (it = units.begin(); it != units.end(); ++it){
- QStringList pair = it->split(":");
- if (pair.count() == 0)
- throw ReParserException(
- QObject::tr("missing ':' in unit definition, e.g. 'k:1000': ")
- + *it);
- if (pair.count() > 2)
- throw ReParserException(
- QObject::tr("too many ':' in unit definition: ") + *it);
- bool ok = false;
- QString unit2 = *pair.begin();
- QString factor = *++pair.begin();
- uint64_t nFactor = factor.toLongLong(&ok);
- if (!ok)
- throw ReParserException(QObject::tr("not a number: ") + factor);
- if (unit2.startsWith(unit, Qt::CaseInsensitive)){
- rc *= nFactor;
- found = true;
- break;
- }
- }
- if (!found)
- throw ReParserException(
- QObject::tr("unknown unit '$1'. Allowed: ").arg(unit)
- + QString(m_unitList));
- }
- return rc;
+uint64_t ReUnitParser::valueOf(const QString& value) const {
+ uint64_t rc = 0;
+ int ix = ReQStringUtil::lengthOfUInt64(value, 0, 10, &rc);
+ if (ix == 0)
+ throw ReParserException(QObject::tr("number expected: ") + value);
+ QString unit = value.mid(ix);
+ if (!unit.isEmpty()) {
+ QStringList units = QString(m_unitList).split(";");
+ QStringList::const_iterator it;
+ bool found = false;
+ for (it = units.begin(); it != units.end(); ++it) {
+ QStringList pair = it->split(":");
+ if (pair.count() == 0)
+ throw ReParserException(
+ QObject::tr(
+ "missing ':' in unit definition, e.g. 'k:1000': ")
+ + *it);
+ if (pair.count() > 2)
+ throw ReParserException(
+ QObject::tr("too many ':' in unit definition: ") + *it);
+ bool ok = false;
+ QString unit2 = *pair.begin();
+ QString factor = *++pair.begin();
+ uint64_t nFactor = factor.toLongLong(&ok);
+ if (!ok)
+ throw ReParserException(QObject::tr("not a number: ") + factor);
+ if (unit2.startsWith(unit, Qt::CaseInsensitive)) {
+ rc *= nFactor;
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ throw ReParserException(
+ QObject::tr("unknown unit '$1'. Allowed: ").arg(unit)
+ + QString(m_unitList));
+ }
+ return rc;
}
/**
* @param expr an expression, e.g. "10*1024kByte+5MiByte"
*/
ReSizeParser::ReSizeParser(const QString& expr) :
- ReUnitParser(expr, "byte:1;kbyte:1000;kibyte:1024;"
- "mbyte:1000000;mibyte:1048576;"
- "gbyte:1000000000;gibyte:1073741824;"
- "tbyte:1000000000000;tibyte:1099511627776"){
+ ReUnitParser(expr, "byte:1;kbyte:1000;kibyte:1024;"
+ "mbyte:1000000;mibyte:1048576;"
+ "gbyte:1000000000;gibyte:1073741824;"
+ "tbyte:1000000000000;tibyte:1099511627776") {
}
/**
* Constructor.
* @param expr an expression, e.g. "3*3days-5min+3weeks"
*/
ReDateTimeParser::ReDateTimeParser(const QString& expr) :
- ReUnitParser("", "minutes:60;hours:3600;days:86400;weeks:604800",
- false){
- parseDateTime(expr);
+ ReUnitParser("", "minutes:60;hours:3600;days:86400;weeks:604800", false) {
+ parseDateTime(expr);
}
/**
*
* @return the parse result. If invalid input the result is the begin of the epoche
*/
-QDateTime ReDateTimeParser::asDateTime() const{
- return m_dateTime;
+QDateTime ReDateTimeParser::asDateTime() const {
+ return m_dateTime;
}
/**
* @return start of the epoche: no valid input<br>
* othewise: the calculated date/time
*/
-QDateTime ReDateTimeParser::parseDateTime(const QString& expr){
- m_expr = expr;
- normalize();
- QDateTime rc = QDateTime::currentDateTime();
- int64_t relativeSeconds = 0;
- if (m_expr.isEmpty())
- m_message = QObject::tr("empty string is not a date/time");
- else{
- QDateTime dateTime;
- int length2 = 0;
- bool checkSum = true;
- if (m_expr.startsWith("now", Qt::CaseInsensitive)){
- m_expr.remove(0, 3);
- }else if ((length2 = ReQStringUtil::lengthOfDateTime(m_expr, 0, true,
- true, &dateTime)) > 0){
- rc = dateTime;
- m_expr.remove(0, length2);
- }else{
- checkSum = false;
- parse();
- // meaning is "older than x seconds"
- relativeSeconds = m_result = -m_result;
- }
- if (checkSum){
- if (m_expr.startsWith("+")){
- m_expr.remove(0, 1);
- }
- if (!m_expr.isEmpty()){
- parse();
- relativeSeconds = m_result;
- }
- }
- }
- rc.setMSecsSinceEpoch(
- isValid() ? rc.toMSecsSinceEpoch() + 1000 * relativeSeconds : 0);
- m_dateTime = rc;
- return rc;
+QDateTime ReDateTimeParser::parseDateTime(const QString& expr) {
+ m_expr = expr;
+ normalize();
+ QDateTime rc = QDateTime::currentDateTime();
+ int64_t relativeSeconds = 0;
+ if (m_expr.isEmpty())
+ m_message = QObject::tr("empty string is not a date/time");
+ else {
+ QDateTime dateTime;
+ int length2 = 0;
+ bool checkSum = true;
+ if (m_expr.startsWith("now", Qt::CaseInsensitive)) {
+ m_expr.remove(0, 3);
+ } else if ((length2 = ReQStringUtil::lengthOfDateTime(m_expr, 0, true,
+ true, &dateTime)) > 0) {
+ rc = dateTime;
+ m_expr.remove(0, length2);
+ } else {
+ checkSum = false;
+ parse();
+ // meaning is "older than x seconds"
+ relativeSeconds = m_result = -m_result;
+ }
+ if (checkSum) {
+ if (m_expr.startsWith("+")) {
+ m_expr.remove(0, 1);
+ }
+ if (!m_expr.isEmpty()) {
+ parse();
+ relativeSeconds = m_result;
+ }
+ }
+ }
+ rc.setMSecsSinceEpoch(
+ isValid() ? rc.toMSecsSinceEpoch() + 1000 * relativeSeconds : 0);
+ m_dateTime = rc;
+ return rc;
}
class ReQStringUtil {
public:
- static ReString chomp(const ReString& text);
- static QString& ensureLastChar(QString& value, QChar lastChar);
- static ReString extensionOf(const ReString& filename);
- static int lengthOfDate(const ReString& text, int start = 0, QDate* value =
- NULL);
- static int lengthOfDateTime(const ReString& text, int start = 0,
- bool allowDateOnly = true, bool allowTimeOnly = true, QDateTime* value =
- NULL);
- static int lengthOfReal(const ReString& text, int start = 0, qreal* value =
- NULL);
- static int lengthOfTime(const ReString& text, int start = 0, QTime* value =
- NULL);
- static int lengthOfUInt64(const ReString& text, int start = 0,
- int radix = 10, uint64_t* value = NULL);
- static int lengthOfUInt(const ReString& text, int start, int radix,
- uint* pValue);
- /**
- * Returns the path with native path separators.
- *
- * @param path the path to change
- * @return the path with native path separators
- */
- inline static QString nativePath(const QString& path){
+ static ReString chomp(const ReString& text);
+ static QString& ensureLastChar(QString& value, QChar lastChar);
+ static ReString extensionOf(const ReString& filename);
+ static int lengthOfDate(const ReString& text, int start = 0, QDate* value =
+ NULL);
+ static int lengthOfDateTime(const ReString& text, int start = 0,
+ bool allowDateOnly = true, bool allowTimeOnly = true, QDateTime* value =
+ NULL);
+ static int lengthOfReal(const ReString& text, int start = 0, qreal* value =
+ NULL);
+ static int lengthOfTime(const ReString& text, int start = 0, QTime* value =
+ NULL);
+ static int lengthOfUInt64(const ReString& text, int start = 0, int radix =
+ 10, uint64_t* value = NULL);
+ static int lengthOfUInt(const ReString& text, int start, int radix,
+ uint* pValue);
+ /**
+ * Returns the path with native path separators.
+ *
+ * @param path the path to change
+ * @return the path with native path separators
+ */
+ inline static QString nativePath(const QString& path) {
#if defined WIN32
- QString rc(path); return rc.replace("/", "\\");
+ QString rc(path); return rc.replace("/", "\\");
#else
- return path;
+ return path;
#endif
- }
- static ReString nodeOf(const ReString& filename);
- static QString pathAppend(const QString& base, const QString& path);
- static QString replaceExtension(const QString& path, const QString& ext);
- static bool replacePlaceholders(QString& text,
- const QMap <QString, QString>& placeholders, QString* error);
- static void skipExpected(const ReString& text, QChar expected, int& index,
- int& length);
- /**
- * @brief Returns the value of a hexadecimal digit.
- *
- * @param digit a (unicode) character
- * @return -1: not a hexadecimal digit<br>
- * 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 ReString nodeOf(const ReString& filename);
+ static QString pathAppend(const QString& base, const QString& path);
+ static QString replaceExtension(const QString& path, const QString& ext);
+ static bool replacePlaceholders(QString& text,
+ const QMap<QString, QString>& placeholders, QString* error);
+ static void skipExpected(const ReString& text, QChar expected, int& index,
+ int& length);
+ /**
+ * @brief Returns the value of a hexadecimal digit.
+ *
+ * @param digit a (unicode) character
+ * @return -1: not a hexadecimal digit<br>
+ * 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);
};
class ReUnitParser {
public:
- ReUnitParser(const QString& expr, const char* unitList, bool parseAtOnce =
- true);
+ ReUnitParser(const QString& expr, const char* unitList, bool parseAtOnce =
+ true);
public:
- bool isValid() const;
- const QString& errorMessage() const;
- int64_t asInt64(int64_t defaultValue = -1ll);
- int asInt(int defaultValue = -1);
- real_t asReal(real_t defaultValue = -1.0);
+ bool isValid() const;
+ const QString& errorMessage() const;
+ int64_t asInt64(int64_t defaultValue = -1ll);
+ int asInt(int defaultValue = -1);
+ real_t asReal(real_t defaultValue = -1.0);
protected:
- void parse();
- void normalize();
- uint64_t valueOf(const QString& value) const;
+ void parse();
+ void normalize();
+ uint64_t valueOf(const QString& value) const;
protected:
- int64_t m_result;
- QString m_expr;
- QString m_message;
- const char* m_unitList;
+ int64_t m_result;
+ QString m_expr;
+ QString m_message;
+ const char* m_unitList;
};
class ReSizeParser: public ReUnitParser {
public:
- ReSizeParser(const QString& expr);
+ ReSizeParser(const QString& expr);
};
class ReDateTimeParser: public ReUnitParser {
public:
- ReDateTimeParser(const QString& expr);
+ ReDateTimeParser(const QString& expr);
public:
- QDateTime parseDateTime(const QString& expr);
- QDateTime asDateTime() const;
+ QDateTime parseDateTime(const QString& expr);
+ QDateTime asDateTime() const;
private:
- QDateTime m_dateTime;
+ QDateTime m_dateTime;
};
#endif // RPLQSTRING_HPP
* @param cc the char to count
* @return the number of <code>cc</code> 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.
* @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;
}
/**
* 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;
+ 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;
* @brief Returns the os specific file path separator.
* @return the file path separator, e.g. "/" for linux
*/
-const char* ReStringUtil::fileSeparator(){
- return fileSeparatorChar() == '/' ? "/" : "\\";
+const char* ReStringUtil::fileSeparator() {
+ return fileSeparatorChar() == '/' ? "/" : "\\";
}
/**
* @brief Returns the os specific file path separator.
* @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;
+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;
}
/**
* @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;
}
/**
* 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;
+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;
}
/**
* @param separator the separator between the items to split
* @return an array with the splitted source
*/
-QList <QByteArray> 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;
+QList<QByteArray> 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;
+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;
}
/**
* @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);
}
/**
* 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;
+ 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.
* @return 0: not a number<br>
* 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 == '-')
- ptr++;
- if (!isdigit(*ptr))
- ptr = ptrToE;
- else{
- while (isdigit(*ptr))
- ptr++;
- }
- }
- if (found && skipTrailingSpaces){
- while (isspace(*ptr)){
- ptr++;
- }
- }
- rc = !found ? 0 : ptr - text;
- return rc;
+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 == '-')
+ ptr++;
+ if (!isdigit(*ptr))
+ ptr = ptrToE;
+ else {
+ while (isdigit(*ptr))
+ ptr++;
+ }
+ }
+ if (found && skipTrailingSpaces) {
+ while (isspace(*ptr)) {
+ ptr++;
+ }
+ }
+ rc = !found ? 0 : ptr - text;
+ return rc;
}
/**
* @brief Adds the count of the possible separators.
* @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, ' ');
}
/**
* @param buffer a line buffer
* @param bufferSize the size of <code>buffer[]</code>
*/
-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 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;
}
/**
* @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;
}
/**
* @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 == '-'){
- 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;
+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++;
+ }
+ if (negative)
+ value /= qPow(10, exponent);
+ else
+ value *= qPow(10, exponent);
+ }
+ }
+ if (pValue)
+ *pValue = value;
+ return found ? length : 0;
}
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 <QByteArray> 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<QByteArray> 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
#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
};
/**
* @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() {
}
/**
* @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;
}
/**
* @return true: the thread should be stopped.<br>
* false: otherwise
*/
-bool ReTerminator::isStopped() const{
- return m_stop;
+bool ReTerminator::isStopped() const {
+ return m_stop;
}
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
* @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);
+ 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);
}
-void ReTest::doIt(){
- try{
- run();
- } catch (ReException e){
- error("unexpected RplException: %s", e.getMessage().constData());
- } catch (...){
- error("unknown Exception");
- }
+void ReTest::doIt() {
+ 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() {
}
/**
* @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;
}
/**
* @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;
}
/**
* @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;
}
/**
* @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;
}
/**
* @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;
}
/**
* @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 < 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;
+ 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;
}
/**
* @param lineNo the line number containing the test
* @return true: equal
*/
-bool ReTest::assertEquals(const QList <QByteArray>& expected,
- const QList <QByteArray>& 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<QByteArray>& expected,
+ const QList<QByteArray>& 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.
* @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);
+ const char* file, int lineNo) {
+ return assertEquals(expected.data(), current.data(), file, lineNo);
}
/**
* @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);
}
/**
* @return true: equal
*/
bool ReTest::assertEquals(const QDate& expected, const QDate& current,
- const char* file, int lineNo){
- return assertEquals(expected.toString("yyyy.MM.dd"),
- current.toString("yyyy.MM.dd"), file, lineNo);
+ const char* file, int lineNo) {
+ return assertEquals(expected.toString("yyyy.MM.dd"),
+ current.toString("yyyy.MM.dd"), file, lineNo);
}
/**
* @return true: equal
*/
bool ReTest::assertEquals(const QDateTime& expected, const QDateTime& current,
- const char* file, int lineNo){
- return assertEquals(expected.toString("yyyy.MM.dd hh:mm:ss"),
- current.toString("yyyy.MM.dd hh:mm:ss"), file, lineNo);
+ const char* file, int lineNo) {
+ return assertEquals(expected.toString("yyyy.MM.dd hh:mm:ss"),
+ current.toString("yyyy.MM.dd hh:mm:ss"), file, lineNo);
}
/**
* @return true: equal
*/
bool ReTest::assertEquals(const QTime& expected, const QTime& current,
- const char* file, int lineNo){
- return assertEquals(expected.toString("hh:mm:ss"),
- current.toString("hh:mm:ss"), file, lineNo);
+ const char* file, int lineNo) {
+ return assertEquals(expected.toString("hh:mm:ss"),
+ current.toString("hh:mm:ss"), file, lineNo);
}
/**
* @param lineNo the line number containing the test
* @return <code>condition</code>
*/
-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;
}
/**
* @param lineNo the line number containing the test
* @return <code>! condition</code>
*/
-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;
}
/**
* @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;
}
/**
* @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;
}
/**
* 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 < QByteArray > expLines = expectedContent.split('\n');
- QList < QByteArray > 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;
}
/**
* @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;
}
/**
* @param ... the values for the placeholders in <code>format</code>
* @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;
}
/**
* @return true: pattern has been found<br>
* false: otherwise
*/
-bool ReTest::logContains(const char* pattern){
- const QList <QByteArray>& 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<QByteArray>& 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;
}
/**
* @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;
}
/**
* @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;
}
// 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);
protected:
- void doIt();
+ void doIt();
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 QDate& expected, const QDate& current,
- const char* file, int lineNo);
- bool assertEquals(const QDateTime& expected, const QDateTime& current,
- const char* file, int lineNo);
- bool assertEquals(const QTime& expected, const QTime& current,
- const char* file, int lineNo);
- bool assertEquals(const QList <QByteArray>& expected,
- const QList <QByteArray>& 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 QDate& expected, const QDate& current,
+ const char* file, int lineNo);
+ bool assertEquals(const QDateTime& expected, const QDateTime& current,
+ const char* file, int lineNo);
+ bool assertEquals(const QTime& expected, const QTime& current,
+ const char* file, int lineNo);
+ bool assertEquals(const QList<QByteArray>& expected,
+ const QList<QByteArray>& 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__)
#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";
+ "\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"
* Closes the output medium.
* Ensures that the destructors of the derived classes are virtual.
*/
-ReWriter::~ReWriter(){
- close();
+ReWriter::~ReWriter() {
+ close();
}
/**
*
* @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);
}
/**
* @param format format string with placeholders like <code>sprintf()</code>
* @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.
* @param format format string with placeholders like <code>sprintf()</code>
* @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);
}
/**
* @param ap variable argument list (like in <code>vsprintf</code>)
* @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);
}
/**
* @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);
}
/**
* @param format format string with placeholders like <code>sprintf</code>
* @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"
* @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;
}
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 {
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
#define UNUSED_VAR(var) (void) var
inline
-int max(int a, int b){
- return a > b ? a : b;
+int max(int a, int b) {
+ return a > b ? a : b;
}
inline
-int min(int a, int b){
- return a < b ? a : b;
+int min(int a, int b) {
+ return a < b ? a : b;
}
-inline double max(double a, double b){
- return a > b ? a : b;
+inline double max(double a, double b) {
+ return a > b ? a : b;
}
-inline double min(double a, double b){
- return a < b ? a : b;
+inline double min(double a, double b) {
+ return a < b ? a : b;
}
/**
*
* @param value the value to round
*/
-inline int roundInt(double value){
- return (int) round(value);
+inline int roundInt(double value) {
+ return (int) round(value);
}
#include "remodules.hpp"
#include "base/rebase.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 {
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();
}
static bool s_allTest = false;
-static void testBase(){
- void testReByteStorage();
- void testReCharPtrMap();
- void testReConfig();
- void testReContainer();
- void testReException();
- void testReQStringUtil();
- void testReStringUtil();
- void testReWriter();
- void testReFile();
+static void testBase() {
+ void testReByteStorage();
+ void testReCharPtrMap();
+ void testReConfig();
+ void testReContainer();
+ void testReException();
+ void testReQStringUtil();
+ void testReStringUtil();
+ void testReWriter();
+ void testReFile();
- testReFile();
- if (s_allTest){
- testReQStringUtil();
- testReByteStorage();
- testReCharPtrMap();
- testReConfig();
- testReContainer();
- testReException();
- testReQStringUtil();
- testReStringUtil();
- testReWriter();
- }
+ testReFile();
+ if (s_allTest) {
+ testReQStringUtil();
+ testReByteStorage();
+ testReCharPtrMap();
+ testReConfig();
+ testReContainer();
+ testReException();
+ testReQStringUtil();
+ testReStringUtil();
+ testReWriter();
+ }
}
-static void testMath(){
+static void testMath() {
}
-static void testExpr(){
- /*
- extern void testReMFParser();
- extern void testRplBenchmark();
- extern void testReVM();
- extern void testReSource();
- extern void testReLexer();
- extern void testReMFParser();
- extern void testReASTree();
- extern void testReVM();
+static void testExpr() {
+ /*
+ extern void testReMFParser();
+ extern void testRplBenchmark();
+ extern void testReVM();
+ extern void testReSource();
+ extern void testReLexer();
+ extern void testReMFParser();
+ extern void testReASTree();
+ extern void testReVM();
- //testRplBenchmark();
- if (s_allTest){
- testReVM();
- testReSource();
- testReLexer();
- testReMFParser();
- testReASTree();
- testReVM();
- }
- */
+ //testRplBenchmark();
+ if (s_allTest){
+ testReVM();
+ testReSource();
+ testReLexer();
+ testReMFParser();
+ testReASTree();
+ testReVM();
+ }
+ */
}
-static void testNet(){
+static void testNet() {
}
-static void testOs(){
+static void testOs() {
}
-void allTests(){
- testBase();
- if (s_allTest){
- testBase();
- testMath();
- testExpr();
- testNet();
- testOs();
- }
+void allTests() {
+ testBase();
+ if (s_allTest) {
+ testBase();
+ testMath();
+ testExpr();
+ testNet();
+ testOs();
+ }
}
class TestReASTree: public ReTest {
private:
- ReSource m_source;
- ReStringReader m_reader;
- ReStringSourceUnit m_unit;
- ReASTree m_tree;
+ ReSource m_source;
+ ReStringReader m_reader;
+ ReStringSourceUnit m_unit;
+ ReASTree m_tree;
public:
- TestReASTree() :
- ReTest("ReASTree"),
- m_source(),
- m_reader(m_source),
- m_unit("<main>", "", &m_reader),
- m_tree(){
- }
+ TestReASTree() :
+ ReTest("ReASTree"),
+ m_source(),
+ m_reader(m_source),
+ m_unit("<main>", "", &m_reader),
+ m_tree() {
+ }
public:
- void testReASException(){
- try{
- m_reader.addSource("<main>", "12");
- m_source.addReader(&m_reader);
- m_source.addSourceUnit(m_reader.currentSourceUnit());
- const ReSourcePosition* pos = m_source.newPosition(2);
- throw ReASException(pos, "simple string: %s", "Hi");
- checkF(true);
- } catch (ReASException exc){
- checkEqu("<main>:0:2: simple string: Hi",
- exc.getMessage().constData());
- }
- }
- void testReASVariant(){
- ReASVariant val1;
- val1.setFloat(2.5E-2);
- checkEqu(2.5E-2, val1.asFloat());
- ReASVariant val2(val1);
- checkEqu(2.5E-2, val2.asFloat());
+ void testReASException() {
+ try {
+ m_reader.addSource("<main>", "12");
+ m_source.addReader(&m_reader);
+ m_source.addSourceUnit(m_reader.currentSourceUnit());
+ const ReSourcePosition* pos = m_source.newPosition(2);
+ throw ReASException(pos, "simple string: %s", "Hi");
+ checkF(true);
+ } catch (ReASException exc) {
+ checkEqu("<main>:0:2: simple string: Hi",
+ exc.getMessage().constData());
+ }
+ }
+ void testReASVariant() {
+ ReASVariant val1;
+ val1.setFloat(2.5E-2);
+ checkEqu(2.5E-2, val1.asFloat());
+ ReASVariant val2(val1);
+ checkEqu(2.5E-2, val2.asFloat());
- val1.setInt(4321);
- checkEqu(4321, val1.asInt());
- val2 = val1;
- checkEqu(4321, val2.asInt());
+ val1.setInt(4321);
+ checkEqu(4321, val1.asInt());
+ val2 = val1;
+ checkEqu(4321, val2.asInt());
- val1.setBool(false);
- checkF(val1.asBool());
- val2 = val1;
- checkF(val2.asBool());
+ val1.setBool(false);
+ checkF(val1.asBool());
+ val2 = val1;
+ checkF(val2.asBool());
- val1.setBool(true);
- checkT(val1.asBool());
- val2 = val1;
- checkT(val2.asBool());
+ val1.setBool(true);
+ checkT(val1.asBool());
+ val2 = val1;
+ checkT(val2.asBool());
- val1.setString("High noon!");
- checkEqu("High noon!", *val1.asString());
- val2 = val1;
- val1.setString("Bye");
- checkEqu("High noon!", *val2.asString());
- ReASVariant val3(val1);
- checkEqu("Bye", *val3.asString());
- }
- void testReASConstant(){
- ReASConstant constant;
- //constant.value().setString("Jonny");
- ReASVariant value;
- //constant.calc(value);
- //checkEqu("Jonny", *value.asString());
- }
- void testReASNamedValue(){
- ReASNamedValue value(NULL, m_tree.symbolSpaces()[0], "gugo",
- ReASNamedValue::A_GLOBAL);
- checkEqu("gugo", value.name());
- }
- virtual void run(){
- testReASNamedValue();
- testReASConstant();
- testReASException();
- testReASVariant();
- }
+ val1.setString("High noon!");
+ checkEqu("High noon!", *val1.asString());
+ val2 = val1;
+ val1.setString("Bye");
+ checkEqu("High noon!", *val2.asString());
+ ReASVariant val3(val1);
+ checkEqu("Bye", *val3.asString());
+ }
+ void testReASConstant() {
+ ReASConstant constant;
+ //constant.value().setString("Jonny");
+ ReASVariant value;
+ //constant.calc(value);
+ //checkEqu("Jonny", *value.asString());
+ }
+ void testReASNamedValue() {
+ ReASNamedValue value(NULL, m_tree.symbolSpaces()[0], "gugo",
+ ReASNamedValue::A_GLOBAL);
+ checkEqu("gugo", value.name());
+ }
+ virtual void run() {
+ testReASNamedValue();
+ testReASConstant();
+ testReASException();
+ testReASVariant();
+ }
};
-void testReASTree(){
- TestReASTree test;
+void testReASTree() {
+ TestReASTree test;
}
class TestRplBenchmark: public ReTest {
private:
- const char* m_filename;
- ReSource m_source;
- ReFileReader m_reader;
- ReASTree m_tree;
+ const char* m_filename;
+ ReSource m_source;
+ ReFileReader m_reader;
+ ReASTree m_tree;
public:
- TestRplBenchmark() :
- ReTest("RplBenchmark"),
- m_filename("/home/ws/qt/rplqt/bench/mfbench.mf"),
- m_source(),
- m_reader(m_source),
- m_tree(){
- m_source.addReader(&m_reader);
- m_reader.addSource(m_filename);
- }
+ TestRplBenchmark() :
+ ReTest("RplBenchmark"),
+ m_filename("/home/ws/qt/rplqt/bench/mfbench.mf"),
+ m_source(),
+ m_reader(m_source),
+ m_tree() {
+ m_source.addReader(&m_reader);
+ m_reader.addSource(m_filename);
+ }
public:
- void benchmark(){
- time_t start = time(NULL);
- ReMFParser parser(m_source, m_tree);
- parser.parse();
- time_t end = time(NULL);
- printf("compilation: %d sec\n", int(end - start));
- }
- virtual void run(){
- try{
- ReFileSourceUnit* unit =
- dynamic_cast <ReFileSourceUnit*>(m_reader.currentSourceUnit());
- if (unit != NULL && !unit->isOpen())
- throw ReException("file not found: %s", m_filename);
- benchmark();
- } catch (ReException ex){
- printf("%s\n", ex.getMessage().constData());
- }
- }
+ void benchmark() {
+ time_t start = time(NULL);
+ ReMFParser parser(m_source, m_tree);
+ parser.parse();
+ time_t end = time(NULL);
+ printf("compilation: %d sec\n", int(end - start));
+ }
+ virtual void run() {
+ try {
+ ReFileSourceUnit* unit = dynamic_cast<ReFileSourceUnit*>(m_reader
+ .currentSourceUnit());
+ if (unit != NULL && !unit->isOpen())
+ throw ReException("file not found: %s", m_filename);
+ benchmark();
+ } catch (ReException ex) {
+ printf("%s\n", ex.getMessage().constData());
+ }
+ }
};
-void testRplBenchmark(){
- TestRplBenchmark test;
- test.run();
+void testRplBenchmark() {
+ TestRplBenchmark test;
+ test.run();
}
class TestReByteStorage: public ReTest {
public:
- TestReByteStorage() :
- ReTest("ReByteStorage"){
- doIt();
- }
+ TestReByteStorage() :
+ ReTest("ReByteStorage") {
+ doIt();
+ }
private:
- void testChars(){
- ReByteStorage store(100);
- char* s1 = store.allocateChars(4);
- memcpy((void*) s1, "123", 4);
- const char* s2 = store.allocateChars("abc");
- const char* s3 = store.allocateChars("defghij", 3);
- checkEqu(s1, "123");
- checkEqu(s2, "abc");
- checkEqu(s3, "def");
- const char* ptr = s1 + 4;
- checkT(ptr == s2);
- ptr += 4;
- checkT(ptr == s3);
- }
+ void testChars() {
+ ReByteStorage store(100);
+ char* s1 = store.allocateChars(4);
+ memcpy((void*) s1, "123", 4);
+ const char* s2 = store.allocateChars("abc");
+ const char* s3 = store.allocateChars("defghij", 3);
+ checkEqu(s1, "123");
+ checkEqu(s2, "abc");
+ checkEqu(s3, "def");
+ const char* ptr = s1 + 4;
+ checkT(ptr == s2);
+ ptr += 4;
+ checkT(ptr == s3);
+ }
- void testBytes(){
- ReByteStorage store(100);
- uint8_t* s1 = store.allocateBytes(4);
- memcpy((void*) s1, "1234", 4);
- uint8_t* s2 = store.allocateBytes((void*) "abcd", 4);
- uint8_t* s3 = store.allocateBytes((void*) "efghij", 4);
- uint8_t* s4 = store.allocateZeros(4);
+ void testBytes() {
+ ReByteStorage store(100);
+ uint8_t* s1 = store.allocateBytes(4);
+ memcpy((void*) s1, "1234", 4);
+ uint8_t* s2 = store.allocateBytes((void*) "abcd", 4);
+ uint8_t* s3 = store.allocateBytes((void*) "efghij", 4);
+ uint8_t* s4 = store.allocateZeros(4);
- checkEqu("1234abcdefgh", (const char* ) s1);
- uint8_t* ptr = s1 + 4;
- checkT(ptr == s2);
- ptr += 4;
- checkT(ptr == s3);
- ptr += 4;
- checkT(ptr == s4);
- for (int ii = 0; ii < 4; ii++)
- checkEqu(0, (int ) s4[ii]);
- }
- void testBufferChange(){
- ReByteStorage store(10);
- char buffer[2];
- buffer[1] = '\0';
- for (int ii = 0; ii < 10000; ii++){
- buffer[1] = 'A' + ii % 26;
- store.allocateBytes(buffer, 1);
- }
- }
+ checkEqu("1234abcdefgh", (const char* ) s1);
+ uint8_t* ptr = s1 + 4;
+ checkT(ptr == s2);
+ ptr += 4;
+ checkT(ptr == s3);
+ ptr += 4;
+ checkT(ptr == s4);
+ for (int ii = 0; ii < 4; ii++)
+ checkEqu(0, (int ) s4[ii]);
+ }
+ void testBufferChange() {
+ ReByteStorage store(10);
+ char buffer[2];
+ buffer[1] = '\0';
+ for (int ii = 0; ii < 10000; ii++) {
+ buffer[1] = 'A' + ii % 26;
+ store.allocateBytes(buffer, 1);
+ }
+ }
public:
- virtual void run(){
- testBufferChange();
- testChars();
- testBytes();
- }
+ virtual void run() {
+ testBufferChange();
+ testChars();
+ testBytes();
+ }
};
-void testReByteStorage(){
- TestReByteStorage test;
+void testReByteStorage() {
+ TestReByteStorage test;
}
class TestReCharPtrMap: public ReTest {
public:
- TestReCharPtrMap() :
- ReTest("ReCharPtrMap"){
- doIt();
- }
+ TestReCharPtrMap() :
+ ReTest("ReCharPtrMap") {
+ doIt();
+ }
protected:
- void testBasic(){
- ReCharPtrMap <const char*> map;
- map["x"] = "x1";
- checkT(map.contains("x"));
- checkF(map.contains("y"));
- checkEqu("x1", map["x"]);
- }
+ void testBasic() {
+ ReCharPtrMap<const char*> map;
+ map["x"] = "x1";
+ checkT(map.contains("x"));
+ checkF(map.contains("y"));
+ checkEqu("x1", map["x"]);
+ }
public:
- virtual void run(void){
- testBasic();
- }
+ virtual void run(void) {
+ testBasic();
+ }
};
-void testReCharPtrMap(){
- TestReCharPtrMap test;
+void testReCharPtrMap() {
+ TestReCharPtrMap test;
}
*/
class TestReConfig: public ReTest {
public:
- TestReConfig() :
- ReTest("ReConfig"){
- doIt();
- }
+ TestReConfig() :
+ ReTest("ReConfig") {
+ doIt();
+ }
public:
- void testBasic(){
- QByteArray fn = getTempFile("test.data", "config");
- ReStringUtil::write(fn, "#comment\na=1\nb.1==x\n#=\nB=zzz");
- ReConfig config(fn.constData());
- checkEqu(3, config.size());
- checkEqu("1", config["a"]);
- checkEqu("=x", config["b.1"]);
- checkEqu("zzz", config["B"]);
- }
- void testAsX(){
- QByteArray fn = getTempFile("test.data", "config");
- ReStringUtil::write(fn, "i=123\nb=1\nb2=true\nb3=yes\ns=abc");
- ReConfig config(fn.constData());
- checkEqu(5, config.size());
- checkEqu(123, config.asInt("i", -1));
- checkEqu(-1, config.asInt("I", -1));
- checkT(config.asBool("b", false));
- checkT(config.asBool("b2", false));
- checkT(config.asBool("b3", false));
- checkT(config.asBool("-", true));
- checkF(config.asBool("-", false));
- checkEqu("abc", config.asString("s", "x"));
- checkEqu("x", config.asString("S", "x"));
- }
+ void testBasic() {
+ QByteArray fn = getTempFile("test.data", "config");
+ ReStringUtil::write(fn, "#comment\na=1\nb.1==x\n#=\nB=zzz");
+ ReConfig config(fn.constData());
+ checkEqu(3, config.size());
+ checkEqu("1", config["a"]);
+ checkEqu("=x", config["b.1"]);
+ checkEqu("zzz", config["B"]);
+ }
+ void testAsX() {
+ QByteArray fn = getTempFile("test.data", "config");
+ ReStringUtil::write(fn, "i=123\nb=1\nb2=true\nb3=yes\ns=abc");
+ ReConfig config(fn.constData());
+ checkEqu(5, config.size());
+ checkEqu(123, config.asInt("i", -1));
+ checkEqu(-1, config.asInt("I", -1));
+ checkT(config.asBool("b", false));
+ checkT(config.asBool("b2", false));
+ checkT(config.asBool("b3", false));
+ checkT(config.asBool("-", true));
+ checkF(config.asBool("-", false));
+ checkEqu("abc", config.asString("s", "x"));
+ checkEqu("x", config.asString("S", "x"));
+ }
- virtual void run(){
- testAsX();
- testBasic();
+ virtual void run() {
+ testAsX();
+ testBasic();
- }
+ }
};
-void testReConfig(){
- TestReConfig test;
+void testReConfig() {
+ TestReConfig test;
}
*/
class TestReContainer: public ReTest {
public:
- TestReContainer() :
- ReTest("RplContainer"){
- doIt();
- }
+ TestReContainer() :
+ ReTest("RplContainer") {
+ doIt();
+ }
public:
- void testBasic(){
- ReContainer container(256);
- // Rpl&1 09 36[2]cis:!7b Nirwana <0> Y -ab34 A long string with an trailing '0' <0><br>
- container.startBag();
- container.addChar('!');
- container.addInt(123);
- container.addString("Nirwana");
- container.startBag();
- container.addChar('Y');
- container.addInt(-0xab34);
- container.addString("A long string with an trailing '0'");
+ void testBasic() {
+ ReContainer container(256);
+ // Rpl&1 09 36[2]cis:!7b Nirwana <0> Y -ab34 A long string with an trailing '0' <0><br>
+ container.startBag();
+ container.addChar('!');
+ container.addInt(123);
+ container.addString("Nirwana");
+ container.startBag();
+ container.addChar('Y');
+ container.addInt(-0xab34);
+ container.addString("A long string with an trailing '0'");
- QByteArray data = container.getData();
+ QByteArray data = container.getData();
- ReContainer container2(256);
- container2.fill(data);
- checkEqu(2, container2.getCountBags());
- checkEqu('!', container2.nextChar());
- checkEqu(123, container2.nextInt());
- checkEqu("Nirwana", container2.nextString());
- container2.nextBag();
- checkEqu('Y', container2.nextChar());
- checkEqu(-0xab34, container2.nextInt());
- checkEqu("A long string with an trailing '0'", container2.nextString());
+ ReContainer container2(256);
+ container2.fill(data);
+ checkEqu(2, container2.getCountBags());
+ checkEqu('!', container2.nextChar());
+ checkEqu(123, container2.nextInt());
+ checkEqu("Nirwana", container2.nextString());
+ container2.nextBag();
+ checkEqu('Y', container2.nextChar());
+ checkEqu(-0xab34, container2.nextInt());
+ checkEqu("A long string with an trailing '0'", container2.nextString());
- log(("Example: " + data).constData());
- }
+ log(("Example: " + data).constData());
+ }
- virtual void run(){
- testBasic();
- }
+ virtual void run() {
+ testBasic();
+ }
};
-void testReContainer(){
- TestReContainer test;
+void testReContainer() {
+ TestReContainer test;
}
*/
class TestReEnigma: public ReTest {
public:
- TestReEnigma() :
- ReTest("ReEnigma"){
- doIt();
- }
+ TestReEnigma() :
+ ReTest("ReEnigma") {
+ doIt();
+ }
public:
- void testOneCharset(const char* value, const char* charSet,
- const char* expected){
- ReEnigma enigma;
- enigma.addByteSecret(QByteArray("Geheim"));
- enigma.setSeed(0);
- QByteArray encoded = value;
- QByteArray booster;
- enigma.encode(encoded.data(), encoded.length(), charSet, booster);
- //printString(encoded.constData());
- QByteArray decoded = encoded;
- enigma.setSeed(0);
- enigma.decode(decoded.data(), decoded.length(), charSet, booster);
- checkEqu(value, decoded.constData());
- checkEqu(expected, encoded);
- }
+ void testOneCharset(const char* value, const char* charSet,
+ const char* expected) {
+ ReEnigma enigma;
+ enigma.addByteSecret(QByteArray("Geheim"));
+ enigma.setSeed(0);
+ QByteArray encoded = value;
+ QByteArray booster;
+ enigma.encode(encoded.data(), encoded.length(), charSet, booster);
+ //printString(encoded.constData());
+ QByteArray decoded = encoded;
+ enigma.setSeed(0);
+ enigma.decode(decoded.data(), decoded.length(), charSet, booster);
+ checkEqu(value, decoded.constData());
+ checkEqu(expected, encoded);
+ }
- void printCharSets(){
- QByteArray value;
- value.reserve(256);
- unsigned char cc;
- for (cc = ' '; cc <= 127; cc++){
- if (cc == '"' || cc == '\\')
- value.append('\\');
- value.append(cc);
- }
- printf("%s\n", value.constData());
- value.resize(0);
- for (cc = 128; cc >= 128; cc++){
- char buf[10];
- if (cc % 32 == 0)
- value.append("\n");
- sprintf(buf, "\\x%02x", cc);
- value.append(buf);
- }
- printf("%s\n", value.constData());
- }
- void printString(const char* value){
- QByteArray v;
- unsigned char cc;
- while ((cc = (unsigned char) *value++) != 0){
- if (cc == '\\' || cc == '"'){
- v.append('\\');
- v.append(cc);
- }else if (cc >= 127){
- char buffer[10];
- sprintf(buffer, "\\x%02x", cc);
- v.append(buffer);
- }else{
- v.append(cc);
- }
- }
- printf("%s\n", v.constData());
- }
- void testOneBytes(const char* bytes){
- ReEnigma enigma;
- enigma.addByteSecret("Hello World");
- enigma.setSeed(0x1234);
+ void printCharSets() {
+ QByteArray value;
+ value.reserve(256);
+ unsigned char cc;
+ for (cc = ' '; cc <= 127; cc++) {
+ if (cc == '"' || cc == '\\')
+ value.append('\\');
+ value.append(cc);
+ }
+ printf("%s\n", value.constData());
+ value.resize(0);
+ for (cc = 128; cc >= 128; cc++) {
+ char buf[10];
+ if (cc % 32 == 0)
+ value.append("\n");
+ sprintf(buf, "\\x%02x", cc);
+ value.append(buf);
+ }
+ printf("%s\n", value.constData());
+ }
+ void printString(const char* value) {
+ QByteArray v;
+ unsigned char cc;
+ while ((cc = (unsigned char) *value++) != 0) {
+ if (cc == '\\' || cc == '"') {
+ v.append('\\');
+ v.append(cc);
+ } else if (cc >= 127) {
+ char buffer[10];
+ sprintf(buffer, "\\x%02x", cc);
+ v.append(buffer);
+ } else {
+ v.append(cc);
+ }
+ }
+ printf("%s\n", v.constData());
+ }
+ void testOneBytes(const char* bytes) {
+ ReEnigma enigma;
+ enigma.addByteSecret("Hello World");
+ enigma.setSeed(0x1234);
- QByteArray encoded(bytes);
- enigma.change(encoded);
+ QByteArray encoded(bytes);
+ enigma.change(encoded);
- enigma.setSeed(0x1234);
- QByteArray decoded(encoded);
- enigma.change(decoded);
- checkEqu(bytes, decoded);
- }
+ enigma.setSeed(0x1234);
+ QByteArray decoded(encoded);
+ enigma.change(decoded);
+ checkEqu(bytes, decoded);
+ }
- void testBytes(){
- testOneBytes("abcdefg");
- testOneBytes(
- "01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
- }
+ void testBytes() {
+ testOneBytes("abcdefg");
+ testOneBytes(
+ "01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ }
- void testCharSet(){
- //testOneCharset("&()[]{}Weiß der Geier/Kuckuck?", ReEnigma::SET_32_255, "2Kc\x9a\xfeQ\xd7\xa84sx)*\xfb\xd2z\xf4\"W\xb0\xee\xb0\xd1\x84\xace\xf8_u*T");
- testOneCharset("\\Weiß der Geier/Kuckuck?", ReEnigma::SET_32_127,
- "(Z?hßaZ_#/QZ+Oi|SI^=<,)A");
- testOneCharset("01234567890abcdef", ReEnigma::SET_HEXDIGITS,
- "c4c25b08735c53a63");
- testOneCharset("data$1%3.^~", ReEnigma::SET_FILENAME, "^voazo-n%$b");
- testOneCharset("Weiß der Geier!", ReEnigma::SET_ALPHANUM,
- "weyß BCk 19NoO!");
- testOneCharset("12345678901234567890", ReEnigma::SET_DECIMALS,
- "97394833084815683977");
- testOneCharset("000000000000000000000000000", ReEnigma::SET_DECIMALS,
- "850592651836811261879625929");
- }
+ void testCharSet() {
+ //testOneCharset("&()[]{}Weiß der Geier/Kuckuck?", ReEnigma::SET_32_255, "2Kc\x9a\xfeQ\xd7\xa84sx)*\xfb\xd2z\xf4\"W\xb0\xee\xb0\xd1\x84\xace\xf8_u*T");
+ testOneCharset("\\Weiß der Geier/Kuckuck?", ReEnigma::SET_32_127,
+ "(Z?hßaZ_#/QZ+Oi|SI^=<,)A");
+ testOneCharset("01234567890abcdef", ReEnigma::SET_HEXDIGITS,
+ "c4c25b08735c53a63");
+ testOneCharset("data$1%3.^~", ReEnigma::SET_FILENAME, "^voazo-n%$b");
+ testOneCharset("Weiß der Geier!", ReEnigma::SET_ALPHANUM,
+ "weyß BCk 19NoO!");
+ testOneCharset("12345678901234567890", ReEnigma::SET_DECIMALS,
+ "97394833084815683977");
+ testOneCharset("000000000000000000000000000", ReEnigma::SET_DECIMALS,
+ "850592651836811261879625929");
+ }
- virtual void run(){
- testBytes();
- testCharSet();
- }
+ virtual void run() {
+ testBytes();
+ testCharSet();
+ }
};
-void testReEnigma(){
- TestReEnigma test;
+void testReEnigma() {
+ TestReEnigma test;
}
class TestReException: public ReTest {
public:
- TestReException() :
- ReTest("RplException"){
- doIt();
- }
+ TestReException() :
+ ReTest("RplException") {
+ doIt();
+ }
public:
- void testBasic(){
- try{
- throw ReException("simple");
- checkF(true);
- } catch (ReException exc){
- checkEqu("simple", exc.getMessage().constData());
- }
- try{
- throw ReException("String: %s and int %d", "Hi", -333);
- checkF(true);
- } catch (ReException exc){
- checkEqu("String: Hi and int -333", exc.getMessage().constData());
- }
- try{
- throw ReException(LOG_INFO, 1234, &m_memoryLogger,
- "String: %s and int %d", "Hi", -333);
- checkF(true);
- } catch (ReException exc){
- checkT(logContains("^ .*\\(1234\\): String: Hi and int -333"));
- }
- log("ok");
- }
- virtual void run(){
- testBasic();
- }
+ void testBasic() {
+ try {
+ throw ReException("simple");
+ checkF(true);
+ } catch (ReException exc) {
+ checkEqu("simple", exc.getMessage().constData());
+ }
+ try {
+ throw ReException("String: %s and int %d", "Hi", -333);
+ checkF(true);
+ } catch (ReException exc) {
+ checkEqu("String: Hi and int -333", exc.getMessage().constData());
+ }
+ try {
+ throw ReException(LOG_INFO, 1234, &m_memoryLogger,
+ "String: %s and int %d", "Hi", -333);
+ checkF(true);
+ } catch (ReException exc) {
+ checkT(logContains("^ .*\\(1234\\): String: Hi and int -333"));
+ }
+ log("ok");
+ }
+ virtual void run() {
+ testBasic();
+ }
};
-void testReException(){
- TestReException test;
+void testReException() {
+ TestReException test;
}
class TestReFile: public ReTest {
public:
- TestReFile() :
- ReTest("ReFile"){
- doIt();
- }
+ TestReFile() :
+ ReTest("ReFile") {
+ doIt();
+ }
public:
- void testBasic(){
- QByteArray fn(ReFile::tempFile("big.txt", NULL, true));
- const char* content =
- "123456789 123456789 123456789 123456789 123456789\n";
- int contentLength = strlen(content);
- ReFile::writeToFile(fn.constData(), content);
- ReFile file(fn.constData());
- int size = 4;
- file.setBlocksize(2 * size);
- int length = -2;
- char* ptr = file.remap(0, size, length);
- checkNN(ptr);
- checkEqu(4, length);
- checkEqu(0,
- strncmp(content, reinterpret_cast <const char*>(ptr), length));
- int part = size / 2;
- ptr = file.remap(contentLength - part, size, length);
- checkEqu(size / 2, length);
- checkEqu(content + contentLength - part,
- reinterpret_cast <const char*>(ptr));
- for (int ix = 0; ix < contentLength - size; ix++){
- ptr = file.remap(ix, size, length);
- checkNN(ptr);
- checkEqu(length, size);
- checkEqu(0,
- strncmp(content + ix, reinterpret_cast <const char*>(ptr), length));
- }
-
- }
- void testTempFile(){
- QByteArray fn(ReFile::tempFile("node.txt", "subdir", true));
- QByteArray content;
- ReFile::writeToFile(fn, "123");
- struct stat info;
- checkEqu(0, stat(fn.constData(), &info));
- checkEqu(3, (int ) info.st_size);
- ReFile::tempFile("node.txt", "subdir", true);
- checkEqu(-1, stat(fn.constData(), &info));
- }
- void testTempDir(){
- QByteArray dir(ReFile::tempDir("subdir", "curefile", false));
- checkT(dir.endsWith("subdir"));
- checkT(dir.endsWith("curefile/subdir"));
- struct stat info;
- checkEqu(0, stat(dir, &info));
- checkT(S_ISDIR(info.st_mode));
- }
- void testWriteRead(){
- QByteArray fn(ReFile::tempFile("node.txt", "subdir", true));
- ReFile::writeToFile(fn, "123");
- QByteArray content;
- ReFile::readFromFile(fn, content);
- checkEqu("123", content);
- ReFile::writeToFile(fn, "abcdef", 2);
- ReFile::readFromFile(fn, content);
- checkEqu("ab", content);
- }
- void countLinesReFile(const char* filename, int64_t blocksize){
- clock_t start = clock();
- int lines = 0;
- { // enforce the destructor inside measurement:
- ReFile file(filename);
- file.setBlocksize(blocksize);
- int length;
- while (file.nextLine(length)){
- lines++;
- }
- }
- double duration = double(clock() - start) / CLOCKS_PER_SEC;
- printf("linecount (ReFile, %d kB): %d lines %.3f sec\n",
- int(blocksize / 1024), lines, duration);
-
- }
- void countLinesFopen(const char* filename){
- clock_t start = clock();
- FILE* fp = fopen(filename, "r");
- int lines = 0;
- char line[64000];
- if (fp != NULL){
- while (fgets(line, sizeof line, fp) != NULL)
- lines++;
- }
- fclose(fp);
- double duration = double(clock() - start) / CLOCKS_PER_SEC;
- printf("linecount (fopen): %d lines %.3f sec\n", lines, duration);
-
- }
-
- void testPerformance(){
- const char* fn = "/opt/bench/long_html.txt";
- if (QFileInfo(fn).exists()){
- countLinesReFile(fn, 60 * 1024 * 1024);
- countLinesFopen(fn);
- countLinesReFile(fn, 100 * 1024);
- countLinesReFile(fn, 1024 * 1024);
- countLinesReFile(fn, 10 * 1024 * 1024);
- }
- }
- void testWritableFile(){
- QByteArray fn(ReFile::tempFile("test.txt", "cuReFile", true));
- ReFile::writeToFile(fn, "123\nabc\nxyz");
- ReFile file(fn, false);
- checkEqu(3, file.lineCount());
- checkEqu("123\n", file.lineAt(0));
- checkEqu("abc\n", file.lineAt(1));
- checkEqu("xyz", file.lineAt(2));
- QByteArray fn2(ReFile::tempFile("test2.txt", "cuReFile", true));
- file.write(fn2);
- file.close();
- checkEqu(0, file.lineCount());
- ReFile file2(fn2, false);
- checkEqu(3, file2.lineCount());
- checkEqu("123", file2.lineAt(0));
- checkEqu("abc", file2.lineAt(1));
- checkEqu("xyz", file2.lineAt(2));
- }
- void testReLinesInsert(){
- ReLines lines;
- // multiple lines in an empty list:
- lines.insertText(0, 0, "123\nabcdefg\nABCDE");
- checkEqu(3, lines.lineCount());
- checkEqu("123", lines.lineAt(0));
- checkEqu("abcdefg", lines.lineAt(1));
- checkEqu("ABCDE", lines.lineAt(2));
-
- // simple string without newlines:
- lines.insertText(1, 2, "xx");
- checkEqu(3, lines.lineCount());
- checkEqu("123", lines.lineAt(0));
- checkEqu("abxxcdefg", lines.lineAt(1));
- checkEqu("ABCDE", lines.lineAt(2));
-
- // no insertText because of wrong parameters:
- lines.insertText(4, 99, "Y");
- checkEqu(3, lines.lineCount());
- checkEqu("123", lines.lineAt(0));
- checkEqu("abxxcdefg", lines.lineAt(1));
- checkEqu("ABCDE", lines.lineAt(2));
-
- // an empty line
- lines.insertText(1, 0, "\n");
- checkEqu(4, lines.lineCount());
- checkEqu("123", lines.lineAt(0));
- checkEqu("", lines.lineAt(1));
- checkEqu("abxxcdefg", lines.lineAt(2));
- checkEqu("ABCDE", lines.lineAt(3));
-
- // 2 lines with text before and after insertText point:
- lines.insertText(2, 5, "Z\nNewline\nY");
- checkEqu(6, lines.lineCount());
- checkEqu("123", lines.lineAt(0));
- checkEqu("", lines.lineAt(1));
- checkEqu("abxxcZ", lines.lineAt(2));
- checkEqu("Newline", lines.lineAt(3));
- checkEqu("Ydefg", lines.lineAt(4));
- checkEqu("ABCDE", lines.lineAt(5));
- }
- void testReLinesRemove(){
- ReLines lines;
- lines.insertText(0, 0, "123\nabcdefg\nABCDE");
- checkEqu(3, lines.lineCount());
- checkEqu("123", lines.lineAt(0));
- checkEqu("abcdefg", lines.lineAt(1));
- checkEqu("ABCDE", lines.lineAt(2));
-
- // at line start:
- lines.remove(0, 0, 2);
- checkEqu(3, lines.lineCount());
- checkEqu("3", lines.lineAt(0));
- checkEqu("abcdefg", lines.lineAt(1));
- checkEqu("ABCDE", lines.lineAt(2));
-
- // at line end (precisely):
- lines.remove(1, 5, 2);
- checkEqu(3, lines.lineCount());
- checkEqu("3", lines.lineAt(0));
- checkEqu("abcde", lines.lineAt(1));
- checkEqu("ABCDE", lines.lineAt(2));
-
- // at line end (too many chars):
- lines.remove(1, 3, 99);
- checkEqu(3, lines.lineCount());
- checkEqu("3", lines.lineAt(0));
- checkEqu("abc", lines.lineAt(1));
- checkEqu("ABCDE", lines.lineAt(2));
-
- // no remove because of wrong arguments:
- lines.remove(-1, 3, 1);
- lines.remove(0, 1, 1);
- lines.remove(3, 1, 1);
- checkEqu(3, lines.lineCount());
- checkEqu("3", lines.lineAt(0));
- checkEqu("abc", lines.lineAt(1));
- checkEqu("ABCDE", lines.lineAt(2));
-
- }
-
- virtual void run(){
- testReLinesInsert();
- testReLinesRemove();
- testWritableFile();
- testPerformance();
- testBasic();
- testTempDir();
- testTempFile();
- testWriteRead();
- }
+ void testBasic() {
+ QByteArray fn(ReFile::tempFile("big.txt", NULL, true));
+ const char* content =
+ "123456789 123456789 123456789 123456789 123456789\n";
+ int contentLength = strlen(content);
+ ReFile::writeToFile(fn.constData(), content);
+ ReFile file(fn.constData());
+ int size = 4;
+ file.setBlocksize(2 * size);
+ int length = -2;
+ char* ptr = file.remap(0, size, length);
+ checkNN(ptr);
+ checkEqu(4, length);
+ checkEqu(0,
+ strncmp(content, reinterpret_cast<const char*>(ptr), length));
+ int part = size / 2;
+ ptr = file.remap(contentLength - part, size, length);
+ checkEqu(size / 2, length);
+ checkEqu(content + contentLength - part,
+ reinterpret_cast<const char*>(ptr));
+ for (int ix = 0; ix < contentLength - size; ix++) {
+ ptr = file.remap(ix, size, length);
+ checkNN(ptr);
+ checkEqu(length, size);
+ checkEqu(0,
+ strncmp(content + ix, reinterpret_cast<const char*>(ptr),
+ length));
+ }
+
+ }
+ void testTempFile() {
+ QByteArray fn(ReFile::tempFile("node.txt", "subdir", true));
+ QByteArray content;
+ ReFile::writeToFile(fn, "123");
+ struct stat info;
+ checkEqu(0, stat(fn.constData(), &info));
+ checkEqu(3, (int ) info.st_size);
+ ReFile::tempFile("node.txt", "subdir", true);
+ checkEqu(-1, stat(fn.constData(), &info));
+ }
+ void testTempDir() {
+ QByteArray dir(ReFile::tempDir("subdir", "curefile", false));
+ checkT(dir.endsWith("subdir"));
+ checkT(dir.endsWith("curefile/subdir"));
+ struct stat info;
+ checkEqu(0, stat(dir, &info));
+ checkT(S_ISDIR(info.st_mode));
+ }
+ void testWriteRead() {
+ QByteArray fn(ReFile::tempFile("node.txt", "subdir", true));
+ ReFile::writeToFile(fn, "123");
+ QByteArray content;
+ ReFile::readFromFile(fn, content);
+ checkEqu("123", content);
+ ReFile::writeToFile(fn, "abcdef", 2);
+ ReFile::readFromFile(fn, content);
+ checkEqu("ab", content);
+ }
+ void countLinesReFile(const char* filename, int64_t blocksize) {
+ clock_t start = clock();
+ int lines = 0;
+ { // enforce the destructor inside measurement:
+ ReFile file(filename);
+ file.setBlocksize(blocksize);
+ int length;
+ while (file.nextLine(length)) {
+ lines++;
+ }
+ }
+ double duration = double(clock() - start) / CLOCKS_PER_SEC;
+ printf("linecount (ReFile, %d kB): %d lines %.3f sec\n",
+ int(blocksize / 1024), lines, duration);
+
+ }
+ void countLinesFopen(const char* filename) {
+ clock_t start = clock();
+ FILE* fp = fopen(filename, "r");
+ int lines = 0;
+ char line[64000];
+ if (fp != NULL) {
+ while (fgets(line, sizeof line, fp) != NULL)
+ lines++;
+ }
+ fclose(fp);
+ double duration = double(clock() - start) / CLOCKS_PER_SEC;
+ printf("linecount (fopen): %d lines %.3f sec\n", lines, duration);
+
+ }
+
+ void testPerformance() {
+ const char* fn = "/opt/bench/long_html.txt";
+ if (QFileInfo(fn).exists()) {
+ countLinesReFile(fn, 60 * 1024 * 1024);
+ countLinesFopen(fn);
+ countLinesReFile(fn, 100 * 1024);
+ countLinesReFile(fn, 1024 * 1024);
+ countLinesReFile(fn, 10 * 1024 * 1024);
+ }
+ }
+ void testWritableFile() {
+ QByteArray fn(ReFile::tempFile("test.txt", "cuReFile", true));
+ ReFile::writeToFile(fn, "123\nabc\nxyz");
+ ReFile file(fn, false);
+ checkEqu(3, file.lineCount());
+ checkEqu("123\n", file.lineAt(0));
+ checkEqu("abc\n", file.lineAt(1));
+ checkEqu("xyz", file.lineAt(2));
+ QByteArray fn2(ReFile::tempFile("test2.txt", "cuReFile", true));
+ file.write(fn2);
+ file.close();
+ checkEqu(0, file.lineCount());
+ ReFile file2(fn2, false);
+ checkEqu(3, file2.lineCount());
+ checkEqu("123", file2.lineAt(0));
+ checkEqu("abc", file2.lineAt(1));
+ checkEqu("xyz", file2.lineAt(2));
+ }
+ void testReLinesInsert() {
+ ReLines lines;
+ // multiple lines in an empty list:
+ lines.insertText(0, 0, "123\nabcdefg\nABCDE");
+ checkEqu(3, lines.lineCount());
+ checkEqu("123", lines.lineAt(0));
+ checkEqu("abcdefg", lines.lineAt(1));
+ checkEqu("ABCDE", lines.lineAt(2));
+
+ // simple string without newlines:
+ lines.insertText(1, 2, "xx");
+ checkEqu(3, lines.lineCount());
+ checkEqu("123", lines.lineAt(0));
+ checkEqu("abxxcdefg", lines.lineAt(1));
+ checkEqu("ABCDE", lines.lineAt(2));
+
+ // no insertText because of wrong parameters:
+ lines.insertText(4, 99, "Y");
+ checkEqu(3, lines.lineCount());
+ checkEqu("123", lines.lineAt(0));
+ checkEqu("abxxcdefg", lines.lineAt(1));
+ checkEqu("ABCDE", lines.lineAt(2));
+
+ // an empty line
+ lines.insertText(1, 0, "\n");
+ checkEqu(4, lines.lineCount());
+ checkEqu("123", lines.lineAt(0));
+ checkEqu("", lines.lineAt(1));
+ checkEqu("abxxcdefg", lines.lineAt(2));
+ checkEqu("ABCDE", lines.lineAt(3));
+
+ // 2 lines with text before and after insertText point:
+ lines.insertText(2, 5, "Z\nNewline\nY");
+ checkEqu(6, lines.lineCount());
+ checkEqu("123", lines.lineAt(0));
+ checkEqu("", lines.lineAt(1));
+ checkEqu("abxxcZ", lines.lineAt(2));
+ checkEqu("Newline", lines.lineAt(3));
+ checkEqu("Ydefg", lines.lineAt(4));
+ checkEqu("ABCDE", lines.lineAt(5));
+ }
+ void testReLinesRemove() {
+ ReLines lines;
+ lines.insertText(0, 0, "123\nabcdefg\nABCDE");
+ checkEqu(3, lines.lineCount());
+ checkEqu("123", lines.lineAt(0));
+ checkEqu("abcdefg", lines.lineAt(1));
+ checkEqu("ABCDE", lines.lineAt(2));
+
+ // at line start:
+ lines.remove(0, 0, 2);
+ checkEqu(3, lines.lineCount());
+ checkEqu("3", lines.lineAt(0));
+ checkEqu("abcdefg", lines.lineAt(1));
+ checkEqu("ABCDE", lines.lineAt(2));
+
+ // at line end (precisely):
+ lines.remove(1, 5, 2);
+ checkEqu(3, lines.lineCount());
+ checkEqu("3", lines.lineAt(0));
+ checkEqu("abcde", lines.lineAt(1));
+ checkEqu("ABCDE", lines.lineAt(2));
+
+ // at line end (too many chars):
+ lines.remove(1, 3, 99);
+ checkEqu(3, lines.lineCount());
+ checkEqu("3", lines.lineAt(0));
+ checkEqu("abc", lines.lineAt(1));
+ checkEqu("ABCDE", lines.lineAt(2));
+
+ // no remove because of wrong arguments:
+ lines.remove(-1, 3, 1);
+ lines.remove(0, 1, 1);
+ lines.remove(3, 1, 1);
+ checkEqu(3, lines.lineCount());
+ checkEqu("3", lines.lineAt(0));
+ checkEqu("abc", lines.lineAt(1));
+ checkEqu("ABCDE", lines.lineAt(2));
+
+ }
+
+ virtual void run() {
+ testReLinesInsert();
+ testReLinesRemove();
+ testWritableFile();
+ testPerformance();
+ testBasic();
+ testTempDir();
+ testTempFile();
+ testWriteRead();
+ }
};
-void testReFile(){
- TestReFile test;
+void testReFile() {
+ TestReFile test;
}
class TestRplLexer: public ReTest, public ReToken {
public:
- TestRplLexer() :
- ReTest("ReLexer"), ReToken(TOKEN_ID){
- }
+ TestRplLexer() :
+ ReTest("ReLexer"),
+ ReToken(TOKEN_ID) {
+ }
public:
- void testRplToken(){
- // test constructor values:
- checkEqu(TOKEN_ID, tokenType());
- checkEqu(0, m_value.m_id);
- checkT(m_string.isEmpty());
- checkT(m_printableString.isEmpty());
+ void testRplToken() {
+ // test constructor values:
+ checkEqu(TOKEN_ID, tokenType());
+ checkEqu(0, m_value.m_id);
+ checkT(m_string.isEmpty());
+ checkT(m_printableString.isEmpty());
- m_value.m_id = 7422;
- checkEqu(7422, ReToken::id());
- m_string = "Wow!";
- checkEqu("Wow!", ReToken::toString());
- m_printableString = "GooGoo";
- checkEqu("GooGoo", rawString());
- m_tokenType = TOKEN_NUMBER;
- checkEqu(TOKEN_NUMBER, tokenType());
+ m_value.m_id = 7422;
+ checkEqu(7422, ReToken::id());
+ m_string = "Wow!";
+ checkEqu("Wow!", ReToken::toString());
+ m_printableString = "GooGoo";
+ checkEqu("GooGoo", rawString());
+ m_tokenType = TOKEN_NUMBER;
+ checkEqu(TOKEN_NUMBER, tokenType());
- clear();
- checkEqu(TOKEN_UNDEF, tokenType());
- checkEqu(0, m_value.m_id);
- checkT(m_string.isEmpty());
- checkT(m_printableString.isEmpty());
+ clear();
+ checkEqu(TOKEN_UNDEF, tokenType());
+ checkEqu(0, m_value.m_id);
+ checkT(m_string.isEmpty());
+ checkT(m_printableString.isEmpty());
- m_value.m_integer = 773322;
- checkEqu(773322, asInteger());
- m_value.m_real = 0.25;
- checkEqu(0.25, asReal());
- }
+ m_value.m_integer = 773322;
+ checkEqu(773322, asInteger());
+ m_value.m_real = 0.25;
+ checkEqu(0.25, asReal());
+ }
- ReToken* checkToken(ReToken* token, RplTokenType type, int id = 0,
- const char* string = NULL){
- checkEqu(type, token->tokenType());
- if (id != 0)
- checkEqu(id, token->id());
- if (string != NULL)
- checkEqu(string, token->toString());
- return token;
- }
- enum {
- KEY_UNDEF, KEY_IF, KEY_THEN, KEY_ELSE, KEY_FI
- };
+ ReToken* checkToken(ReToken* token, RplTokenType type, int id = 0,
+ const char* string = NULL) {
+ checkEqu(type, token->tokenType());
+ if (id != 0)
+ checkEqu(id, token->id());
+ if (string != NULL)
+ checkEqu(string, token->toString());
+ return token;
+ }
+ enum {
+ KEY_UNDEF,
+ KEY_IF,
+ KEY_THEN,
+ KEY_ELSE,
+ KEY_FI
+ };
# define KEYWORDS "if then else fi"
- enum {
- OP_UNDEF,
- OP_PLUS,
- OP_TIMES,
- OP_DIV,
- OP_GT,
- OP_LT,
- OP_GE,
- OP_LE,
- OP_EQ,
- OP_ASSIGN,
- OP_PLUS_ASSIGN,
- OP_DIV_ASSIGN,
- OP_TIMES_ASSIGN
- };
+ enum {
+ OP_UNDEF,
+ OP_PLUS,
+ OP_TIMES,
+ OP_DIV,
+ OP_GT,
+ OP_LT,
+ OP_GE,
+ OP_LE,
+ OP_EQ,
+ OP_ASSIGN,
+ OP_PLUS_ASSIGN,
+ OP_DIV_ASSIGN,
+ OP_TIMES_ASSIGN
+ };
# define OPERATORS "+\n* /\n> < >= <= ==\n= += /= *="
- enum {
- COMMENT_UNDEF, COMMENT_1, COMMENT_MULTILINE, COMMENT_2
- };
+ enum {
+ COMMENT_UNDEF,
+ COMMENT_1,
+ COMMENT_MULTILINE,
+ COMMENT_2
+ };
# define COMMENTS "/* */ // \n"
- void testSpace(){
- ReSource source;
- ReStringReader reader(source);
+ void testSpace() {
+ ReSource source;
+ ReStringReader reader(source);
# define BLANKS1 "\t\t \n"
# define BLANKS2 " \n"
- reader.addSource("<main>", BLANKS1 BLANKS2);
- source.addReader(&reader);
- ReLexer lex(&source, KEYWORDS, OPERATORS, "=", COMMENTS, "A-Za-z_",
- "A-Za-z0-9_", ReLexer::NUMTYPE_DECIMAL, ReLexer::SF_TICK,
- ReLexer::STORE_ALL);
- checkToken(lex.nextToken(), TOKEN_SPACE, 0, BLANKS1);
- checkToken(lex.nextToken(), TOKEN_SPACE, 0, BLANKS2);
- }
- void testNumeric(){
- ReSource source;
- ReStringReader reader(source);
- const char* blanks = "321 0x73 7.8e+5";
- reader.addSource("<main>", blanks);
- source.addReader(&reader);
- ReLexer lex(&source, KEYWORDS, OPERATORS, "=", COMMENTS, "A-Za-z_",
- "A-Za-z0-9_", ReLexer::NUMTYPE_ALL, ReLexer::SF_TICK,
- ReLexer::STORE_ALL);
- ReToken* token = checkToken(lex.nextToken(), TOKEN_NUMBER);
- checkEqu(321, token->asInteger());
- token = checkToken(lex.nextNonSpaceToken(), TOKEN_NUMBER);
- checkEqu(0x73, token->asInteger());
- token = checkToken(lex.nextNonSpaceToken(), TOKEN_REAL);
- checkEqu(7.8e+5, token->asReal());
- }
+ reader.addSource("<main>", BLANKS1 BLANKS2);
+ source.addReader(&reader);
+ ReLexer lex(&source, KEYWORDS, OPERATORS, "=", COMMENTS, "A-Za-z_",
+ "A-Za-z0-9_", ReLexer::NUMTYPE_DECIMAL, ReLexer::SF_TICK,
+ ReLexer::STORE_ALL);
+ checkToken(lex.nextToken(), TOKEN_SPACE, 0, BLANKS1);
+ checkToken(lex.nextToken(), TOKEN_SPACE, 0, BLANKS2);
+ }
+ void testNumeric() {
+ ReSource source;
+ ReStringReader reader(source);
+ const char* blanks = "321 0x73 7.8e+5";
+ reader.addSource("<main>", blanks);
+ source.addReader(&reader);
+ ReLexer lex(&source, KEYWORDS, OPERATORS, "=", COMMENTS, "A-Za-z_",
+ "A-Za-z0-9_", ReLexer::NUMTYPE_ALL, ReLexer::SF_TICK,
+ ReLexer::STORE_ALL);
+ ReToken* token = checkToken(lex.nextToken(), TOKEN_NUMBER);
+ checkEqu(321, token->asInteger());
+ token = checkToken(lex.nextNonSpaceToken(), TOKEN_NUMBER);
+ checkEqu(0x73, token->asInteger());
+ token = checkToken(lex.nextNonSpaceToken(), TOKEN_REAL);
+ checkEqu(7.8e+5, token->asReal());
+ }
- void testOperators(){
- ReSource source;
- ReStringReader reader(source);
- const char* ops = "<< < <<< <= == = ( ) [ ]";
- reader.addSource("<main>", ops);
- source.addReader(&reader);
- enum {
- UNDEF,
- SHIFT,
- LT,
- SHIFT2,
- LE,
- EQ,
- ASSIGN,
- LPARENT,
- RPARENT,
- LBRACKET,
- RBRACKET
- };
- ReLexer lex(&source, KEYWORDS, ops, "=", COMMENTS, "A-Za-z_",
- "A-Za-z0-9_", ReLexer::NUMTYPE_ALL, ReLexer::SF_TICK,
- ReLexer::STORE_ALL);
- checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, SHIFT);
- checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, LT);
- checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, SHIFT2);
- checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, LE);
- checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, EQ);
- checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, ASSIGN);
- checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, LPARENT);
- checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, RPARENT);
- checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, LBRACKET);
- checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, RBRACKET);
- checkToken(lex.nextNonSpaceToken(), TOKEN_END_OF_SOURCE);
- reader.addSource("<buffer2>", "(([[");
- lex.startUnit("<buffer2>");
- checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, LPARENT);
- checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, LPARENT);
- checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, LBRACKET);
- checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, LBRACKET);
- checkToken(lex.nextNonSpaceToken(), TOKEN_END_OF_SOURCE);
- }
+ void testOperators() {
+ ReSource source;
+ ReStringReader reader(source);
+ const char* ops = "<< < <<< <= == = ( ) [ ]";
+ reader.addSource("<main>", ops);
+ source.addReader(&reader);
+ enum {
+ UNDEF,
+ SHIFT,
+ LT,
+ SHIFT2,
+ LE,
+ EQ,
+ ASSIGN,
+ LPARENT,
+ RPARENT,
+ LBRACKET,
+ RBRACKET
+ };
+ ReLexer lex(&source, KEYWORDS, ops, "=", COMMENTS, "A-Za-z_",
+ "A-Za-z0-9_", ReLexer::NUMTYPE_ALL, ReLexer::SF_TICK,
+ ReLexer::STORE_ALL);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, SHIFT);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, LT);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, SHIFT2);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, LE);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, EQ);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, ASSIGN);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, LPARENT);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, RPARENT);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, LBRACKET);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, RBRACKET);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_END_OF_SOURCE);
+ reader.addSource("<buffer2>", "(([[");
+ lex.startUnit("<buffer2>");
+ checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, LPARENT);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, LPARENT);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, LBRACKET);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_OPERATOR, LBRACKET);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_END_OF_SOURCE);
+ }
- void testComments(){
- ReSource source;
- ReStringReader reader(source);
+ void testComments() {
+ ReSource source;
+ ReStringReader reader(source);
- reader.addSource("<main>", "/**/9//\n8/***/7// wow\n/*\n*\n*\n**/");
- source.addReader(&reader);
+ reader.addSource("<main>", "/**/9//\n8/***/7// wow\n/*\n*\n*\n**/");
+ source.addReader(&reader);
- enum {
- COMMENT_UNDEF, COMMENT_MULTILINE, COMMENT_1
- };
- ReLexer lex(&source, KEYWORDS, OPERATORS, "=", COMMENTS, "A-Za-z_",
- "A-Za-z0-9_", ReLexer::NUMTYPE_ALL, ReLexer::SF_LIKE_C,
- ReLexer::STORE_ALL);
- checkToken(lex.nextToken(), TOKEN_COMMENT_START, COMMENT_MULTILINE,
- "/**/");
- checkToken(lex.nextToken(), TOKEN_NUMBER);
- checkToken(lex.nextToken(), TOKEN_COMMENT_START, COMMENT_1, "//\n");
- checkToken(lex.nextToken(), TOKEN_NUMBER);
- checkToken(lex.nextToken(), TOKEN_COMMENT_START, COMMENT_MULTILINE,
- "/***/");
- checkToken(lex.nextToken(), TOKEN_NUMBER);
- checkToken(lex.nextToken(), TOKEN_COMMENT_START, COMMENT_1, "// wow\n");
- checkToken(lex.nextToken(), TOKEN_COMMENT_START, COMMENT_MULTILINE,
- "/*\n*\n*\n**/");
- }
- void testStrings(){
- ReSource source;
- ReStringReader reader(source);
+ enum {
+ COMMENT_UNDEF,
+ COMMENT_MULTILINE,
+ COMMENT_1
+ };
+ ReLexer lex(&source, KEYWORDS, OPERATORS, "=", COMMENTS, "A-Za-z_",
+ "A-Za-z0-9_", ReLexer::NUMTYPE_ALL, ReLexer::SF_LIKE_C,
+ ReLexer::STORE_ALL);
+ checkToken(lex.nextToken(), TOKEN_COMMENT_START, COMMENT_MULTILINE,
+ "/**/");
+ checkToken(lex.nextToken(), TOKEN_NUMBER);
+ checkToken(lex.nextToken(), TOKEN_COMMENT_START, COMMENT_1, "//\n");
+ checkToken(lex.nextToken(), TOKEN_NUMBER);
+ checkToken(lex.nextToken(), TOKEN_COMMENT_START, COMMENT_MULTILINE,
+ "/***/");
+ checkToken(lex.nextToken(), TOKEN_NUMBER);
+ checkToken(lex.nextToken(), TOKEN_COMMENT_START, COMMENT_1, "// wow\n");
+ checkToken(lex.nextToken(), TOKEN_COMMENT_START, COMMENT_MULTILINE,
+ "/*\n*\n*\n**/");
+ }
+ void testStrings() {
+ ReSource source;
+ ReStringReader reader(source);
- reader.addSource("<main>", "\"abc\\t\\r\\n\\a\\v\"'1\\x9Z\\x21A\\X9'");
- source.addReader(&reader);
+ reader.addSource("<main>", "\"abc\\t\\r\\n\\a\\v\"'1\\x9Z\\x21A\\X9'");
+ source.addReader(&reader);
- ReLexer lex(&source, KEYWORDS, OPERATORS, "=", COMMENTS, "A-Za-z_",
- "A-Za-z0-9_", ReLexer::NUMTYPE_ALL, ReLexer::SF_LIKE_C,
- ReLexer::STORE_ALL);
- checkToken(lex.nextToken(), TOKEN_STRING, '"', "abc\t\r\n\a\v");
- checkToken(lex.nextToken(), TOKEN_STRING, '\'', "1\tZ!A\t");
- }
- void testKeywords(){
- ReSource source;
- ReStringReader reader(source);
+ ReLexer lex(&source, KEYWORDS, OPERATORS, "=", COMMENTS, "A-Za-z_",
+ "A-Za-z0-9_", ReLexer::NUMTYPE_ALL, ReLexer::SF_LIKE_C,
+ ReLexer::STORE_ALL);
+ checkToken(lex.nextToken(), TOKEN_STRING, '"', "abc\t\r\n\a\v");
+ checkToken(lex.nextToken(), TOKEN_STRING, '\'', "1\tZ!A\t");
+ }
+ void testKeywords() {
+ ReSource source;
+ ReStringReader reader(source);
- reader.addSource("<main>", "if\n\tthen else\nfi");
- source.addReader(&reader);
+ reader.addSource("<main>", "if\n\tthen else\nfi");
+ source.addReader(&reader);
- ReLexer lex(&source, KEYWORDS, OPERATORS, "=", COMMENTS, "A-Za-z_",
- "A-Za-z0-9_", ReLexer::NUMTYPE_ALL, ReLexer::SF_LIKE_C,
- ReLexer::STORE_ALL);
- checkToken(lex.nextToken(), TOKEN_KEYWORD, KEY_IF);
- checkToken(lex.nextNonSpaceToken(), TOKEN_KEYWORD, KEY_THEN);
- checkToken(lex.nextNonSpaceToken(), TOKEN_KEYWORD, KEY_ELSE);
- checkToken(lex.nextNonSpaceToken(), TOKEN_KEYWORD, KEY_FI);
- checkToken(lex.nextNonSpaceToken(), TOKEN_END_OF_SOURCE);
- }
+ ReLexer lex(&source, KEYWORDS, OPERATORS, "=", COMMENTS, "A-Za-z_",
+ "A-Za-z0-9_", ReLexer::NUMTYPE_ALL, ReLexer::SF_LIKE_C,
+ ReLexer::STORE_ALL);
+ checkToken(lex.nextToken(), TOKEN_KEYWORD, KEY_IF);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_KEYWORD, KEY_THEN);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_KEYWORD, KEY_ELSE);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_KEYWORD, KEY_FI);
+ checkToken(lex.nextNonSpaceToken(), TOKEN_END_OF_SOURCE);
+ }
- void testIds(){
- ReSource source;
- ReStringReader reader(source);
+ void testIds() {
+ ReSource source;
+ ReStringReader reader(source);
- reader.addSource("<main>", "i\n\tifs\n"
- "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
- source.addReader(&reader);
+ reader.addSource("<main>", "i\n\tifs\n"
+ "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+ source.addReader(&reader);
- ReLexer lex(&source, KEYWORDS, OPERATORS, "=", COMMENTS, "A-Za-z_",
- "A-Za-z0-9_", ReLexer::NUMTYPE_ALL, ReLexer::SF_LIKE_C,
- ReLexer::STORE_ALL);
- checkToken(lex.nextToken(), TOKEN_ID, 0, "i");
- checkToken(lex.nextNonSpaceToken(), TOKEN_ID, 0, "ifs");
- checkToken(lex.nextNonSpaceToken(), TOKEN_ID, 0,
- "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
- }
+ ReLexer lex(&source, KEYWORDS, OPERATORS, "=", COMMENTS, "A-Za-z_",
+ "A-Za-z0-9_", ReLexer::NUMTYPE_ALL, ReLexer::SF_LIKE_C,
+ ReLexer::STORE_ALL);
+ checkToken(lex.nextToken(), TOKEN_ID, 0, "i");
+ checkToken(lex.nextNonSpaceToken(), TOKEN_ID, 0, "ifs");
+ checkToken(lex.nextNonSpaceToken(), TOKEN_ID, 0,
+ "_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+ }
- void testBasic(){
- ReSource source;
- ReStringReader reader(source);
- source.addReader(&reader);
- reader.addSource("<main>", "if i>1 then i=1+2*_x9 fi");
- ReLexer lex(&source, KEYWORDS, OPERATORS, "=", COMMENTS, "A-Za-z_",
- "A-Za-z0-9_", ReLexer::NUMTYPE_ALL, ReLexer::SF_LIKE_C,
- ReLexer::STORE_ALL);
- ReToken* token;
- checkToken(lex.nextToken(), TOKEN_KEYWORD, KEY_IF);
- checkToken(lex.nextToken(), TOKEN_SPACE, 0);
- checkToken(lex.nextToken(), TOKEN_ID, 0, "i");
- checkToken(lex.nextToken(), TOKEN_OPERATOR, OP_GT);
- token = checkToken(lex.nextToken(), TOKEN_NUMBER);
- checkEqu(1, token->asInteger());
- checkToken(lex.nextToken(), TOKEN_SPACE, 0);
- checkToken(lex.nextToken(), TOKEN_KEYWORD, KEY_THEN);
- checkToken(lex.nextToken(), TOKEN_SPACE, 0);
+ void testBasic() {
+ ReSource source;
+ ReStringReader reader(source);
+ source.addReader(&reader);
+ reader.addSource("<main>", "if i>1 then i=1+2*_x9 fi");
+ ReLexer lex(&source, KEYWORDS, OPERATORS, "=", COMMENTS, "A-Za-z_",
+ "A-Za-z0-9_", ReLexer::NUMTYPE_ALL, ReLexer::SF_LIKE_C,
+ ReLexer::STORE_ALL);
+ ReToken* token;
+ checkToken(lex.nextToken(), TOKEN_KEYWORD, KEY_IF);
+ checkToken(lex.nextToken(), TOKEN_SPACE, 0);
+ checkToken(lex.nextToken(), TOKEN_ID, 0, "i");
+ checkToken(lex.nextToken(), TOKEN_OPERATOR, OP_GT);
+ token = checkToken(lex.nextToken(), TOKEN_NUMBER);
+ checkEqu(1, token->asInteger());
+ checkToken(lex.nextToken(), TOKEN_SPACE, 0);
+ checkToken(lex.nextToken(), TOKEN_KEYWORD, KEY_THEN);
+ checkToken(lex.nextToken(), TOKEN_SPACE, 0);
- }
- void testPrio(){
- ReSource source;
- ReStringReader reader(source);
- source.addReader(&reader);
- reader.addSource("x", "");
- enum {
- O_UNDEF, O_ASSIGN, O_PLUS, O_MINUS, O_TIMES, O_DIV
- };
- ReLexer lex(&source, KEYWORDS, "=\n+ -\n* /", "=",
- COMMENTS, "A-Za-z_", "A-Za-z0-9_", ReLexer::NUMTYPE_ALL,
- ReLexer::SF_LIKE_C, ReLexer::STORE_ALL);
- checkT(lex.prioOfOp(O_ASSIGN) < lex.prioOfOp(O_PLUS));
- checkEqu(lex.prioOfOp(O_PLUS), lex.prioOfOp(O_MINUS));
- checkT(lex.prioOfOp(O_MINUS) < lex.prioOfOp(O_TIMES));
- checkEqu(lex.prioOfOp(O_TIMES), lex.prioOfOp(O_DIV));
- }
+ }
+ void testPrio() {
+ ReSource source;
+ ReStringReader reader(source);
+ source.addReader(&reader);
+ reader.addSource("x", "");
+ enum {
+ O_UNDEF,
+ O_ASSIGN,
+ O_PLUS,
+ O_MINUS,
+ O_TIMES,
+ O_DIV
+ };
+ ReLexer lex(&source, KEYWORDS, "=\n+ -\n* /", "=",
+ COMMENTS, "A-Za-z_", "A-Za-z0-9_", ReLexer::NUMTYPE_ALL,
+ ReLexer::SF_LIKE_C, ReLexer::STORE_ALL);
+ checkT(lex.prioOfOp(O_ASSIGN) < lex.prioOfOp(O_PLUS));
+ checkEqu(lex.prioOfOp(O_PLUS), lex.prioOfOp(O_MINUS));
+ checkT(lex.prioOfOp(O_MINUS) < lex.prioOfOp(O_TIMES));
+ checkEqu(lex.prioOfOp(O_TIMES), lex.prioOfOp(O_DIV));
+ }
- virtual void run(void){
- testPrio();
- testBasic();
- testIds();
- testKeywords();
- testComments();
- testStrings();
- testOperators();
- testNumeric();
- testSpace();
- testRplToken();
- }
+ virtual void run(void) {
+ testPrio();
+ testBasic();
+ testIds();
+ testKeywords();
+ testComments();
+ testStrings();
+ testOperators();
+ testNumeric();
+ testSpace();
+ testRplToken();
+ }
};
-void testReLexer(){
- TestRplLexer test;
- test.run();
+void testReLexer() {
+ TestRplLexer test;
+ test.run();
}
class TestReMFParser: public ReTest {
private:
- ReSource m_source;
- ReASTree m_tree;
- ReStringReader m_reader;
- ReFileReader m_fileReader;
- QByteArray m_currentSource;
+ ReSource m_source;
+ ReASTree m_tree;
+ ReStringReader m_reader;
+ ReFileReader m_fileReader;
+ QByteArray m_currentSource;
public:
- TestReMFParser() :
- ReTest("ReMFParser"),
- m_source(),
- m_tree(),
- m_reader(m_source),
- m_fileReader(m_source){
- m_source.addReader(&m_reader);
- doIt();
- }
+ TestReMFParser() :
+ ReTest("ReMFParser"),
+ m_source(),
+ m_tree(),
+ m_reader(m_source),
+ m_fileReader(m_source) {
+ m_source.addReader(&m_reader);
+ doIt();
+ }
protected:
- void setSource(const char* content){
- ReASItem::reset();
- m_currentSource = content;
- m_tree.clear();
- m_source.clear();
- m_reader.clear();
- m_reader.addSource("<test>", content);
- m_source.addReader(&m_reader);
- m_source.addSourceUnit(m_reader.currentSourceUnit());
- }
- void setFileSource(const char* filename){
- ReASItem::reset();
- m_currentSource = ReStringUtil::read(filename);
- m_tree.clear();
- m_source.clear();
- m_fileReader.clear();
- m_fileReader.addSource(filename);
- m_source.addReader(&m_fileReader);
- m_source.addSourceUnit(m_fileReader.currentSourceUnit());
- }
+ void setSource(const char* content) {
+ ReASItem::reset();
+ m_currentSource = content;
+ m_tree.clear();
+ m_source.clear();
+ m_reader.clear();
+ m_reader.addSource("<test>", content);
+ m_source.addReader(&m_reader);
+ m_source.addSourceUnit(m_reader.currentSourceUnit());
+ }
+ void setFileSource(const char* filename) {
+ ReASItem::reset();
+ m_currentSource = ReStringUtil::read(filename);
+ m_tree.clear();
+ m_source.clear();
+ m_fileReader.clear();
+ m_fileReader.addSource(filename);
+ m_source.addReader(&m_fileReader);
+ m_source.addSourceUnit(m_fileReader.currentSourceUnit());
+ }
private:
- void checkAST(const char* fileExpected, int lineNo){
- QByteArray fnExpected = "test";
- fnExpected += QDir::separator().toLatin1();
- fnExpected += "mfparser";
- fnExpected += (char) QDir::separator().toLatin1();
- fnExpected += fileExpected;
- QByteArray fnCurrent = getTempFile(fileExpected, "rplmfparser");
- m_tree.dump(fnCurrent, ReASTree::DMP_NO_GLOBALS, m_currentSource);
- assertEqualFiles(fnExpected.constData(), fnCurrent.constData(),
- __FILE__, lineNo);
- }
+ void checkAST(const char* fileExpected, int lineNo) {
+ QByteArray fnExpected = "test";
+ fnExpected += QDir::separator().toLatin1();
+ fnExpected += "mfparser";
+ fnExpected += (char) QDir::separator().toLatin1();
+ fnExpected += fileExpected;
+ QByteArray fnCurrent = getTempFile(fileExpected, "rplmfparser");
+ m_tree.dump(fnCurrent, ReASTree::DMP_NO_GLOBALS, m_currentSource);
+ assertEqualFiles(fnExpected.constData(), fnCurrent.constData(),
+ __FILE__, lineNo);
+ }
public:
- void fileClassTest(){
- setFileSource("test/rplmfparser/string1.mf");
- ReMFParser parser(m_source, m_tree);
- parser.parse();
- checkAST("string1.txt", __LINE__);
- }
+ void fileClassTest() {
+ setFileSource("test/rplmfparser/string1.mf");
+ ReMFParser parser(m_source, m_tree);
+ parser.parse();
+ checkAST("string1.txt", __LINE__);
+ }
- void baseTest(){
- setSource("2+3*4");
- ReMFParser parser(m_source, m_tree);
- parser.parse();
- checkAST("baseTest.txt", __LINE__);
- }
+ void baseTest() {
+ setSource("2+3*4");
+ ReMFParser parser(m_source, m_tree);
+ parser.parse();
+ checkAST("baseTest.txt", __LINE__);
+ }
- void varDefTest(){
- setSource("const lazy Str s = 'Hi';\nconst List l;\nInt i = 3;");
- ReMFParser parser(m_source, m_tree);
- parser.parse();
- checkAST("varDefTest.txt", __LINE__);
- }
+ void varDefTest() {
+ setSource("const lazy Str s = 'Hi';\nconst List l;\nInt i = 3;");
+ ReMFParser parser(m_source, m_tree);
+ parser.parse();
+ checkAST("varDefTest.txt", __LINE__);
+ }
- void ifTest(){
- setSource(
- "Int a;\nInt b;\na = b = 2;\nif 11 < 12\nthen a = 13 * 14\nelse a = 15 / 16\nfi");
- // setSource("Int a; if 11 < 12 then a = 13 * 14 else a = 15 / 16 fi");
- ReMFParser parser(m_source, m_tree);
- parser.parse();
- checkAST("ifTest1.txt", __LINE__);
- setSource("Str x;\nif 7 < 6\nthen x = '123';\nfi");
- parser.parse();
- checkAST("ifTest2.txt", __LINE__);
- }
- void whileTest(){
- setSource("Int a = 20;\nwhile 3 < 5 do\n a = 7\nod");
- ReMFParser parser(m_source, m_tree);
- parser.parse();
- checkAST("whileTest.txt", __LINE__);
- }
+ void ifTest() {
+ setSource(
+ "Int a;\nInt b;\na = b = 2;\nif 11 < 12\nthen a = 13 * 14\nelse a = 15 / 16\nfi");
+ // setSource("Int a; if 11 < 12 then a = 13 * 14 else a = 15 / 16 fi");
+ ReMFParser parser(m_source, m_tree);
+ parser.parse();
+ checkAST("ifTest1.txt", __LINE__);
+ setSource("Str x;\nif 7 < 6\nthen x = '123';\nfi");
+ parser.parse();
+ checkAST("ifTest2.txt", __LINE__);
+ }
+ void whileTest() {
+ setSource("Int a = 20;\nwhile 3 < 5 do\n a = 7\nod");
+ ReMFParser parser(m_source, m_tree);
+ parser.parse();
+ checkAST("whileTest.txt", __LINE__);
+ }
- void repeatTest(){
- setSource("Int a;\nrepeat\na++;\nuntil a != 2 * 3;");
- ReMFParser parser(m_source, m_tree);
- parser.parse();
- checkAST("repeatTest.txt", __LINE__);
- }
- void forCTest(){
- setSource("Int a;\nfor b from 10 to 1 step -2 do\na += 1;\nod");
- ReMFParser parser(m_source, m_tree);
- parser.parse();
- checkAST("forC1.txt", __LINE__);
- setSource("Int a; for to 10 do a += 1 od");
- parser.parse();
- checkAST("forC2.txt", __LINE__);
- }
- void opTest(){
- checkEqu(25, ReMFParser::O_QUESTION);
- checkEqu(37, ReMFParser::O_RSHIFT2);
- checkEqu(41, ReMFParser::O_DEC);
- checkEqu(48, ReMFParser::O_RBRACE);
- setSource(
- "Int a = 1;\nInt b = 100;\n--a;\nb++;\na--*++b**(8-3);\na=b=(a+(b-2)*3)");
- ReMFParser parser(m_source, m_tree);
- parser.parse();
- checkAST("opTest1.txt", __LINE__);
- }
- void forItTest(){
- setSource("Map a;\nfor x in a do\na += 1;\nod");
- ReMFParser parser(m_source, m_tree);
- parser.parse();
- checkAST("forIt1.txt", __LINE__);
- }
- void listTest(){
- ReMFParser parser(m_source, m_tree);
- setSource("List b = [];");
- parser.parse();
- checkAST("list1.txt", __LINE__);
- setSource("List a = [2+3, 3.14, 7, 'hi', a]; List b = [];");
- parser.parse();
- checkAST("list2.txt", __LINE__);
- }
- void mapTest(){
- setSource("Map a = {};");
- ReMFParser parser(m_source, m_tree);
- parser.parse();
- checkAST("map1.txt", __LINE__);
- setSource(
- "Map a = {'a': 2+3,'bcd':3.14,'ccc':7, 'hi':'world'};\nMap b = {};");
- parser.parse();
- checkAST("map2.txt", __LINE__);
- }
- void methodCallTest(){
- //setSource("max(4,3.14);");
- setSource("rand();\nsin(a);\nmax(1+2*3,4**(5-4));");
- ReMFParser parser(m_source, m_tree);
- parser.parse();
- checkAST("methc1.txt", __LINE__);
- }
- void fieldTest(){
- setSource("file.find('*.c')[0].name;\n[1,2,3].join(' ');\n3.14.trunc;");
- ReMFParser parser(m_source, m_tree);
- parser.parse();
- checkAST("field1.txt", __LINE__);
- }
+ void repeatTest() {
+ setSource("Int a;\nrepeat\na++;\nuntil a != 2 * 3;");
+ ReMFParser parser(m_source, m_tree);
+ parser.parse();
+ checkAST("repeatTest.txt", __LINE__);
+ }
+ void forCTest() {
+ setSource("Int a;\nfor b from 10 to 1 step -2 do\na += 1;\nod");
+ ReMFParser parser(m_source, m_tree);
+ parser.parse();
+ checkAST("forC1.txt", __LINE__);
+ setSource("Int a; for to 10 do a += 1 od");
+ parser.parse();
+ checkAST("forC2.txt", __LINE__);
+ }
+ void opTest() {
+ checkEqu(25, ReMFParser::O_QUESTION);
+ checkEqu(37, ReMFParser::O_RSHIFT2);
+ checkEqu(41, ReMFParser::O_DEC);
+ checkEqu(48, ReMFParser::O_RBRACE);
+ setSource(
+ "Int a = 1;\nInt b = 100;\n--a;\nb++;\na--*++b**(8-3);\na=b=(a+(b-2)*3)");
+ ReMFParser parser(m_source, m_tree);
+ parser.parse();
+ checkAST("opTest1.txt", __LINE__);
+ }
+ void forItTest() {
+ setSource("Map a;\nfor x in a do\na += 1;\nod");
+ ReMFParser parser(m_source, m_tree);
+ parser.parse();
+ checkAST("forIt1.txt", __LINE__);
+ }
+ void listTest() {
+ ReMFParser parser(m_source, m_tree);
+ setSource("List b = [];");
+ parser.parse();
+ checkAST("list1.txt", __LINE__);
+ setSource("List a = [2+3, 3.14, 7, 'hi', a]; List b = [];");
+ parser.parse();
+ checkAST("list2.txt", __LINE__);
+ }
+ void mapTest() {
+ setSource("Map a = {};");
+ ReMFParser parser(m_source, m_tree);
+ parser.parse();
+ checkAST("map1.txt", __LINE__);
+ setSource(
+ "Map a = {'a': 2+3,'bcd':3.14,'ccc':7, 'hi':'world'};\nMap b = {};");
+ parser.parse();
+ checkAST("map2.txt", __LINE__);
+ }
+ void methodCallTest() {
+ //setSource("max(4,3.14);");
+ setSource("rand();\nsin(a);\nmax(1+2*3,4**(5-4));");
+ ReMFParser parser(m_source, m_tree);
+ parser.parse();
+ checkAST("methc1.txt", __LINE__);
+ }
+ void fieldTest() {
+ setSource("file.find('*.c')[0].name;\n[1,2,3].join(' ');\n3.14.trunc;");
+ ReMFParser parser(m_source, m_tree);
+ parser.parse();
+ checkAST("field1.txt", __LINE__);
+ }
- void methodTest(){
- setSource("func Float pi: 3.1415; endf func Str delim(): '/' endf;");
- ReMFParser parser(m_source, m_tree);
- parser.parse();
- checkAST("meth1.txt", __LINE__);
- setSource("func Int fac(const Int n):\n"
- "Int rc; if rc <= 1 then rc = 1 else rc = n*fac(n-1) fi\n"
- "rc endf");
- parser.parse();
- checkAST("meth2.txt", __LINE__);
- setSource("func Int max(Int a, Int b):\n Int rc = a;\n"
- "if a < b then rc = b; fi\nrc\n"
- "endf\n"
- "func Int max(const Int a, Int b, Int c):\n"
- "max(a, max(b, c))\n"
- "endf");
- parser.parse();
- checkAST("meth3.txt", __LINE__);
- setSource("func Int max(const Int a, Int b, Int c):\n"
- "func Int max(Int a, Int b):\n Int rc = a;\n"
- "if a < b then rc = b; fi\nrc\n"
- "endf\n"
- "max(a, max(b, c))\n"
- "endf");
- parser.parse();
- checkAST("meth4.txt", __LINE__);
- }
- void mainTest(){
- setSource("Int a=2+3*4;\nfunc Void main():\na;\nendf");
- ReMFParser parser(m_source, m_tree);
- parser.parse();
- checkAST("main1.txt", __LINE__);
- }
+ void methodTest() {
+ setSource("func Float pi: 3.1415; endf func Str delim(): '/' endf;");
+ ReMFParser parser(m_source, m_tree);
+ parser.parse();
+ checkAST("meth1.txt", __LINE__);
+ setSource("func Int fac(const Int n):\n"
+ "Int rc; if rc <= 1 then rc = 1 else rc = n*fac(n-1) fi\n"
+ "rc endf");
+ parser.parse();
+ checkAST("meth2.txt", __LINE__);
+ setSource("func Int max(Int a, Int b):\n Int rc = a;\n"
+ "if a < b then rc = b; fi\nrc\n"
+ "endf\n"
+ "func Int max(const Int a, Int b, Int c):\n"
+ "max(a, max(b, c))\n"
+ "endf");
+ parser.parse();
+ checkAST("meth3.txt", __LINE__);
+ setSource("func Int max(const Int a, Int b, Int c):\n"
+ "func Int max(Int a, Int b):\n Int rc = a;\n"
+ "if a < b then rc = b; fi\nrc\n"
+ "endf\n"
+ "max(a, max(b, c))\n"
+ "endf");
+ parser.parse();
+ checkAST("meth4.txt", __LINE__);
+ }
+ void mainTest() {
+ setSource("Int a=2+3*4;\nfunc Void main():\na;\nendf");
+ ReMFParser parser(m_source, m_tree);
+ parser.parse();
+ checkAST("main1.txt", __LINE__);
+ }
- virtual void run(void){
- mainTest();
- varDefTest();
- repeatTest();
- baseTest();
- whileTest();
- methodTest();
- fieldTest();
- methodCallTest();
- mapTest();
- forItTest();
- forCTest();
- listTest();
- opTest();
- fileClassTest();
- }
+ virtual void run(void) {
+ mainTest();
+ varDefTest();
+ repeatTest();
+ baseTest();
+ whileTest();
+ methodTest();
+ fieldTest();
+ methodCallTest();
+ mapTest();
+ forItTest();
+ forCTest();
+ listTest();
+ opTest();
+ fileClassTest();
+ }
};
-void testReMFParser(){
- TestReMFParser test;
+void testReMFParser() {
+ TestReMFParser test;
}
class TestRplMatrix: public ReTest {
public:
- TestRplMatrix() :
- ReTest("RplMatrix"){
- doIt();
- }
+ TestRplMatrix() :
+ ReTest("RplMatrix") {
+ doIt();
+ }
public:
- void fillMatrix(RplMatrix& mx, MatVal offset = 0){
- for (int row = 0; row < mx.getRows(); row++){
- for (int col = 0; col < mx.getCols(); col++){
- mx.set(row, col, 100.0 * row + col + offset);
- }
- }
- }
- void checkMatrix(const RplMatrix& mx, MatVal offset = 0){
- int count = 0;
- for (int row = 0; row < mx.getRows(); row++){
- for (int col = 0; col < mx.getCols(); col++){
- checkEqu(100.0 * row + col + offset, mx.get(row, col));
- count++;
- }
- }
- checkEqu(mx.getCols() * mx.getRows(), count);
- }
- void fillConst(RplMatrix& mx, MatVal value){
- for (int row = 0; row < mx.getRows(); row++){
- for (int col = 0; col < mx.getCols(); col++){
- mx.set(row, col, value);
- }
- }
- }
- void checkConst(const RplMatrix& mx, MatVal value){
- int count = 0;
- for (int row = 0; row < mx.getRows(); row++){
- for (int col = 0; col < mx.getCols(); col++){
- checkEqu(value, mx.get(row, col));
- count++;
- }
- }
- checkEqu(mx.getCols() * mx.getRows(), count);
- }
-
- void testBasic(){
- Tuple2 tuple(-2.0, 0.5);
- checkEqu(-2.0, tuple.m_value1);
- checkEqu(0.5, tuple.m_value2);
- RplMatrix mat("mx");
- try{
- throw RplMatrixException(mat, "String: %s and int %d", "Hi", -333);
- checkF(true);
- } catch (RplMatrixException exc){
- checkEqu("mx: String: Hi and int -333", exc.getMessage());
- }
- RplMatrix mat2;
- try{
- throw RplMatrixException(mat2, "String: %s and int %d", "Hi", -333);
- checkF(true);
- } catch (RplMatrixException exc){
- checkEqu("String: Hi and int -333", exc.getMessage());
- }
- checkEqu("mx", mat.getName());
- checkEqu("", mat2.getName());
-
- RplMatrix m2x3(2, 3, "m2x3");
- checkEqu("m2x3", m2x3.getName());
- checkEqu(2, m2x3.getRows());
- checkEqu(3, m2x3.getCols());
- fillMatrix(m2x3);
- checkMatrix(m2x3);
-
- RplMatrix mxCopy(m2x3);
- checkEqu("m2x3-copy", mxCopy.getName());
- checkEqu(2, mxCopy.getRows());
- checkEqu(3, mxCopy.getCols());
- checkMatrix(mxCopy);
-
- RplMatrix mxCopy2("mxCopy2");
- mxCopy2 = m2x3;
- checkEqu("mxCopy2", mxCopy2.getName());
- checkEqu(2, mxCopy2.getRows());
- checkEqu(3, mxCopy2.getCols());
- checkMatrix(mxCopy2);
- }
- void testAddOperators(){
- RplMatrix m1(3, 2, "m1");
- fillMatrix(m1);
- checkMatrix(m1);
- RplMatrix m2(3, 2, "m2");
- fillMatrix(m2, 42);
- checkMatrix(m2, 42);
- RplMatrix m3(3, 2, "m3");
- fillMatrix(m3, -42);
- checkMatrix(m3, -42);
-
- m1 += 42;
- checkMatrix(m1, 42);
-
- checkT(m1 == m2);
- checkF(m1 == m3);
-
- m1 -= 42;
- checkMatrix(m1);
- m1 -= m1;
- checkConst(m1, 0);
-
- fillMatrix(m1);
- m1 -= m3;
- checkConst(m1, 42);
- m1 += m2;
- checkMatrix(m1, 42 * 2);
- }
- void testCompareOperators(){
- RplMatrix m1(3, 2, "m1");
- fillMatrix(m1);
- checkMatrix(m1);
- RplMatrix m2(3, 2, "m2");
- fillMatrix(m2);
-
- checkT(m1 == m2);
- checkF(m1 != m2);
- // modify each element, comparism must return false:
- int row, col;
- for (row = 0; row < m2.getRows(); row++)
- for (col = 0; col < m2.getCols(); col++){
- fillMatrix(m2);
- m2.set(row, col, -1);
- checkF(m1 == m2);
- checkT(m1 != m2);
- }
-
- fillConst(m1, 42);
- checkT(m1 == 42);
- checkF(m1 == 43);
- checkT(m1 != 43);
- for (row = 0; row < m1.getRows(); row++)
- for (col = 0; col < m1.getCols(); col++){
- fillMatrix(m1, 42);
- m1.set(row, col, -1);
- checkF(m1 == 42);
- checkT(m1 != 42);
- }
- }
-
- void testCheckDefinition(){
- RplMatrix m1(3, 2, "m1");
- fillMatrix(m1);
- checkMatrix(m1);
- RplMatrix m2(3, 2, "m2");
- fillMatrix(m2);
-
- m1.checkDefinition(1, 1);
- m1.checkDefinition(1000, 1000);
- m1.checkDefinition(0, 0);
- try{
- m1.checkDefinition(-1, 1);
- checkT(false);
- } catch (RplMatrixException exc){
- checkEqu("m1: row number negative: -1", exc.getMessage());
- }
- try{
- m1.checkDefinition(1, -1);
- checkT(false);
- } catch (RplMatrixException exc){
- checkEqu("m1: column number negative: -1", exc.getMessage());
- }
-
- }
- void testCheck(){
- RplMatrix m1(3, 2, "m1");
- fillMatrix(m1);
- checkMatrix(m1);
-
- m1.check(0, 0);
- m1.check(3 - 1, 2 - 1);
- try{
- m1.check(-1, 1);
- checkT(false);
- } catch (RplMatrixException exc){
- checkEqu("m1: invalid row: -1 not in [0,3[", exc.getMessage());
- }
- try{
- m1.check(3, 1);
- checkT(false);
- } catch (RplMatrixException exc){
- checkEqu("m1: invalid row: 3 not in [0,3[", exc.getMessage());
- }
- try{
- m1.check(1, -1);
- checkT(false);
- } catch (RplMatrixException exc){
- checkEqu("m1: invalid column: -1 not in [0,2[", exc.getMessage());
- }
- try{
- m1.check(1, 2);
- checkT(false);
- } catch (RplMatrixException exc){
- checkEqu("m1: invalid column: 2 not in [0,2[", exc.getMessage());
- }
- }
- void testCheckSameDimension(){
- RplMatrix m1(3, 2, "m1");
- RplMatrix m2(3, 2, "m2");
-
- m1.checkSameDimension(m2);
-
- m2.resize(2, 2);
- try{
- m1.checkSameDimension(m2);
- checkT(false);
- } catch (RplMatrixException exc){
- checkEqu("m1: m2 has a different row count: 3 / 2", exc.getMessage());
- }
- m2.resize(3, 3);
- try{
- m1.checkSameDimension(m2);
- checkT(false);
- } catch (RplMatrixException exc){
- checkEqu("m1: m2 has a different column count: 2 / 3",
- exc.getMessage());
- }
- }
- void testResize(){
- RplMatrix m1(3, 2, "m1");
- fillMatrix(m1);
- checkMatrix(m1);
- RplMatrix m2(2, 4, "m2");
- fillConst(m2, 0);
- checkConst(m2, 0);
-
- m1.resize(2, 4);
- checkEqu(2, m1.getRows());
- checkEqu(4, m1.getCols());
- checkT(m1 == m2);
- }
-
- void testMinMax(){
- RplMatrix m1(4, 5, "m1");
- fillMatrix(m1);
- checkMatrix(m1);
- m1.set(0, 0, -98);
- m1.set(3, 4, 9999);
- Tuple2 miniMax = m1.minMax();
- checkEqu(-98.0, miniMax.m_value1);
- checkEqu(9999.0, miniMax.m_value2);
-
- fillMatrix(m1);
- checkMatrix(m1);
- m1.set(1, 1, 7777);
- m1.set(3, 4, -987);
- miniMax = m1.minMax();
- checkEqu(-987.0, miniMax.m_value1);
- checkEqu(7777.0, miniMax.m_value2);
- }
-
- void testTranspose(){
- RplMatrix m1(1, 5, "m1");
- fillMatrix(m1);
- RplMatrix m2(m1.transpose());
-
- checkEqu(5, m2.getRows());
- checkEqu(1, m2.getCols());
-
- int row, col;
- col = 0;
- for (row = 0; row < 5; row++){
- checkEqu(qreal(col * 100 + row), m2.get(row, 0));
- }
-
- m1.resize(35, 73);
- fillMatrix(m1);
- m2 = m1.transpose();
-
- checkEqu(73, m2.getRows());
- checkEqu(35, m2.getCols());
-
- int count = 0;
- for (row = 0; row < m2.getRows(); row++){
- for (col = 0; col < m2.getCols(); col++){
- checkEqu(qreal(col * 100 + row), m2.get(row, col));
- count++;
- }
- }
- checkEqu(73 * 35, count);
- }
- void testToString(){
- RplMatrix m1(1, 1, "m1");
- m1.set(0, 0, 2.34);
- checkEqu("[2.340000,\n]", m1.toString().constData());
- checkEqu("jonny[2.34000 |]",
- m1.toString("jonny", "%.5f", "|", " ").constData());
-
- m1.resize(2, 1);
- m1.set(0, 0, 2.34);
- m1.set(1, 0, 55.5);
-
- checkEqu("[2.340000,\n55.500000,\n]", m1.toString().constData());
- checkEqu("jonny[2.34000 |55.50000 |]",
- m1.toString("jonny", "%.5f", "|", " ").constData());
- log("");
- }
- void testReadCsv(){
- QByteArray fn = getTempFile("rplmatrixtest.csv");
- const char* content;
- RplMatrix m1(1, 1, "m1");
-
- fillMatrix(m1);
- content = ",Port0,Port1,Port2\n"
- "element1,5, -3E-99 , 0.5\n"
- "element2,7,-22.3,44\n"
- "\n"
- "2 Elements, 3, Ports";
- ReStringUtil::write(fn, content);
- m1.readFromCvs(fn, 256);
- checkEqu(2, m1.getRows());
- checkEqu(3, m1.getCols());
-
- checkEqu(5.0, m1.get(0, 0));
- checkEqu(-3.0E-99, m1.get(0, 1));
- checkEqu(0.5, m1.get(0, 2));
-
- checkEqu(7.0, m1.get(1, 0));
- checkEqu(-22.3, m1.get(1, 1));
- checkEqu(44.0, m1.get(1, 2));
-
- fillMatrix(m1);
- content = "Port0,Port1,Port2\n"
- "5, -3E-99 , 0.5\n";
- ReStringUtil::write(fn, content);
- m1.readFromCvs(fn, 256);
- checkEqu(1, m1.getRows());
- checkEqu(3, m1.getCols());
- checkEqu(5.0, m1.get(0, 0));
- checkEqu(-3.0E-99, m1.get(0, 1));
- checkEqu(0.5, m1.get(0, 2));
-
- /*
- 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);
- */
- }
- virtual void run(void){
- testBasic();
- testAddOperators();
- testCompareOperators();
- testCheckDefinition();
- testCheck();
- testCheckSameDimension();
- testResize();
- testMinMax();
- testTranspose();
- testToString();
- testReadCsv();
- }
+ void fillMatrix(RplMatrix& mx, MatVal offset = 0) {
+ for (int row = 0; row < mx.getRows(); row++) {
+ for (int col = 0; col < mx.getCols(); col++) {
+ mx.set(row, col, 100.0 * row + col + offset);
+ }
+ }
+ }
+ void checkMatrix(const RplMatrix& mx, MatVal offset = 0) {
+ int count = 0;
+ for (int row = 0; row < mx.getRows(); row++) {
+ for (int col = 0; col < mx.getCols(); col++) {
+ checkEqu(100.0 * row + col + offset, mx.get(row, col));
+ count++;
+ }
+ }
+ checkEqu(mx.getCols() * mx.getRows(), count);
+ }
+ void fillConst(RplMatrix& mx, MatVal value) {
+ for (int row = 0; row < mx.getRows(); row++) {
+ for (int col = 0; col < mx.getCols(); col++) {
+ mx.set(row, col, value);
+ }
+ }
+ }
+ void checkConst(const RplMatrix& mx, MatVal value) {
+ int count = 0;
+ for (int row = 0; row < mx.getRows(); row++) {
+ for (int col = 0; col < mx.getCols(); col++) {
+ checkEqu(value, mx.get(row, col));
+ count++;
+ }
+ }
+ checkEqu(mx.getCols() * mx.getRows(), count);
+ }
+
+ void testBasic() {
+ Tuple2 tuple(-2.0, 0.5);
+ checkEqu(-2.0, tuple.m_value1);
+ checkEqu(0.5, tuple.m_value2);
+ RplMatrix mat("mx");
+ try {
+ throw RplMatrixException(mat, "String: %s and int %d", "Hi", -333);
+ checkF(true);
+ } catch (RplMatrixException exc) {
+ checkEqu("mx: String: Hi and int -333", exc.getMessage());
+ }
+ RplMatrix mat2;
+ try {
+ throw RplMatrixException(mat2, "String: %s and int %d", "Hi", -333);
+ checkF(true);
+ } catch (RplMatrixException exc) {
+ checkEqu("String: Hi and int -333", exc.getMessage());
+ }
+ checkEqu("mx", mat.getName());
+ checkEqu("", mat2.getName());
+
+ RplMatrix m2x3(2, 3, "m2x3");
+ checkEqu("m2x3", m2x3.getName());
+ checkEqu(2, m2x3.getRows());
+ checkEqu(3, m2x3.getCols());
+ fillMatrix(m2x3);
+ checkMatrix(m2x3);
+
+ RplMatrix mxCopy(m2x3);
+ checkEqu("m2x3-copy", mxCopy.getName());
+ checkEqu(2, mxCopy.getRows());
+ checkEqu(3, mxCopy.getCols());
+ checkMatrix(mxCopy);
+
+ RplMatrix mxCopy2("mxCopy2");
+ mxCopy2 = m2x3;
+ checkEqu("mxCopy2", mxCopy2.getName());
+ checkEqu(2, mxCopy2.getRows());
+ checkEqu(3, mxCopy2.getCols());
+ checkMatrix(mxCopy2);
+ }
+ void testAddOperators() {
+ RplMatrix m1(3, 2, "m1");
+ fillMatrix(m1);
+ checkMatrix(m1);
+ RplMatrix m2(3, 2, "m2");
+ fillMatrix(m2, 42);
+ checkMatrix(m2, 42);
+ RplMatrix m3(3, 2, "m3");
+ fillMatrix(m3, -42);
+ checkMatrix(m3, -42);
+
+ m1 += 42;
+ checkMatrix(m1, 42);
+
+ checkT(m1 == m2);
+ checkF(m1 == m3);
+
+ m1 -= 42;
+ checkMatrix(m1);
+ m1 -= m1;
+ checkConst(m1, 0);
+
+ fillMatrix(m1);
+ m1 -= m3;
+ checkConst(m1, 42);
+ m1 += m2;
+ checkMatrix(m1, 42 * 2);
+ }
+ void testCompareOperators() {
+ RplMatrix m1(3, 2, "m1");
+ fillMatrix(m1);
+ checkMatrix(m1);
+ RplMatrix m2(3, 2, "m2");
+ fillMatrix(m2);
+
+ checkT(m1 == m2);
+ checkF(m1 != m2);
+ // modify each element, comparism must return false:
+ int row, col;
+ for (row = 0; row < m2.getRows(); row++)
+ for (col = 0; col < m2.getCols(); col++) {
+ fillMatrix(m2);
+ m2.set(row, col, -1);
+ checkF(m1 == m2);
+ checkT(m1 != m2);
+ }
+
+ fillConst(m1, 42);
+ checkT(m1 == 42);
+ checkF(m1 == 43);
+ checkT(m1 != 43);
+ for (row = 0; row < m1.getRows(); row++)
+ for (col = 0; col < m1.getCols(); col++) {
+ fillMatrix(m1, 42);
+ m1.set(row, col, -1);
+ checkF(m1 == 42);
+ checkT(m1 != 42);
+ }
+ }
+
+ void testCheckDefinition() {
+ RplMatrix m1(3, 2, "m1");
+ fillMatrix(m1);
+ checkMatrix(m1);
+ RplMatrix m2(3, 2, "m2");
+ fillMatrix(m2);
+
+ m1.checkDefinition(1, 1);
+ m1.checkDefinition(1000, 1000);
+ m1.checkDefinition(0, 0);
+ try {
+ m1.checkDefinition(-1, 1);
+ checkT(false);
+ } catch (RplMatrixException exc) {
+ checkEqu("m1: row number negative: -1", exc.getMessage());
+ }
+ try {
+ m1.checkDefinition(1, -1);
+ checkT(false);
+ } catch (RplMatrixException exc) {
+ checkEqu("m1: column number negative: -1", exc.getMessage());
+ }
+
+ }
+ void testCheck() {
+ RplMatrix m1(3, 2, "m1");
+ fillMatrix(m1);
+ checkMatrix(m1);
+
+ m1.check(0, 0);
+ m1.check(3 - 1, 2 - 1);
+ try {
+ m1.check(-1, 1);
+ checkT(false);
+ } catch (RplMatrixException exc) {
+ checkEqu("m1: invalid row: -1 not in [0,3[", exc.getMessage());
+ }
+ try {
+ m1.check(3, 1);
+ checkT(false);
+ } catch (RplMatrixException exc) {
+ checkEqu("m1: invalid row: 3 not in [0,3[", exc.getMessage());
+ }
+ try {
+ m1.check(1, -1);
+ checkT(false);
+ } catch (RplMatrixException exc) {
+ checkEqu("m1: invalid column: -1 not in [0,2[", exc.getMessage());
+ }
+ try {
+ m1.check(1, 2);
+ checkT(false);
+ } catch (RplMatrixException exc) {
+ checkEqu("m1: invalid column: 2 not in [0,2[", exc.getMessage());
+ }
+ }
+ void testCheckSameDimension() {
+ RplMatrix m1(3, 2, "m1");
+ RplMatrix m2(3, 2, "m2");
+
+ m1.checkSameDimension(m2);
+
+ m2.resize(2, 2);
+ try {
+ m1.checkSameDimension(m2);
+ checkT(false);
+ } catch (RplMatrixException exc) {
+ checkEqu("m1: m2 has a different row count: 3 / 2",
+ exc.getMessage());
+ }
+ m2.resize(3, 3);
+ try {
+ m1.checkSameDimension(m2);
+ checkT(false);
+ } catch (RplMatrixException exc) {
+ checkEqu("m1: m2 has a different column count: 2 / 3",
+ exc.getMessage());
+ }
+ }
+ void testResize() {
+ RplMatrix m1(3, 2, "m1");
+ fillMatrix(m1);
+ checkMatrix(m1);
+ RplMatrix m2(2, 4, "m2");
+ fillConst(m2, 0);
+ checkConst(m2, 0);
+
+ m1.resize(2, 4);
+ checkEqu(2, m1.getRows());
+ checkEqu(4, m1.getCols());
+ checkT(m1 == m2);
+ }
+
+ void testMinMax() {
+ RplMatrix m1(4, 5, "m1");
+ fillMatrix(m1);
+ checkMatrix(m1);
+ m1.set(0, 0, -98);
+ m1.set(3, 4, 9999);
+ Tuple2 miniMax = m1.minMax();
+ checkEqu(-98.0, miniMax.m_value1);
+ checkEqu(9999.0, miniMax.m_value2);
+
+ fillMatrix(m1);
+ checkMatrix(m1);
+ m1.set(1, 1, 7777);
+ m1.set(3, 4, -987);
+ miniMax = m1.minMax();
+ checkEqu(-987.0, miniMax.m_value1);
+ checkEqu(7777.0, miniMax.m_value2);
+ }
+
+ void testTranspose() {
+ RplMatrix m1(1, 5, "m1");
+ fillMatrix(m1);
+ RplMatrix m2(m1.transpose());
+
+ checkEqu(5, m2.getRows());
+ checkEqu(1, m2.getCols());
+
+ int row, col;
+ col = 0;
+ for (row = 0; row < 5; row++) {
+ checkEqu(qreal(col * 100 + row), m2.get(row, 0));
+ }
+
+ m1.resize(35, 73);
+ fillMatrix(m1);
+ m2 = m1.transpose();
+
+ checkEqu(73, m2.getRows());
+ checkEqu(35, m2.getCols());
+
+ int count = 0;
+ for (row = 0; row < m2.getRows(); row++) {
+ for (col = 0; col < m2.getCols(); col++) {
+ checkEqu(qreal(col * 100 + row), m2.get(row, col));
+ count++;
+ }
+ }
+ checkEqu(73 * 35, count);
+ }
+ void testToString() {
+ RplMatrix m1(1, 1, "m1");
+ m1.set(0, 0, 2.34);
+ checkEqu("[2.340000,\n]", m1.toString().constData());
+ checkEqu("jonny[2.34000 |]",
+ m1.toString("jonny", "%.5f", "|", " ").constData());
+
+ m1.resize(2, 1);
+ m1.set(0, 0, 2.34);
+ m1.set(1, 0, 55.5);
+
+ checkEqu("[2.340000,\n55.500000,\n]", m1.toString().constData());
+ checkEqu("jonny[2.34000 |55.50000 |]",
+ m1.toString("jonny", "%.5f", "|", " ").constData());
+ log("");
+ }
+ void testReadCsv() {
+ QByteArray fn = getTempFile("rplmatrixtest.csv");
+ const char* content;
+ RplMatrix m1(1, 1, "m1");
+
+ fillMatrix(m1);
+ content = ",Port0,Port1,Port2\n"
+ "element1,5, -3E-99 , 0.5\n"
+ "element2,7,-22.3,44\n"
+ "\n"
+ "2 Elements, 3, Ports";
+ ReStringUtil::write(fn, content);
+ m1.readFromCvs(fn, 256);
+ checkEqu(2, m1.getRows());
+ checkEqu(3, m1.getCols());
+
+ checkEqu(5.0, m1.get(0, 0));
+ checkEqu(-3.0E-99, m1.get(0, 1));
+ checkEqu(0.5, m1.get(0, 2));
+
+ checkEqu(7.0, m1.get(1, 0));
+ checkEqu(-22.3, m1.get(1, 1));
+ checkEqu(44.0, m1.get(1, 2));
+
+ fillMatrix(m1);
+ content = "Port0,Port1,Port2\n"
+ "5, -3E-99 , 0.5\n";
+ ReStringUtil::write(fn, content);
+ m1.readFromCvs(fn, 256);
+ checkEqu(1, m1.getRows());
+ checkEqu(3, m1.getCols());
+ checkEqu(5.0, m1.get(0, 0));
+ checkEqu(-3.0E-99, m1.get(0, 1));
+ checkEqu(0.5, m1.get(0, 2));
+
+ /*
+ 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);
+ */
+ }
+ virtual void run(void) {
+ testBasic();
+ testAddOperators();
+ testCompareOperators();
+ testCheckDefinition();
+ testCheck();
+ testCheckSameDimension();
+ testResize();
+ testMinMax();
+ testTranspose();
+ testToString();
+ testReadCsv();
+ }
};
-void testRplMatrix(){
- TestRplMatrix test;
+void testRplMatrix() {
+ TestRplMatrix test;
}
class TestReQStringUtil: public ReTest {
public:
- TestReQStringUtil() :
- ReTest("ReQStringUtil"){
- doIt();
- }
+ TestReQStringUtil() :
+ ReTest("ReQStringUtil") {
+ doIt();
+ }
public:
- void testLengthOfUInt64(){
- quint64 value = -3;
- checkEqu(1, ReQStringUtil::lengthOfUInt64(ReString("0"), 0, 10, &value));
- checkEqu(int64_t(0), value);
- checkEqu(3, ReQStringUtil::lengthOfUInt64("x432", 1, 10, &value));
- checkEqu(int64_t(432LL), value);
- checkEqu(3, ReQStringUtil::lengthOfUInt64("x432 x", 1, 10, &value));
- checkEqu(int64_t(432LL), value);
- checkEqu(3, ReQStringUtil::lengthOfUInt64("x432fabc x", 1, 10, &value));
- checkEqu(int64_t(432LL), value);
- checkEqu(16,
- ReQStringUtil::lengthOfUInt64("a1234567890123567", 1, 10, &value));
- checkEqu(int64_t(1234567890123567LL), value);
- checkEqu(10, ReQStringUtil::lengthOfUInt64("x1234abcdef", 1, 16, &value));
- checkEqu(int64_t(0x1234abcdefLL), value);
- checkEqu(3, ReQStringUtil::lengthOfUInt64("432", 0, 8, &value));
- checkEqu(int64_t(0432LL), value);
- checkEqu(6, ReQStringUtil::lengthOfUInt64(" 765432 ", 1, 8, &value));
- checkEqu(int64_t(0765432LL), value);
+ void testLengthOfUInt64() {
+ quint64 value = -3;
+ checkEqu(1,
+ ReQStringUtil::lengthOfUInt64(ReString("0"), 0, 10, &value));
+ checkEqu(int64_t(0), value);
+ checkEqu(3, ReQStringUtil::lengthOfUInt64("x432", 1, 10, &value));
+ checkEqu(int64_t(432LL), value);
+ checkEqu(3, ReQStringUtil::lengthOfUInt64("x432 x", 1, 10, &value));
+ checkEqu(int64_t(432LL), value);
+ checkEqu(3, ReQStringUtil::lengthOfUInt64("x432fabc x", 1, 10, &value));
+ checkEqu(int64_t(432LL), value);
+ checkEqu(16,
+ ReQStringUtil::lengthOfUInt64("a1234567890123567", 1, 10, &value));
+ checkEqu(int64_t(1234567890123567LL), value);
+ checkEqu(10,
+ ReQStringUtil::lengthOfUInt64("x1234abcdef", 1, 16, &value));
+ checkEqu(int64_t(0x1234abcdefLL), value);
+ checkEqu(3, ReQStringUtil::lengthOfUInt64("432", 0, 8, &value));
+ checkEqu(int64_t(0432LL), value);
+ checkEqu(6, ReQStringUtil::lengthOfUInt64(" 765432 ", 1, 8, &value));
+ checkEqu(int64_t(0765432LL), value);
- checkEqu(0, ReQStringUtil::lengthOfUInt64("1 ", 1, 8, &value));
- checkEqu(0, ReQStringUtil::lengthOfUInt64("", 1, 8, &value));
- }
- void testLengthOfUInt(){
- uint value = 3;
- checkEqu(1, ReQStringUtil::lengthOfUInt(ReString("0"), 0, 10, &value));
- checkEqu(0, value);
- checkEqu(3, ReQStringUtil::lengthOfUInt("x432", 1, 10, &value));
- checkEqu(432, value);
- checkEqu(3, ReQStringUtil::lengthOfUInt("x432 x", 1, 10, &value));
- checkEqu(432, value);
- checkEqu(3, ReQStringUtil::lengthOfUInt("x432fabc x", 1, 10, &value));
- checkEqu(432, value);
- checkEqu(3, ReQStringUtil::lengthOfUInt("432", 0, 8, &value));
- checkEqu(0432, value);
- checkEqu(6, ReQStringUtil::lengthOfUInt(" 765432 ", 1, 8, &value));
- checkEqu(0765432, value);
+ checkEqu(0, ReQStringUtil::lengthOfUInt64("1 ", 1, 8, &value));
+ checkEqu(0, ReQStringUtil::lengthOfUInt64("", 1, 8, &value));
+ }
+ void testLengthOfUInt() {
+ uint value = 3;
+ checkEqu(1, ReQStringUtil::lengthOfUInt(ReString("0"), 0, 10, &value));
+ checkEqu(0, value);
+ checkEqu(3, ReQStringUtil::lengthOfUInt("x432", 1, 10, &value));
+ checkEqu(432, value);
+ checkEqu(3, ReQStringUtil::lengthOfUInt("x432 x", 1, 10, &value));
+ checkEqu(432, value);
+ checkEqu(3, ReQStringUtil::lengthOfUInt("x432fabc x", 1, 10, &value));
+ checkEqu(432, value);
+ checkEqu(3, ReQStringUtil::lengthOfUInt("432", 0, 8, &value));
+ checkEqu(0432, value);
+ checkEqu(6, ReQStringUtil::lengthOfUInt(" 765432 ", 1, 8, &value));
+ checkEqu(0765432, value);
- checkEqu(0, ReQStringUtil::lengthOfUInt("1 ", 1, 8, &value));
- checkEqu(0, ReQStringUtil::lengthOfUInt("", 1, 8, &value));
- }
- void testLengthOfReal(){
- qreal value;
- checkEqu(4, ReQStringUtil::lengthOfReal(ReString("0.25"), 0, &value));
- checkEqu(0.25, value);
- checkEqu(3, ReQStringUtil::lengthOfReal(ReString("X.25"), 1, &value));
- checkEqu(0.25, value);
- checkEqu(1, ReQStringUtil::lengthOfReal(ReString(" 0"), 1, &value));
- checkEqu(0.0, value);
- checkEqu(17,
- ReQStringUtil::lengthOfReal(ReString("X12345678901234567"), 1,
- &value));
- checkEqu(12345678901234567.0, value);
- checkEqu(2, ReQStringUtil::lengthOfReal(ReString(".5"), 0, &value));
- checkEqu(0.5, value);
- checkEqu(5, ReQStringUtil::lengthOfReal(ReString("2.5e2x"), 0, &value));
- checkEqu(250.0, value);
- checkEqu(6, ReQStringUtil::lengthOfReal(ReString("2.5e+2"), 0, &value));
- checkEqu(250.0, value);
- checkEqu(7, ReQStringUtil::lengthOfReal(ReString("2.5E-33"), 0, &value));
- checkEqu(2.5e-33, value);
+ checkEqu(0, ReQStringUtil::lengthOfUInt("1 ", 1, 8, &value));
+ checkEqu(0, ReQStringUtil::lengthOfUInt("", 1, 8, &value));
+ }
+ void testLengthOfReal() {
+ qreal value;
+ checkEqu(4, ReQStringUtil::lengthOfReal(ReString("0.25"), 0, &value));
+ checkEqu(0.25, value);
+ checkEqu(3, ReQStringUtil::lengthOfReal(ReString("X.25"), 1, &value));
+ checkEqu(0.25, value);
+ checkEqu(1, ReQStringUtil::lengthOfReal(ReString(" 0"), 1, &value));
+ checkEqu(0.0, value);
+ checkEqu(17,
+ ReQStringUtil::lengthOfReal(ReString("X12345678901234567"), 1,
+ &value));
+ checkEqu(12345678901234567.0, value);
+ checkEqu(2, ReQStringUtil::lengthOfReal(ReString(".5"), 0, &value));
+ checkEqu(0.5, value);
+ checkEqu(5, ReQStringUtil::lengthOfReal(ReString("2.5e2x"), 0, &value));
+ checkEqu(250.0, value);
+ checkEqu(6, ReQStringUtil::lengthOfReal(ReString("2.5e+2"), 0, &value));
+ checkEqu(250.0, value);
+ checkEqu(7,
+ ReQStringUtil::lengthOfReal(ReString("2.5E-33"), 0, &value));
+ checkEqu(2.5e-33, value);
- checkEqu(3, ReQStringUtil::lengthOfReal(ReString("2.5E"), 0, &value));
- checkEqu(2.5, value);
- checkEqu(3, ReQStringUtil::lengthOfReal(ReString("2.5E+"), 0, &value));
- checkEqu(2.5, value);
- checkEqu(3, ReQStringUtil::lengthOfReal(ReString("2.5E-a"), 0, &value));
- checkEqu(2.5, value);
- }
+ checkEqu(3, ReQStringUtil::lengthOfReal(ReString("2.5E"), 0, &value));
+ checkEqu(2.5, value);
+ checkEqu(3, ReQStringUtil::lengthOfReal(ReString("2.5E+"), 0, &value));
+ checkEqu(2.5, value);
+ checkEqu(3, ReQStringUtil::lengthOfReal(ReString("2.5E-a"), 0, &value));
+ checkEqu(2.5, value);
+ }
- void testValueOfHexDigit(){
- checkEqu(0, ReQStringUtil::valueOfHexDigit('0'));
- checkEqu(9, ReQStringUtil::valueOfHexDigit('9'));
- checkEqu(10, ReQStringUtil::valueOfHexDigit('a'));
- checkEqu(15, ReQStringUtil::valueOfHexDigit('f'));
- checkEqu(10, ReQStringUtil::valueOfHexDigit('A'));
- checkEqu(15, ReQStringUtil::valueOfHexDigit('F'));
+ void testValueOfHexDigit() {
+ checkEqu(0, ReQStringUtil::valueOfHexDigit('0'));
+ checkEqu(9, ReQStringUtil::valueOfHexDigit('9'));
+ checkEqu(10, ReQStringUtil::valueOfHexDigit('a'));
+ checkEqu(15, ReQStringUtil::valueOfHexDigit('f'));
+ checkEqu(10, ReQStringUtil::valueOfHexDigit('A'));
+ checkEqu(15, ReQStringUtil::valueOfHexDigit('F'));
- checkEqu(-1, ReQStringUtil::valueOfHexDigit('0' - 1));
- checkEqu(-1, ReQStringUtil::valueOfHexDigit('9' + 1));
- checkEqu(-1, ReQStringUtil::valueOfHexDigit('A' - 1));
- checkEqu(-1, ReQStringUtil::valueOfHexDigit('F' + 1));
- checkEqu(-1, ReQStringUtil::valueOfHexDigit('a' - 1));
- checkEqu(-1, ReQStringUtil::valueOfHexDigit('f' + 1));
- }
- void testUtf8(){
- ReString name = "Heinz Müller";
- char buffer[32];
- checkEqu("Heinz Müller",
- ReQStringUtil::utf8(name, buffer, sizeof buffer));
- memset(buffer, 'x', sizeof buffer);
- checkEqu("Heinz", ReQStringUtil::utf8(name, buffer, (size_t)(5 + 1)));
- checkEqu(buffer[6], 'x');
- }
+ checkEqu(-1, ReQStringUtil::valueOfHexDigit('0' - 1));
+ checkEqu(-1, ReQStringUtil::valueOfHexDigit('9' + 1));
+ checkEqu(-1, ReQStringUtil::valueOfHexDigit('A' - 1));
+ checkEqu(-1, ReQStringUtil::valueOfHexDigit('F' + 1));
+ checkEqu(-1, ReQStringUtil::valueOfHexDigit('a' - 1));
+ checkEqu(-1, ReQStringUtil::valueOfHexDigit('f' + 1));
+ }
+ void testUtf8() {
+ ReString name = "Heinz Müller";
+ char buffer[32];
+ checkEqu("Heinz Müller",
+ ReQStringUtil::utf8(name, buffer, sizeof buffer));
+ memset(buffer, 'x', sizeof buffer);
+ checkEqu("Heinz", ReQStringUtil::utf8(name, buffer, (size_t)(5 + 1)));
+ checkEqu(buffer[6], 'x');
+ }
- void testUnitParser(){
- ReUnitParser parser("-1-2*3*4+2^3*4", NULL);
- checkT(parser.isValid());
- checkEqu(7, parser.asInt());
- checkEqu(7LL, parser.asInt64());
- checkEqu(7.0, parser.asReal());
- }
- void testSizeParser(){
- ReSizeParser parser("2^3byte+2*1k+1m+1g+1t");
- checkT(parser.isValid());
- checkEqu(1001001002008LL, parser.asInt64());
+ void testUnitParser() {
+ ReUnitParser parser("-1-2*3*4+2^3*4", NULL);
+ checkT(parser.isValid());
+ checkEqu(7, parser.asInt());
+ checkEqu(7LL, parser.asInt64());
+ checkEqu(7.0, parser.asReal());
+ }
+ void testSizeParser() {
+ ReSizeParser parser("2^3byte+2*1k+1m+1g+1t");
+ checkT(parser.isValid());
+ checkEqu(1001001002008LL, parser.asInt64());
- ReSizeParser parser2("1ki+1mi+1gi+1ti");
- checkT(parser2.isValid());
- checkEqu(1100586419200ll, parser2.asInt64());
- }
- void testDateTimeParser(){
- ReDateTimeParser parser("3.4.2014");
- checkEqu(QDateTime(QDate(2014, 4, 3)), parser.asDateTime());
- ReDateTimeParser parser2("21.4.2014-2w");
- checkEqu(QDateTime(QDate(2014, 4, 7)), parser2.asDateTime());
- ReDateTimeParser parserB2("1+1min+1h+1day+1week");
- checkT(parserB2.isValid());
- checkEqu(-694861, parserB2.asInt());
- }
- void testLengtOfDate(){
- QDate date;
- checkEqu(8, ReQStringUtil::lengthOfDate("1.2.2001", 0, &date));
- checkEqu(QDate(2001, 2, 1), date);
- checkEqu(9, ReQStringUtil::lengthOfDate("5.12.2001xxx", 0, &date));
- checkEqu(QDate(2001, 12, 5), date);
- checkEqu(10, ReQStringUtil::lengthOfDate("011.10.2001xxx", 1, &date));
- checkEqu(QDate(2001, 10, 11), date);
+ ReSizeParser parser2("1ki+1mi+1gi+1ti");
+ checkT(parser2.isValid());
+ checkEqu(1100586419200ll, parser2.asInt64());
+ }
+ void testDateTimeParser() {
+ ReDateTimeParser parser("3.4.2014");
+ checkEqu(QDateTime(QDate(2014, 4, 3)), parser.asDateTime());
+ ReDateTimeParser parser2("21.4.2014-2w");
+ checkEqu(QDateTime(QDate(2014, 4, 7)), parser2.asDateTime());
+ ReDateTimeParser parserB2("1+1min+1h+1day+1week");
+ checkT(parserB2.isValid());
+ checkEqu(-694861, parserB2.asInt());
+ }
+ void testLengtOfDate() {
+ QDate date;
+ checkEqu(8, ReQStringUtil::lengthOfDate("1.2.2001", 0, &date));
+ checkEqu(QDate(2001, 2, 1), date);
+ checkEqu(9, ReQStringUtil::lengthOfDate("5.12.2001xxx", 0, &date));
+ checkEqu(QDate(2001, 12, 5), date);
+ checkEqu(10, ReQStringUtil::lengthOfDate("011.10.2001xxx", 1, &date));
+ checkEqu(QDate(2001, 10, 11), date);
- checkEqu(8, ReQStringUtil::lengthOfDate("2001.2.1", 0, &date));
- checkEqu(QDate(2001, 2, 1), date);
- checkEqu(9, ReQStringUtil::lengthOfDate("2001.12.5xxx", 0, &date));
- checkEqu(QDate(2001, 12, 5), date);
- checkEqu(10, ReQStringUtil::lengthOfDate("02001.03.01xxx", 1, &date));
- checkEqu(QDate(2001, 3, 1), date);
- }
- void testLengtOfTime(){
- QTime time;
- checkEqu(3, ReQStringUtil::lengthOfTime("1:2", 0, &time));
- checkEqu(QTime(1, 2, 0), time);
- checkEqu(5, ReQStringUtil::lengthOfTime("301:02", 1, &time));
- checkEqu(QTime(1, 2, 0), time);
- checkEqu(7, ReQStringUtil::lengthOfTime("301:02:9", 1, &time));
- checkEqu(QTime(1, 2, 9), time);
- checkEqu(8, ReQStringUtil::lengthOfTime("301:02:09x", 1, &time));
- checkEqu(QTime(1, 2, 9), time);
- }
+ checkEqu(8, ReQStringUtil::lengthOfDate("2001.2.1", 0, &date));
+ checkEqu(QDate(2001, 2, 1), date);
+ checkEqu(9, ReQStringUtil::lengthOfDate("2001.12.5xxx", 0, &date));
+ checkEqu(QDate(2001, 12, 5), date);
+ checkEqu(10, ReQStringUtil::lengthOfDate("02001.03.01xxx", 1, &date));
+ checkEqu(QDate(2001, 3, 1), date);
+ }
+ void testLengtOfTime() {
+ QTime time;
+ checkEqu(3, ReQStringUtil::lengthOfTime("1:2", 0, &time));
+ checkEqu(QTime(1, 2, 0), time);
+ checkEqu(5, ReQStringUtil::lengthOfTime("301:02", 1, &time));
+ checkEqu(QTime(1, 2, 0), time);
+ checkEqu(7, ReQStringUtil::lengthOfTime("301:02:9", 1, &time));
+ checkEqu(QTime(1, 2, 9), time);
+ checkEqu(8, ReQStringUtil::lengthOfTime("301:02:09x", 1, &time));
+ checkEqu(QTime(1, 2, 9), time);
+ }
- virtual void run(void){
- testLengtOfTime();
- testLengtOfDate();
- testDateTimeParser();
- testUnitParser();
- testSizeParser();
- testUtf8();
- testLengthOfUInt64();
- testLengthOfUInt();
- testLengthOfReal();
- testValueOfHexDigit();
- }
+ virtual void run(void) {
+ testLengtOfTime();
+ testLengtOfDate();
+ testDateTimeParser();
+ testUnitParser();
+ testSizeParser();
+ testUtf8();
+ testLengthOfUInt64();
+ testLengthOfUInt();
+ testLengthOfReal();
+ testValueOfHexDigit();
+ }
};
-void testReQStringUtil(){
- TestReQStringUtil test;
+void testReQStringUtil() {
+ TestReQStringUtil test;
}
class TestReSource: public ReTest {
public:
- TestReSource() :
- ReTest("TestReSource"){
- doIt();
- }
+ TestReSource() :
+ ReTest("TestReSource") {
+ doIt();
+ }
private:
- QByteArray m_content1_1;
- QByteArray m_content1_2;
- QByteArray m_content2;
- ReSource m_source;
+ QByteArray m_content1_1;
+ QByteArray m_content1_2;
+ QByteArray m_content2;
+ ReSource m_source;
protected:
- void init(){
- m_content1_1 = "# test\nimport source2\n";
- m_content1_2 = "a=1;\nveeeeeeeeery looooooooooooooong\n";
- m_content2 = "x=2";
- }
+ void init() {
+ m_content1_1 = "# test\nimport source2\n";
+ m_content1_2 = "a=1;\nveeeeeeeeery looooooooooooooong\n";
+ m_content2 = "x=2";
+ }
- void testReStringSourceUnit(){
- ReStringReader reader(m_source);
- QByteArray content("a=1;\nveeeeeeeeery looooooooooooooong\n");
- ReStringSourceUnit unit("test", content, &reader);
- unit.setLineNo(144);
- checkEqu(144, unit.lineNo());
- checkEqu("test", unit.name());
- }
- void checkOne(int maxSize, ReReader& reader){
- QByteArray total;
- QByteArray buffer;
- int lineNo = 0;
- bool hasMore;
- checkF(reader.openSourceUnit("unknownSource"));
- checkT(reader.openSourceUnit("source1"));
- while (reader.nextLine(maxSize, buffer, hasMore)){
- lineNo++;
- total += buffer;
- buffer.clear();
- while (hasMore && reader.fillBuffer(maxSize, buffer, hasMore)){
- total += buffer;
- buffer.clear();
- }
- bool isImport = total.endsWith("source2\n");
- if (isImport){
- reader.openSourceUnit("source2");
- checkEqu("source2", reader.currentSourceUnit()->name());
- while (reader.nextLine(maxSize, buffer, hasMore)){
- lineNo++;
- while (hasMore && reader.fillBuffer(maxSize, buffer, hasMore)){
- total += buffer;
- buffer.clear();
- }
- }
- checkEqu("source1", reader.currentSourceUnit()->name());
- }
- }
- checkEqu(5, lineNo);
- checkEqu(m_content1_1 + m_content2 + m_content1_2, total);
+ void testReStringSourceUnit() {
+ ReStringReader reader(m_source);
+ QByteArray content("a=1;\nveeeeeeeeery looooooooooooooong\n");
+ ReStringSourceUnit unit("test", content, &reader);
+ unit.setLineNo(144);
+ checkEqu(144, unit.lineNo());
+ checkEqu("test", unit.name());
+ }
+ void checkOne(int maxSize, ReReader& reader) {
+ QByteArray total;
+ QByteArray buffer;
+ int lineNo = 0;
+ bool hasMore;
+ checkF(reader.openSourceUnit("unknownSource"));
+ checkT(reader.openSourceUnit("source1"));
+ while (reader.nextLine(maxSize, buffer, hasMore)) {
+ lineNo++;
+ total += buffer;
+ buffer.clear();
+ while (hasMore && reader.fillBuffer(maxSize, buffer, hasMore)) {
+ total += buffer;
+ buffer.clear();
+ }
+ bool isImport = total.endsWith("source2\n");
+ if (isImport) {
+ reader.openSourceUnit("source2");
+ checkEqu("source2", reader.currentSourceUnit()->name());
+ while (reader.nextLine(maxSize, buffer, hasMore)) {
+ lineNo++;
+ while (hasMore
+ && reader.fillBuffer(maxSize, buffer, hasMore)) {
+ total += buffer;
+ buffer.clear();
+ }
+ }
+ checkEqu("source1", reader.currentSourceUnit()->name());
+ }
+ }
+ checkEqu(5, lineNo);
+ checkEqu(m_content1_1 + m_content2 + m_content1_2, total);
- }
+ }
- void testReStringReader(){
- ReStringReader reader(m_source);
- reader.addSource("source1", m_content1_1 + m_content1_2);
- reader.addSource("source2", m_content2);
- ReSourceUnit* unit = reader.openSourceUnit("source1");
- checkNN(unit);
- checkEqu("source1", unit->name());
- checkEqu(0, unit->lineNo());
- checkOne(6, reader);
- checkOne(100, reader);
- reader.replaceSource("source2", "content2");
+ void testReStringReader() {
+ ReStringReader reader(m_source);
+ reader.addSource("source1", m_content1_1 + m_content1_2);
+ reader.addSource("source2", m_content2);
+ ReSourceUnit* unit = reader.openSourceUnit("source1");
+ checkNN(unit);
+ checkEqu("source1", unit->name());
+ checkEqu(0, unit->lineNo());
+ checkOne(6, reader);
+ checkOne(100, reader);
+ reader.replaceSource("source2", "content2");
- unit = reader.openSourceUnit("source2");
- QByteArray buffer;
- bool hasMore;
- checkT(reader.nextLine(50, buffer, hasMore));
- checkEqu("content2", buffer);
- checkF(hasMore);
- }
+ unit = reader.openSourceUnit("source2");
+ QByteArray buffer;
+ bool hasMore;
+ checkT(reader.nextLine(50, buffer, hasMore));
+ checkEqu("content2", buffer);
+ checkF(hasMore);
+ }
public:
- void run(void){
- init();
- testReStringSourceUnit();
- testReStringReader();
- }
+ void run(void) {
+ init();
+ testReStringSourceUnit();
+ testReStringReader();
+ }
};
-void testReSource(){
- TestReSource test;
+void testReSource() {
+ TestReSource test;
}
*/
class TestReStringUtil: public ReTest {
public:
- TestReStringUtil() :
- ReTest("ReStringUtil"){
- doIt();
- }
+ TestReStringUtil() :
+ ReTest("ReStringUtil") {
+ doIt();
+ }
public:
- void testCountChar(){
- checkEqu(1, ReStringUtil::countChar("x", 'x'));
- checkEqu(0, ReStringUtil::countChar("X", 'x'));
- checkEqu(2, ReStringUtil::countChar("xbxxbxx", 'b'));
- }
-
- void testCount(){
- checkEqu(0, ReStringUtil::count("abc", " "));
- checkEqu(1, ReStringUtil::count("abc", "b"));
- checkEqu(2, ReStringUtil::count("axx", "x"));
-
- checkEqu(0, ReStringUtil::count("abbc", "bbb"));
- checkEqu(1, ReStringUtil::count("\n\n", "\n\n"));
- checkEqu(2, ReStringUtil::count(" a ", " "));
- }
-
- void testCutString(){
- QByteArray source("123");
- QByteArray buffer;
- checkEqu(QByteArray("123"), ReStringUtil::cutString(source, 4, buffer));
- checkEqu(QByteArray("123"), ReStringUtil::cutString(source, 3, buffer));
- checkEqu(QByteArray("12..."), ReStringUtil::cutString(source, 2, buffer));
- checkEqu(QByteArray("12"),
- ReStringUtil::cutString(source, 2, buffer, ""));
- }
-
- void testHexDump(){
- QByteArray data("abc123\nxyz");
- checkEqu(QByteArray("61 62 63 31 abc1\n"
- "32 33 0a 78 23.x\n"
- "79 7a yz\n"),
- ReStringUtil::hexDump((uint8_t* ) data.constData(), data.length(), 4));
- checkEqu(QByteArray("61 62 63 31 32 33 0a 78 79 7a abc123.xyz"),
- ReStringUtil::hexDump((uint8_t* ) data.constData(), data.length(),
- 10));
- checkEqu(QByteArray("61 62 63 31 32 33 0a 78 79 7a abc123.xyz"),
- ReStringUtil::hexDump((uint8_t* ) data.constData(), data.length(),
- 12));
- }
-
- void testReadWrite(){
- QByteArray fn = getTempFile("test.dat");
- const char* content = "Hello world\nLine2\n";
- checkT(ReStringUtil::write(fn, content));
- checkEqu(content, ReStringUtil::read(fn, false));
- checkEqu(content, ReStringUtil::read(fn, true) + "\n");
- }
-
- void testToArray(){
- QList < QByteArray > array = ReStringUtil::toArray("1 abc 3", " ");
- checkEqu(3, array.size());
- checkEqu("1", array.at(0));
- checkEqu("abc", array.at(1));
- checkEqu("3", array.at(2));
- }
-
- void testToNumber(){
- checkEqu("3", ReStringUtil::toNumber(3));
- checkEqu("-33", ReStringUtil::toNumber(-33));
- checkEqu("003", ReStringUtil::toNumber(3, "%03d"));
- }
-
- void testLengthOfNumber(){
- checkEqu(3, ReStringUtil::lengthOfNumber("0.3xxx"));
- checkEqu(5, ReStringUtil::lengthOfNumber(" \t0.3xxx"));
- checkEqu(3, ReStringUtil::lengthOfNumber("-.3xxx"));
- checkEqu(2, ReStringUtil::lengthOfNumber(".3exxx"));
- checkEqu(2, ReStringUtil::lengthOfNumber(".3e+xxx"));
- checkEqu(16, ReStringUtil::lengthOfNumber("1234567.9012E+77"));
- checkEqu(17, ReStringUtil::lengthOfNumber("-1234567.9012E+77 "));
- checkEqu(18, ReStringUtil::lengthOfNumber("-1234567.9012E+77 ", true));
- checkEqu(18, ReStringUtil::lengthOfNumber("-1234567.9012E+77 x", true));
- checkEqu(20, ReStringUtil::lengthOfNumber(" -1234567.9012E+77 x", true));
- }
-
- void checkCsv(const char* content, char expected){
- QByteArray fn = getTempFile("testrplstring.csv");
- ReStringUtil::write(fn, content);
- FILE* fp = fopen(fn, "r");
- checkNN(fp);
- char buffer[256];
- checkEqu(expected,
- ReStringUtil::findCsvSeparator(fp, buffer, sizeof buffer));
- fclose(fp);
- }
-
- void testFindCsvSeparator(){
- const char* content = ",,,\t;;;||||";
- checkCsv(content, '\t');
-
- content = "col1,col2\n1.5,3,5\n";
- checkCsv(content, ',');
-
- content = "col1;col2\n1,50;3.5\n"
- "7;8\n10;12\n13;14";
- checkCsv(content, ';');
-
- content = "0.3 7.8 8.9\n7.8 9.4 8.3";
- checkCsv(content, ' ');
-
- content = "0.3|7.8|8.9\n7.8| 9.4|8.3";
- checkCsv(content, '|');
-
- content = "0,3;7.8;8.9";
- checkCsv(content, ';');
- }
- void testLengthOfUInt64(){
- quint64 value = -3;
- checkEqu(1, ReStringUtil::lengthOfUInt64("0", 10, &value));
- checkEqu((int64_t ) 0LL, value);
- checkEqu(3, ReStringUtil::lengthOfUInt64("432", 10, &value));
- checkEqu((int64_t ) 432LL, value);
- checkEqu(3, ReStringUtil::lengthOfUInt64("432 x", 10, &value));
- checkEqu((int64_t ) 432LL, value);
- checkEqu(3, ReStringUtil::lengthOfUInt64("432fabc x", 10, &value));
- checkEqu((int64_t ) 432LL, value);
- checkEqu(16,
- ReStringUtil::lengthOfUInt64("1234567890123567", 10, &value));
- checkEqu((int64_t ) 1234567890123567LL, value);
- checkEqu(10, ReStringUtil::lengthOfUInt64("1234abcdef", 16, &value));
- checkEqu((int64_t ) 0x1234abcdefLL, value);
- checkEqu(3, ReStringUtil::lengthOfUInt64("432", 8, &value));
- checkEqu((int64_t ) 0432LL, value);
- checkEqu(6, ReStringUtil::lengthOfUInt64("765432 ", 8, &value));
- checkEqu((int64_t ) 0765432LL, value);
-
- checkEqu(0, ReStringUtil::lengthOfUInt64(" ", 8, &value));
- checkEqu(0, ReStringUtil::lengthOfUInt64("", 8, &value));
- }
- void testLengthOfReal(){
- qreal value;
- checkEqu(1, ReStringUtil::lengthOfReal("0", &value));
- checkEqu(0.0, value);
- checkEqu(1, ReStringUtil::lengthOfReal("0%", &value));
- checkEqu(0.0, value);
- checkEqu(4, ReStringUtil::lengthOfReal("0.25", &value));
- checkEqu(0.25, value);
- checkEqu(3, ReStringUtil::lengthOfReal(".25", &value));
- checkEqu(0.25, value);
- checkEqu(17, ReStringUtil::lengthOfReal("12345678901234567", &value));
- checkEqu(12345678901234567.0, value);
- checkEqu(2, ReStringUtil::lengthOfReal(".5", &value));
- checkEqu(0.5, value);
- checkEqu(5, ReStringUtil::lengthOfReal("2.5e2x", &value));
- checkEqu(250.0, value);
- checkEqu(6, ReStringUtil::lengthOfReal("2.5e+2", &value));
- checkEqu(250.0, value);
- checkEqu(7, ReStringUtil::lengthOfReal("2.5E-33", &value));
- checkEqu(2.5e-33, value);
-
- checkEqu(3, ReStringUtil::lengthOfReal("2.5E", &value));
- checkEqu(2.5, value);
- checkEqu(3, ReStringUtil::lengthOfReal("2.5E+", &value));
- checkEqu(2.5, value);
- checkEqu(3, ReStringUtil::lengthOfReal("2.5E-a", &value));
- checkEqu(2.5, value);
- }
-
- virtual void run(){
- testLengthOfReal();
- testLengthOfUInt64();
- testCountChar();
- testCount();
- testCutString();
- testToNumber();
- testToArray();
- testHexDump();
- testReadWrite();
- testLengthOfNumber();
- testFindCsvSeparator();
- }
+ void testCountChar() {
+ checkEqu(1, ReStringUtil::countChar("x", 'x'));
+ checkEqu(0, ReStringUtil::countChar("X", 'x'));
+ checkEqu(2, ReStringUtil::countChar("xbxxbxx", 'b'));
+ }
+
+ void testCount() {
+ checkEqu(0, ReStringUtil::count("abc", " "));
+ checkEqu(1, ReStringUtil::count("abc", "b"));
+ checkEqu(2, ReStringUtil::count("axx", "x"));
+
+ checkEqu(0, ReStringUtil::count("abbc", "bbb"));
+ checkEqu(1, ReStringUtil::count("\n\n", "\n\n"));
+ checkEqu(2, ReStringUtil::count(" a ", " "));
+ }
+
+ void testCutString() {
+ QByteArray source("123");
+ QByteArray buffer;
+ checkEqu(QByteArray("123"), ReStringUtil::cutString(source, 4, buffer));
+ checkEqu(QByteArray("123"), ReStringUtil::cutString(source, 3, buffer));
+ checkEqu(QByteArray("12..."),
+ ReStringUtil::cutString(source, 2, buffer));
+ checkEqu(QByteArray("12"),
+ ReStringUtil::cutString(source, 2, buffer, ""));
+ }
+
+ void testHexDump() {
+ QByteArray data("abc123\nxyz");
+ checkEqu(QByteArray("61 62 63 31 abc1\n"
+ "32 33 0a 78 23.x\n"
+ "79 7a yz\n"),
+ ReStringUtil::hexDump((uint8_t* ) data.constData(), data.length(),
+ 4));
+ checkEqu(QByteArray("61 62 63 31 32 33 0a 78 79 7a abc123.xyz"),
+ ReStringUtil::hexDump((uint8_t* ) data.constData(), data.length(),
+ 10));
+ checkEqu(QByteArray("61 62 63 31 32 33 0a 78 79 7a abc123.xyz"),
+ ReStringUtil::hexDump((uint8_t* ) data.constData(), data.length(),
+ 12));
+ }
+
+ void testReadWrite() {
+ QByteArray fn = getTempFile("test.dat");
+ const char* content = "Hello world\nLine2\n";
+ checkT(ReStringUtil::write(fn, content));
+ checkEqu(content, ReStringUtil::read(fn, false));
+ checkEqu(content, ReStringUtil::read(fn, true) + "\n");
+ }
+
+ void testToArray() {
+ QList < QByteArray > array = ReStringUtil::toArray("1 abc 3", " ");
+ checkEqu(3, array.size());
+ checkEqu("1", array.at(0));
+ checkEqu("abc", array.at(1));
+ checkEqu("3", array.at(2));
+ }
+
+ void testToNumber() {
+ checkEqu("3", ReStringUtil::toNumber(3));
+ checkEqu("-33", ReStringUtil::toNumber(-33));
+ checkEqu("003", ReStringUtil::toNumber(3, "%03d"));
+ }
+
+ void testLengthOfNumber() {
+ checkEqu(3, ReStringUtil::lengthOfNumber("0.3xxx"));
+ checkEqu(5, ReStringUtil::lengthOfNumber(" \t0.3xxx"));
+ checkEqu(3, ReStringUtil::lengthOfNumber("-.3xxx"));
+ checkEqu(2, ReStringUtil::lengthOfNumber(".3exxx"));
+ checkEqu(2, ReStringUtil::lengthOfNumber(".3e+xxx"));
+ checkEqu(16, ReStringUtil::lengthOfNumber("1234567.9012E+77"));
+ checkEqu(17, ReStringUtil::lengthOfNumber("-1234567.9012E+77 "));
+ checkEqu(18, ReStringUtil::lengthOfNumber("-1234567.9012E+77 ", true));
+ checkEqu(18, ReStringUtil::lengthOfNumber("-1234567.9012E+77 x", true));
+ checkEqu(20,
+ ReStringUtil::lengthOfNumber(" -1234567.9012E+77 x", true));
+ }
+
+ void checkCsv(const char* content, char expected) {
+ QByteArray fn = getTempFile("testrplstring.csv");
+ ReStringUtil::write(fn, content);
+ FILE* fp = fopen(fn, "r");
+ checkNN(fp);
+ char buffer[256];
+ checkEqu(expected,
+ ReStringUtil::findCsvSeparator(fp, buffer, sizeof buffer));
+ fclose(fp);
+ }
+
+ void testFindCsvSeparator() {
+ const char* content = ",,,\t;;;||||";
+ checkCsv(content, '\t');
+
+ content = "col1,col2\n1.5,3,5\n";
+ checkCsv(content, ',');
+
+ content = "col1;col2\n1,50;3.5\n"
+ "7;8\n10;12\n13;14";
+ checkCsv(content, ';');
+
+ content = "0.3 7.8 8.9\n7.8 9.4 8.3";
+ checkCsv(content, ' ');
+
+ content = "0.3|7.8|8.9\n7.8| 9.4|8.3";
+ checkCsv(content, '|');
+
+ content = "0,3;7.8;8.9";
+ checkCsv(content, ';');
+ }
+ void testLengthOfUInt64() {
+ quint64 value = -3;
+ checkEqu(1, ReStringUtil::lengthOfUInt64("0", 10, &value));
+ checkEqu((int64_t ) 0LL, value);
+ checkEqu(3, ReStringUtil::lengthOfUInt64("432", 10, &value));
+ checkEqu((int64_t ) 432LL, value);
+ checkEqu(3, ReStringUtil::lengthOfUInt64("432 x", 10, &value));
+ checkEqu((int64_t ) 432LL, value);
+ checkEqu(3, ReStringUtil::lengthOfUInt64("432fabc x", 10, &value));
+ checkEqu((int64_t ) 432LL, value);
+ checkEqu(16,
+ ReStringUtil::lengthOfUInt64("1234567890123567", 10, &value));
+ checkEqu((int64_t ) 1234567890123567LL, value);
+ checkEqu(10, ReStringUtil::lengthOfUInt64("1234abcdef", 16, &value));
+ checkEqu((int64_t ) 0x1234abcdefLL, value);
+ checkEqu(3, ReStringUtil::lengthOfUInt64("432", 8, &value));
+ checkEqu((int64_t ) 0432LL, value);
+ checkEqu(6, ReStringUtil::lengthOfUInt64("765432 ", 8, &value));
+ checkEqu((int64_t ) 0765432LL, value);
+
+ checkEqu(0, ReStringUtil::lengthOfUInt64(" ", 8, &value));
+ checkEqu(0, ReStringUtil::lengthOfUInt64("", 8, &value));
+ }
+ void testLengthOfReal() {
+ qreal value;
+ checkEqu(1, ReStringUtil::lengthOfReal("0", &value));
+ checkEqu(0.0, value);
+ checkEqu(1, ReStringUtil::lengthOfReal("0%", &value));
+ checkEqu(0.0, value);
+ checkEqu(4, ReStringUtil::lengthOfReal("0.25", &value));
+ checkEqu(0.25, value);
+ checkEqu(3, ReStringUtil::lengthOfReal(".25", &value));
+ checkEqu(0.25, value);
+ checkEqu(17, ReStringUtil::lengthOfReal("12345678901234567", &value));
+ checkEqu(12345678901234567.0, value);
+ checkEqu(2, ReStringUtil::lengthOfReal(".5", &value));
+ checkEqu(0.5, value);
+ checkEqu(5, ReStringUtil::lengthOfReal("2.5e2x", &value));
+ checkEqu(250.0, value);
+ checkEqu(6, ReStringUtil::lengthOfReal("2.5e+2", &value));
+ checkEqu(250.0, value);
+ checkEqu(7, ReStringUtil::lengthOfReal("2.5E-33", &value));
+ checkEqu(2.5e-33, value);
+
+ checkEqu(3, ReStringUtil::lengthOfReal("2.5E", &value));
+ checkEqu(2.5, value);
+ checkEqu(3, ReStringUtil::lengthOfReal("2.5E+", &value));
+ checkEqu(2.5, value);
+ checkEqu(3, ReStringUtil::lengthOfReal("2.5E-a", &value));
+ checkEqu(2.5, value);
+ }
+
+ virtual void run() {
+ testLengthOfReal();
+ testLengthOfUInt64();
+ testCountChar();
+ testCount();
+ testCutString();
+ testToNumber();
+ testToArray();
+ testHexDump();
+ testReadWrite();
+ testLengthOfNumber();
+ testFindCsvSeparator();
+ }
};
-void testReStringUtil(){
- TestReStringUtil test;
+void testReStringUtil() {
+ TestReStringUtil test;
}
class TestReTraverser: public ReTestUnit {
public:
- TestReTraverser() :
- ReTestUnit("ReTraverser", __FILE__),
- m_base(),
- m_buffer(),
- m_logger(ReLogger::globalLogger()){
- m_base = testDir();
- m_base.append("traverser");
- _mkdir(m_base.str(), ALLPERMS);
- m_base.append(OS_SEPARATOR, -1);
- run();
- ReDirectory::deleteTree(m_base.str(), true);
- }
+ TestReTraverser() :
+ ReTestUnit("ReTraverser", __FILE__),
+ m_base(),
+ m_buffer(),
+ m_logger(ReLogger::globalLogger()) {
+ m_base = testDir();
+ m_base.append("traverser");
+ _mkdir(m_base.str(), ALLPERMS);
+ m_base.append(OS_SEPARATOR, -1);
+ run();
+ ReDirectory::deleteTree(m_base.str(), true);
+ }
private:
- ReByteBuffer m_base;
- ReByteBuffer m_buffer;
- ReLogger* m_logger;
+ ReByteBuffer m_base;
+ ReByteBuffer m_buffer;
+ ReLogger* m_logger;
private:
- const char* makeDir(const char* relPath){
- m_buffer = m_base;
- m_buffer.append(relPath);
- m_buffer.replaceAll("/", 1, OS_SEPARATOR, -1);
- _mkdir(m_buffer.str(), ALLPERMS);
- struct stat info;
- if (stat(m_buffer.str(), &info) != 0){
- logF(true, "cannot create dir %1$s", m_buffer.str());
- }
- return m_buffer.str();
- }
- void makeFile(const char* relPath){
- ReByteBuffer path(m_base);
- path.append("/").append(relPath);
- path.replaceAll("/", 1, OS_SEPARATOR, -1);
- createFile(path.str(), relPath);
- struct stat info;
- if (stat(path.str(), &info) != 0){
- logF(true, "cannot create file %1$s", path.str());
- }
- }
- void initTree(){
- makeFile("1.txt");
- makeDir("dir1");
- makeDir("dir2");
- makeDir("dir1/dir1_1");
- makeDir("dir1/dir1_2");
- makeDir("dir1/dir1_2/dir1_2_1");
- makeDir("dir1/cache");
- makeFile("dir1/dir1_2/dir1_2_1/x1.txt");
- makeFile("dir1/dir1_2/dir1_2_1/x2.txt");
- makeFile("dir2/2.x");
- makeFile("dir1/cache/cache.txt");
- }
- void run(){
- testFilter();
- initTree();
+ const char* makeDir(const char* relPath) {
+ m_buffer = m_base;
+ m_buffer.append(relPath);
+ m_buffer.replaceAll("/", 1, OS_SEPARATOR, -1);
+ _mkdir(m_buffer.str(), ALLPERMS);
+ struct stat info;
+ if (stat(m_buffer.str(), &info) != 0) {
+ logF(true, "cannot create dir %1$s", m_buffer.str());
+ }
+ return m_buffer.str();
+ }
+ void makeFile(const char* relPath) {
+ ReByteBuffer path(m_base);
+ path.append("/").append(relPath);
+ path.replaceAll("/", 1, OS_SEPARATOR, -1);
+ createFile(path.str(), relPath);
+ struct stat info;
+ if (stat(path.str(), &info) != 0) {
+ logF(true, "cannot create file %1$s", path.str());
+ }
+ }
+ void initTree() {
+ makeFile("1.txt");
+ makeDir("dir1");
+ makeDir("dir2");
+ makeDir("dir1/dir1_1");
+ makeDir("dir1/dir1_2");
+ makeDir("dir1/dir1_2/dir1_2_1");
+ makeDir("dir1/cache");
+ makeFile("dir1/dir1_2/dir1_2_1/x1.txt");
+ makeFile("dir1/dir1_2/dir1_2_1/x2.txt");
+ makeFile("dir2/2.x");
+ makeFile("dir1/cache/cache.txt");
+ }
+ void run() {
+ testFilter();
+ initTree();
- testBasic();
- testList();
- }
- void testFilter(){
- ReDirEntryFilter filter;
+ testBasic();
+ testList();
+ }
+ void testFilter() {
+ ReDirEntryFilter filter;
- }
- void testList(){
- const char* argv[] = { "list", m_base.str(), NULL };
- ReDirList(m_logger).run(2, argv);
- }
- void testCopyFile(){
+ }
+ void testList() {
+ const char* argv[] = { "list", m_base.str(), NULL };
+ ReDirList(m_logger).run(2, argv);
+ }
+ void testCopyFile() {
#if defined __linux__
- ReByteBuffer src(m_base);
- src.append("dir1/dir1_2/dir1_2_1/x1.txt");
- ReByteBuffer trg(testDir());
- trg.append("copy_x1.txt");
- ReByteBuffer buffer;
- buffer.ensureSize(5);
- ReDirSync::copyFile(src.str(), NULL, trg.str(), buffer,
- ReLogger::globalLogger());
- checkFileEqu(src.str(), trg.str());
+ ReByteBuffer src(m_base);
+ src.append("dir1/dir1_2/dir1_2_1/x1.txt");
+ ReByteBuffer trg(testDir());
+ trg.append("copy_x1.txt");
+ ReByteBuffer buffer;
+ buffer.ensureSize(5);
+ ReDirSync::copyFile(src.str(), NULL, trg.str(), buffer,
+ ReLogger::globalLogger());
+ checkFileEqu(src.str(), trg.str());
#else
- log(false, "testCopyFile not implemented");
+ log(false, "testCopyFile not implemented");
#endif
- }
+ }
- void checkRelDate(time_t absTime, int relTime){
- int diff = int(time(NULL) - relTime - absTime);
- if (diff < 0)
- diff = -diff;
- checkT(diff < 2);
- }
+ void checkRelDate(time_t absTime, int relTime) {
+ int diff = int(time(NULL) - relTime - absTime);
+ if (diff < 0)
+ diff = -diff;
+ checkT(diff < 2);
+ }
- void checkOneFile(const char* node, const char* parent,
- const ReHashList& hash){
- ReByteBuffer path, expected;
- checkT(hash.get(ReByteBuffer(node), path));
- expected.set(parent, -1);
- if (!expected.endsWith(OS_SEPARATOR))
- expected.append(OS_SEPARATOR);
- if (!path.endsWith(expected.str(), -1))
- checkT(false);
- }
- void testBasic(){
- ReTraverser traverser(m_base.str());
- RePatternList patterns;
- // exclude */cache/*
- ReByteBuffer buffer(";*;-cache");
- patterns.set(buffer.str());
- traverser.setDirPattern(&patterns);
- int level = 0;
- ReDirStatus_t* entry;
- ReHashList hashPath;
- ReSeqArray listChanged;
- int state = 0;
- while ((entry = traverser.rawNextFile(level)) != NULL){
- const char* node = entry->node();
- hashPath.put(ReByteBuffer(node, -1), entry->m_path);
- if (traverser.hasChangedPath(state))
- listChanged.add(-1, node);
- logF(false, "%d: %-12s %2d %s", level, node, int(entry->fileSize()),
- entry->m_path.str());
- }
- checkOneFile("x1.txt", "dir1_2_1", hashPath);
- checkOneFile("x2.txt", "dir1_2_1", hashPath);
- bool changed1 = listChanged.find("x1.txt") != (ReSeqArray::Index) - 1;
- bool changed2 = listChanged.find("x2.txt") != (ReSeqArray::Index) - 1;
- checkT(changed1 != changed2);
- checkOneFile("dir1_2_1", "dir1_2", hashPath);
- checkT(listChanged.find("dir1_2_1") >= 0);
- checkOneFile("dir1_1", "dir1", hashPath);
- checkOneFile("dir1_2", "dir1", hashPath);
- changed1 = listChanged.find("dir1_1") != (ReSeqArray::Index) - 1;
- changed2 = listChanged.find("dir1_2") != (ReSeqArray::Index) - 1;
- checkT(changed1 != changed2);
- checkF(hashPath.get("cache.txt", buffer));
- }
+ void checkOneFile(const char* node, const char* parent,
+ const ReHashList& hash) {
+ ReByteBuffer path, expected;
+ checkT(hash.get(ReByteBuffer(node), path));
+ expected.set(parent, -1);
+ if (!expected.endsWith(OS_SEPARATOR))
+ expected.append(OS_SEPARATOR);
+ if (!path.endsWith(expected.str(), -1))
+ checkT(false);
+ }
+ void testBasic() {
+ ReTraverser traverser(m_base.str());
+ RePatternList patterns;
+ // exclude */cache/*
+ ReByteBuffer buffer(";*;-cache");
+ patterns.set(buffer.str());
+ traverser.setDirPattern(&patterns);
+ int level = 0;
+ ReDirStatus_t* entry;
+ ReHashList hashPath;
+ ReSeqArray listChanged;
+ int state = 0;
+ while ((entry = traverser.rawNextFile(level)) != NULL) {
+ const char* node = entry->node();
+ hashPath.put(ReByteBuffer(node, -1), entry->m_path);
+ if (traverser.hasChangedPath(state))
+ listChanged.add(-1, node);
+ logF(false, "%d: %-12s %2d %s", level, node, int(entry->fileSize()),
+ entry->m_path.str());
+ }
+ checkOneFile("x1.txt", "dir1_2_1", hashPath);
+ checkOneFile("x2.txt", "dir1_2_1", hashPath);
+ bool changed1 = listChanged.find("x1.txt") != (ReSeqArray::Index) - 1;
+ bool changed2 = listChanged.find("x2.txt") != (ReSeqArray::Index) - 1;
+ checkT(changed1 != changed2);
+ checkOneFile("dir1_2_1", "dir1_2", hashPath);
+ checkT(listChanged.find("dir1_2_1") >= 0);
+ checkOneFile("dir1_1", "dir1", hashPath);
+ checkOneFile("dir1_2", "dir1", hashPath);
+ changed1 = listChanged.find("dir1_1") != (ReSeqArray::Index) - 1;
+ changed2 = listChanged.find("dir1_2") != (ReSeqArray::Index) - 1;
+ checkT(changed1 != changed2);
+ checkF(hashPath.get("cache.txt", buffer));
+ }
};
extern void testReTraverser(void);
-void testReTraverser(void){
- TestReTraverser unit;
+void testReTraverser(void) {
+ TestReTraverser unit;
}
class TestReVM: public ReTest {
private:
- ReSource m_source;
- ReASTree m_tree;
- ReStringReader m_reader;
- const char* m_currentSource;
+ ReSource m_source;
+ ReASTree m_tree;
+ ReStringReader m_reader;
+ const char* m_currentSource;
public:
- TestReVM() :
- ReTest("ReVM"), m_source(), m_tree(), m_reader(m_source){
- m_source.addReader(&m_reader);
- doIt();
- }
+ TestReVM() :
+ ReTest("ReVM"),
+ m_source(),
+ m_tree(),
+ m_reader(m_source) {
+ m_source.addReader(&m_reader);
+ doIt();
+ }
protected:
- void setSource(const char* content){
- ReASItem::reset();
- m_currentSource = content;
- m_tree.clear();
- m_source.clear();
- m_reader.clear();
- m_reader.addSource("<test>", content);
- m_source.addReader(&m_reader);
- m_source.addSourceUnit(m_reader.currentSourceUnit());
- }
+ void setSource(const char* content) {
+ ReASItem::reset();
+ m_currentSource = content;
+ m_tree.clear();
+ m_source.clear();
+ m_reader.clear();
+ m_reader.addSource("<test>", content);
+ m_source.addReader(&m_reader);
+ m_source.addSourceUnit(m_reader.currentSourceUnit());
+ }
private:
- void checkAST(const char* fileExpected, int lineNo){
- QByteArray fnExpected = "test";
- fnExpected += QDir::separator().toLatin1();
- fnExpected += "ReVM";
- fnExpected += (char) QDir::separator().toLatin1();
- fnExpected += fileExpected;
- QByteArray fnCurrent = getTempFile(fileExpected, "ReVM");
- ReMFParser parser(m_source, m_tree);
- parser.parse();
- ReVirtualMachine vm(m_tree, m_source);
- vm.setFlag(ReVirtualMachine::VF_TRACE_STATEMENTS);
- ReFileWriter writer(fnCurrent);
- vm.setTraceWriter(&writer);
- writer.write(m_currentSource);
- vm.executeModule("<test>");
- assertEqualFiles(fnExpected.constData(), fnCurrent.constData(),
- __FILE__, lineNo);
- }
+ void checkAST(const char* fileExpected, int lineNo) {
+ QByteArray fnExpected = "test";
+ fnExpected += QDir::separator().toLatin1();
+ fnExpected += "ReVM";
+ fnExpected += (char) QDir::separator().toLatin1();
+ fnExpected += fileExpected;
+ QByteArray fnCurrent = getTempFile(fileExpected, "ReVM");
+ ReMFParser parser(m_source, m_tree);
+ parser.parse();
+ ReVirtualMachine vm(m_tree, m_source);
+ vm.setFlag(ReVirtualMachine::VF_TRACE_STATEMENTS);
+ ReFileWriter writer(fnCurrent);
+ vm.setTraceWriter(&writer);
+ writer.write(m_currentSource);
+ vm.executeModule("<test>");
+ assertEqualFiles(fnExpected.constData(), fnCurrent.constData(),
+ __FILE__, lineNo);
+ }
public:
- void baseTest(){
- setSource("Int a=2+3*4;\nfunc Void main():\na;\nendf");
- checkAST("baseTest.txt", __LINE__);
- }
- virtual void run(void){
- baseTest();
- }
+ void baseTest() {
+ setSource("Int a=2+3*4;\nfunc Void main():\na;\nendf");
+ checkAST("baseTest.txt", __LINE__);
+ }
+ virtual void run(void) {
+ baseTest();
+ }
};
-void testReVM(){
- TestReVM test;
+void testReVM() {
+ TestReVM test;
}
*/
class TestReWriter: public ReTest {
public:
- TestReWriter() :
- ReTest("ReWriter"){
- doIt();
- }
+ TestReWriter() :
+ ReTest("ReWriter") {
+ doIt();
+ }
private:
- void testFileWriter(){
- QByteArray fn = getTempFile("rplwriter.txt");
- ReFileWriter writer(fn);
- writer.writeLine("abc");
- writer.formatLine("%04d", 42);
- writer.writeIndented(3, "123");
- writer.indent(2);
- writer.write("pi");
- writer.format("%3c%.2f", ':', 3.1415);
- writer.writeLine();
- writer.close();
- QByteArray current = ReStringUtil::read(fn, false);
- checkEqu("abc\n0042\n\t\t\t123\n\t\tpi :3.14\n", current);
- }
+ void testFileWriter() {
+ QByteArray fn = getTempFile("rplwriter.txt");
+ ReFileWriter writer(fn);
+ writer.writeLine("abc");
+ writer.formatLine("%04d", 42);
+ writer.writeIndented(3, "123");
+ writer.indent(2);
+ writer.write("pi");
+ writer.format("%3c%.2f", ':', 3.1415);
+ writer.writeLine();
+ writer.close();
+ QByteArray current = ReStringUtil::read(fn, false);
+ checkEqu("abc\n0042\n\t\t\t123\n\t\tpi :3.14\n", current);
+ }
public:
- virtual void run(void){
- testFileWriter();
- }
+ virtual void run(void) {
+ testFileWriter();
+ }
};
-void testReWriter(){
- TestReWriter test;
+void testReWriter() {
+ TestReWriter test;
}
* The latest sources: https://github.com/republib
*/
-
#include <QCoreApplication>
-int main(int argc, char *argv[])
-{
- QCoreApplication a(argc, argv);
- void allTests();
- allTests();
- return a.exec();
+int main(int argc, char *argv[]) {
+ QCoreApplication a(argc, argv);
+ void allTests();
+ allTests();
+ return a.exec();
}
* @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){
+ 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 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){
+ 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();
- }
+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();
+ }
}
/**
*
* @param scope OUT: status info
*/
-void ReSymbolSpace::startScope(ReASScope& scope){
- scope.m_varNoAtStart = m_listOfVars.size();
+void ReSymbolSpace::startScope(ReASScope& scope) {
+ scope.m_varNoAtStart = m_listOfVars.size();
}
/**
* 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);
- }
+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);
+ }
}
/**
* @return NULL: not found<br>
* 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;
+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;
}
/**
* @return NULL: not found<br>
* 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;
+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;
}
/**
* @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;
+ReASMethod* ReSymbolSpace::findMethod(const QByteArray& name) const {
+ ReASMethod* rc = NULL;
+ if (m_methods.contains(name))
+ rc = m_methods[name];
+ return rc;
}
/**
* @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 ? "<none>" : 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 <QByteArray>());
- QList <QByteArray>::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 <QByteArray>());
- QList <QByteArray>::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 <QByteArray>::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);
- }
+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 ? "<none>" : 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<QByteArray>());
+ QList<QByteArray>::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<QByteArray>());
+ QList<QByteArray>::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<QByteArray>::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);
+ }
}
/**
* @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;
+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;
}
/**
* @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;
+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;
+ReSymbolSpace::VariableList ReSymbolSpace::listOfVars() const {
+ return m_listOfVars;
}
/**
* @return the symbolspace of the object (module, method, class..) containing
* the object belonging to the instance
*/
-ReSymbolSpace* ReSymbolSpace::parent() const{
- return m_parent;
+ReSymbolSpace* ReSymbolSpace::parent() const {
+ return m_parent;
}
/**
* @return NULL: no body available<br>
* othewise: the body of the instance
*/
-ReASItem* ReSymbolSpace::body() const{
- return m_body;
+ReASItem* ReSymbolSpace::body() const {
+ return m_body;
}
/**
*
* @param body the new body
*/
-void ReSymbolSpace::setBody(ReASItem* body){
- m_body = body;
+void ReSymbolSpace::setBody(ReASItem* body) {
+ m_body = body;
}
/**
* @return NULL: success<br>
* 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;
+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;
}
/**
* @return NULL: success<br>
* 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;
+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.
* @return NULL: success<br>
* 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 <ReASUserClass*>(m_classes[name]);
- }else{
- m_classes[name] = clazz;
- }
- return rc;
+ReASUserClass* ReSymbolSpace::addClass(ReASUserClass* clazz) {
+ ReASUserClass* rc = NULL;
+ const QByteArray& name = clazz->name();
+ if (m_classes.contains(name)) {
+ rc = dynamic_cast<ReASUserClass*>(m_classes[name]);
+ } else {
+ m_classes[name] = clazz;
+ }
+ return rc;
}
/**
*
* @return the name
*/
-const QByteArray& ReSymbolSpace::name() const{
- return m_name;
+const QByteArray& ReSymbolSpace::name() const {
+ return m_name;
}
/** @class ReASBoolean rplastree.hpp "rplexpr/rplastree.hpp"
* @brief Constructor.
*/
ReASBoolean::ReASBoolean(ReASTree& tree) :
- ReASClass("Bool", tree){
+ ReASClass("Bool", tree) {
}
/**
* @brief Creates a value object (used in ReASVariant).
* @param source NULL or a source to copy
* @return NULL
*/
-void* ReASBoolean::newValueInstance(void*) const{
- return NULL;
+void* ReASBoolean::newValueInstance(void*) const {
+ return NULL;
}
/**
*
* @param object object to destroy
*/
-void ReASBoolean::destroyValueInstance(void*) const{
+void ReASBoolean::destroyValueInstance(void*) const {
}
/**
* @param object the object to test (with type QList*)
* @return false
*/
-bool ReASBoolean::boolValueOf(void*) const{
- return false;
+bool ReASBoolean::boolValueOf(void*) const {
+ return false;
}
/**
* @param maxLength not used
* @return a string describing the <code>object</code>
*/
-QByteArray ReASBoolean::toString(void* object, int) const{
- return ((ReASVariant*) object)->asBool() ? "True" : "False";
+QByteArray ReASBoolean::toString(void* object, int) const {
+ return ((ReASVariant*) object)->asBool() ? "True" : "False";
}
/** @class ReASNumber rplastree.hpp "rplexpr/rplastree.hpp"
* @brief Constructor.
*/
ReASFloat::ReASFloat(ReASTree& tree) :
- ReASClass("Float", tree){
+ ReASClass("Float", tree) {
}
ReASFloat::ReASFloat(const QByteArray& name, ReASTree& tree) :
- ReASClass(name, tree){
- m_superClass = ReASFloat::m_instance;
+ ReASClass(name, tree) {
+ m_superClass = ReASFloat::m_instance;
}
/**
* @brief Creates a value object (used in ReASVariant).
* @param source NULL or a source to copy
* @return NULL
*/
-void* ReASFloat::newValueInstance(void*) const{
- return NULL;
+void* ReASFloat::newValueInstance(void*) const {
+ return NULL;
}
/**
*
* @param object object to destroy
*/
-void ReASFloat::destroyValueInstance(void*) const{
+void ReASFloat::destroyValueInstance(void*) const {
}
/**
* @param object the object to test
* @return false
*/
-bool ReASFloat::boolValueOf(void*) const{
- return false;
+bool ReASFloat::boolValueOf(void*) const {
+ return false;
}
/**
* @param maxLength not used
* @return a string describing the <code>object</code>
*/
-QByteArray ReASFloat::toString(void* object, int) const{
- char buffer[256];
+QByteArray ReASFloat::toString(void* object, int) const {
+ char buffer[256];
- qsnprintf(buffer, sizeof buffer, "%f", ((ReASVariant *) object)->asFloat());
- return buffer;
+ qsnprintf(buffer, sizeof buffer, "%f", ((ReASVariant *) object)->asFloat());
+ return buffer;
}
/** @class ReASInteger rplastree.hpp "rplexpr/rplastree.hpp"
* @brief Constructor.
*/
ReASInteger::ReASInteger(ReASTree& tree) :
- ReASFloat("Int", tree){
+ ReASFloat("Int", tree) {
}
/**
* @param object the object to test
* @return false
*/
-bool ReASInteger::boolValueOf(void*) const{
- return false;
+bool ReASInteger::boolValueOf(void*) const {
+ return false;
}
/**
* @param maxLength the maximum length of the result
* @return a string describing the <code>object</code>
*/
-QByteArray ReASInteger::toString(void* object, int maxLength) const{
- char buffer[64];
- qsnprintf(buffer, sizeof buffer, "%.*d", maxLength,
- ((ReASVariant *) object)->asInt());
- return buffer;
+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 Constructor.
*/
ReASString::ReASString(ReASTree& tree) :
- ReASClass("Str", 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;
+void* ReASString::newValueInstance(void* source) const {
+ QByteArray* rc =
+ source == NULL ?
+ new QByteArray() : new QByteArray(*(QByteArray*) source);
+ return (void*) rc;
}
/**
*
* @param object object to destroy
*/
-void ReASString::destroyValueInstance(void* object) const{
- delete (QByteArray*) object;
+void ReASString::destroyValueInstance(void* object) const {
+ delete (QByteArray*) object;
}
/**
* @return false: the string is empty
* true: otherwise
*/
-bool ReASString::boolValueOf(void* object) const{
- bool rc = false;
- if (object != NULL){
- QByteArray* string = static_cast <QByteArray*>(object);
- if (string == NULL)
- throw ReException("ReASString.boolValueOf(): not a string");
- rc = !string->isEmpty();
- }
- return rc;
+bool ReASString::boolValueOf(void* object) const {
+ bool rc = false;
+ if (object != NULL) {
+ QByteArray* string = static_cast<QByteArray*>(object);
+ if (string == NULL)
+ throw ReException("ReASString.boolValueOf(): not a string");
+ rc = !string->isEmpty();
+ }
+ return rc;
}
/**
* @param maxLength the maximum length of the result
* @return a string describing the <code>object</code>
*/
-QByteArray ReASString::toString(void* object, int maxLength) const{
- QByteArray rc;
- QByteArray* string = reinterpret_cast <QByteArray*>(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;
+QByteArray ReASString::toString(void* object, int maxLength) const {
+ QByteArray rc;
+ QByteArray* string = reinterpret_cast<QByteArray*>(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 Constructor.
*/
ReASList::ReASList(ReASTree& tree) :
- ReASClass("List", tree){
+ ReASClass("List", tree) {
}
/**
* @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;
+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;
}
/**
*
* @param object object to destroy
*/
-void ReASList::destroyValueInstance(void* object) const{
- delete static_cast <ReASListOfVariants*>(object);
+void ReASList::destroyValueInstance(void* object) const {
+ delete static_cast<ReASListOfVariants*>(object);
}
/**
* @return false: the list is empty<br>
* true: otherwise
*/
-bool ReASList::boolValueOf(void* object) const{
- bool rc = false;
- if (object != NULL){
- ReASListOfVariants* list = static_cast <ReASListOfVariants*>(object);
- if (list == NULL)
- throw ReException("ReASList.boolValueOf(): not a list");
- rc = !list->empty();
- }
- return rc;
+bool ReASList::boolValueOf(void* object) const {
+ bool rc = false;
+ if (object != NULL) {
+ ReASListOfVariants* list = static_cast<ReASListOfVariants*>(object);
+ if (list == NULL)
+ throw ReException("ReASList.boolValueOf(): not a list");
+ rc = !list->empty();
+ }
+ return rc;
}
/**
* @param maxLength unused
* @return a string describing the <code>object</code>
*/
-QByteArray ReASList::toString(void* object, int maxLength) const{
- QByteArray rc;
- rc.reserve(maxLength);
- rc += "[";
- ReASListOfVariants* list = reinterpret_cast <ReASListOfVariants*>(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;
+QByteArray ReASList::toString(void* object, int maxLength) const {
+ QByteArray rc;
+ rc.reserve(maxLength);
+ rc += "[";
+ ReASListOfVariants* list = reinterpret_cast<ReASListOfVariants*>(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 Constructor.
*/
ReASMap::ReASMap(ReASTree& tree) :
- ReASClass("Map", 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 <ReASMapOfVariants*>(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;
+void* ReASMap::newValueInstance(void* source) const {
+ ReASMapOfVariants* rc = new ReASMapOfVariants();
+ if (source != NULL) {
+ ReASMapOfVariants* source2 = static_cast<ReASMapOfVariants*>(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;
}
/**
*
* @param object object to destroy
*/
-void ReASMap::destroyValueInstance(void* object) const{
- delete (ReASMapOfVariants*) object;
+void ReASMap::destroyValueInstance(void* object) const {
+ delete (ReASMapOfVariants*) 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 <ReASMapOfVariants*>(object);
- if (map == NULL)
- throw ReException("ReASMap.boolValueOf(): not a map");
- rc = map->empty() > 0;
- }
- return rc;
+bool ReASMap::boolValueOf(void* object) const {
+ bool rc = false;
+ if (object != NULL) {
+ ReASMapOfVariants* map = reinterpret_cast<ReASMapOfVariants*>(object);
+ if (map == NULL)
+ throw ReException("ReASMap.boolValueOf(): not a map");
+ rc = map->empty() > 0;
+ }
+ return rc;
}
/**
* @param maxLength maximal length of the result
* @return a string describing the <code>object</code>
*/
-QByteArray ReASMap::toString(void* object, int maxLength) const{
- QByteArray rc;
- rc.reserve(maxLength);
- rc += "[";
- ReASMapOfVariants* map = reinterpret_cast <ReASMapOfVariants*>(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;
+QByteArray ReASMap::toString(void* object, int maxLength) const {
+ QByteArray rc;
+ rc.reserve(maxLength);
+ rc += "[";
+ ReASMapOfVariants* map = reinterpret_cast<ReASMapOfVariants*>(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 Constructor.
*/
ReVariable::ReVariable(const QByteArray& name) :
- m_name(name), m_namespace(NULL), m_value(), m_type(NULL){
+ m_name(name),
+ m_namespace(NULL),
+ m_value(),
+ m_type(NULL) {
}
* @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());
+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;
+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;
+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;
+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){
+ ReASClass("Void", tree) {
}
/**
* @param source ignored
* @return
*/
-void*ReASVoid::newValueInstance(void*) const{
- return NULL;
+void*ReASVoid::newValueInstance(void*) const {
+ return NULL;
}
/**
*
* @param object not used
*/
-void ReASVoid::destroyValueInstance(void*) const{
+void ReASVoid::destroyValueInstance(void*) const {
}
/**
* @param object ignored
* @return false
*/
-bool ReASVoid::boolValueOf(void*) const{
- return false;
+bool ReASVoid::boolValueOf(void*) const {
+ return false;
}
/**
* @param maxLength ignored
* @return the empty string
*/
-QByteArray ReASVoid::toString(void*, int) const{
- return QByteArray("");
+QByteArray ReASVoid::toString(void*, int) const {
+ return QByteArray("");
}
/** @class ReASFormula rplastree.hpp "rplexpr/rplastree.hpp"
* @param tree the abstract syntax tree
*/
ReASFormula::ReASFormula(ReASTree& tree) :
- ReASClass("Formula", tree){
+ ReASClass("Formula", tree) {
}
/**
* @param expr the result
* @return
*/
-void* ReASFormula::newValueInstance(void* expr) const{
- return expr;
+void* ReASFormula::newValueInstance(void* expr) const {
+ return expr;
}
/**
*
* @param object not used
*/
-void ReASFormula::destroyValueInstance(void*) const{
+void ReASFormula::destroyValueInstance(void*) const {
}
/**
* @param object ignored
* @return false
*/
-bool ReASFormula::boolValueOf(void*) const{
- return false;
+bool ReASFormula::boolValueOf(void*) const {
+ return false;
}
/**
* @param maxLength ignored
* @return the empty string
*/
-QByteArray ReASFormula::toString(void* object, int) const{
- ReASExprStatement* expr = static_cast <ReASExprStatement*>(object);
+QByteArray ReASFormula::toString(void* object, int) const {
+ ReASExprStatement* expr = static_cast<ReASExprStatement*>(object);
- char buffer[64];
- qsnprintf(buffer, sizeof buffer, "<formula %d>", expr->id());
- return buffer;
+ char buffer[64];
+ qsnprintf(buffer, sizeof buffer, "<formula %d>", expr->id());
+ return buffer;
}
/** @class ReASUserClass rplastree.hpp "rplexpr/rplastree.hpp"
* @param tree the abstract syntax tree
*/
ReASUserClass::ReASUserClass(const QByteArray& name,
- const ReSourcePosition* position, ReASTree& tree) :
- ReASClass(name, tree), m_position(position){
+ const ReSourcePosition* position, ReASTree& tree) :
+ ReASClass(name, tree),
+ m_position(position) {
}
/**
* @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 <ReASUserClass*>(source);
- ReASUserObject* rc = new ReASUserObject(clazz);
- return static_cast <void*>(rc);
+void*ReASUserClass::newValueInstance(void* source) const {
+ ReASUserClass* clazz = static_cast<ReASUserClass*>(source);
+ ReASUserObject* rc = new ReASUserObject(clazz);
+ return static_cast<void*>(rc);
}
-void ReASUserClass::destroyValueInstance(void* object) const{
- ReASUserObject* obj = static_cast <ReASUserObject*>(object);
- delete obj;
+void ReASUserClass::destroyValueInstance(void* object) const {
+ ReASUserObject* obj = static_cast<ReASUserObject*>(object);
+ delete obj;
}
/**
* @return true: object != NULL<br>
* false: object == NULL
*/
-bool ReASUserClass::boolValueOf(void* object) const{
- return object != NULL;
+bool ReASUserClass::boolValueOf(void* object) const {
+ return object != NULL;
}
/**
* @param maxLength maximum length of the string
* @return
*/
-QByteArray ReASUserClass::toString(void*, int) const{
- return m_name;
+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;
+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){
+ m_class(clazz),
+ m_fields(NULL) {
}
/**
* @brief Destructor.
*/
-ReASUserObject::~ReASUserObject(){
- delete[] m_fields;
- m_fields = NULL;
+ReASUserObject::~ReASUserObject() {
+ delete[] m_fields;
+ m_fields = NULL;
}
class ReSymbolSpace;
class ReVariable {
public:
- ReVariable(const QByteArray& name);
+ ReVariable(const QByteArray& name);
public:
- void dump(ReWriter& writer, int indent);
+ void dump(ReWriter& writer, int indent);
- ReASClass* type() const;
- void setType(ReASClass* type);
- const QByteArray& name() const;
+ 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;
+ 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;
+ 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
- };
+ enum SymbolSpaceType {
+ SST_UNDEF,
+ SST_GLOBAL,
+ SST_MODULE,
+ SST_CLASS,
+ SST_METHOD
+ };
public:
- typedef QMap <QByteArray, ReASVarDefinition*> VariableMap;
- typedef QMap <QByteArray, ReASClass*> ClassMap;
- typedef QMap <QByteArray, ReASMethod*> MethodMap;
- typedef QList <ReASVarDefinition*> VariableList;
+ typedef QMap<QByteArray, ReASVarDefinition*> VariableMap;
+ typedef QMap<QByteArray, ReASClass*> ClassMap;
+ typedef QMap<QByteArray, ReASMethod*> MethodMap;
+ typedef QList<ReASVarDefinition*> 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);
+ 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;
+ 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);
+ 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;
+ 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;
+ static ReASBoolean* m_instance;
};
class ReASFloat: public ReASClass {
public:
- ReASFloat(ReASTree& tree);
- ReASFloat(const QByteArray& name, ReASTree& tree);
+ 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;
+ 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;
+ static ReASFloat* m_instance;
};
class ReASInteger: public ReASFloat {
public:
- ReASInteger(ReASTree& tree);
+ ReASInteger(ReASTree& tree);
public:
- virtual bool boolValueOf(void* object) const;
- virtual QByteArray toString(void *object, int maxLength = 80) const;
+ virtual bool boolValueOf(void* object) const;
+ virtual QByteArray toString(void *object, int maxLength = 80) const;
public:
- static ReASInteger* m_instance;
+ static ReASInteger* m_instance;
};
class ReASString: public ReASClass {
public:
- ReASString(ReASTree& tree);
+ 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;
+ 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;
+ static ReASString* m_instance;
};
class ReASList: public ReASClass {
public:
- ReASList(ReASTree& tree);
+ 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;
+ 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;
+ static ReASList* m_instance;
};
class ReASMap: public ReASClass {
public:
- ReASMap(ReASTree& tree);
+ 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;
+ 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;
+ static ReASMap* m_instance;
};
class ReASVoid: public ReASClass {
public:
- ReASVoid(ReASTree& tree);
+ 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;
+ 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;
+ static ReASVoid* m_instance;
};
class ReASFormula: public ReASClass {
public:
- ReASFormula(ReASTree& tree);
+ 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;
+ 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;
+ static ReASFormula* m_instance;
};
class ReASUserClass: public ReASClass {
public:
- ReASUserClass(const QByteArray& name, const ReSourcePosition* position,
- ReASTree& tree);
+ 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;
+ 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;
+ const ReSourcePosition* m_position;
};
class ReASUserObject {
public:
- ReASUserObject(ReASUserClass* clazz);
- ~ReASUserObject();
+ ReASUserObject(ReASUserClass* clazz);
+ ~ReASUserObject();
public:
- void callMember();
+ void callMember();
private:
- ReASUserClass* m_class;
- ReASVariant* m_fields;
+ ReASUserClass* m_class;
+ ReASVariant* m_fields;
};
#endif // RPLASCLASSES_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;
* @param map map to dump
* @param withEndOfLine true: '\n' will be written at the end
*/
-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 <QByteArray>());
- QList <QByteArray>::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<QByteArray>());
+ QList<QByteArray>::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"
* @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;
+ 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;
}
/**
* @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"
* @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;
}
/**
* @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);
+ m_variantType(source.m_variantType),
+ m_flags(source.m_flags),
+ // m_value
+ m_class(source.m_class) {
+ copyValue(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;
}
/**
*
* @return the type as string
*/
-const char*ReASVariant::nameOfType() const{
- const char* rc = "?";
- switch (m_variantType) {
- case VT_UNDEF:
- rc = "<undef>";
- 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 = "<undef>";
+ 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;
}
/**
*
* @return the variant type
*/
-const ReASClass* ReASVariant::getClass() const{
- return m_class;
+const ReASClass* ReASVariant::getClass() const {
+ return m_class;
}
/**
* @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.
* @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;
}
/**
* @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;
}
/**
* @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;
}
/**
* @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 <const QByteArray*>(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<const QByteArray*>(asObject(&clazz));
+ if (clazz != ReASString::m_instance) {
+ const QByteArray& name = clazz->name();
+ throw ReException("ReASVariant::asString: not a string: %s",
+ name.constData());
+ }
+ return rc;
}
/**
*
* @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;
}
/**
*
* @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;
}
/**
*
* @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;
}
/**
*
* @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);
}
/**
* @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;
}
/**
* @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"
* @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() {
}
/**
* <code>false</code>: otherwise
*/
bool ReASItem::checkAsCalculable(const char* description,
- ReASClass* expectedClass, ReParser& parser){
- RE_UNUSED(expectedClass);
- bool rc = true;
- if (!check(parser))
- rc = false;
- if (rc){
- ReASCalculable* expr = dynamic_cast <ReASCalculable*>(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<ReASCalculable*>(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;
}
/**
*
* @return the position of the item
*/
-const ReSourcePosition* ReASItem::position() const{
- return m_position;
+const ReSourcePosition* ReASItem::position() const {
+ return m_position;
}
/**
*
* @param position the position to store
*/
-void ReASItem::setPosition(const ReSourcePosition* position){
- m_position = position;
+void ReASItem::setPosition(const ReSourcePosition* position) {
+ m_position = position;
}
/**
*
* @return the id
*/
-unsigned int ReASItem::id() const{
- return m_id;
+unsigned int ReASItem::id() const {
+ return m_id;
}
/**
* @param bufferSize size of the target buffer
* @return <code>buffer</code>
*/
-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;
}
/**
* @param format string with placeholders (optional) like <code>sprintf()</code>
* @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.
* @param thread the execution unit
* @return the value described by the node <code>expr</code>
*/
-int ReASItem::calcAsInteger(ReASItem* expr, ReVMThread& thread){
- ReASCalculable* expr2 = dynamic_cast <ReASCalculable*>(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<ReASCalculable*>(expr);
+ expr2->calc(thread);
+ ReASVariant& value = thread.popValue();
+ int rc = value.asInt();
+ return rc;
}
/**
* @param thread the execution unit
* @return the value described by the node <code>expr</code>
*/
-bool ReASItem::calcAsBoolean(ReASItem* expr, ReVMThread& thread){
- ReASCalculable* expr2 = dynamic_cast <ReASCalculable*>(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<ReASCalculable*>(expr);
+ expr2->calc(thread);
+ ReASVariant& value = thread.popValue();
+ bool rc = value.asBool();
+ return rc;
}
/**
* @brief Checks the correctness of a statement list.
* @return <code>true</code>: all statements are correct<br>
* <code>false</code>: otherwise
*/
-bool ReASItem::checkStatementList(ReASItem* list, ReParser& parser){
- bool rc = true;
-
- while (list != NULL){
- if (!list->check(parser))
- rc = false;
- if (dynamic_cast <ReASStatement*>(list) == NULL)
- rc = list->error(LOC_ITEM_STATEM_LIST_1, parser, "not a statement: %s",
- list->nameOfItemType());
- ReASNode1* node = dynamic_cast <ReASNode1*>(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<ReASStatement*>(list) == NULL)
+ rc = list->error(LOC_ITEM_STATEM_LIST_1, parser,
+ "not a statement: %s", list->nameOfItemType());
+ ReASNode1* node = dynamic_cast<ReASNode1*>(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;
}
/**
*
* @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;
}
/**
* @return true: classes are compatible<br>
* 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 ReASItem::typeCheck(ReASClass* class1, ReASClass* class2) {
+ bool rc;
+ if (class1 == NULL || class2 == NULL)
+ rc = false;
+ else
+ //@ToDo: subclasses
+ rc = class1 == class2;
+ return rc;
}
/**
* @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;
}
/**
* @param info additional info
* @return <code>false</code> (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",
- info);
- 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"
* @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"
*
*/
ReASConstant::ReASConstant() :
- ReASItem(AST_CONSTANT), m_value(){
+ ReASItem(AST_CONSTANT),
+ m_value() {
}
/**
*
* @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);
}
/**
* @param parser for error processing
* @return <code>true</code>: a constant is always correct
*/
-bool ReASConstant::check(ReParser& parser){
- RE_UNUSED(&parser);
- return true;
+bool ReASConstant::check(ReParser& parser) {
+ RE_UNUSED(&parser);
+ return true;
}
/**
* @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));
}
/**
*
* @return the internal value
*/
-ReASVariant& ReASConstant::value(){
- return m_value;
+ReASVariant& ReASConstant::value() {
+ return m_value;
}
/** @class ReASListConstant rplastree.hpp "rplexpr/rplastree.hpp"
* @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.
*
* @return the list
*/
-ReASListOfVariants* ReASListConstant::list(){
- ReASListOfVariants* rc = static_cast <ReASListOfVariants*>(m_value.asObject(
- NULL));
- return rc;
+ReASListOfVariants* ReASListConstant::list() {
+ ReASListOfVariants* rc = static_cast<ReASListOfVariants*>(m_value.asObject(
+ NULL));
+ return rc;
}
/**
*
* @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);
}
/**
* @param parser for error processing
* @return <code>true</code>: a constant is always correct
*/
-bool ReASListConstant::check(ReParser& parser){
- RE_UNUSED(&parser);
- return true;
+bool ReASListConstant::check(ReParser& parser) {
+ RE_UNUSED(&parser);
+ return true;
}
/**
* @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());
}
/**
*
* @return the internal value
*/
-ReASVariant& ReASListConstant::value(){
- return m_value;
+ReASVariant& ReASListConstant::value() {
+ return m_value;
}
/** @class ReASMapConstant rplastree.hpp "rplexpr/rplastree.hpp"
* @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);
}
/**
*
* @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);
}
/**
* @param parser for error processing
* @return <code>true</code>: a constant is always correct
*/
-bool ReASMapConstant::check(ReParser& parser){
- RE_UNUSED(&parser);
- return true;
+bool ReASMapConstant::check(ReParser& parser) {
+ RE_UNUSED(&parser);
+ return true;
}
/**
* @brief Writes the internals into a file.
* @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);
}
/**
*
* @return the variant value
*/
-ReASVariant& ReASMapConstant::value(){
- return m_value;
+ReASVariant& ReASMapConstant::value() {
+ return m_value;
}
/**
*
* @return the map of the constant
*/
-ReASMapOfVariants* ReASMapConstant::map(){
- ReASMapOfVariants* rc = static_cast <ReASMapOfVariants*>(m_value.asObject(
- NULL));
- return rc;
+ReASMapOfVariants* ReASMapConstant::map() {
+ ReASMapOfVariants* rc = static_cast<ReASMapOfVariants*>(m_value.asObject(
+ NULL));
+ return rc;
}
/** @class ReASNamedValue rplastree.hpp "rplexpr/rplastree.hpp"
* @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;
+ const QByteArray& name, int attributes) :
+ ReASItem(AST_NAMED_VALUE),
+ m_name(name),
+ m_attributes(attributes),
+ m_symbolSpace(space),
+ m_variableNo(-1) {
+ m_class = clazz;
}
/**
*
* @return the name
*/
-const QByteArray& ReASNamedValue::name() const{
- return m_name;
+const QByteArray& ReASNamedValue::name() const {
+ return m_name;
}
/**
* @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());
}
/**
* @return <code>true</code>: node is correct<br>
* <code>false</code>: otherwise
*/
-bool ReASNamedValue::check(ReParser& parser){
- RE_UNUSED(&parser);
- return true;
+bool ReASNamedValue::check(ReParser& parser) {
+ RE_UNUSED(&parser);
+ return true;
}
/**
* @brief Writes the internals into a file.
* @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));
}
/**
*
* @return the symbol space
*/
-ReSymbolSpace*ReASNamedValue::symbolSpace() const{
- return m_symbolSpace;
+ReSymbolSpace*ReASNamedValue::symbolSpace() const {
+ return m_symbolSpace;
}
/**
*
* @param variableNo the variable number
*/
-void ReASNamedValue::setVariableNo(int variableNo){
- m_variableNo = variableNo;
+void ReASNamedValue::setVariableNo(int variableNo) {
+ m_variableNo = variableNo;
}
/**
*
* @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"
* @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();
}
/**
*
* @param thread execution value
*/
-void ReASConversion::calc(ReVMThread& thread){
- ReASCalculable* expr = dynamic_cast <ReASCalculable*>(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<ReASCalculable*>(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());
}
/**
* 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;
}
/**
* @return <code>true</code>: node is correct<br>
* <code>false</code>: otherwise
*/
-bool ReASConversion::check(ReParser& parser){
- bool rc = m_child != NULL && m_child->check(parser);
- ReASCalculable* expr = dynamic_cast <ReASCalculable*>(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<ReASCalculable*>(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;
}
/**
* @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));
}
/**
* 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 <ReASCalculable*>(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<ReASCalculable*>(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"
* <code>m_child2</code>: the index expression
*/
ReASIndexedValue::ReASIndexedValue() :
- ReASNode2(AST_INDEXED_VALUE){
+ ReASNode2(AST_INDEXED_VALUE) {
}
/**
*
* @param thread execution value
*/
-void ReASIndexedValue::calc(ReVMThread& thread){
- ReASCalculable* expr = dynamic_cast <ReASCalculable*>(m_child2);
- expr->calc(thread);
- ReASVariant& ixValue = thread.popValue();
- int ix = ixValue.asInt();
- ReASCalculable* list = dynamic_cast <ReASCalculable*>(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<ReASCalculable*>(m_child2);
+ expr->calc(thread);
+ ReASVariant& ixValue = thread.popValue();
+ int ix = ixValue.asInt();
+ ReASCalculable* list = dynamic_cast<ReASCalculable*>(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());
}
/**
* @return <code>true</code>: node is correct<br>
* <code>false</code>: otherwise
*/
-bool ReASIndexedValue::check(ReParser& parser){
- ReASCalculable* list = dynamic_cast <ReASCalculable*>(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<ReASCalculable*>(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;
}
/**
* @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"
* @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;
}
/**
* @param writer writes to output
* @param indent nesting level
*/
-void ReASVarDefinition::dump(ReWriter& writer, int indent){
- ReASNamedValue* namedValue = dynamic_cast <ReASNamedValue*>(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<ReASNamedValue*>(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);
}
/**
*
* @return the name
*/
-const QByteArray& ReASVarDefinition::name() const{
- ReASNamedValue* namedValue = dynamic_cast <ReASNamedValue*>(m_child2);
- const QByteArray& rc = namedValue->name();
- return rc;
+const QByteArray& ReASVarDefinition::name() const {
+ ReASNamedValue* namedValue = dynamic_cast<ReASNamedValue*>(m_child2);
+ const QByteArray& rc = namedValue->name();
+ return rc;
}
/**
*
* @return the data type
*/
-ReASClass* ReASVarDefinition::clazz() const{
- ReASNamedValue* namedValue = dynamic_cast <ReASNamedValue*>(m_child2);
- ReASClass* rc = namedValue == NULL ? NULL : namedValue->clazz();
- return rc;
+ReASClass* ReASVarDefinition::clazz() const {
+ ReASNamedValue* namedValue = dynamic_cast<ReASNamedValue*>(m_child2);
+ ReASClass* rc = namedValue == NULL ? NULL : namedValue->clazz();
+ return rc;
}
/**
* @brief Returns the column of the scope end.
*
* @return 0 or the column of the scope end
*/
-int ReASVarDefinition::endOfScope() const{
- return m_endOfScope;
+int ReASVarDefinition::endOfScope() const {
+ return m_endOfScope;
}
/**
*
* @param endOfScope the column of the scope end
*/
-void ReASVarDefinition::setEndOfScope(int endOfScope){
- m_endOfScope = endOfScope;
+void ReASVarDefinition::setEndOfScope(int endOfScope) {
+ m_endOfScope = endOfScope;
}
/**
* @return <code>true</code>: node is correct<br>
* <code>false</code>: otherwise
*/
-bool ReASVarDefinition::check(ReParser& parser){
- ReASNamedValue* var = dynamic_cast <ReASNamedValue*>(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 <ReASCalculable*>(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<ReASNamedValue*>(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<ReASCalculable*>(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;
}
/**
*
* @return 0: continue the current statement list<br>
*/
-int ReASVarDefinition::execute(ReVMThread& thread){
- if (m_child3 != NULL){
- // has an initialization:
- ReASNamedValue* var = dynamic_cast <ReASNamedValue*>(m_child2);
- ReASCalculable* expr = dynamic_cast <ReASCalculable*>(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<ReASNamedValue*>(m_child2);
+ ReASCalculable* expr = dynamic_cast<ReASCalculable*>(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"
* @brief Constructor.
*/
ReASExprStatement::ReASExprStatement() :
- ReASNode2(AST_EXPR_STATEMENT), ReASStatement(){
- m_flags |= NF_STATEMENT;
+ ReASNode2(AST_EXPR_STATEMENT),
+ ReASStatement() {
+ m_flags |= NF_STATEMENT;
}
/**
* @return <code>true</code>: node is correct<br>
* <code>false</code>: otherwise
*/
-bool ReASExprStatement::check(ReParser& parser){
- bool rc = m_child2->check(parser);
- if (rc){
- ReASCalculable* expr = dynamic_cast <ReASCalculable*>(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<ReASCalculable*>(m_child2);
+ if (expr == NULL)
+ rc = ensureError(parser, "ReASExprStatement::check");
+ }
+ return rc;
}
/**
* @brief Executes the statement.
*
* @return 0: continue the current statement list<br>
*/
-int ReASExprStatement::execute(ReVMThread& thread){
- ReASCalculable* expr = dynamic_cast <ReASCalculable*>(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<ReASCalculable*>(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;
}
/**
* @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"
* @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;
}
/**
* @param statements the chain of statements to dump
*/
void ReASNode1::dumpStatements(ReWriter& writer, int indent,
- ReASItem* statements){
- ReASNode1* chain = dynamic_cast <ReASNode1*>(statements);
- while (chain != NULL){
- chain->dump(writer, indent);
- chain = dynamic_cast <ReASNode1*>(chain->m_child);
- }
+ ReASItem* statements) {
+ ReASNode1* chain = dynamic_cast<ReASNode1*>(statements);
+ while (chain != NULL) {
+ chain->dump(writer, indent);
+ chain = dynamic_cast<ReASNode1*>(chain->m_child);
+ }
}
/** @class ReASNode2 rplastree.hpp "rplexpr/rplastree.hpp"
* @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"
* @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;
}
/**
*
* @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"
* @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;
}
/**
*
* @return the child 4
*/
-ReASItem* ReASNode4::child4() const{
- return m_child4;
+ReASItem* ReASNode4::child4() const {
+ return m_child4;
}
/**
*
* @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"
* @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;
}
/**
*
* @return the child 5
*/
-ReASItem* ReASNode5::child5() const{
- return m_child5;
+ReASItem* ReASNode5::child5() const {
+ return m_child5;
}
/**
*
* @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"
* @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;
}
/**
*
* @return the child 5
*/
-ReASItem* ReASNode6::child6() const{
- return m_child6;
+ReASItem* ReASNode6::child6() const {
+ return m_child6;
}
/**
*
* @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"
* @param type the node type
*/
ReASUnaryOp::ReASUnaryOp(UnaryOp op, ReASItemType type) :
- ReASNode1(type), m_operator(op){
+ ReASNode1(type),
+ m_operator(op) {
}
/**
*
* @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());
}
/**
* @return <code>true</code>: node is correct<br>
* <code>false</code>: otherwise
*/
-bool ReASUnaryOp::check(ReParser& parser){
- bool rc = m_child->check(parser);
- if (rc){
- ReASCalculable* expr = dynamic_cast <ReASCalculable*>(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<ReASCalculable*>(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;
}
/**
*
* @return the operator
*/
-int ReASUnaryOp::getOperator() const{
- return m_operator;
+int ReASUnaryOp::getOperator() const {
+ return m_operator;
}
/**
* @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.
* @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 Constructor.
*/
-ReASStatement::ReASStatement(){
+ReASStatement::ReASStatement() {
}
/**
* @brief Executes the statements of a statement list.
* 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 <ReASStatement*>(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<ReASStatement*>(list);
+ rc = statement->execute(thread);
+ }
+ return rc;
}
/** @class ReASIf rplastree.hpp "rplexpr/rplastree.hpp"
*/
ReASIf::ReASIf() :
- ReASNode4(AST_IF){
- m_flags |= NF_STATEMENT;
+ ReASNode4(AST_IF) {
+ m_flags |= NF_STATEMENT;
}
/**
* @return <code>true</code>: node is correct<br>
* <code>false</code>: 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;
}
/**
* 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;
}
/**
* @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"
* @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;
}
/**
* @return <code>true</code>: node is correct<br>
* <code>false</code>: otherwise
*/
-bool ReASForIterated::check(ReParser& parser){
- RE_UNUSED(&parser);
- return false;
+bool ReASForIterated::check(ReParser& parser) {
+ RE_UNUSED(&parser);
+ return false;
}
/**
* 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){
- RE_UNUSED(&thread);
- return 0;
+int ReASForIterated::execute(ReVMThread& thread) {
+ RE_UNUSED(&thread);
+ return 0;
}
/**
* @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"
* @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;
}
/**
* @return <code>true</code>: node is correct<br>
* <code>false</code>: otherwise
*/
-bool ReASForCounted::check(ReParser& parser){
- bool rc = true;
- ReASNamedValue* var = NULL;
- if (m_child3 != NULL){
- var = dynamic_cast <ReASNamedValue*>(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;
+bool ReASForCounted::check(ReParser& parser) {
+ bool rc = true;
+ ReASNamedValue* var = NULL;
+ if (m_child3 != NULL) {
+ var = dynamic_cast<ReASNamedValue*>(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;
}
/**
* 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 <ReASStatement*>(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 <ReASNamedValue*>(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<ReASStatement*>(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<ReASNamedValue*>(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;
}
/**
* @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"
*/
ReASWhile::ReASWhile() :
- ReASNode3(AST_WHILE), ReASStatement(){
- m_flags |= NF_STATEMENT;
+ ReASNode3(AST_WHILE),
+ ReASStatement() {
+ m_flags |= NF_STATEMENT;
}
/**
* @return <code>true</code>: node is correct<br>
* <code>false</code>: 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;
}
/**
* 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 <ReASStatement*>(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<ReASStatement*>(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;
}
/**
* @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"
*/
ReASRepeat::ReASRepeat() :
- ReASNode3(AST_REPEAT), ReASStatement(){
- m_flags |= NF_STATEMENT;
+ ReASNode3(AST_REPEAT),
+ ReASStatement() {
+ m_flags |= NF_STATEMENT;
}
/**
* @return <code>true</code>: node is correct<br>
* <code>false</code>: 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;
}
/**
* m_child: body
* m_child2: condition
*/
-int ReASRepeat::execute(ReVMThread& thread){
- int rc = 0;
- ReASStatement* body = dynamic_cast <ReASStatement*>(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<ReASStatement*>(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;
}
/**
* @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"
* @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) {
}
/**
* Does nothing but forces a virtual destructor of all derived classes.
*
*/
-ReASClass::~ReASClass(){
+ReASClass::~ReASClass() {
}
*
* @return the class name
*/
-const QByteArray& ReASClass::name() const{
- return m_name;
+const QByteArray& ReASClass::name() const {
+ return m_name;
}
/**
* @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 ? "<none>" : 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 ? "<none>" : 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"
* @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();
}
/**
*
* 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;
}
/**
* @return true: the module is new<br>
* 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.
* @return NULL: not found<br>
* 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);
+ }
}
/**
* @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;
}
/**
*
* @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);
+ }
}
/**
*
* @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();
}
/**
* @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 < 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 <QByteArray>());
- QList <QByteArray>::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<QByteArray>());
+ QList<QByteArray>::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"
*/
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;
}
/**
* @return <code>true</code>: node is correct<br>
* <code>false</code>: otherwise
*/
-bool ReASMethodCall::check(ReParser& parser){
- bool rc = true;
- ReASExprStatement* args = dynamic_cast <ReASExprStatement*>(m_child2);
- int argCount = 0;
- ReASMethod* method = m_method;
- ReASVarDefinition* params =
- dynamic_cast <ReASVarDefinition*>(method->child2());
- while (args != NULL && params != NULL){
- argCount++;
- ReASCalculable* argExpr = dynamic_cast <ReASCalculable*>(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 <ReASNamedValue*>(param)) == NULL)
- rc = error(LOC_MEHTOD_CALL_CHECK_2, parser,
- "parameter %d misses named value: %s", argCount,
- param == NULL ? "<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 <ReASExprStatement*>(args->child());
- params = dynamic_cast <ReASVarDefinition*>(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<ReASExprStatement*>(m_child2);
+ int argCount = 0;
+ ReASMethod* method = m_method;
+ ReASVarDefinition* params =
+ dynamic_cast<ReASVarDefinition*>(method->child2());
+ while (args != NULL && params != NULL) {
+ argCount++;
+ ReASCalculable* argExpr = dynamic_cast<ReASCalculable*>(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<ReASNamedValue*>(param)) == NULL)
+ rc = error(LOC_MEHTOD_CALL_CHECK_2, parser,
+ "parameter %d misses named value: %s", argCount,
+ param == NULL ? "<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<ReASExprStatement*>(args->child());
+ params = dynamic_cast<ReASVarDefinition*>(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;
}
/**
* @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);
}
/**
*
* @return 0: continue the current statement list
*/
-int ReASMethodCall::execute(ReVMThread& thread){
- int rc = 0;
- ReStackFrame frame(this, m_method->symbols());
- thread.pushFrame(&frame);
- ReASExprStatement* args = dynamic_cast <ReASExprStatement*>(m_child2);
- int ixArg = -1;
- while (args != NULL){
- ixArg++;
- ReASCalculable* argExpr = dynamic_cast <ReASCalculable*>(args->child2());
- argExpr->calc(thread);
- ReASVariant& value = thread.popValue();
- ReASVariant& varValue = frame.valueOfVariable(ixArg);
- varValue.copyValue(value);
- }
- thread.popFrame();
- return rc;
+int ReASMethodCall::execute(ReVMThread& thread) {
+ int rc = 0;
+ ReStackFrame frame(this, m_method->symbols());
+ thread.pushFrame(&frame);
+ ReASExprStatement* args = dynamic_cast<ReASExprStatement*>(m_child2);
+ int ixArg = -1;
+ while (args != NULL) {
+ ixArg++;
+ ReASCalculable* argExpr = dynamic_cast<ReASCalculable*>(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;
+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;
}
/**
*
* @return the first element of an argument list
*/
-ReASExprStatement* ReASMethodCall::arg1() const{
- return dynamic_cast <ReASExprStatement*>(m_child2);
+ReASExprStatement* ReASMethodCall::arg1() const {
+ return dynamic_cast<ReASExprStatement*>(m_child2);
}
/** @class ReASException rplastree.hpp "rplexpr/rplastree.hpp"
* @brief Constructor.
*/
ReASBinaryOp::ReASBinaryOp() :
- ReASNode2(AST_BINARY_OP), m_operator(BOP_UNDEF){
+ ReASNode2(AST_BINARY_OP),
+ m_operator(BOP_UNDEF) {
}
/**
*
* @param thread IN/OUT: the bool value of the condition
*/
-void ReASBinaryOp::calc(ReVMThread& thread){
- if (isAssignment())
- assign(thread);
- else{
- ReASCalculable* op1 = dynamic_cast <ReASCalculable*>(m_child);
- ReASCalculable* op2 = dynamic_cast <ReASCalculable*>(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;
- default:
- break;
- }
- thread.popValue();
- }
- }
+void ReASBinaryOp::calc(ReVMThread& thread) {
+ if (isAssignment())
+ assign(thread);
+ else {
+ ReASCalculable* op1 = dynamic_cast<ReASCalculable*>(m_child);
+ ReASCalculable* op2 = dynamic_cast<ReASCalculable*>(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;
+ default:
+ break;
+ }
+ thread.popValue();
+ }
+ }
}
/**
* @return <code>true</code>: node is correct<br>
* <code>false</code>: otherwise
*/
-bool ReASBinaryOp::check(ReParser& parser){
- RE_UNUSED(&parser);
- return false;
+bool ReASBinaryOp::check(ReParser& parser) {
+ RE_UNUSED(&parser);
+ return false;
}
/**
*
* @return the operator
*/
-ReASBinaryOp::BinOperator ReASBinaryOp::getOperator() const{
- return m_operator;
+ReASBinaryOp::BinOperator ReASBinaryOp::getOperator() const {
+ return m_operator;
}
/**
*
* @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.
* @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);
}
/**
*
* @param thread
*/
-void ReASBinaryOp::assign(ReVMThread& thread){
- ReASVariant& rValue = thread.lValue(m_child);
- ReASCalculable* expr = dynamic_cast <ReASCalculable*>(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<ReASCalculable*>(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.
*
* @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"
* @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) {
}
/**
* @return <code>true</code>: node is correct<br>
* <code>false</code>: otherwise
*/
-bool ReASMethod::check(ReParser& parser){
- RE_UNUSED(&parser);
- return false;
+bool ReASMethod::check(ReParser& parser) {
+ RE_UNUSED(&parser);
+ return false;
}
/**
*
* This method will be never called. Must exit: Otherwise the class is abstract.
*/
-int ReASMethod::execute(ReVMThread& thread){
- RE_UNUSED(&thread);
- return 0;
+int ReASMethod::execute(ReVMThread& thread) {
+ RE_UNUSED(&thread);
+ return 0;
}
/**
* @param writer writes to output
* @param indent nesting level
*/
-void ReASMethod::dump(ReWriter& writer, int indent){
+void ReASMethod::dump(ReWriter& writer, int indent) {
- char buffer[256];
- writer.indent(indent);
- writer.format("Method %s %s(",
- m_resultType == NULL ? "<NoneType>" : 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);
+ char buffer[256];
+ writer.indent(indent);
+ writer.format("Method %s %s(",
+ m_resultType == NULL ? "<NoneType>" : 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;
}
/**
* @return true: same signature<br>
* false: otherwise
*/
-bool ReASMethod::equalSignature(ReASMethod& other) const{
- bool rc = true;
- ReASExprStatement* args = dynamic_cast <ReASExprStatement*>(m_child2);
- ReASExprStatement* otherArgs =
- dynamic_cast <ReASExprStatement*>(other.child2());
-
- while (rc && (args != NULL || otherArgs != NULL)){
- if (args == NULL || otherArgs == NULL)
- rc = false;
- else{
- ReASVarDefinition* def =
- dynamic_cast <ReASVarDefinition*>(args->child2());
- ReASVarDefinition* defOther =
- dynamic_cast <ReASVarDefinition*>(otherArgs->child2());
- if (def->clazz() != defOther->clazz())
- rc = false;
- }
- }
- return rc;
+bool ReASMethod::equalSignature(ReASMethod& other) const {
+ bool rc = true;
+ ReASExprStatement* args = dynamic_cast<ReASExprStatement*>(m_child2);
+ ReASExprStatement* otherArgs =
+ dynamic_cast<ReASExprStatement*>(other.child2());
+
+ while (rc && (args != NULL || otherArgs != NULL)) {
+ if (args == NULL || otherArgs == NULL)
+ rc = false;
+ else {
+ ReASVarDefinition* def = dynamic_cast<ReASVarDefinition*>(args
+ ->child2());
+ ReASVarDefinition* defOther =
+ dynamic_cast<ReASVarDefinition*>(otherArgs->child2());
+ if (def->clazz() != defOther->clazz())
+ rc = false;
+ }
+ }
+ return rc;
}
/**
* @brief Returns the next overloaded method.
* @return NULL: no other method available<br>
* 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;
}
/**
*
* @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.
* @return -1: no parameter has a default value<br>
* 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"
* @param name name of the field
*/
ReASField::ReASField(const QByteArray& name) :
- ReASNode1(AST_FIELD), m_name(name){
+ ReASNode1(AST_FIELD),
+ m_name(name) {
}
/**
* @return <code>true</code>: node is correct<br>
* <code>false</code>: otherwise
*/
-bool ReASField::check(ReParser& parser){
- RE_UNUSED(&parser);
- return false;
+bool ReASField::check(ReParser& parser) {
+ RE_UNUSED(&parser);
+ return false;
}
/**
* @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);
}
#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
+ 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, ...);
+ 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;
class ReASCondition;
class ReASVariant {
- /* 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();
+ /* 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();
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 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);
+ 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 {
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 ReVMThread;
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 {
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 {
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 {
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 {
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 {
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 {
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 <ReASVariant*> ReASListOfVariants;
-typedef QMap <QByteArray, ReASVariant*> ReASMapOfVariants;
+typedef QList<ReASVariant*> ReASListOfVariants;
+typedef QMap<QByteArray, ReASVariant*> ReASMapOfVariants;
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 {
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);
+ 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 {
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 {
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 {
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 {
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 <code>ReASItem::m_sourcePosition</code>
- 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 <code>ReASItem::m_sourcePosition</code>
+ int m_endOfScope;
};
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 {
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;
+ 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
- };
+ 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 {
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 {
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 {
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 {
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 {
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 {
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 {
public:
- RplParameter();
- virtual ~RplParameter();
+ RplParameter();
+ virtual ~RplParameter();
private:
- QByteArray m_name;
- ReASNamedValue* m_default;
+ QByteArray m_name;
+ ReASNamedValue* m_default;
};
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 {
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 <QByteArray, ReASMethod*> 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 <code>newValueInstance()</code>.
- *
- * @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<br>
- * 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 <code>object</code>
- */
- 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<QByteArray, ReASMethod*> 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 <code>newValueInstance()</code>.
+ *
+ * @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<br>
+ * 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 <code>object</code>
+ */
+ 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 "expr/ReASClasses.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 <QByteArray, ReSymbolSpace*> SymbolSpaceMap;
- typedef QList <ReSymbolSpace*> 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();
+ 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<QByteArray, ReSymbolSpace*> SymbolSpaceMap;
+ typedef QList<ReSymbolSpace*> 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
* @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"
* @param type token type
*/
ReToken::ReToken(RplTokenType type) :
- m_tokenType(type), m_string(), m_printableString()
+ 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.
* @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.
* @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;
}
/**
*
* @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;
}
/**
*
* @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;
}
/**
*
* @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;
}
/**
*
* @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.
*
* @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;
}
/**
* @return true: the expected type is the current<br>
* false: otherwise
*/
-bool ReToken::isTokenType(RplTokenType expected) const{
- return m_tokenType == expected;
+bool ReToken::isTokenType(RplTokenType expected) const {
+ return m_tokenType == expected;
}
/**
* @return true: the instance is an operator and the expected or the alternative<br>
* 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);
}
/**
* 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;
}
/**
* @return true: the token is an id and the first char is an upper case char<br>
* 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;
}
/**
*
* @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"
*/
static void itemsToVector(const char* items, ReLexer::StringList& vector,
- int firstCharFlag, int secondCharFlag, int thirdCharFlag, int restCharFlag,
- int charInfo[]){
- QByteArray array2(items);
- QList < QByteArray > list = array2.split(' ');
- QList <QByteArray>::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] |= restCharFlag;
- }
- }
- }
- qSort(vector.begin(), vector.end(), qLess <QByteArray>());
+ int firstCharFlag, int secondCharFlag, int thirdCharFlag, int restCharFlag,
+ int charInfo[]) {
+ QByteArray array2(items);
+ QList < QByteArray > list = array2.split(' ');
+ QList<QByteArray>::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] |= restCharFlag;
+ }
+ }
+ }
+ qSort(vector.begin(), vector.end(), qLess<QByteArray>());
}
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;
- }
- }
- ix += 2;
- }
- }
+ 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;
+ }
+ }
}
/**
* 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
+ 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),
+ m_trace(true),
#endif
- m_opNames(){
- memset(m_prioOfOp, 0, sizeof m_prioOfOp);
- memset(m_assocOfOp, 0, sizeof m_assocOfOp);
+ 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() {
}
/**
* @param end pointer to the last char to check
* @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 countBlanks(const char* start, const char* end) {
+ int rc = 0;
+ while (start != end) {
+ if (*start++ == ' ') {
+ rc++;
+ }
+ }
+ return rc;
}
/**
* 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 < QByteArray > items = comments2.split(' ');
- QList <QByteArray>::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<QByteArray>::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 <code>m_input</code> in the vector.
* @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.
* @return false: no more input is available<br>
* 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;
}
/**
* 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;
- }
- }
- }
- }
- }
- 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;
+ 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;
}
/**
*
* @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 = ReQStringUtil::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 = ReQStringUtil::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;
+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 = ReQStringUtil::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 = ReQStringUtil::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;
}
/**
*
* 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)
- 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;
+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);
+ 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
/**
*
* @return the current token
*/
-ReToken* ReLexer::currentToken() const{
- return m_currentToken;
+ReToken* ReLexer::currentToken() const {
+ return m_currentToken;
}
/**
*
* @return the current source code position
*/
-const ReSourcePosition* ReLexer::currentPosition() const{
- return m_currentPosition;
+const ReSourcePosition* ReLexer::currentPosition() const {
+ return m_currentPosition;
}
/**
*
* @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)
- 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;
- }
+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 {
+ 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(),
- m_currentPosition->utf8(buffer, sizeof buffer));
- if (strstr(buffer, "0:28") != NULL)
- buffer[0] = 0;
- }
+ 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;
+ }
#endif
- return rc;
+ return rc;
}
/**
* @brief Reverses the last <code>nextToken()</code>.
*
* Makes that <code>nextToken()</code> 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",
- m_waitingToken->dump().constData(),
- m_waitingPosition1->utf8(buffer, sizeof buffer));
- if (strcmp(buffer, "<test>:2:6") == 0)
- buffer[0] = 0;
- }
+ 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, "<test>:2:6") == 0)
+ buffer[0] = 0;
+ }
#endif
}
*
* Makes that <code>nextToken()</code> 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;
}
/**
* </code></pre>
* Then <code>token1</code> and <code>token2</code> 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;
}
/**
*
* @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;
}
/**
*
* @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;
}
/**
*
* @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;
}
/**
* @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;
}
/**
* @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;
}
/**
* @return true: the operator is right associative<br>
* 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;
}
//#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 {
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 {
public:
- typedef QList <QByteArray> 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<QByteArray> 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 <QByteArray> 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<QByteArray> m_opNames;
#if defined (RPL_LEXER_TRACE)
- bool m_trace;
+ bool m_trace;
#endif
};
#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
+ 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
};
*/
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;
}
/**
* @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;
}
/**
* @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;
}
/**
* @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;
}
/**
* 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 <ReASExprStatement*>(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<ReASExprStatement*>(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;
}
/**
* @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:
- // 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->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;
+ 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->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;
}
/**
* @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 <ReASListOfVariants*>(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<ReASListOfVariants*>(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;
}
/**
* @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 <ReASMapOfVariants*>(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;
- 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();
- 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;
+ReASItem* ReMFParser::parseMap() {
+ ReASMapConstant* rc = new ReASMapConstant();
+ ReASVariant& varMap = rc->value();
+ ReASMapOfVariants* map = static_cast<ReASMapOfVariants*>(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;
+ 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();
+ 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;
}
/**
* <code>ReASNamedValue</code> 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.
*
* @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;
}
/**
* @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();
- 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);
+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();
+ 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{
- 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 <ReASNode1*>(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;
+ 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<ReASNode1*>(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;
}
/**
* @brief Converts a MF specific binary operator into one of AST.
*
* @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 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;
}
/**
* @param depth the level of the parenthesis
* @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));
+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));
- 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 <ReASBinaryOp*>(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<ReASBinaryOp*>(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;
}
/**
* @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;
}
/**
*
* @return the variable definition
*/
-ReASItem* ReMFParser::parseLocalVar(){
- ReASItem* rc = parseVarDefinition(ReASNamedValue::A_NONE);
- return rc;
+ReASItem* ReMFParser::parseLocalVar() {
+ ReASItem* rc = parseVarDefinition(ReASNamedValue::A_NONE);
+ return rc;
}
/**
* @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;
- default:
- break;
- }
- if (again && item != NULL){
- if (body == NULL){
- body = item;
- }else{
- lastStatement->setChild(item);
- }
- lastStatement = dynamic_cast <ReASNode1*>(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;
- }
- } 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);
+ 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;
+ default:
+ break;
+ }
+ if (again && item != NULL) {
+ if (body == NULL) {
+ body = item;
+ } else {
+ lastStatement->setChild(item);
+ }
+ lastStatement = dynamic_cast<ReASNode1*>(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;
+ }
+ } 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;
}
/**
* @post token behind ')' is read
* @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* 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;
}
/**
* @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)){
- token = m_lexer.nextNonSpaceToken();
- if (token->isOperator(O_RPARENTH)){
- token = m_lexer.nextNonSpaceToken();
- }else{
- parameterList = parseParameterList();
- method->setChild2(parameterList);
- }
- }
- if (!token->isOperator(O_COLON))
- syntaxError(L_PARSE_METH_NO_COLON, "':' 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)) {
+ token = m_lexer.nextNonSpaceToken();
+ if (token->isOperator(O_RPARENTH)) {
+ token = m_lexer.nextNonSpaceToken();
+ } else {
+ parameterList = parseParameterList();
+ method->setChild2(parameterList);
+ }
+ }
+ 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);
}
/**
* @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() {
}
*
* @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());
+ }
}
/**
* @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;
}
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))
". ( ) [ ] { }"
#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
* @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"
* @param reason the reason of the exception
*/
RplParserStop::RplParserStop(const char* reason) :
- ReSyntaxError(reason){
+ ReSyntaxError(reason) {
}
/** @class ReParser ReParser.hpp "expr/ReParser.hpp"
* @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) {
}
/**
* @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;
}
/**
* @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);
}
/**
* @param message error message
*/
-void ReParser::syntaxError(int location, const char* message){
- addSimpleMessage(LT_ERROR, location, m_lexer.currentPosition(), message);
- throw ReSyntaxError(message);
+void ReParser::syntaxError(int location, const char* message) {
+ addSimpleMessage(LT_ERROR, location, m_lexer.currentPosition(), message);
+ throw ReSyntaxError(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 ReSyntaxError(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);
}
/**
* @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.
* @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;
}
/**
* @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;
}
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 {
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 <QByteArray> MessageList;
+ typedef QList<QByteArray> 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
* @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();
}
/**
*
* @return the line number
*/
-int ReSourceUnit::lineNo() const{
- return m_lineNo;
+int ReSourceUnit::lineNo() const {
+ return m_lineNo;
}
/**
*
* @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"
* @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) {
}
/**
* @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 <ReReader*>(unit->reader());
- m_caller = reader->source().caller();
+ m_sourceUnit(unit),
+ m_lineNo(lineNo),
+ m_column(colNo),
+ m_caller(NULL) {
+ ReReader* reader = dynamic_cast<ReReader*>(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);
}
/**
* @param buffer buffer for the instance
* @return <code>buffer</code>
*/
-void*ReSourcePosition::operator new(size_t, void* buffer){
- return buffer;
+void*ReSourcePosition::operator new(size_t, void* buffer) {
+ return 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);
}
/**
* @param bufferSize the size of the buffer
* @return <code>buffer</code>
*/
-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;
}
/**
*
* @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;
}
/**
*
* @param column the new column
*/
-void ReSourcePosition::setColumn(int column){
- m_column = column;
+void ReSourcePosition::setColumn(int column) {
+ m_column = column;
}
/**
*
* @return the source unit of the instance
*/
-ReSourceUnit* ReSourcePosition::sourceUnit() const{
- return m_sourceUnit;
+ReSourceUnit* ReSourcePosition::sourceUnit() const {
+ return m_sourceUnit;
}
/**
*
* @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"
* @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;
}
/**
*
* @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;
}
/**
* @return true: source unit exists<br>
* 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"
* Therefore a simple allocation is possible with blocks.
*/
ReSourcePositionBlock::ReSourcePositionBlock() :
- m_successor(NULL)
+ 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"
* @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;
+ }
}
/**
* @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;
}
/**
*
* @return the stack
*/
-QStack <const ReSourcePosition*> ReSource::sourcePositionStack() const{
- return m_sourcePositionStack;
+QStack<const ReSourcePosition*> ReSource::sourcePositionStack() const {
+ return m_sourcePositionStack;
}
/**
* @brief Returns the source unit stack.
* @return the stack of the source units
*/
-QStack <ReSourceUnit*>& ReSource::sourceUnitStack(){
- return m_unitStack;
+QStack<ReSourceUnit*>& ReSource::sourceUnitStack() {
+ return m_unitStack;
}
/**
*
* @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;
}
/**
*
* @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);
}
/**
* @param caller the position of the include
*
*/
-bool ReSource::startUnit(ReSourceUnitName unit, const ReSourcePosition& caller){
- m_sourcePositionStack.push_back(&caller);
- ReReader* reader = NULL;
- QList <ReReader*>::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<ReReader*>::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;
}
/**
*
* @param unit the source unit
*/
-void ReSource::pushSourceUnit(ReSourceUnit* unit){
- m_unitStack.push(unit);
+void ReSource::pushSourceUnit(ReSourceUnit* unit) {
+ m_unitStack.push(unit);
}
/**
* @return NULL: the current reader does not have an open source unit<br>
* 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;
}
/**
* @return NULL: no reader active<br>
* otherwise: the current reader
*/
-ReReader* ReSource::currentReader(){
- return m_currentReader;
+ReReader* ReSource::currentReader() {
+ return m_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 <ReSourceUnit*>(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<ReSourceUnit*>(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();
}
/**
* @return NULL: stack is empty<br>
* 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"
* @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.
* @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;
}
/**
* @param currentPosition the offset (count of QChars) of the end of
* the last read block inside <code>m_content</code>
*/
-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"
* @param source the parent
*/
ReStringReader::ReStringReader(ReSource& source) :
- ReReader(source){
+ ReReader(source) {
}
/**
* @brief Destructor.
*/
-ReStringReader::~ReStringReader(){
- clear();
+ReStringReader::~ReStringReader() {
+ clear();
}
/**
* otherwise: an instance of a sub class of
* <code>ReSourceUnit</code>
*/
-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.
* @return false: no more input available<br>
* 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;
}
/**
* @return false: no more input available<br>
* 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;
}
/**
* @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;
}
/**
* @param content new content
*/
void ReStringReader::replaceSource(ReSourceUnitName name,
- ReSourceUnitContent content){
- if (m_units.contains(name)){
- ReStringSourceUnit* unit =
- dynamic_cast <ReStringSourceUnit*>(m_units[name]);
- unit->m_content = content;
- }
+ ReSourceUnitContent content) {
+ if (m_units.contains(name)) {
+ ReStringSourceUnit* unit =
+ dynamic_cast<ReStringSourceUnit*>(m_units[name]);
+ unit->m_content = content;
+ }
}
/** @class ReFileSourceUnit ReSource.hpp "expr/ReSource.hpp"
*/
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"
*
* @brief Constructor.
*/
ReFileReader::ReFileReader(ReSource& source) :
- ReReader(source){
+ ReReader(source) {
}
/**
* @brief Destructor.
*/
-ReFileReader::~ReFileReader(){
+ReFileReader::~ReFileReader() {
}
/**
* otherwise: an instance of a sub class of
* <code>ReSourceUnit</code>
*/
-ReSourceUnit* ReFileReader::openSourceUnit(ReSourceUnitName unit){
- ReSourceUnit* rc = NULL;
- if (m_units.contains(unit)){
- rc = *m_units.find(unit);
- m_currentSourceUnit = static_cast <ReFileSourceUnit*>(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<ReFileSourceUnit*>(rc);
+ }
+ return rc;
}
/**
* @brief Delivers the next line from the input medium or the first part of it.
* @return false: no more input available<br>
* true: success
*/
-bool ReFileReader::nextLine(int maxSize, QByteArray& buffer, bool& hasMore){
- ReFileSourceUnit* unit = static_cast <ReFileSourceUnit*>(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<ReFileSourceUnit*>(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;
}
/**
* @return false: no more input available<br>
* true: success
*/
-bool ReFileReader::fillBuffer(int maxSize, QByteArray& buffer, bool& hasMore){
- ReFileSourceUnit* unit = static_cast <ReFileSourceUnit*>(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<ReFileSourceUnit*>(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;
}
/**
*
* @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;
}
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 <ReSourceUnit*> 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<br>
- * otherwise: an instance with the state of the reader
- * for the source. This is normally a sub class of
- * <code>ReSourceUnit</code>
- */
- 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 <code>fillBuffer()</code>
- * @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<br>
- * 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<br>
- * 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<ReSourceUnit*> 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<br>
+ * otherwise: an instance with the state of the reader
+ * for the source. This is normally a sub class of
+ * <code>ReSourceUnit</code>
+ */
+ 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 <code>fillBuffer()</code>
+ * @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<br>
+ * 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<br>
+ * 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;
+ 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 <const ReSourcePosition*> sourcePositionStack() const;
- QStack <ReSourceUnit*>& 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<const ReSourcePosition*> sourcePositionStack() const;
+ QStack<ReSourceUnit*>& 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 <const ReSourcePosition*> m_sourcePositionStack;
- ReSourcePositionBlock* m_sourcePositionBlock;
- int m_countPositionBlock;
- QList <ReReader*> m_readers;
- QList <ReSourceUnit*> m_sourceUnits;
- // setCurrentSourceUnit() pushes one entry, removeSourceUnit() pops it
- // (when end of input has been reached).
- QStack <ReSourceUnit*> m_unitStack;
- ReReader* m_currentReader;
+ // stack of the info about the stacked (open) source units:
+ QStack<const ReSourcePosition*> m_sourcePositionStack;
+ ReSourcePositionBlock* m_sourcePositionBlock;
+ int m_countPositionBlock;
+ QList<ReReader*> m_readers;
+ QList<ReSourceUnit*> m_sourceUnits;
+ // setCurrentSourceUnit() pushes one entry, removeSourceUnit() pops it
+ // (when end of input has been reached).
+ QStack<ReSourceUnit*> m_unitStack;
+ ReReader* m_currentReader;
};
class ReStringReader;
class ReStringSourceUnit: public ReSourceUnit {
- friend class ReStringReader;
+ 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 {
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;
+ 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 {
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
#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;
* @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"
*/
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;
}
/**
*
* @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"
* @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!
- //@ToDo:
- //m_frameStack.append(new ReStackFrame(vm->tree().symbolSpaces()[0]));
- throw ReNotImplementedException("ReVMThread::ReVMThread");
- // 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);
}
/**
* <code>m_child</code>
* @param space the current symbol space
*/
-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 <ReASStatement*>(statements);
- if (statement != NULL)
- statement->execute(*this);
- statements = dynamic_cast <ReASNode1*>(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<ReASStatement*>(statements);
+ if (statement != NULL)
+ statement->execute(*this);
+ statements = dynamic_cast<ReASNode1*>(statements->child());
+ }
}
/**
*
* @param statement the current statement (not yet executed)
*/
-void ReVMThread::debug(ReASNode1* statement){
+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;
}
/**
*
* @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;
}
/**
*
* @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;
}
/**
*
* @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;
}
/**
* @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
}
/**
* @param item
* @return
*/
-ReASVariant& ReVMThread::lValue(ReASItem* item){
- ReASVariant* rc;
- switch (item->nodeType()) {
- case AST_NAMED_VALUE: {
- ReASNamedValue* var = dynamic_cast <ReASNamedValue*>(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<ReASNamedValue*>(item);
+ rc = &valueOfVariable(var->symbolSpace(), var->variableNo());
+ break;
+ }
+ default:
+ break;
+ }
+ return *rc;
}
/**
* @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<br>
* false: otherwise
*/
-bool ReVMThread::tracing() const{
- return m_tracing;
+bool ReVMThread::tracing() const {
+ return m_tracing;
}
/**
* @param tracing true: tracing will be done<br>
* false: tracing will not be done
*/
-void ReVMThread::setTracing(bool tracing){
- m_tracing = tracing;
+void ReVMThread::setTracing(bool tracing) {
+ m_tracing = tracing;
}
/**
*
* @return the virtual machine
*/
-ReVirtualMachine* ReVMThread::vm() const{
- return m_vm;
+ReVirtualMachine* ReVMThread::vm() const {
+ return m_vm;
}
/**
*
* @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"
* 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);
}
/**
*
* @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);
- //@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);
+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);
}
/**
* <= 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 <ReASNode1*>(initialization),
- spaceInitialization);
- }
- if (statements != NULL)
- thread->execute(dynamic_cast <ReASNode1*>(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<ReASNode1*>(initialization),
+ spaceInitialization);
+ }
+ if (statements != NULL)
+ thread->execute(dynamic_cast<ReASNode1*>(statements), space);
}
/**
* @brief Tests whether a given flag is set.
* @return true: the flag is set<br>
* 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.
* @param flag
* @return
*/
-void ReVirtualMachine::setFlag(ReVirtualMachine::VMFlag flag){
- m_flags |= flag;
+void ReVirtualMachine::setFlag(ReVirtualMachine::VMFlag flag) {
+ m_flags |= 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;
}
/**
*
* @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;
}
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;
+ friend class ReASItem;
+ friend class ReASStatement;
+ friend class ReASCalculable;
+ friend class ReASCondition;
public:
- typedef QList <ReStackFrame*> StackFrameList;
+ typedef QList<ReStackFrame*> 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 <ReASVariant*> 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<ReASVariant*> m_valueStack;
+ int m_topOfValues;
+ ReVirtualMachine* m_vm;
+ ReLogger* m_logger;
private:
- static int m_nextId;
+ static int m_nextId;
};
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 <const char*> LineList;
+ };
+ typedef QList<const char*> 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 <ReVMThread*> m_threads;
- int m_flags;
- ReSource& m_source;
- ReASTree& m_tree;
- LineList m_trace;
- ReWriter* m_traceWriter;
+ int m_maxStack;
+ QList<ReVMThread*> m_threads;
+ int m_flags;
+ ReSource& m_source;
+ ReASTree& m_tree;
+ LineList m_trace;
+ ReWriter* m_traceWriter;
};
#endif // ReVM_HPP
* @param height the line height
* @return the full line height (with gap)
*/
-inline int heightToFullHeight(int height){
- return height * 7 / 6;
+inline int heightToFullHeight(int height) {
+ return height * 7 / 6;
}
/**
* @param edit the parent
*/
ReLook::ReLook() :
- m_font(NULL),
- m_metrics(NULL),
- m_foreground(FG_STANDARD),
- m_background(BG_STANDARD),
- m_edit(NULL){
+ m_font(NULL),
+ m_metrics(NULL),
+ m_foreground(FG_STANDARD),
+ m_background(BG_STANDARD),
+ m_edit(NULL) {
}
/**
* @param look the presentation of the text
*/
ReEditText::ReEditText(const QString& text, ReLook* look) :
- m_text(text), m_look(look){
+ m_text(text),
+ m_look(look) {
}
* @param edit the edit field (parent)
*/
void ReCursortLineBuilder::buildParagraph(ReParagraph& paragraph, int lineNo,
- ReEdit* edit){
- if (lineNo == edit->cursorLine()){
- for (int ix = 0; ix < paragraph.length(); ix++){
- ReEditText* text = paragraph.at(ix);
- ReLook::ForeGround foreground = text->look()->m_foreground;
- switch (foreground) {
- case ReLook::FG_STANDARD:
- foreground = ReLook::FG_CURRENT_LINE;
- break;
- case ReLook::FG_SELECTED:
- foreground = ReLook::FG_CURRENT_SELECTED;
- break;
- default:
- // don't change!
- break;
- }
- ReLook::BackGround background = text->look()->m_background;
- switch (background) {
- case ReLook::BG_SELECTED:
- background = ReLook::BG_CURRENT_SELECTED;
- break;
- default:
- background = ReLook::BG_CURRENT_LINE;
- break;
- }
- text->setLook(edit->lookOf(foreground, background));
- }
- }
+ ReEdit* edit) {
+ if (lineNo == edit->cursorLine()) {
+ for (int ix = 0; ix < paragraph.length(); ix++) {
+ ReEditText* text = paragraph.at(ix);
+ ReLook::ForeGround foreground = text->look()->m_foreground;
+ switch (foreground) {
+ case ReLook::FG_STANDARD:
+ foreground = ReLook::FG_CURRENT_LINE;
+ break;
+ case ReLook::FG_SELECTED:
+ foreground = ReLook::FG_CURRENT_SELECTED;
+ break;
+ default:
+ // don't change!
+ break;
+ }
+ ReLook::BackGround background = text->look()->m_background;
+ switch (background) {
+ case ReLook::BG_SELECTED:
+ background = ReLook::BG_CURRENT_SELECTED;
+ break;
+ default:
+ background = ReLook::BG_CURRENT_LINE;
+ break;
+ }
+ text->setLook(edit->lookOf(foreground, background));
+ }
+ }
}
/**
* @param parent NULL or a widget which destroy the instance
*/
ReEdit::ReEdit(QWidget* parent) :
- QWidget(parent),
- ReMouseCatcher(),
- m_widthEdit(0),
- m_heightEdit(0),
- m_insertMode(true),
- m_breakLines(false),
- m_widthLineNo(50),
- m_widthVScrollBar(10),
- m_heightHScrollBar(10),
- m_looks(),
- m_standardBrush(new QBrush(Qt::SolidPattern)),
- m_scrollbarBrush(new QBrush(Qt::SolidPattern)),
- m_sliderBrush(new QBrush(Qt::ConicalGradientPattern)),
- m_brushColors(),
- m_standardPen(new QPen(Qt::SolidLine)),
- m_standardFont(NULL),
- m_standardMetrics(NULL),
- m_fontColors(),
- m_keyAlt(),
- m_keyAltControl(),
- m_keyAltControlShift(),
- m_keyAltShift(),
- m_keyControl(),
- m_keyControlShift(),
- m_keyRaw(),
- m_keyShift(){
- setFocusPolicy(Qt::WheelFocus);
- m_standardFont = new QFont("Courier");
- m_standardFont->setStyleHint(QFont::TypeWriter);
- m_standardFont->setPixelSize(16);
- m_standardMetrics = new QFontMetrics(*m_standardFont);
- m_standardBrush->setColor(Qt::white);
- QColor color1(214, 210, 208);
- m_scrollbarBrush->setColor(color1);
- m_sliderBrush->setColor(Qt::lightGray);
- memset(m_looks, 0, sizeof m_looks);
- memset(m_brushColors, 0, sizeof m_brushColors);
-
- assignColorsStandard();
-
- setTabStrings(3);
- appendBuilder(new ReParagraphBuilder());
- appendBuilder(new ReCursortLineBuilder());
- assignKeysStandard();
-}
-void ReEdit::assignColorsStandard(){
- m_fontColors[ReLook::FG_STANDARD] = new QColor(Qt::black);
- m_fontColors[ReLook::FG_CURRENT_LINE] = new QColor(Qt::blue);
- m_fontColors[ReLook::FG_SELECTED] = new QColor(Qt::blue);
- m_fontColors[ReLook::FG_CURRENT_SELECTED] = new QColor(Qt::blue);
- m_fontColors[ReLook::FG_RED_LIGHT] = new QColor(Qt::red);
- m_fontColors[ReLook::FG_RED_DARK] = new QColor(Qt::darkRed);
- m_fontColors[ReLook::FG_BLUE_LIGHT] = new QColor(Qt::blue);
- m_fontColors[ReLook::FG_BLUE_DARK] = new QColor(Qt::darkBlue);
- m_fontColors[ReLook::FG_GREEN_LIGHT] = new QColor(Qt::green);
- m_fontColors[ReLook::FG_GREEN_DARK] = new QColor(Qt::darkGreen);
- m_fontColors[ReLook::FG_GREY_LIGHT] = new QColor(Qt::lightGray);
- m_fontColors[ReLook::FG_GREY_DARK] = new QColor(Qt::darkGray);
- m_fontColors[ReLook::FG_YELLOW_LIGHT] = new QColor(Qt::yellow);
- m_fontColors[ReLook::FG_YELLOW_DARK] = new QColor(Qt::darkYellow);
- m_fontColors[ReLook::FG_MAGENTA_LIGHT] = new QColor(Qt::magenta);
- m_fontColors[ReLook::FG_MAGENTA_DARK] = new QColor(Qt::darkMagenta);
- m_fontColors[ReLook::FG_CYAN_LIGHT] = new QColor(Qt::cyan);
- m_fontColors[ReLook::FG_CYAN_DARK] = new QColor(Qt::darkCyan);
-
- m_brushColors[ReLook::BG_STANDARD] = new QColor(Qt::white);
- m_brushColors[ReLook::BG_CURRENT_LINE] = new QColor(Qt::lightGray);
- m_brushColors[ReLook::BG_SELECTED] = new QColor(Qt::blue);
- m_brushColors[ReLook::BG_CURRENT_SELECTED] = new QColor(Qt::blue);
- m_brushColors[ReLook::BG_SCROLLBAR] = new QColor(216, 214, 212);
- m_brushColors[ReLook::BG_SLIDER] = new QColor(231, 230, 228);
- m_brushColors[ReLook::BG_SEARCHED] = new QColor(Qt::yellow);
- m_brushColors[ReLook::BG_SAME_WORD] = new QColor(Qt::yellow);
- m_brushColors[ReLook::BG_YELLOW] = new QColor(Qt::yellow);
- m_brushColors[ReLook::BG_GREY] = new QColor(Qt::lightGray);
- m_brushColors[ReLook::BG_RED] = new QColor(Qt::red);
- m_brushColors[ReLook::BG_GREEN] = new QColor(Qt::green);
- m_brushColors[ReLook::BG_BLUE] = new QColor(Qt::blue);
-}
-
-void ReEdit::assignKeysStandard(){
- m_keyRaw.clear();
- m_keyControl.clear();
- m_keyShift.clear();
- m_keyAlt.clear();
- m_keyAltControl.clear();
- m_keyAltControlShift.clear();
- m_keyControlShift.clear();
-
- m_keyRaw[Qt::Key_Left] = EA_CHAR_LEFT;
- m_keyRaw[Qt::Key_Right] = EA_CHAR_RIGHT;
- m_keyRaw[Qt::Key_Up] = EA_LINE_UP;
- m_keyRaw[Qt::Key_Down] = EA_LINE_DOWN;
- m_keyRaw[Qt::Key_Home] = EA_BEGIN_OF_LINE;
- m_keyRaw[Qt::Key_End] = EA_END_OF_LINE;
- m_keyControl[Qt::Key_Home] = EA_BEGIN_OF_FILE;
- m_keyControl[Qt::Key_End] = EA_END_OF_FILE;
- m_keyRaw[Qt::Key_PageUp] = EA_PAGE_UP;
- m_keyRaw[Qt::Key_PageDown] = EA_PAGE_DOWN;
- m_keyRaw[Qt::Key_Delete] = EA_DEL_CHAR;
- m_keyRaw[Qt::Key_Backspace] = EA_BACKSPACE;
- m_keyControl[Qt::Key_Delete] = EA_DEL_END_OF_LINE;
- m_keyShift[Qt::Key_Delete] = EA_DEL_BEGIN_OF_LINE;
- m_keyAlt[Qt::Key_Delete] = EA_DEL_LINE;
+ QWidget(parent),
+ ReMouseCatcher(),
+ m_widthEdit(0),
+ m_heightEdit(0),
+ m_insertMode(true),
+ m_breakLines(false),
+ m_widthLineNo(50),
+ m_widthVScrollBar(10),
+ m_heightHScrollBar(10),
+ m_looks(),
+ m_standardBrush(new QBrush(Qt::SolidPattern)),
+ m_scrollbarBrush(new QBrush(Qt::SolidPattern)),
+ m_sliderBrush(new QBrush(Qt::ConicalGradientPattern)),
+ m_brushColors(),
+ m_standardPen(new QPen(Qt::SolidLine)),
+ m_standardFont(NULL),
+ m_standardMetrics(NULL),
+ m_fontColors(),
+ m_keyAlt(),
+ m_keyAltControl(),
+ m_keyAltControlShift(),
+ m_keyAltShift(),
+ m_keyControl(),
+ m_keyControlShift(),
+ m_keyRaw(),
+ m_keyShift() {
+ setFocusPolicy(Qt::WheelFocus);
+ m_standardFont = new QFont("Courier");
+ m_standardFont->setStyleHint(QFont::TypeWriter);
+ m_standardFont->setPixelSize(16);
+ m_standardMetrics = new QFontMetrics(*m_standardFont);
+ m_standardBrush->setColor(Qt::white);
+ QColor color1(214, 210, 208);
+ m_scrollbarBrush->setColor(color1);
+ m_sliderBrush->setColor(Qt::lightGray);
+ memset(m_looks, 0, sizeof m_looks);
+ memset(m_brushColors, 0, sizeof m_brushColors);
+
+ assignColorsStandard();
+
+ setTabStrings(3);
+ appendBuilder(new ReParagraphBuilder());
+ appendBuilder(new ReCursortLineBuilder());
+ assignKeysStandard();
+}
+void ReEdit::assignColorsStandard() {
+ m_fontColors[ReLook::FG_STANDARD] = new QColor(Qt::black);
+ m_fontColors[ReLook::FG_CURRENT_LINE] = new QColor(Qt::blue);
+ m_fontColors[ReLook::FG_SELECTED] = new QColor(Qt::blue);
+ m_fontColors[ReLook::FG_CURRENT_SELECTED] = new QColor(Qt::blue);
+ m_fontColors[ReLook::FG_RED_LIGHT] = new QColor(Qt::red);
+ m_fontColors[ReLook::FG_RED_DARK] = new QColor(Qt::darkRed);
+ m_fontColors[ReLook::FG_BLUE_LIGHT] = new QColor(Qt::blue);
+ m_fontColors[ReLook::FG_BLUE_DARK] = new QColor(Qt::darkBlue);
+ m_fontColors[ReLook::FG_GREEN_LIGHT] = new QColor(Qt::green);
+ m_fontColors[ReLook::FG_GREEN_DARK] = new QColor(Qt::darkGreen);
+ m_fontColors[ReLook::FG_GREY_LIGHT] = new QColor(Qt::lightGray);
+ m_fontColors[ReLook::FG_GREY_DARK] = new QColor(Qt::darkGray);
+ m_fontColors[ReLook::FG_YELLOW_LIGHT] = new QColor(Qt::yellow);
+ m_fontColors[ReLook::FG_YELLOW_DARK] = new QColor(Qt::darkYellow);
+ m_fontColors[ReLook::FG_MAGENTA_LIGHT] = new QColor(Qt::magenta);
+ m_fontColors[ReLook::FG_MAGENTA_DARK] = new QColor(Qt::darkMagenta);
+ m_fontColors[ReLook::FG_CYAN_LIGHT] = new QColor(Qt::cyan);
+ m_fontColors[ReLook::FG_CYAN_DARK] = new QColor(Qt::darkCyan);
+
+ m_brushColors[ReLook::BG_STANDARD] = new QColor(Qt::white);
+ m_brushColors[ReLook::BG_CURRENT_LINE] = new QColor(Qt::lightGray);
+ m_brushColors[ReLook::BG_SELECTED] = new QColor(Qt::blue);
+ m_brushColors[ReLook::BG_CURRENT_SELECTED] = new QColor(Qt::blue);
+ m_brushColors[ReLook::BG_SCROLLBAR] = new QColor(216, 214, 212);
+ m_brushColors[ReLook::BG_SLIDER] = new QColor(231, 230, 228);
+ m_brushColors[ReLook::BG_SEARCHED] = new QColor(Qt::yellow);
+ m_brushColors[ReLook::BG_SAME_WORD] = new QColor(Qt::yellow);
+ m_brushColors[ReLook::BG_YELLOW] = new QColor(Qt::yellow);
+ m_brushColors[ReLook::BG_GREY] = new QColor(Qt::lightGray);
+ m_brushColors[ReLook::BG_RED] = new QColor(Qt::red);
+ m_brushColors[ReLook::BG_GREEN] = new QColor(Qt::green);
+ m_brushColors[ReLook::BG_BLUE] = new QColor(Qt::blue);
+}
+
+void ReEdit::assignKeysStandard() {
+ m_keyRaw.clear();
+ m_keyControl.clear();
+ m_keyShift.clear();
+ m_keyAlt.clear();
+ m_keyAltControl.clear();
+ m_keyAltControlShift.clear();
+ m_keyControlShift.clear();
+
+ m_keyRaw[Qt::Key_Left] = EA_CHAR_LEFT;
+ m_keyRaw[Qt::Key_Right] = EA_CHAR_RIGHT;
+ m_keyRaw[Qt::Key_Up] = EA_LINE_UP;
+ m_keyRaw[Qt::Key_Down] = EA_LINE_DOWN;
+ m_keyRaw[Qt::Key_Home] = EA_BEGIN_OF_LINE;
+ m_keyRaw[Qt::Key_End] = EA_END_OF_LINE;
+ m_keyControl[Qt::Key_Home] = EA_BEGIN_OF_FILE;
+ m_keyControl[Qt::Key_End] = EA_END_OF_FILE;
+ m_keyRaw[Qt::Key_PageUp] = EA_PAGE_UP;
+ m_keyRaw[Qt::Key_PageDown] = EA_PAGE_DOWN;
+ m_keyRaw[Qt::Key_Delete] = EA_DEL_CHAR;
+ m_keyRaw[Qt::Key_Backspace] = EA_BACKSPACE;
+ m_keyControl[Qt::Key_Delete] = EA_DEL_END_OF_LINE;
+ m_keyShift[Qt::Key_Delete] = EA_DEL_BEGIN_OF_LINE;
+ m_keyAlt[Qt::Key_Delete] = EA_DEL_LINE;
}
* @param length OUT: the slider length in pixel
*/
void calcSliderSize(int size, int minSize, double sizeFactor, double posFactor,
- int& position, int& length){
- if (sizeFactor > 1.0)
- sizeFactor = 1.0;
- if (posFactor > 100)
- posFactor = 100;
- length = roundInt(size * sizeFactor);
- if (length < minSize)
- length = minSize;
- position = roundInt((size - length) * posFactor);
+ int& position, int& length) {
+ if (sizeFactor > 1.0)
+ sizeFactor = 1.0;
+ if (posFactor > 100)
+ posFactor = 100;
+ length = roundInt(size * sizeFactor);
+ if (length < minSize)
+ length = minSize;
+ position = roundInt((size - length) * posFactor);
}
/**
* @param background the symbolic background color
* @return an new created instance of a brush
*/
-QBrush* ReEdit::createBrush(ReLook::BackGround background){
- QBrush* rc = new QBrush();
- *rc = *m_standardBrush;
- rc->setColor(*m_brushColors[background]);
- return rc;
+QBrush* ReEdit::createBrush(ReLook::BackGround background) {
+ QBrush* rc = new QBrush();
+ *rc = *m_standardBrush;
+ rc->setColor(*m_brushColors[background]);
+ return rc;
}
/**
*
* @return the line number [0..N-1]
*/
-int ReEdit::cursorLine() const{
- return m_cursorLine;
+int ReEdit::cursorLine() const {
+ return m_cursorLine;
}
/**
* @param posHorizontal the position of the scrollbar as factor [0..1]
*/
void ReEdit::drawScrollbars(QPainter& painter, const QRect& rect,
- double sizeVertical, double posVertical, double sizeHorizontal,
- double posHorizontal){
- // We paint the vertical scrollbar:
- QBrush brush(*m_brushColors[ReLook::BG_SCROLLBAR], Qt::SolidPattern);
- painter.setBrush(brush);
- int x = rect.right() - m_widthVScrollBar;
- m_vScrollBar->setRect(x, rect.top(), m_widthVScrollBar,
- rect.height() - m_heightHScrollBar);
- painter.drawRect(*m_vScrollBar);
-
- // We paint the horizontal scrollbar:
- m_hScrollBar->setRect(rect.left() + m_widthLineNo,
- rect.bottom() - m_heightHScrollBar,
- rect.width() - m_widthVScrollBar - m_widthLineNo, m_heightHScrollBar);
- painter.drawRect(*m_hScrollBar);
-
- // Slider (vertical)
- QBrush brush2(*m_brushColors[ReLook::BG_SLIDER], Qt::SolidPattern);
- painter.setBrush(brush2);
- int sliderSize = 0;
- int sliderPos = 0;
- calcSliderSize(rect.height() - m_heightHScrollBar, m_heightHScrollBar,
- sizeVertical, posVertical, sliderPos, sliderSize);
- m_vSlider->setRect(x, rect.top() + sliderPos, m_widthVScrollBar, sliderSize);
- painter.drawRect(*m_vSlider);
- // Slider (horizontal)
- calcSliderSize(rect.width() - m_widthLineNo - m_widthVScrollBar,
- m_heightHScrollBar, sizeHorizontal, posHorizontal, sliderPos, sliderSize);
- m_hSlider->setRect(rect.left() + m_widthLineNo + sliderPos,
- rect.bottom() - m_heightHScrollBar, sliderSize, m_heightHScrollBar);
- painter.drawRect(*m_hSlider);
+ double sizeVertical, double posVertical, double sizeHorizontal,
+ double posHorizontal) {
+ // We paint the vertical scrollbar:
+ QBrush brush(*m_brushColors[ReLook::BG_SCROLLBAR], Qt::SolidPattern);
+ painter.setBrush(brush);
+ int x = rect.right() - m_widthVScrollBar;
+ m_vScrollBar->setRect(x, rect.top(), m_widthVScrollBar,
+ rect.height() - m_heightHScrollBar);
+ painter.drawRect(*m_vScrollBar);
+
+ // We paint the horizontal scrollbar:
+ m_hScrollBar->setRect(rect.left() + m_widthLineNo,
+ rect.bottom() - m_heightHScrollBar,
+ rect.width() - m_widthVScrollBar - m_widthLineNo, m_heightHScrollBar);
+ painter.drawRect(*m_hScrollBar);
+
+ // Slider (vertical)
+ QBrush brush2(*m_brushColors[ReLook::BG_SLIDER], Qt::SolidPattern);
+ painter.setBrush(brush2);
+ int sliderSize = 0;
+ int sliderPos = 0;
+ calcSliderSize(rect.height() - m_heightHScrollBar, m_heightHScrollBar,
+ sizeVertical, posVertical, sliderPos, sliderSize);
+ m_vSlider->setRect(x, rect.top() + sliderPos, m_widthVScrollBar,
+ sliderSize);
+ painter.drawRect(*m_vSlider);
+ // Slider (horizontal)
+ calcSliderSize(rect.width() - m_widthLineNo - m_widthVScrollBar,
+ m_heightHScrollBar, sizeHorizontal, posHorizontal, sliderPos,
+ sliderSize);
+ m_hSlider->setRect(rect.left() + m_widthLineNo + sliderPos,
+ rect.bottom() - m_heightHScrollBar, sliderSize, m_heightHScrollBar);
+ painter.drawRect(*m_hSlider);
}
/**
*
* @param action action to do
*/
-void ReEdit::editorAction(ReEdit::EditorAction action){
- int pageSize = m_list.length() - 1;
- switch (action) {
- case EA_UNDEF:
- break;
- case EA_CHAR_LEFT:
- if (m_cursorCol-- < -1)
- m_cursorCol = -1;
- ensureCursorVisible();
- break;
- case EA_CHAR_RIGHT:
- if (++m_cursorCol >= m_lines->lineAt(m_cursorLine).length())
- m_cursorCol = m_lines->lineAt(m_cursorLine).length() - 1;
- ensureCursorVisible();
- break;
- case EA_LINE_UP:
- if (--m_cursorLine < 0)
- m_cursorLine = 0;
- ensureCursorVisible();
- break;
- case EA_LINE_DOWN:
- if (++m_cursorLine >= m_lines->lineCount())
- m_cursorLine = m_lines->lineCount() - 1;
- ensureCursorVisible();
- break;
- case EA_BEGIN_OF_LINE:
- m_cursorCol = -1;
- ensureCursorVisible();
- break;
- case EA_END_OF_LINE:
- m_cursorCol = m_lines->lineAt(m_cursorLine).length() - 1;
- ;
- ensureCursorVisible();
- break;
- case EA_BEGIN_OF_FILE:
- ensureCursorVisible(0);
- break;
- case EA_END_OF_FILE:
- ensureCursorVisible(m_lines->lineCount() - 1);
- break;
- case EA_PAGE_UP:
- // Do not change cursor line!
- reposition(m_firstLine - pageSize);
- break;
- case EA_PAGE_DOWN:
- // Do not change cursor line!
- reposition(m_firstLine + pageSize);
- break;
- case EA_DEL_CHAR:
- break;
- case EA_BACKSPACE:
- break;
- case EA_DEL_END_OF_LINE:
- break;
- case EA_DEL_BEGIN_OF_LINE:
- break;
- case EA_DEL_LINE:
- break;
- default:
- break;
- }
- emit repaint();
+void ReEdit::editorAction(ReEdit::EditorAction action) {
+ int pageSize = m_list.length() - 1;
+ switch (action) {
+ case EA_UNDEF:
+ break;
+ case EA_CHAR_LEFT:
+ if (--m_cursorCol < -1)
+ m_cursorCol = -1;
+ ensureCursorVisible();
+ break;
+ case EA_CHAR_RIGHT:
+ if (++m_cursorCol >= m_lines->lineAt(m_cursorLine).length())
+ m_cursorCol = m_lines->lineAt(m_cursorLine).length() - 1;
+ ensureCursorVisible();
+ break;
+ case EA_LINE_UP:
+ if (--m_cursorLine < 0)
+ m_cursorLine = 0;
+ ensureCursorVisible();
+ break;
+ case EA_LINE_DOWN:
+ if (++m_cursorLine >= m_lines->lineCount())
+ m_cursorLine = m_lines->lineCount() - 1;
+ ensureCursorVisible();
+ break;
+ case EA_BEGIN_OF_LINE:
+ m_cursorCol = -1;
+ ensureCursorVisible();
+ break;
+ case EA_END_OF_LINE:
+ m_cursorCol = m_lines->lineAt(m_cursorLine).length() - 1;
+ ;
+ ensureCursorVisible();
+ break;
+ case EA_BEGIN_OF_FILE:
+ ensureCursorVisible(0);
+ break;
+ case EA_END_OF_FILE:
+ ensureCursorVisible(m_lines->lineCount() - 1);
+ break;
+ case EA_PAGE_UP:
+ // Do not change cursor line!
+ reposition(m_firstLine - pageSize);
+ break;
+ case EA_PAGE_DOWN:
+ // Do not change cursor line!
+ reposition(m_firstLine + pageSize);
+ break;
+ case EA_DEL_CHAR:
+ break;
+ case EA_BACKSPACE:
+ break;
+ case EA_DEL_END_OF_LINE:
+ break;
+ case EA_DEL_BEGIN_OF_LINE:
+ break;
+ case EA_DEL_LINE:
+ break;
+ default:
+ break;
+ }
+ emit repaint();
}
/**
*
* @param cursorLine -1 or number of the new cursor line
*/
-void ReEdit::ensureCursorVisible(int cursorLine){
- if (cursorLine >= 0)
- m_cursorLine = cursorLine;
- if (m_cursorLine < m_firstLine || m_cursorLine >= m_firstLine + pageSize()){
- reposition(m_cursorLine);
- }
+void ReEdit::ensureCursorVisible(int cursorLine) {
+ if (cursorLine >= 0)
+ m_cursorLine = cursorLine;
+ if (m_cursorLine < m_firstLine
+ || m_cursorLine >= m_firstLine + pageSize()) {
+ reposition(m_cursorLine);
+ }
}
/**
*
* @param event the description of the key click
*/
-void ReEdit::keyPressEvent(QKeyEvent* event){
- bool shift = event->modifiers() & Qt::ShiftModifier;
- bool control = event->modifiers() & Qt::ControlModifier;
- bool alt = event->modifiers() & Qt::MetaModifier;
- int key = event->key();
- QString keyText = event->text();
- if (!keyText.isEmpty() && !shift && !control && !alt){
- switch (key) {
- case Qt::Key_Enter:
- case Qt::Key_Return:
- m_lines->insertText(m_cursorLine, columnToTextIndex(m_cursorCol + 1),
- "\n");
- m_cursorCol = -1;
- m_cursorLine++;
- break;
- case Qt::Key_Backspace:
- m_lines->remove(m_cursorLine, columnToTextIndex(m_cursorCol + 1), 1);
- if (m_cursorCol-- < -1)
- m_cursorCol = -1;
- break;
- case Qt::Key_Delete:
- m_lines->remove(m_cursorLine, columnToTextIndex(m_cursorCol + 1), 1);
- break;
- default:
- m_lines->insertText(m_cursorLine, columnToTextIndex(m_cursorCol + 1),
- keyText);
- m_cursorCol++;
- break;
- }
- }else{
- QMap <int, EditorAction>* map;
- if (!shift && !alt && !control)
- map = &m_keyRaw;
- else if (shift && !alt && !control)
- map = &m_keyShift;
- else if (alt && !shift && !control)
- map = &m_keyAlt;
- else if (control && !alt && !shift)
- map = &m_keyControl;
- else if (alt && control && !shift)
- map = &m_keyAltControl;
- else if (control && shift && !alt)
- map = &m_keyControlShift;
- else
- map = &m_keyAltControlShift;
- if (map->contains(event->key())){
- EditorAction action = (*map)[key];
- editorAction(action);
- }
- }
- emit repaint();
+void ReEdit::keyPressEvent(QKeyEvent* event) {
+ bool shift = event->modifiers() & Qt::ShiftModifier;
+ bool control = event->modifiers() & Qt::ControlModifier;
+ bool alt = event->modifiers() & Qt::MetaModifier;
+ int key = event->key();
+ QString keyText = event->text();
+ if (!keyText.isEmpty() && !shift && !control && !alt) {
+ switch (key) {
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ m_lines->insertText(m_cursorLine,
+ columnToIndex(m_cursorCol) + 1, "\n");
+ m_cursorCol = -1;
+ m_cursorLine++;
+ break;
+ case Qt::Key_Backspace:{
+ int currentCol = m_cursorCol;
+ m_cursorCol = max(-1, currentCol - 1);
+ if (currentCol == -1 && m_cursorLine > 0) {
+ // join the previous and the current line:
+ // the cursor position will be the end of the previous line:
+ m_cursorCol = indexToColumn(m_lines->lineAt(m_cursorLine - 1)
+ .length() - 1);
+ }
+ if (m_lines->remove(m_cursorLine, columnToIndex(currentCol), 1))
+ m_cursorLine = max(0, m_cursorLine - 1);
+ break;
+ }
+ case Qt::Key_Delete:
+ m_lines->remove(m_cursorLine, columnToIndex(m_cursorCol) + 1, 1);
+ break;
+ default:
+ m_lines->insertText(m_cursorLine,
+ columnToIndex(m_cursorCol) + 1, keyText);
+ m_cursorCol++;
+ break;
+ }
+ } else if (shift && ! keyText.isEmpty() && key != Qt::Key_Delete
+ && key != Qt::Key_Backspace){
+ m_lines->insertText(m_cursorLine,
+ columnToIndex(m_cursorCol) + 1, keyText);
+ m_cursorCol++;
+ } else {
+ QMap<int, EditorAction>* map;
+ if (!shift && !alt && !control)
+ map = &m_keyRaw;
+ else if (shift && !alt && !control)
+ map = &m_keyShift;
+ else if (alt && !shift && !control)
+ map = &m_keyAlt;
+ else if (control && !alt && !shift)
+ map = &m_keyControl;
+ else if (alt && control && !shift)
+ map = &m_keyAltControl;
+ else if (control && shift && !alt)
+ map = &m_keyControlShift;
+ else
+ map = &m_keyAltControlShift;
+ if (map->contains(event->key())) {
+ EditorAction action = (*map)[key];
+ editorAction(action);
+ }
+ }
+ emit repaint();
}
/**
*
* @return the text source
*/
-ReLines& ReEdit::lines(){
- if (m_lines == NULL)
- m_lines = new ReLines();
- return *m_lines;
+ReLines& ReEdit::lines() {
+ if (m_lines == NULL)
+ m_lines = new ReLines();
+ return *m_lines;
}
/**
* @return
*/
ReLook* ReEdit::lookOf(ReLook::ForeGround foreground,
- ReLook::BackGround background){
- int index = foreground * ReLook::BG_COUNT + background;
- ReLook* rc = m_looks[index];
- if (rc == NULL){
- rc = m_looks[index] = new ReLook();
- rc->m_edit = this;
- rc->m_foreground = foreground;
- rc->m_background = background;
- rc->m_brush = createBrush(background);
- if (foreground != ReLook::FG_CURRENT_LINE)
- rc->m_font = m_standardFont;
- else{
- rc->m_font = new QFont(*m_standardFont);
- rc->m_font->setBold(true);
- }
- rc->m_metrics = m_standardMetrics;
- rc->m_pen = new QPen(*m_standardPen);
- rc->m_pen->setColor(*m_fontColors[foreground]);
- }
- return rc;
+ ReLook::BackGround background) {
+ int index = foreground * ReLook::BG_COUNT + background;
+ ReLook* rc = m_looks[index];
+ if (rc == NULL) {
+ rc = m_looks[index] = new ReLook();
+ rc->m_edit = this;
+ rc->m_foreground = foreground;
+ rc->m_background = background;
+ rc->m_brush = createBrush(background);
+ if (foreground != ReLook::FG_CURRENT_LINE)
+ rc->m_font = m_standardFont;
+ else {
+ rc->m_font = new QFont(*m_standardFont);
+ rc->m_font->setBold(true);
+ }
+ rc->m_metrics = m_standardMetrics;
+ rc->m_pen = new QPen(*m_standardPen);
+ rc->m_pen->setColor(*m_fontColors[foreground]);
+ }
+ return rc;
}
/**
* Handles the event when a drag action is done
* @param event
*/
-void ReEdit::mouseMoveEvent(QMouseEvent* event){
- if (m_lastMousePosition.x() >= 0
- && (handleHScrollBar(event, true, this)
- || handleVScrollBar(event, true, this))){
- emit repaint();
- }
+void ReEdit::mouseMoveEvent(QMouseEvent* event) {
+ if (m_lastMousePosition.x() >= 0
+ && (handleHScrollBar(event, true, this)
+ || handleVScrollBar(event, true, this))) {
+ emit repaint();
+ }
}
/**
*
* @param event the description of the mouse click
*/
-void ReEdit::mousePressEvent(QMouseEvent* event){
- if (handleVScrollBar(event, false, this)){
+void ReEdit::mousePressEvent(QMouseEvent* event) {
+ if (handleVScrollBar(event, false, this)) {
- }else if (handleHScrollBar(event, false, this)){
+ } else if (handleHScrollBar(event, false, this)) {
- }else{
- QPoint position = event->pos();
- m_cursorLine = position.y()
- / heightToFullHeight(m_standardMetrics->height()) + m_firstLine;
- int x = position.x();
- int charWidth = m_standardMetrics->width('x');
- if (x >= m_widthLineNo && x < m_widthEdit - m_widthVScrollBar){
- if (x <= m_widthLineNo + charWidth / 2)
- m_cursorCol = -1;
- else
- m_cursorCol = (x - m_widthLineNo) / charWidth;
- }
- }
- m_lastMousePosition = event->pos();
- m_lastTopVSlider = m_vSlider->top();
- m_lastLeftHSlider = m_hSlider->left();
- emit repaint();
+ } else {
+ QPoint position = event->pos();
+ m_cursorLine = position.y()
+ / heightToFullHeight(m_standardMetrics->height()) + m_firstLine;
+ int x = position.x();
+ int charWidth = m_standardMetrics->width('x');
+ if (x >= m_widthLineNo && x < m_widthEdit - m_widthVScrollBar) {
+ if (x <= m_widthLineNo + charWidth / 2)
+ m_cursorCol = -1;
+ else
+ m_cursorCol = (x - m_widthLineNo) / charWidth;
+ }
+ }
+ m_lastMousePosition = event->pos();
+ m_lastTopVSlider = m_vSlider->top();
+ m_lastLeftHSlider = m_hSlider->left();
+ emit repaint();
}
/**
*
* @param event the description of the mouse click
*/
-void ReEdit::mouseReleaseEvent(QMouseEvent* event){
- m_lastMousePosition.setX(-1);
+void ReEdit::mouseReleaseEvent(QMouseEvent* event) {
+ m_lastMousePosition.setX(-1);
}
/**
*
* @param event the trigger event
*/
-void ReEdit::paintEvent(QPaintEvent* event){
- clock_t start = clock();
- QRect rect = event->rect();
- m_widthEdit = rect.width();
- m_heightEdit = rect.height();
- int lineHeight = heightToFullHeight(m_standardMetrics->height());
- int pageSize = (rect.height() - m_heightHScrollBar) / lineHeight;
- int firstLine = m_firstLine;
- load(firstLine, pageSize, this);
- QPainter painter(this);
- ReLook* look = lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD);
- painter.setBrush(*look->m_brush);
- QRect editArea(rect.left() + m_widthLineNo, rect.top(),
- rect.right() - m_widthVScrollBar, rect.bottom() - m_heightHScrollBar);
- painter.drawRect(editArea);
- draw(painter, rect.top(), rect.left() + m_widthLineNo);
- int left = rect.left() + m_widthLineNo - 3;
- left = rect.left();
- int y = 0;
- int lineNo = firstLine + 1;
- ReLook* lookStd = lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD);
- for (int ix = 0; ix < m_list.length(); ix++, lineNo++){
- QString number = QString::number(lineNo) + ":";
- ReLook* look =
- lineNo == m_cursorLine + 1 ?
- lookOf(ReLook::FG_CURRENT_LINE, ReLook::BG_CURRENT_LINE) :
- lookStd;
- int width = look->m_metrics->width(number);
- if (ix == 0)
- y = rect.top() + look->m_metrics->height()
- - look->m_metrics->descent();
- painter.setFont(*look->m_font);
- painter.setPen(*look->m_pen);
- painter.drawText(left + m_widthLineNo - width - 5, y, number);
- y += lineHeight;
- }
- // We paint the cursor:
- if (m_cursorVisible && m_cursorLine >= firstLine
- && m_cursorLine < firstLine + pageSize){
- int col = m_cursorCol;
- if (m_lines->lineAt(m_cursorLine).length() <= col)
- col = m_lines->lineAt(m_cursorLine).length() - 1;
- int x = rect.left() + m_widthLineNo + 1
- + (col + 1) * lookStd->m_metrics->width('x');
- int y = rect.top() + (m_cursorLine - firstLine) * lineHeight;
- painter.setPen(*look->m_pen);
- painter.drawLine(x, y, x, y + lineHeight);
- }
- int maxWidth = max(1, m_maxLineLength);
- int width = (rect.width() - m_widthLineNo - m_widthVScrollBar)
- / m_standardMetrics->width('x');
- int maxLines = max(1, m_lines->lineCount() - pageSize);
- drawScrollbars(painter, rect, double(pageSize) / maxLines,
- double(m_firstLine) / maxLines, double(width) / maxWidth,
- 0.0);
- ReLogger::globalLogger()->logv(LOG_INFO, 3, "draw: %.4f",
- double(clock() - start) / CLOCKS_PER_SEC);
+void ReEdit::paintEvent(QPaintEvent* event) {
+ clock_t start = clock();
+ QRect rect = event->rect();
+ m_widthEdit = rect.width();
+ m_heightEdit = rect.height();
+ int lineHeight = heightToFullHeight(m_standardMetrics->height());
+ int pageSize = (rect.height() - m_heightHScrollBar) / lineHeight;
+ int firstLine = m_firstLine;
+ load(firstLine, pageSize, this);
+ QPainter painter(this);
+ ReLook* look = lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD);
+ painter.setBrush(*look->m_brush);
+ QRect editArea(rect.left() + m_widthLineNo, rect.top(),
+ rect.right() - m_widthVScrollBar, rect.bottom() - m_heightHScrollBar);
+ painter.drawRect(editArea);
+ draw(painter, rect.top(), rect.left() + m_widthLineNo);
+ int left = rect.left() + m_widthLineNo - 3;
+ left = rect.left();
+ int y = 0;
+ int lineNo = firstLine + 1;
+ ReLook* lookStd = lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD);
+ for (int ix = 0; ix < m_list.length(); ix++, lineNo++) {
+ QString number = QString::number(lineNo) + ":";
+ ReLook* look =
+ lineNo == m_cursorLine + 1 ?
+ lookOf(ReLook::FG_CURRENT_LINE, ReLook::BG_CURRENT_LINE) :
+ lookStd;
+ int width = look->m_metrics->width(number);
+ if (ix == 0)
+ y = rect.top() + look->m_metrics->height()
+ - look->m_metrics->descent();
+ painter.setFont(*look->m_font);
+ painter.setPen(*look->m_pen);
+ painter.drawText(left + m_widthLineNo - width - 5, y, number);
+ y += lineHeight;
+ }
+ // We paint the cursor:
+ if (m_cursorVisible && m_cursorLine >= firstLine
+ && m_cursorLine < firstLine + pageSize) {
+ int col = m_cursorCol;
+ if (m_lines->lineAt(m_cursorLine).length() <= col)
+ col = m_lines->lineAt(m_cursorLine).length() - 1;
+ int x = rect.left() + m_widthLineNo + 1
+ + (col + 1) * lookStd->m_metrics->width('x');
+ int y = rect.top() + (m_cursorLine - firstLine) * lineHeight;
+ painter.setPen(*look->m_pen);
+ painter.drawLine(x, y, x, y + lineHeight);
+ }
+ int maxWidth = max(1, m_maxLineLength);
+ int width = (rect.width() - m_widthLineNo - m_widthVScrollBar)
+ / m_standardMetrics->width('x');
+ int maxLines = max(1, m_lines->lineCount() - pageSize);
+ drawScrollbars(painter, rect, double(pageSize) / maxLines,
+ double(m_firstLine) / maxLines, double(width) / maxWidth, 0.0);
+ ReLogger::globalLogger()->logv(LOG_INFO, 3, "draw: %.4f",
+ double(clock() - start) / CLOCKS_PER_SEC);
}
/**
*
* @param firstLine number of the line which should be visible
*/
-void ReEdit::reposition(int firstLine){
- int pageSize = m_list.length();
- if (firstLine <= 0)
- firstLine = 0;
- else if (firstLine >= m_lines->lineCount() - pageSize)
- firstLine = m_lines->lineCount() - pageSize + 1;
- // We do not load because each redraw loads it:
- m_firstLine = firstLine;
+void ReEdit::reposition(int firstLine) {
+ int pageSize = m_list.length();
+ if (firstLine <= 0)
+ firstLine = 0;
+ else if (firstLine >= m_lines->lineCount() - pageSize)
+ firstLine = m_lines->lineCount() - pageSize + 1;
+ // We do not load because each redraw loads it:
+ m_firstLine = firstLine;
}
/**
* Sets the line number of the cursor line.
* @param cursorLine the line number [0..N-1]
*/
-void ReEdit::setCursorLine(int cursorLine){
- m_cursorLine = cursorLine;
+void ReEdit::setCursorLine(int cursorLine) {
+ m_cursorLine = cursorLine;
}
/**
* </pre>
* @param tabWidth
*/
-void ReEdit::setTabStrings(int tabWidth){
- m_tabWidth = tabWidth;
- m_tabStrings.clear();
- QString blanks;
- blanks.fill(' ', tabWidth);
- for (int ix = 0; ix < tabWidth - 1; ix++){
- m_tabStrings.append(m_tabChar + blanks.mid(0, tabWidth - 1 - ix));
- }
+void ReEdit::setTabStrings(int tabWidth) {
+ m_tabWidth = tabWidth;
+ m_tabStrings.clear();
+ QString blanks;
+ blanks.fill(' ', tabWidth);
+ for (int ix = 0; ix <= tabWidth - 1; ix++) {
+ m_tabStrings.append(m_tabChar + blanks.mid(0, tabWidth - 1 - ix));
+ }
}
/**
* Constructor.
*/
ReParagraphs::ReParagraphs() :
- m_builders(),
- m_firstLine(0),
- m_firstCol(0),
- m_cursorLine(0),
- m_cursorCol(-1),
- m_lines(NULL),
- m_list(),
- m_maxLineLength(0),
- m_cursorVisible(true) {
+ m_builders(),
+ m_firstLine(0),
+ m_firstCol(0),
+ m_cursorLine(0),
+ m_cursorCol(-1),
+ m_lines(NULL),
+ m_list(),
+ m_maxLineLength(0),
+ m_cursorVisible(true) {
}
/**
* Destructor.
*/
-ReParagraphs::~ReParagraphs(){
- clear();
+ReParagraphs::~ReParagraphs() {
+ clear();
}
/**
* Makes the list empty and frees the resources.
*/
-void ReParagraphs::clear(){
- m_maxLineLength = 0;
- for (int ix = m_list.length() - 1; ix >= 0; ix--){
- ReParagraph* current = m_list.at(ix);
- delete current;
- }
- m_list.clear();
+void ReParagraphs::clear() {
+ m_maxLineLength = 0;
+ for (int ix = m_list.length() - 1; ix >= 0; ix--) {
+ ReParagraph* current = m_list.at(ix);
+ delete current;
+ }
+ m_list.clear();
+}
+
+/**
+ * Calculates the line string index from the screen column.
+ *
+ * The index may be larger because of expanded tabulators.
+ * Example:
+ * <pre>"x\ty", tabulator width: 4
+ * _01230123
+ * _ x index: 0 blanks: 3
+ * _x x index: 1 blanks: 2
+ * _xx x index: 2 blanks: 1
+ * _xxx x index: 3 blanks: 0
+ * </pre>
+ * @param column the column to convert (0..N-1)
+ * @param tabWidth the tabulator width: the maximal width of a tabulator on the screen
+ * @param string the string which will displayed
+ * @return -1: column < 0<br>
+ * otherwise: the position of the string index in a string with
+ * expanded tabs
+ */
+int ReParagraphs::columnToIndex(int column, int tabWidth,
+ const QString& string) {
+ int rc = 0;
+ if (column < 0)
+ rc = -1;
+ else {
+ int cursor = 0;
+ int length = string.length();
+ while(rc < length - 1 && cursor < column) {
+ rc++;
+ if (string.at(rc) != m_tabChar)
+ cursor++;
+ else {
+ cursor += tabWidth - 1 - (cursor % tabWidth);
+ if (cursor >= column){
+ break;
+ }
+ }
+ }
+ }
+ return rc;
}
/**
*
* @return the cursor line
*/
-ReParagraph* ReParagraphs::cursorLine(){
- ReParagraph* rc = NULL;
- if (m_cursorLine >= m_firstLine && m_cursorLine < m_firstLine + m_list.length()){
- rc = m_list.at(m_cursorLine - m_firstLine);
- }
- return rc;
+ReParagraph* ReParagraphs::cursorLine() {
+ ReParagraph* rc = NULL;
+ if (m_cursorLine >= m_firstLine
+ && m_cursorLine < m_firstLine + m_list.length()) {
+ rc = m_list.at(m_cursorLine - m_firstLine);
+ }
+ return rc;
}
/**
- * Calculates the index of the line string from the cursor column.
- *
- * The index may be smaller because of expanded tabulators.
- * Example:
- * <pre>"x\ty", tabulator width: 3, screen display: "x y"
- * columnToTextIndex(0) == 0; ('x')
- * columnToTextIndex(1) == 1; ('\t')
- * columnToTextIndex(2) == 1; ('\t')
- * columnToTextIndex(3) == 2; ('y')
- * </pre>
+ * Calculates the index of the line string from the cursor column (of the current line).
*
* @param cursorCol the cursor position
- * @return the
- */
-int ReParagraphs::columnToTextIndex(int cursorCol){
- ReParagraph* current = cursorLine();
- int rc = 0;
- if (current == NULL)
- rc = cursorCol;
- else {
- // tab gaps (spaces between tab and tab position)
- int gaps = 0;
- // sum of columns
- int cursor = 0;
- for (int ix = 0; cursor < cursorCol && ix < current->length(); ix++){
- ReEditText* text = current->at(ix);
- int len = text->text().length();
- if (len > 0 && text->text().at(0) == m_tabChar){
- gaps = len - 1;
- rc += 1;
- cursor += len;
- if (cursor >= cursorCol)
- break;
- } else {
- if (cursor + len <= cursorCol)
- rc += len;
- else {
- rc += cursorCol - cursor;
- break;
- }
- }
- }
- }
- return rc;
+ * @return the index of the content string
+ */
+int ReParagraphs::columnToIndex(int cursorCol) {
+ int rc = columnToIndex(cursorCol, m_tabWidth, m_lines->lineAt(m_cursorLine));
+ return rc;
}
/**
* @param top the position of the first line
* @param left the position of the first line
*/
-void ReParagraphs::draw(QPainter& painter, int top, int left){
- for (int ix = 0; ix < m_list.length(); ix++){
- ReParagraph* current = m_list.at(ix);
- current->draw(painter, top, left);
- //if (top > rect.y() + rect.height())
- // break;
- }
+void ReParagraphs::draw(QPainter& painter, int top, int left) {
+ for (int ix = 0; ix < m_list.length(); ix++) {
+ ReParagraph* current = m_list.at(ix);
+ current->draw(painter, top, left);
+ //if (top > rect.y() + rect.height())
+ // break;
+ }
}
/**
- * Transfers some lines starting with a given start into a paragraph list.
+ * Calculates the cursor column from the line string index.
*
- * @param lineNo the line number of the first line to transfer
- * @param count the number of lines to transfer
+ * The index may be larger because of expanded tabulators.
+ * Example:
+ * <pre>tabulator width: 4
+ * _01230123
+ * _ x index: 0 blanks: 3
+ * _x x index: 1 blanks: 2
+ * _xx x index: 2 blanks: 1
+ * _xxx x index: 3 blanks: 0
+ * </pre>
+ * @param index
+ * @param tabWidth
+ * @param string
+ * @return
*/
-void ReParagraphs::load(int lineNo, int count, ReEdit* edit){
- clear();
- m_maxLineLength = 0;
- m_firstLine = lineNo;
- for (int ix = lineNo; ix < lineNo + count; ix++){
- ReParagraph* para = new ReParagraph();
- m_list.append(para);
- for (int builder = 0; builder < m_builders.length(); builder++)
- m_builders.at(builder)->buildParagraph(*para, ix, edit);
- int current = para->m_columns;
- if (current > m_maxLineLength)
- m_maxLineLength = current;
- }
+int ReParagraphs::indexToColumn(int index, int tabWidth,
+ const QString& string) {
+ int rc = 0;
+ if (index >= 0) {
+ int length = string.length();
+ for (int cursor = 0; cursor < index && cursor < length; cursor++) {
+ if (string.at(cursor) != m_tabChar)
+ rc++;
+ else {
+ // if the cursor points to the last char (tab): do not expand!
+ if (cursor < index - 1)
+ rc += tabWidth - 1 - (cursor % tabWidth);
+ }
+ }
+ }
+ return rc;
+}
+
+/**
+ * Calculates the cursor column from the line string index (of the current line).
+ *
+ * @param index the index in the line string
+ * @return the column in the edit field
+ */
+int ReParagraphs::indexToColumn(int index) {
+ int rc = indexToColumn(index, m_tabWidth, m_lines->lineAt(m_cursorLine));
+ return rc;
}
/**
- * Sets the text source of the instance.
+ * Transfers some lines starting with a given start into a paragraph list.
*
- * @param lines the new text source
+ * @param lineNo the line number of the first line to transfer
+ * @param count the number of lines to transfer
*/
-void ReParagraphs::setLines(ReLines* lines){
- m_lines = lines;
+void ReParagraphs::load(int lineNo, int count, ReEdit* edit) {
+ clear();
+ m_maxLineLength = 0;
+ m_firstLine = lineNo;
+ for (int ix = lineNo; ix < lineNo + count; ix++) {
+ ReParagraph* para = new ReParagraph();
+ m_list.append(para);
+ for (int builder = 0; builder < m_builders.length(); builder++)
+ m_builders.at(builder)->buildParagraph(*para, ix, edit);
+ int current = para->m_columns;
+ if (current > m_maxLineLength)
+ m_maxLineLength = current;
+ }
}
/**
- * Calculates the cursor column from the line string index.
+ * Sets the text source of the instance.
*
- * The index may be larger because of expanded tabulators.
- * Example:
- * <pre>"x\ty", tabulator width: 3, screen display: "x y"
- * textIndexToColumn(0) == 0;
- * textIndexToColumn(1) == 1;
- * textIndexToColumn(2) == 3;
- * </pre>
- * @param index the index in the line string
- * @return the column in the edit field
+ * @param lines the new text source
*/
-int ReParagraphs::textIndexToColumn(int index){
- ReParagraph* current = cursorLine();
- int rc = 0;
- if (current == NULL)
- rc = index;
- else {
- int cursor;
- for (int ix = 0; cursor < index && ix < current->length(); ix++){
- ReEditText* text = current->at(ix);
- int len = text->text().length();
- if (len > 0 && text->text().at(0) == m_tabChar){
- rc += len;
- cursor += 1;
- if (cursor >= index)
- break;
- } else {
- if (cursor + len < index){
- cursor += len;
- rc += len;
- } else {
- rc += index - cursor;
- break;
- }
- }
- }
- }
- return rc;
+void ReParagraphs::setLines(ReLines* lines) {
+ m_lines = lines;
}
-
/**
* Changes the look of a paragraph.
*
* @param edit the parent, the edit field
*/
void ReParagraphBuilder::buildParagraph(ReParagraph& paragraph, int lineNo,
- ReEdit* edit){
- if (paragraph.length() == 0){
- const QString& text = edit->lines().lineAt(lineNo);
- ReLook* look = edit->lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD);
- ReLook* lookTab = edit->lookOf(ReLook::FG_GREY_LIGHT,
- ReLook::BG_STANDARD);
- paragraph.m_columns = 0;
- int ixTab;
- ReEditText* part;
- int start = 0;
- while ((ixTab = text.indexOf('\t', start)) >= 0){
- if (ixTab > start){
- part = new ReEditText(text.mid(start, ixTab - start), look);
- paragraph.append(part);
- paragraph.m_columns += ixTab - start;
- }
- paragraph.append(
- new ReEditText(ReEdit::tabString(paragraph.m_columns), lookTab));
- start = ixTab + 1;
- }
-
- part = new ReEditText(start == 0 ? text : text.mid(start), look);
- paragraph.m_columns += part->text().length();
- paragraph.append(part);
- }
+ReEdit* edit) {
+if (paragraph.length() == 0) {
+ const QString& text = edit->lines().lineAt(lineNo);
+ ReLook* look = edit->lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD);
+ ReLook* lookTab = edit->lookOf(ReLook::FG_GREY_LIGHT, ReLook::BG_STANDARD);
+ paragraph.m_columns = 0;
+ int ixTab;
+ ReEditText* part;
+ int start = 0;
+ while ((ixTab = text.indexOf('\t', start)) >= 0) {
+ if (ixTab > start) {
+ part = new ReEditText(text.mid(start, ixTab - start), look);
+ paragraph.append(part);
+ paragraph.m_columns += ixTab - start;
+ }
+ paragraph.append(
+ new ReEditText(ReEdit::tabString(paragraph.m_columns + 1),
+ lookTab));
+ start = ixTab + 1;
+ }
+
+ part = new ReEditText(start == 0 ? text : text.mid(start), look);
+ paragraph.m_columns += part->text().length();
+ paragraph.append(part);
+}
}
/**
* Destructor.
*/
-ReParagraph::~ReParagraph(){
- for (int ix = length() - 1; ix >= 0; ix--)
- delete at(ix);
- clear();
+ReParagraph::~ReParagraph() {
+for (int ix = length() - 1; ix >= 0; ix--)
+ delete at(ix);
+clear();
}
/**
* OUT: the first position under the drawn line
* @param left the starting x position (left hand)
*/
-void ReParagraph::draw(QPainter& painter, int& top, int left){
- int x = left;
- QFontMetrics* metrics = at(0)->look()->m_metrics;
- x += metrics->width('x') / 2;
- int height = metrics->height();
- int y = top + height - metrics->descent();
- top += heightToFullHeight(height);
- for (int ix = 0; ix < length(); ix++){
- ReEditText* current = at(ix);
- ReLook* look = current->look();
- painter.setFont(*look->m_font);
- const ReLook::ForeGround fg = look->m_foreground;
- QPen pen(*look->m_edit->foregroundColors()[fg]);
- painter.setPen(pen);
- painter.drawText(x, y, current->text());
- x += metrics->width(current->text());
- }
+void ReParagraph::draw(QPainter& painter, int& top, int left) {
+int x = left;
+QFontMetrics* metrics = at(0)->look()->m_metrics;
+x += metrics->width('x') / 2;
+int height = metrics->height();
+int y = top + height - metrics->descent();
+top += heightToFullHeight(height);
+for (int ix = 0; ix < length(); ix++) {
+ ReEditText* current = at(ix);
+ ReLook* look = current->look();
+ painter.setFont(*look->m_font);
+ const ReLook::ForeGround fg = look->m_foreground;
+ QPen pen(*look->m_edit->foregroundColors()[fg]);
+ painter.setPen(pen);
+ painter.drawText(x, y, current->text());
+ x += metrics->width(current->text());
+}
}
/**
* Constructor.
*/
ReMouseCatcher::ReMouseCatcher() :
- m_clickObjects(),
- m_vScrollBar(new ClickPosition(CO_VSCROLLBAR)),
- m_hScrollBar(new ClickPosition(CO_HSCROLLBAR)),
- m_hSlider(new ClickPosition(CO_HSLIDER)),
- m_vSlider(new ClickPosition(CO_VSLIDER)),
- m_lastMousePosition(),
- m_lastTopVSlider(0),
- m_lastLeftHSlider(0){
+ m_clickObjects(),
+ m_vScrollBar(new ClickPosition(CO_VSCROLLBAR)),
+ m_hScrollBar(new ClickPosition(CO_HSCROLLBAR)),
+ m_hSlider(new ClickPosition(CO_HSLIDER)),
+ m_vSlider(new ClickPosition(CO_VSLIDER)),
+ m_lastMousePosition(),
+ m_lastTopVSlider(0),
+ m_lastLeftHSlider(0) {
}
/**
* Destructor.
*/
-ReMouseCatcher::~ReMouseCatcher(){
- delete m_vScrollBar;
- delete m_hScrollBar;
- delete m_vSlider;
- delete m_vSlider;
- m_vScrollBar = m_hScrollBar = m_vSlider = m_hSlider = NULL;
+ReMouseCatcher::~ReMouseCatcher() {
+delete m_vScrollBar;
+delete m_hScrollBar;
+delete m_vSlider;
+delete m_vSlider;
+m_vScrollBar = m_hScrollBar = m_vSlider = m_hSlider = NULL;
}
/**
*
* @param object the object to insert.
*/
-void ReMouseCatcher::insertClickObject(ReMouseCatcher::ClickPosition* object){
- if (!m_clickObjects.contains(object))
- m_clickObjects.append(object);
+void ReMouseCatcher::insertClickObject(ReMouseCatcher::ClickPosition* object) {
+if (!m_clickObjects.contains(object))
+ m_clickObjects.append(object);
}
/**
* @return <code>true</code>: the mouse click is inside the horizontal sb
*/
bool ReMouseCatcher::handleHScrollBar(QMouseEvent* event, bool isDragged,
- ReEdit* edit){
- QPoint pos = event->pos();
- bool rc = rectContains(*m_hScrollBar, pos, "hScrollBar");
- if (rc){
+ReEdit* edit) {
+QPoint pos = event->pos();
+bool rc = rectContains(*m_hScrollBar, pos, "hScrollBar");
+if (rc) {
- }
- return rc;
+}
+return rc;
}
/**
* @return <code>true</code>: the mouse click is inside the vertical sb
*/
bool ReMouseCatcher::handleVScrollBar(QMouseEvent* event, bool isDragged,
- ReEdit* edit){
- QPoint pos = event->pos();
- bool rc = rectContains(*m_vScrollBar, pos, "vScrollBar")
- || (isDragged && m_vScrollBar->contains(m_lastMousePosition));
- if (rc){
- if (isDragged){
- int distance = pos.y() - m_lastMousePosition.y();
- int sliderPos = m_lastTopVSlider + distance;
- double position = double(sliderPos)
- / (m_vScrollBar->height() - m_vSlider->height());
- int line = roundInt(
- (edit->lines().lineCount() - edit->pageSize())
- * max(0.0, min(position, 1.0)));
- edit->reposition(line);
- } else {
- if (pos.y() < m_vSlider->top())
- edit->editorAction(ReEdit::EA_PAGE_UP);
- else if (pos.y() > m_vSlider->bottom())
- edit->editorAction(ReEdit::EA_PAGE_DOWN);
- }
- }
- return rc;
+ReEdit* edit) {
+QPoint pos = event->pos();
+bool rc = rectContains(*m_vScrollBar, pos, "vScrollBar")
+ || (isDragged && m_vScrollBar->contains(m_lastMousePosition));
+if (rc) {
+ if (isDragged) {
+ int distance = pos.y() - m_lastMousePosition.y();
+ int sliderPos = m_lastTopVSlider + distance;
+ double position = double(sliderPos)
+ / (m_vScrollBar->height() - m_vSlider->height());
+ int line = roundInt(
+ (edit->lines().lineCount() - edit->pageSize())
+ * max(0.0, min(position, 1.0)));
+ edit->reposition(line);
+ } else {
+ if (pos.y() < m_vSlider->top())
+ edit->editorAction(ReEdit::EA_PAGE_UP);
+ else if (pos.y() > m_vSlider->bottom())
+ edit->editorAction(ReEdit::EA_PAGE_DOWN);
+ }
+}
+return rc;
}
*/
class ReLook {
public:
- enum ForeGround {
- FG_STANDARD,
- FG_CURRENT_LINE,
- FG_SELECTED,
- FG_CURRENT_SELECTED,
- FG_RED_LIGHT,
- FG_RED_DARK,
- FG_BLUE_LIGHT,
- FG_BLUE_DARK,
- FG_GREEN_LIGHT,
- FG_GREEN_DARK,
- FG_GREY_LIGHT,
- FG_GREY_DARK,
- FG_YELLOW_LIGHT,
- FG_YELLOW_DARK,
- FG_MAGENTA_LIGHT,
- FG_MAGENTA_DARK,
- FG_CYAN_LIGHT,
- FG_CYAN_DARK,
- FG_COUNT
- };
- enum BackGround {
- BG_STANDARD,
- BG_CURRENT_LINE,
- BG_SELECTED,
- BG_CURRENT_SELECTED,
- BG_SCROLLBAR,
- BG_SLIDER,
- BG_SEARCHED,
- BG_SAME_WORD,
- BG_YELLOW,
- BG_GREY,
- BG_RED,
- BG_GREEN,
- BG_BLUE,
- BG_COUNT
- };
+ enum ForeGround {
+ FG_STANDARD,
+ FG_CURRENT_LINE,
+ FG_SELECTED,
+ FG_CURRENT_SELECTED,
+ FG_RED_LIGHT,
+ FG_RED_DARK,
+ FG_BLUE_LIGHT,
+ FG_BLUE_DARK,
+ FG_GREEN_LIGHT,
+ FG_GREEN_DARK,
+ FG_GREY_LIGHT,
+ FG_GREY_DARK,
+ FG_YELLOW_LIGHT,
+ FG_YELLOW_DARK,
+ FG_MAGENTA_LIGHT,
+ FG_MAGENTA_DARK,
+ FG_CYAN_LIGHT,
+ FG_CYAN_DARK,
+ FG_COUNT
+ };
+ enum BackGround {
+ BG_STANDARD,
+ BG_CURRENT_LINE,
+ BG_SELECTED,
+ BG_CURRENT_SELECTED,
+ BG_SCROLLBAR,
+ BG_SLIDER,
+ BG_SEARCHED,
+ BG_SAME_WORD,
+ BG_YELLOW,
+ BG_GREY,
+ BG_RED,
+ BG_GREEN,
+ BG_BLUE,
+ BG_COUNT
+ };
public:
- ReLook();
+ ReLook();
public:
- QFont* m_font;
- QFontMetrics* m_metrics;
- ForeGround m_foreground;
- BackGround m_background;
- ReEdit* m_edit;
- QBrush* m_brush;
- QPen* m_pen;
+ QFont* m_font;
+ QFontMetrics* m_metrics;
+ ForeGround m_foreground;
+ BackGround m_background;
+ ReEdit* m_edit;
+ QBrush* m_brush;
+ QPen* m_pen;
};
/**
*/
class ReEditText {
public:
- ReEditText(const QString& text, ReLook* ReLook);
- /** Copy constructor.
- * @param source source to copy
- */
- inline ReEditText(const ReEditText& source) :
- m_text(source.m_text), m_look(source.m_look){
- }
- /** Assignment operator.
- * @param source source to copy
- * @return the instance
- */
- inline ReEditText& operator =(const ReEditText& source){
- m_text = source.m_text;
- m_look = source.m_look;
- return *this;
- }
+ ReEditText(const QString& text, ReLook* ReLook);
+ /** Copy constructor.
+ * @param source source to copy
+ */
+ inline ReEditText(const ReEditText& source) :
+ m_text(source.m_text),
+ m_look(source.m_look) {
+ }
+ /** Assignment operator.
+ * @param source source to copy
+ * @return the instance
+ */
+ inline ReEditText& operator =(const ReEditText& source) {
+ m_text = source.m_text;
+ m_look = source.m_look;
+ return *this;
+ }
public:
- /** Returns the look of the instance.
- * @return the look
- */
- ReLook* look() const{
- return m_look;
- }
- /** Sets the look of the instance
- * @param look the new look
- */
- void setLook(ReLook* look){
- m_look = look;
- }
- /** Returns the text.
- * @return the text
- */
- inline const QString& text() const{
- return m_text;
- }
+ /** Returns the look of the instance.
+ * @return the look
+ */
+ ReLook* look() const {
+ return m_look;
+ }
+ /** Sets the look of the instance
+ * @param look the new look
+ */
+ void setLook(ReLook* look) {
+ m_look = look;
+ }
+ /** Returns the text.
+ * @return the text
+ */
+ inline const QString& text() const {
+ return m_text;
+ }
private:
- QString m_text;
- ReLook* m_look;
+ QString m_text;
+ ReLook* m_look;
};
/**
*
* A paragraph can contain texts with different presentations.
*/
-class ReParagraph: public QList <ReEditText*> {
+class ReParagraph: public QList<ReEditText*> {
public:
- virtual ~ReParagraph();
+ virtual ~ReParagraph();
public:
- void draw(QPainter& painter, int& top, int left);
+ void draw(QPainter& painter, int& top, int left);
public:
- // number of columns of the paragraph (length with expanded tabs).
- int m_columns;
+ // number of columns of the paragraph (length with expanded tabs).
+ int m_columns;
};
/**
*/
class ReParagraphBuilder {
public:
- virtual void buildParagraph(ReParagraph& paragraph, int lineNo,
- ReEdit* edit);
+ virtual void buildParagraph(ReParagraph& paragraph, int lineNo,
+ ReEdit* edit);
};
class ReCursortLineBuilder: public ReParagraphBuilder {
- // ReParagraphBuilder interface
+ // ReParagraphBuilder interface
public:
- virtual void buildParagraph(ReParagraph& paragraph, int lineNo,
- ReEdit* edit);
+ virtual void buildParagraph(ReParagraph& paragraph, int lineNo,
+ ReEdit* edit);
};
/**
*/
class ReParagraphs {
public:
- ReParagraphs();
- virtual ~ReParagraphs();
+ ReParagraphs();
+ virtual ~ReParagraphs();
public:
- /** Appends a paragraph builder to the list
- * @param builder the paragraph builder to append
- */
- void appendBuilder(ReParagraphBuilder* builder){
- m_builders.append(builder);
- }
- void clear();
- ReParagraph* cursorLine();
- void draw(QPainter& painter, int top, int left);
- int columnToTextIndex(int cursorCol);
- /** Returns the paragraph with a given index from the list.
- * @param ix the index [0..N-1] of the paragraph in the list
- * @return NULL: wrong index<br>
- * the wanted paragraph
- */
- virtual ReParagraph* lineAt(int ix){
- return ix < 0 || ix >= m_list.length() ? NULL : m_list.at(ix);
- }
- void load(int lineNo, int count, ReEdit* edit);
- int textIndexToColumn(int index);
+ /** Appends a paragraph builder to the list
+ * @param builder the paragraph builder to append
+ */
+ void appendBuilder(ReParagraphBuilder* builder) {
+ m_builders.append(builder);
+ }
+ void clear();
+ ReParagraph* cursorLine();
+ void draw(QPainter& painter, int top, int left);
+ int columnToIndex(int cursorCol);
+ /** Returns the paragraph with a given index from the list.
+ * @param ix the index [0..N-1] of the paragraph in the list
+ * @return NULL: wrong index<br>
+ * the wanted paragraph
+ */
+ virtual ReParagraph* lineAt(int ix) {
+ return ix < 0 || ix >= m_list.length() ? NULL : m_list.at(ix);
+ }
+ void load(int lineNo, int count, ReEdit* edit);
+ int indexToColumn(int index);
public:
- void setLines(ReLines* lines);
+ void setLines(ReLines* lines);
+public:
+ static int columnToIndex(int column, int tabWidth, const QString& string);
+ static int indexToColumn(int index, int tabWidth, const QString& string);
protected:
- QList <ReParagraphBuilder*> m_builders;
- /// the m_list.at(0) belongs to m_lines.atLine(m_firstLine)
- int m_firstLine;
- /// the first visible column (horizontal scrolling)
- int m_firstCol;
- /// the number of the line containing the insertion cursor (0..N-1)
- int m_cursorLine;
- /// the column of the insertion cursor (0..N-1)
- int m_cursorCol;
- ReLines* m_lines;
- QList <ReParagraph*> m_list;
- int m_maxLineLength;
- /// true: the text cursor is visible (blinking)
- bool m_cursorVisible;
+ QList<ReParagraphBuilder*> m_builders;
+ /// the m_list.at(0) belongs to m_lines.atLine(m_firstLine)
+ int m_firstLine;
+ /// the first visible column (horizontal scrolling)
+ int m_firstCol;
+ /// the number of the line containing the insertion cursor (0..N-1)
+ int m_cursorLine;
+ /// the column of the insertion cursor (0..N-1)
+ int m_cursorCol;
+ ReLines* m_lines;
+ QList<ReParagraph*> m_list;
+ int m_maxLineLength;
+ /// true: the text cursor is visible (blinking)
+ bool m_cursorVisible;
protected:
- static QStringList m_tabStrings;
- static QChar m_tabChar;
- static int m_tabWidth;
+ static QStringList m_tabStrings;
+ static QChar m_tabChar;
+ static int m_tabWidth;
};
/**
*/
class ReMouseCatcher {
public:
- enum ClickObjType {
- CO_UNDEF,
- CO_HSCROLLBAR,
- CO_HSLIDER,
- CO_VSCROLLBAR,
- CO_VSLIDER,
- CO_BOOKMARK
- };
- class ClickPosition: public QRect {
- public:
- ClickPosition(ClickObjType type) :
- QRect(0, 0, 0, 0), m_type(type), m_title(), m_object(NULL){
- }
- public:
- bool operator <(const ClickPosition& op){
- return y() < op.y() || (y() == op.y() && x() < op.x());
- }
- public:
- ClickObjType m_type;
- QString m_title;
- void* m_object;
- };
+ enum ClickObjType {
+ CO_UNDEF,
+ CO_HSCROLLBAR,
+ CO_HSLIDER,
+ CO_VSCROLLBAR,
+ CO_VSLIDER,
+ CO_BOOKMARK
+ };
+ class ClickPosition: public QRect {
+ public:
+ ClickPosition(ClickObjType type) :
+ QRect(0, 0, 0, 0),
+ m_type(type),
+ m_title(),
+ m_object(NULL) {
+ }
+ public:
+ bool operator <(const ClickPosition& op) {
+ return y() < op.y() || (y() == op.y() && x() < op.x());
+ }
+ public:
+ ClickObjType m_type;
+ QString m_title;
+ void* m_object;
+ };
public:
- ReMouseCatcher();
- ~ReMouseCatcher();
+ ReMouseCatcher();
+ ~ReMouseCatcher();
public:
- void insertClickObject(ClickPosition* object);
- bool handleVScrollBar(QMouseEvent* event, bool isDragged, ReEdit* edit);
- bool handleHScrollBar(QMouseEvent* event, bool isDragged, ReEdit* edit);
+ void insertClickObject(ClickPosition* object);
+ bool handleVScrollBar(QMouseEvent* event, bool isDragged, ReEdit* edit);
+ bool handleHScrollBar(QMouseEvent* event, bool isDragged, ReEdit* edit);
public:
- QList <ClickPosition*> m_clickObjects;
- ClickPosition* m_vScrollBar;
- ClickPosition* m_hScrollBar;
- ClickPosition* m_hSlider;
- ClickPosition* m_vSlider;
- QPoint m_lastMousePosition;
- int m_lastTopVSlider;
- int m_lastLeftHSlider;
+ QList<ClickPosition*> m_clickObjects;
+ ClickPosition* m_vScrollBar;
+ ClickPosition* m_hScrollBar;
+ ClickPosition* m_hSlider;
+ ClickPosition* m_vSlider;
+ QPoint m_lastMousePosition;
+ int m_lastTopVSlider;
+ int m_lastLeftHSlider;
};
/**
* scroll bars and handle the key and mouse events to implement an editor.
*/
class ReEdit: public QWidget, protected ReMouseCatcher, public ReParagraphs {
- Q_OBJECT
+ Q_OBJECT
public:
- enum EditorAction {
- EA_UNDEF,
- EA_CHAR_LEFT,
- EA_CHAR_RIGHT,
- EA_LINE_UP,
- EA_LINE_DOWN,
- EA_BEGIN_OF_LINE,
- EA_END_OF_LINE,
- EA_BEGIN_OF_FILE,
- EA_END_OF_FILE,
- EA_PAGE_UP,
- EA_PAGE_DOWN,
- EA_DEL_CHAR,
- EA_BACKSPACE,
- EA_DEL_END_OF_LINE,
- EA_DEL_BEGIN_OF_LINE,
- EA_DEL_LINE,
- };
+ enum EditorAction {
+ EA_UNDEF,
+ EA_CHAR_LEFT,
+ EA_CHAR_RIGHT,
+ EA_LINE_UP,
+ EA_LINE_DOWN,
+ EA_BEGIN_OF_LINE,
+ EA_END_OF_LINE,
+ EA_BEGIN_OF_FILE,
+ EA_END_OF_FILE,
+ EA_PAGE_UP,
+ EA_PAGE_DOWN,
+ EA_DEL_CHAR,
+ EA_BACKSPACE,
+ EA_DEL_END_OF_LINE,
+ EA_DEL_BEGIN_OF_LINE,
+ EA_DEL_LINE,
+ };
public:
- explicit ReEdit(QWidget *parent = 0);
+ explicit ReEdit(QWidget *parent = 0);
public:
- void assignColorsStandard();
- void assignKeysStandard();
- int cursorLine() const;
- void editorAction(EditorAction action);
- ReLines& lines();
- ReLook* lookOf(ReLook::ForeGround foreground, ReLook::BackGround background);
- /** Returns the current page size.
- * return number of visible lines in the edit field
- */
- inline
- int pageSize(){
- return m_list.length();
- }
- void reposition(int firstLine);
- void setCursorLine(int cursorLine);
- /** Returns the array of the foreground colors.
- * @return the array of the foreground colors
- */
- inline const QColor* const * foregroundColors() const{
- return m_fontColors;
- }
- /** Returns the array of the background colors.
- * @return the array of the background colors
- */
- inline const QColor* const * backgroundColors() const{
- return m_brushColors;
- }
+ void assignColorsStandard();
+ void assignKeysStandard();
+ int cursorLine() const;
+ void editorAction(EditorAction action);
+ ReLines& lines();
+ ReLook* lookOf(ReLook::ForeGround foreground,
+ ReLook::BackGround background);
+ /** Returns the current page size.
+ * return number of visible lines in the edit field
+ */
+ inline
+ int pageSize() {
+ return m_list.length();
+ }
+ void reposition(int firstLine);
+ void setCursorLine(int cursorLine);
+ /** Returns the array of the foreground colors.
+ * @return the array of the foreground colors
+ */
+ inline const QColor* const * foregroundColors() const {
+ return m_fontColors;
+ }
+ /** Returns the array of the background colors.
+ * @return the array of the background colors
+ */
+ inline const QColor* const * backgroundColors() const {
+ return m_brushColors;
+ }
protected:
- QBrush* createBrush(ReLook::BackGround background);
- void drawScrollbars(QPainter& painter, const QRect& rect,
- double sizeVertical, double posVertical, double sizeHorizontal,
- double posHorizontal);
- void ensureCursorVisible(int cursorLine = -1);
-protected slots:
- void keyPressEvent(QKeyEvent* event);
- void paintEvent(QPaintEvent *);
- void mouseMoveEvent(QMouseEvent* event);
- void mousePressEvent(QMouseEvent* event);
- void mouseReleaseEvent(QMouseEvent* event);
+ QBrush* createBrush(ReLook::BackGround background);
+ void drawScrollbars(QPainter& painter, const QRect& rect,
+ double sizeVertical, double posVertical, double sizeHorizontal,
+ double posHorizontal);
+ void ensureCursorVisible(int cursorLine = -1);protected slots:
+ void keyPressEvent(QKeyEvent* event);
+ void paintEvent(QPaintEvent *);
+ void mouseMoveEvent(QMouseEvent* event);
+ void mousePressEvent(QMouseEvent* event);
+ void mouseReleaseEvent(QMouseEvent* event);
public:
- /** Returns the tabulator expanding string.
- * @param position the position of the tabulator (0..N-1)
- * @return the tabulator expanding string
- */
- inline static const QString& tabString(int position){
- return m_tabStrings.at(position % m_tabWidth);
- }
- static void setTabStrings(int tabWidth);
+ /** Returns the tabulator expanding string.
+ * @param position the position of the tabulator (0..N-1)
+ * @return the tabulator expanding string
+ */
+ inline static const QString& tabString(int position) {
+ return m_tabStrings.at(position % m_tabWidth);
+ }
+ static void setTabStrings(int tabWidth);
protected:
- // number of pixels of the width of the edit field
- int m_widthEdit;
- // number of pixels of the height of the edit field
- int m_heightEdit;
- /// true: keys will be inserted at the cursor position
- bool m_insertMode;
- /// true: a file line will be displayed in multiple lines (if long enough)
- bool m_breakLines;
- /// number of pixels for the line number
- int m_widthLineNo;
- /// number of pixels for the right scroll bar
- int m_widthVScrollBar;
- /// number of pixels for the bottom scroll bar
- int m_heightHScrollBar;
- ReLook* m_looks[ReLook::BG_COUNT * ReLook::FG_COUNT];
- QBrush* m_standardBrush;
- QBrush* m_scrollbarBrush;
- QBrush* m_sliderBrush;
- const QColor* m_brushColors[ReLook::BG_COUNT];
- QPen* m_standardPen;
- QFont* m_standardFont;
- QFontMetrics* m_standardMetrics;
- const QColor* m_fontColors[ReLook::FG_COUNT];
- QMap <int, EditorAction> m_keyAlt;
- QMap <int, EditorAction> m_keyAltControl;
- QMap <int, EditorAction> m_keyAltControlShift;
- QMap <int, EditorAction> m_keyAltShift;
- QMap <int, EditorAction> m_keyControl;
- QMap <int, EditorAction> m_keyControlShift;
- QMap <int, EditorAction> m_keyRaw;
- QMap <int, EditorAction> m_keyShift;
- ReMouseCatcher m_mouseCatcher;
+ // number of pixels of the width of the edit field
+ int m_widthEdit;
+ // number of pixels of the height of the edit field
+ int m_heightEdit;
+ /// true: keys will be inserted at the cursor position
+ bool m_insertMode;
+ /// true: a file line will be displayed in multiple lines (if long enough)
+ bool m_breakLines;
+ /// number of pixels for the line number
+ int m_widthLineNo;
+ /// number of pixels for the right scroll bar
+ int m_widthVScrollBar;
+ /// number of pixels for the bottom scroll bar
+ int m_heightHScrollBar;
+ ReLook* m_looks[ReLook::BG_COUNT * ReLook::FG_COUNT];
+ QBrush* m_standardBrush;
+ QBrush* m_scrollbarBrush;
+ QBrush* m_sliderBrush;
+ const QColor* m_brushColors[ReLook::BG_COUNT];
+ QPen* m_standardPen;
+ QFont* m_standardFont;
+ QFontMetrics* m_standardMetrics;
+ const QColor* m_fontColors[ReLook::FG_COUNT];
+ QMap<int, EditorAction> m_keyAlt;
+ QMap<int, EditorAction> m_keyAltControl;
+ QMap<int, EditorAction> m_keyAltControlShift;
+ QMap<int, EditorAction> m_keyAltShift;
+ QMap<int, EditorAction> m_keyControl;
+ QMap<int, EditorAction> m_keyControlShift;
+ QMap<int, EditorAction> m_keyRaw;
+ QMap<int, EditorAction> m_keyShift;
+ ReMouseCatcher m_mouseCatcher;
};
#endif // REEDITOR_HPP
* Constructor.
*/
ReGuiValidator::ReGuiValidator() :
- m_errors(0){
+ m_errors(0) {
}
/**
* Destructor.
*/
-ReGuiValidator::~ReGuiValidator(){
+ReGuiValidator::~ReGuiValidator() {
}
/**
*
* @return the date resulting from the formula or begin of the epoch (error case)
*/
-QDateTime ReGuiValidator::comboDate(QComboBox* combo){
- QDateTime rc;
- QString value = combo->currentText();
- if (value.isEmpty())
- rc.setMSecsSinceEpoch(0);
- else{
- ReDateTimeParser parser(value);
- if (parser.isValid()){
- rc = parser.asDateTime();
- setInHistory(combo, value);
- combo->setCurrentText(rc.toString("yyyy.MM.dd/hh:mm"));
- }else{
- guiError(combo, parser.errorMessage());
- rc.setMSecsSinceEpoch(0);
- }
- }
- return rc;
+QDateTime ReGuiValidator::comboDate(QComboBox* combo) {
+ QDateTime rc;
+ QString value = combo->currentText();
+ if (value.isEmpty())
+ rc.setMSecsSinceEpoch(0);
+ else {
+ ReDateTimeParser parser(value);
+ if (parser.isValid()) {
+ rc = parser.asDateTime();
+ setInHistory(combo, value);
+ combo->setCurrentText(rc.toString("yyyy.MM.dd/hh:mm"));
+ } else {
+ guiError(combo, parser.errorMessage());
+ rc.setMSecsSinceEpoch(0);
+ }
+ }
+ return rc;
}
/**
* Returns an integer given in a combobox.
* otherwise: or the size resulting from the formula
*/
int ReGuiValidator::comboInt(QComboBox* combo, int defaultValue,
- const char* specialString, int specialValue){
- QString value = combo->currentText();
- int rc = defaultValue;
- if (!value.isEmpty()){
- if (specialString != NULL && value == specialString){
- rc = specialValue;
- }else{
- uint nValue = 0;
- if (ReQStringUtil::lengthOfUInt(value, 0, 10, &nValue) == 0)
- guiError(combo, QObject::tr("not an integer: ") + value);
- else{
- setInHistory(combo, value);
- rc = (int) nValue;
- }
- }
- }
- return rc;
+ const char* specialString, int specialValue) {
+ QString value = combo->currentText();
+ int rc = defaultValue;
+ if (!value.isEmpty()) {
+ if (specialString != NULL && value == specialString) {
+ rc = specialValue;
+ } else {
+ uint nValue = 0;
+ if (ReQStringUtil::lengthOfUInt(value, 0, 10, &nValue) == 0)
+ guiError(combo, QObject::tr("not an integer: ") + value);
+ else {
+ setInHistory(combo, value);
+ rc = (int) nValue;
+ }
+ }
+ }
+ return rc;
}
/**
* @return -1: empty or invalid input<br>
* otherwise: or the size resulting from the formula
*/
-int64_t ReGuiValidator::comboSize(QComboBox* combo){
- QString value = combo->currentText();
- int64_t rc = -1;
- if (!value.isEmpty()){
- ReSizeParser parser(value);
- rc = parser.asInt64(-1);
- if (rc >= 0){
- setInHistory(combo, value);
- combo->setCurrentText(QString("").sprintf("%ld", rc));
- }else
- guiError(combo, parser.errorMessage());
- }
- return rc;
+int64_t ReGuiValidator::comboSize(QComboBox* combo) {
+ QString value = combo->currentText();
+ int64_t rc = -1;
+ if (!value.isEmpty()) {
+ ReSizeParser parser(value);
+ rc = parser.asInt64(-1);
+ if (rc >= 0) {
+ setInHistory(combo, value);
+ combo->setCurrentText(QString("").sprintf("%ld", rc));
+ } else
+ guiError(combo, parser.errorMessage());
+ }
+ return rc;
}
/**
*
* @return the current text
*/
-QString ReGuiValidator::comboText(QComboBox* combo){
- QString rc = combo->currentText();
- setInHistory(combo, rc);
- return rc;
+QString ReGuiValidator::comboText(QComboBox* combo) {
+ QString rc = combo->currentText();
+ setInHistory(combo, rc);
+ return rc;
}
/**
* @param widget the widget where the error was found
* @param message the error message
*/
-void ReGuiValidator::guiError(QWidget* widget, const QString& message){
- if (widget != NULL)
- widget->setFocus(Qt::OtherFocusReason);
- setStatusMessage(true, message);
- m_errors++;
+void ReGuiValidator::guiError(QWidget* widget, const QString& message) {
+ if (widget != NULL)
+ widget->setFocus(Qt::OtherFocusReason);
+ setStatusMessage(true, message);
+ m_errors++;
}
/**
* @param combo the combobox to change
* @param value the text to set
*/
-void ReGuiValidator::setInHistory(QComboBox* combo, const QString& value){
- if (value.isEmpty()){
- // nothing to do
- }else if (combo->count() == 0)
- combo->addItem(value);
- else{
- if (value != combo->itemText(0)){
- combo->insertItem(0, value);
- }
- for (int ii = 1; ii < combo->count(); ii++){
- if (value == combo->itemText(ii)){
- combo->removeItem(ii);
- }
- }
- if (combo->count() > 20)
- combo->removeItem(20);
- }
+void ReGuiValidator::setInHistory(QComboBox* combo, const QString& value) {
+ if (value.isEmpty()) {
+ // nothing to do
+ } else if (combo->count() == 0)
+ combo->addItem(value);
+ else {
+ if (value != combo->itemText(0)) {
+ combo->insertItem(0, value);
+ }
+ for (int ii = 1; ii < combo->count(); ii++) {
+ if (value == combo->itemText(ii)) {
+ combo->removeItem(ii);
+ }
+ }
+ if (combo->count() > 20)
+ combo->removeItem(20);
+ }
}
class ReGuiValidator {
public:
- ReGuiValidator();
- ~ReGuiValidator();
+ ReGuiValidator();
+ ~ReGuiValidator();
public:
- QDateTime comboDate(QComboBox* combo);
- int comboInt(QComboBox* combo, int defaultValue, const char* specialString =
- NULL, int specialValue = 0);
- int64_t comboSize(QComboBox* combo);
- QString comboText(QComboBox* combo);
- virtual void guiError(QWidget* widget, const QString& message);
- void setInHistory(QComboBox* combo, const QString& value);
- virtual void setStatusMessage(bool error, const QString& message) = 0;
+ QDateTime comboDate(QComboBox* combo);
+ int comboInt(QComboBox* combo, int defaultValue, const char* specialString =
+ NULL, int specialValue = 0);
+ int64_t comboSize(QComboBox* combo);
+ QString comboText(QComboBox* combo);
+ virtual void guiError(QWidget* widget, const QString& message);
+ void setInHistory(QComboBox* combo, const QString& value);
+ virtual void setStatusMessage(bool error, const QString& message) = 0;
protected:
- int m_errors;
+ int m_errors;
};
#endif /* GUI_REVALIDATOR_HPP_ */
* @param filename filename with path of the storage file
*/
ReStateStorage::ReStateStorage(const QString& filename) :
- m_filename(filename), m_fp(NULL), m_stream(NULL), m_form(){
+ m_filename(filename),
+ m_fp(NULL),
+ m_stream(NULL),
+ m_form() {
}
/**
* Destructor.
*/
-ReStateStorage::~ReStateStorage(){
- close();
+ReStateStorage::~ReStateStorage() {
+ close();
}
/**
* Closes open stream/file and frees the resources.
*/
-void ReStateStorage::close(){
- delete m_stream;
- m_stream = NULL;
- if (m_fp != NULL){
- fclose(m_fp);
- m_fp = NULL;
- }
+void ReStateStorage::close() {
+ delete m_stream;
+ m_stream = NULL;
+ if (m_fp != NULL) {
+ fclose(m_fp);
+ m_fp = NULL;
+ }
}
/**
* Initializes the instance for writing the storage information.
*/
-bool ReStateStorage::initForRead(){
- if (m_fp == NULL)
- m_fp = fopen(m_filename.toUtf8().constData(), "rb");
- if (m_fp != NULL && m_stream == NULL){
- m_stream = new QTextStream(m_fp, QIODevice::ReadOnly);
- QString line;
- m_map.clear();
- QString value;
- while (!m_stream->atEnd()){
- line = m_stream->readLine(64 * 1024);
- int ixAssignment = line.indexOf('=');
- if (ixAssignment > 0){
- value = line.mid(ixAssignment + 1);
- QString key = line.mid(0, ixAssignment);
- m_map.insert(key, value);
- }
- }
- }
- return m_stream != NULL;
+bool ReStateStorage::initForRead() {
+ if (m_fp == NULL)
+ m_fp = fopen(m_filename.toUtf8().constData(), "rb");
+ if (m_fp != NULL && m_stream == NULL) {
+ m_stream = new QTextStream(m_fp, QIODevice::ReadOnly);
+ QString line;
+ m_map.clear();
+ QString value;
+ while (!m_stream->atEnd()) {
+ line = m_stream->readLine(64 * 1024);
+ int ixAssignment = line.indexOf('=');
+ if (ixAssignment > 0) {
+ value = line.mid(ixAssignment + 1);
+ QString key = line.mid(0, ixAssignment);
+ m_map.insert(key, value);
+ }
+ }
+ }
+ return m_stream != NULL;
}
/**
* Initializes the instance for writing the storage information.
*/
-bool ReStateStorage::initForWrite(){
- if (m_fp == NULL)
- m_fp = fopen(m_filename.toUtf8().constData(), "wb");
- if (m_fp != NULL)
- m_stream = new QTextStream(m_fp, QIODevice::ReadWrite);
- return m_stream != NULL;
+bool ReStateStorage::initForWrite() {
+ if (m_fp == NULL)
+ m_fp = fopen(m_filename.toUtf8().constData(), "wb");
+ if (m_fp != NULL)
+ m_stream = new QTextStream(m_fp, QIODevice::ReadWrite);
+ return m_stream != NULL;
}
/**
* Returns the name of the current form.
*
* @return the name of the current form
*/
-QString ReStateStorage::form() const{
- return m_form;
+QString ReStateStorage::form() const {
+ return m_form;
}
/**
* @param name the name of the widget
* @return <form name> '.' <name> or <name> (if no form name is set)
*/
-QString ReStateStorage::fullname(const QString& name){
- return m_form.isEmpty() ? name : m_form + "." + name;
+QString ReStateStorage::fullname(const QString& name) {
+ return m_form.isEmpty() ? name : m_form + "." + name;
}
/**
* Sets the name of the current form.
*
* @param form the name of the current form
*/
-void ReStateStorage::setForm(const QString& form){
- m_form = form;
+void ReStateStorage::setForm(const QString& form) {
+ m_form = form;
}
/**
* @param withCurrentText <code>true</code>: the current text will be set too
*/
void ReStateStorage::restore(QComboBox* combo, const QString& name,
- bool withCurrentText){
- if (initForRead()){
- QString keyPrefix = fullname(name) + ".item";
- int ix = 0;
- QString key;
- while (true){
- key = keyPrefix + QString::number(ix);
- if (!m_map.contains(key))
- break;
- combo->addItem(m_map.value(key));
- ix++;
- }
- key = fullname(name) + ".text";
- if (!withCurrentText)
- combo->setCurrentText("");
- else{
- if (m_map.contains(key))
- combo->setCurrentText(m_map.value(key));
- }
- }
+ bool withCurrentText) {
+ if (initForRead()) {
+ QString keyPrefix = fullname(name) + ".item";
+ int ix = 0;
+ QString key;
+ while (true) {
+ key = keyPrefix + QString::number(ix);
+ if (!m_map.contains(key))
+ break;
+ combo->addItem(m_map.value(key));
+ ix++;
+ }
+ key = fullname(name) + ".text";
+ if (!withCurrentText)
+ combo->setCurrentText("");
+ else {
+ if (m_map.contains(key))
+ combo->setCurrentText(m_map.value(key));
+ }
+ }
}
/**
* Reads a value from the storage.
* @return "": not found<br>
* otherwise: the stored value of the variable
*/
-QString ReStateStorage::restore(const QString& name, int index){
- QString rc;
- if (initForRead()){
- QString key(name);
- if (index >= 0)
- key += QString::number(index);
- if (m_map.contains(key))
- rc = m_map.value(key);
- }
- return rc;
+QString ReStateStorage::restore(const QString& name, int index) {
+ QString rc;
+ if (initForRead()) {
+ QString key(name);
+ if (index >= 0)
+ key += QString::number(index);
+ if (m_map.contains(key))
+ rc = m_map.value(key);
+ }
+ return rc;
}
/**
* Stores the data of a combobox.
* @param withCurrentText <code>true</code>: the current text will be saved too
*/
void ReStateStorage::store(const QComboBox* combo, const QString& name,
- bool withCurrentText){
- if (initForWrite()){
- QString fullname;
- if (!m_form.isEmpty())
- fullname = m_form + ".";
- fullname += name;
- for (int ii = 0; ii < combo->count(); ii++){
- *m_stream << fullname << ".item" << ii << "=" << combo->itemText(ii)
- << endl;
- }
- if (withCurrentText){
- *m_stream << fullname << ".text=" << combo->currentText() << endl;
- }
- }
- m_stream->flush();
+ bool withCurrentText) {
+ if (initForWrite()) {
+ QString fullname;
+ if (!m_form.isEmpty())
+ fullname = m_form + ".";
+ fullname += name;
+ for (int ii = 0; ii < combo->count(); ii++) {
+ *m_stream << fullname << ".item" << ii << "=" << combo->itemText(ii)
+ << endl;
+ }
+ if (withCurrentText) {
+ *m_stream << fullname << ".text=" << combo->currentText() << endl;
+ }
+ }
+ m_stream->flush();
}
/**
* @param withCurrentText <code>true</code>: the current text will be saved too
*/
void ReStateStorage::store(const QString& name, const QString& value,
- int index){
- if (initForWrite()){
- QString key(name);
- if (index >= 0)
- key += QString::number(index);
- *m_stream << key << "=" << value << endl;
- }
- m_stream->flush();
+ int index) {
+ if (initForWrite()) {
+ QString key(name);
+ if (index >= 0)
+ key += QString::number(index);
+ *m_stream << key << "=" << value << endl;
+ }
+ m_stream->flush();
}
class ReStateStorage {
public:
- ReStateStorage(const QString& filename);
- virtual ~ReStateStorage();
+ ReStateStorage(const QString& filename);
+ virtual ~ReStateStorage();
public:
- void close();
- QString form() const;
- QString fullname(const QString& name);
- bool initForRead();
- bool initForWrite();
- void restore(QComboBox* combo, const QString& name, bool withCurrentText =
- false);
- QString restore(const QString& name, int index = -1);
- void setForm(const QString& form);
- void store(const QComboBox* combo, const QString& name,
- bool withCurrentText = true);
- void store(const QString& name, const QString& value, int index = -1);
+ void close();
+ QString form() const;
+ QString fullname(const QString& name);
+ bool initForRead();
+ bool initForWrite();
+ void restore(QComboBox* combo, const QString& name, bool withCurrentText =
+ false);
+ QString restore(const QString& name, int index = -1);
+ void setForm(const QString& form);
+ void store(const QComboBox* combo, const QString& name,
+ bool withCurrentText = true);
+ void store(const QString& name, const QString& value, int index = -1);
private:
- QString m_filename;
- FILE* m_fp;
- QTextStream* m_stream;
- QString m_form;
- QMap <QString, QString> m_map;
+ QString m_filename;
+ FILE* m_fp;
+ QTextStream* m_stream;
+ QString m_form;
+ QMap<QString, QString> m_map;
};
#endif /* GUI_RESTATESTORAGE_HPP_ */
* @return <code>true</code>: the point lays inside the rectangle
*/
inline bool rectContains(const QRect& rect, const QPoint& point,
- const char* what = ""){
+ const char* what = "") {
#if 1
- return point.x() >= rect.x() && point.y() >= rect.y()
- && point.x() < rect.x() + rect.width()
- && point.y() < rect.y() + rect.height();
+ return point.x() >= rect.x() && point.y() >= rect.y()
+ && point.x() < rect.x() + rect.width()
+ && point.y() < rect.y() + rect.height();
#else
- bool rc = point.x() >= rect.x();
- char reason = ' ';
- if (! rc)
- reason = 'x';
- else{
- rc = point.y() >= rect.y();
- if (! rc)
- reason = 'y';
- else{
- rc = point.x() < rect.x() + rect.width();
- if (! rc)
- reason = 'X';
- else{
- rc = point.y() < rect.y() + rect.height();
- if (! rc)
- reason = 'Y';
- }
- }
- }
- if (! rc)
- ReLogger::globalLogger()->logv(LOG_INFO, 1, "rectContains(%s) %c %d/%d %d-%d/%d-%d",
- what, reason, point.x(), point.y(), rect.x(), rect.x() + rect.width(),
- rect.y(), rect.y() + rect.height());
- return rc;
+ bool rc = point.x() >= rect.x();
+ char reason = ' ';
+ if (! rc)
+ reason = 'x';
+ else {
+ rc = point.y() >= rect.y();
+ if (! rc)
+ reason = 'y';
+ else {
+ rc = point.x() < rect.x() + rect.width();
+ if (! rc)
+ reason = 'X';
+ else {
+ rc = point.y() < rect.y() + rect.height();
+ if (! rc)
+ reason = 'Y';
+ }
+ }
+ }
+ if (! rc)
+ ReLogger::globalLogger()->logv(LOG_INFO, 1, "rectContains(%s) %c %d/%d %d-%d/%d-%d",
+ what, reason, point.x(), point.y(), rect.x(), rect.x() + rect.width(),
+ rect.y(), rect.y() + rect.height());
+ return rc;
#endif
}
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";
+ "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";
+ " !\"#$%&'()*+,-./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.
* @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;
+ }
}
/**
* @return empty string: error while reading<br>
* 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;
}
/**
* 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];
+ }
+ }
}
/**
* 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.
* @param data IN: data to encode/decoded<br>
* 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;
+ }
}
/**
*
* @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);
+ }
}
/**
* @param maxValue
* @return
*/
-int ReEnigma::nextInt(int maxValue){
- uint64_t seed = 0;
- QList <secret_t*>::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<secret_t*>::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;
}
/**
*
* @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;
}
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 <code>m_random</code>' seed
- QList <secret_t*> 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 <code>m_random</code>' seed
+ QList<secret_t*> 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
#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) {
}
/**
* @param name the name of the matrix
*/
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_rows(rows),
+ m_cols(cols),
+ 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;
}
/**
* @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);
}
/**
* @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);
}
/**
* @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.
* @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());
}
/**
*
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @return true: the matrices are equal<br>
* 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.
* @return true: all elements are equal to the scalar<br>
* 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<qreal>::max()
#define DBL_MIN std::numeric_limits<qreal>::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;
}
/**
*
* @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.
* @param separator the column separator
* @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 == '\\'){
- ptr++;
- if (*ptr != '\0')
- ptr++;
- }else if (*ptr == separator)
- break;
- else if (*ptr != delimiter){
- ptr++;
- while (*ptr && *ptr != separator)
- ptr++;
- }
- }
- int rc = ptr - text;
- return rc;
+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 == '\\') {
+ ptr++;
+ if (*ptr != '\0')
+ ptr++;
+ } else if (*ptr == separator)
+ break;
+ else if (*ptr != delimiter) {
+ ptr++;
+ while (*ptr && *ptr != separator)
+ ptr++;
+ }
+ }
+ int rc = ptr - text;
+ return rc;
}
/**
* Skips all columns with a content other than a numeric value.
* @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.
* @return 0: not only numbers are in the line<br>
* 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;
+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;
}
/**
* 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);
}
*/
class RplMatrixException: public ReException {
public:
- RplMatrixException(const RplMatrix& RplMatrix, const char* format, ...);
+ RplMatrixException(const RplMatrix& RplMatrix, const char* format, ...);
};
/**
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_ */
* @brief Constructor.
*/
ReRandom::ReRandom() :
- m_seed(0){
+ m_seed(0) {
}
/**
* @brief Destructor.
*/
-ReRandom::~ReRandom(){
+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;
}
/**
*
* @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;
}
/**
* @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;
}
/**
* @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;
}
/**
* @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;
}
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
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
#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"
* @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;
}
/**
* @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;
}
/**
*
* @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"
* @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);
+ 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;
}
/**
*
* Calls <code>doIt()</code> for the real things.
*/
-void RplClientThread::run(){
- doIt();
+void RplClientThread::run() {
+ doIt();
}
class ReTCPPeer;
class RplTcpClient: public QObject {
- Q_OBJECT
+ 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 {
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 <code>QThread::run()</code>.
- * The implementations of this abstract method should be call <code>getPeer()</code>
- * 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 <code>QThread::run()</code>.
+ * The implementations of this abstract method should be call <code>getPeer()</code>
+ * 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 // RETCPCLIENT_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;
* @return an instance of <code>ReTCPPeer</code>
*/
ReTCPPeer* ReTCPPeer::createPeer(ReConfigurator& configurator, QThread* thread,
- ReTerminator* terminator, ReLogger* logger){
- return new ReTCPPeer(configurator, thread, terminator, logger);
+ ReTerminator* terminator, ReLogger* logger) {
+ return new ReTCPPeer(configurator, thread, terminator, logger);
}
/**
* @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() {
}
* @return true: success<br>
* 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;
}
/**
* @return "": read not successful: timeout or termination or error<br>
* 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;
}
/**
* @return true: success<br>
* 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;
}
* 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;
+ 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;
}
/**
*
* @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();
}
/**
*
* @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 = "<not connected>";
- else
- rc = m_socket->peerAddress().toString().toUtf8();
- return rc;
+QByteArray ReTCPPeer::getPeerAddress() {
+ QByteArray rc;
+ if (m_socket == NULL)
+ rc = "<not connected>";
+ else
+ rc = m_socket->peerAddress().toString().toUtf8();
+ return rc;
}
/**
*
* @return the socket
*/
-QAbstractSocket* ReTCPPeer::getSocket() const{
- return m_socket;
+QAbstractSocket* ReTCPPeer::getSocket() const {
+ return m_socket;
}
/**
* @brief Returns the port.
* @return the port of the peer.
*/
-int ReTCPPeer::getPort(){
- int port = m_configurator.asInt(ReNetConfig::PORT, 12345);
- return port;
+int ReTCPPeer::getPort() {
+ int port = m_configurator.asInt(ReNetConfig::PORT, 12345);
+ return port;
}
/**
* @brief Returns the ip address.
* @return "": all addresses (for listening)<br>
* otherwise: the address (e.g. 127.0.0.1)
*/
-QByteArray ReTCPPeer::getIp(){
- QByteArray ip = m_configurator.asString(ReNetConfig::IP, "");
- return ip;
+QByteArray ReTCPPeer::getIp() {
+ 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);
}
#endif
class ReTCPPeer: public QObject {
- Q_OBJECT
+ 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;
- // <ip>:<port>
- 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;
+ // <ip>:<port>
+ 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
#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"
* @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){
+ int threadId, ReTaskHandler* handler) :
+ m_threadId(threadId),
+ m_taskHandler(handler),
+ m_socketDescriptor(socketDescriptor),
+ m_configurator(configurator) {
}
/**
* @brief Destructor.
*/
-ReTCPThread::~ReTCPThread(){
+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());
+ }
}
/**
*
* @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"
* @param parent NULL or the parent which deletes the childen
*/
ReTCPServer::ReTCPServer(ReConfigurator& configurator,
- ReTaskHandler* taskHandler, ReThreadFactory& 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) {
}
/**
*
* @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"
* @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() {
}
/**
* @return false: the application should stop<br>
* 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;
}
/**
*
* @param id the thread id
*/
-void ReTaskHandler::setThreadId(int id){
- m_threadId = id;
+void ReTaskHandler::setThreadId(int id) {
+ m_threadId = id;
}
/**
*
* @return the thread id
*/
-int ReTaskHandler::getThreadId() const{
- return m_threadId;
+int ReTaskHandler::getThreadId() const {
+ return m_threadId;
}
/**
*
* @return the logger
*/
-ReLogger* ReTaskHandler::getLogger() const{
- return m_logger;
+ReLogger* ReTaskHandler::getLogger() const {
+ return m_logger;
}
/**
*
* @return the termination controller
*/
-ReTerminator* ReTaskHandler::getTerminator() const{
- return m_terminator;
+ReTerminator* ReTaskHandler::getTerminator() const {
+ return m_terminator;
}
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<br>
- * 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<br>
+ * 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
+ 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
+ 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
#endif
enum {
- LC_RIGHTS_AS_STRING_1 = LOC_FIRST_OF(LOC_TRAVERSER), // 50401
- LC_RIGHTS_AS_STRING_2, // 50402
- LC_RIGHTS_AS_STRING_3, // 50403
- LC_GET_PRIVILEGE_1, // 50404
- LC_GET_PRIVILEGE_2, // 50405
- LC_GET_PRIVILEGE_3, // 50406
- LC_GET_FILE_OWNER_1, // 50407
- LC_GET_FILE_OWNER_2, // 50408
+ LC_RIGHTS_AS_STRING_1 = LOC_FIRST_OF(LOC_TRAVERSER), // 50401
+ LC_RIGHTS_AS_STRING_2, // 50402
+ LC_RIGHTS_AS_STRING_3, // 50403
+ LC_GET_PRIVILEGE_1, // 50404
+ LC_GET_PRIVILEGE_2, // 50405
+ LC_GET_PRIVILEGE_3, // 50406
+ LC_GET_FILE_OWNER_1, // 50407
+ LC_GET_FILE_OWNER_2, // 50408
};
int ReDirEntryFilter::m_serialId = buildSerialId(CLASSID_DIR_ENTRY_FILTER, 1);
#endif
{
#ifdef __linux__
- memset(&m_status, 0, sizeof m_status);
+ memset(&m_status, 0, sizeof m_status);
#elif defined WIN32
- memset(&m_data, 0, sizeof m_data);
+ memset(&m_data, 0, sizeof m_data);
#endif
}
*
* @return the last access time
*/
-const ReFileTime_t* ReDirStatus_t::accessed(){
+const ReFileTime_t* ReDirStatus_t::accessed() {
#ifdef __linux__
- return &(getStatus()->st_atim);
+ return &(getStatus()->st_atim);
#elif defined __WIN32__
- return &m_data.ftLastAccessTime;
+ return &m_data.ftLastAccessTime;
#endif
}
*
* @return the filesize
*/
-ReFileSize_t ReDirStatus_t::fileSize(){
+ReFileSize_t ReDirStatus_t::fileSize() {
#ifdef __linux__
- return getStatus()->st_size;
+ return getStatus()->st_size;
#elif defined __WIN32__
- return ((int64_t) m_data.nFileSizeHigh << 32) + m_data.nFileSizeLow;
+ return ((int64_t) m_data.nFileSizeHigh << 32) + m_data.nFileSizeLow;
#endif
}
* @param buffer OUT: the file time
* @return <code>buffer.str()</code> (for chaining)
*/
-const char* ReDirStatus_t::filetimeAsString(ReByteBuffer& buffer){
- return filetimeToString(modified(), buffer);
+const char* ReDirStatus_t::filetimeAsString(ReByteBuffer& buffer) {
+ return filetimeToString(modified(), buffer);
}
/**
* @return <code>buffer.str()</code>, e.g. "2014.01.07 02:59:43"
*/
const char* ReDirStatus_t::filetimeToString(const ReFileTime_t* time,
- ReByteBuffer& buffer){
- time_t time1 = filetimeToTime(time);
- struct tm* time2 = localtime(&time1);
- buffer.setLength(4 + 2 * 2 + 2 * 2 + 1 + 3 * 2 + 2 * 1);
- strftime(buffer.buffer(), buffer.length(), "%Y.%m.%d %H:%M:%S", time2);
- return buffer.str();
+ ReByteBuffer& buffer) {
+ time_t time1 = filetimeToTime(time);
+ struct tm* time2 = localtime(&time1);
+ buffer.setLength(4 + 2 * 2 + 2 * 2 + 1 + 3 * 2 + 2 * 1);
+ strftime(buffer.buffer(), buffer.length(), "%Y.%m.%d %H:%M:%S", time2);
+ return buffer.str();
}
/**
* @param filetime the filetime to convert
* @return the count of seconds since 1.1.1970
*/
-time_t ReDirStatus_t::filetimeToTime(const ReFileTime_t* filetime){
+time_t ReDirStatus_t::filetimeToTime(const ReFileTime_t* filetime) {
#ifdef __linux__
- return filetime->tv_sec;
+ return filetime->tv_sec;
#elif defined __WIN32__
- // 64-bit arithmetic:
- LARGE_INTEGER date, adjust;
- date.HighPart = filetime->dwHighDateTime;
- date.LowPart = filetime->dwLowDateTime;
- // 100-nanoseconds = milliseconds * 10000
- adjust.QuadPart = 11644473600000 * 10000;
- // removes the diff between 1970 and 1601
- date.QuadPart -= adjust.QuadPart;
- // converts back from 100-nanoseconds to seconds
- time_t rc = (time_t) (date.QuadPart / 10000000);
- return rc;
+ // 64-bit arithmetic:
+ LARGE_INTEGER date, adjust;
+ date.HighPart = filetime->dwHighDateTime;
+ date.LowPart = filetime->dwLowDateTime;
+ // 100-nanoseconds = milliseconds * 10000
+ adjust.QuadPart = 11644473600000 * 10000;
+ // removes the diff between 1970 and 1601
+ date.QuadPart -= adjust.QuadPart;
+ // converts back from 100-nanoseconds to seconds
+ time_t rc = (time_t) (date.QuadPart / 10000000);
+ return rc;
#endif
}
*
* @return <code>true</code>: success
*/
-bool ReDirStatus_t::findFirst(){
- bool rc = false;
+bool ReDirStatus_t::findFirst() {
+ bool rc = false;
#if defined __linux__
- if (m_handle != NULL)
- closedir(m_handle);
- m_handle = opendir(m_path.str());
- rc = m_handle != NULL && (m_data = readdir(m_handle)) != NULL;
- m_status.st_ino = 0;
+ if (m_handle != NULL)
+ closedir(m_handle);
+ m_handle = opendir(m_path.str());
+ rc = m_handle != NULL && (m_data = readdir(m_handle)) != NULL;
+ m_status.st_ino = 0;
#elif defined __WIN32__
- if (m_handle != INVALID_HANDLE_VALUE)
- FindClose(m_handle);
- ReByteBuffer thePath(m_path);
- thePath.append(m_path.lastChar() == '\\' ? "*" : "\\*");
- m_handle = FindFirstFileA(thePath.str(), &m_data);
- rc = m_handle != INVALID_HANDLE_VALUE;
+ if (m_handle != INVALID_HANDLE_VALUE)
+ FindClose(m_handle);
+ ReByteBuffer thePath(m_path);
+ thePath.append(m_path.lastChar() == '\\' ? "*" : "\\*");
+ m_handle = FindFirstFileA(thePath.str(), &m_data);
+ rc = m_handle != INVALID_HANDLE_VALUE;
#endif
- m_fullName.setLength(0);
- return rc;
+ m_fullName.setLength(0);
+ return rc;
}
/**
*
* @return <code>true</code>: success
*/
-bool ReDirStatus_t::findNext(){
+bool ReDirStatus_t::findNext() {
#if defined __linux__
- bool rc = m_handle != NULL && (m_data = readdir(m_handle)) != NULL;
- m_status.st_ino = 0;
+ bool rc = m_handle != NULL && (m_data = readdir(m_handle)) != NULL;
+ m_status.st_ino = 0;
#elif defined __WIN32__
- bool rc = m_handle != INVALID_HANDLE_VALUE && FindNextFileA(m_handle, &m_data);
+ bool rc = m_handle != INVALID_HANDLE_VALUE && FindNextFileA(m_handle, &m_data);
#endif
- m_fullName.setLength(0);
- return rc;
+ m_fullName.setLength(0);
+ return rc;
}
/**
* Frees the resources of an instance.
*/
-void ReDirStatus_t::freeEntry(){
+void ReDirStatus_t::freeEntry() {
#if defined __linux__
- if (m_handle != NULL){
- closedir(m_handle);
- m_handle = NULL;
- }
+ if (m_handle != NULL) {
+ closedir(m_handle);
+ m_handle = NULL;
+ }
#elif defined __WIN32__
- if (m_handle != INVALID_HANDLE_VALUE){
- FindClose(m_handle);
- m_handle = INVALID_HANDLE_VALUE;
- }
+ if (m_handle != INVALID_HANDLE_VALUE) {
+ FindClose(m_handle);
+ m_handle = INVALID_HANDLE_VALUE;
+ }
#endif
- m_path.setLength(0);
- m_fullName.setLength(0);
+ m_path.setLength(0);
+ m_fullName.setLength(0);
}
/**
*
* @return the filename with path
*/
-const char* ReDirStatus_t::fullName(){
- if (m_fullName.length() == 0)
- m_fullName.set(m_path).append(node(), -1);
- return m_fullName.str();
+const char* ReDirStatus_t::fullName() {
+ if (m_fullName.length() == 0)
+ m_fullName.set(m_path).append(node(), -1);
+ return m_fullName.str();
}
#if defined __WIN32__
* @return <code>true</code>: success
*/
bool ReDirStatus_t::getFileOwner(HANDLE handle, const char* file,
- ReByteBuffer& name, ReLogger* logger){
- bool rc = false;
- PSID pSidOwner = NULL;
- PSECURITY_DESCRIPTOR pSD = NULL;
- if (GetSecurityInfo(handle, SE_FILE_OBJECT,
- OWNER_SECURITY_INFORMATION, &pSidOwner, NULL, NULL, NULL, &pSD) != ERROR_SUCCESS){
- if (logger != NULL)
- logger->sayF(LOG_ERROR | CAT_FILE, LC_GET_FILE_OWNER_1,
- "GetSecurityInfo($1): $2").arg(file).arg((int) GetLastError()).end();
- } else{
- char accountName[128];
- char domainName[128];
- DWORD dwAcctName = sizeof accountName;
- DWORD dwDomainName = sizeof domainName;
- SID_NAME_USE eUse = SidTypeUnknown;
- if (! LookupAccountSid(NULL, pSidOwner, accountName, &dwAcctName, domainName,
- &dwDomainName, &eUse)){
- if (logger != NULL)
- logger->sayF(LOG_ERROR | CAT_SECURITY, LC_GET_FILE_OWNER_2,
- "LookupAccountSid(): $1").arg((int) GetLastError()).end();
- } else{
- if (dwDomainName > 0)
- name.append(domainName).appendChar('\\');
- name.append(accountName);
- rc = true;
- }
- }
- return rc;
+ ReByteBuffer& name, ReLogger* logger) {
+ bool rc = false;
+ PSID pSidOwner = NULL;
+ PSECURITY_DESCRIPTOR pSD = NULL;
+ if (GetSecurityInfo(handle, SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION, &pSidOwner, NULL, NULL, NULL, &pSD) != ERROR_SUCCESS) {
+ if (logger != NULL)
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_GET_FILE_OWNER_1,
+ "GetSecurityInfo($1): $2").arg(file).arg((int) GetLastError()).end();
+ } else {
+ char accountName[128];
+ char domainName[128];
+ DWORD dwAcctName = sizeof accountName;
+ DWORD dwDomainName = sizeof domainName;
+ SID_NAME_USE eUse = SidTypeUnknown;
+ if (! LookupAccountSid(NULL, pSidOwner, accountName, &dwAcctName, domainName,
+ &dwDomainName, &eUse)) {
+ if (logger != NULL)
+ logger->sayF(LOG_ERROR | CAT_SECURITY, LC_GET_FILE_OWNER_2,
+ "LookupAccountSid(): $1").arg((int) GetLastError()).end();
+ } else {
+ if (dwDomainName > 0)
+ name.append(domainName).appendChar('\\');
+ name.append(accountName);
+ rc = true;
+ }
+ }
+ return rc;
}
#endif /* __WIN32__ */
* @param privilege the name of the privilege, e.g. "SeBackup"
* @param logger logger for error logging
*/
-bool ReDirStatus_t::getPrivilege(const char* privilege, ReLogger* logger){
- bool rc = false;
- LUID luidPrivilege;
- HANDLE hAccessToken;
- if (! OpenProcessToken (GetCurrentProcess(),
- TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hAccessToken)){
- if (logger != NULL)
- logger->sayF(LOG_ERROR | CAT_FILE, LC_GET_PRIVILEGE_1,
- "OpenProcessToken(): $1").arg((int) GetLastError()).end();
- } else if (! LookupPrivilegeValue (NULL, SE_BACKUP_NAME, &luidPrivilege)){
- if (logger != NULL)
- logger->sayF(LOG_ERROR | CAT_FILE, LC_GET_PRIVILEGE_2,
- "LookupPrivilegeValue(): $1").arg((int) GetLastError()).end();
- } else{
- TOKEN_PRIVILEGES tpPrivileges;
- tpPrivileges.PrivilegeCount = 1;
- tpPrivileges.Privileges[0].Luid = luidPrivilege;
- tpPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- if (AdjustTokenPrivileges (hAccessToken, FALSE, &tpPrivileges,
- 0, NULL, NULL) == 0)
- rc = true;
- else{
- int error = GetLastError();
- if (error != 1300 && logger != NULL)
- logger->sayF(LOG_ERROR | CAT_FILE, LC_GET_PRIVILEGE_3,
- "AdjustTokenPrivileges(): $1").arg((int) GetLastError()).end();
- }
- }
- return rc;
+bool ReDirStatus_t::getPrivilege(const char* privilege, ReLogger* logger) {
+ bool rc = false;
+ LUID luidPrivilege;
+ HANDLE hAccessToken;
+ if (! OpenProcessToken (GetCurrentProcess(),
+ TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hAccessToken)) {
+ if (logger != NULL)
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_GET_PRIVILEGE_1,
+ "OpenProcessToken(): $1").arg((int) GetLastError()).end();
+ } else if (! LookupPrivilegeValue (NULL, SE_BACKUP_NAME, &luidPrivilege)) {
+ if (logger != NULL)
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_GET_PRIVILEGE_2,
+ "LookupPrivilegeValue(): $1").arg((int) GetLastError()).end();
+ } else {
+ TOKEN_PRIVILEGES tpPrivileges;
+ tpPrivileges.PrivilegeCount = 1;
+ tpPrivileges.Privileges[0].Luid = luidPrivilege;
+ tpPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+ if (AdjustTokenPrivileges (hAccessToken, FALSE, &tpPrivileges,
+ 0, NULL, NULL) == 0)
+ rc = true;
+ else {
+ int error = GetLastError();
+ if (error != 1300 && logger != NULL)
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_GET_PRIVILEGE_3,
+ "AdjustTokenPrivileges(): $1").arg((int) GetLastError()).end();
+ }
+ }
+ return rc;
}
#endif /* __WIN32__ */
*
* @return <code>true</code>: instance contains the data of a directory
*/
-bool ReDirStatus_t::isDirectory(){
+bool ReDirStatus_t::isDirectory() {
#ifdef __linux__
- return m_data->d_type == DT_DIR
- || (m_data->d_type == DT_UNKNOWN && S_ISDIR(getStatus()->st_mode));
+ return m_data->d_type == DT_DIR
+ || (m_data->d_type == DT_UNKNOWN && S_ISDIR(getStatus()->st_mode));
#elif defined __WIN32__
- return 0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
+ return 0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
#endif
}
*
* @return <code>true</code>: an ignorable entry has been found
*/
-bool ReDirStatus_t::isDotDir() const{
+bool ReDirStatus_t::isDotDir() const {
#ifdef __linux__
- bool rc = m_data == NULL
- || (m_data->d_name[0] == '.'
- && (m_data->d_name[1] == '\0'
- || (m_data->d_name[1] == '.' && m_data->d_name[2] == '\0')));
+ bool rc = m_data == NULL
+ || (m_data->d_name[0] == '.'
+ && (m_data->d_name[1] == '\0'
+ || (m_data->d_name[1] == '.' && m_data->d_name[2] == '\0')));
#elif defined __WIN32__
- bool rc = m_data.cFileName[0] == '.' && (m_data.cFileName[1] == '\0'
- || (m_data.cFileName[1] == '.' && m_data.cFileName[2] == '\0'));
+ bool rc = m_data.cFileName[0] == '.' && (m_data.cFileName[1] == '\0'
+ || (m_data.cFileName[1] == '.' && m_data.cFileName[2] == '\0'));
#endif
- return rc;
+ return rc;
}
/**
*
* @return <code>true</code>: instance contains the data of a link
*/
-bool ReDirStatus_t::isLink(){
- bool rc;
+bool ReDirStatus_t::isLink() {
+ bool rc;
#ifdef __linux__
- rc = m_data->d_type == DT_LNK
- || (m_data->d_type == DT_UNKNOWN && S_ISLNK(getStatus()->st_mode));
+ rc = m_data->d_type == DT_LNK
+ || (m_data->d_type == DT_UNKNOWN && S_ISLNK(getStatus()->st_mode));
#elif defined __WIN32__
- rc = 0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT);
+ rc = 0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT);
#endif
- return rc;
+ return rc;
}
/**
* Tests whether the instance is a "normal" file.
*
* @return <code>true</code>: instance contains the data of a not special file
*/
-bool ReDirStatus_t::isRegular(){
+bool ReDirStatus_t::isRegular() {
#ifdef __linux__
- return m_data->d_type == DT_REG
- || (m_data->d_type == DT_UNKNOWN && S_ISREG(getStatus()->st_mode));
+ return m_data->d_type == DT_REG
+ || (m_data->d_type == DT_UNKNOWN && S_ISREG(getStatus()->st_mode));
#elif defined __WIN32__
- return 0 == (m_data.dwFileAttributes & (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE));
+ return 0 == (m_data.dwFileAttributes & (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE));
#endif
}
/**
*
* @return the modification time
*/
-const ReFileTime_t* ReDirStatus_t::modified(){
+const ReFileTime_t* ReDirStatus_t::modified() {
#ifdef __linux__
- return &(getStatus()->st_mtim);
+ return &(getStatus()->st_mtim);
#elif defined __WIN32__
- return &m_data.ftLastWriteTime;
+ return &m_data.ftLastWriteTime;
#endif
}
*
* @return the name of the current file.
*/
-const char* ReDirStatus_t::node() const{
+const char* ReDirStatus_t::node() const {
#ifdef __linux__
- return m_data->d_name;
+ return m_data->d_name;
#elif defined __WIN32__
- return m_data.cFileName;
+ return m_data.cFileName;
#endif
}
-inline void addRight(int mode, ReByteBuffer& buffer){
- char right;
- switch (mode & 7) {
- case 1:
- right = 'x';
- break;
- case 2:
- right = 'w';
- break;
- case 3:
- right = 'X';
- break;
- case 4:
- right = 'r';
- break;
- case 5:
- right = 'R';
- break;
- case 6:
- right = 'W';
- break;
- case 7:
- right = 'A';
- break;
- default:
- right = '-';
- break;
- }
- buffer.appendChar(right);
-}
-inline void addId(const char* id, int maxLength, ReByteBuffer& buffer){
- int length = strlen(id);
- if (length == maxLength)
- buffer.append(id, length);
- else if (length < maxLength)
- buffer.append(id, length).appendChar(' ', maxLength - length);
- else{
- buffer.append(id, 2);
- buffer.append(id + length - maxLength - 2, maxLength - 2);
- }
+inline void addRight(int mode, ReByteBuffer& buffer) {
+ char right;
+ switch (mode & 7) {
+ case 1:
+ right = 'x';
+ break;
+ case 2:
+ right = 'w';
+ break;
+ case 3:
+ right = 'X';
+ break;
+ case 4:
+ right = 'r';
+ break;
+ case 5:
+ right = 'R';
+ break;
+ case 6:
+ right = 'W';
+ break;
+ case 7:
+ right = 'A';
+ break;
+ default:
+ right = '-';
+ break;
+ }
+ buffer.appendChar(right);
+}
+inline void addId(const char* id, int maxLength, ReByteBuffer& buffer) {
+ int length = strlen(id);
+ if (length == maxLength)
+ buffer.append(id, length);
+ else if (length < maxLength)
+ buffer.append(id, length).appendChar(' ', maxLength - length);
+ else {
+ buffer.append(id, 2);
+ buffer.append(id + length - maxLength - 2, maxLength - 2);
+ }
}
/**
* Returns the file rights as a string.
* @return <code>buffer.str()</code> (for chaining)
*/
const char* ReDirStatus_t::rightsAsString(ReByteBuffer& buffer, bool numerical,
- int ownerWidth){
- buffer.setLength(0);
+ int ownerWidth) {
+ buffer.setLength(0);
#if defined __linux__
- if (numerical){
- buffer.appendInt(getStatus()->st_mode & ALLPERMS, "%04o");
- buffer.appendInt(getStatus()->st_uid, " %4d");
- buffer.appendInt(getStatus()->st_gid, " %4d");
- } else{
- int mode = getStatus()->st_mode & ALLPERMS;
- addRight(mode >> 6, buffer);
- addRight(mode >> 3, buffer);
- addRight(mode, buffer);
- buffer.appendChar(' ');
- struct passwd* passwd = getpwuid(getStatus()->st_uid);
- if (passwd == NULL)
- buffer.appendInt(getStatus()->st_uid, "%4d");
- else
- addId(passwd->pw_name, 5, buffer);
- buffer.appendChar(' ');
- struct group* group = getgrgid(getStatus()->st_gid);
- if (group == NULL)
- buffer.appendInt(getStatus()->st_gid, "%4d");
- else
- addId(group->gr_name, 5, buffer);
- buffer.appendChar(' ');
- }
+ if (numerical) {
+ buffer.appendInt(getStatus()->st_mode & ALLPERMS, "%04o");
+ buffer.appendInt(getStatus()->st_uid, " %4d");
+ buffer.appendInt(getStatus()->st_gid, " %4d");
+ } else {
+ int mode = getStatus()->st_mode & ALLPERMS;
+ addRight(mode >> 6, buffer);
+ addRight(mode >> 3, buffer);
+ addRight(mode, buffer);
+ buffer.appendChar(' ');
+ struct passwd* passwd = getpwuid(getStatus()->st_uid);
+ if (passwd == NULL)
+ buffer.appendInt(getStatus()->st_uid, "%4d");
+ else
+ addId(passwd->pw_name, 5, buffer);
+ buffer.appendChar(' ');
+ struct group* group = getgrgid(getStatus()->st_gid);
+ if (group == NULL)
+ buffer.appendInt(getStatus()->st_gid, "%4d");
+ else
+ addId(group->gr_name, 5, buffer);
+ buffer.appendChar(' ');
+ }
#elif defined __WIN32__
- const char* name = fullName();
- HANDLE handle = INVALID_HANDLE_VALUE;
- if (! isDirectory()){
- if ( (handle = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
- m_logger->sayF(LOG_ERROR | CAT_FILE, LC_RIGHTS_AS_STRING_1,
- "CreateFile($1): $2").arg(name).arg((int) GetLastError()).end();
- } else if (m_getPrivilege){
- // we try only one time:
- m_getPrivilege = false;
- if (getPrivilege(SE_BACKUP_NAME, m_logger)){
- if ( (handle = CreateFile(name, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
- NULL)) != INVALID_HANDLE_VALUE)
- m_logger->sayF(LOG_ERROR | CAT_FILE, LC_RIGHTS_AS_STRING_2,
- "CreateFile($1): $2").arg(name).arg((int) GetLastError()).end();
- }
-
- }
- ReByteBuffer owner;
- if (handle != INVALID_HANDLE_VALUE)
- getFileOwner(handle, name, owner, m_logger);
- CloseHandle(handle);
- buffer.appendFix(owner.str(), owner.length(), ownerWidth, ownerWidth);
+ const char* name = fullName();
+ HANDLE handle = INVALID_HANDLE_VALUE;
+ if (! isDirectory()) {
+ if ( (handle = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
+ m_logger->sayF(LOG_ERROR | CAT_FILE, LC_RIGHTS_AS_STRING_1,
+ "CreateFile($1): $2").arg(name).arg((int) GetLastError()).end();
+ } else if (m_getPrivilege) {
+ // we try only one time:
+ m_getPrivilege = false;
+ if (getPrivilege(SE_BACKUP_NAME, m_logger)) {
+ if ( (handle = CreateFile(name, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
+ NULL)) != INVALID_HANDLE_VALUE)
+ m_logger->sayF(LOG_ERROR | CAT_FILE, LC_RIGHTS_AS_STRING_2,
+ "CreateFile($1): $2").arg(name).arg((int) GetLastError()).end();
+ }
+
+ }
+ ReByteBuffer owner;
+ if (handle != INVALID_HANDLE_VALUE)
+ getFileOwner(handle, name, owner, m_logger);
+ CloseHandle(handle);
+ buffer.appendFix(owner.str(), owner.length(), ownerWidth, ownerWidth);
#endif
- return buffer.str();
+ return buffer.str();
}
/**
* @param time the unix time (secondes since 1.1.1970)
* @param filetime OUT: the OS specific filetime
*/
-void ReDirStatus_t::timeToFiletime(time_t time, ReFileTime_t& filetime){
+void ReDirStatus_t::timeToFiletime(time_t time, ReFileTime_t& filetime) {
#ifdef __linux__
- filetime.tv_sec = time;
- filetime.tv_nsec = 0;
+ filetime.tv_sec = time;
+ filetime.tv_nsec = 0;
#elif defined __WIN32__
- LONGLONG ll = Int32x32To64(time, 10000000) + 116444736000000000;
- filetime.dwLowDateTime = (DWORD)ll;
- filetime.dwHighDateTime = ll >> 32;
+ LONGLONG ll = Int32x32To64(time, 10000000) + 116444736000000000;
+ filetime.dwLowDateTime = (DWORD)ll;
+ filetime.dwHighDateTime = ll >> 32;
#endif
}
/**
* Returns the type of the entry.
* return the file type, e.g. TF_REGULAR
*/
-ReDirStatus_t::Type_t ReDirStatus_t::type(){
- Type_t rc = TF_UNDEF;
+ReDirStatus_t::Type_t ReDirStatus_t::type() {
+ Type_t rc = TF_UNDEF;
#if defined __linux__
- int flags = getStatus()->st_mode;
- if (S_ISDIR(flags))
- rc = TF_SUBDIR;
- else if (flags == 0 || S_ISREG(flags))
- rc = TF_REGULAR;
- else if (S_ISLNK(flags))
- rc = TF_LINK;
- else if (S_ISCHR(flags))
- rc = TF_CHAR;
- else if (S_ISBLK(flags))
- rc = TF_BLOCK;
- else if (S_ISFIFO(flags))
- rc = TF_PIPE;
- else if (S_ISSOCK(flags))
- rc = TF_SOCKET;
- else
- rc = TF_OTHER;
+ int flags = getStatus()->st_mode;
+ if (S_ISDIR(flags))
+ rc = TF_SUBDIR;
+ else if (flags == 0 || S_ISREG(flags))
+ rc = TF_REGULAR;
+ else if (S_ISLNK(flags))
+ rc = TF_LINK;
+ else if (S_ISCHR(flags))
+ rc = TF_CHAR;
+ else if (S_ISBLK(flags))
+ rc = TF_BLOCK;
+ else if (S_ISFIFO(flags))
+ rc = TF_PIPE;
+ else if (S_ISSOCK(flags))
+ rc = TF_SOCKET;
+ else
+ rc = TF_OTHER;
#elif defined __WIN32__
- int flags = (m_data.dwFileAttributes & ~(FILE_ATTRIBUTE_READONLY
- | FILE_ATTRIBUTE_HIDDEN
- | FILE_ATTRIBUTE_SYSTEM
- | FILE_ATTRIBUTE_ARCHIVE
- | FILE_ATTRIBUTE_NORMAL
- | FILE_ATTRIBUTE_TEMPORARY
- | FILE_ATTRIBUTE_SPARSE_FILE
- | FILE_ATTRIBUTE_COMPRESSED
- | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
- | FILE_ATTRIBUTE_ENCRYPTED
- | FILE_ATTRIBUTE_HIDDEN));
-
- if (0 == flags)
- rc = TF_REGULAR;
- else if (0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){
- rc = (0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))
- ? TF_LINK_DIR : TF_SUBDIR;
- } else if (0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))
- rc = TF_LINK;
- else
- rc = TF_OTHER;
+ int flags = (m_data.dwFileAttributes & ~(FILE_ATTRIBUTE_READONLY
+ | FILE_ATTRIBUTE_HIDDEN
+ | FILE_ATTRIBUTE_SYSTEM
+ | FILE_ATTRIBUTE_ARCHIVE
+ | FILE_ATTRIBUTE_NORMAL
+ | FILE_ATTRIBUTE_TEMPORARY
+ | FILE_ATTRIBUTE_SPARSE_FILE
+ | FILE_ATTRIBUTE_COMPRESSED
+ | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
+ | FILE_ATTRIBUTE_ENCRYPTED
+ | FILE_ATTRIBUTE_HIDDEN));
+
+ if (0 == flags)
+ rc = TF_REGULAR;
+ else if (0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+ rc = (0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))
+ ? TF_LINK_DIR : TF_SUBDIR;
+ } else if (0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))
+ rc = TF_LINK;
+ else
+ rc = TF_OTHER;
#endif
- return rc;
+ return rc;
}
/**
*
* @return the filetype, e.g. 'd' for a directory
*/
-char ReDirStatus_t::typeAsChar(){
- char rc = ' ';
- switch (type()) {
- case TF_REGULAR:
- rc = ' ';
- break;
- case TF_LINK:
- rc = 'l';
- break;
- case TF_SUBDIR:
- rc = 'd';
- break;
- case TF_CHAR:
- rc = 'c';
- break;
- case TF_BLOCK:
- rc = 'b';
- break;
- case TF_PIPE:
- rc = 'p';
- break;
- case TF_SOCKET:
- rc = 's';
- break;
- default:
- rc = 'o';
- break;
- }
- return rc;
+char ReDirStatus_t::typeAsChar() {
+ char rc = ' ';
+ switch (type()) {
+ case TF_REGULAR:
+ rc = ' ';
+ break;
+ case TF_LINK:
+ rc = 'l';
+ break;
+ case TF_SUBDIR:
+ rc = 'd';
+ break;
+ case TF_CHAR:
+ rc = 'c';
+ break;
+ case TF_BLOCK:
+ rc = 'b';
+ break;
+ case TF_PIPE:
+ rc = 'p';
+ break;
+ case TF_SOCKET:
+ rc = 's';
+ break;
+ default:
+ rc = 'o';
+ break;
+ }
+ return rc;
}
/**
* Constructor.
*/
ReDirEntryFilter::ReDirEntryFilter() :
- ReSerializable(m_serialId),
- m_types(ReDirStatus_t::TC_ALL),
- m_nodePatterns(NULL),
- m_pathPatterns(NULL),
- m_minSize(0),
- m_maxSize(-1),
- //m_minAge(0),
- //m_maxAge(0),
- m_minDepth(0),
- m_maxDepth(512),
- m_allDirectories(false){
- setFiletimeUndef(m_minAge);
- setFiletimeUndef(m_maxAge);
+ ReSerializable(m_serialId),
+ m_types(ReDirStatus_t::TC_ALL),
+ m_nodePatterns(NULL),
+ m_pathPatterns(NULL),
+ m_minSize(0),
+ m_maxSize(-1),
+ //m_minAge(0),
+ //m_maxAge(0),
+ m_minDepth(0),
+ m_maxDepth(512),
+ m_allDirectories(false) {
+ setFiletimeUndef(m_minAge);
+ setFiletimeUndef(m_maxAge);
}
/**
* Destructor.
*/
-ReDirEntryFilter::~ReDirEntryFilter(){
+ReDirEntryFilter::~ReDirEntryFilter() {
}
/**
* @param sequence IN/OUT: the serialized byte sequence
* @param length INT/OUT the length of <code>sequence</code>
*/
-void ReDirEntryFilter::deserialize(const uint8_t*& sequence, size_t& length){
- int id;
- unpackInt24(sequence, length, id);
- if (id != m_serialId)
- throw ReSerializeFormatException("wrong serialId", this);
- ReByteBuffer buffer;
- unpackString64k(sequence, length, buffer);
- bool ignoreCase;
- unpackBool(sequence, length, ignoreCase);
- m_nodePatterns->set(buffer.str(), ignoreCase);
- unpackString64k(sequence, length, buffer);
- unpackBool(sequence, length, ignoreCase);
- unpackString64k(sequence, length, buffer);
- m_pathPatterns->set(buffer.str(), ignoreCase);
- unpackInt64(sequence, length, m_minSize);
- unpackInt64(sequence, length, m_maxSize);
- int64_t value;
- unpackInt64(sequence, length, value);
- unpackBool(sequence, length, m_allDirectories);
+void ReDirEntryFilter::deserialize(const uint8_t*& sequence, size_t& length) {
+ int id;
+ unpackInt24(sequence, length, id);
+ if (id != m_serialId)
+ throw ReSerializeFormatException("wrong serialId", this);
+ ReByteBuffer buffer;
+ unpackString64k(sequence, length, buffer);
+ bool ignoreCase;
+ unpackBool(sequence, length, ignoreCase);
+ m_nodePatterns->set(buffer.str(), ignoreCase);
+ unpackString64k(sequence, length, buffer);
+ unpackBool(sequence, length, ignoreCase);
+ unpackString64k(sequence, length, buffer);
+ m_pathPatterns->set(buffer.str(), ignoreCase);
+ unpackInt64(sequence, length, m_minSize);
+ unpackInt64(sequence, length, m_maxSize);
+ int64_t value;
+ unpackInt64(sequence, length, value);
+ unpackBool(sequence, length, m_allDirectories);
}
/**
* Packs the members into a byte sequence.
*
* @param sequence IN/OUT: the place for the byte sequence
*/
-ReByteBuffer& ReDirEntryFilter::serialize(ReByteBuffer& sequence){
- sequence.appendBits24(m_serialId);
- packString64k(sequence, m_nodePatterns->patternString());
- packBool(sequence, m_nodePatterns->ignoreCase());
- packString64k(sequence, m_pathPatterns->patternString());
- packBool(sequence, m_pathPatterns->ignoreCase());
- sequence.appendBits64(m_minSize);
- sequence.appendBits64(m_maxSize);
- uint64_t value;
+ReByteBuffer& ReDirEntryFilter::serialize(ReByteBuffer& sequence) {
+ sequence.appendBits24(m_serialId);
+ packString64k(sequence, m_nodePatterns->patternString());
+ packBool(sequence, m_nodePatterns->ignoreCase());
+ packString64k(sequence, m_pathPatterns->patternString());
+ packBool(sequence, m_pathPatterns->ignoreCase());
+ sequence.appendBits64(m_minSize);
+ sequence.appendBits64(m_maxSize);
+ uint64_t value;
#if defined __linux__
- value = (m_minAge.tv_sec << 32) + m_minAge.tv_nsec;
- sequence.appendBits64(int64_t(value));
- value = (m_minAge.tv_sec << 32) + m_minAge.tv_nsec;
+ value = (m_minAge.tv_sec << 32) + m_minAge.tv_nsec;
+ sequence.appendBits64(int64_t(value));
+ value = (m_minAge.tv_sec << 32) + m_minAge.tv_nsec;
#elif defined __WIN32__
#error "missing impl"
#endif
- sequence.appendBits64(int64_t(value));
- packBool(sequence, m_allDirectories);
+ sequence.appendBits64(int64_t(value));
+ packBool(sequence, m_allDirectories);
}
/**
* @return <true>: the entry matches the conditions of the filter<br>
* <false>: otherwise
*/
-bool ReDirEntryFilter::match(ReDirStatus_t& entry){
- bool rc = false;
- do{
- if (m_allDirectories && entry.isDirectory()){
- rc = true;
- break;
- }
- if (0 == (entry.type() & m_types))
- break;
- int64_t size = entry.fileSize();
- if (m_minSize > 0 && size < m_minSize)
- break;
- if (m_maxSize >= 0 && size > m_maxSize)
- break;
- if (!filetimeIsUndefined(m_minAge) && *entry.modified() > m_minAge)
- break;
- if (!filetimeIsUndefined(m_maxAge) && m_maxAge > *entry.modified())
- break;
- const char* node = entry.node();
- if (m_nodePatterns != NULL && !m_nodePatterns->match(node))
- break;
- rc = true;
- }while (false);
- return rc;
+bool ReDirEntryFilter::match(ReDirStatus_t& entry) {
+ bool rc = false;
+ do {
+ if (m_allDirectories && entry.isDirectory()) {
+ rc = true;
+ break;
+ }
+ if (0 == (entry.type() & m_types))
+ break;
+ int64_t size = entry.fileSize();
+ if (m_minSize > 0 && size < m_minSize)
+ break;
+ if (m_maxSize >= 0 && size > m_maxSize)
+ break;
+ if (!filetimeIsUndefined(m_minAge) && *entry.modified() > m_minAge)
+ break;
+ if (!filetimeIsUndefined(m_maxAge) && m_maxAge > *entry.modified())
+ break;
+ const char* node = entry.node();
+ if (m_nodePatterns != NULL && !m_nodePatterns->match(node))
+ break;
+ rc = true;
+ } while (false);
+ return rc;
}
;
*
* @return the status of the current file
*/
-struct stat* ReDirStatus_t::getStatus(){
- if (m_status.st_ino == 0){
- if (stat(fullName(), &m_status) != 0)
- m_status.st_ino = 0;
- }
- return &m_status;
+struct stat* ReDirStatus_t::getStatus() {
+ if (m_status.st_ino == 0) {
+ if (stat(fullName(), &m_status) != 0)
+ m_status.st_ino = 0;
+ }
+ return &m_status;
}
#endif
* Constructor.
*/
ReDirTreeStatistic::ReDirTreeStatistic() :
- m_directories(0), m_files(0), m_sizes(0ll){
+ m_directories(0),
+ m_files(0),
+ m_sizes(0ll) {
}
/**
* Builds a string describing the data.
* @return a human readable string
*/
const char* ReDirTreeStatistic::statisticAsString(ReByteBuffer& buffer,
- bool append, const char* formatFiles, const char* formatSizes,
- const char* formatDirs){
- if (!append)
- buffer.setLength(0);
- buffer.appendInt(m_files, formatFiles);
- buffer.append(i18n("file(s)")).appendChar(' ');
- buffer.append(m_sizes / 1000.0 / 1000, formatSizes);
- buffer.append(" ", 1).append(i18n("MByte")).appendChar(' ');
- buffer.appendInt(m_directories, formatDirs);
- buffer.append(i18n("dirs(s)"));
- return buffer.str();
+ bool append, const char* formatFiles, const char* formatSizes,
+ const char* formatDirs) {
+ if (!append)
+ buffer.setLength(0);
+ buffer.appendInt(m_files, formatFiles);
+ buffer.append(i18n("file(s)")).appendChar(' ');
+ buffer.append(m_sizes / 1000.0 / 1000, formatSizes);
+ buffer.append(" ", 1).append(i18n("MByte")).appendChar(' ');
+ buffer.appendInt(m_directories, formatDirs);
+ buffer.append(i18n("dirs(s)"));
+ return buffer.str();
}
/**
* @param interval the minimum number of seconds between two traces
*/
ReTraceUnit::ReTraceUnit(int triggerCount, int interval) :
- m_count(0),
- m_triggerCount(triggerCount),
- m_lastTrace(0),
- m_interval(interval),
- m_startTime(time(NULL)){
- m_lastTrace = m_startTime;
+ m_count(0),
+ m_triggerCount(triggerCount),
+ m_lastTrace(0),
+ m_interval(interval),
+ m_startTime(time(NULL)) {
+ m_lastTrace = m_startTime;
}
/**
* Destructor.
*/
-ReTraceUnit::~ReTraceUnit(){
+ReTraceUnit::~ReTraceUnit() {
}
/**
* @param message message for the trace
* @return <code>true</code> (for chaining)
*/
-bool ReTraceUnit::trace(const char* message){
- printf("%s\n", message);
- return true;
+bool ReTraceUnit::trace(const char* message) {
+ printf("%s\n", message);
+ return true;
}
/**
* @param base the base directory. The traversal starts at this point
*/
ReTraverser::ReTraverser(const char* base, ReTraceUnit* tracer,
- ReLogger* logger) :
- ReDirTreeStatistic(),
- m_minLevel(0),
- m_maxLevel(512),
- m_level(-1),
- m_base(base),
- // m_dirs
- m_passNoForDirSearch(2),
- m_dirPatterns(NULL),
- m_tracer(tracer),
- m_logger(logger){
- memset(m_dirs, 0, sizeof m_dirs);
- m_dirs[0] = new ReDirStatus_t(m_logger);
- // remove a preceeding "./". This simplifies the pattern expressions:
- if (m_base.startsWith(
- ReByteBuffer(".").appendChar(OS_SEPARATOR_CHAR).str())){
- m_base.remove(0, 2);
- }
+ ReLogger* logger) :
+ ReDirTreeStatistic(),
+ m_minLevel(0),
+ m_maxLevel(512),
+ m_level(-1),
+ m_base(base),
+ // m_dirs
+ m_passNoForDirSearch(2),
+ m_dirPatterns(NULL),
+ m_tracer(tracer),
+ m_logger(logger) {
+ memset(m_dirs, 0, sizeof m_dirs);
+ m_dirs[0] = new ReDirStatus_t(m_logger);
+ // remove a preceeding "./". This simplifies the pattern expressions:
+ if (m_base.startsWith(
+ ReByteBuffer(".").appendChar(OS_SEPARATOR_CHAR).str())) {
+ m_base.remove(0, 2);
+ }
}
/**
* Destructor.
*/
-ReTraverser::~ReTraverser(){
- destroy();
+ReTraverser::~ReTraverser() {
+ destroy();
}
/**
*
* @param base the base directory to search
*/
-void ReTraverser::changeBase(const char* base){
- destroy();
- m_base.setLength(0).append(base);
- memset(m_dirs, 0, sizeof m_dirs);
- m_dirs[0] = new ReDirStatus_t(m_logger);
- // remove a preceeding "./". This simplifies the pattern expressions:
- if (m_base.startsWith(
- ReByteBuffer(".").appendChar(OS_SEPARATOR_CHAR).str())){
- m_base.remove(0, 2);
- }
+void ReTraverser::changeBase(const char* base) {
+ destroy();
+ m_base.setLength(0).append(base);
+ memset(m_dirs, 0, sizeof m_dirs);
+ m_dirs[0] = new ReDirStatus_t(m_logger);
+ // remove a preceeding "./". This simplifies the pattern expressions:
+ if (m_base.startsWith(
+ ReByteBuffer(".").appendChar(OS_SEPARATOR_CHAR).str())) {
+ m_base.remove(0, 2);
+ }
}
/**
* Releases the resources.
*/
-void ReTraverser::destroy(){
- for (size_t ix = 0; ix < sizeof m_dirs / sizeof m_dirs[0]; ix++){
- if (m_dirs[ix] != NULL){
- m_dirs[ix]->freeEntry();
- delete m_dirs[ix];
- m_dirs[ix] = NULL;
- }
- }
+void ReTraverser::destroy() {
+ for (size_t ix = 0; ix < sizeof m_dirs / sizeof m_dirs[0]; ix++) {
+ if (m_dirs[ix] != NULL) {
+ m_dirs[ix]->freeEntry();
+ delete m_dirs[ix];
+ m_dirs[ix] = NULL;
+ }
+ }
}
/**
* Returns the info about the next file in the directory tree traversal.
* otherwise: the stack entry with the next file in the
* directory tree. May be a directory too
*/
-ReDirStatus_t* ReTraverser::rawNextFile(int& level){
- ReDirStatus_t* rc = NULL;
- bool alreadyRead = false;
- bool again;
- do{
- again = false;
- if (m_level < 0){
- // Not yet initialized?
- if (m_dirs[0]->m_passNo == 2)
- rc = NULL;
- else{
- // first call:
- if (initEntry(m_base.str(), NULL, 0)){
- m_directories++;
- if (1 != m_passNoForDirSearch)
- rc = m_dirs[0];
- else
- again = alreadyRead = true;
- }
- }
- }else{
- ReDirStatus_t* current = m_dirs[m_level];
- if (alreadyRead || current->findNext()){
- alreadyRead = false;
- // a file or directory found:
- if (m_tracer != NULL && m_tracer->isCountTriggered()
- && m_tracer->isTimeTriggered())
- m_tracer->trace(current->fullName());
- if (current->m_passNo != m_passNoForDirSearch){
- // we search for any file:
- rc = m_dirs[m_level];
- }else{
- // we are interested only in true subdirectories:
- again = true;
- if (m_level < m_maxLevel && current->isDirectory()
- && !current->isDotDir() && !current->isLink()
- && (m_dirPatterns == NULL || isAllowedDir(current->node()))){
- // open a new level
- alreadyRead = initEntry(current->m_path, current->node(),
- m_level + 1);
- m_directories++;
- }
- }
- }else{
- // the current subdir does not have more files:
- if (current->m_passNo == 1){
- // we start the second pass:
- alreadyRead = initEntry(current->m_path, NULL, -1);
- current->m_passNo = 2;
- again = true;
- }else{
- // this subdirectory is complete. We continue in the parent directory:
- current->freeEntry();
- if (--m_level >= 0){
- again = true;
- }
- }
- }
- }
- if (rc != NULL && rc->isDotDir())
- again = true;
- }while (again);
- if (rc != NULL && !rc->isDirectory()){
- m_files++;
- if (m_sizes >= 0)
- m_sizes += rc->fileSize();
- }
- level = m_level;
- return rc;
+ReDirStatus_t* ReTraverser::rawNextFile(int& level) {
+ ReDirStatus_t* rc = NULL;
+ bool alreadyRead = false;
+ bool again;
+ do {
+ again = false;
+ if (m_level < 0) {
+ // Not yet initialized?
+ if (m_dirs[0]->m_passNo == 2)
+ rc = NULL;
+ else {
+ // first call:
+ if (initEntry(m_base.str(), NULL, 0)) {
+ m_directories++;
+ if (1 != m_passNoForDirSearch)
+ rc = m_dirs[0];
+ else
+ again = alreadyRead = true;
+ }
+ }
+ } else {
+ ReDirStatus_t* current = m_dirs[m_level];
+ if (alreadyRead || current->findNext()) {
+ alreadyRead = false;
+ // a file or directory found:
+ if (m_tracer != NULL && m_tracer->isCountTriggered()
+ && m_tracer->isTimeTriggered())
+ m_tracer->trace(current->fullName());
+ if (current->m_passNo != m_passNoForDirSearch) {
+ // we search for any file:
+ rc = m_dirs[m_level];
+ } else {
+ // we are interested only in true subdirectories:
+ again = true;
+ if (m_level < m_maxLevel && current->isDirectory()
+ && !current->isDotDir() && !current->isLink()
+ && (m_dirPatterns == NULL
+ || isAllowedDir(current->node()))) {
+ // open a new level
+ alreadyRead = initEntry(current->m_path,
+ current->node(), m_level + 1);
+ m_directories++;
+ }
+ }
+ } else {
+ // the current subdir does not have more files:
+ if (current->m_passNo == 1) {
+ // we start the second pass:
+ alreadyRead = initEntry(current->m_path, NULL, -1);
+ current->m_passNo = 2;
+ again = true;
+ } else {
+ // this subdirectory is complete. We continue in the parent directory:
+ current->freeEntry();
+ if (--m_level >= 0) {
+ again = true;
+ }
+ }
+ }
+ }
+ if (rc != NULL && rc->isDotDir())
+ again = true;
+ } while (again);
+ if (rc != NULL && !rc->isDirectory()) {
+ m_files++;
+ if (m_sizes >= 0)
+ m_sizes += rc->fileSize();
+ }
+ level = m_level;
+ return rc;
}
/**
* Returns the info about the next file matching the filter options.
* otherwise: the info about the next file in the
* directory tree
*/
-ReDirStatus_t* ReTraverser::nextFile(int& level, ReDirEntryFilter* filter){
- ReDirStatus_t* rc = rawNextFile(level);
- while (rc != NULL){
- if (filter == NULL || filter->match(*rc)){
- break;
- }
- rc = rawNextFile(level);
- }
- return rc;
+ReDirStatus_t* ReTraverser::nextFile(int& level, ReDirEntryFilter* filter) {
+ ReDirStatus_t* rc = rawNextFile(level);
+ while (rc != NULL) {
+ if (filter == NULL || filter->match(*rc)) {
+ break;
+ }
+ rc = rawNextFile(level);
+ }
+ return rc;
}
/**
* <cude>false/code>: findFirstEntry() signals: no entry.
*/
bool ReTraverser::initEntry(const ReByteBuffer& parent, const char* node,
- int level){
- bool rc = false;
- if (level < MAX_ENTRY_STACK_DEPTH){
- if (level >= 0)
- m_level = level;
- if (m_dirs[m_level] == NULL)
- m_dirs[m_level] = new ReDirStatus_t(m_logger);
- ReDirStatus_t* current = m_dirs[m_level];
- current->m_passNo = 1;
- if (level >= 0){
- current->m_path.set(parent.str(), parent.length());
- if (!parent.endsWith(OS_SEPARATOR))
- current->m_path.append(OS_SEPARATOR);
- if (node != NULL)
- current->m_path.append(node).append(OS_SEPARATOR);
- }
- rc = current->findFirst();
- }
- return rc;
+ int level) {
+ bool rc = false;
+ if (level < MAX_ENTRY_STACK_DEPTH) {
+ if (level >= 0)
+ m_level = level;
+ if (m_dirs[m_level] == NULL)
+ m_dirs[m_level] = new ReDirStatus_t(m_logger);
+ ReDirStatus_t* current = m_dirs[m_level];
+ current->m_passNo = 1;
+ if (level >= 0) {
+ current->m_path.set(parent.str(), parent.length());
+ if (!parent.endsWith(OS_SEPARATOR))
+ current->m_path.append(OS_SEPARATOR);
+ if (node != NULL)
+ current->m_path.append(node).append(OS_SEPARATOR);
+ }
+ rc = current->findFirst();
+ }
+ return rc;
}
/**
*
* @param filter the filter with the properties to set
*/
-void ReTraverser::setPropertiesFromFilter(ReDirEntryFilter* filter){
- m_minLevel = filter->m_minDepth;
- m_maxLevel = filter->m_maxDepth;
- setDirPattern(filter->m_pathPatterns);
+void ReTraverser::setPropertiesFromFilter(ReDirEntryFilter* filter) {
+ m_minLevel = filter->m_minDepth;
+ m_maxLevel = filter->m_maxDepth;
+ setDirPattern(filter->m_pathPatterns);
}
/**
* @return NULL: not available<br>
* otherwise: the wanted entry
*/
-ReDirStatus_t* ReTraverser::topOfStack(int offsetFromTop){
- ReDirStatus_t* rc = NULL;
- if (offsetFromTop >= 0 && m_level - 1 - offsetFromTop >= 0)
- rc = m_dirs[m_level - 1 - offsetFromTop];
- return rc;
+ReDirStatus_t* ReTraverser::topOfStack(int offsetFromTop) {
+ ReDirStatus_t* rc = NULL;
+ if (offsetFromTop >= 0 && m_level - 1 - offsetFromTop >= 0)
+ rc = m_dirs[m_level - 1 - offsetFromTop];
+ return rc;
}
* @param time the filetime to test
* @return <code>true</code>: the given filetime is undefined
*/
-inline bool filetimeIsUndefined(ReFileTime_t& time){
+inline bool filetimeIsUndefined(ReFileTime_t& time) {
#if defined __linux__
- return time.tv_sec == 0 && time.tv_nsec == 0;
+ return time.tv_sec == 0 && time.tv_nsec == 0;
#elif defined __WIN32__
- return time.dwHighDateTime == 0 && time.dwLowDateTime == 0;
+ return time.dwHighDateTime == 0 && time.dwLowDateTime == 0;
#endif
}
/** Sets the filetime to undefined.
* @param time the filetime to clear
*/
-inline void setFiletimeUndef(ReFileTime_t& time){
+inline void setFiletimeUndef(ReFileTime_t& time) {
#if defined __linux__
- time.tv_sec = time.tv_nsec = 0;
+ time.tv_sec = time.tv_nsec = 0;
#elif defined __WIN32__
- time.dwHighDateTime = time.dwLowDateTime = 0;
+ time.dwHighDateTime = time.dwLowDateTime = 0;
#endif
}
class ReDirStatus_t {
public:
- enum Type_t {
- TF_UNDEF = 0,
- // single property flags:
- TF_SUBDIR = 1 << 0,
- TF_REGULAR = 1 << 1,
- TF_LINK = 1 << 2,
- TF_LINK_DIR = 1 << 3,
- TF_BLOCK = 1 << 4,
- TF_PIPE = 1 << 5,
- TF_CHAR = 1 << 6,
- TF_SOCKET = 1 << 7,
- TF_OTHER = 1 << 8,
- // collections:
- TC_SPECIAL = (TF_BLOCK | TF_CHAR | TF_SOCKET | TF_PIPE | TF_OTHER),
- TC_NON_DIR = (TC_SPECIAL | TF_LINK | TF_REGULAR),
- TC_ALL = (TF_SUBDIR | TC_NON_DIR | TF_LINK_DIR)
- };
+ enum Type_t {
+ TF_UNDEF = 0,
+ // single property flags:
+ TF_SUBDIR = 1 << 0,
+ TF_REGULAR = 1 << 1,
+ TF_LINK = 1 << 2,
+ TF_LINK_DIR = 1 << 3,
+ TF_BLOCK = 1 << 4,
+ TF_PIPE = 1 << 5,
+ TF_CHAR = 1 << 6,
+ TF_SOCKET = 1 << 7,
+ TF_OTHER = 1 << 8,
+ // collections:
+ TC_SPECIAL = (TF_BLOCK | TF_CHAR | TF_SOCKET | TF_PIPE | TF_OTHER),
+ TC_NON_DIR = (TC_SPECIAL | TF_LINK | TF_REGULAR),
+ TC_ALL = (TF_SUBDIR | TC_NON_DIR | TF_LINK_DIR)
+ };
public:
- ReDirStatus_t(ReLogger* logger);
+ ReDirStatus_t(ReLogger* logger);
public:
- const ReFileTime_t* accessed();
- ReFileSize_t fileSize();
- const char* filetimeAsString(ReByteBuffer& buffer);
- bool findFirst();
- bool findNext();
- void freeEntry();
- const char* fullName();
- bool isDirectory();
- bool isDotDir() const;
- bool isLink();
- bool isRegular();
- const ReFileTime_t* modified();
- const char* node() const;
- const char* rightsAsString(ReByteBuffer& buffer, bool numerical,
- int ownerWidth);
- Type_t type();
- char typeAsChar();
+ const ReFileTime_t* accessed();
+ ReFileSize_t fileSize();
+ const char* filetimeAsString(ReByteBuffer& buffer);
+ bool findFirst();
+ bool findNext();
+ void freeEntry();
+ const char* fullName();
+ bool isDirectory();
+ bool isDotDir() const;
+ bool isLink();
+ bool isRegular();
+ const ReFileTime_t* modified();
+ const char* node() const;
+ const char* rightsAsString(ReByteBuffer& buffer, bool numerical,
+ int ownerWidth);
+ Type_t type();
+ char typeAsChar();
public:
- static const char* filetimeToString(const ReFileTime_t* time,
- ReByteBuffer& buffer);
- static time_t filetimeToTime(const ReFileTime_t* time);
+ static const char* filetimeToString(const ReFileTime_t* time,
+ ReByteBuffer& buffer);
+ static time_t filetimeToTime(const ReFileTime_t* time);
#if defined __WIN32__
- static bool getFileOwner(HANDLE handle, const char* file, ReByteBuffer& name,
- ReLogger* logger = NULL);
- static bool getPrivilege(const char* privilege, ReLogger* logger);
+ static bool getFileOwner(HANDLE handle, const char* file, ReByteBuffer& name,
+ ReLogger* logger = NULL);
+ static bool getPrivilege(const char* privilege, ReLogger* logger);
#endif
- static void timeToFiletime(time_t time, ReFileTime_t& filetime);
+ static void timeToFiletime(time_t time, ReFileTime_t& filetime);
public:
- ReByteBuffer m_path;
- ReByteBuffer m_fullName;
- int m_passNo;
- ReLogger* m_logger;
+ ReByteBuffer m_path;
+ ReByteBuffer m_fullName;
+ int m_passNo;
+ ReLogger* m_logger;
#ifdef __linux__
- DIR* m_handle;
- struct dirent* m_data;
- struct stat m_status;
+ DIR* m_handle;
+ struct dirent* m_data;
+ struct stat m_status;
public:
- struct stat* getStatus();
+ struct stat* getStatus();
#elif defined WIN32
- HANDLE m_handle;
- WIN32_FIND_DATAA m_data;
- bool m_getPrivilege;
+ HANDLE m_handle;
+ WIN32_FIND_DATAA m_data;
+ bool m_getPrivilege;
#endif
};
class ReDirEntryFilter: public ReSerializable {
public:
- ReDirEntryFilter();
- ~ReDirEntryFilter();
+ ReDirEntryFilter();
+ ~ReDirEntryFilter();
public:
- virtual void deserialize(const uint8_t*& sequence, size_t& length);
- bool match(ReDirStatus_t& entry);
- virtual ReByteBuffer& serialize(ReByteBuffer& sequence);
+ virtual void deserialize(const uint8_t*& sequence, size_t& length);
+ bool match(ReDirStatus_t& entry);
+ virtual ReByteBuffer& serialize(ReByteBuffer& sequence);
public:
- ReDirStatus_t::Type_t m_types;
- RePatternList* m_nodePatterns;
- RePatternList* m_pathPatterns;
- ReFileSize_t m_minSize;
- ReFileSize_t m_maxSize;
- ReFileTime_t m_minAge;
- ReFileTime_t m_maxAge;
- int m_minDepth;
- int m_maxDepth;
- bool m_allDirectories;
+ ReDirStatus_t::Type_t m_types;
+ RePatternList* m_nodePatterns;
+ RePatternList* m_pathPatterns;
+ ReFileSize_t m_minSize;
+ ReFileSize_t m_maxSize;
+ ReFileTime_t m_minAge;
+ ReFileTime_t m_maxAge;
+ int m_minDepth;
+ int m_maxDepth;
+ bool m_allDirectories;
private:
- static int m_serialId;
+ static int m_serialId;
};
class ReTraceUnit {
public:
- ReTraceUnit(int m_triggerCount = 10, int interval = 60);
- virtual ~ReTraceUnit();
+ ReTraceUnit(int m_triggerCount = 10, int interval = 60);
+ virtual ~ReTraceUnit();
public:
- /** Returns whether the the instance is triggered.
- * To avoid too the not cheap call of time() the trace unit uses a counter.
- * If the counter reaches a given level the time check should be done.
- * @return <code>true</code>: the counter has reached <code>m_triggerCount</code>
- */
- inline bool isCountTriggered(){
- bool rc = ++m_count % m_triggerCount == 0;
- return rc;
- }
- /** Tests whether a given waiting time has been gone since the last trace.
- * @return <code>true</code>: the last trace has been done after
- * at least <code>m_interval</code> seconds
- */
- inline bool isTimeTriggered(){
- time_t now = time(NULL);
- bool rc = now - m_lastTrace > m_interval;
- if (rc){
- m_lastTrace = now;
- }
- return rc;
- }
- virtual bool trace(const char* message);
+ /** Returns whether the the instance is triggered.
+ * To avoid too the not cheap call of time() the trace unit uses a counter.
+ * If the counter reaches a given level the time check should be done.
+ * @return <code>true</code>: the counter has reached <code>m_triggerCount</code>
+ */
+ inline bool isCountTriggered() {
+ bool rc = ++m_count % m_triggerCount == 0;
+ return rc;
+ }
+ /** Tests whether a given waiting time has been gone since the last trace.
+ * @return <code>true</code>: the last trace has been done after
+ * at least <code>m_interval</code> seconds
+ */
+ inline bool isTimeTriggered() {
+ time_t now = time(NULL);
+ bool rc = now - m_lastTrace > m_interval;
+ if (rc) {
+ m_lastTrace = now;
+ }
+ return rc;
+ }
+ virtual bool trace(const char* message);
protected:
- int m_count;
- int m_triggerCount;
- time_t m_lastTrace;
- int m_interval;
- time_t m_startTime;
+ int m_count;
+ int m_triggerCount;
+ time_t m_lastTrace;
+ int m_interval;
+ time_t m_startTime;
};
class ReDirTreeStatistic {
public:
- ReDirTreeStatistic();
+ ReDirTreeStatistic();
public:
- const char* statisticAsString(ReByteBuffer& buffer, bool append = false,
- const char* formatFiles = "%8d ", const char* formatSizes = "%12.6f",
- const char* formatDirs = "%7d ");
- /**
- * Resets the counters.
- */
- inline void clear(){
- m_files = m_directories = 0;
- m_sizes = 0ll;
- }
+ const char* statisticAsString(ReByteBuffer& buffer, bool append = false,
+ const char* formatFiles = "%8d ", const char* formatSizes = "%12.6f",
+ const char* formatDirs = "%7d ");
+ /**
+ * Resets the counters.
+ */
+ inline void clear() {
+ m_files = m_directories = 0;
+ m_sizes = 0ll;
+ }
public:
- int m_directories;
- int m_files;
- int64_t m_sizes;
+ int m_directories;
+ int m_files;
+ int64_t m_sizes;
};
#define MAX_ENTRY_STACK_DEPTH 256
class ReTraverser: public ReDirTreeStatistic {
public:
- ReTraverser(const char* base, ReTraceUnit* tracer = NULL, ReLogger* logger =
- NULL);
- virtual ~ReTraverser();
+ ReTraverser(const char* base, ReTraceUnit* tracer = NULL, ReLogger* logger =
+ NULL);
+ virtual ~ReTraverser();
public:
- void changeBase(const char* base);
- /**
- * Return the number of entered directories .
- * @return the number of directories entered until now
- */
- inline int directories() const{
- return m_directories;
- }
- /**
- * Return the number of found files.
- * @return the number of files found until now
- */
- inline int files() const{
- return m_files;
- }
- /** Returns whether the current directory has changed since the last call.
- * @param state IN/OUT: stored info about the current directory.
- * The value has no interest for the caller
- * @return <code>true</code>: the path has been changed
- */
- inline bool hasChangedPath(int& state){
- bool rc = m_directories > state;
- state = m_directories;
- return rc;
- }
- ReDirStatus_t* rawNextFile(int& level);
- ReDirStatus_t* nextFile(int& level, ReDirEntryFilter* filter = NULL);
- /** Sets the tree traversal algorithm.
- * @param depthFirst <code>true</code>: files of the subdirectories will
- * be returned earlier
- */
- void setDepthFirst(bool depthFirst){
- m_passNoForDirSearch = depthFirst ? 1 : 2;
- }
- /** Sets directory filter (pattern list).
- * @param pattern pattern list for the subdirs to be entered
- */
- inline void setDirPattern(RePatternList* pattern){
- m_dirPatterns = pattern;
- if (pattern != NULL)
- m_dirPatterns->setIgnoreCase(true);
- }
- /** Sets the maximal depth.
- * @param value the value to set
- */
- inline void setMaxLevel(int value){
- m_maxLevel = value;
- }
- /** Sets the minimal depth.
- * @param value the value to set
- */
- inline void setMinLevel(int value){
- m_minLevel = value;
- }
- void setPropertiesFromFilter(ReDirEntryFilter* filter);
- /**
- * Return the sum of file lengths of the found files.
- * @return the sum of file lengths of the files found until now
- */
- inline int64_t sizes() const{
- return m_sizes;
- }
- ReDirStatus_t* topOfStack(int offset = 0);
+ void changeBase(const char* base);
+ /**
+ * Return the number of entered directories .
+ * @return the number of directories entered until now
+ */
+ inline int directories() const {
+ return m_directories;
+ }
+ /**
+ * Return the number of found files.
+ * @return the number of files found until now
+ */
+ inline int files() const {
+ return m_files;
+ }
+ /** Returns whether the current directory has changed since the last call.
+ * @param state IN/OUT: stored info about the current directory.
+ * The value has no interest for the caller
+ * @return <code>true</code>: the path has been changed
+ */
+ inline bool hasChangedPath(int& state) {
+ bool rc = m_directories > state;
+ state = m_directories;
+ return rc;
+ }
+ ReDirStatus_t* rawNextFile(int& level);
+ ReDirStatus_t* nextFile(int& level, ReDirEntryFilter* filter = NULL);
+ /** Sets the tree traversal algorithm.
+ * @param depthFirst <code>true</code>: files of the subdirectories will
+ * be returned earlier
+ */
+ void setDepthFirst(bool depthFirst) {
+ m_passNoForDirSearch = depthFirst ? 1 : 2;
+ }
+ /** Sets directory filter (pattern list).
+ * @param pattern pattern list for the subdirs to be entered
+ */
+ inline void setDirPattern(RePatternList* pattern) {
+ m_dirPatterns = pattern;
+ if (pattern != NULL)
+ m_dirPatterns->setIgnoreCase(true);
+ }
+ /** Sets the maximal depth.
+ * @param value the value to set
+ */
+ inline void setMaxLevel(int value) {
+ m_maxLevel = value;
+ }
+ /** Sets the minimal depth.
+ * @param value the value to set
+ */
+ inline void setMinLevel(int value) {
+ m_minLevel = value;
+ }
+ void setPropertiesFromFilter(ReDirEntryFilter* filter);
+ /**
+ * Return the sum of file lengths of the found files.
+ * @return the sum of file lengths of the files found until now
+ */
+ inline int64_t sizes() const {
+ return m_sizes;
+ }
+ ReDirStatus_t* topOfStack(int offset = 0);
protected:
- void destroy();
- void freeEntry(int level);
- bool initEntry(const ReByteBuffer& parent, const char* node, int level);
- /**
- * Tests whether a directory should be processed.
- * @param node the base name of the subdir
- * @return <code>true</code>: the subdir will be processed<br>
- * <code>false</code>: do not enter this subdir
- */
- inline bool isAllowedDir(const char* node){
- bool rc = m_dirPatterns->match(node);
- return rc;
- }
+ void destroy();
+ void freeEntry(int level);
+ bool initEntry(const ReByteBuffer& parent, const char* node, int level);
+ /**
+ * Tests whether a directory should be processed.
+ * @param node the base name of the subdir
+ * @return <code>true</code>: the subdir will be processed<br>
+ * <code>false</code>: do not enter this subdir
+ */
+ inline bool isAllowedDir(const char* node) {
+ bool rc = m_dirPatterns->match(node);
+ return rc;
+ }
protected:
- int m_minLevel;
- int m_maxLevel;
- int m_level;
- ReByteBuffer m_base;
- ReDirStatus_t* m_dirs[MAX_ENTRY_STACK_DEPTH];
- /// each directory will be passed twice: for all files + for directories only
- /// 1: depth first 2: breadth first
- int m_passNoForDirSearch;
- /// a subdirectory will be entered only if this pattern list matches
- /// if NULL any directory will be entered
- RePatternList* m_dirPatterns;
- ReDirTreeStatistic m_statistic;
- ReTraceUnit* m_tracer;
- ReLogger* m_logger;
+ int m_minLevel;
+ int m_maxLevel;
+ int m_level;
+ ReByteBuffer m_base;
+ ReDirStatus_t* m_dirs[MAX_ENTRY_STACK_DEPTH];
+ /// each directory will be passed twice: for all files + for directories only
+ /// 1: depth first 2: breadth first
+ int m_passNoForDirSearch;
+ /// a subdirectory will be entered only if this pattern list matches
+ /// if NULL any directory will be entered
+ RePatternList* m_dirPatterns;
+ ReDirTreeStatistic m_statistic;
+ ReTraceUnit* m_tracer;
+ ReLogger* m_logger;
};
#endif /* OS_RETRAVERSER_HPP_ */
* @param time2 second operand
* @return <code>true</code>: time1 > time2
*/
-inline bool operator >(const ReFileTime_t& time1, const ReFileTime_t& time2){
+inline bool operator >(const ReFileTime_t& time1, const ReFileTime_t& time2) {
#if defined __linux__
- return time1.tv_sec > time2.tv_sec
- || (time1.tv_sec == time2.tv_sec && time1.tv_nsec > time2.tv_nsec);
+ return time1.tv_sec > time2.tv_sec
+ || (time1.tv_sec == time2.tv_sec && time1.tv_nsec > time2.tv_nsec);
#else
- return time1.dwHighDateTime > time2.dwHighDateTime
- || (time1.dwHighDateTime == time2.dwHighDateTime
- && time1.dwLowDateTime > time2.dwLowDateTime);
+ return time1.dwHighDateTime > time2.dwHighDateTime
+ || (time1.dwHighDateTime == time2.dwHighDateTime
+ && time1.dwLowDateTime > time2.dwLowDateTime);
#endif
}
#include "os/ReTraverser.hpp"
* The latest sources: https://github.com/republib
*/
-int main(int argc, char** argv){
- void allTests();
- allTests();
+int main(int argc, char** argv) {
+ void allTests();
+ allTests();
}