Such as:

        #line 23 "foo.c"

Having a filename here is quite useful and many other OpenGL implementations
allow this.

Note that for GLES we take the hard line and insist on a numeric source string
number as per the specification and which glcpp has always supported:

        #line 23 3
---
 src/glsl/glcpp/glcpp-lex.l   |   28 ++++++++++++++----
 src/glsl/glcpp/glcpp-parse.y |   64 ++++++++++++++++++++++++++++++++++--------
 src/glsl/glcpp/glcpp.h       |    8 +++---
 src/glsl/glcpp/pp.c          |    4 +--
 4 files changed, 81 insertions(+), 23 deletions(-)

diff --git a/src/glsl/glcpp/glcpp-lex.l b/src/glsl/glcpp/glcpp-lex.l
index fd28711..a6171cc 100644
--- a/src/glsl/glcpp/glcpp-lex.l
+++ b/src/glsl/glcpp/glcpp-lex.l
@@ -44,20 +44,20 @@ void glcpp_set_column (int  column_no , yyscan_t yyscanner);
        do {                                                            \
                if (parser->has_new_line_number)                        \
                        yylineno = parser->new_line_number;             \
-               if (parser->has_new_source_number)                      \
-                       yylloc->source = parser->new_source_number;     \
+               if (parser->has_new_source)                             \
+                       yylloc->source = parser->new_source;            \
                yylloc->first_column = yycolumn + 1;                    \
                yylloc->first_line = yylineno;                          \
                yycolumn += yyleng;                                     \
                parser->has_new_line_number = 0;                        \
-               parser->has_new_source_number = 0;                      \
+               parser->has_new_source = 0;                             \
  } while(0);
 
 #define YY_USER_INIT                   \
        do {                            \
                yylineno = 1;           \
                yycolumn = 1;           \
-               yylloc->source = 0;     \
+               yylloc->source = "0";   \
        } while(0)
 %}
 
@@ -84,7 +84,7 @@ strings, we have to be careful to avoid OTHER matching and 
hiding
 something that CPP does care about. So we simply exclude all
 characters that appear in any other expressions. */
 
