diff --git a/src/lib/ebus/data.cpp b/src/lib/ebus/data.cpp index adfad6fb..569c9353 100644 --- a/src/lib/ebus/data.cpp +++ b/src/lib/ebus/data.cpp @@ -110,7 +110,7 @@ void printErrorPos(vector::iterator begin, const vector::iterato { if (pos > begin) pos--; - cout << "Error reading \"" << filename << "\" line " << static_cast(pos.base()-begin.base()) << " value \"" << *pos << "\": " << getResultCode(result) << endl; + cout << "Error reading \"" << filename << "\" line " << static_cast(lineNo) << " field " << static_cast(1+pos.base()-begin.base()) << " value \"" << *pos << "\": " << getResultCode(result) << endl; cout << "Erroneous item is here:" << endl; bool first = true; int cnt = 0; @@ -1218,11 +1218,10 @@ result_t DataFieldTemplates::add(DataField* field, bool replace) return RESULT_OK; } -result_t DataFieldTemplates::addFromFile(vector& row, void* arg, vector< vector >* defaults, const string& filename, unsigned int lineNo) +result_t DataFieldTemplates::addFromFile(vector::iterator& begin, const vector::iterator end, void* arg, vector< vector >* defaults, const string& filename, unsigned int lineNo) { DataField* field = NULL; - vector::iterator it = row.begin(); - result_t result = DataField::create(it, row.end(), this, field); + result_t result = DataField::create(begin, end, this, field); if (result != RESULT_OK) return result; @@ -1241,4 +1240,3 @@ DataField* DataFieldTemplates::get(const string name) return ref->second; } - diff --git a/src/lib/ebus/data.h b/src/lib/ebus/data.h index 5fbfa1d0..17f4bc26 100644 --- a/src/lib/ebus/data.h +++ b/src/lib/ebus/data.h @@ -678,7 +678,7 @@ public: result_t add(DataField* field, bool replace=false); // @copydoc - virtual result_t addFromFile(vector& row, void* arg, vector< vector >* defaults, const string& filename, unsigned int lineNo); + virtual result_t addFromFile(vector::iterator& begin, const vector::iterator end, void* arg, vector< vector >* defaults, const string& filename, unsigned int lineNo); /** * @brief Gets the template @a DataField instance with the specified name. diff --git a/src/lib/ebus/filereader.h b/src/lib/ebus/filereader.h index 972e9e62..ddc496e4 100644 --- a/src/lib/ebus/filereader.h +++ b/src/lib/ebus/filereader.h @@ -39,6 +39,8 @@ using namespace std; /** @brief the separator character used to quote text having the @a FIELD_SEPARATOR in it. */ #define TEXT_SEPARATOR '"' +extern void printErrorPos(vector::iterator begin, const vector::iterator end, vector::iterator pos, string filename, size_t lineNo, result_t result); + /** * @brief An abstract class that support reading definitions from a file. @@ -63,9 +65,10 @@ public: * @brief Read the definitions from a file. * @param filename the name of the file being read. * @param arg an argument to pass to @a addFromFile(). + * @param verbose whether to verbosely log problems. * @return @a RESULT_OK on success, or an error code. */ - virtual result_t readFromFile(const string filename, T arg=NULL) + virtual result_t readFromFile(const string filename, T arg=NULL, bool verbose=false) { ifstream ifs; ifs.open(filename.c_str(), ifstream::in); @@ -125,21 +128,25 @@ public: row.push_back(field.str()); result_t result; + vector::iterator it = row.begin(); + const vector::iterator end = row.end(); if (m_supportsDefaults == true) { if (line[0] == '*') { row[0] = row[0].substr(1); defaults.push_back(row); continue; } - result = addFromFile(row, arg, &defaults, filename, lineNo); + result = addFromFile(it, end, arg, &defaults, filename, lineNo); } else - result = addFromFile(row, arg, NULL, filename, lineNo); + result = addFromFile(it, end, arg, NULL, filename, lineNo); if (result != RESULT_OK) { - cerr << "error reading \"" << filename << "\" line " << static_cast(lineNo) << ": " << getResultCode(result) << endl; - ifs.close(); - return result; + if (verbose == false) { + ifs.close(); + return result; + } + printErrorPos(row.begin(), end, it, filename, lineNo, result); } } @@ -149,14 +156,15 @@ public: /** * @brief Add a definition that was read from a file. - * @param row the definition row read from the file. + * @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 arg the argument passed to @a readFromFile(). * @param defaults all previously read default rows (initial star char removed), or NULL if not supported. * @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& row, T arg, vector< vector >* defaults, const string& filename, unsigned int lineNo) = 0; + virtual result_t addFromFile(vector::iterator& begin, const vector::iterator end, T arg, vector< vector >* defaults, const string& filename, unsigned int lineNo) = 0; private: diff --git a/src/lib/ebus/message.cpp b/src/lib/ebus/message.cpp index 380c77fb..52bb00fe 100644 --- a/src/lib/ebus/message.cpp +++ b/src/lib/ebus/message.cpp @@ -376,10 +376,11 @@ result_t MessageMap::add(Message* message) return RESULT_OK; } -result_t MessageMap::addFromFile(vector& row, DataFieldTemplates* arg, vector< vector >* defaults, const string& filename, unsigned int lineNo) +result_t MessageMap::addFromFile(vector::iterator& begin, const vector::iterator end, DataFieldTemplates* arg, vector< vector >* defaults, const string& filename, unsigned int lineNo) { Message* message = NULL; - string types = row[0]; + vector::iterator restart = begin; + string types = *restart; if (types.length() == 0) types.append("r"); result_t result = RESULT_ERR_EOF; @@ -387,17 +388,17 @@ result_t MessageMap::addFromFile(vector& row, DataFieldTemplates* arg, v istringstream stream(types); string type; while (getline(stream, type, VALUE_SEPARATOR) != 0) { - row[0] = type; - vector::iterator it = row.begin(); - result = Message::create(it, row.end(), defaults, arg, message); - if (result != RESULT_OK) { - printErrorPos(row.begin(), row.end(), it, filename, lineNo, result); - continue; - } + *restart = type; + begin = restart; + result = Message::create(begin, end, defaults, arg, message); + if (result != RESULT_OK) + return result; result = add(message); if (result != RESULT_OK) { delete message; + return result; } + begin = restart; } return result; } diff --git a/src/lib/ebus/message.h b/src/lib/ebus/message.h index 56a97375..9fec78ef 100644 --- a/src/lib/ebus/message.h +++ b/src/lib/ebus/message.h @@ -308,7 +308,7 @@ public: result_t add(Message* message); // @copydoc - virtual result_t addFromFile(vector& row, DataFieldTemplates* arg, vector< vector >* defaults, const string& filename, unsigned int lineNo); + virtual result_t addFromFile(vector::iterator& begin, const vector::iterator end, DataFieldTemplates* arg, vector< vector >* defaults, const string& filename, unsigned int lineNo); /** * @brief Find the @a Message instance for the specified class and name.