Subversion Repositories Kolibri OS

Rev

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