summaryrefslogtreecommitdiff
path: root/glcpp-lex.l
diff options
context:
space:
mode:
Diffstat (limited to 'glcpp-lex.l')
-rw-r--r--glcpp-lex.l48
1 files changed, 34 insertions, 14 deletions
diff --git a/glcpp-lex.l b/glcpp-lex.l
index 52269c6..a51d9e1 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;
}