Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. %{
  2. /*
  3.  * Copyright © 2010 Intel Corporation
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the "Software"),
  7.  * to deal in the Software without restriction, including without limitation
  8.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9.  * and/or sell copies of the Software, and to permit persons to whom the
  10.  * Software is furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the next
  13.  * paragraph) shall be included in all copies or substantial portions of the
  14.  * Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22.  * DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <assert.h>
  29. #include <inttypes.h>
  30.  
  31. #include "glcpp.h"
  32. #include "main/core.h" /* for struct gl_extensions */
  33. #include "main/mtypes.h" /* for gl_api enum */
  34.  
  35. static void
  36. yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error);
  37.  
  38. static void
  39. _define_object_macro (glcpp_parser_t *parser,
  40.                       YYLTYPE *loc,
  41.                       const char *macro,
  42.                       token_list_t *replacements);
  43.  
  44. static void
  45. _define_function_macro (glcpp_parser_t *parser,
  46.                         YYLTYPE *loc,
  47.                         const char *macro,
  48.                         string_list_t *parameters,
  49.                         token_list_t *replacements);
  50.  
  51. static string_list_t *
  52. _string_list_create (void *ctx);
  53.  
  54. static void
  55. _string_list_append_item (string_list_t *list, const char *str);
  56.  
  57. static int
  58. _string_list_contains (string_list_t *list, const char *member, int *index);
  59.  
  60. static int
  61. _string_list_length (string_list_t *list);
  62.  
  63. static int
  64. _string_list_equal (string_list_t *a, string_list_t *b);
  65.  
  66. static argument_list_t *
  67. _argument_list_create (void *ctx);
  68.  
  69. static void
  70. _argument_list_append (argument_list_t *list, token_list_t *argument);
  71.  
  72. static int
  73. _argument_list_length (argument_list_t *list);
  74.  
  75. static token_list_t *
  76. _argument_list_member_at (argument_list_t *list, int index);
  77.  
  78. /* Note: This function ralloc_steal()s the str pointer. */
  79. static token_t *
  80. _token_create_str (void *ctx, int type, char *str);
  81.  
  82. static token_t *
  83. _token_create_ival (void *ctx, int type, int ival);
  84.  
  85. static token_list_t *
  86. _token_list_create (void *ctx);
  87.  
  88. static void
  89. _token_list_append (token_list_t *list, token_t *token);
  90.  
  91. static void
  92. _token_list_append_list (token_list_t *list, token_list_t *tail);
  93.  
  94. static int
  95. _token_list_equal_ignoring_space (token_list_t *a, token_list_t *b);
  96.  
  97. static void
  98. _parser_active_list_push (glcpp_parser_t *parser,
  99.                           const char *identifier,
  100.                           token_node_t *marker);
  101.  
  102. static void
  103. _parser_active_list_pop (glcpp_parser_t *parser);
  104.  
  105. static int
  106. _parser_active_list_contains (glcpp_parser_t *parser, const char *identifier);
  107.  
  108. /* Expand list, and begin lexing from the result (after first
  109.  * prefixing a token of type 'head_token_type').
  110.  */
  111. static void
  112. _glcpp_parser_expand_and_lex_from (glcpp_parser_t *parser,
  113.                                    int head_token_type,
  114.                                    token_list_t *list);
  115.  
  116. /* Perform macro expansion in-place on the given list. */
  117. static void
  118. _glcpp_parser_expand_token_list (glcpp_parser_t *parser,
  119.                                  token_list_t *list);
  120.  
  121. static void
  122. _glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser,
  123.                                          token_list_t *list);
  124.  
  125. static void
  126. _glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc,
  127.                                   int condition);
  128.  
  129. static void
  130. _glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc,
  131.                                     const char *type, int condition);
  132.  
  133. static void
  134. _glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc);
  135.  
  136. static void
  137. _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version,
  138.                                          const char *ident);
  139.  
  140. static int
  141. glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser);
  142.  
  143. static void
  144. glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list);
  145.  
  146. static void
  147. add_builtin_define(glcpp_parser_t *parser, const char *name, int value);
  148.  
  149. %}
  150.  
  151. %pure-parser
  152. %error-verbose
  153.  
  154. %locations
  155. %initial-action {
  156.         @$.first_line = 1;
  157.         @$.first_column = 1;
  158.         @$.last_line = 1;
  159.         @$.last_column = 1;
  160.         @$.source = 0;
  161. }
  162.  
  163. %parse-param {glcpp_parser_t *parser}
  164. %lex-param {glcpp_parser_t *parser}
  165.  
  166. %expect 0
  167. %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
  168. %token PASTE
  169. %type <ival> expression INTEGER operator SPACE integer_constant
  170. %type <str> IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER
  171. %type <string_list> identifier_list
  172. %type <token> preprocessing_token conditional_token
  173. %type <token_list> pp_tokens replacement_list text_line conditional_tokens
  174. %left OR
  175. %left AND
  176. %left '|'
  177. %left '^'
  178. %left '&'
  179. %left EQUAL NOT_EQUAL
  180. %left '<' '>' LESS_OR_EQUAL GREATER_OR_EQUAL
  181. %left LEFT_SHIFT RIGHT_SHIFT
  182. %left '+' '-'
  183. %left '*' '/' '%'
  184. %right UNARY
  185.  
  186. %%
  187.  
  188. input:
  189.         /* empty */
  190. |       input line
  191. ;
  192.  
  193. line:
  194.         control_line {
  195.                 ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n");
  196.         }
  197. |       HASH_LINE pp_tokens NEWLINE {
  198.                 if (parser->skip_stack == NULL ||
  199.                     parser->skip_stack->type == SKIP_NO_SKIP)
  200.                 {
  201.                         _glcpp_parser_expand_and_lex_from (parser,
  202.                                                            LINE_EXPANDED, $2);
  203.                 }
  204.         }
  205. |       text_line {
  206.                 _glcpp_parser_print_expanded_token_list (parser, $1);
  207.                 ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n");
  208.                 ralloc_free ($1);
  209.         }
  210. |       expanded_line
  211. |       HASH non_directive
  212. ;
  213.  
  214. expanded_line:
  215.         IF_EXPANDED expression NEWLINE {
  216.                 _glcpp_parser_skip_stack_push_if (parser, & @1, $2);
  217.         }
  218. |       ELIF_EXPANDED expression NEWLINE {
  219.                 _glcpp_parser_skip_stack_change_if (parser, & @1, "elif", $2);
  220.         }
  221. |       LINE_EXPANDED integer_constant NEWLINE {
  222.                 parser->has_new_line_number = 1;
  223.                 parser->new_line_number = $2;
  224.                 ralloc_asprintf_rewrite_tail (&parser->output,
  225.                                               &parser->output_length,
  226.                                               "#line %" PRIiMAX "\n",
  227.                                               $2);
  228.         }
  229. |       LINE_EXPANDED integer_constant integer_constant NEWLINE {
  230.                 parser->has_new_line_number = 1;
  231.                 parser->new_line_number = $2;
  232.                 parser->has_new_source_number = 1;
  233.                 parser->new_source_number = $3;
  234.                 ralloc_asprintf_rewrite_tail (&parser->output,
  235.                                               &parser->output_length,
  236.                                               "#line %" PRIiMAX " %" PRIiMAX "\n",
  237.                                               $2, $3);
  238.         }
  239. ;
  240.  
  241. control_line:
  242.         HASH_DEFINE OBJ_IDENTIFIER replacement_list NEWLINE {
  243.                 _define_object_macro (parser, & @2, $2, $3);
  244.         }
  245. |       HASH_DEFINE FUNC_IDENTIFIER '(' ')' replacement_list NEWLINE {
  246.                 _define_function_macro (parser, & @2, $2, NULL, $5);
  247.         }
  248. |       HASH_DEFINE FUNC_IDENTIFIER '(' identifier_list ')' replacement_list NEWLINE {
  249.                 _define_function_macro (parser, & @2, $2, $4, $6);
  250.         }
  251. |       HASH_UNDEF IDENTIFIER NEWLINE {
  252.                 macro_t *macro = hash_table_find (parser->defines, $2);
  253.                 if (macro) {
  254.                         hash_table_remove (parser->defines, $2);
  255.                         ralloc_free (macro);
  256.                 }
  257.                 ralloc_free ($2);
  258.         }
  259. |       HASH_IF conditional_tokens NEWLINE {
  260.                 /* Be careful to only evaluate the 'if' expression if
  261.                  * we are not skipping. When we are skipping, we
  262.                  * simply push a new 0-valued 'if' onto the skip
  263.                  * stack.
  264.                  *
  265.                  * This avoids generating diagnostics for invalid
  266.                  * expressions that are being skipped. */
  267.                 if (parser->skip_stack == NULL ||
  268.                     parser->skip_stack->type == SKIP_NO_SKIP)
  269.                 {
  270.                         _glcpp_parser_expand_and_lex_from (parser,
  271.                                                            IF_EXPANDED, $2);
  272.                 }      
  273.                 else
  274.                 {
  275.                         _glcpp_parser_skip_stack_push_if (parser, & @1, 0);
  276.                         parser->skip_stack->type = SKIP_TO_ENDIF;
  277.                 }
  278.         }
  279. |       HASH_IF NEWLINE {
  280.                 /* #if without an expression is only an error if we
  281.                  *  are not skipping */
  282.                 if (parser->skip_stack == NULL ||
  283.                     parser->skip_stack->type == SKIP_NO_SKIP)
  284.                 {
  285.                         glcpp_error(& @1, parser, "#if with no expression");
  286.                 }      
  287.                 _glcpp_parser_skip_stack_push_if (parser, & @1, 0);
  288.         }
  289. |       HASH_IFDEF IDENTIFIER junk NEWLINE {
  290.                 macro_t *macro = hash_table_find (parser->defines, $2);
  291.                 ralloc_free ($2);
  292.                 _glcpp_parser_skip_stack_push_if (parser, & @1, macro != NULL);
  293.         }
  294. |       HASH_IFNDEF IDENTIFIER junk NEWLINE {
  295.                 macro_t *macro = hash_table_find (parser->defines, $2);
  296.                 ralloc_free ($2);
  297.                 _glcpp_parser_skip_stack_push_if (parser, & @1, macro == NULL);
  298.         }
  299. |       HASH_ELIF conditional_tokens NEWLINE {
  300.                 /* Be careful to only evaluate the 'elif' expression
  301.                  * if we are not skipping. When we are skipping, we
  302.                  * simply change to a 0-valued 'elif' on the skip
  303.                  * stack.
  304.                  *
  305.                  * This avoids generating diagnostics for invalid
  306.                  * expressions that are being skipped. */
  307.                 if (parser->skip_stack &&
  308.                     parser->skip_stack->type == SKIP_TO_ELSE)
  309.                 {
  310.                         _glcpp_parser_expand_and_lex_from (parser,
  311.                                                            ELIF_EXPANDED, $2);
  312.                 }
  313.                 else
  314.                 {
  315.                         _glcpp_parser_skip_stack_change_if (parser, & @1,
  316.                                                             "elif", 0);
  317.                 }
  318.         }
  319. |       HASH_ELIF NEWLINE {
  320.                 /* #elif without an expression is an error unless we
  321.                  * are skipping. */
  322.                 if (parser->skip_stack &&
  323.                     parser->skip_stack->type == SKIP_TO_ELSE)
  324.                 {
  325.                         glcpp_error(& @1, parser, "#elif with no expression");
  326.                 }
  327.                 else
  328.                 {
  329.                         _glcpp_parser_skip_stack_change_if (parser, & @1,
  330.                                                             "elif", 0);
  331.                         glcpp_warning(& @1, parser, "ignoring illegal #elif without expression");
  332.                 }
  333.         }
  334. |       HASH_ELSE {
  335.                 _glcpp_parser_skip_stack_change_if (parser, & @1, "else", 1);
  336.         } NEWLINE
  337. |       HASH_ENDIF {
  338.                 _glcpp_parser_skip_stack_pop (parser, & @1);
  339.         } NEWLINE
  340. |       HASH_VERSION integer_constant NEWLINE {
  341.                 _glcpp_parser_handle_version_declaration(parser, $2, NULL);
  342.         }
  343. |       HASH_VERSION integer_constant IDENTIFIER NEWLINE {
  344.                 _glcpp_parser_handle_version_declaration(parser, $2, $3);
  345.         }
  346. |       HASH NEWLINE
  347. ;
  348.  
  349. integer_constant:
  350.         INTEGER_STRING {
  351.                 if (strlen ($1) >= 3 && strncmp ($1, "0x", 2) == 0) {
  352.                         $$ = strtoll ($1 + 2, NULL, 16);
  353.                 } else if ($1[0] == '0') {
  354.                         $$ = strtoll ($1, NULL, 8);
  355.                 } else {
  356.                         $$ = strtoll ($1, NULL, 10);
  357.                 }
  358.         }
  359. |       INTEGER {
  360.                 $$ = $1;
  361.         }
  362.  
  363. expression:
  364.         integer_constant
  365. |       IDENTIFIER {
  366.                 if (parser->is_gles)
  367.                         glcpp_error(& @1, parser, "undefined macro %s in expression (illegal in GLES)", $1);
  368.                 $$ = 0;
  369.         }
  370. |       expression OR expression {
  371.                 $$ = $1 || $3;
  372.         }
  373. |       expression AND expression {
  374.                 $$ = $1 && $3;
  375.         }
  376. |       expression '|' expression {
  377.                 $$ = $1 | $3;
  378.         }
  379. |       expression '^' expression {
  380.                 $$ = $1 ^ $3;
  381.         }
  382. |       expression '&' expression {
  383.                 $$ = $1 & $3;
  384.         }
  385. |       expression NOT_EQUAL expression {
  386.                 $$ = $1 != $3;
  387.         }
  388. |       expression EQUAL expression {
  389.                 $$ = $1 == $3;
  390.         }
  391. |       expression GREATER_OR_EQUAL expression {
  392.                 $$ = $1 >= $3;
  393.         }
  394. |       expression LESS_OR_EQUAL expression {
  395.                 $$ = $1 <= $3;
  396.         }
  397. |       expression '>' expression {
  398.                 $$ = $1 > $3;
  399.         }
  400. |       expression '<' expression {
  401.                 $$ = $1 < $3;
  402.         }
  403. |       expression RIGHT_SHIFT expression {
  404.                 $$ = $1 >> $3;
  405.         }
  406. |       expression LEFT_SHIFT expression {
  407.                 $$ = $1 << $3;
  408.         }
  409. |       expression '-' expression {
  410.                 $$ = $1 - $3;
  411.         }
  412. |       expression '+' expression {
  413.                 $$ = $1 + $3;
  414.         }
  415. |       expression '%' expression {
  416.                 if ($3 == 0) {
  417.                         yyerror (& @1, parser,
  418.                                  "zero modulus in preprocessor directive");
  419.                 } else {
  420.                         $$ = $1 % $3;
  421.                 }
  422.         }
  423. |       expression '/' expression {
  424.                 if ($3 == 0) {
  425.                         yyerror (& @1, parser,
  426.                                  "division by 0 in preprocessor directive");
  427.                 } else {
  428.                         $$ = $1 / $3;
  429.                 }
  430.         }
  431. |       expression '*' expression {
  432.                 $$ = $1 * $3;
  433.         }
  434. |       '!' expression %prec UNARY {
  435.                 $$ = ! $2;
  436.         }
  437. |       '~' expression %prec UNARY {
  438.                 $$ = ~ $2;
  439.         }
  440. |       '-' expression %prec UNARY {
  441.                 $$ = - $2;
  442.         }
  443. |       '+' expression %prec UNARY {
  444.                 $$ = + $2;
  445.         }
  446. |       '(' expression ')' {
  447.                 $$ = $2;
  448.         }
  449. ;
  450.  
  451. identifier_list:
  452.         IDENTIFIER {
  453.                 $$ = _string_list_create (parser);
  454.                 _string_list_append_item ($$, $1);
  455.                 ralloc_steal ($$, $1);
  456.         }
  457. |       identifier_list ',' IDENTIFIER {
  458.                 $$ = $1;       
  459.                 _string_list_append_item ($$, $3);
  460.                 ralloc_steal ($$, $3);
  461.         }
  462. ;
  463.  
  464. text_line:
  465.         NEWLINE { $$ = NULL; }
  466. |       pp_tokens NEWLINE
  467. ;
  468.  
  469. non_directive:
  470.         pp_tokens NEWLINE {
  471.                 yyerror (& @1, parser, "Invalid tokens after #");
  472.         }
  473. ;
  474.  
  475. replacement_list:
  476.         /* empty */ { $$ = NULL; }
  477. |       pp_tokens
  478. ;
  479.  
  480. junk:
  481.         /* empty */
  482. |       pp_tokens {
  483.                 glcpp_warning(&@1, parser, "extra tokens at end of directive");
  484.         }
  485. ;
  486.  
  487. conditional_token:
  488.         /* Handle "defined" operator */
  489.         DEFINED IDENTIFIER {
  490.                 int v = hash_table_find (parser->defines, $2) ? 1 : 0;
  491.                 $$ = _token_create_ival (parser, INTEGER, v);
  492.         }
  493. |       DEFINED '(' IDENTIFIER ')' {
  494.                 int v = hash_table_find (parser->defines, $3) ? 1 : 0;
  495.                 $$ = _token_create_ival (parser, INTEGER, v);
  496.         }
  497. |       preprocessing_token
  498. ;
  499.  
  500. conditional_tokens:
  501.         /* Exactly the same as pp_tokens, but using conditional_token */
  502.         conditional_token {
  503.                 $$ = _token_list_create (parser);
  504.                 _token_list_append ($$, $1);
  505.         }
  506. |       conditional_tokens conditional_token {
  507.                 $$ = $1;
  508.                 _token_list_append ($$, $2);
  509.         }
  510. ;
  511.  
  512. pp_tokens:
  513.         preprocessing_token {
  514.                 parser->space_tokens = 1;
  515.                 $$ = _token_list_create (parser);
  516.                 _token_list_append ($$, $1);
  517.         }
  518. |       pp_tokens preprocessing_token {
  519.                 $$ = $1;
  520.                 _token_list_append ($$, $2);
  521.         }
  522. ;
  523.  
  524. preprocessing_token:
  525.         IDENTIFIER {
  526.                 $$ = _token_create_str (parser, IDENTIFIER, $1);
  527.                 $$->location = yylloc;
  528.         }
  529. |       INTEGER_STRING {
  530.                 $$ = _token_create_str (parser, INTEGER_STRING, $1);
  531.                 $$->location = yylloc;
  532.         }
  533. |       operator {
  534.                 $$ = _token_create_ival (parser, $1, $1);
  535.                 $$->location = yylloc;
  536.         }
  537. |       OTHER {
  538.                 $$ = _token_create_str (parser, OTHER, $1);
  539.                 $$->location = yylloc;
  540.         }
  541. |       SPACE {
  542.                 $$ = _token_create_ival (parser, SPACE, SPACE);
  543.                 $$->location = yylloc;
  544.         }
  545. ;
  546.  
  547. operator:
  548.         '['                     { $$ = '['; }
  549. |       ']'                     { $$ = ']'; }
  550. |       '('                     { $$ = '('; }
  551. |       ')'                     { $$ = ')'; }
  552. |       '{'                     { $$ = '{'; }
  553. |       '}'                     { $$ = '}'; }
  554. |       '.'                     { $$ = '.'; }
  555. |       '&'                     { $$ = '&'; }
  556. |       '*'                     { $$ = '*'; }
  557. |       '+'                     { $$ = '+'; }
  558. |       '-'                     { $$ = '-'; }
  559. |       '~'                     { $$ = '~'; }
  560. |       '!'                     { $$ = '!'; }
  561. |       '/'                     { $$ = '/'; }
  562. |       '%'                     { $$ = '%'; }
  563. |       LEFT_SHIFT              { $$ = LEFT_SHIFT; }
  564. |       RIGHT_SHIFT             { $$ = RIGHT_SHIFT; }
  565. |       '<'                     { $$ = '<'; }
  566. |       '>'                     { $$ = '>'; }
  567. |       LESS_OR_EQUAL           { $$ = LESS_OR_EQUAL; }
  568. |       GREATER_OR_EQUAL        { $$ = GREATER_OR_EQUAL; }
  569. |       EQUAL                   { $$ = EQUAL; }
  570. |       NOT_EQUAL               { $$ = NOT_EQUAL; }
  571. |       '^'                     { $$ = '^'; }
  572. |       '|'                     { $$ = '|'; }
  573. |       AND                     { $$ = AND; }
  574. |       OR                      { $$ = OR; }
  575. |       ';'                     { $$ = ';'; }
  576. |       ','                     { $$ = ','; }
  577. |       '='                     { $$ = '='; }
  578. |       PASTE                   { $$ = PASTE; }
  579. ;
  580.  
  581. %%
  582.  
  583. string_list_t *
  584. _string_list_create (void *ctx)
  585. {
  586.         string_list_t *list;
  587.  
  588.         list = ralloc (ctx, string_list_t);
  589.         list->head = NULL;
  590.         list->tail = NULL;
  591.  
  592.         return list;
  593. }
  594.  
  595. void
  596. _string_list_append_item (string_list_t *list, const char *str)
  597. {
  598.         string_node_t *node;
  599.  
  600.         node = ralloc (list, string_node_t);
  601.         node->str = ralloc_strdup (node, str);
  602.  
  603.         node->next = NULL;
  604.  
  605.         if (list->head == NULL) {
  606.                 list->head = node;
  607.         } else {
  608.                 list->tail->next = node;
  609.         }
  610.  
  611.         list->tail = node;
  612. }
  613.  
  614. int
  615. _string_list_contains (string_list_t *list, const char *member, int *index)
  616. {
  617.         string_node_t *node;
  618.         int i;
  619.  
  620.         if (list == NULL)
  621.                 return 0;
  622.  
  623.         for (i = 0, node = list->head; node; i++, node = node->next) {
  624.                 if (strcmp (node->str, member) == 0) {
  625.                         if (index)
  626.                                 *index = i;
  627.                         return 1;
  628.                 }
  629.         }
  630.  
  631.         return 0;
  632. }
  633.  
  634. int
  635. _string_list_length (string_list_t *list)
  636. {
  637.         int length = 0;
  638.         string_node_t *node;
  639.  
  640.         if (list == NULL)
  641.                 return 0;
  642.  
  643.         for (node = list->head; node; node = node->next)
  644.                 length++;
  645.  
  646.         return length;
  647. }
  648.  
  649. int
  650. _string_list_equal (string_list_t *a, string_list_t *b)
  651. {
  652.         string_node_t *node_a, *node_b;
  653.  
  654.         if (a == NULL && b == NULL)
  655.                 return 1;
  656.  
  657.         if (a == NULL || b == NULL)
  658.                 return 0;
  659.  
  660.         for (node_a = a->head, node_b = b->head;
  661.              node_a && node_b;
  662.              node_a = node_a->next, node_b = node_b->next)
  663.         {
  664.                 if (strcmp (node_a->str, node_b->str))
  665.                         return 0;
  666.         }
  667.  
  668.         /* Catch the case of lists being different lengths, (which
  669.          * would cause the loop above to terminate after the shorter
  670.          * list). */
  671.         return node_a == node_b;
  672. }
  673.  
  674. argument_list_t *
  675. _argument_list_create (void *ctx)
  676. {
  677.         argument_list_t *list;
  678.  
  679.         list = ralloc (ctx, argument_list_t);
  680.         list->head = NULL;
  681.         list->tail = NULL;
  682.  
  683.         return list;
  684. }
  685.  
  686. void
  687. _argument_list_append (argument_list_t *list, token_list_t *argument)
  688. {
  689.         argument_node_t *node;
  690.  
  691.         node = ralloc (list, argument_node_t);
  692.         node->argument = argument;
  693.  
  694.         node->next = NULL;
  695.  
  696.         if (list->head == NULL) {
  697.                 list->head = node;
  698.         } else {
  699.                 list->tail->next = node;
  700.         }
  701.  
  702.         list->tail = node;
  703. }
  704.  
  705. int
  706. _argument_list_length (argument_list_t *list)
  707. {
  708.         int length = 0;
  709.         argument_node_t *node;
  710.  
  711.         if (list == NULL)
  712.                 return 0;
  713.  
  714.         for (node = list->head; node; node = node->next)
  715.                 length++;
  716.  
  717.         return length;
  718. }
  719.  
  720. token_list_t *
  721. _argument_list_member_at (argument_list_t *list, int index)
  722. {
  723.         argument_node_t *node;
  724.         int i;
  725.  
  726.         if (list == NULL)
  727.                 return NULL;
  728.  
  729.         node = list->head;
  730.         for (i = 0; i < index; i++) {
  731.                 node = node->next;
  732.                 if (node == NULL)
  733.                         break;
  734.         }
  735.  
  736.         if (node)
  737.                 return node->argument;
  738.  
  739.         return NULL;
  740. }
  741.  
  742. /* Note: This function ralloc_steal()s the str pointer. */
  743. token_t *
  744. _token_create_str (void *ctx, int type, char *str)
  745. {
  746.         token_t *token;
  747.  
  748.         token = ralloc (ctx, token_t);
  749.         token->type = type;
  750.         token->value.str = str;
  751.  
  752.         ralloc_steal (token, str);
  753.  
  754.         return token;
  755. }
  756.  
  757. token_t *
  758. _token_create_ival (void *ctx, int type, int ival)
  759. {
  760.         token_t *token;
  761.  
  762.         token = ralloc (ctx, token_t);
  763.         token->type = type;
  764.         token->value.ival = ival;
  765.  
  766.         return token;
  767. }
  768.  
  769. token_list_t *
  770. _token_list_create (void *ctx)
  771. {
  772.         token_list_t *list;
  773.  
  774.         list = ralloc (ctx, token_list_t);
  775.         list->head = NULL;
  776.         list->tail = NULL;
  777.         list->non_space_tail = NULL;
  778.  
  779.         return list;
  780. }
  781.  
  782. void
  783. _token_list_append (token_list_t *list, token_t *token)
  784. {
  785.         token_node_t *node;
  786.  
  787.         node = ralloc (list, token_node_t);
  788.         node->token = token;
  789.         node->next = NULL;
  790.  
  791.         if (list->head == NULL) {
  792.                 list->head = node;
  793.         } else {
  794.                 list->tail->next = node;
  795.         }
  796.  
  797.         list->tail = node;
  798.         if (token->type != SPACE)
  799.                 list->non_space_tail = node;
  800. }
  801.  
  802. void
  803. _token_list_append_list (token_list_t *list, token_list_t *tail)
  804. {
  805.         if (tail == NULL || tail->head == NULL)
  806.                 return;
  807.  
  808.         if (list->head == NULL) {
  809.                 list->head = tail->head;
  810.         } else {
  811.                 list->tail->next = tail->head;
  812.         }
  813.  
  814.         list->tail = tail->tail;
  815.         list->non_space_tail = tail->non_space_tail;
  816. }
  817.  
  818. static token_list_t *
  819. _token_list_copy (void *ctx, token_list_t *other)
  820. {
  821.         token_list_t *copy;
  822.         token_node_t *node;
  823.  
  824.         if (other == NULL)
  825.                 return NULL;
  826.  
  827.         copy = _token_list_create (ctx);
  828.         for (node = other->head; node; node = node->next) {
  829.                 token_t *new_token = ralloc (copy, token_t);
  830.                 *new_token = *node->token;
  831.                 _token_list_append (copy, new_token);
  832.         }
  833.  
  834.         return copy;
  835. }
  836.  
  837. static void
  838. _token_list_trim_trailing_space (token_list_t *list)
  839. {
  840.         token_node_t *tail, *next;
  841.  
  842.         if (list->non_space_tail) {
  843.                 tail = list->non_space_tail->next;
  844.                 list->non_space_tail->next = NULL;
  845.                 list->tail = list->non_space_tail;
  846.  
  847.                 while (tail) {
  848.                         next = tail->next;
  849.                         ralloc_free (tail);
  850.                         tail = next;
  851.                 }
  852.         }
  853. }
  854.  
  855. static int
  856. _token_list_is_empty_ignoring_space (token_list_t *l)
  857. {
  858.         token_node_t *n;
  859.  
  860.         if (l == NULL)
  861.                 return 1;
  862.  
  863.         n = l->head;
  864.         while (n != NULL && n->token->type == SPACE)
  865.                 n = n->next;
  866.  
  867.         return n == NULL;
  868. }
  869.  
  870. int
  871. _token_list_equal_ignoring_space (token_list_t *a, token_list_t *b)
  872. {
  873.         token_node_t *node_a, *node_b;
  874.  
  875.         if (a == NULL || b == NULL) {
  876.                 int a_empty = _token_list_is_empty_ignoring_space(a);
  877.                 int b_empty = _token_list_is_empty_ignoring_space(b);
  878.                 return a_empty == b_empty;
  879.         }
  880.  
  881.         node_a = a->head;
  882.         node_b = b->head;
  883.  
  884.         while (1)
  885.         {
  886.                 if (node_a == NULL && node_b == NULL)
  887.                         break;
  888.  
  889.                 if (node_a == NULL || node_b == NULL)
  890.                         return 0;
  891.  
  892.                 if (node_a->token->type == SPACE) {
  893.                         node_a = node_a->next;
  894.                         continue;
  895.                 }
  896.  
  897.                 if (node_b->token->type == SPACE) {
  898.                         node_b = node_b->next;
  899.                         continue;
  900.                 }
  901.  
  902.                 if (node_a->token->type != node_b->token->type)
  903.                         return 0;
  904.  
  905.                 switch (node_a->token->type) {
  906.                 case INTEGER:
  907.                         if (node_a->token->value.ival !=
  908.                             node_b->token->value.ival)
  909.                         {
  910.                                 return 0;
  911.                         }
  912.                         break;
  913.                 case IDENTIFIER:
  914.                 case INTEGER_STRING:
  915.                 case OTHER:
  916.                         if (strcmp (node_a->token->value.str,
  917.                                     node_b->token->value.str))
  918.                         {
  919.                                 return 0;
  920.                         }
  921.                         break;
  922.                 }
  923.  
  924.                 node_a = node_a->next;
  925.                 node_b = node_b->next;
  926.         }
  927.  
  928.         return 1;
  929. }
  930.  
  931. static void
  932. _token_print (char **out, size_t *len, token_t *token)
  933. {
  934.         if (token->type < 256) {
  935.                 ralloc_asprintf_rewrite_tail (out, len, "%c", token->type);
  936.                 return;
  937.         }
  938.  
  939.         switch (token->type) {
  940.         case INTEGER:
  941.                 ralloc_asprintf_rewrite_tail (out, len, "%" PRIiMAX, token->value.ival);
  942.                 break;
  943.         case IDENTIFIER:
  944.         case INTEGER_STRING:
  945.         case OTHER:
  946.                 ralloc_asprintf_rewrite_tail (out, len, "%s", token->value.str);
  947.                 break;
  948.         case SPACE:
  949.                 ralloc_asprintf_rewrite_tail (out, len, " ");
  950.                 break;
  951.         case LEFT_SHIFT:
  952.                 ralloc_asprintf_rewrite_tail (out, len, "<<");
  953.                 break;
  954.         case RIGHT_SHIFT:
  955.                 ralloc_asprintf_rewrite_tail (out, len, ">>");
  956.                 break;
  957.         case LESS_OR_EQUAL:
  958.                 ralloc_asprintf_rewrite_tail (out, len, "<=");
  959.                 break;
  960.         case GREATER_OR_EQUAL:
  961.                 ralloc_asprintf_rewrite_tail (out, len, ">=");
  962.                 break;
  963.         case EQUAL:
  964.                 ralloc_asprintf_rewrite_tail (out, len, "==");
  965.                 break;
  966.         case NOT_EQUAL:
  967.                 ralloc_asprintf_rewrite_tail (out, len, "!=");
  968.                 break;
  969.         case AND:
  970.                 ralloc_asprintf_rewrite_tail (out, len, "&&");
  971.                 break;
  972.         case OR:
  973.                 ralloc_asprintf_rewrite_tail (out, len, "||");
  974.                 break;
  975.         case PASTE:
  976.                 ralloc_asprintf_rewrite_tail (out, len, "##");
  977.                 break;
  978.         case COMMA_FINAL:
  979.                 ralloc_asprintf_rewrite_tail (out, len, ",");
  980.                 break;
  981.         case PLACEHOLDER:
  982.                 /* Nothing to print. */
  983.                 break;
  984.         default:
  985.                 assert(!"Error: Don't know how to print token.");
  986.                 break;
  987.         }
  988. }
  989.  
  990. /* Return a new token (ralloc()ed off of 'token') formed by pasting
  991.  * 'token' and 'other'. Note that this function may return 'token' or
  992.  * 'other' directly rather than allocating anything new.
  993.  *
  994.  * Caution: Only very cursory error-checking is performed to see if
  995.  * the final result is a valid single token. */
  996. static token_t *
  997. _token_paste (glcpp_parser_t *parser, token_t *token, token_t *other)
  998. {
  999.         token_t *combined = NULL;
  1000.  
  1001.         /* Pasting a placeholder onto anything makes no change. */
  1002.         if (other->type == PLACEHOLDER)
  1003.                 return token;
  1004.  
  1005.         /* When 'token' is a placeholder, just return 'other'. */
  1006.         if (token->type == PLACEHOLDER)
  1007.                 return other;
  1008.  
  1009.         /* A very few single-character punctuators can be combined
  1010.          * with another to form a multi-character punctuator. */
  1011.         switch (token->type) {
  1012.         case '<':
  1013.                 if (other->type == '<')
  1014.                         combined = _token_create_ival (token, LEFT_SHIFT, LEFT_SHIFT);
  1015.                 else if (other->type == '=')
  1016.                         combined = _token_create_ival (token, LESS_OR_EQUAL, LESS_OR_EQUAL);
  1017.                 break;
  1018.         case '>':
  1019.                 if (other->type == '>')
  1020.                         combined = _token_create_ival (token, RIGHT_SHIFT, RIGHT_SHIFT);
  1021.                 else if (other->type == '=')
  1022.                         combined = _token_create_ival (token, GREATER_OR_EQUAL, GREATER_OR_EQUAL);
  1023.                 break;
  1024.         case '=':
  1025.                 if (other->type == '=')
  1026.                         combined = _token_create_ival (token, EQUAL, EQUAL);
  1027.                 break;
  1028.         case '!':
  1029.                 if (other->type == '=')
  1030.                         combined = _token_create_ival (token, NOT_EQUAL, NOT_EQUAL);
  1031.                 break;
  1032.         case '&':
  1033.                 if (other->type == '&')
  1034.                         combined = _token_create_ival (token, AND, AND);
  1035.                 break;
  1036.         case '|':
  1037.                 if (other->type == '|')
  1038.                         combined = _token_create_ival (token, OR, OR);
  1039.                 break;
  1040.         }
  1041.  
  1042.         if (combined != NULL) {
  1043.                 /* Inherit the location from the first token */
  1044.                 combined->location = token->location;
  1045.                 return combined;
  1046.         }
  1047.  
  1048.         /* Two string-valued (or integer) tokens can usually just be
  1049.          * mashed together. (We also handle a string followed by an
  1050.          * integer here as well.)
  1051.          *
  1052.          * There are some exceptions here. Notably, if the first token
  1053.          * is an integer (or a string representing an integer), then
  1054.          * the second token must also be an integer or must be a
  1055.          * string representing an integer that begins with a digit.
  1056.          */
  1057.         if ((token->type == IDENTIFIER || token->type == OTHER || token->type == INTEGER_STRING || token->type == INTEGER) &&
  1058.             (other->type == IDENTIFIER || other->type == OTHER || other->type == INTEGER_STRING || other->type == INTEGER))
  1059.         {
  1060.                 char *str;
  1061.                 int combined_type;
  1062.  
  1063.                 /* Check that pasting onto an integer doesn't create a
  1064.                  * non-integer, (that is, only digits can be
  1065.                  * pasted. */
  1066.                 if (token->type == INTEGER_STRING || token->type == INTEGER)
  1067.                 {
  1068.                         switch (other->type) {
  1069.                         case INTEGER_STRING:
  1070.                                 if (other->value.str[0] < '0' ||
  1071.                                     other->value.str[0] > '9')
  1072.                                         goto FAIL;
  1073.                                 break;
  1074.                         case INTEGER:
  1075.                                 if (other->value.ival < 0)
  1076.                                         goto FAIL;
  1077.                                 break;
  1078.                         default:
  1079.                                 goto FAIL;
  1080.                         }
  1081.                 }
  1082.  
  1083.                 if (token->type == INTEGER)
  1084.                         str = ralloc_asprintf (token, "%" PRIiMAX,
  1085.                                                token->value.ival);
  1086.                 else
  1087.                         str = ralloc_strdup (token, token->value.str);
  1088.                                                
  1089.  
  1090.                 if (other->type == INTEGER)
  1091.                         ralloc_asprintf_append (&str, "%" PRIiMAX,
  1092.                                                 other->value.ival);
  1093.                 else
  1094.                         ralloc_strcat (&str, other->value.str);
  1095.  
  1096.                 /* New token is same type as original token, unless we
  1097.                  * started with an integer, in which case we will be
  1098.                  * creating an integer-string. */
  1099.                 combined_type = token->type;
  1100.                 if (combined_type == INTEGER)
  1101.                         combined_type = INTEGER_STRING;
  1102.  
  1103.                 combined = _token_create_str (token, combined_type, str);
  1104.                 combined->location = token->location;
  1105.                 return combined;
  1106.         }
  1107.  
  1108.     FAIL:
  1109.         glcpp_error (&token->location, parser, "");
  1110.         ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "Pasting \"");
  1111.         _token_print (&parser->info_log, &parser->info_log_length, token);
  1112.         ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "\" and \"");
  1113.         _token_print (&parser->info_log, &parser->info_log_length, other);
  1114.         ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "\" does not give a valid preprocessing token.\n");
  1115.  
  1116.         return token;
  1117. }
  1118.  
  1119. static void
  1120. _token_list_print (glcpp_parser_t *parser, token_list_t *list)
  1121. {
  1122.         token_node_t *node;
  1123.  
  1124.         if (list == NULL)
  1125.                 return;
  1126.  
  1127.         for (node = list->head; node; node = node->next)
  1128.                 _token_print (&parser->output, &parser->output_length, node->token);
  1129. }
  1130.  
  1131. void
  1132. yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error)
  1133. {
  1134.         glcpp_error(locp, parser, "%s", error);
  1135. }
  1136.  
  1137. static void add_builtin_define(glcpp_parser_t *parser,
  1138.                                const char *name, int value)
  1139. {
  1140.    token_t *tok;
  1141.    token_list_t *list;
  1142.  
  1143.    tok = _token_create_ival (parser, INTEGER, value);
  1144.  
  1145.    list = _token_list_create(parser);
  1146.    _token_list_append(list, tok);
  1147.    _define_object_macro(parser, NULL, name, list);
  1148. }
  1149.  
  1150. glcpp_parser_t *
  1151. glcpp_parser_create (const struct gl_extensions *extensions, int api)
  1152. {
  1153.         glcpp_parser_t *parser;
  1154.         int language_version;
  1155.  
  1156.         parser = ralloc (NULL, glcpp_parser_t);
  1157.  
  1158.         glcpp_lex_init_extra (parser, &parser->scanner);
  1159.         parser->defines = hash_table_ctor (32, hash_table_string_hash,
  1160.                                            hash_table_string_compare);
  1161.         parser->active = NULL;
  1162.         parser->lexing_if = 0;
  1163.         parser->space_tokens = 1;
  1164.         parser->newline_as_space = 0;
  1165.         parser->in_control_line = 0;
  1166.         parser->paren_count = 0;
  1167.  
  1168.         parser->skip_stack = NULL;
  1169.  
  1170.         parser->lex_from_list = NULL;
  1171.         parser->lex_from_node = NULL;
  1172.  
  1173.         parser->output = ralloc_strdup(parser, "");
  1174.         parser->output_length = 0;
  1175.         parser->info_log = ralloc_strdup(parser, "");
  1176.         parser->info_log_length = 0;
  1177.         parser->error = 0;
  1178.  
  1179.         parser->has_new_line_number = 0;
  1180.         parser->new_line_number = 1;
  1181.         parser->has_new_source_number = 0;
  1182.         parser->new_source_number = 0;
  1183.  
  1184.         parser->is_gles = false;
  1185.  
  1186.         /* Add pre-defined macros. */
  1187.         if (api == API_OPENGLES2) {
  1188.            parser->is_gles = true;
  1189.            add_builtin_define(parser, "GL_ES", 1);
  1190.  
  1191.            if (extensions != NULL) {
  1192.               if (extensions->OES_EGL_image_external)
  1193.                  add_builtin_define(parser, "GL_OES_EGL_image_external", 1);
  1194.            }
  1195.         } else {
  1196.            add_builtin_define(parser, "GL_ARB_draw_buffers", 1);
  1197.            add_builtin_define(parser, "GL_ARB_texture_rectangle", 1);
  1198.  
  1199.            if (extensions != NULL) {
  1200.               if (extensions->EXT_texture_array) {
  1201.                  add_builtin_define(parser, "GL_EXT_texture_array", 1);
  1202.               }
  1203.  
  1204.               if (extensions->ARB_fragment_coord_conventions)
  1205.                  add_builtin_define(parser, "GL_ARB_fragment_coord_conventions",
  1206.                                     1);
  1207.  
  1208.               if (extensions->ARB_explicit_attrib_location)
  1209.                  add_builtin_define(parser, "GL_ARB_explicit_attrib_location", 1);
  1210.  
  1211.               if (extensions->ARB_shader_texture_lod)
  1212.                  add_builtin_define(parser, "GL_ARB_shader_texture_lod", 1);
  1213.  
  1214.               if (extensions->ARB_draw_instanced)
  1215.                  add_builtin_define(parser, "GL_ARB_draw_instanced", 1);
  1216.  
  1217.               if (extensions->ARB_conservative_depth) {
  1218.                  add_builtin_define(parser, "GL_AMD_conservative_depth", 1);
  1219.                  add_builtin_define(parser, "GL_ARB_conservative_depth", 1);
  1220.               }
  1221.  
  1222.               if (extensions->ARB_shader_bit_encoding)
  1223.                  add_builtin_define(parser, "GL_ARB_shader_bit_encoding", 1);
  1224.  
  1225.               if (extensions->ARB_uniform_buffer_object)
  1226.                  add_builtin_define(parser, "GL_ARB_uniform_buffer_object", 1);
  1227.  
  1228.               if (extensions->ARB_texture_cube_map_array)
  1229.                  add_builtin_define(parser, "GL_ARB_texture_cube_map_array", 1);
  1230.  
  1231.               if (extensions->ARB_shading_language_packing)
  1232.                  add_builtin_define(parser, "GL_ARB_shading_language_packing", 1);
  1233.  
  1234.               if (extensions->ARB_texture_multisample)
  1235.                  add_builtin_define(parser, "GL_ARB_texture_multisample", 1);
  1236.  
  1237.               if (extensions->ARB_texture_query_lod)
  1238.                  add_builtin_define(parser, "GL_ARB_texture_query_lod", 1);
  1239.  
  1240.               if (extensions->ARB_gpu_shader5)
  1241.                  add_builtin_define(parser, "GL_ARB_gpu_shader5", 1);
  1242.  
  1243.               if (extensions->AMD_vertex_shader_layer)
  1244.                  add_builtin_define(parser, "GL_AMD_vertex_shader_layer", 1);
  1245.  
  1246.               if (extensions->ARB_shading_language_420pack)
  1247.                  add_builtin_define(parser, "GL_ARB_shading_language_420pack", 1);
  1248.            }
  1249.         }
  1250.  
  1251.         language_version = 110;
  1252.         add_builtin_define(parser, "__VERSION__", language_version);
  1253.  
  1254.         return parser;
  1255. }
  1256.  
  1257. void
  1258. glcpp_parser_destroy (glcpp_parser_t *parser)
  1259. {
  1260.         glcpp_lex_destroy (parser->scanner);
  1261.         hash_table_dtor (parser->defines);
  1262.         ralloc_free (parser);
  1263. }
  1264.  
  1265. typedef enum function_status
  1266. {
  1267.         FUNCTION_STATUS_SUCCESS,
  1268.         FUNCTION_NOT_A_FUNCTION,
  1269.         FUNCTION_UNBALANCED_PARENTHESES
  1270. } function_status_t;
  1271.  
  1272. /* Find a set of function-like macro arguments by looking for a
  1273.  * balanced set of parentheses.
  1274.  *
  1275.  * When called, 'node' should be the opening-parenthesis token, (or
  1276.  * perhaps preceeding SPACE tokens). Upon successful return *last will
  1277.  * be the last consumed node, (corresponding to the closing right
  1278.  * parenthesis).
  1279.  *
  1280.  * Return values:
  1281.  *
  1282.  *   FUNCTION_STATUS_SUCCESS:
  1283.  *
  1284.  *      Successfully parsed a set of function arguments.       
  1285.  *
  1286.  *   FUNCTION_NOT_A_FUNCTION:
  1287.  *
  1288.  *      Macro name not followed by a '('. This is not an error, but
  1289.  *      simply that the macro name should be treated as a non-macro.
  1290.  *
  1291.  *   FUNCTION_UNBALANCED_PARENTHESES
  1292.  *
  1293.  *      Macro name is not followed by a balanced set of parentheses.
  1294.  */
  1295. static function_status_t
  1296. _arguments_parse (argument_list_t *arguments,
  1297.                   token_node_t *node,
  1298.                   token_node_t **last)
  1299. {
  1300.         token_list_t *argument;
  1301.         int paren_count;
  1302.  
  1303.         node = node->next;
  1304.  
  1305.         /* Ignore whitespace before first parenthesis. */
  1306.         while (node && node->token->type == SPACE)
  1307.                 node = node->next;
  1308.  
  1309.         if (node == NULL || node->token->type != '(')
  1310.                 return FUNCTION_NOT_A_FUNCTION;
  1311.  
  1312.         node = node->next;
  1313.  
  1314.         argument = _token_list_create (arguments);
  1315.         _argument_list_append (arguments, argument);
  1316.  
  1317.         for (paren_count = 1; node; node = node->next) {
  1318.                 if (node->token->type == '(')
  1319.                 {
  1320.                         paren_count++;
  1321.                 }
  1322.                 else if (node->token->type == ')')
  1323.                 {
  1324.                         paren_count--;
  1325.                         if (paren_count == 0)
  1326.                                 break;
  1327.                 }
  1328.  
  1329.                 if (node->token->type == ',' &&
  1330.                          paren_count == 1)
  1331.                 {
  1332.                         _token_list_trim_trailing_space (argument);
  1333.                         argument = _token_list_create (arguments);
  1334.                         _argument_list_append (arguments, argument);
  1335.                 }
  1336.                 else {
  1337.                         if (argument->head == NULL) {
  1338.                                 /* Don't treat initial whitespace as
  1339.                                  * part of the arguement. */
  1340.                                 if (node->token->type == SPACE)
  1341.                                         continue;
  1342.                         }
  1343.                         _token_list_append (argument, node->token);
  1344.                 }
  1345.         }
  1346.  
  1347.         if (paren_count)
  1348.                 return FUNCTION_UNBALANCED_PARENTHESES;
  1349.  
  1350.         *last = node;
  1351.  
  1352.         return FUNCTION_STATUS_SUCCESS;
  1353. }
  1354.  
  1355. static token_list_t *
  1356. _token_list_create_with_one_ival (void *ctx, int type, int ival)
  1357. {
  1358.         token_list_t *list;
  1359.         token_t *node;
  1360.  
  1361.         list = _token_list_create (ctx);
  1362.         node = _token_create_ival (list, type, ival);
  1363.         _token_list_append (list, node);
  1364.  
  1365.         return list;
  1366. }
  1367.  
  1368. static token_list_t *
  1369. _token_list_create_with_one_space (void *ctx)
  1370. {
  1371.         return _token_list_create_with_one_ival (ctx, SPACE, SPACE);
  1372. }
  1373.  
  1374. static token_list_t *
  1375. _token_list_create_with_one_integer (void *ctx, int ival)
  1376. {
  1377.         return _token_list_create_with_one_ival (ctx, INTEGER, ival);
  1378. }
  1379.  
  1380. /* Perform macro expansion on 'list', placing the resulting tokens
  1381.  * into a new list which is initialized with a first token of type
  1382.  * 'head_token_type'. Then begin lexing from the resulting list,
  1383.  * (return to the current lexing source when this list is exhausted).
  1384.  */
  1385. static void
  1386. _glcpp_parser_expand_and_lex_from (glcpp_parser_t *parser,
  1387.                                    int head_token_type,
  1388.                                    token_list_t *list)
  1389. {
  1390.         token_list_t *expanded;
  1391.         token_t *token;
  1392.  
  1393.         expanded = _token_list_create (parser);
  1394.         token = _token_create_ival (parser, head_token_type, head_token_type);
  1395.         _token_list_append (expanded, token);
  1396.         _glcpp_parser_expand_token_list (parser, list);
  1397.         _token_list_append_list (expanded, list);
  1398.         glcpp_parser_lex_from (parser, expanded);
  1399. }
  1400.  
  1401. static void
  1402. _glcpp_parser_apply_pastes (glcpp_parser_t *parser, token_list_t *list)
  1403. {
  1404.         token_node_t *node;
  1405.  
  1406.         node = list->head;
  1407.         while (node)
  1408.         {
  1409.                 token_node_t *next_non_space;
  1410.  
  1411.                 /* Look ahead for a PASTE token, skipping space. */
  1412.                 next_non_space = node->next;
  1413.                 while (next_non_space && next_non_space->token->type == SPACE)
  1414.                         next_non_space = next_non_space->next;
  1415.  
  1416.                 if (next_non_space == NULL)
  1417.                         break;
  1418.  
  1419.                 if (next_non_space->token->type != PASTE) {
  1420.                         node = next_non_space;
  1421.                         continue;
  1422.                 }
  1423.  
  1424.                 /* Now find the next non-space token after the PASTE. */
  1425.                 next_non_space = next_non_space->next;
  1426.                 while (next_non_space && next_non_space->token->type == SPACE)
  1427.                         next_non_space = next_non_space->next;
  1428.  
  1429.                 if (next_non_space == NULL) {
  1430.                         yyerror (&node->token->location, parser, "'##' cannot appear at either end of a macro expansion\n");
  1431.                         return;
  1432.                 }
  1433.  
  1434.                 node->token = _token_paste (parser, node->token, next_non_space->token);
  1435.                 node->next = next_non_space->next;
  1436.                 if (next_non_space == list->tail)
  1437.                         list->tail = node;
  1438.         }
  1439.  
  1440.         list->non_space_tail = list->tail;
  1441. }
  1442.  
  1443. /* This is a helper function that's essentially part of the
  1444.  * implementation of _glcpp_parser_expand_node. It shouldn't be called
  1445.  * except for by that function.
  1446.  *
  1447.  * Returns NULL if node is a simple token with no expansion, (that is,
  1448.  * although 'node' corresponds to an identifier defined as a
  1449.  * function-like macro, it is not followed with a parenthesized
  1450.  * argument list).
  1451.  *
  1452.  * Compute the complete expansion of node (which is a function-like
  1453.  * macro) and subsequent nodes which are arguments.
  1454.  *
  1455.  * Returns the token list that results from the expansion and sets
  1456.  * *last to the last node in the list that was consumed by the
  1457.  * expansion. Specifically, *last will be set as follows: as the
  1458.  * token of the closing right parenthesis.
  1459.  */
  1460. static token_list_t *
  1461. _glcpp_parser_expand_function (glcpp_parser_t *parser,
  1462.                                token_node_t *node,
  1463.                                token_node_t **last)
  1464.                                
  1465. {
  1466.         macro_t *macro;
  1467.         const char *identifier;
  1468.         argument_list_t *arguments;
  1469.         function_status_t status;
  1470.         token_list_t *substituted;
  1471.         int parameter_index;
  1472.  
  1473.         identifier = node->token->value.str;
  1474.  
  1475.         macro = hash_table_find (parser->defines, identifier);
  1476.  
  1477.         assert (macro->is_function);
  1478.  
  1479.         arguments = _argument_list_create (parser);
  1480.         status = _arguments_parse (arguments, node, last);
  1481.  
  1482.         switch (status) {
  1483.         case FUNCTION_STATUS_SUCCESS:
  1484.                 break;
  1485.         case FUNCTION_NOT_A_FUNCTION:
  1486.                 return NULL;
  1487.         case FUNCTION_UNBALANCED_PARENTHESES:
  1488.                 glcpp_error (&node->token->location, parser, "Macro %s call has unbalanced parentheses\n", identifier);
  1489.                 return NULL;
  1490.         }
  1491.  
  1492.         /* Replace a macro defined as empty with a SPACE token. */
  1493.         if (macro->replacements == NULL) {
  1494.                 ralloc_free (arguments);
  1495.                 return _token_list_create_with_one_space (parser);
  1496.         }
  1497.  
  1498.         if (! ((_argument_list_length (arguments) ==
  1499.                 _string_list_length (macro->parameters)) ||
  1500.                (_string_list_length (macro->parameters) == 0 &&
  1501.                 _argument_list_length (arguments) == 1 &&
  1502.                 arguments->head->argument->head == NULL)))
  1503.         {
  1504.                 glcpp_error (&node->token->location, parser,
  1505.                               "Error: macro %s invoked with %d arguments (expected %d)\n",
  1506.                               identifier,
  1507.                               _argument_list_length (arguments),
  1508.                               _string_list_length (macro->parameters));
  1509.                 return NULL;
  1510.         }
  1511.  
  1512.         /* Perform argument substitution on the replacement list. */
  1513.         substituted = _token_list_create (arguments);
  1514.  
  1515.         for (node = macro->replacements->head; node; node = node->next)
  1516.         {
  1517.                 if (node->token->type == IDENTIFIER &&
  1518.                     _string_list_contains (macro->parameters,
  1519.                                            node->token->value.str,
  1520.                                            &parameter_index))
  1521.                 {
  1522.                         token_list_t *argument;
  1523.                         argument = _argument_list_member_at (arguments,
  1524.                                                              parameter_index);
  1525.                         /* Before substituting, we expand the argument
  1526.                          * tokens, or append a placeholder token for
  1527.                          * an empty argument. */
  1528.                         if (argument->head) {
  1529.                                 token_list_t *expanded_argument;
  1530.                                 expanded_argument = _token_list_copy (parser,
  1531.                                                                       argument);
  1532.                                 _glcpp_parser_expand_token_list (parser,
  1533.                                                                  expanded_argument);
  1534.                                 _token_list_append_list (substituted,
  1535.                                                          expanded_argument);
  1536.                         } else {
  1537.                                 token_t *new_token;
  1538.  
  1539.                                 new_token = _token_create_ival (substituted,
  1540.                                                                 PLACEHOLDER,
  1541.                                                                 PLACEHOLDER);
  1542.                                 _token_list_append (substituted, new_token);
  1543.                         }
  1544.                 } else {
  1545.                         _token_list_append (substituted, node->token);
  1546.                 }
  1547.         }
  1548.  
  1549.         /* After argument substitution, and before further expansion
  1550.          * below, implement token pasting. */
  1551.  
  1552.         _token_list_trim_trailing_space (substituted);
  1553.  
  1554.         _glcpp_parser_apply_pastes (parser, substituted);
  1555.  
  1556.         return substituted;
  1557. }
  1558.  
  1559. /* Compute the complete expansion of node, (and subsequent nodes after
  1560.  * 'node' in the case that 'node' is a function-like macro and
  1561.  * subsequent nodes are arguments).
  1562.  *
  1563.  * Returns NULL if node is a simple token with no expansion.
  1564.  *
  1565.  * Otherwise, returns the token list that results from the expansion
  1566.  * and sets *last to the last node in the list that was consumed by
  1567.  * the expansion. Specifically, *last will be set as follows:
  1568.  *
  1569.  *      As 'node' in the case of object-like macro expansion.
  1570.  *
  1571.  *      As the token of the closing right parenthesis in the case of
  1572.  *      function-like macro expansion.
  1573.  */
  1574. static token_list_t *
  1575. _glcpp_parser_expand_node (glcpp_parser_t *parser,
  1576.                            token_node_t *node,
  1577.                            token_node_t **last)
  1578. {
  1579.         token_t *token = node->token;
  1580.         const char *identifier;
  1581.         macro_t *macro;
  1582.  
  1583.         /* We only expand identifiers */
  1584.         if (token->type != IDENTIFIER) {
  1585.                 /* We change any COMMA into a COMMA_FINAL to prevent
  1586.                  * it being mistaken for an argument separator
  1587.                  * later. */
  1588.                 if (token->type == ',') {
  1589.                         token->type = COMMA_FINAL;
  1590.                         token->value.ival = COMMA_FINAL;
  1591.                 }
  1592.  
  1593.                 return NULL;
  1594.         }
  1595.  
  1596.         *last = node;
  1597.         identifier = token->value.str;
  1598.  
  1599.         /* Special handling for __LINE__ and __FILE__, (not through
  1600.          * the hash table). */
  1601.         if (strcmp(identifier, "__LINE__") == 0)
  1602.                 return _token_list_create_with_one_integer (parser, node->token->location.first_line);
  1603.  
  1604.         if (strcmp(identifier, "__FILE__") == 0)
  1605.                 return _token_list_create_with_one_integer (parser, node->token->location.source);
  1606.  
  1607.         /* Look up this identifier in the hash table. */
  1608.         macro = hash_table_find (parser->defines, identifier);
  1609.  
  1610.         /* Not a macro, so no expansion needed. */
  1611.         if (macro == NULL)
  1612.                 return NULL;
  1613.  
  1614.         /* Finally, don't expand this macro if we're already actively
  1615.          * expanding it, (to avoid infinite recursion). */
  1616.         if (_parser_active_list_contains (parser, identifier)) {
  1617.                 /* We change the token type here from IDENTIFIER to
  1618.                  * OTHER to prevent any future expansion of this
  1619.                  * unexpanded token. */
  1620.                 char *str;
  1621.                 token_list_t *expansion;
  1622.                 token_t *final;
  1623.  
  1624.                 str = ralloc_strdup (parser, token->value.str);
  1625.                 final = _token_create_str (parser, OTHER, str);
  1626.                 expansion = _token_list_create (parser);
  1627.                 _token_list_append (expansion, final);
  1628.                 return expansion;
  1629.         }
  1630.  
  1631.         if (! macro->is_function)
  1632.         {
  1633.                 token_list_t *replacement;
  1634.  
  1635.                 /* Replace a macro defined as empty with a SPACE token. */
  1636.                 if (macro->replacements == NULL)
  1637.                         return _token_list_create_with_one_space (parser);
  1638.  
  1639.                 replacement = _token_list_copy (parser, macro->replacements);
  1640.                 _glcpp_parser_apply_pastes (parser, replacement);
  1641.                 return replacement;
  1642.         }
  1643.  
  1644.         return _glcpp_parser_expand_function (parser, node, last);
  1645. }
  1646.  
  1647. /* Push a new identifier onto the parser's active list.
  1648.  *
  1649.  * Here, 'marker' is the token node that appears in the list after the
  1650.  * expansion of 'identifier'. That is, when the list iterator begins
  1651.  * examining 'marker', then it is time to pop this node from the
  1652.  * active stack.
  1653.  */
  1654. static void
  1655. _parser_active_list_push (glcpp_parser_t *parser,
  1656.                           const char *identifier,
  1657.                           token_node_t *marker)
  1658. {
  1659.         active_list_t *node;
  1660.  
  1661.         node = ralloc (parser->active, active_list_t);
  1662.         node->identifier = ralloc_strdup (node, identifier);
  1663.         node->marker = marker;
  1664.         node->next = parser->active;
  1665.  
  1666.         parser->active = node;
  1667. }
  1668.  
  1669. static void
  1670. _parser_active_list_pop (glcpp_parser_t *parser)
  1671. {
  1672.         active_list_t *node = parser->active;
  1673.  
  1674.         if (node == NULL) {
  1675.                 parser->active = NULL;
  1676.                 return;
  1677.         }
  1678.  
  1679.         node = parser->active->next;
  1680.         ralloc_free (parser->active);
  1681.  
  1682.         parser->active = node;
  1683. }
  1684.  
  1685. static int
  1686. _parser_active_list_contains (glcpp_parser_t *parser, const char *identifier)
  1687. {
  1688.         active_list_t *node;
  1689.  
  1690.         if (parser->active == NULL)
  1691.                 return 0;
  1692.  
  1693.         for (node = parser->active; node; node = node->next)
  1694.                 if (strcmp (node->identifier, identifier) == 0)
  1695.                         return 1;
  1696.  
  1697.         return 0;
  1698. }
  1699.  
  1700. /* Walk over the token list replacing nodes with their expansion.
  1701.  * Whenever nodes are expanded the walking will walk over the new
  1702.  * nodes, continuing to expand as necessary. The results are placed in
  1703.  * 'list' itself;
  1704.  */
  1705. static void
  1706. _glcpp_parser_expand_token_list (glcpp_parser_t *parser,
  1707.                                  token_list_t *list)
  1708. {
  1709.         token_node_t *node_prev;
  1710.         token_node_t *node, *last = NULL;
  1711.         token_list_t *expansion;
  1712.         active_list_t *active_initial = parser->active;
  1713.  
  1714.         if (list == NULL)
  1715.                 return;
  1716.  
  1717.         _token_list_trim_trailing_space (list);
  1718.  
  1719.         node_prev = NULL;
  1720.         node = list->head;
  1721.  
  1722.         while (node) {
  1723.  
  1724.                 while (parser->active && parser->active->marker == node)
  1725.                         _parser_active_list_pop (parser);
  1726.  
  1727.                 expansion = _glcpp_parser_expand_node (parser, node, &last);
  1728.                 if (expansion) {
  1729.                         token_node_t *n;
  1730.  
  1731.                         for (n = node; n != last->next; n = n->next)
  1732.                                 while (parser->active &&
  1733.                                        parser->active->marker == n)
  1734.                                 {
  1735.                                         _parser_active_list_pop (parser);
  1736.                                 }
  1737.  
  1738.                         _parser_active_list_push (parser,
  1739.                                                   node->token->value.str,
  1740.                                                   last->next);
  1741.                        
  1742.                         /* Splice expansion into list, supporting a
  1743.                          * simple deletion if the expansion is
  1744.                          * empty. */
  1745.                         if (expansion->head) {
  1746.                                 if (node_prev)
  1747.                                         node_prev->next = expansion->head;
  1748.                                 else
  1749.                                         list->head = expansion->head;
  1750.                                 expansion->tail->next = last->next;
  1751.                                 if (last == list->tail)
  1752.                                         list->tail = expansion->tail;
  1753.                         } else {
  1754.                                 if (node_prev)
  1755.                                         node_prev->next = last->next;
  1756.                                 else
  1757.                                         list->head = last->next;
  1758.                                 if (last == list->tail)
  1759.                                         list->tail = NULL;
  1760.                         }
  1761.                 } else {
  1762.                         node_prev = node;
  1763.                 }
  1764.                 node = node_prev ? node_prev->next : list->head;
  1765.         }
  1766.  
  1767.         /* Remove any lingering effects of this invocation on the
  1768.          * active list. That is, pop until the list looks like it did
  1769.          * at the beginning of this function. */
  1770.         while (parser->active && parser->active != active_initial)
  1771.                 _parser_active_list_pop (parser);
  1772.  
  1773.         list->non_space_tail = list->tail;
  1774. }
  1775.  
  1776. void
  1777. _glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser,
  1778.                                          token_list_t *list)
  1779. {
  1780.         if (list == NULL)
  1781.                 return;
  1782.  
  1783.         _glcpp_parser_expand_token_list (parser, list);
  1784.  
  1785.         _token_list_trim_trailing_space (list);
  1786.  
  1787.         _token_list_print (parser, list);
  1788. }
  1789.  
  1790. static void
  1791. _check_for_reserved_macro_name (glcpp_parser_t *parser, YYLTYPE *loc,
  1792.                                 const char *identifier)
  1793. {
  1794.         /* According to the GLSL specification, macro names starting with "__"
  1795.          * or "GL_" are reserved for future use.  So, don't allow them.
  1796.          */
  1797.         if (strstr(identifier, "__")) {
  1798.                 glcpp_error (loc, parser, "Macro names containing \"__\" are reserved.\n");
  1799.         }
  1800.         if (strncmp(identifier, "GL_", 3) == 0) {
  1801.                 glcpp_error (loc, parser, "Macro names starting with \"GL_\" are reserved.\n");
  1802.         }
  1803. }
  1804.  
  1805. static int
  1806. _macro_equal (macro_t *a, macro_t *b)
  1807. {
  1808.         if (a->is_function != b->is_function)
  1809.                 return 0;
  1810.  
  1811.         if (a->is_function) {
  1812.                 if (! _string_list_equal (a->parameters, b->parameters))
  1813.                         return 0;
  1814.         }
  1815.  
  1816.         return _token_list_equal_ignoring_space (a->replacements,
  1817.                                                  b->replacements);
  1818. }
  1819.  
  1820. void
  1821. _define_object_macro (glcpp_parser_t *parser,
  1822.                       YYLTYPE *loc,
  1823.                       const char *identifier,
  1824.                       token_list_t *replacements)
  1825. {
  1826.         macro_t *macro, *previous;
  1827.  
  1828.         if (loc != NULL)
  1829.                 _check_for_reserved_macro_name(parser, loc, identifier);
  1830.  
  1831.         macro = ralloc (parser, macro_t);
  1832.  
  1833.         macro->is_function = 0;
  1834.         macro->parameters = NULL;
  1835.         macro->identifier = ralloc_strdup (macro, identifier);
  1836.         macro->replacements = replacements;
  1837.         ralloc_steal (macro, replacements);
  1838.  
  1839.         previous = hash_table_find (parser->defines, identifier);
  1840.         if (previous) {
  1841.                 if (_macro_equal (macro, previous)) {
  1842.                         ralloc_free (macro);
  1843.                         return;
  1844.                 }
  1845.                 glcpp_error (loc, parser, "Redefinition of macro %s\n",
  1846.                              identifier);
  1847.         }
  1848.  
  1849.         hash_table_insert (parser->defines, macro, identifier);
  1850. }
  1851.  
  1852. void
  1853. _define_function_macro (glcpp_parser_t *parser,
  1854.                         YYLTYPE *loc,
  1855.                         const char *identifier,
  1856.                         string_list_t *parameters,
  1857.                         token_list_t *replacements)
  1858. {
  1859.         macro_t *macro, *previous;
  1860.  
  1861.         _check_for_reserved_macro_name(parser, loc, identifier);
  1862.  
  1863.         macro = ralloc (parser, macro_t);
  1864.         ralloc_steal (macro, parameters);
  1865.         ralloc_steal (macro, replacements);
  1866.  
  1867.         macro->is_function = 1;
  1868.         macro->parameters = parameters;
  1869.         macro->identifier = ralloc_strdup (macro, identifier);
  1870.         macro->replacements = replacements;
  1871.         previous = hash_table_find (parser->defines, identifier);
  1872.         if (previous) {
  1873.                 if (_macro_equal (macro, previous)) {
  1874.                         ralloc_free (macro);
  1875.                         return;
  1876.                 }
  1877.                 glcpp_error (loc, parser, "Redefinition of macro %s\n",
  1878.                              identifier);
  1879.         }
  1880.  
  1881.         hash_table_insert (parser->defines, macro, identifier);
  1882. }
  1883.  
  1884. static int
  1885. glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser)
  1886. {
  1887.         token_node_t *node;
  1888.         int ret;
  1889.  
  1890.         if (parser->lex_from_list == NULL) {
  1891.                 ret = glcpp_lex (yylval, yylloc, parser->scanner);
  1892.  
  1893.                 /* XXX: This ugly block of code exists for the sole
  1894.                  * purpose of converting a NEWLINE token into a SPACE
  1895.                  * token, but only in the case where we have seen a
  1896.                  * function-like macro name, but have not yet seen its
  1897.                  * closing parenthesis.
  1898.                  *
  1899.                  * There's perhaps a more compact way to do this with
  1900.                  * mid-rule actions in the grammar.
  1901.                  *
  1902.                  * I'm definitely not pleased with the complexity of
  1903.                  * this code here.
  1904.                  */
  1905.                 if (parser->newline_as_space)
  1906.                 {
  1907.                         if (ret == '(') {
  1908.                                 parser->paren_count++;
  1909.                         } else if (ret == ')') {
  1910.                                 parser->paren_count--;
  1911.                                 if (parser->paren_count == 0)
  1912.                                         parser->newline_as_space = 0;
  1913.                         } else if (ret == NEWLINE) {
  1914.                                 ret = SPACE;
  1915.                         } else if (ret != SPACE) {
  1916.                                 if (parser->paren_count == 0)
  1917.                                         parser->newline_as_space = 0;
  1918.                         }
  1919.                 }
  1920.                 else if (parser->in_control_line)
  1921.                 {
  1922.                         if (ret == NEWLINE)
  1923.                                 parser->in_control_line = 0;
  1924.                 }
  1925.                 else if (ret == HASH_DEFINE ||
  1926.                            ret == HASH_UNDEF || ret == HASH_IF ||
  1927.                            ret == HASH_IFDEF || ret == HASH_IFNDEF ||
  1928.                            ret == HASH_ELIF || ret == HASH_ELSE ||
  1929.                            ret == HASH_ENDIF || ret == HASH)
  1930.                 {
  1931.                         parser->in_control_line = 1;
  1932.                 }
  1933.                 else if (ret == IDENTIFIER)
  1934.                 {
  1935.                         macro_t *macro;
  1936.                         macro = hash_table_find (parser->defines,
  1937.                                                  yylval->str);
  1938.                         if (macro && macro->is_function) {
  1939.                                 parser->newline_as_space = 1;
  1940.                                 parser->paren_count = 0;
  1941.                         }
  1942.                 }
  1943.  
  1944.                 return ret;
  1945.         }
  1946.  
  1947.         node = parser->lex_from_node;
  1948.  
  1949.         if (node == NULL) {
  1950.                 ralloc_free (parser->lex_from_list);
  1951.                 parser->lex_from_list = NULL;
  1952.                 return NEWLINE;
  1953.         }
  1954.  
  1955.         *yylval = node->token->value;
  1956.         ret = node->token->type;
  1957.  
  1958.         parser->lex_from_node = node->next;
  1959.  
  1960.         return ret;
  1961. }
  1962.  
  1963. static void
  1964. glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list)
  1965. {
  1966.         token_node_t *node;
  1967.  
  1968.         assert (parser->lex_from_list == NULL);
  1969.  
  1970.         /* Copy list, eliminating any space tokens. */
  1971.         parser->lex_from_list = _token_list_create (parser);
  1972.  
  1973.         for (node = list->head; node; node = node->next) {
  1974.                 if (node->token->type == SPACE)
  1975.                         continue;
  1976.                 _token_list_append (parser->lex_from_list, node->token);
  1977.         }
  1978.  
  1979.         ralloc_free (list);
  1980.  
  1981.         parser->lex_from_node = parser->lex_from_list->head;
  1982.  
  1983.         /* It's possible the list consisted of nothing but whitespace. */
  1984.         if (parser->lex_from_node == NULL) {
  1985.                 ralloc_free (parser->lex_from_list);
  1986.                 parser->lex_from_list = NULL;
  1987.         }
  1988. }
  1989.  
  1990. static void
  1991. _glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc,
  1992.                                   int condition)
  1993. {
  1994.         skip_type_t current = SKIP_NO_SKIP;
  1995.         skip_node_t *node;
  1996.  
  1997.         if (parser->skip_stack)
  1998.                 current = parser->skip_stack->type;
  1999.  
  2000.         node = ralloc (parser, skip_node_t);
  2001.         node->loc = *loc;
  2002.  
  2003.         if (current == SKIP_NO_SKIP) {
  2004.                 if (condition)
  2005.                         node->type = SKIP_NO_SKIP;
  2006.                 else
  2007.                         node->type = SKIP_TO_ELSE;
  2008.         } else {
  2009.                 node->type = SKIP_TO_ENDIF;
  2010.         }
  2011.  
  2012.         node->next = parser->skip_stack;
  2013.         parser->skip_stack = node;
  2014. }
  2015.  
  2016. static void
  2017. _glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc,
  2018.                                     const char *type, int condition)
  2019. {
  2020.         if (parser->skip_stack == NULL) {
  2021.                 glcpp_error (loc, parser, "%s without #if\n", type);
  2022.                 return;
  2023.         }
  2024.  
  2025.         if (parser->skip_stack->type == SKIP_TO_ELSE) {
  2026.                 if (condition)
  2027.                         parser->skip_stack->type = SKIP_NO_SKIP;
  2028.         } else {
  2029.                 parser->skip_stack->type = SKIP_TO_ENDIF;
  2030.         }
  2031. }
  2032.  
  2033. static void
  2034. _glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc)
  2035. {
  2036.         skip_node_t *node;
  2037.  
  2038.         if (parser->skip_stack == NULL) {
  2039.                 glcpp_error (loc, parser, "#endif without #if\n");
  2040.                 return;
  2041.         }
  2042.  
  2043.         node = parser->skip_stack;
  2044.         parser->skip_stack = node->next;
  2045.         ralloc_free (node);
  2046. }
  2047.  
  2048. static void
  2049. _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version,
  2050.                                          const char *es_identifier)
  2051. {
  2052.         macro_t *macro = hash_table_find (parser->defines, "__VERSION__");
  2053.         if (macro) {
  2054.                 hash_table_remove (parser->defines, "__VERSION__");
  2055.                 ralloc_free (macro);
  2056.         }
  2057.         add_builtin_define (parser, "__VERSION__", version);
  2058.  
  2059.         /* If we didn't have a GLES context to begin with, (indicated
  2060.          * by parser->api), then the version declaration here might
  2061.          * indicate GLES. */
  2062.         if (! parser->is_gles &&
  2063.             (version == 100 ||
  2064.              (es_identifier && (strcmp(es_identifier, "es") == 0))))
  2065.         {
  2066.                 parser->is_gles = true;
  2067.                 add_builtin_define (parser, "GL_ES", 1);
  2068.         }
  2069.  
  2070.         if (version >= 150)
  2071.                 add_builtin_define(parser, "GL_core_profile", 1);
  2072.  
  2073.         /* Currently, all ES2/ES3 implementations support highp in the
  2074.          * fragment shader, so we always define this macro in ES2/ES3.
  2075.          * If we ever get a driver that doesn't support highp, we'll
  2076.          * need to add a flag to the gl_context and check that here.
  2077.          */
  2078.         if (version >= 130 || parser->is_gles)
  2079.                 add_builtin_define (parser, "GL_FRAGMENT_PRECISION_HIGH", 1);
  2080.  
  2081.         ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length,
  2082.                                       "#version %" PRIiMAX "%s%s", version,
  2083.                                       es_identifier ? " " : "",
  2084.                                       es_identifier ? es_identifier : "");
  2085. }
  2086.