diff --git a/src/lexer.c b/src/lexer.c index 6be47d3..c3c7bf7 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -77,7 +77,8 @@ typedef enum { T_cppd_elif, T_cppd_else, T_cppd_endif, - T_cppd_ifdef + T_cppd_ifdef, + T_cppd_ifndef } token_t; char token_str[MAX_TOKEN_LEN]; @@ -206,6 +207,8 @@ token_t lex_token_internal(bool aliasing) return T_cppd_elif; if (!strcmp(token_str, "#ifdef")) return T_cppd_ifdef; + if (!strcmp(token_str, "#ifndef")) + return T_cppd_ifndef; if (!strcmp(token_str, "#else")) return T_cppd_else; if (!strcmp(token_str, "#endif")) diff --git a/src/parser.c b/src/parser.c index 8ce1c24..fa04232 100644 --- a/src/parser.c +++ b/src/parser.c @@ -334,9 +334,9 @@ void cppd_control_flow_skip_lines() skip_whitespace(); } -void check_def(char *alias) +void check_def(char *alias, bool expected) { - if (find_alias(alias)) + if ((find_alias(alias) != NULL) == expected) preproc_match = true; } @@ -349,7 +349,7 @@ void read_defined_macro() lex_ident(T_identifier, lookup_alias); lex_expect(T_close_bracket); - check_def(lookup_alias); + check_def(lookup_alias, true); } /* read preprocessor directive at each potential positions: e.g., @@ -485,7 +485,20 @@ bool read_preproc_directive() if (lex_accept_internal(T_cppd_ifdef, false)) { preproc_match = false; lex_ident(T_identifier, token); - check_def(token); + check_def(token, true); + + if (preproc_match) { + skip_whitespace(); + return true; + } + + cppd_control_flow_skip_lines(); + return true; + } + if (lex_accept_internal(T_cppd_ifndef, false)) { + preproc_match = false; + lex_ident(T_identifier, token); + check_def(token, false); if (preproc_match) { skip_whitespace(); diff --git a/tests/driver.sh b/tests/driver.sh index 4859a29..31385cd 100755 --- a/tests/driver.sh +++ b/tests/driver.sh @@ -458,6 +458,19 @@ int main() } EOF +# #ifndef...#else...#endif +try_ 0 << EOF +#ifndef A +#define A 0 +#else +#define A 1 +#endif +int main() +{ + return A; +} +EOF + # #if defined(...) ... #elif defined(...) ... #else ... #endif try_ 0 << EOF #define A 0