From adcf3e0d3360d5255213042641896c2d024a4913 Mon Sep 17 00:00:00 2001 From: john30 Date: Sun, 20 Mar 2016 12:25:47 +0100 Subject: [PATCH] log included/loaded files by instruction --- src/ebusd/main.cpp | 10 ++++++-- src/lib/ebus/message.cpp | 37 +++++++++++++++++++++++---- src/lib/ebus/message.h | 55 +++++++++++++++++++++++++--------------- 3 files changed, 74 insertions(+), 28 deletions(-) diff --git a/src/ebusd/main.cpp b/src/ebusd/main.cpp index 9868d841..179b6f9b 100644 --- a/src/ebusd/main.cpp +++ b/src/ebusd/main.cpp @@ -668,9 +668,12 @@ result_t loadConfigFiles(MessageMap* messages, bool verbose, bool denyRecursive) if (result != RESULT_OK) logError(lf_main, "error resolving conditions: %s, %s", getResultCode(result), messages->getLastError().c_str()); - result = messages->executeInstructions(verbose); + ostringstream log; + result = messages->executeInstructions(verbose, log); if (result != RESULT_OK) logError(lf_main, "error executing instructions: %s, %s", getResultCode(result), messages->getLastError().c_str()); + else if (log.tellp() > 0) + logNotice(lf_main, log.str().c_str()); logNotice(lf_main, "found messages: %d (%d conditional on %d conditions, %d poll, %d update)", messages->size(), messages->sizeConditional(), messages->sizeConditions(), messages->sizePoll(), messages->sizePassive()); @@ -841,9 +844,12 @@ result_t loadScanConfigFile(MessageMap* messages, unsigned char address, SymbolS if (result != RESULT_OK) logError(lf_main, "error resolving conditions: %s, %s", getResultCode(result), messages->getLastError().c_str()); - result = messages->executeInstructions(false); + ostringstream log; + result = messages->executeInstructions(false, log); if (result != RESULT_OK) logError(lf_main, "error executing instructions: %s, %s", getResultCode(result), messages->getLastError().c_str()); + else if (log.tellp() > 0) + logNotice(lf_main, log.str().c_str()); logNotice(lf_main, "found messages: %d (%d conditional on %d conditions, %d poll, %d update)", messages->size(), messages->sizeConditional(), messages->sizeConditions(), messages->sizePoll(), messages->sizePassive()); relativeFile = best.substr(strlen(opt.configPath)+1); diff --git a/src/lib/ebus/message.cpp b/src/lib/ebus/message.cpp index b0f7172e..d3bf9740 100644 --- a/src/lib/ebus/message.cpp +++ b/src/lib/ebus/message.cpp @@ -1275,16 +1275,43 @@ result_t Instruction::create(const string contextPath, const string& defaultDest } else { path = contextPath.substr(0, pos+1); } - returnValue = new LoadInstruction(condition, singleton, path+(*it), defaultDest, defaultCircuit, defaultSuffix); + returnValue = new LoadInstruction(condition, singleton, defaultDest, defaultCircuit, defaultSuffix, path+(*it)); return RESULT_OK; } // unknown instruction return RESULT_ERR_INVALID_ARG; } +string Instruction::getDestination() +{ + // ZZ.circuit[.suffix] + string ret; + if (!m_defaultDest.empty()) + ret = m_defaultDest; + if (!m_defaultCircuit.empty() || !m_defaultSuffix.empty()) { + if (!ret.empty()) + ret += "."; + if (m_defaultCircuit.empty()) + ret += "*"; + else + ret += m_defaultCircuit; + if (!m_defaultSuffix.empty()) + ret += "."+m_defaultSuffix; + } + return ret; +} -result_t LoadInstruction::execute(MessageMap* messages) { - return messages->readFromFile(m_filename, false, m_defaultDest, m_defaultCircuit, m_defaultSuffix); + +result_t LoadInstruction::execute(MessageMap* messages, ostringstream& log) { + result_t result = messages->readFromFile(m_filename, false, m_defaultDest, m_defaultCircuit, m_defaultSuffix); + if (result!=RESULT_OK) { + if (log.tellp()>0) + log << ", "; + log << "error " << (isSingleton() ? "loading " : "including ") << m_filename << " for \"" << getDestination() << "\": " << getResultCode(result); + return result; + } + log << (isSingleton() ? "loaded " : "included ") << m_filename << " for \"" << getDestination() << "\""; + return result; } @@ -1556,7 +1583,7 @@ result_t MessageMap::resolveCondition(Condition* condition) { return result; } -result_t MessageMap::executeInstructions(bool verbose) { +result_t MessageMap::executeInstructions(bool verbose, ostringstream& log) { result_t overallResult = RESULT_OK; for (map >::iterator it = m_instructions.begin(); it != m_instructions.end(); it++) { vector instructions = it->second; @@ -1582,7 +1609,7 @@ result_t MessageMap::executeInstructions(bool verbose) { if (instruction->isSingleton()) { removeSingletons = true; } - result_t result = instruction->execute(this); + result_t result = instruction->execute(this, log); if (result!=RESULT_OK) { overallResult = result; } diff --git a/src/lib/ebus/message.h b/src/lib/ebus/message.h index 5339d39e..75d51f42 100644 --- a/src/lib/ebus/message.h +++ b/src/lib/ebus/message.h @@ -943,9 +943,12 @@ public: * Construct a new instance. * @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 defaultDest the default destination address, or empty. + * @param defaultCircuit the default circuit name, or empty. + * @param defaultSuffix the default circuit name suffix (starting with a "."), or empty. */ - Instruction(Condition* condition, const bool singleton) - : m_condition(condition), m_singleton(singleton) { } + Instruction(Condition* condition, const bool singleton, const string& defaultDest, const string& defaultCircuit, const string& defaultSuffix) + : m_condition(condition), m_singleton(singleton), m_defaultDest(defaultDest), m_defaultCircuit(defaultCircuit), m_defaultSuffix(defaultSuffix) { } /** * Destructor. @@ -955,9 +958,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 defaultDest the default destination address, or empty. + * @param defaultCircuit the default circuit name, or empty. + * @param defaultSuffix the default circuit name suffix (starting with a "."), 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. @@ -980,12 +983,19 @@ public: */ bool isSingleton() { return m_singleton; } + /** + * Return a string describing the destination from the stored default values. + * @return a string describing the destination. + */ + string getDestination(); + /** * Execute the instruction. * @param messages the @a MessageMap. + * @param log the @a ostringstream to log success messages to (if necessary). * @return @a RESULT_OK on success, or an error code. */ - virtual result_t execute(MessageMap* messages) = 0; + virtual result_t execute(MessageMap* messages, ostringstream& log) = 0; private: @@ -995,6 +1005,17 @@ private: /** whether this @a Instruction belongs to a set of instructions of which only the first one may be executed for the same source file. */ bool m_singleton; +protected: + + /** the default destination address, or empty. */ + const string m_defaultDest; + + /** the default circuit name, or empty. */ + const string m_defaultCircuit; + + /** the default circuit name suffix (starting with a "."), or empty. */ + const string m_defaultSuffix; + }; @@ -1009,13 +1030,13 @@ public: * Construct a new instance. * @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. + * @param defaultSuffix the default circuit name suffix (starting with a ".", may be overwritten by file name), or empty. + * @param filename the name of the file to load. */ - 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) { } + LoadInstruction(Condition* condition, const bool singleton, const string& defaultDest, const string& defaultCircuit, const string& defaultSuffix, const string filename) + : Instruction(condition, singleton, defaultDest, defaultCircuit, defaultSuffix), m_filename(filename) { } /** * Destructor. @@ -1023,22 +1044,13 @@ public: virtual ~LoadInstruction() { } // @copydoc - virtual result_t execute(MessageMap* messages); + virtual result_t execute(MessageMap* messages, ostringstream& log); 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; - }; @@ -1119,9 +1131,10 @@ public: /** * Run all executable @a Instruction instances. * @param verbose whether to verbosely add all problems to the error message. + * @param log the @a ostringstream to log success messages to (if necessary). * @return @a RESULT_OK on success, or an error code. */ - result_t executeInstructions(bool verbose); + result_t executeInstructions(bool verbose, ostringstream& log); /** * Get the stored @a Message instances for the key.