Skip to content

Commit bd2b385

Browse files
committed
fixed #1059 - extract configurations for compound preprocessor checks with operators
1 parent 4d8eab3 commit bd2b385

2 files changed

Lines changed: 83 additions & 20 deletions

File tree

lib/preprocessor.cpp

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "errorlogger.h"
2323
#include "errortypes.h"
2424
#include "library.h"
25+
#include "mathlib.h"
2526
#include "path.h"
2627
#include "platform.h"
2728
#include "settings.h"
@@ -420,17 +421,21 @@ static std::string readcondition(const simplecpp::Token *iftok, const std::set<s
420421

421422
if (len == 3 && cond->name && (next1->str() == "==" || next1->str() == "<=" || next1->str() == ">=") && next2->number) {
422423
if (defined.find(cond->str()) == defined.end())
423-
return cond->str() + '=' + cond->next->next->str();
424+
return cond->str() + '=' + next1->next->str();
424425
}
425426

427+
const auto lessGreaterThanConfig = [](const simplecpp::Token* dtok, const simplecpp::Token* ctok) {
428+
int v = MathLib::toBigNumber(ctok->next->str());
429+
if (ctok->op == '<')
430+
v -= 1;
431+
else
432+
v += 1;
433+
return dtok->str() + '=' + std::to_string(v);
434+
};
435+
426436
if (len == 3 && cond->name && (next1->op == '<' || next1->op == '>') && next2->number) {
427437
if (defined.find(cond->str()) == defined.end()) {
428-
int v = strToInt<int>(cond->next->next->str());
429-
if (next1->op == '<')
430-
v -= 1;
431-
else
432-
v += 1;
433-
return cond->str() + '=' + std::to_string(v);
438+
return lessGreaterThanConfig(cond, next1);
434439
}
435440
}
436441

@@ -447,22 +452,40 @@ static std::string readcondition(const simplecpp::Token *iftok, const std::set<s
447452
configset.insert(cond->next->str() + "=0");
448453
continue;
449454
}
450-
if (cond->str() != "defined")
455+
if (cond->str() == "==" || cond->str() == "<=" || cond->str() == ">=") {
456+
if (cond->next->number) {
457+
const simplecpp::Token *dtok = cond->previous;
458+
if (sameline(iftok,dtok) && dtok->name && defined.find(dtok->str()) == defined.end() && undefined.find(dtok->str()) == undefined.end())
459+
configset.insert(dtok->str() + '=' + cond->next->str());
460+
}
451461
continue;
452-
const simplecpp::Token *dtok = cond->next;
453-
if (!dtok)
454-
break;
455-
if (dtok->op == '(')
456-
dtok = dtok->next;
457-
458-
if (sameline(iftok,dtok) && dtok->name && defined.find(dtok->str()) == defined.end() && undefined.find(dtok->str()) == undefined.end()) {
459-
if (!isNotDefinedMacro) {
460-
configset.insert(dtok->str() + "=" + dtok->str()); // if defined is set to itself.
461-
} else {
462-
configset.insert(dtok->str());
462+
}
463+
if (cond->op == '<' || cond->op == '>') {
464+
if (cond->next->number) {
465+
const simplecpp::Token *dtok = cond->previous;
466+
if (sameline(iftok,dtok) && dtok->name && defined.find(dtok->str()) == defined.end() && undefined.find(dtok->str()) == undefined.end()) {
467+
configset.insert(lessGreaterThanConfig(dtok, cond));
468+
}
463469
}
470+
continue;
471+
}
472+
if (cond->str() == "defined") {
473+
const simplecpp::Token *dtok = cond->next;
474+
if (!dtok)
475+
break;
476+
if (dtok->op == '(')
477+
dtok = dtok->next;
478+
479+
if (sameline(iftok,dtok) && dtok->name && defined.find(dtok->str()) == defined.end() && undefined.find(dtok->str()) == undefined.end()) {
480+
if (!isNotDefinedMacro) {
481+
configset.insert(dtok->str() + "=" + dtok->str()); // if defined is set to itself.
482+
} else {
483+
configset.insert(dtok->str());
484+
}
485+
isNotDefinedMacro = false;
486+
}
487+
continue;
464488
}
465-
isNotDefinedMacro = false;
466489
}
467490
std::string cfgStr;
468491
for (const std::string &s : configset) {

test/testpreprocessor.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,11 @@ class TestPreprocessor : public TestFixture {
323323
TEST_CASE(getConfigs15); // #1059
324324
TEST_CASE(getConfigs16); // #1059
325325
TEST_CASE(getConfigs17); // #1059
326+
TEST_CASE(getConfigs18); // #1059
327+
TEST_CASE(getConfigs19); // #1059
328+
TEST_CASE(getConfigs20); // #1059
329+
TEST_CASE(getConfigs21); // #1059
330+
TEST_CASE(getConfigs22); // #1059
326331
TEST_CASE(getConfigsError);
327332

328333
TEST_CASE(getConfigsD1);
@@ -2359,6 +2364,41 @@ class TestPreprocessor : public TestFixture {
23592364
ASSERT_EQUALS("\nA=0\n", getConfigsStr(filedata));
23602365
}
23612366

2367+
void getConfigs18() { // #1059
2368+
const char filedata[] = "#if A == 1 && defined(B)\n"
2369+
"1\n"
2370+
"#endif\n";
2371+
ASSERT_EQUALS("\nA=1;B\n", getConfigsStr(filedata));
2372+
}
2373+
2374+
void getConfigs19() { // #1059
2375+
const char filedata[] = "#if A >= 1 && defined(B)\n"
2376+
"1\n"
2377+
"#endif\n";
2378+
ASSERT_EQUALS("\nA=1;B\n", getConfigsStr(filedata));
2379+
}
2380+
2381+
void getConfigs20() { // #1059
2382+
const char filedata[] = "#if A <= 1 && defined(B)\n"
2383+
"1\n"
2384+
"#endif\n";
2385+
ASSERT_EQUALS("\nA=1;B\n", getConfigsStr(filedata));
2386+
}
2387+
2388+
void getConfigs21() { // #1059
2389+
const char filedata[] = "#if A > 1 && defined(B)\n"
2390+
"1\n"
2391+
"#endif\n";
2392+
ASSERT_EQUALS("\nA=2;B\n", getConfigsStr(filedata));
2393+
}
2394+
2395+
void getConfigs22() { // #1059
2396+
const char filedata[] = "#if A < 1 && defined(B)\n"
2397+
"1\n"
2398+
"#endif\n";
2399+
ASSERT_EQUALS("\nA=0;B\n", getConfigsStr(filedata));
2400+
}
2401+
23622402
void getConfigsError() {
23632403
const char filedata1[] = "#ifndef X\n"
23642404
"#error \"!X\"\n"

0 commit comments

Comments
 (0)