Skip to content

Commit f420e61

Browse files
authored
Fix #688: Support #elifdef and #elifndef (#691)
1 parent 5d81c8a commit f420e61

2 files changed

Lines changed: 84 additions & 6 deletions

File tree

simplecpp.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ static const simplecpp::TokenString IFNDEF("ifndef");
9696
static const simplecpp::TokenString DEFINED("defined");
9797
static const simplecpp::TokenString ELSE("else");
9898
static const simplecpp::TokenString ELIF("elif");
99+
static const simplecpp::TokenString ELIFDEF("elifdef");
100+
static const simplecpp::TokenString ELIFNDEF("elifndef");
99101
static const simplecpp::TokenString ENDIF("endif");
100102

101103
static const simplecpp::TokenString PRAGMA("pragma");
@@ -3637,7 +3639,9 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
36373639
continue;
36383640
}
36393641

3640-
if (ifstates.size() <= 1U && (rawtok->str() == ELIF || rawtok->str() == ELSE || rawtok->str() == ENDIF)) {
3642+
if (ifstates.size() <= 1U && (rawtok->str() == ELIF || rawtok->str() == ELIFDEF ||
3643+
rawtok->str() == ELIFNDEF || rawtok->str() == ELSE ||
3644+
rawtok->str() == ENDIF)) {
36413645
if (outputList) {
36423646
simplecpp::Output err{
36433647
Output::SYNTAX_ERROR,
@@ -3778,7 +3782,8 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
37783782
rawtok = filedata->tokens.cfront();
37793783
continue;
37803784
}
3781-
} else if (rawtok->str() == IF || rawtok->str() == IFDEF || rawtok->str() == IFNDEF || rawtok->str() == ELIF) {
3785+
} else if (rawtok->str() == IF || rawtok->str() == IFDEF || rawtok->str() == IFNDEF || rawtok->str() == ELIF ||
3786+
rawtok->str() == ELIFDEF || rawtok->str() == ELIFNDEF) {
37823787
if (!sameline(rawtok,rawtok->next)) {
37833788
if (outputList) {
37843789
simplecpp::Output out{
@@ -3793,10 +3798,11 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
37933798
}
37943799

37953800
bool conditionIsTrue;
3796-
if (ifstates.top() == AlwaysFalse || (ifstates.top() == ElseIsTrue && rawtok->str() != ELIF)) {
3801+
if (ifstates.top() == AlwaysFalse || (ifstates.top() == ElseIsTrue && rawtok->str() != ELIF &&
3802+
rawtok->str() != ELIFDEF && rawtok->str() != ELIFNDEF)) {
37973803
conditionIsTrue = false;
37983804
}
3799-
else if (rawtok->str() == IFDEF) {
3805+
else if (rawtok->str() == IFDEF || rawtok->str() == ELIFDEF) {
38003806
const std::string &name = rawtok->next->str();
38013807
conditionIsTrue = (macros.find(name) != macros.end() || (hasInclude && name == HAS_INCLUDE));
38023808
maybeUsedMacros[name].emplace_back(rawtok->next->location);
@@ -3805,7 +3811,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
38053811
const long long result = conditionIsTrue ? 1 : 0;
38063812
ifCond->emplace_back(rawtok->location, E, result);
38073813
}
3808-
} else if (rawtok->str() == IFNDEF) {
3814+
} else if (rawtok->str() == IFNDEF || rawtok->str() == ELIFNDEF) {
38093815
const std::string &name = rawtok->next->str();
38103816
conditionIsTrue = (macros.find(name) == macros.end() && !(hasInclude && name == HAS_INCLUDE));
38113817
maybeUsedMacros[name].emplace_back(rawtok->next->location);
@@ -3936,7 +3942,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
39363942
}
39373943
}
39383944

3939-
if (rawtok->str() != ELIF) {
3945+
if (rawtok->str() != ELIF && rawtok->str() != ELIFDEF && rawtok->str() != ELIFNDEF) {
39403946
// push a new ifstate..
39413947
if (ifstates.top() != True)
39423948
ifstates.push(AlwaysFalse);

test.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2403,6 +2403,76 @@ static void elif()
24032403
ASSERT_EQUALS("\n\n\n\n\n3", preprocess(code3));
24042404
}
24052405

2406+
static void elifdef()
2407+
{
2408+
{
2409+
const char code[] = "#if 1\n"
2410+
"1\n"
2411+
"#elifdef X\n"
2412+
"2\n"
2413+
"#else\n"
2414+
"3\n"
2415+
"#endif";
2416+
ASSERT_EQUALS("\n1", preprocess(code));
2417+
}
2418+
{
2419+
const char code[] = "#define X\n"
2420+
"#if 0\n"
2421+
"1\n"
2422+
"#elifdef X\n"
2423+
"2\n"
2424+
"#else\n"
2425+
"3\n"
2426+
"#endif";
2427+
ASSERT_EQUALS("\n\n\n\n2", preprocess(code));
2428+
}
2429+
{
2430+
const char code[] = "#if 0\n"
2431+
"1\n"
2432+
"#elifdef X\n"
2433+
"2\n"
2434+
"#else\n"
2435+
"3\n"
2436+
"#endif";
2437+
ASSERT_EQUALS("\n\n\n\n\n3", preprocess(code));
2438+
}
2439+
}
2440+
2441+
static void elifndef()
2442+
{
2443+
{
2444+
const char code[] = "#if 1\n"
2445+
"1\n"
2446+
"#elifndef X\n"
2447+
"2\n"
2448+
"#else\n"
2449+
"3\n"
2450+
"#endif";
2451+
ASSERT_EQUALS("\n1", preprocess(code));
2452+
}
2453+
{
2454+
const char code[] = "#if 0\n"
2455+
"1\n"
2456+
"#elifndef X\n"
2457+
"2\n"
2458+
"#else\n"
2459+
"3\n"
2460+
"#endif";
2461+
ASSERT_EQUALS("\n\n\n2", preprocess(code));
2462+
}
2463+
{
2464+
const char code[] = "#define X\n"
2465+
"#if 0\n"
2466+
"1\n"
2467+
"#elifndef X\n"
2468+
"2\n"
2469+
"#else\n"
2470+
"3\n"
2471+
"#endif";
2472+
ASSERT_EQUALS("\n\n\n\n\n\n3", preprocess(code));
2473+
}
2474+
}
2475+
24062476
static void ifif()
24072477
{
24082478
// source code from LLVM
@@ -4591,6 +4661,8 @@ static void runTests(int argc, char **argv, Input input)
45914661
TEST_CASE(ifLogical);
45924662
TEST_CASE(ifSizeof);
45934663
TEST_CASE(elif);
4664+
TEST_CASE(elifdef);
4665+
TEST_CASE(elifndef);
45944666
TEST_CASE(ifif);
45954667
TEST_CASE(ifoverflow);
45964668
TEST_CASE(ifdiv0);

0 commit comments

Comments
 (0)