From fdbedba4d50e1b28b0249c83ba11c029f096e400 Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 11 Aug 2014 21:14:48 +0200 Subject: fontconfig libX11 libxcb libxcb/xcb-proto mesa xserver xkeyboard-config git update 11 Aug 2014 xserver commit 3714f5401690b288045090c4bcd9cb01c6e4860e libxcb commit 966fba6ba4838949d0727dfa45eeb9392d1f85d9 libxcb/xcb-proto commit 4b384d2a015c50d0e93dcacda4b8260a3fd37640 xkeyboard-config commit 651a00ab656a1754b9183a383970a735209bbb50 libX11 commit 368a6401c6a3275d3497fec38a3dcbc38cd9df60 libXdmcp commit fe8eab93e9bcdbe8bb8052434bb5e676e3a0ee8f libXext commit efdcbb7634501e1117d422636a0a75d7ea84b16b libfontenc commit 0037a42107b952c9d903719615747e760e4e7247 libXinerama commit edd95182b26eb5d576d4878c559e0f17dddaa909 libXau commit 1e4635be11154dd8262f37b379511bd627defa2a xkbcomp commit d4e02a09258063c6d024c3ccd42d6b22212e6e18 pixman commit 6d2cf40166d81bfc63108504c8022dc4fec37ff5 xextproto commit 66afec3f49e8eb0d4c2e9af7088fc3116d4bafd7 randrproto commit a4a6694c059d74247c16527eef4a0ec9f56bbef6 glproto commit f84853d97d5749308992412a215fa518b6536eb3 mkfontscale commit 47908fd7a0d061fdcd21e3498da4e223ca9136d9 xwininfo commit 017b3736489985999d8dcf4d9e473e1fd6dd3647 libXft commit 214f9b5306d833e2787c75fe41dfdc9228fcb738 libXmu commit 22d9c590901e121936f50dee97dc60c4f7defb63 libxtrans commit a57a7f62242e1ea972b81414741729bf3dbae0a4 fontconfig commit 841753a93f0e5698663b7931b8456e7b96259f54 mesa commit f24be7340162c6a831b392d46d6637e9656e7a8a --- mesalib/src/glsl/glcpp/glcpp-parse.y | 426 ++++++++++++++++++++++++++--------- 1 file changed, 318 insertions(+), 108 deletions(-) (limited to 'mesalib/src/glsl/glcpp/glcpp-parse.y') diff --git a/mesalib/src/glsl/glcpp/glcpp-parse.y b/mesalib/src/glsl/glcpp/glcpp-parse.y index 084078eb0..a61697394 100644 --- a/mesalib/src/glsl/glcpp/glcpp-parse.y +++ b/mesalib/src/glsl/glcpp/glcpp-parse.y @@ -57,6 +57,9 @@ _string_list_append_item (string_list_t *list, const char *str); static int _string_list_contains (string_list_t *list, const char *member, int *index); +static const char * +_string_list_has_duplicate (string_list_t *list); + static int _string_list_length (string_list_t *list); @@ -105,18 +108,25 @@ _parser_active_list_pop (glcpp_parser_t *parser); static int _parser_active_list_contains (glcpp_parser_t *parser, const char *identifier); +typedef enum { + EXPANSION_MODE_IGNORE_DEFINED, + EXPANSION_MODE_EVALUATE_DEFINED +} expansion_mode_t; + /* Expand list, and begin lexing from the result (after first * prefixing a token of type 'head_token_type'). */ static void _glcpp_parser_expand_and_lex_from (glcpp_parser_t *parser, int head_token_type, - token_list_t *list); + token_list_t *list, + expansion_mode_t mode); /* Perform macro expansion in-place on the given list. */ static void _glcpp_parser_expand_token_list (glcpp_parser_t *parser, - token_list_t *list); + token_list_t *list, + expansion_mode_t mode); static void _glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser, @@ -164,14 +174,18 @@ 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 + + /* We use HASH_TOKEN, DEFINE_TOKEN and VERSION_TOKEN (as opposed to + * HASH, DEFINE, and VERSION) to avoid conflicts with other symbols, + * (such as the and start conditions in the lexer). */ +%token DEFINED ELIF_EXPANDED HASH_TOKEN DEFINE_TOKEN FUNC_IDENTIFIER OBJ_IDENTIFIER ELIF ELSE ENDIF ERROR_TOKEN IF IFDEF IFNDEF LINE PRAGMA UNDEF VERSION_TOKEN GARBAGE IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE PLUS_PLUS MINUS_MINUS %token PASTE %type INTEGER operator SPACE integer_constant %type expression -%type IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER +%type IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER ERROR_TOKEN PRAGMA %type identifier_list -%type preprocessing_token conditional_token -%type pp_tokens replacement_list text_line conditional_tokens +%type preprocessing_token +%type pp_tokens replacement_list text_line %left OR %left AND %left '|' @@ -184,6 +198,8 @@ add_builtin_define(glcpp_parser_t *parser, const char *name, int value); %left '*' '/' '%' %right UNARY +%debug + %% input: @@ -192,27 +208,14 @@ input: ; line: - control_line { - ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n"); - } -| HASH_LINE { - glcpp_parser_resolve_implicit_version(parser); - } pp_tokens NEWLINE { - - if (parser->skip_stack == NULL || - parser->skip_stack->type == SKIP_NO_SKIP) - { - _glcpp_parser_expand_and_lex_from (parser, - LINE_EXPANDED, $3); - } - } + control_line +| SPACE control_line | text_line { _glcpp_parser_print_expanded_token_list (parser, $1); ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n"); ralloc_free ($1); } | expanded_line -| HASH non_directive ; expanded_line: @@ -259,29 +262,48 @@ define: ; control_line: - HASH_DEFINE { + control_line_success { + ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n"); + } +| control_line_error +| HASH_TOKEN LINE { + glcpp_parser_resolve_implicit_version(parser); + } pp_tokens NEWLINE { + + if (parser->skip_stack == NULL || + parser->skip_stack->type == SKIP_NO_SKIP) + { + _glcpp_parser_expand_and_lex_from (parser, + LINE_EXPANDED, $4, + EXPANSION_MODE_IGNORE_DEFINED); + } + } +; + +control_line_success: + HASH_TOKEN DEFINE_TOKEN { glcpp_parser_resolve_implicit_version(parser); } define -| HASH_UNDEF { +| HASH_TOKEN UNDEF { glcpp_parser_resolve_implicit_version(parser); } IDENTIFIER NEWLINE { macro_t *macro; - if (strcmp("__LINE__", $3) == 0 - || strcmp("__FILE__", $3) == 0 - || strcmp("__VERSION__", $3) == 0) + if (strcmp("__LINE__", $4) == 0 + || strcmp("__FILE__", $4) == 0 + || strcmp("__VERSION__", $4) == 0) glcpp_error(& @1, parser, "Built-in (pre-defined)" " macro names can not be undefined."); - macro = hash_table_find (parser->defines, $3); + macro = hash_table_find (parser->defines, $4); if (macro) { - hash_table_remove (parser->defines, $3); + hash_table_remove (parser->defines, $4); ralloc_free (macro); } - ralloc_free ($3); + ralloc_free ($4); } -| HASH_IF { +| HASH_TOKEN IF { glcpp_parser_resolve_implicit_version(parser); - } conditional_tokens NEWLINE { + } pp_tokens NEWLINE { /* Be careful to only evaluate the 'if' expression if * we are not skipping. When we are skipping, we * simply push a new 0-valued 'if' onto the skip @@ -293,7 +315,8 @@ control_line: parser->skip_stack->type == SKIP_NO_SKIP) { _glcpp_parser_expand_and_lex_from (parser, - IF_EXPANDED, $3); + IF_EXPANDED, $4, + EXPANSION_MODE_EVALUATE_DEFINED); } else { @@ -301,7 +324,7 @@ control_line: parser->skip_stack->type = SKIP_TO_ENDIF; } } -| HASH_IF NEWLINE { +| HASH_TOKEN IF NEWLINE { /* #if without an expression is only an error if we * are not skipping */ if (parser->skip_stack == NULL || @@ -311,21 +334,21 @@ control_line: } _glcpp_parser_skip_stack_push_if (parser, & @1, 0); } -| HASH_IFDEF { +| HASH_TOKEN IFDEF { glcpp_parser_resolve_implicit_version(parser); } IDENTIFIER junk NEWLINE { - macro_t *macro = hash_table_find (parser->defines, $3); - ralloc_free ($3); + macro_t *macro = hash_table_find (parser->defines, $4); + ralloc_free ($4); _glcpp_parser_skip_stack_push_if (parser, & @1, macro != NULL); } -| HASH_IFNDEF { +| HASH_TOKEN IFNDEF { glcpp_parser_resolve_implicit_version(parser); } IDENTIFIER junk NEWLINE { - macro_t *macro = hash_table_find (parser->defines, $3); - ralloc_free ($3); - _glcpp_parser_skip_stack_push_if (parser, & @2, macro == NULL); + macro_t *macro = hash_table_find (parser->defines, $4); + ralloc_free ($4); + _glcpp_parser_skip_stack_push_if (parser, & @3, macro == NULL); } -| HASH_ELIF conditional_tokens NEWLINE { +| HASH_TOKEN ELIF pp_tokens NEWLINE { /* Be careful to only evaluate the 'elif' expression * if we are not skipping. When we are skipping, we * simply change to a 0-valued 'elif' on the skip @@ -337,7 +360,8 @@ control_line: parser->skip_stack->type == SKIP_TO_ELSE) { _glcpp_parser_expand_and_lex_from (parser, - ELIF_EXPANDED, $2); + ELIF_EXPANDED, $3, + EXPANSION_MODE_EVALUATE_DEFINED); } else if (parser->skip_stack && parser->skip_stack->has_else) @@ -350,7 +374,7 @@ control_line: "elif", 0); } } -| HASH_ELIF NEWLINE { +| HASH_TOKEN ELIF NEWLINE { /* #elif without an expression is an error unless we * are skipping. */ if (parser->skip_stack && @@ -370,7 +394,7 @@ control_line: glcpp_warning(& @1, parser, "ignoring illegal #elif without expression"); } } -| HASH_ELSE { parser->lexing_directive = 1; } NEWLINE { +| HASH_TOKEN ELSE { parser->lexing_directive = 1; } NEWLINE { if (parser->skip_stack && parser->skip_stack->has_else) { @@ -383,24 +407,39 @@ control_line: parser->skip_stack->has_else = true; } } -| HASH_ENDIF { +| HASH_TOKEN ENDIF { _glcpp_parser_skip_stack_pop (parser, & @1); } NEWLINE -| HASH_VERSION integer_constant NEWLINE { +| HASH_TOKEN VERSION_TOKEN integer_constant NEWLINE { if (parser->version_resolved) { glcpp_error(& @1, parser, "#version must appear on the first line"); } - _glcpp_parser_handle_version_declaration(parser, $2, NULL, true); + _glcpp_parser_handle_version_declaration(parser, $3, NULL, true); } -| HASH_VERSION integer_constant IDENTIFIER NEWLINE { +| HASH_TOKEN VERSION_TOKEN integer_constant IDENTIFIER NEWLINE { if (parser->version_resolved) { glcpp_error(& @1, parser, "#version must appear on the first line"); } - _glcpp_parser_handle_version_declaration(parser, $2, $3, true); + _glcpp_parser_handle_version_declaration(parser, $3, $4, true); } -| HASH NEWLINE { +| HASH_TOKEN NEWLINE { glcpp_parser_resolve_implicit_version(parser); } +| HASH_TOKEN PRAGMA NEWLINE { + ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "#%s", $2); + } +; + +control_line_error: + HASH_TOKEN ERROR_TOKEN NEWLINE { + glcpp_error(& @1, parser, "#%s", $2); + } +| HASH_TOKEN DEFINE_TOKEN NEWLINE { + glcpp_error (& @1, parser, "#define without macro name"); + } +| HASH_TOKEN GARBAGE pp_tokens NEWLINE { + glcpp_error (& @1, parser, "Illegal non-directive after #"); + } ; integer_constant: @@ -612,12 +651,6 @@ text_line: | pp_tokens NEWLINE ; -non_directive: - pp_tokens NEWLINE { - yyerror (& @1, parser, "Invalid tokens after #"); - } -; - replacement_list: /* empty */ { $$ = NULL; } | pp_tokens @@ -630,31 +663,6 @@ junk: } ; -conditional_token: - /* Handle "defined" operator */ - DEFINED IDENTIFIER { - int v = hash_table_find (parser->defines, $2) ? 1 : 0; - $$ = _token_create_ival (parser, INTEGER, v); - } -| DEFINED '(' IDENTIFIER ')' { - int v = hash_table_find (parser->defines, $3) ? 1 : 0; - $$ = _token_create_ival (parser, INTEGER, v); - } -| preprocessing_token -; - -conditional_tokens: - /* Exactly the same as pp_tokens, but using conditional_token */ - conditional_token { - $$ = _token_list_create (parser); - _token_list_append ($$, $1); - } -| conditional_tokens conditional_token { - $$ = $1; - _token_list_append ($$, $2); - } -; - pp_tokens: preprocessing_token { parser->space_tokens = 1; @@ -680,6 +688,10 @@ preprocessing_token: $$ = _token_create_ival (parser, $1, $1); $$->location = yylloc; } +| DEFINED { + $$ = _token_create_ival (parser, DEFINED, DEFINED); + $$->location = yylloc; + } | OTHER { $$ = _token_create_str (parser, OTHER, $1); $$->location = yylloc; @@ -722,6 +734,8 @@ operator: | ',' { $$ = ','; } | '=' { $$ = '='; } | PASTE { $$ = PASTE; } +| PLUS_PLUS { $$ = PLUS_PLUS; } +| MINUS_MINUS { $$ = MINUS_MINUS; } ; %% @@ -777,6 +791,25 @@ _string_list_contains (string_list_t *list, const char *member, int *index) return 0; } +/* Return duplicate string in list (if any), NULL otherwise. */ +const char * +_string_list_has_duplicate (string_list_t *list) +{ + string_node_t *node, *dup; + + if (list == NULL) + return NULL; + + for (node = list->head; node; node = node->next) { + for (dup = node->next; dup; dup = dup->next) { + if (strcmp (node->str, dup->str) == 0) + return node->str; + } + } + + return NULL; +} + int _string_list_length (string_list_t *list) { @@ -1123,14 +1156,21 @@ _token_print (char **out, size_t *len, token_t *token) case PASTE: ralloc_asprintf_rewrite_tail (out, len, "##"); break; - case COMMA_FINAL: - ralloc_asprintf_rewrite_tail (out, len, ","); + case PLUS_PLUS: + ralloc_asprintf_rewrite_tail (out, len, "++"); + break; + case MINUS_MINUS: + ralloc_asprintf_rewrite_tail (out, len, "--"); + break; + case DEFINED: + ralloc_asprintf_rewrite_tail (out, len, "defined"); break; case PLACEHOLDER: /* Nothing to print. */ break; default: assert(!"Error: Don't know how to print token."); + break; } } @@ -1308,12 +1348,16 @@ glcpp_parser_create (const struct gl_extensions *extensions, gl_api api) parser->active = NULL; parser->lexing_directive = 0; parser->space_tokens = 1; + parser->last_token_was_newline = 0; + parser->last_token_was_space = 0; + parser->first_non_space_token_this_line = 1; parser->newline_as_space = 0; parser->in_control_line = 0; parser->paren_count = 0; parser->commented_newlines = 0; parser->skip_stack = NULL; + parser->skipping = 0; parser->lex_from_list = NULL; parser->lex_from_node = NULL; @@ -1459,15 +1503,143 @@ _token_list_create_with_one_integer (void *ctx, int ival) return _token_list_create_with_one_ival (ctx, INTEGER, ival); } +/* Evaluate a DEFINED token node (based on subsequent tokens in the list). + * + * Note: This function must only be called when "node" is a DEFINED token, + * (and will abort with an assertion failure otherwise). + * + * If "node" is followed, (ignoring any SPACE tokens), by an IDENTIFIER token + * (optionally preceded and followed by '(' and ')' tokens) then the following + * occurs: + * + * If the identifier is a defined macro, this function returns 1. + * + * If the identifier is not a defined macro, this function returns 0. + * + * In either case, *last will be updated to the last node in the list + * consumed by the evaluation, (either the token of the identifier or the + * token of the closing parenthesis). + * + * In all other cases, (such as "node is the final node of the list", or + * "missing closing parenthesis", etc.), this function generates a + * preprocessor error, returns -1 and *last will not be set. + */ +static int +_glcpp_parser_evaluate_defined (glcpp_parser_t *parser, + token_node_t *node, + token_node_t **last) +{ + token_node_t *argument, *defined = node; + + assert (node->token->type == DEFINED); + + node = node->next; + + /* Ignore whitespace after DEFINED token. */ + while (node && node->token->type == SPACE) + node = node->next; + + if (node == NULL) + goto FAIL; + + if (node->token->type == IDENTIFIER || node->token->type == OTHER) { + argument = node; + } else if (node->token->type == '(') { + node = node->next; + + /* Ignore whitespace after '(' token. */ + while (node && node->token->type == SPACE) + node = node->next; + + if (node == NULL || (node->token->type != IDENTIFIER && + node->token->type != OTHER)) + { + goto FAIL; + } + + argument = node; + + node = node->next; + + /* Ignore whitespace after identifier, before ')' token. */ + while (node && node->token->type == SPACE) + node = node->next; + + if (node == NULL || node->token->type != ')') + goto FAIL; + } else { + goto FAIL; + } + + *last = node; + + return hash_table_find (parser->defines, + argument->token->value.str) ? 1 : 0; + +FAIL: + glcpp_error (&defined->token->location, parser, + "\"defined\" not followed by an identifier"); + return -1; +} + +/* Evaluate all DEFINED nodes in a given list, modifying the list in place. + */ +static void +_glcpp_parser_evaluate_defined_in_list (glcpp_parser_t *parser, + token_list_t *list) +{ + token_node_t *node, *node_prev, *replacement, *last = NULL; + int value; + + if (list == NULL) + return; + + node_prev = NULL; + node = list->head; + + while (node) { + + if (node->token->type != DEFINED) + goto NEXT; + + value = _glcpp_parser_evaluate_defined (parser, node, &last); + if (value == -1) + goto NEXT; + + replacement = ralloc (list, token_node_t); + replacement->token = _token_create_ival (list, INTEGER, value); + + /* Splice replacement node into list, replacing from "node" + * through "last". */ + if (node_prev) + node_prev->next = replacement; + else + list->head = replacement; + replacement->next = last->next; + if (last == list->tail) + list->tail = replacement; + + node = replacement; + + NEXT: + node_prev = node; + node = node->next; + } +} + /* Perform macro expansion on 'list', placing the resulting tokens * into a new list which is initialized with a first token of type * 'head_token_type'. Then begin lexing from the resulting list, * (return to the current lexing source when this list is exhausted). + * + * See the documentation of _glcpp_parser_expand_token_list for a description + * of the "mode" parameter. */ static void _glcpp_parser_expand_and_lex_from (glcpp_parser_t *parser, int head_token_type, - token_list_t *list) + token_list_t *list, + expansion_mode_t mode) { token_list_t *expanded; token_t *token; @@ -1475,7 +1647,7 @@ _glcpp_parser_expand_and_lex_from (glcpp_parser_t *parser, expanded = _token_list_create (parser); token = _token_create_ival (parser, head_token_type, head_token_type); _token_list_append (expanded, token); - _glcpp_parser_expand_token_list (parser, list); + _glcpp_parser_expand_token_list (parser, list, mode); _token_list_append_list (expanded, list); glcpp_parser_lex_from (parser, expanded); } @@ -1538,12 +1710,15 @@ _glcpp_parser_apply_pastes (glcpp_parser_t *parser, token_list_t *list) * *last to the last node in the list that was consumed by the * expansion. Specifically, *last will be set as follows: as the * token of the closing right parenthesis. + * + * See the documentation of _glcpp_parser_expand_token_list for a description + * of the "mode" parameter. */ static token_list_t * _glcpp_parser_expand_function (glcpp_parser_t *parser, token_node_t *node, - token_node_t **last) - + token_node_t **last, + expansion_mode_t mode) { macro_t *macro; const char *identifier; @@ -1612,7 +1787,8 @@ _glcpp_parser_expand_function (glcpp_parser_t *parser, expanded_argument = _token_list_copy (parser, argument); _glcpp_parser_expand_token_list (parser, - expanded_argument); + expanded_argument, + mode); _token_list_append_list (substituted, expanded_argument); } else { @@ -1652,11 +1828,15 @@ _glcpp_parser_expand_function (glcpp_parser_t *parser, * * As the token of the closing right parenthesis in the case of * function-like macro expansion. + * + * See the documentation of _glcpp_parser_expand_token_list for a description + * of the "mode" parameter. */ static token_list_t * _glcpp_parser_expand_node (glcpp_parser_t *parser, token_node_t *node, - token_node_t **last) + token_node_t **last, + expansion_mode_t mode) { token_t *token = node->token; const char *identifier; @@ -1664,14 +1844,6 @@ _glcpp_parser_expand_node (glcpp_parser_t *parser, /* We only expand identifiers */ if (token->type != IDENTIFIER) { - /* We change any COMMA into a COMMA_FINAL to prevent - * it being mistaken for an argument separator - * later. */ - if (token->type == ',') { - token->type = COMMA_FINAL; - token->value.ival = COMMA_FINAL; - } - return NULL; } @@ -1723,7 +1895,7 @@ _glcpp_parser_expand_node (glcpp_parser_t *parser, return replacement; } - return _glcpp_parser_expand_function (parser, node, last); + return _glcpp_parser_expand_function (parser, node, last, mode); } /* Push a new identifier onto the parser's active list. @@ -1782,11 +1954,28 @@ _parser_active_list_contains (glcpp_parser_t *parser, const char *identifier) /* Walk over the token list replacing nodes with their expansion. * Whenever nodes are expanded the walking will walk over the new * nodes, continuing to expand as necessary. The results are placed in - * 'list' itself; + * 'list' itself. + * + * The "mode" argument controls the handling of any DEFINED tokens that + * result from expansion as follows: + * + * EXPANSION_MODE_IGNORE_DEFINED: Any resulting DEFINED tokens will be + * left in the final list, unevaluated. This is the correct mode + * for expanding any list in any context other than a + * preprocessor conditional, (#if or #elif). + * + * EXPANSION_MODE_EVALUATE_DEFINED: Any resulting DEFINED tokens will be + * evaluated to 0 or 1 tokens depending on whether the following + * token is the name of a defined macro. If the DEFINED token is + * not followed by an (optionally parenthesized) identifier, then + * an error will be generated. This the correct mode for + * expanding any list in the context of a preprocessor + * conditional, (#if or #elif). */ static void _glcpp_parser_expand_token_list (glcpp_parser_t *parser, - token_list_t *list) + token_list_t *list, + expansion_mode_t mode) { token_node_t *node_prev; token_node_t *node, *last = NULL; @@ -1801,15 +1990,23 @@ _glcpp_parser_expand_token_list (glcpp_parser_t *parser, node_prev = NULL; node = list->head; + if (mode == EXPANSION_MODE_EVALUATE_DEFINED) + _glcpp_parser_evaluate_defined_in_list (parser, list); + while (node) { while (parser->active && parser->active->marker == node) _parser_active_list_pop (parser); - expansion = _glcpp_parser_expand_node (parser, node, &last); + expansion = _glcpp_parser_expand_node (parser, node, &last, mode); if (expansion) { token_node_t *n; + if (mode == EXPANSION_MODE_EVALUATE_DEFINED) { + _glcpp_parser_evaluate_defined_in_list (parser, + expansion); + } + for (n = node; n != last->next; n = n->next) while (parser->active && parser->active->marker == n) @@ -1862,7 +2059,7 @@ _glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser, if (list == NULL) return; - _glcpp_parser_expand_token_list (parser, list); + _glcpp_parser_expand_token_list (parser, list, EXPANSION_MODE_IGNORE_DEFINED); _token_list_trim_trailing_space (list); @@ -1923,6 +2120,10 @@ _define_object_macro (glcpp_parser_t *parser, { macro_t *macro, *previous; + /* We define pre-defined macros before we've started parsing the + * actual file. So if there's no location defined yet, that's what + * were doing and we don't want to generate an error for using the + * reserved names. */ if (loc != NULL) _check_for_reserved_macro_name(parser, loc, identifier); @@ -1955,9 +2156,16 @@ _define_function_macro (glcpp_parser_t *parser, token_list_t *replacements) { macro_t *macro, *previous; + const char *dup; _check_for_reserved_macro_name(parser, loc, identifier); + /* Check for any duplicate parameter names. */ + if ((dup = _string_list_has_duplicate (parameters)) != NULL) { + glcpp_error (loc, parser, "Duplicate macro parameter \"%s\"", + dup); + } + macro = ralloc (parser, macro_t); ralloc_steal (macro, parameters); ralloc_steal (macro, replacements); @@ -2020,11 +2228,11 @@ glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser) if (ret == NEWLINE) parser->in_control_line = 0; } - else if (ret == HASH_DEFINE || - ret == HASH_UNDEF || ret == HASH_IF || - ret == HASH_IFDEF || ret == HASH_IFNDEF || - ret == HASH_ELIF || ret == HASH_ELSE || - ret == HASH_ENDIF || ret == HASH) + else if (ret == DEFINE_TOKEN || + ret == UNDEF || ret == IF || + ret == IFDEF || ret == IFNDEF || + ret == ELIF || ret == ELSE || + ret == ENDIF || ret == HASH_TOKEN) { parser->in_control_line = 1; } @@ -2117,7 +2325,7 @@ _glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc, const char *type, int condition) { if (parser->skip_stack == NULL) { - glcpp_error (loc, parser, "%s without #if\n", type); + glcpp_error (loc, parser, "#%s without #if\n", type); return; } @@ -2170,6 +2378,8 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio if (extensions != NULL) { if (extensions->OES_EGL_image_external) add_builtin_define(parser, "GL_OES_EGL_image_external", 1); + if (extensions->OES_standard_derivatives) + add_builtin_define(parser, "GL_OES_standard_derivatives", 1); } } else { add_builtin_define(parser, "GL_ARB_draw_buffers", 1); -- cgit v1.2.3