Preprocessor: Use set instead of list to track '#pragma once' usage

This commit is contained in:
Daniel Marjamäki 2013-10-27 10:33:37 +01:00
parent 9faaef840b
commit ec3ab74631
3 changed files with 28 additions and 26 deletions

View File

@ -1026,7 +1026,7 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
std::map<std::string, std::string> defs(getcfgmap(_settings ? _settings->userDefines : std::string(""))); std::map<std::string, std::string> defs(getcfgmap(_settings ? _settings->userDefines : std::string("")));
if (_settings && _settings->_maxConfigs == 1U) { if (_settings && _settings->_maxConfigs == 1U) {
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
std::list<std::string> includes; std::list<std::string> includes;
processedFile = handleIncludes(processedFile, filename, includePaths, defs, pragmaOnce, includes); processedFile = handleIncludes(processedFile, filename, includePaths, defs, pragmaOnce, includes);
resultConfigurations = getcfgs(processedFile, filename, defs); resultConfigurations = getcfgs(processedFile, filename, defs);
@ -2011,7 +2011,7 @@ static bool openHeader(std::string &filename, const std::list<std::string> &incl
} }
std::string Preprocessor::handleIncludes(const std::string &code, const std::string &filePath, const std::list<std::string> &includePaths, std::map<std::string,std::string> &defs, std::list<std::string> &pragmaOnce, std::list<std::string> includes) std::string Preprocessor::handleIncludes(const std::string &code, const std::string &filePath, const std::list<std::string> &includePaths, std::map<std::string,std::string> &defs, std::set<std::string> &pragmaOnce, std::list<std::string> includes)
{ {
const std::string path(filePath.substr(0, 1 + filePath.find_last_of("\\/"))); const std::string path(filePath.substr(0, 1 + filePath.find_last_of("\\/")));
@ -2060,7 +2060,7 @@ std::string Preprocessor::handleIncludes(const std::string &code, const std::str
std::stack<bool>::reference elseIsTrue = elseIsTrueStack.top(); std::stack<bool>::reference elseIsTrue = elseIsTrueStack.top();
if (line == "#pragma once") { if (line == "#pragma once") {
pragmaOnce.push_back(filePath); pragmaOnce.insert(filePath);
} else if (line.compare(0,7,"#ifdef ") == 0) { } else if (line.compare(0,7,"#ifdef ") == 0) {
if (indent == indentmatch) { if (indent == indentmatch) {
const std::string tag = getdef(line,true); const std::string tag = getdef(line,true);
@ -2202,7 +2202,7 @@ std::string Preprocessor::handleIncludes(const std::string &code, const std::str
includes.push_back(filename); includes.push_back(filename);
// Don't include header if it's already included and contains #pragma once // Don't include header if it's already included and contains #pragma once
if (std::find(pragmaOnce.begin(), pragmaOnce.end(), filename) != pragmaOnce.end()) { if (pragmaOnce.find(filename) != pragmaOnce.end()) {
ostr << std::endl; ostr << std::endl;
continue; continue;
} }

View File

@ -25,6 +25,7 @@
#include <istream> #include <istream>
#include <string> #include <string>
#include <list> #include <list>
#include <set>
#include "config.h" #include "config.h"
class ErrorLogger; class ErrorLogger;
@ -240,7 +241,7 @@ public:
* @param includes provide a empty list. this is just used to prevent recursive inclusions. * @param includes provide a empty list. this is just used to prevent recursive inclusions.
* \return resulting string * \return resulting string
*/ */
std::string handleIncludes(const std::string &code, const std::string &filePath, const std::list<std::string> &includePaths, std::map<std::string,std::string> &defs, std::list<std::string> &pragmaOnce, std::list<std::string> includes); std::string handleIncludes(const std::string &code, const std::string &filePath, const std::list<std::string> &includePaths, std::map<std::string,std::string> &defs, std::set<std::string> &pragmaOnce, std::list<std::string> includes);
void setFile0(const std::string &f) { void setFile0(const std::string &f) {
file0 = f; file0 = f;

View File

@ -30,6 +30,7 @@
#include <map> #include <map>
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <set>
extern std::ostringstream errout; extern std::ostringstream errout;
extern std::ostringstream output; extern std::ostringstream output;
@ -2443,7 +2444,7 @@ private:
Preprocessor preprocessor(NULL, this); Preprocessor preprocessor(NULL, this);
const std::list<std::string> includePaths; const std::list<std::string> includePaths;
std::map<std::string,std::string> defs; std::map<std::string,std::string> defs;
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
preprocessor.handleIncludes(code, "123.h", includePaths, defs, pragmaOnce, std::list<std::string>()); preprocessor.handleIncludes(code, "123.h", includePaths, defs, pragmaOnce, std::list<std::string>());
ASSERT_EQUALS(1U, pragmaOnce.size()); ASSERT_EQUALS(1U, pragmaOnce.size());
ASSERT_EQUALS("123.h", *(pragmaOnce.begin())); ASSERT_EQUALS("123.h", *(pragmaOnce.begin()));
@ -3317,12 +3318,12 @@ private:
defs.clear(); defs.clear();
defs["A"] = ""; defs["A"] = "";
{ {
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
const std::string code("#ifdef A\n123\n#endif\n"); const std::string code("#ifdef A\n123\n#endif\n");
const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>())); const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>()));
ASSERT_EQUALS("\n123\n\n", actual); ASSERT_EQUALS("\n123\n\n", actual);
}{ }{
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
const std::string code("#ifdef B\n123\n#endif\n"); const std::string code("#ifdef B\n123\n#endif\n");
const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>())); const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>()));
ASSERT_EQUALS("\n\n\n", actual); ASSERT_EQUALS("\n\n\n", actual);
@ -3334,12 +3335,12 @@ private:
defs.clear(); defs.clear();
defs["A"] = ""; defs["A"] = "";
{ {
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
const std::string code("#ifndef A\n123\n#endif\n"); const std::string code("#ifndef A\n123\n#endif\n");
const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>())); const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>()));
ASSERT_EQUALS("\n\n\n", actual); ASSERT_EQUALS("\n\n\n", actual);
}{ }{
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
const std::string code("#ifndef B\n123\n#endif\n"); const std::string code("#ifndef B\n123\n#endif\n");
const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>())); const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>()));
ASSERT_EQUALS("\n123\n\n", actual); ASSERT_EQUALS("\n123\n\n", actual);
@ -3348,7 +3349,7 @@ private:
// define - ifndef // define - ifndef
{ {
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
defs.clear(); defs.clear();
const std::string code("#ifndef X\n#define X\n123\n#endif\n" const std::string code("#ifndef X\n#define X\n123\n#endif\n"
"#ifndef X\n#define X\n123\n#endif\n"); "#ifndef X\n#define X\n123\n#endif\n");
@ -3358,7 +3359,7 @@ private:
// #define => #if // #define => #if
{ {
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
defs.clear(); defs.clear();
const std::string code("#define X 123\n" const std::string code("#define X 123\n"
"#if X==123\n" "#if X==123\n"
@ -3380,7 +3381,7 @@ private:
"4\n" "4\n"
"#endif"); "#endif");
{ {
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
defs.clear(); defs.clear();
defs["A"] = ""; defs["A"] = "";
defs["C"] = ""; defs["C"] = "";
@ -3389,7 +3390,7 @@ private:
} }
{ {
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
defs.clear(); defs.clear();
defs["B"] = ""; defs["B"] = "";
const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>())); const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>()));
@ -3397,7 +3398,7 @@ private:
} }
{ {
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
defs.clear(); defs.clear();
const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>())); const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>()));
ASSERT_EQUALS("\n\n\n\n\n\n\n4\n\n", actual); ASSERT_EQUALS("\n\n\n\n\n\n\n4\n\n", actual);
@ -3408,7 +3409,7 @@ private:
{ {
// see also endifsemicolon // see also endifsemicolon
const std::string code("{\n#ifdef X\n#endif;\n}"); const std::string code("{\n#ifdef X\n#endif;\n}");
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
defs.clear(); defs.clear();
defs["Z"] = ""; defs["Z"] = "";
const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>())); const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>()));
@ -3422,7 +3423,7 @@ private:
"123\n" "123\n"
"#endif\n"); "#endif\n");
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
pragmaOnce.clear(); pragmaOnce.clear();
defs.clear(); defs.clear();
@ -3438,7 +3439,7 @@ private:
// #error // #error
{ {
errout.str(""); errout.str("");
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
defs.clear(); defs.clear();
const std::string code("#ifndef X\n#error abc\n#endif"); const std::string code("#ifndef X\n#error abc\n#endif");
const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>())); const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>()));
@ -3457,7 +3458,7 @@ private:
// missing local include // missing local include
{ {
const std::string code("#include \"missing-include!!.h\"\n"); const std::string code("#include \"missing-include!!.h\"\n");
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
pragmaOnce.clear(); pragmaOnce.clear();
errout.str(""); errout.str("");
@ -3481,7 +3482,7 @@ private:
// missing system header // missing system header
{ {
const std::string code("#include <missing-include!!.h>\n"); const std::string code("#include <missing-include!!.h>\n");
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
pragmaOnce.clear(); pragmaOnce.clear();
errout.str(""); errout.str("");
@ -3511,7 +3512,7 @@ private:
defs.clear(); defs.clear();
defs["GNU"] = ""; defs["GNU"] = "";
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
errout.str(""); errout.str("");
settings = Settings(); settings = Settings();
preprocessor.handleIncludes(code,"test.c",includePaths,defs,pragmaOnce,std::list<std::string>()); preprocessor.handleIncludes(code,"test.c",includePaths,defs,pragmaOnce,std::list<std::string>());
@ -3527,7 +3528,7 @@ private:
// #3405 // #3405
{ {
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
defs.clear(); defs.clear();
defs["A"] = ""; defs["A"] = "";
const std::string code("\n#ifndef PAL_UTIL_UTILS_H_\n" const std::string code("\n#ifndef PAL_UTIL_UTILS_H_\n"
@ -3563,7 +3564,7 @@ private:
// #3418 // #3418
{ {
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
defs.clear(); defs.clear();
const char code[] = "#define A 1\n" const char code[] = "#define A 1\n"
"#define B A\n" "#define B A\n"
@ -3595,7 +3596,7 @@ private:
const std::list<std::string> includePaths; const std::list<std::string> includePaths;
std::map<std::string,std::string> defs; std::map<std::string,std::string> defs;
defs["A"] = "1"; defs["A"] = "1";
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
ASSERT_EQUALS(std::string::npos, // No "123" in the output ASSERT_EQUALS(std::string::npos, // No "123" in the output
preprocessor.handleIncludes(code, "test.c", includePaths, defs, pragmaOnce,std::list<std::string>()).find("123")); preprocessor.handleIncludes(code, "test.c", includePaths, defs, pragmaOnce,std::list<std::string>()).find("123"));
} }
@ -3616,7 +3617,7 @@ private:
std::map<std::string,std::string> defs; std::map<std::string,std::string> defs;
defs["B"] = "1"; defs["B"] = "1";
defs["C"] = "1"; defs["C"] = "1";
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
preprocessor.handleIncludes(code, "test.c", includePaths, defs, pragmaOnce, std::list<std::string>()); // don't crash preprocessor.handleIncludes(code, "test.c", includePaths, defs, pragmaOnce, std::list<std::string>()); // don't crash
} }
@ -3631,7 +3632,7 @@ private:
const std::string filePath("test.c"); const std::string filePath("test.c");
const std::list<std::string> includePaths; const std::list<std::string> includePaths;
std::map<std::string,std::string> defs; std::map<std::string,std::string> defs;
std::list<std::string> pragmaOnce; std::set<std::string> pragmaOnce;
Preprocessor preprocessor(NULL, this); Preprocessor preprocessor(NULL, this);
std::istringstream istr(code); std::istringstream istr(code);