Previously, a line such as: #else garbage
would flag an error if it followed "#if 0", but not if it followed "#if 1". We fix this by setting a new bit of state (lexing_else) that allows the lexer to defer switching to the <SKIP> start state until after the NEWLINE following the #else directive. A new test case is added for: #if 1 #else garbage #endif which was untested before, (and did not generate the desired error). --- Matt Turner <matts...@gmail.com> writes: > The preprocessor is one of the only bits that uses tabs. I'd rather we > stick with that, or convert the whole thing. Thanks for the catch. There are a handful of lines indented with spaces that have managed to sneak in, but I might as well not add more. So I've fixed that. Also, here in v2, instead of adding a lexing_else bit next to lexing_if, instead I'm reusing the original bit and renaming it to lexing_directive. src/glsl/glcpp/glcpp-lex.l | 25 +++++++++++----------- src/glsl/glcpp/glcpp-parse.y | 6 +++--- src/glsl/glcpp/glcpp.h | 2 +- src/glsl/glcpp/tests/103-garbage-after-else-0.c | 3 +++ .../tests/103-garbage-after-else-0.c.expected | 4 ++++ src/glsl/glcpp/tests/103-garbage-after-else.c | 3 --- .../glcpp/tests/103-garbage-after-else.c.expected | 4 ---- src/glsl/glcpp/tests/123-garbage-after-else-1.c | 3 +++ .../tests/123-garbage-after-else-1.c.expected | 4 ++++ 9 files changed, 31 insertions(+), 23 deletions(-) create mode 100644 src/glsl/glcpp/tests/103-garbage-after-else-0.c create mode 100644 src/glsl/glcpp/tests/103-garbage-after-else-0.c.expected delete mode 100644 src/glsl/glcpp/tests/103-garbage-after-else.c delete mode 100644 src/glsl/glcpp/tests/103-garbage-after-else.c.expected create mode 100644 src/glsl/glcpp/tests/123-garbage-after-else-1.c create mode 100644 src/glsl/glcpp/tests/123-garbage-after-else-1.c.expected diff --git a/src/glsl/glcpp/glcpp-lex.l b/src/glsl/glcpp/glcpp-lex.l index 188e454..d5fb087 100644 --- a/src/glsl/glcpp/glcpp-lex.l +++ b/src/glsl/glcpp/glcpp-lex.l @@ -137,14 +137,15 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? * 2. The skip_stack is NULL meaning that we've reached * the last #endif. * - * 3. The lexing_if bit is set. This indicates that we - * are lexing the expression following an "#if" of - * "#elif". Even inside an "#if 0" we need to lex this - * expression so the parser can correctly update the - * skip_stack state. + * 3. The lexing_directive bit is set. This indicates that we are + * lexing a pre-processor directive, (such as #if, #elif, or + * #else). For the #if and #elif directives we always need to + * parse the conditions, (even if otherwise within an #if + * 0). And for #else, we want to be able to generate an error + * if any garbage follows #else. */ if (YY_START == INITIAL || YY_START == SKIP) { - if (parser->lexing_if || + if (parser->lexing_directive || parser->skip_stack == NULL || parser->skip_stack->type == SKIP_NO_SKIP) { @@ -193,25 +194,25 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? <SKIP,INITIAL>{ {HASH}ifdef { - yyextra->lexing_if = 1; + yyextra->lexing_directive = 1; yyextra->space_tokens = 0; return HASH_IFDEF; } {HASH}ifndef { - yyextra->lexing_if = 1; + yyextra->lexing_directive = 1; yyextra->space_tokens = 0; return HASH_IFNDEF; } {HASH}if/[^_a-zA-Z0-9] { - yyextra->lexing_if = 1; + yyextra->lexing_directive = 1; yyextra->space_tokens = 0; return HASH_IF; } {HASH}elif/[^_a-zA-Z0-9] { - yyextra->lexing_if = 1; + yyextra->lexing_directive = 1; yyextra->space_tokens = 0; return HASH_ELIF; } @@ -348,7 +349,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? if (parser->commented_newlines) { BEGIN NEWLINE_CATCHUP; } - yyextra->lexing_if = 0; + yyextra->lexing_directive = 0; yylineno++; yycolumn = 0; return NEWLINE; @@ -357,7 +358,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? /* Handle missing newline at EOF. */ <INITIAL><<EOF>> { BEGIN DONE; /* Don't keep matching this rule forever. */ - yyextra->lexing_if = 0; + yyextra->lexing_directive = 0; return NEWLINE; } diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y index 650d0d4..6906e62 100644 --- a/src/glsl/glcpp/glcpp-parse.y +++ b/src/glsl/glcpp/glcpp-parse.y @@ -364,7 +364,7 @@ control_line: glcpp_warning(& @1, parser, "ignoring illegal #elif without expression"); } } -| HASH_ELSE { +| HASH_ELSE { parser->lexing_directive = 1; } NEWLINE { if (parser->skip_stack && parser->skip_stack->has_else) { @@ -376,7 +376,7 @@ control_line: if (parser->skip_stack) parser->skip_stack->has_else = true; } - } NEWLINE + } | HASH_ENDIF { _glcpp_parser_skip_stack_pop (parser, & @1); } NEWLINE @@ -1211,7 +1211,7 @@ glcpp_parser_create (const struct gl_extensions *extensions, gl_api api) parser->defines = hash_table_ctor (32, hash_table_string_hash, hash_table_string_compare); parser->active = NULL; - parser->lexing_if = 0; + parser->lexing_directive = 0; parser->space_tokens = 1; parser->newline_as_space = 0; parser->in_control_line = 0; diff --git a/src/glsl/glcpp/glcpp.h b/src/glsl/glcpp/glcpp.h index 79ccb23..b2654ff 100644 --- a/src/glsl/glcpp/glcpp.h +++ b/src/glsl/glcpp/glcpp.h @@ -168,7 +168,7 @@ struct glcpp_parser { yyscan_t scanner; struct hash_table *defines; active_list_t *active; - int lexing_if; + int lexing_directive; int space_tokens; int newline_as_space; int in_control_line; diff --git a/src/glsl/glcpp/tests/103-garbage-after-else-0.c b/src/glsl/glcpp/tests/103-garbage-after-else-0.c new file mode 100644 index 0000000..c460fea --- /dev/null +++ b/src/glsl/glcpp/tests/103-garbage-after-else-0.c @@ -0,0 +1,3 @@ +#if 0 +#else garbage +#endif diff --git a/src/glsl/glcpp/tests/103-garbage-after-else-0.c.expected b/src/glsl/glcpp/tests/103-garbage-after-else-0.c.expected new file mode 100644 index 0000000..f9f5f19 --- /dev/null +++ b/src/glsl/glcpp/tests/103-garbage-after-else-0.c.expected @@ -0,0 +1,4 @@ +0:2(7): preprocessor error: syntax error, unexpected IDENTIFIER, expecting NEWLINE +0:1(7): preprocessor error: Unterminated #if + + diff --git a/src/glsl/glcpp/tests/103-garbage-after-else.c b/src/glsl/glcpp/tests/103-garbage-after-else.c deleted file mode 100644 index c460fea..0000000 --- a/src/glsl/glcpp/tests/103-garbage-after-else.c +++ /dev/null @@ -1,3 +0,0 @@ -#if 0 -#else garbage -#endif diff --git a/src/glsl/glcpp/tests/103-garbage-after-else.c.expected b/src/glsl/glcpp/tests/103-garbage-after-else.c.expected deleted file mode 100644 index f9f5f19..0000000 --- a/src/glsl/glcpp/tests/103-garbage-after-else.c.expected +++ /dev/null @@ -1,4 +0,0 @@ -0:2(7): preprocessor error: syntax error, unexpected IDENTIFIER, expecting NEWLINE -0:1(7): preprocessor error: Unterminated #if - - diff --git a/src/glsl/glcpp/tests/123-garbage-after-else-1.c b/src/glsl/glcpp/tests/123-garbage-after-else-1.c new file mode 100644 index 0000000..0b341a3 --- /dev/null +++ b/src/glsl/glcpp/tests/123-garbage-after-else-1.c @@ -0,0 +1,3 @@ +#if 1 +#else garbage +#endif diff --git a/src/glsl/glcpp/tests/123-garbage-after-else-1.c.expected b/src/glsl/glcpp/tests/123-garbage-after-else-1.c.expected new file mode 100644 index 0000000..f9f5f19 --- /dev/null +++ b/src/glsl/glcpp/tests/123-garbage-after-else-1.c.expected @@ -0,0 +1,4 @@ +0:2(7): preprocessor error: syntax error, unexpected IDENTIFIER, expecting NEWLINE +0:1(7): preprocessor error: Unterminated #if + + -- 2.0.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev