diff options
| -rw-r--r-- | preprocess.c | 48 | ||||
| -rw-r--r-- | tests/062.sh | 38 |
2 files changed, 86 insertions, 0 deletions
diff --git a/preprocess.c b/preprocess.c index a8b3b91..205e2bd 100644 --- a/preprocess.c +++ b/preprocess.c @@ -37,6 +37,7 @@ struct Preprocessor { int n_pp_tokens; PpDefines* pp_defines; int include_depth; + int skip_pp_tokens; }; typedef struct Preprocessor Preprocessor; @@ -83,6 +84,11 @@ int find_pp_define(Preprocessor* pp, String* name) { return -1; } +int skip_pp_tokens(Preprocessor* pp) { + // TODO: support nested #if + return pp->skip_pp_tokens; +} + void pp_tokenize_all(Preprocessor* pp) { char* buf; int ch; @@ -416,7 +422,49 @@ void process_pp_directives(Preprocessor* pp) { pp->n_pp_tokens += n_include_pp_tokens; } + } else if (tok2->kind == PpTokenKind_identifier && string_equals_cstr(&tok2->raw, "ifdef")) { + ++tok2; + while (tok2->kind != PpTokenKind_eof && tok2->kind == PpTokenKind_whitespace) + ++tok2; + if (tok2->kind == PpTokenKind_identifier) { + // Process #ifdef directive. + PpToken* name = tok2; + ++tok2; + + pp->skip_pp_tokens = find_pp_define(pp, &name->raw) == -1; + } + // Remove #ifdef directive. + while (tok != tok2 + 1) { + tok->kind = PpTokenKind_whitespace; + tok->raw.len = 0; + tok->raw.data = NULL; + ++tok; + } + } else if (tok2->kind == PpTokenKind_identifier && string_equals_cstr(&tok2->raw, "endif")) { + ++tok2; + pp->skip_pp_tokens = 0; + // Remove #endif directive. + while (tok != tok2 + 1) { + tok->kind = PpTokenKind_whitespace; + tok->raw.len = 0; + tok->raw.data = NULL; + ++tok; + } + } else if (tok2->kind == PpTokenKind_identifier && string_equals_cstr(&tok2->raw, "else")) { + ++tok2; + pp->skip_pp_tokens = 1 - pp->skip_pp_tokens; + // Remove #else directive. + while (tok != tok2 + 1) { + tok->kind = PpTokenKind_whitespace; + tok->raw.len = 0; + tok->raw.data = NULL; + ++tok; + } } + } else if (skip_pp_tokens(pp)) { + tok->kind = PpTokenKind_whitespace; + tok->raw.len = 0; + tok->raw.data = NULL; } else if (tok->kind == PpTokenKind_identifier) { int pp_define_idx = find_pp_define(pp, &tok->raw); if (pp_define_idx != -1) { diff --git a/tests/062.sh b/tests/062.sh new file mode 100644 index 0000000..d50ecc6 --- /dev/null +++ b/tests/062.sh @@ -0,0 +1,38 @@ +set -e + +cat <<'EOF' > expected +__ducc__ is defined. +A is defined. +B is undefined. +EOF + +bash ../../test_diff.sh <<'EOF' +int printf(); + +#define A 123 + +int main() { + +#ifdef __ducc__ + printf("__ducc__ is defined.\n"); +#else + printf("__ducc__ is undefined.\n"); +#endif + +#ifdef A + printf("A is defined.\n"); +#else + printf("A is undefined.\n"); +#endif + +#ifdef B + printf("B is defined.\n"); +#else + printf("B is undefined.\n"); +#endif + +#define B 456 + + return 0; +} +EOF |
