diff options
Diffstat (limited to 'glcpp-lex.l')
-rw-r--r-- | glcpp-lex.l | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/glcpp-lex.l b/glcpp-lex.l index 52269c6b30..a51d9e185f 100644 --- a/glcpp-lex.l +++ b/glcpp-lex.l @@ -47,39 +47,58 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? %% -{HASH}define{HSPACE}+/{IDENTIFIER}"(" { +{HASH}if/.*\n { + yyextra->lexing_if = 1; yyextra->space_tokens = 0; - return HASH_DEFINE_FUNC; + return HASH_IF; } -{HASH}define { +{HASH}elif/.*\n { + yyextra->lexing_if = 1; yyextra->space_tokens = 0; - return HASH_DEFINE_OBJ; + return HASH_ELIF; } -{HASH}undef { +{HASH}else/.*\n { yyextra->space_tokens = 0; - return HASH_UNDEF; + return HASH_ELSE; } -{HASH}if { +{HASH}endif/.*\n { yyextra->space_tokens = 0; - return HASH_IF; + return HASH_ENDIF; } -{HASH}elif { + /* When skipping (due to an #if 0 or similar) consume anything + * up to a newline. We do this less priroty than any + * #if-related directive (#if, #elif, #else, #endif), but with + * more priority than any other directive or token to avoid + * any side-effects from skipped content. + * + * We use the lexing_if flag to avoid skipping any part of an + * if conditional expression. */ +[^\n]+/\n { + if (yyextra->lexing_if || + yyextra->skip_stack == NULL || + yyextra->skip_stack->type == SKIP_NO_SKIP) + { + REJECT; + } +} + +{HASH}define{HSPACE}+/{IDENTIFIER}"(" { yyextra->space_tokens = 0; - return HASH_ELIF; + return HASH_DEFINE_FUNC; } -{HASH}else { +{HASH}define { yyextra->space_tokens = 0; - return HASH_ELSE; + return HASH_DEFINE_OBJ; } -{HASH}endif { +{HASH}undef { yyextra->space_tokens = 0; - return HASH_ENDIF; + return HASH_UNDEF; } {HASH} { @@ -163,6 +182,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? } \n { + yyextra->lexing_if = 0; return NEWLINE; } |