From 6e6e05c10e3322d247013b7f54f303a00ba04cd1 Mon Sep 17 00:00:00 2001 From: john30 Date: Sun, 13 Mar 2016 16:04:20 +0100 Subject: [PATCH] pass default destination address, circuit and suffix to load instruction, fix for instruction cleanup --- src/lib/ebus/data.cpp | 2 +- src/lib/ebus/data.h | 2 +- src/lib/ebus/filereader.h | 34 ++++++++++++++++++---------------- src/lib/ebus/message.cpp | 34 +++++++++++++++++++++------------- src/lib/ebus/message.h | 24 ++++++++++++++++++++---- 5 files changed, 61 insertions(+), 35 deletions(-) diff --git a/src/lib/ebus/data.cpp b/src/lib/ebus/data.cpp index aa5f390c..21fad3fb 100644 --- a/src/lib/ebus/data.cpp +++ b/src/lib/ebus/data.cpp @@ -1689,7 +1689,7 @@ result_t DataFieldTemplates::add(DataField* field, string name, bool replace) } result_t DataFieldTemplates::addFromFile(vector::iterator& begin, const vector::iterator end, - vector< vector >* defaults, + vector< vector >* defaults, const string& defaultDest, const string& defaultCircuit, const string& defaultSuffix, const string& filename, unsigned int lineNo) { vector::iterator restart = begin; diff --git a/src/lib/ebus/data.h b/src/lib/ebus/data.h index 00579e76..09cbcfb0 100644 --- a/src/lib/ebus/data.h +++ b/src/lib/ebus/data.h @@ -884,7 +884,7 @@ public: // @copydoc virtual result_t addFromFile(vector::iterator& begin, const vector::iterator end, - vector< vector >* defaults, + vector< vector >* defaults, const string& defaultDest, const string& defaultCircuit, const string& defaultSuffix, const string& filename, unsigned int lineNo); /** diff --git a/src/lib/ebus/filereader.h b/src/lib/ebus/filereader.h index 93f3bc1d..93edec9e 100644 --- a/src/lib/ebus/filereader.h +++ b/src/lib/ebus/filereader.h @@ -78,9 +78,13 @@ public: * Read the definitions from a file. * @param filename the name of the file being read. * @param verbose whether to verbosely log problems. + * @param defaultDest the default destination address (may be overwritten by file name), or empty. + * @param defaultCircuit the default circuit name (may be overwritten by file name), or empty. + * @param defaultSuffix the default circuit name suffix (starting with a ".", may be overwritten by file name, or empty. * @return @a RESULT_OK on success, or an error code. */ - virtual result_t readFromFile(const string filename, bool verbose=false) + virtual result_t readFromFile(const string filename, bool verbose=false, + string defaultDest = "", string defaultCircuit = "", string defaultSuffix = "") { ifstream ifs; ifs.open(filename.c_str(), ifstream::in); @@ -90,22 +94,17 @@ public: } size_t lastSep = filename.find_last_of('/'); size_t firstDot = filename.find_first_of('.', lastSep+1); - string defaultDest = ""; - string defaultCircuit = ""; - string defaultSuffix = ""; if (lastSep!=string::npos && firstDot==lastSep+1+2) { // potential destination address, matches "^ZZ." result_t result; - defaultDest = filename.substr(lastSep+1, 2); - unsigned char zz = (unsigned char)parseInt(defaultDest.c_str(), 16, 0, 0xff, result, NULL); - if (result!=RESULT_OK || !isValidAddress(zz)) - defaultDest = ""; // invalid: not in hex or no master/slave/broadcast address - else { + string str = filename.substr(lastSep+1, 2); + unsigned char zz = (unsigned char)parseInt(str.c_str(), 16, 0, 0xff, result, NULL); + if (result==RESULT_OK && isValidAddress(zz)) { + defaultDest = str; size_t endDot = filename.find_first_of('.', firstDot+1); if (endDot>firstDot && endDot-firstDot<=6) { // potential ident, matches "^ZZ.IDENT." - defaultCircuit = filename.substr(firstDot+1, endDot-firstDot-1); // IDENT - if (defaultCircuit.find_first_of(' ')!=string::npos) - defaultCircuit = ""; // invalid: contains spaces - else { + str = filename.substr(firstDot+1, endDot-firstDot-1); // IDENT + if (str.find_first_of(' ')==string::npos) { + defaultCircuit = str; size_t nextDot = filename.find_first_of('.', endDot+1); if (nextDot!=string::npos && nextDot>endDot+1) { // potential index suffix, matches "^ZZ.IDENT.[0-9]*." parseInt(filename.substr(endDot+1, nextDot-endDot-1).c_str(), 10, 1, 16, result, NULL); @@ -133,10 +132,10 @@ public: if (result == RESULT_OK) continue; } else - result = addFromFile(it, end, &defaults, filename, lineNo); + result = addFromFile(it, end, &defaults, defaultDest, defaultCircuit, defaultSuffix, filename, lineNo); } else - result = addFromFile(it, end, NULL, filename, lineNo); + result = addFromFile(it, end, NULL, defaultDest, defaultCircuit, defaultSuffix, filename, lineNo); if (result != RESULT_OK) { if (!verbose) { @@ -193,12 +192,15 @@ public: * @param begin an iterator to the first column of the definition row to read. * @param end the end iterator of the definition row to read. * @param defaults all previously read default rows (initial star char removed), or NULL if not supported. + * @param defaultDest the valid destination address extracted from the file name (from ZZ part), or empty. + * @param defaultCircuit the valid circuit name extracted from the file name (from IDENT part), or empty. + * @param defaultSuffix the valid circuit name suffix (starting with a ".") extracted from the file name (number after after IDENT part and "."), or empty. * @param filename the name of the file being read. * @param lineNo the current line number in the file being read. * @return @a RESULT_OK on success, or an error code. */ virtual result_t addFromFile(vector::iterator& begin, const vector::iterator end, - vector< vector >* defaults, + vector< vector >* defaults, const string& defaultDest, const string& defaultCircuit, const string& defaultSuffix, const string& filename, unsigned int lineNo) = 0; /** diff --git a/src/lib/ebus/message.cpp b/src/lib/ebus/message.cpp index ea8019f0..b0f7172e 100644 --- a/src/lib/ebus/message.cpp +++ b/src/lib/ebus/message.cpp @@ -1259,7 +1259,8 @@ bool CombinedCondition::isTrue() } -result_t Instruction::create(const string contextPath, Condition* condition, const string type, vector::iterator& it, const vector::iterator end, Instruction*& returnValue) +result_t Instruction::create(const string contextPath, const string& defaultDest, const string& defaultCircuit, const string& defaultSuffix, + Condition* condition, const string type, vector::iterator& it, const vector::iterator end, Instruction*& returnValue) { // type[,argument]* (type already skipped by caller) bool singleton = false; @@ -1274,7 +1275,7 @@ result_t Instruction::create(const string contextPath, Condition* condition, con } else { path = contextPath.substr(0, pos+1); } - returnValue = new LoadInstruction(condition, singleton, path+(*it)); + returnValue = new LoadInstruction(condition, singleton, path+(*it), defaultDest, defaultCircuit, defaultSuffix); return RESULT_OK; } // unknown instruction @@ -1283,7 +1284,7 @@ result_t Instruction::create(const string contextPath, Condition* condition, con result_t LoadInstruction::execute(MessageMap* messages) { - return messages->readFromFile(m_filename); + return messages->readFromFile(m_filename, false, m_defaultDest, m_defaultCircuit, m_defaultSuffix); } @@ -1452,7 +1453,7 @@ result_t MessageMap::readConditions(string& types, const string& filename, Condi } result_t MessageMap::addFromFile(vector::iterator& begin, const vector::iterator end, - vector< vector >* defaults, + vector< vector >* defaults, const string& defaultDest, const string& defaultCircuit, const string& defaultSuffix, const string& filename, unsigned int lineNo) { vector::iterator restart = begin; @@ -1465,7 +1466,7 @@ result_t MessageMap::addFromFile(vector::iterator& begin, const vector >::iterator it = m_instructions.begin(); it != m_instructions.end(); it++) { vector instructions = it->second; bool removeSingletons = false; + vector remain; for (vector::iterator lit = instructions.begin(); lit != instructions.end(); lit++) { Instruction* instruction = *lit; if (removeSingletons && instruction->isSingleton()) { + delete instruction; continue; } Condition* condition = instruction->getCondition(); @@ -1576,30 +1579,35 @@ result_t MessageMap::executeInstructions(bool verbose) { } } if (execute) { - if (instruction->isSingleton()) + if (instruction->isSingleton()) { removeSingletons = true; + } result_t result = instruction->execute(this); if (result!=RESULT_OK) { overallResult = result; } delete instruction; - instructions.erase(lit--); + } else { + remain.push_back(instruction); } } - if (removeSingletons) { + if (removeSingletons && !remain.empty()) { + instructions = remain; + remain.clear(); for (vector::iterator lit = instructions.begin(); lit != instructions.end(); lit++) { Instruction* instruction = *lit; if (!instruction->isSingleton()) { + remain.push_back(instruction); continue; } delete instruction; - instructions.erase(lit); - lit--; - } - if (instructions.empty()) { - m_instructions.erase(it--); } } + if (remain.empty()) { + m_instructions.erase(it--); + } else { + it->second = remain; + } } return overallResult; } diff --git a/src/lib/ebus/message.h b/src/lib/ebus/message.h index c3ae1c53..5339d39e 100644 --- a/src/lib/ebus/message.h +++ b/src/lib/ebus/message.h @@ -955,6 +955,9 @@ public: /** * Factory method for creating a new instance. * @param contextPath the path and/or filename context being loaded. + * @param defaultDest the default destination address (may be overwritten by file name), or empty. + * @param defaultCircuit the default circuit name (may be overwritten by file name), or empty. + * @param defaultSuffix the default circuit name suffix (starting with a ".", may be overwritten by file name, or empty. * @param condition the @a Condition for the instruction, or NULL. * @param type the type of the instruction. * @param it the iterator to traverse for the definition parts. @@ -962,7 +965,8 @@ public: * @param returnValue the variable in which to store the created instance. * @return @a RESULT_OK on success, or an error code. */ - static result_t create(const string contextPath, Condition* condition, const string type, vector::iterator& it, const vector::iterator end, Instruction*& returnValue); + static result_t create(const string contextPath, const string& defaultDest, const string& defaultCircuit, const string& defaultSuffix, + Condition* condition, const string type, vector::iterator& it, const vector::iterator end, Instruction*& returnValue); /** * Return the @a Condition this instruction requires. @@ -1006,9 +1010,12 @@ public: * @param condition the @a Condition this instruction requires, or null. * @param singleton whether this @a Instruction belongs to a set of instructions of which only the first one may be executed for the same source file. * @param filename the name of the file to load. + * @param defaultDest the default destination address (may be overwritten by file name), or empty. + * @param defaultCircuit the default circuit name (may be overwritten by file name), or empty. + * @param defaultSuffix the default circuit name suffix (starting with a ".", may be overwritten by file name, or empty. */ - LoadInstruction(Condition* condition, const bool singleton, const string filename) - : Instruction(condition, singleton), m_filename(filename) { } + LoadInstruction(Condition* condition, const bool singleton, const string filename, const string& defaultDest, const string& defaultCircuit, const string& defaultSuffix) + : Instruction(condition, singleton), m_filename(filename), m_defaultDest(defaultDest), m_defaultCircuit(defaultCircuit), m_defaultSuffix(defaultSuffix) { } /** * Destructor. @@ -1023,6 +1030,15 @@ private: /** the name of the file to load. */ const string m_filename; + /** the default destination address (may be overwritten by file name), or empty. */ + const string m_defaultDest; + + /** the default circuit name (may be overwritten by file name), or empty. */ + const string m_defaultCircuit; + + /** the default circuit name suffix (starting with a ".", may be overwritten by file name, or empty. */ + const string m_defaultSuffix; + }; @@ -1076,7 +1092,7 @@ public: // @copydoc virtual result_t addFromFile(vector::iterator& begin, const vector::iterator end, - vector< vector >* defaults, + vector< vector >* defaults, const string& defaultDest, const string& defaultCircuit, const string& defaultSuffix, const string& filename, unsigned int lineNo); /**