[Mesa-dev] [PATCH 09/10] glsl: Add support to #line for a filnename, not just a source string number

Carl Worth cworth at cworth.org
Sat Dec 8 13:43:44 PST 2012


Such as:

	#line 23 "foo.c"

Having a filename here is quite useful and many other OpenGL implementations
allow this.
---
 src/glsl/ast.h                  |    2 +-
 src/glsl/glsl_lexer.ll          |   56 ++++++++++++++++++++++++++++++---------
 src/glsl/glsl_parser.yy         |    2 +-
 src/glsl/glsl_parser_extras.cpp |    2 +-
 src/glsl/glsl_parser_extras.h   |    4 +--
 5 files changed, 48 insertions(+), 18 deletions(-)

diff --git a/src/glsl/ast.h b/src/glsl/ast.h
index 5074782..7d9ba69 100644
--- a/src/glsl/ast.h
+++ b/src/glsl/ast.h
@@ -116,7 +116,7 @@ public:
     * Source location of the AST node.
     */
    struct {
-      unsigned source;    /**< GLSL source number. */
+      char *source;       /**< GLSL source number. */
       unsigned line;      /**< Line number within the source string. */
       unsigned column;    /**< Column in the line. */
    } location;
diff --git a/src/glsl/glsl_lexer.ll b/src/glsl/glsl_lexer.ll
index ac06fd2..66e6377 100644
--- a/src/glsl/glsl_lexer.ll
+++ b/src/glsl/glsl_lexer.ll
@@ -41,7 +41,7 @@ static int classify_identifier(struct _mesa_glsl_parse_state *, const char *);
       yycolumn += yyleng;					\
    } while(0);
 
-#define YY_USER_INIT yylineno = 0; yycolumn = 0; yylloc->source = 0;
+#define YY_USER_INIT yylineno = 0; yycolumn = 0; yylloc->source = (char *) "0";
 
 /* A macro for handling reserved words and keywords across language versions.
  *
@@ -160,6 +160,7 @@ INT		({DEC_INT}|{HEX_INT}|{OCT_INT})
 SPC		[ \t]*
 SPCP		[ \t]+
 HASH		^{SPC}#{SPC}
+STRING_LITERAL	\"(\\.|[^\\"\n])*\"
 %%
 
 	/* Make state available to all actions. */
@@ -171,7 +172,12 @@ HASH		^{SPC}#{SPC}
 {HASH}$				;
 {HASH}version			{ BEGIN PP; return VERSION_TOK; }
 {HASH}extension			{ BEGIN PP; return EXTENSION; }
-{HASH}line{SPCP}{INT}{SPCP}{INT}{SPC}$ {
+	/* We subtract 2 from the number in a #line directive because:
+	 * 1. yylineno is zero-based, rather than one-based as desired, and
+	 * 2. #line gives the line number for the subsequent line of the source,
+	 *    and we will increment yylineno before then at the next newline.
+	 */
+{HASH}line{SPCP}{INT}{SPCP}{STRING_LITERAL}$ {
 				   /* Eat characters until the first digit is
 				    * encountered
 				    */
@@ -179,13 +185,42 @@ HASH		^{SPC}#{SPC}
 				   while (!isdigit(*ptr))
 				      ptr++;
 
-				   /* Subtract two from the line number parsed.
-				    * 1 because yylineno is zero-based and
-				    * 2 because #line gives the line number for
-				    * the subsequent line of the source.
+				   yylineno = strtol(ptr, &ptr, 0) - 2;
+
+				   /* Skip space before string. */
+				   while (isspace(*ptr))
+				      ptr++;
+
+				   /* Omit initial and final quotation marks
+				    * when copying string value.
+				    */
+				   yylloc->source =
+				   ralloc_strndup(state, ptr+1, strlen(ptr)-2);
+				}
+{HASH}line{SPCP}{INT}{SPCP}{INT}{SPC}$ {
+				   /* Eat characters until the first digit is
+				    * encountered
 				    */
+				   char *ptr = yytext;
+				   while (!isdigit(*ptr))
+				      ptr++;
+
 				   yylineno = strtol(ptr, &ptr, 0) - 2;
-				   yylloc->source = strtol(ptr, NULL, 0);
+
+				   /* Skip space before source number. */
+				   while (isspace(*ptr))
+				      ptr++;
+
+				   yylloc->source = ralloc_strdup(state, ptr);
+				   ptr = yylloc->source;
+
+				   /* Terminate after digits to
+				    * eliminate any trailing space.
+				    */
+				   while (isdigit(*ptr))
+				      ptr++;
+				   *ptr = '\0';
+
 				}
 {HASH}line{SPCP}{INT}{SPC}$	{
 				   /* Eat characters until the first digit is
@@ -195,12 +230,7 @@ HASH		^{SPC}#{SPC}
 				   while (!isdigit(*ptr))
 				      ptr++;
 
-				   /* Subtract two from the line number parsed.
-				    * 1 because yylineno is zero-based and
-				    * 2 because #line gives the line number for
-				    * the subsequent line of the source.
-				    */
-				   yylineno = strtol(ptr, &ptr, 0) - 2;
+				   yylineno = strtol(ptr, NULL, 0) - 2;
 				}
 ^{SPC}#{SPC}pragma{SPCP}debug{SPC}\({SPC}on{SPC}\) {
 				  BEGIN PP;
diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy
index 0af71e7..ad07d60 100644
--- a/src/glsl/glsl_parser.yy
+++ b/src/glsl/glsl_parser.yy
@@ -50,7 +50,7 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg)
    @$.first_column = 1;
    @$.last_line = 1;
    @$.last_column = 1;
-   @$.source = 0;
+   @$.source = (char *) "0";
 }
 
 %lex-param   {void *scanner}
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index d360892..a4a7985 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -313,7 +313,7 @@ _mesa_glsl_msg(const YYLTYPE *locp, _mesa_glsl_parse_state *state,
    /* Get the offset that the new message will be written to. */
    int msg_offset = strlen(state->info_log);
 
-   ralloc_asprintf_append(&state->info_log, "%u:%u(%u): %s: ",
+   ralloc_asprintf_append(&state->info_log, "%s:%u(%u): %s: ",
 					    locp->source,
 					    locp->first_line,
 					    locp->first_column,
diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
index 2e6bb0b..ed6bc4a 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -64,7 +64,7 @@ typedef struct YYLTYPE {
    int first_column;
    int last_line;
    int last_column;
-   unsigned source;
+   char *source;
 } YYLTYPE;
 # define YYLTYPE_IS_DECLARED 1
 # define YYLTYPE_IS_TRIVIAL 1
@@ -298,7 +298,7 @@ do {								\
       (Current).first_column = (Current).last_column =		\
 	 YYRHSLOC(Rhs, 0).last_column;				\
    }								\
-   (Current).source = 0;					\
+   (Current).source = (char *) "0";				\
 } while (0)
 
 extern void _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
-- 
1.7.10



More information about the mesa-dev mailing list