summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/glsl/glcpp/glcpp-lex.l38
-rw-r--r--src/glsl/glcpp/tests/130-define-comment.c2
-rw-r--r--src/glsl/glcpp/tests/130-define-comment.c.expected3
3 files changed, 41 insertions, 2 deletions
diff --git a/src/glsl/glcpp/glcpp-lex.l b/src/glsl/glcpp/glcpp-lex.l
index 0d4bfc8d443..a9801f4b6a4 100644
--- a/src/glsl/glcpp/glcpp-lex.l
+++ b/src/glsl/glcpp/glcpp-lex.l
@@ -161,7 +161,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
}
/* Multi-line comments */
-"/*" { yy_push_state(COMMENT, yyscanner); }
+<DEFINE,INITIAL>"/*" { yy_push_state(COMMENT, yyscanner); }
<COMMENT>[^*\n]*
<COMMENT>[^*\n]*\n { yylineno++; yycolumn = 0; parser->commented_newlines++; }
<COMMENT>"*"+[^*/\n]*
@@ -241,25 +241,59 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]?
glcpp_error(yylloc, yyextra, "#error%s", p);
}
+ /* After we see a "#define" we enter the <DEFINE> start state
+ * for the lexer. Within <DEFINE> we are looking for the first
+ * identifier and specifically checking whether the identifier
+ * is followed by a '(' or not, (to lex either a
+ * FUNC_IDENTIFIER or an OBJ_IDENITIFIER token).
+ *
+ * While in the <DEFINE> state we also need to explicitly
+ * handle a few other things that may appear before the
+ * identifier:
+ *
+ * * Comments, (handled above with the main support for
+ * comments).
+ *
+ * * Whitespace (simply ignored)
+ *
+ * * Anything else, (not an identifier, not a comment,
+ * and not whitespace). This will generate an error.
+ */
{HASH}define{HSPACE}+ {
yyextra->space_tokens = 0;
yy_push_state(DEFINE, yyscanner);
return HASH_DEFINE;
}
+ /* An identifier immediately followed by '(' */
<DEFINE>{IDENTIFIER}/"(" {
yy_pop_state(yyscanner);
yylval->str = ralloc_strdup (yyextra, yytext);
return FUNC_IDENTIFIER;
}
+ /* An identifier not immediately followed by '(' */
<DEFINE>{IDENTIFIER} {
yy_pop_state(yyscanner);
yylval->str = ralloc_strdup (yyextra, yytext);
return OBJ_IDENTIFIER;
}
-<DEFINE>[^_a-zA-Z]{NONSPACE}* {
+ /* Whitespace */
+<DEFINE>{HSPACE}+ {
+ /* Just ignore it. Nothing to do here. */
+}
+
+ /* '/' not followed by '*', so not a comment. This is an error. */
+<DEFINE>[/][^*]{NONSPACE}* {
+ BEGIN INITIAL;
+ glcpp_error(yylloc, yyextra, "#define followed by a non-identifier: %s", yytext);
+ return INTEGER_STRING;
+}
+
+ /* A character that can't start an identifier, comment, or
+ * space. This is an error. */
+<DEFINE>[^_a-zA-Z/[:space:]]{NONSPACE}* {
BEGIN INITIAL;
glcpp_error(yylloc, yyextra, "#define followed by a non-identifier: %s", yytext);
return INTEGER_STRING;
diff --git a/src/glsl/glcpp/tests/130-define-comment.c b/src/glsl/glcpp/tests/130-define-comment.c
new file mode 100644
index 00000000000..33312362cc7
--- /dev/null
+++ b/src/glsl/glcpp/tests/130-define-comment.c
@@ -0,0 +1,2 @@
+#define /*...*/ FUNC( /*...*/ x /*...*/ ) /*...*/ FOO( /*...*/ x /*...*/ )
+FUNC(bar)
diff --git a/src/glsl/glcpp/tests/130-define-comment.c.expected b/src/glsl/glcpp/tests/130-define-comment.c.expected
new file mode 100644
index 00000000000..ed59055e306
--- /dev/null
+++ b/src/glsl/glcpp/tests/130-define-comment.c.expected
@@ -0,0 +1,3 @@
+
+FOO( bar )
+