-OTHER          [^][_#[:space:]#a-zA-Z0-9(){}.&*~!/%<>^|;,=+-]
+OTHER          [^][_#[:space:]#a-zA-Z0-9(){}.&*~!/%<>^|;,="+-]
 
 DIGITS                 [0-9][0-9]*
 DECIMAL_INTEGER                [1-9][0-9]*[uU]?
@@ -120,6 +120,24 @@ HEXADECIMAL_INTEGER        0[xX][0-9a-fA-F]+[uU]?
                return SPACE;
 }
 
+\"(\\.|[^\\"\n])*\" {
+       /* Drop the quotation marks when returning a string's literal value.
+        *
+        * Note: A truly *correct* solution would also interpret any
+        * escape sequences within the string. We intentionally don't
+        * do this. The rationale is for code savings and the
+        * justification is that strings aren't actually part of the
+        * GLSL language. We're only parsing them as a convenience for
+        * use in '#line XX "foo.c"' and even that isn't part of the
+        * specification. So, for this limited use case of filenames,
+        * escape sequences shouldn't be common, and when they are,
+        * users can deal with the un-interpreted escape sequence
+        * appearing in the filename in error messages.
+        */
+       yylval->str = ralloc_strndup (yyextra, yytext + 1, strlen(yytext) - 2);
+       return STRING_LITERAL;
+}
+
 {HASH}version{HSPACE}+ {
        yylval->str = ralloc_strdup (yyextra, yytext);
        yyextra->space_tokens = 0;
diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y
index 380a1d9..eaf01cd 100644
--- a/src/glsl/glcpp/glcpp-parse.y
+++ b/src/glsl/glcpp/glcpp-parse.y
@@ -164,10 +164,10 @@ add_builtin_define(glcpp_parser_t *parser, const char 
*name, int value);
 %lex-param {glcpp_parser_t *parser}
 
 %expect 0
-%token COMMA_FINAL DEFINED ELIF_EXPANDED HASH HASH_DEFINE FUNC_IDENTIFIER 
OBJ_IDENTIFIER HASH_ELIF HASH_ELSE HASH_ENDIF HASH_IF HASH_IFDEF HASH_IFNDEF 
HASH_LINE HASH_UNDEF HASH_VERSION IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING 
LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE
+%token COMMA_FINAL DEFINED ELIF_EXPANDED HASH HASH_DEFINE FUNC_IDENTIFIER 
OBJ_IDENTIFIER HASH_ELIF HASH_ELSE HASH_ENDIF HASH_IF HASH_IFDEF HASH_IFNDEF 
HASH_LINE HASH_UNDEF HASH_VERSION IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING 
LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE STRING_LITERAL
 %token PASTE
 %type <ival> expression INTEGER operator SPACE integer_constant
-%type <str> IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER
+%type <str> IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER 
STRING_LITERAL
 %type <string_list> identifier_list
 %type <token> preprocessing_token conditional_token
 %type <token_list> pp_tokens replacement_list text_line conditional_tokens
@@ -229,13 +229,27 @@ expanded_line:
 |      LINE_EXPANDED integer_constant integer_constant NEWLINE {
                parser->has_new_line_number = 1;
                parser->new_line_number = $2;
-               parser->has_new_source_number = 1;
-               parser->new_source_number = $3;
+               parser->has_new_source = 1;
+               parser->new_source = ralloc_asprintf (parser, "%" PRIiMAX, $3);
                ralloc_asprintf_rewrite_tail (&parser->output,
                                              &parser->output_length,
                                              "#line %" PRIiMAX " %" PRIiMAX 
"\n",
                                              $2, $3);
        }
+|      LINE_EXPANDED integer_constant STRING_LITERAL NEWLINE {
+#if 0
+               if (parser->is_gles)
+                       glcpp_error(& @1, parser, "#line with non-numeric 
source number (illegal in GLES)");
+#endif
+               parser->has_new_line_number = 1;
+               parser->new_line_number = $2;
+               parser->has_new_source = 1;
+               parser->new_source = $3;
+               ralloc_asprintf_rewrite_tail (&parser->output,
+                                             &parser->output_length,
+                                             "#line %" PRIiMAX " \"%s\"\n",
+                                             $2, $3);
+       }
 ;
 
 control_line:
@@ -540,6 +554,10 @@ preprocessing_token:
                $$ = _token_create_ival (parser, SPACE, SPACE);
                $$->location = yylloc;
        }
+|      STRING_LITERAL {
+               $$ = _token_create_str (parser, STRING_LITERAL, $1);
+               $$->location = yylloc;
+       }
 ;
 
 operator:
@@ -911,6 +929,7 @@ _token_list_equal_ignoring_space (token_list_t *a, 
token_list_t *b)
                case IDENTIFIER:
                case INTEGER_STRING:
                case OTHER:
+               case STRING_LITERAL:
                        if (strcmp (node_a->token->value.str,
                                    node_b->token->value.str))
                        {
@@ -938,6 +957,9 @@ _token_print (char **out, size_t *len, token_t *token)
        case INTEGER:
                ralloc_asprintf_rewrite_tail (out, len, "%" PRIiMAX, 
token->value.ival);
                break;
+       case STRING_LITERAL:
+               ralloc_asprintf_rewrite_tail (out, len, "\"%s\"", 
token->value.str);
+               break;
        case IDENTIFIER:
        case INTEGER_STRING:
        case OTHER:
@@ -1052,8 +1074,8 @@ _token_paste (glcpp_parser_t *parser, token_t *token, 
token_t *other)
         * the second token must also be an integer or must be a
         * string representing an integer that begins with a digit.
         */
-       if ((token->type == IDENTIFIER || token->type == OTHER || token->type 
== INTEGER_STRING || token->type == INTEGER) &&
-           (other->type == IDENTIFIER || other->type == OTHER || other->type 
== INTEGER_STRING || other->type == INTEGER))
+       if ((token->type == IDENTIFIER || token->type == OTHER || token->type 
== STRING_LITERAL || token->type == INTEGER_STRING || token->type == INTEGER) &&
+           (other->type == IDENTIFIER || other->type == OTHER || other->type 
== STRING_LITERAL || INTEGER_STRING || other->type == INTEGER))
        {
                char *str;
                int combined_type;
@@ -1064,6 +1086,8 @@ _token_paste (glcpp_parser_t *parser, token_t *token, 
token_t *other)
                if (token->type == INTEGER_STRING || token->type == INTEGER)
                {
                        switch (other->type) {
+                       case OTHER:
+                       case STRING_LITERAL:
                        case INTEGER_STRING:
                                if (other->value.str[0] < '0' ||
                                    other->value.str[0] > '9')
@@ -1176,8 +1200,8 @@ glcpp_parser_create (const struct gl_extensions 
*extensions, int api)
 
        parser->has_new_line_number = 0;
        parser->new_line_number = 1;
-       parser->has_new_source_number = 0;
-       parser->new_source_number = 0;
+       parser->has_new_source = 0;
+       parser->new_source = "0";
 
        /* Add pre-defined macros. */
        if (extensions != NULL) {
@@ -1330,19 +1354,35 @@ _arguments_parse (argument_list_t *arguments,
 }
 
 static token_list_t *
-_token_list_create_with_one_ival (void *ctx, int type, int ival)
+_token_list_create_with_one_node (void *ctx, token_t *node)
 {
        token_list_t *list;
-       token_t *node;
 
        list = _token_list_create (ctx);
-       node = _token_create_ival (list, type, ival);
        _token_list_append (list, node);
 
        return list;
 }
 
 static token_list_t *
+_token_list_create_with_one_ival (void *ctx, int type, int ival)
+{
+       token_t *node;
+
+       node = _token_create_ival (ctx, type, ival);
+       return _token_list_create_with_one_node (ctx, node);
+}
+
+static token_list_t *
+_token_list_create_with_one_string (void *ctx, int type, const char *str)
+{
+       token_t *node;
+
+       node = _token_create_str (ctx, type, ralloc_strdup (ctx, str));
+       return _token_list_create_with_one_node (ctx, node);
+}
+
+static token_list_t *
 _token_list_create_with_one_space (void *ctx)
 {
        return _token_list_create_with_one_ival (ctx, SPACE, SPACE);
@@ -1579,7 +1619,7 @@ _glcpp_parser_expand_node (glcpp_parser_t *parser,
                return _token_list_create_with_one_integer (parser, 
node->token->location.first_line);
 
        if (strcmp(identifier, "__FILE__") == 0)
-               return _token_list_create_with_one_integer (parser, 
node->token->location.source);
+               return _token_list_create_with_one_string (parser, OTHER, 
node->token->location.source);
 
        /* Look up this identifier in the hash table. */
        macro = hash_table_find (parser->defines, identifier);
diff --git a/src/glsl/glcpp/glcpp.h b/src/glsl/glcpp/glcpp.h
index cdcbdfe..09f711c 100644
--- a/src/glsl/glcpp/glcpp.h
+++ b/src/glsl/glcpp/glcpp.h
@@ -67,7 +67,7 @@ typedef struct YYLTYPE {
    int first_column;
    int last_line;
    int last_column;
-   unsigned source;
+   const char *source;
 } YYLTYPE;
 # define YYLTYPE_IS_DECLARED 1
 # define YYLTYPE_IS_TRIVIAL 1
@@ -88,7 +88,7 @@ do {                                                          
\
       (Current).first_column = (Current).last_column =         \
         YYRHSLOC(Rhs, 0).last_column;                          \
    }                                                           \
-   (Current).source = 0;                                       \
+   (Current).source = "0";                                     \
 } while (0)
 
 struct token {
@@ -182,8 +182,8 @@ struct glcpp_parser {
        int error;
        bool has_new_line_number;
        int new_line_number;
-       bool has_new_source_number;
-       int new_source_number;
+       bool has_new_source;
+       const char *new_source;
 };
 
 struct gl_extensions;
diff --git a/src/glsl/glcpp/pp.c b/src/glsl/glcpp/pp.c
index 789f7f9..4a43a9c 100644
--- a/src/glsl/glcpp/pp.c
+++ b/src/glsl/glcpp/pp.c
@@ -35,7 +35,7 @@ glcpp_error (YYLTYPE *locp, glcpp_parser_t *parser, const 
char *fmt, ...)
        parser->error = 1;
        ralloc_asprintf_rewrite_tail(&parser->info_log,
                                     &parser->info_log_length,
-                                    "%u:%u(%u): "
+                                    "%s:%u(%u): "
                                     "preprocessor error: ",
                                     locp->source,
                                     locp->first_line,
@@ -56,7 +56,7 @@ glcpp_warning (YYLTYPE *locp, glcpp_parser_t *parser, const 
char *fmt, ...)
 
        ralloc_asprintf_rewrite_tail(&parser->info_log,
                                     &parser->info_log_length,
-                                    "%u:%u(%u): "
+                                    "%s:%u(%u): "
                                     "preprocessor warning: ",
                                     locp->source,
                                     locp->first_line,
-- 
1.7.10

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to