diff options
| -rw-r--r-- | preprocess.c | 26 | ||||
| -rw-r--r-- | tests/084.sh | 28 |
2 files changed, 54 insertions, 0 deletions
diff --git a/preprocess.c b/preprocess.c index 5b7c180..72e8ca3 100644 --- a/preprocess.c +++ b/preprocess.c @@ -362,6 +362,11 @@ int find_pp_macro(Preprocessor* pp, String* name) { return -1; } +void undef_pp_macro(Preprocessor* pp, int idx) { + pp->pp_macros->data[idx].name.len = 0; + // TODO: Can predefined macro like __FILE__ be undefined? +} + void add_include_path(Preprocessor* pp, char* include_path) { pp->include_paths[pp->n_include_paths].data = include_path; pp->include_paths[pp->n_include_paths].len = strlen(include_path); @@ -867,6 +872,24 @@ Token* process_define_directive(Preprocessor* pp, Token* tok) { return NULL; } +Token* process_undef_directive(Preprocessor* pp, Token* tok) { + Token* tok2 = skip_whitespace(tok + 1); + if (tok2->kind == TokenKind_ident && string_equals_cstr(&tok2->raw, "undef")) { + tok2 = skip_whitespace(tok2 + 1); + if (tok2->kind == TokenKind_ident) { + Token* macro_name = tok2; + ++tok2; + int pp_macro_idx = find_pp_macro(pp, ¯o_name->raw); + if (pp_macro_idx != -1) { + undef_pp_macro(pp, pp_macro_idx); + } + } + remove_directive_tokens(tok, tok2); + return tok2; + } + return NULL; +} + BOOL expand_macro(Preprocessor* pp, Token* tok) { int pp_macro_idx = find_pp_macro(pp, &tok->raw); if (pp_macro_idx == -1) { @@ -945,6 +968,9 @@ void process_pp_directives(Preprocessor* pp) { } else if ((next_tok = process_define_directive(pp, tok)) != NULL) { tok = next_tok; continue; + } else if ((next_tok = process_undef_directive(pp, tok)) != NULL) { + tok = next_tok; + continue; } else { fatal_error("%s:%d: unknown preprocessor directive (%s)", tok->loc.filename, tok->loc.line, token_stringify(tok + 1)); diff --git a/tests/084.sh b/tests/084.sh new file mode 100644 index 0000000..3b2fe15 --- /dev/null +++ b/tests/084.sh @@ -0,0 +1,28 @@ +set -e + +cat <<'EOF' > expected +A is defined +A is undefined +EOF + +bash ../../test_diff.sh <<'EOF' +int printf(); + +int main() { +#define A 1 + +#ifdef A + printf("A is defined\n"); +#else + printf("A is undefined\n"); +#endif + +#undef A + +#ifdef A + printf("A is defined\n"); +#else + printf("A is undefined\n"); +#endif +} +EOF |
