diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 87eeaceb2..366a26e1a 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -71,30 +71,11 @@ static unsigned char readChar(std::istream &istr) return ch; } -// Splits a string that contains the specified separator into substrings -static std::list split(const std::string &s, char separator) -{ - std::list parts; - - std::string::size_type prevPos = 0; - for (std::string::size_type pos = 0; pos < s.length(); ++pos) { - if (s[pos] == separator) { - if (pos > prevPos) - parts.push_back(s.substr(prevPos, pos - prevPos)); - prevPos = pos + 1; - } - } - if (prevPos < s.length()) - parts.push_back(s.substr(prevPos)); - - return parts; -} - // Concatenates a list of strings, inserting a separator between parts -static std::string join(const std::list &list, char separator) +static std::string join(const std::set& list, char separator) { std::string s; - for (std::list::const_iterator it = list.begin(); it != list.end(); ++it) { + for (std::set::const_iterator it = list.begin(); it != list.end(); ++it) { if (!s.empty()) s += separator; @@ -103,6 +84,25 @@ static std::string join(const std::list &list, char separator) return s; } +// Removes duplicate string portions separated by the specified separator +static std::string unify(const std::string &s, char separator) +{ + std::set parts; + + std::string::size_type prevPos = 0; + for (std::string::size_type pos = 0; pos < s.length(); ++pos) { + if (s[pos] == separator) { + if (pos > prevPos) + parts.insert(s.substr(prevPos, pos - prevPos)); + prevPos = pos + 1; + } + } + if (prevPos < s.length()) + parts.insert(s.substr(prevPos)); + + return join(parts, separator); +} + /** Just read the code into a string. Perform simple cleanup of the code */ std::string Preprocessor::read(std::istream &istr, const std::string &filename, Settings *settings) { @@ -549,12 +549,8 @@ std::string Preprocessor::removeIf0(const std::string &code) std::istringstream istr(code); std::string line; while (std::getline(istr,line)) { - if (line != "#if 0") - ret << line << "\n"; - else { - // replace '#if 0' with empty line - ret << line << "\n"; - + ret << line << "\n"; + if (line == "#if 0") { // goto the end of the '#if 0' block unsigned int level = 1; bool in = false; @@ -1136,23 +1132,22 @@ std::list Preprocessor::getcfgs(const std::string &filedata, const const Token *tok = tokenizer.tokens(); - std::list varList; + std::set varList; while (tok) { if (Token::Match(tok, "defined ( %var% )")) { - varList.push_back(tok->strAt(2)); + varList.insert(tok->strAt(2)); tok = tok->tokAt(4); if (tok && tok->str() == "&&") { tok = tok->next(); } } else if (Token::Match(tok, "%var% ;")) { - varList.push_back(tok->str()); + varList.insert(tok->str()); tok = tok->tokAt(2); } else { break; } } - varList.sort(); s = join(varList, ';'); if (!s.empty()) @@ -1161,15 +1156,8 @@ std::list Preprocessor::getcfgs(const std::string &filedata, const } // Convert configurations into a canonical form: B;C;A or C;A;B => A;B;C - for (std::list::iterator it = ret.begin(); it != ret.end(); ++it) { - // Split the configuration into a list of defines - std::list defs = split(*it, ';'); - - // Re-constitute the configuration after sorting the defines - defs.sort(); - defs.unique(); - *it = join(defs, ';'); - } + for (std::list::iterator it = ret.begin(); it != ret.end(); ++it) + *it = unify(*it, ';'); // Remove duplicates from the ret list.. ret.sort();