Skip to content

Commit ec3ab74

Browse files
committed
Preprocessor: Use set instead of list to track '#pragma once' usage
1 parent 9faaef8 commit ec3ab74

3 files changed

Lines changed: 28 additions & 26 deletions

File tree

lib/preprocessor.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,7 +1026,7 @@ void Preprocessor::preprocess(std::istream &srcCodeStream, std::string &processe
10261026
std::map<std::string, std::string> defs(getcfgmap(_settings ? _settings->userDefines : std::string("")));
10271027

10281028
if (_settings && _settings->_maxConfigs == 1U) {
1029-
std::list<std::string> pragmaOnce;
1029+
std::set<std::string> pragmaOnce;
10301030
std::list<std::string> includes;
10311031
processedFile = handleIncludes(processedFile, filename, includePaths, defs, pragmaOnce, includes);
10321032
resultConfigurations = getcfgs(processedFile, filename, defs);
@@ -2011,7 +2011,7 @@ static bool openHeader(std::string &filename, const std::list<std::string> &incl
20112011
}
20122012

20132013

2014-
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)
2014+
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)
20152015
{
20162016
const std::string path(filePath.substr(0, 1 + filePath.find_last_of("\\/")));
20172017

@@ -2060,7 +2060,7 @@ std::string Preprocessor::handleIncludes(const std::string &code, const std::str
20602060
std::stack<bool>::reference elseIsTrue = elseIsTrueStack.top();
20612061

20622062
if (line == "#pragma once") {
2063-
pragmaOnce.push_back(filePath);
2063+
pragmaOnce.insert(filePath);
20642064
} else if (line.compare(0,7,"#ifdef ") == 0) {
20652065
if (indent == indentmatch) {
20662066
const std::string tag = getdef(line,true);
@@ -2202,7 +2202,7 @@ std::string Preprocessor::handleIncludes(const std::string &code, const std::str
22022202
includes.push_back(filename);
22032203

22042204
// Don't include header if it's already included and contains #pragma once
2205-
if (std::find(pragmaOnce.begin(), pragmaOnce.end(), filename) != pragmaOnce.end()) {
2205+
if (pragmaOnce.find(filename) != pragmaOnce.end()) {
22062206
ostr << std::endl;
22072207
continue;
22082208
}

lib/preprocessor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <istream>
2626
#include <string>
2727
#include <list>
28+
#include <set>
2829
#include "config.h"
2930

3031
class ErrorLogger;
@@ -240,7 +241,7 @@ class CPPCHECKLIB Preprocessor {
240241
* @param includes provide a empty list. this is just used to prevent recursive inclusions.
241242
* \return resulting string
242243
*/
243-
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);
244+
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);
244245

245246
void setFile0(const std::string &f) {
246247
file0 = f;

test/testpreprocessor.cpp

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <map>
3131
#include <string>
3232
#include <sstream>
33+
#include <set>
3334

3435
extern std::ostringstream errout;
3536
extern std::ostringstream output;
@@ -2443,7 +2444,7 @@ class TestPreprocessor : public TestFixture {
24432444
Preprocessor preprocessor(NULL, this);
24442445
const std::list<std::string> includePaths;
24452446
std::map<std::string,std::string> defs;
2446-
std::list<std::string> pragmaOnce;
2447+
std::set<std::string> pragmaOnce;
24472448
preprocessor.handleIncludes(code, "123.h", includePaths, defs, pragmaOnce, std::list<std::string>());
24482449
ASSERT_EQUALS(1U, pragmaOnce.size());
24492450
ASSERT_EQUALS("123.h", *(pragmaOnce.begin()));
@@ -3317,12 +3318,12 @@ class TestPreprocessor : public TestFixture {
33173318
defs.clear();
33183319
defs["A"] = "";
33193320
{
3320-
std::list<std::string> pragmaOnce;
3321+
std::set<std::string> pragmaOnce;
33213322
const std::string code("#ifdef A\n123\n#endif\n");
33223323
const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>()));
33233324
ASSERT_EQUALS("\n123\n\n", actual);
33243325
}{
3325-
std::list<std::string> pragmaOnce;
3326+
std::set<std::string> pragmaOnce;
33263327
const std::string code("#ifdef B\n123\n#endif\n");
33273328
const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>()));
33283329
ASSERT_EQUALS("\n\n\n", actual);
@@ -3334,12 +3335,12 @@ class TestPreprocessor : public TestFixture {
33343335
defs.clear();
33353336
defs["A"] = "";
33363337
{
3337-
std::list<std::string> pragmaOnce;
3338+
std::set<std::string> pragmaOnce;
33383339
const std::string code("#ifndef A\n123\n#endif\n");
33393340
const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>()));
33403341
ASSERT_EQUALS("\n\n\n", actual);
33413342
}{
3342-
std::list<std::string> pragmaOnce;
3343+
std::set<std::string> pragmaOnce;
33433344
const std::string code("#ifndef B\n123\n#endif\n");
33443345
const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>()));
33453346
ASSERT_EQUALS("\n123\n\n", actual);
@@ -3348,7 +3349,7 @@ class TestPreprocessor : public TestFixture {
33483349

33493350
// define - ifndef
33503351
{
3351-
std::list<std::string> pragmaOnce;
3352+
std::set<std::string> pragmaOnce;
33523353
defs.clear();
33533354
const std::string code("#ifndef X\n#define X\n123\n#endif\n"
33543355
"#ifndef X\n#define X\n123\n#endif\n");
@@ -3358,7 +3359,7 @@ class TestPreprocessor : public TestFixture {
33583359

33593360
// #define => #if
33603361
{
3361-
std::list<std::string> pragmaOnce;
3362+
std::set<std::string> pragmaOnce;
33623363
defs.clear();
33633364
const std::string code("#define X 123\n"
33643365
"#if X==123\n"
@@ -3380,7 +3381,7 @@ class TestPreprocessor : public TestFixture {
33803381
"4\n"
33813382
"#endif");
33823383
{
3383-
std::list<std::string> pragmaOnce;
3384+
std::set<std::string> pragmaOnce;
33843385
defs.clear();
33853386
defs["A"] = "";
33863387
defs["C"] = "";
@@ -3389,15 +3390,15 @@ class TestPreprocessor : public TestFixture {
33893390
}
33903391

33913392
{
3392-
std::list<std::string> pragmaOnce;
3393+
std::set<std::string> pragmaOnce;
33933394
defs.clear();
33943395
defs["B"] = "";
33953396
const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>()));
33963397
ASSERT_EQUALS("\n\n\n2\n\n\n\n\n\n", actual);
33973398
}
33983399

33993400
{
3400-
std::list<std::string> pragmaOnce;
3401+
std::set<std::string> pragmaOnce;
34013402
defs.clear();
34023403
const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>()));
34033404
ASSERT_EQUALS("\n\n\n\n\n\n\n4\n\n", actual);
@@ -3408,7 +3409,7 @@ class TestPreprocessor : public TestFixture {
34083409
{
34093410
// see also endifsemicolon
34103411
const std::string code("{\n#ifdef X\n#endif;\n}");
3411-
std::list<std::string> pragmaOnce;
3412+
std::set<std::string> pragmaOnce;
34123413
defs.clear();
34133414
defs["Z"] = "";
34143415
const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>()));
@@ -3422,7 +3423,7 @@ class TestPreprocessor : public TestFixture {
34223423
"123\n"
34233424
"#endif\n");
34243425

3425-
std::list<std::string> pragmaOnce;
3426+
std::set<std::string> pragmaOnce;
34263427

34273428
pragmaOnce.clear();
34283429
defs.clear();
@@ -3438,7 +3439,7 @@ class TestPreprocessor : public TestFixture {
34383439
// #error
34393440
{
34403441
errout.str("");
3441-
std::list<std::string> pragmaOnce;
3442+
std::set<std::string> pragmaOnce;
34423443
defs.clear();
34433444
const std::string code("#ifndef X\n#error abc\n#endif");
34443445
const std::string actual(preprocessor.handleIncludes(code,filePath,includePaths,defs,pragmaOnce,std::list<std::string>()));
@@ -3457,7 +3458,7 @@ class TestPreprocessor : public TestFixture {
34573458
// missing local include
34583459
{
34593460
const std::string code("#include \"missing-include!!.h\"\n");
3460-
std::list<std::string> pragmaOnce;
3461+
std::set<std::string> pragmaOnce;
34613462

34623463
pragmaOnce.clear();
34633464
errout.str("");
@@ -3481,7 +3482,7 @@ class TestPreprocessor : public TestFixture {
34813482
// missing system header
34823483
{
34833484
const std::string code("#include <missing-include!!.h>\n");
3484-
std::list<std::string> pragmaOnce;
3485+
std::set<std::string> pragmaOnce;
34853486

34863487
pragmaOnce.clear();
34873488
errout.str("");
@@ -3511,7 +3512,7 @@ class TestPreprocessor : public TestFixture {
35113512
defs.clear();
35123513
defs["GNU"] = "";
35133514

3514-
std::list<std::string> pragmaOnce;
3515+
std::set<std::string> pragmaOnce;
35153516
errout.str("");
35163517
settings = Settings();
35173518
preprocessor.handleIncludes(code,"test.c",includePaths,defs,pragmaOnce,std::list<std::string>());
@@ -3527,7 +3528,7 @@ class TestPreprocessor : public TestFixture {
35273528

35283529
// #3405
35293530
{
3530-
std::list<std::string> pragmaOnce;
3531+
std::set<std::string> pragmaOnce;
35313532
defs.clear();
35323533
defs["A"] = "";
35333534
const std::string code("\n#ifndef PAL_UTIL_UTILS_H_\n"
@@ -3563,7 +3564,7 @@ class TestPreprocessor : public TestFixture {
35633564

35643565
// #3418
35653566
{
3566-
std::list<std::string> pragmaOnce;
3567+
std::set<std::string> pragmaOnce;
35673568
defs.clear();
35683569
const char code[] = "#define A 1\n"
35693570
"#define B A\n"
@@ -3595,7 +3596,7 @@ class TestPreprocessor : public TestFixture {
35953596
const std::list<std::string> includePaths;
35963597
std::map<std::string,std::string> defs;
35973598
defs["A"] = "1";
3598-
std::list<std::string> pragmaOnce;
3599+
std::set<std::string> pragmaOnce;
35993600
ASSERT_EQUALS(std::string::npos, // No "123" in the output
36003601
preprocessor.handleIncludes(code, "test.c", includePaths, defs, pragmaOnce,std::list<std::string>()).find("123"));
36013602
}
@@ -3616,7 +3617,7 @@ class TestPreprocessor : public TestFixture {
36163617
std::map<std::string,std::string> defs;
36173618
defs["B"] = "1";
36183619
defs["C"] = "1";
3619-
std::list<std::string> pragmaOnce;
3620+
std::set<std::string> pragmaOnce;
36203621
preprocessor.handleIncludes(code, "test.c", includePaths, defs, pragmaOnce, std::list<std::string>()); // don't crash
36213622
}
36223623

@@ -3631,7 +3632,7 @@ class TestPreprocessor : public TestFixture {
36313632
const std::string filePath("test.c");
36323633
const std::list<std::string> includePaths;
36333634
std::map<std::string,std::string> defs;
3634-
std::list<std::string> pragmaOnce;
3635+
std::set<std::string> pragmaOnce;
36353636
Preprocessor preprocessor(NULL, this);
36363637

36373638
std::istringstream istr(code);

0 commit comments

Comments
 (0)