/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/README |
---|
0,0 → 1,30 |
glcpp -- GLSL "C" preprocessor |
This is a simple preprocessor designed to provide the preprocessing |
needs of the GLSL language. The requirements for this preprocessor are |
specified in the GLSL 1.30 specification availble from: |
http://www.opengl.org/registry/doc/GLSLangSpec.Full.1.30.10.pdf |
This specification is not precise on some semantics, (for example, |
#define and #if), defining these merely "as is standard for C++ |
preprocessors". To fill in these details, I've been using a draft of |
the C99 standard as available from: |
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf |
Any downstream compiler accepting output from glcpp should be prepared |
to encounter and deal with the following preprocessor macros: |
#line |
#pragma |
#extension |
All other macros will be handled according to the GLSL specification |
and will not appear in the output. |
Known limitations |
----------------- |
A file that ends with a function-like macro name as the last |
non-whitespace token will result in a parse error, (where it should be |
passed through as is). |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/glcpp-lex.c |
---|
0,0 → 1,2898 |
#line 2 "glcpp/glcpp-lex.c" |
#line 4 "glcpp/glcpp-lex.c" |
#define YY_INT_ALIGNED short int |
/* A lexical scanner generated by flex */ |
#define FLEX_SCANNER |
#define YY_FLEX_MAJOR_VERSION 2 |
#define YY_FLEX_MINOR_VERSION 5 |
#define YY_FLEX_SUBMINOR_VERSION 39 |
#if YY_FLEX_SUBMINOR_VERSION > 0 |
#define FLEX_BETA |
#endif |
/* First, we deal with platform-specific or compiler-specific issues. */ |
/* begin standard C headers. */ |
#include <stdio.h> |
#include <string.h> |
#include <errno.h> |
#include <stdlib.h> |
/* end standard C headers. */ |
/* flex integer type definitions */ |
#ifndef FLEXINT_H |
#define FLEXINT_H |
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ |
#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L |
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, |
* if you want the limit (max/min) macros for int types. |
*/ |
#ifndef __STDC_LIMIT_MACROS |
#define __STDC_LIMIT_MACROS 1 |
#endif |
#include <inttypes.h> |
typedef int8_t flex_int8_t; |
typedef uint8_t flex_uint8_t; |
typedef int16_t flex_int16_t; |
typedef uint16_t flex_uint16_t; |
typedef int32_t flex_int32_t; |
typedef uint32_t flex_uint32_t; |
#else |
typedef signed char flex_int8_t; |
typedef short int flex_int16_t; |
typedef int flex_int32_t; |
typedef unsigned char flex_uint8_t; |
typedef unsigned short int flex_uint16_t; |
typedef unsigned int flex_uint32_t; |
/* Limits of integral types. */ |
#ifndef INT8_MIN |
#define INT8_MIN (-128) |
#endif |
#ifndef INT16_MIN |
#define INT16_MIN (-32767-1) |
#endif |
#ifndef INT32_MIN |
#define INT32_MIN (-2147483647-1) |
#endif |
#ifndef INT8_MAX |
#define INT8_MAX (127) |
#endif |
#ifndef INT16_MAX |
#define INT16_MAX (32767) |
#endif |
#ifndef INT32_MAX |
#define INT32_MAX (2147483647) |
#endif |
#ifndef UINT8_MAX |
#define UINT8_MAX (255U) |
#endif |
#ifndef UINT16_MAX |
#define UINT16_MAX (65535U) |
#endif |
#ifndef UINT32_MAX |
#define UINT32_MAX (4294967295U) |
#endif |
#endif /* ! C99 */ |
#endif /* ! FLEXINT_H */ |
#ifdef __cplusplus |
/* The "const" storage-class-modifier is valid. */ |
#define YY_USE_CONST |
#else /* ! __cplusplus */ |
/* C99 requires __STDC__ to be defined as 1. */ |
#if defined (__STDC__) |
#define YY_USE_CONST |
#endif /* defined (__STDC__) */ |
#endif /* ! __cplusplus */ |
#ifdef YY_USE_CONST |
#define yyconst const |
#else |
#define yyconst |
#endif |
/* Returned upon end-of-file. */ |
#define YY_NULL 0 |
/* Promotes a possibly negative, possibly signed char to an unsigned |
* integer for use as an array index. If the signed char is negative, |
* we want to instead treat it as an 8-bit unsigned char, hence the |
* double cast. |
*/ |
#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) |
/* An opaque pointer. */ |
#ifndef YY_TYPEDEF_YY_SCANNER_T |
#define YY_TYPEDEF_YY_SCANNER_T |
typedef void* yyscan_t; |
#endif |
/* For convenience, these vars (plus the bison vars far below) |
are macros in the reentrant scanner. */ |
#define yyin yyg->yyin_r |
#define yyout yyg->yyout_r |
#define yyextra yyg->yyextra_r |
#define yyleng yyg->yyleng_r |
#define yytext yyg->yytext_r |
#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) |
#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) |
#define yy_flex_debug yyg->yy_flex_debug_r |
/* Enter a start condition. This macro really ought to take a parameter, |
* but we do it the disgusting crufty way forced on us by the ()-less |
* definition of BEGIN. |
*/ |
#define BEGIN yyg->yy_start = 1 + 2 * |
/* Translate the current start state into a value that can be later handed |
* to BEGIN to return to the state. The YYSTATE alias is for lex |
* compatibility. |
*/ |
#define YY_START ((yyg->yy_start - 1) / 2) |
#define YYSTATE YY_START |
/* Action number for EOF rule of a given start state. */ |
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) |
/* Special action meaning "start processing a new file". */ |
#define YY_NEW_FILE glcpp_restart(yyin ,yyscanner ) |
#define YY_END_OF_BUFFER_CHAR 0 |
/* Size of default input buffer. */ |
#ifndef YY_BUF_SIZE |
#define YY_BUF_SIZE 16384 |
#endif |
/* The state buf must be large enough to hold one state per character in the main buffer. |
*/ |
#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) |
#ifndef YY_TYPEDEF_YY_BUFFER_STATE |
#define YY_TYPEDEF_YY_BUFFER_STATE |
typedef struct yy_buffer_state *YY_BUFFER_STATE; |
#endif |
#ifndef YY_TYPEDEF_YY_SIZE_T |
#define YY_TYPEDEF_YY_SIZE_T |
typedef size_t yy_size_t; |
#endif |
#define EOB_ACT_CONTINUE_SCAN 0 |
#define EOB_ACT_END_OF_FILE 1 |
#define EOB_ACT_LAST_MATCH 2 |
#define YY_LESS_LINENO(n) |
#define YY_LINENO_REWIND_TO(ptr) |
/* Return all but the first "n" matched characters back to the input stream. */ |
#define yyless(n) \ |
do \ |
{ \ |
/* Undo effects of setting up yytext. */ \ |
int yyless_macro_arg = (n); \ |
YY_LESS_LINENO(yyless_macro_arg);\ |
*yy_cp = yyg->yy_hold_char; \ |
YY_RESTORE_YY_MORE_OFFSET \ |
yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ |
YY_DO_BEFORE_ACTION; /* set up yytext again */ \ |
} \ |
while ( 0 ) |
#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) |
#ifndef YY_STRUCT_YY_BUFFER_STATE |
#define YY_STRUCT_YY_BUFFER_STATE |
struct yy_buffer_state |
{ |
FILE *yy_input_file; |
char *yy_ch_buf; /* input buffer */ |
char *yy_buf_pos; /* current position in input buffer */ |
/* Size of input buffer in bytes, not including room for EOB |
* characters. |
*/ |
yy_size_t yy_buf_size; |
/* Number of characters read into yy_ch_buf, not including EOB |
* characters. |
*/ |
yy_size_t yy_n_chars; |
/* Whether we "own" the buffer - i.e., we know we created it, |
* and can realloc() it to grow it, and should free() it to |
* delete it. |
*/ |
int yy_is_our_buffer; |
/* Whether this is an "interactive" input source; if so, and |
* if we're using stdio for input, then we want to use getc() |
* instead of fread(), to make sure we stop fetching input after |
* each newline. |
*/ |
int yy_is_interactive; |
/* Whether we're considered to be at the beginning of a line. |
* If so, '^' rules will be active on the next match, otherwise |
* not. |
*/ |
int yy_at_bol; |
int yy_bs_lineno; /**< The line count. */ |
int yy_bs_column; /**< The column count. */ |
/* Whether to try to fill the input buffer when we reach the |
* end of it. |
*/ |
int yy_fill_buffer; |
int yy_buffer_status; |
#define YY_BUFFER_NEW 0 |
#define YY_BUFFER_NORMAL 1 |
/* When an EOF's been seen but there's still some text to process |
* then we mark the buffer as YY_EOF_PENDING, to indicate that we |
* shouldn't try reading from the input source any more. We might |
* still have a bunch of tokens to match, though, because of |
* possible backing-up. |
* |
* When we actually see the EOF, we change the status to "new" |
* (via glcpp_restart()), so that the user can continue scanning by |
* just pointing yyin at a new input file. |
*/ |
#define YY_BUFFER_EOF_PENDING 2 |
}; |
#endif /* !YY_STRUCT_YY_BUFFER_STATE */ |
/* We provide macros for accessing buffer states in case in the |
* future we want to put the buffer states in a more general |
* "scanner state". |
* |
* Returns the top of the stack, or NULL. |
*/ |
#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ |
? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ |
: NULL) |
/* Same as previous macro, but useful when we know that the buffer stack is not |
* NULL or when we need an lvalue. For internal use only. |
*/ |
#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] |
void glcpp_restart (FILE *input_file ,yyscan_t yyscanner ); |
void glcpp__switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); |
YY_BUFFER_STATE glcpp__create_buffer (FILE *file,int size ,yyscan_t yyscanner ); |
void glcpp__delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); |
void glcpp__flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); |
void glcpp_push_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); |
void glcpp_pop_buffer_state (yyscan_t yyscanner ); |
static void glcpp_ensure_buffer_stack (yyscan_t yyscanner ); |
static void glcpp__load_buffer_state (yyscan_t yyscanner ); |
static void glcpp__init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); |
#define YY_FLUSH_BUFFER glcpp__flush_buffer(YY_CURRENT_BUFFER ,yyscanner) |
YY_BUFFER_STATE glcpp__scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); |
YY_BUFFER_STATE glcpp__scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); |
YY_BUFFER_STATE glcpp__scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); |
void *glcpp_alloc (yy_size_t ,yyscan_t yyscanner ); |
void *glcpp_realloc (void *,yy_size_t ,yyscan_t yyscanner ); |
void glcpp_free (void * ,yyscan_t yyscanner ); |
#define yy_new_buffer glcpp__create_buffer |
#define yy_set_interactive(is_interactive) \ |
{ \ |
if ( ! YY_CURRENT_BUFFER ){ \ |
glcpp_ensure_buffer_stack (yyscanner); \ |
YY_CURRENT_BUFFER_LVALUE = \ |
glcpp__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ |
} \ |
YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ |
} |
#define yy_set_bol(at_bol) \ |
{ \ |
if ( ! YY_CURRENT_BUFFER ){\ |
glcpp_ensure_buffer_stack (yyscanner); \ |
YY_CURRENT_BUFFER_LVALUE = \ |
glcpp__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ |
} \ |
YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ |
} |
#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) |
/* Begin user sect3 */ |
#define glcpp_wrap(yyscanner) 1 |
#define YY_SKIP_YYWRAP |
typedef unsigned char YY_CHAR; |
typedef int yy_state_type; |
#define yytext_ptr yytext_r |
static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); |
static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); |
static int yy_get_next_buffer (yyscan_t yyscanner ); |
static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); |
/* Done after the current pattern has been matched and before the |
* corresponding action - sets up yytext. |
*/ |
#define YY_DO_BEFORE_ACTION \ |
yyg->yytext_ptr = yy_bp; \ |
yyleng = (size_t) (yy_cp - yy_bp); \ |
yyg->yy_hold_char = *yy_cp; \ |
*yy_cp = '\0'; \ |
yyg->yy_c_buf_p = yy_cp; |
#define YY_NUM_RULES 52 |
#define YY_END_OF_BUFFER 53 |
/* This struct is not used in this scanner, |
but its presence is necessary. */ |
struct yy_trans_info |
{ |
flex_int32_t yy_verify; |
flex_int32_t yy_nxt; |
}; |
static yyconst flex_int16_t yy_accept[174] = |
{ 0, |
0, 0, 3, 3, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 53, 48, 49, 50, 51, 50, |
47, 8, 47, 47, 47, 47, 47, 47, 31, 30, |
47, 47, 47, 45, 45, 47, 3, 4, 4, 5, |
29, 27, 51, 26, 24, 23, 13, 13, 24, 24, |
24, 24, 24, 24, 24, 24, 48, 50, 38, 43, |
39, 41, 42, 46, 2, 1, 46, 31, 46, 31, |
46, 30, 30, 33, 35, 37, 36, 34, 45, 45, |
40, 3, 4, 4, 4, 5, 6, 6, 5, 7, |
29, 27, 28, 1, 25, 26, 23, 13, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, 1, 32, |
32, 45, 4, 6, 28, 1, 0, 0, 0, 0, |
0, 0, 16, 0, 0, 0, 0, 0, 0, 32, |
45, 0, 0, 18, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 45, 0, 17, 19, 20, 0, 14, |
0, 12, 0, 22, 0, 45, 21, 20, 0, 15, |
11, 0, 44, 21, 0, 11, 11, 10, 0, 0, |
9, 11, 0 |
} ; |
static yyconst flex_int32_t yy_ec[256] = |
{ 0, |
1, 1, 1, 1, 1, 1, 1, 1, 2, 3, |
4, 4, 5, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 2, 6, 1, 7, 1, 8, 9, 1, 10, |
8, 11, 12, 8, 13, 14, 15, 16, 17, 17, |
17, 17, 17, 17, 17, 18, 18, 1, 8, 19, |
20, 21, 1, 1, 22, 22, 22, 22, 23, 22, |
24, 24, 24, 24, 24, 24, 24, 24, 24, 25, |
24, 24, 24, 24, 26, 24, 24, 27, 24, 24, |
8, 1, 8, 8, 24, 1, 28, 22, 22, 29, |
30, 31, 32, 24, 33, 24, 24, 34, 35, 36, |
37, 38, 24, 39, 40, 41, 42, 43, 24, 44, |
24, 24, 8, 45, 8, 8, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1 |
} ; |
static yyconst flex_int32_t yy_meta[46] = |
{ 0, |
1, 2, 3, 2, 3, 1, 1, 1, 1, 4, |
5, 1, 1, 6, 1, 7, 7, 7, 1, 1, |
1, 7, 7, 7, 7, 7, 7, 7, 8, 7, |
7, 7, 7, 7, 7, 8, 7, 7, 7, 7, |
7, 7, 7, 7, 1 |
} ; |
static yyconst flex_int16_t yy_base[191] = |
{ 0, |
0, 0, 43, 44, 55, 0, 47, 48, 99, 141, |
102, 103, 106, 107, 435, 433, 436, 428, 436, 429, |
411, 423, 436, 420, 416, 414, 99, 107, 169, 198, |
100, 406, 103, 0, 395, 379, 122, 418, 419, 144, |
0, 419, 115, 410, 436, 417, 413, 414, 120, 386, |
114, 384, 381, 374, 376, 381, 409, 436, 436, 436, |
436, 436, 436, 138, 436, 0, 139, 164, 197, 126, |
229, 0, 139, 436, 436, 436, 436, 436, 0, 378, |
436, 131, 403, 404, 436, 186, 401, 402, 197, 436, |
0, 402, 0, 163, 436, 393, 400, 436, 370, 133, |
371, 360, 357, 169, 361, 368, 366, 355, 0, 146, |
191, 360, 436, 436, 0, 227, 359, 360, 360, 356, |
351, 357, 436, 356, 356, 341, 329, 319, 301, 206, |
304, 297, 0, 436, 297, 288, 276, 280, 268, 261, |
220, 219, 216, 218, 214, 436, 436, 0, 203, 436, |
207, 232, 198, 436, 188, 164, 185, 0, 145, 436, |
251, 124, 0, 155, 117, 227, 259, 436, 138, 85, |
111, 234, 436, 264, 272, 280, 283, 285, 293, 301, |
309, 317, 322, 330, 338, 346, 354, 362, 368, 376 |
} ; |
static yyconst flex_int16_t yy_def[191] = |
{ 0, |
173, 1, 174, 174, 173, 5, 175, 175, 176, 176, |
175, 175, 175, 175, 173, 173, 173, 173, 173, 173, |
173, 173, 173, 173, 173, 173, 173, 173, 177, 177, |
173, 173, 173, 178, 178, 173, 179, 173, 173, 180, |
181, 173, 182, 183, 173, 173, 173, 173, 173, 173, |
173, 173, 173, 173, 173, 173, 173, 173, 173, 173, |
173, 173, 173, 177, 173, 184, 177, 30, 177, 69, |
69, 30, 69, 173, 173, 173, 173, 173, 178, 178, |
173, 179, 173, 173, 173, 180, 173, 173, 180, 173, |
181, 173, 185, 186, 173, 183, 173, 173, 173, 173, |
173, 173, 173, 187, 173, 173, 173, 173, 184, 71, |
71, 178, 173, 173, 185, 186, 173, 173, 173, 173, |
173, 173, 173, 173, 173, 173, 173, 173, 173, 69, |
178, 173, 188, 173, 173, 173, 173, 173, 173, 173, |
173, 173, 173, 178, 173, 173, 173, 189, 173, 173, |
173, 173, 173, 173, 173, 178, 173, 189, 173, 173, |
190, 173, 178, 173, 173, 190, 190, 173, 173, 173, |
173, 190, 0, 173, 173, 173, 173, 173, 173, 173, |
173, 173, 173, 173, 173, 173, 173, 173, 173, 173 |
} ; |
static yyconst flex_int16_t yy_nxt[482] = |
{ 0, |
16, 17, 18, 19, 20, 21, 22, 23, 24, 23, |
23, 25, 26, 27, 28, 29, 30, 30, 31, 32, |
33, 34, 34, 34, 34, 34, 34, 34, 35, 34, |
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, |
34, 34, 34, 34, 36, 38, 38, 39, 39, 18, |
18, 20, 20, 40, 40, 41, 42, 18, 19, 20, |
41, 41, 41, 41, 41, 41, 41, 41, 41, 43, |
41, 41, 41, 41, 41, 41, 44, 44, 44, 44, |
44, 44, 44, 44, 44, 44, 44, 44, 44, 44, |
44, 44, 44, 44, 44, 44, 44, 44, 44, 41, |
46, 47, 19, 48, 18, 18, 20, 20, 18, 18, |
20, 20, 171, 49, 64, 64, 64, 65, 74, 75, |
172, 66, 77, 78, 83, 65, 84, 50, 51, 94, |
65, 52, 53, 83, 66, 84, 54, 173, 173, 171, |
55, 56, 46, 47, 19, 48, 87, 100, 88, 101, |
173, 173, 102, 170, 89, 49, 164, 103, 90, 169, |
69, 69, 69, 69, 109, 118, 109, 69, 69, 50, |
51, 130, 119, 52, 53, 69, 69, 165, 54, 68, |
68, 67, 55, 56, 68, 68, 164, 130, 87, 70, |
88, 69, 163, 69, 70, 71, 173, 124, 69, 87, |
173, 88, 67, 67, 125, 70, 69, 89, 67, 67, |
70, 90, 71, 72, 72, 72, 130, 173, 173, 69, |
69, 69, 69, 73, 162, 161, 69, 69, 109, 173, |
109, 173, 130, 152, 69, 69, 173, 160, 173, 73, |
173, 173, 159, 157, 110, 110, 110, 156, 155, 154, |
110, 111, 167, 168, 153, 168, 110, 110, 111, 110, |
167, 168, 152, 168, 37, 37, 37, 37, 37, 37, |
37, 37, 19, 19, 19, 19, 19, 19, 19, 19, |
45, 45, 45, 45, 45, 45, 45, 45, 67, 67, |
67, 79, 79, 82, 82, 82, 82, 151, 82, 82, |
82, 86, 86, 86, 86, 86, 86, 86, 86, 91, |
150, 149, 91, 91, 91, 91, 91, 93, 93, 93, |
93, 93, 93, 93, 93, 96, 148, 147, 96, 96, |
109, 109, 145, 109, 109, 109, 109, 109, 115, 144, |
143, 115, 115, 115, 115, 115, 116, 116, 142, 116, |
116, 116, 116, 116, 123, 123, 123, 123, 123, 123, |
141, 123, 146, 146, 146, 146, 146, 146, 158, 158, |
140, 158, 158, 158, 158, 158, 166, 166, 166, 166, |
166, 166, 166, 166, 139, 138, 137, 136, 135, 134, |
133, 132, 131, 129, 128, 127, 126, 122, 121, 120, |
117, 97, 95, 92, 114, 114, 113, 113, 112, 57, |
108, 107, 106, 105, 104, 99, 98, 98, 97, 95, |
92, 85, 85, 81, 80, 76, 63, 62, 61, 60, |
59, 58, 58, 57, 173, 15, 173, 173, 173, 173, |
173, 173, 173, 173, 173, 173, 173, 173, 173, 173, |
173, 173, 173, 173, 173, 173, 173, 173, 173, 173, |
173, 173, 173, 173, 173, 173, 173, 173, 173, 173, |
173, 173, 173, 173, 173, 173, 173, 173, 173, 173, |
173 |
} ; |
static yyconst flex_int16_t yy_chk[482] = |
{ 0, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 3, 4, 3, 4, 7, |
8, 7, 8, 3, 4, 5, 5, 5, 5, 5, |
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, |
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, |
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, |
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, |
9, 9, 9, 9, 11, 12, 11, 12, 13, 14, |
13, 14, 171, 9, 27, 27, 27, 28, 31, 31, |
170, 28, 33, 33, 37, 43, 37, 9, 9, 43, |
49, 9, 9, 82, 49, 82, 9, 70, 70, 169, |
9, 9, 10, 10, 10, 10, 40, 51, 40, 51, |
73, 73, 51, 165, 40, 10, 164, 51, 40, 162, |
64, 67, 64, 67, 94, 100, 94, 64, 67, 10, |
10, 110, 100, 10, 10, 64, 67, 159, 10, 68, |
68, 68, 10, 10, 29, 29, 157, 110, 86, 68, |
86, 29, 156, 29, 29, 29, 86, 104, 29, 89, |
86, 89, 111, 111, 104, 68, 29, 89, 69, 69, |
29, 89, 29, 30, 30, 30, 111, 130, 130, 69, |
30, 69, 30, 30, 155, 153, 69, 30, 116, 166, |
116, 166, 111, 152, 69, 30, 172, 151, 172, 30, |
71, 71, 149, 145, 71, 71, 71, 144, 143, 142, |
71, 71, 161, 161, 141, 161, 71, 71, 71, 71, |
167, 167, 140, 167, 174, 174, 174, 174, 174, 174, |
174, 174, 175, 175, 175, 175, 175, 175, 175, 175, |
176, 176, 176, 176, 176, 176, 176, 176, 177, 177, |
177, 178, 178, 179, 179, 179, 179, 139, 179, 179, |
179, 180, 180, 180, 180, 180, 180, 180, 180, 181, |
138, 137, 181, 181, 181, 181, 181, 182, 182, 182, |
182, 182, 182, 182, 182, 183, 136, 135, 183, 183, |
184, 184, 132, 184, 184, 184, 184, 184, 185, 131, |
129, 185, 185, 185, 185, 185, 186, 186, 128, 186, |
186, 186, 186, 186, 187, 187, 187, 187, 187, 187, |
127, 187, 188, 188, 188, 188, 188, 188, 189, 189, |
126, 189, 189, 189, 189, 189, 190, 190, 190, 190, |
190, 190, 190, 190, 125, 124, 122, 121, 120, 119, |
118, 117, 112, 108, 107, 106, 105, 103, 102, 101, |
99, 97, 96, 92, 88, 87, 84, 83, 80, 57, |
56, 55, 54, 53, 52, 50, 48, 47, 46, 44, |
42, 39, 38, 36, 35, 32, 26, 25, 24, 22, |
21, 20, 18, 16, 15, 173, 173, 173, 173, 173, |
173, 173, 173, 173, 173, 173, 173, 173, 173, 173, |
173, 173, 173, 173, 173, 173, 173, 173, 173, 173, |
173, 173, 173, 173, 173, 173, 173, 173, 173, 173, |
173, 173, 173, 173, 173, 173, 173, 173, 173, 173, |
173 |
} ; |
/* The intent behind this definition is that it'll catch |
* any uses of REJECT which flex missed. |
*/ |
#define REJECT reject_used_but_not_detected |
#define yymore() yymore_used_but_not_detected |
#define YY_MORE_ADJ 0 |
#define YY_RESTORE_YY_MORE_OFFSET |
#line 1 "../../../src/glsl/glcpp/glcpp-lex.l" |
#line 2 "../../../src/glsl/glcpp/glcpp-lex.l" |
/* |
* Copyright © 2010 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#include <stdio.h> |
#include <string.h> |
#include <ctype.h> |
#include "glcpp.h" |
#include "glcpp-parse.h" |
/* Flex annoyingly generates some functions without making them |
* static. Let's declare them here. */ |
int glcpp_get_column (yyscan_t yyscanner); |
void glcpp_set_column (int column_no , yyscan_t yyscanner); |
#ifdef _MSC_VER |
#define YY_NO_UNISTD_H |
#endif |
#define YY_NO_INPUT |
#define YY_USER_ACTION \ |
do { \ |
if (parser->has_new_line_number) \ |
yylineno = parser->new_line_number; \ |
if (parser->has_new_source_number) \ |
yylloc->source = parser->new_source_number; \ |
yylloc->first_column = yycolumn + 1; \ |
yylloc->first_line = yylloc->last_line = yylineno; \ |
yycolumn += yyleng; \ |
yylloc->last_column = yycolumn + 1; \ |
parser->has_new_line_number = 0; \ |
parser->has_new_source_number = 0; \ |
} while(0); |
#define YY_USER_INIT \ |
do { \ |
yylineno = 1; \ |
yycolumn = 0; \ |
yylloc->source = 0; \ |
} while(0) |
/* It's ugly to have macros that have return statements inside of |
* them, but flex-based lexer generation is all built around the |
* return statement. |
* |
* To mitigate the ugliness, we defer as much of the logic as possible |
* to an actual function, not a macro (see |
* glcpplex_update_state_per_token) and we make the word RETURN |
* prominent in all of the macros which may return. |
* |
* The most-commonly-used macro is RETURN_TOKEN which will perform all |
* necessary state updates based on the provided token,, then |
* conditionally return the token. It will not return a token if the |
* parser is currently skipping tokens, (such as within #if |
* 0...#else). |
* |
* The RETURN_TOKEN_NEVER_SKIP macro is a lower-level variant that |
* makes the token returning unconditional. This is needed for things |
* like #if and the tokens of its condition, (since these must be |
* evaluated by the parser even when otherwise skipping). |
* |
* Finally, RETURN_STRING_TOKEN is a simple convenience wrapper on top |
* of RETURN_TOKEN that performs a string copy of yytext before the |
* return. |
*/ |
#define RETURN_TOKEN_NEVER_SKIP(token) \ |
do { \ |
if (glcpp_lex_update_state_per_token (parser, token)) \ |
return token; \ |
} while (0) |
#define RETURN_TOKEN(token) \ |
do { \ |
if (! parser->skipping) { \ |
RETURN_TOKEN_NEVER_SKIP(token); \ |
} \ |
} while(0) |
#define RETURN_STRING_TOKEN(token) \ |
do { \ |
if (! parser->skipping) { \ |
yylval->str = ralloc_strdup (yyextra, yytext); \ |
RETURN_TOKEN_NEVER_SKIP (token); \ |
} \ |
} while(0) |
/* Update all state necessary for each token being returned. |
* |
* Here we'll be tracking newlines and spaces so that the lexer can |
* alter its behavior as necessary, (for example, '#' has special |
* significance if it is the first non-whitespace, non-comment token |
* in a line, but does not otherwise). |
* |
* NOTE: If this function returns FALSE, then no token should be |
* returned at all. This is used to suprress duplicate SPACE tokens. |
*/ |
static int |
glcpp_lex_update_state_per_token (glcpp_parser_t *parser, int token) |
{ |
/* After the first non-space token in a line, we won't |
* allow any '#' to introduce a directive. */ |
if (token == NEWLINE) { |
parser->first_non_space_token_this_line = 1; |
} else if (token != SPACE) { |
parser->first_non_space_token_this_line = 0; |
} |
/* Track newlines just to know whether a newline needs |
* to be inserted if end-of-file comes early. */ |
if (token == NEWLINE) { |
parser->last_token_was_newline = 1; |
} else { |
parser->last_token_was_newline = 0; |
} |
/* Track spaces to avoid emitting multiple SPACE |
* tokens in a row. */ |
if (token == SPACE) { |
if (! parser->last_token_was_space) { |
parser->last_token_was_space = 1; |
return 1; |
} else { |
parser->last_token_was_space = 1; |
return 0; |
} |
} else { |
parser->last_token_was_space = 0; |
return 1; |
} |
} |
/* Note: When adding any start conditions to this list, you must also |
* update the "Internal compiler error" catch-all rule near the end of |
* this file. */ |
/* The OTHER class is simply a catch-all for things that the CPP |
parser just doesn't care about. Since flex regular expressions that |
match longer strings take priority over those matching shorter |
strings, we have to be careful to avoid OTHER matching and hiding |
something that CPP does care about. So we simply exclude all |
characters that appear in any other expressions. */ |
#line 763 "glcpp/glcpp-lex.c" |
#define INITIAL 0 |
#define COMMENT 1 |
#define DEFINE 2 |
#define DONE 3 |
#define HASH 4 |
#define NEWLINE_CATCHUP 5 |
#define UNREACHABLE 6 |
#ifndef YY_NO_UNISTD_H |
/* Special case for "unistd.h", since it is non-ANSI. We include it way |
* down here because we want the user's section 1 to have been scanned first. |
* The user has a chance to override it with an option. |
*/ |
#include <unistd.h> |
#endif |
#define YY_EXTRA_TYPE glcpp_parser_t * |
/* Holds the entire state of the reentrant scanner. */ |
struct yyguts_t |
{ |
/* User-defined. Not touched by flex. */ |
YY_EXTRA_TYPE yyextra_r; |
/* The rest are the same as the globals declared in the non-reentrant scanner. */ |
FILE *yyin_r, *yyout_r; |
size_t yy_buffer_stack_top; /**< index of top of stack. */ |
size_t yy_buffer_stack_max; /**< capacity of stack. */ |
YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ |
char yy_hold_char; |
yy_size_t yy_n_chars; |
yy_size_t yyleng_r; |
char *yy_c_buf_p; |
int yy_init; |
int yy_start; |
int yy_did_buffer_switch_on_eof; |
int yy_start_stack_ptr; |
int yy_start_stack_depth; |
int *yy_start_stack; |
yy_state_type yy_last_accepting_state; |
char* yy_last_accepting_cpos; |
int yylineno_r; |
int yy_flex_debug_r; |
char *yytext_r; |
int yy_more_flag; |
int yy_more_len; |
YYSTYPE * yylval_r; |
YYLTYPE * yylloc_r; |
}; /* end struct yyguts_t */ |
static int yy_init_globals (yyscan_t yyscanner ); |
/* This must go here because YYSTYPE and YYLTYPE are included |
* from bison output in section 1.*/ |
# define yylval yyg->yylval_r |
# define yylloc yyg->yylloc_r |
int glcpp_lex_init (yyscan_t* scanner); |
int glcpp_lex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); |
/* Accessor methods to globals. |
These are made visible to non-reentrant scanners for convenience. */ |
int glcpp_lex_destroy (yyscan_t yyscanner ); |
int glcpp_get_debug (yyscan_t yyscanner ); |
void glcpp_set_debug (int debug_flag ,yyscan_t yyscanner ); |
YY_EXTRA_TYPE glcpp_get_extra (yyscan_t yyscanner ); |
void glcpp_set_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); |
FILE *glcpp_get_in (yyscan_t yyscanner ); |
void glcpp_set_in (FILE * in_str ,yyscan_t yyscanner ); |
FILE *glcpp_get_out (yyscan_t yyscanner ); |
void glcpp_set_out (FILE * out_str ,yyscan_t yyscanner ); |
yy_size_t glcpp_get_leng (yyscan_t yyscanner ); |
char *glcpp_get_text (yyscan_t yyscanner ); |
int glcpp_get_lineno (yyscan_t yyscanner ); |
void glcpp_set_lineno (int line_number ,yyscan_t yyscanner ); |
int glcpp_get_column (yyscan_t yyscanner ); |
void glcpp_set_column (int column_no ,yyscan_t yyscanner ); |
YYSTYPE * glcpp_get_lval (yyscan_t yyscanner ); |
void glcpp_set_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); |
YYLTYPE *glcpp_get_lloc (yyscan_t yyscanner ); |
void glcpp_set_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); |
/* Macros after this point can all be overridden by user definitions in |
* section 1. |
*/ |
#ifndef YY_SKIP_YYWRAP |
#ifdef __cplusplus |
extern "C" int glcpp_wrap (yyscan_t yyscanner ); |
#else |
extern int glcpp_wrap (yyscan_t yyscanner ); |
#endif |
#endif |
static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); |
#ifndef yytext_ptr |
static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); |
#endif |
#ifdef YY_NEED_STRLEN |
static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); |
#endif |
#ifndef YY_NO_INPUT |
#ifdef __cplusplus |
static int yyinput (yyscan_t yyscanner ); |
#else |
static int input (yyscan_t yyscanner ); |
#endif |
#endif |
static void yy_push_state (int new_state ,yyscan_t yyscanner); |
static void yy_pop_state (yyscan_t yyscanner ); |
static int yy_top_state (yyscan_t yyscanner ); |
/* Amount of stuff to slurp up with each read. */ |
#ifndef YY_READ_BUF_SIZE |
#define YY_READ_BUF_SIZE 8192 |
#endif |
/* Copy whatever the last rule matched to the standard output. */ |
#ifndef ECHO |
/* This used to be an fputs(), but since the string might contain NUL's, |
* we now use fwrite(). |
*/ |
#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) |
#endif |
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, |
* is returned in "result". |
*/ |
#ifndef YY_INPUT |
#define YY_INPUT(buf,result,max_size) \ |
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ |
{ \ |
int c = '*'; \ |
size_t n; \ |
for ( n = 0; n < max_size && \ |
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \ |
buf[n] = (char) c; \ |
if ( c == '\n' ) \ |
buf[n++] = (char) c; \ |
if ( c == EOF && ferror( yyin ) ) \ |
YY_FATAL_ERROR( "input in flex scanner failed" ); \ |
result = n; \ |
} \ |
else \ |
{ \ |
errno=0; \ |
while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ |
{ \ |
if( errno != EINTR) \ |
{ \ |
YY_FATAL_ERROR( "input in flex scanner failed" ); \ |
break; \ |
} \ |
errno=0; \ |
clearerr(yyin); \ |
} \ |
}\ |
\ |
#endif |
/* No semi-colon after return; correct usage is to write "yyterminate();" - |
* we don't want an extra ';' after the "return" because that will cause |
* some compilers to complain about unreachable statements. |
*/ |
#ifndef yyterminate |
#define yyterminate() return YY_NULL |
#endif |
/* Number of entries by which start-condition stack grows. */ |
#ifndef YY_START_STACK_INCR |
#define YY_START_STACK_INCR 25 |
#endif |
/* Report a fatal error. */ |
#ifndef YY_FATAL_ERROR |
#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) |
#endif |
/* end tables serialization structures and prototypes */ |
/* Default declaration of generated scanner - a define so the user can |
* easily add parameters. |
*/ |
#ifndef YY_DECL |
#define YY_DECL_IS_OURS 1 |
extern int glcpp_lex \ |
(YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); |
#define YY_DECL int glcpp_lex \ |
(YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) |
#endif /* !YY_DECL */ |
/* Code executed at the beginning of each rule, after yytext and yyleng |
* have been set up. |
*/ |
#ifndef YY_USER_ACTION |
#define YY_USER_ACTION |
#endif |
/* Code executed at the end of each rule. */ |
#ifndef YY_BREAK |
#define YY_BREAK break; |
#endif |
#define YY_RULE_SETUP \ |
YY_USER_ACTION |
/** The main scanner function which does all the work. |
*/ |
YY_DECL |
{ |
register yy_state_type yy_current_state; |
register char *yy_cp, *yy_bp; |
register int yy_act; |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
yylval = yylval_param; |
yylloc = yylloc_param; |
if ( !yyg->yy_init ) |
{ |
yyg->yy_init = 1; |
#ifdef YY_USER_INIT |
YY_USER_INIT; |
#endif |
if ( ! yyg->yy_start ) |
yyg->yy_start = 1; /* first start state */ |
if ( ! yyin ) |
yyin = stdin; |
if ( ! yyout ) |
yyout = stdout; |
if ( ! YY_CURRENT_BUFFER ) { |
glcpp_ensure_buffer_stack (yyscanner); |
YY_CURRENT_BUFFER_LVALUE = |
glcpp__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); |
} |
glcpp__load_buffer_state(yyscanner ); |
} |
{ |
#line 194 "../../../src/glsl/glcpp/glcpp-lex.l" |
glcpp_parser_t *parser = yyextra; |
/* When we lex a multi-line comment, we replace it (as |
* specified) with a single space. But if the comment spanned |
* multiple lines, then subsequent parsing stages will not |
* count correct line numbers. To avoid this problem we keep |
* track of all newlines that were commented out by a |
* multi-line comment, and we emit a NEWLINE token for each at |
* the next legal opportunity, (which is when the lexer would |
* be emitting a NEWLINE token anyway). |
*/ |
if (YY_START == NEWLINE_CATCHUP) { |
if (parser->commented_newlines) |
parser->commented_newlines--; |
if (parser->commented_newlines == 0) |
BEGIN INITIAL; |
RETURN_TOKEN_NEVER_SKIP (NEWLINE); |
} |
/* Set up the parser->skipping bit here before doing any lexing. |
* |
* This bit controls whether tokens are skipped, (as implemented by |
* RETURN_TOKEN), such as between "#if 0" and "#endif". |
* |
* The parser maintains a skip_stack indicating whether we should be |
* skipping, (and nested levels of #if/#ifdef/#ifndef/#endif) will |
* push and pop items from the stack. |
* |
* Here are the rules for determining whether we are skipping: |
* |
* 1. If the skip stack is NULL, we are outside of all #if blocks |
* and we are not skipping. |
* |
* 2. If the skip stack is non-NULL, the type of the top node in |
* the stack determines whether to skip. A type of |
* SKIP_NO_SKIP is used for blocks wheere we are emitting |
* tokens, (such as between #if 1 and #endif, or after the |
* #else of an #if 0, etc.). |
* |
* 3. The lexing_directive bit overrides the skip stack. This bit |
* is set when we are actively lexing the expression for a |
* pre-processor condition, (such as #if, #elif, or #else). In |
* this case, even if otherwise skipping, we need to emit the |
* tokens for this condition so that the parser can evaluate |
* the expression. (For, #else, there's no expression, but we |
* emit tokens so the parser can generate a nice error message |
* if there are any tokens here). |
*/ |
if (parser->skip_stack && |
parser->skip_stack->type != SKIP_NO_SKIP && |
! parser->lexing_directive) |
{ |
parser->skipping = 1; |
} else { |
parser->skipping = 0; |
} |
/* Single-line comments */ |
#line 1110 "glcpp/glcpp-lex.c" |
while ( 1 ) /* loops until end-of-file is reached */ |
{ |
yy_cp = yyg->yy_c_buf_p; |
/* Support of yytext. */ |
*yy_cp = yyg->yy_hold_char; |
/* yy_bp points to the position in yy_ch_buf of the start of |
* the current run. |
*/ |
yy_bp = yy_cp; |
yy_current_state = yyg->yy_start; |
yy_match: |
do |
{ |
register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; |
if ( yy_accept[yy_current_state] ) |
{ |
yyg->yy_last_accepting_state = yy_current_state; |
yyg->yy_last_accepting_cpos = yy_cp; |
} |
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) |
{ |
yy_current_state = (int) yy_def[yy_current_state]; |
if ( yy_current_state >= 174 ) |
yy_c = yy_meta[(unsigned int) yy_c]; |
} |
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; |
++yy_cp; |
} |
while ( yy_current_state != 173 ); |
yy_cp = yyg->yy_last_accepting_cpos; |
yy_current_state = yyg->yy_last_accepting_state; |
yy_find_action: |
yy_act = yy_accept[yy_current_state]; |
YY_DO_BEFORE_ACTION; |
do_action: /* This label is used only to access EOF actions. */ |
switch ( yy_act ) |
{ /* beginning of action switch */ |
case 0: /* must back up */ |
/* undo the effects of YY_DO_BEFORE_ACTION */ |
*yy_cp = yyg->yy_hold_char; |
yy_cp = yyg->yy_last_accepting_cpos; |
yy_current_state = yyg->yy_last_accepting_state; |
goto yy_find_action; |
case 1: |
YY_RULE_SETUP |
#line 254 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
} |
YY_BREAK |
/* Multi-line comments */ |
case 2: |
YY_RULE_SETUP |
#line 258 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ yy_push_state(COMMENT, yyscanner); } |
YY_BREAK |
case 3: |
YY_RULE_SETUP |
#line 259 "../../../src/glsl/glcpp/glcpp-lex.l" |
YY_BREAK |
case 4: |
/* rule 4 can match eol */ |
YY_RULE_SETUP |
#line 260 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ yylineno++; yycolumn = 0; parser->commented_newlines++; } |
YY_BREAK |
case 5: |
YY_RULE_SETUP |
#line 261 "../../../src/glsl/glcpp/glcpp-lex.l" |
YY_BREAK |
case 6: |
/* rule 6 can match eol */ |
YY_RULE_SETUP |
#line 262 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ yylineno++; yycolumn = 0; parser->commented_newlines++; } |
YY_BREAK |
case 7: |
YY_RULE_SETUP |
#line 263 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
yy_pop_state(yyscanner); |
/* In the <HASH> start condition, we don't want any SPACE token. */ |
if (yyextra->space_tokens && YY_START != HASH) |
RETURN_TOKEN (SPACE); |
} |
YY_BREAK |
case 8: |
YY_RULE_SETUP |
#line 270 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
/* If the '#' is the first non-whitespace, non-comment token on this |
* line, then it introduces a directive, switch to the <HASH> start |
* condition. |
* |
* Otherwise, this is just punctuation, so return the HASH_TOKEN |
* token. */ |
if (parser->first_non_space_token_this_line) { |
BEGIN HASH; |
} |
RETURN_TOKEN_NEVER_SKIP (HASH_TOKEN); |
} |
YY_BREAK |
case 9: |
YY_RULE_SETUP |
#line 285 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
yyextra->space_tokens = 0; |
RETURN_STRING_TOKEN (VERSION_TOKEN); |
} |
YY_BREAK |
/* Swallow empty #pragma directives, (to avoid confusing the |
* downstream compiler). |
* |
* Note: We use a simple regular expression for the lookahead |
* here. Specifically, we cannot use the complete {NEWLINE} expression |
* since it uses alternation and we've found that there's a flex bug |
* where using alternation in the lookahead portion of a pattern |
* triggers a buffer overrun. */ |
case 10: |
/* rule 10 can match eol */ |
*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ |
YY_LINENO_REWIND_TO(yy_cp - 1); |
yyg->yy_c_buf_p = yy_cp -= 1; |
YY_DO_BEFORE_ACTION; /* set up yytext again */ |
YY_RULE_SETUP |
#line 299 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
} |
YY_BREAK |
/* glcpp doesn't handle #extension, #version, or #pragma directives. |
* Simply pass them through to the main compiler's lexer/parser. */ |
case 11: |
YY_RULE_SETUP |
#line 305 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
RETURN_STRING_TOKEN (PRAGMA); |
} |
YY_BREAK |
case 12: |
YY_RULE_SETUP |
#line 310 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
RETURN_TOKEN (LINE); |
} |
YY_BREAK |
case 13: |
/* rule 13 can match eol */ |
YY_RULE_SETUP |
#line 315 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
RETURN_TOKEN_NEVER_SKIP (NEWLINE); |
} |
YY_BREAK |
/* For the pre-processor directives, we return these tokens |
* even when we are otherwise skipping. */ |
case 14: |
YY_RULE_SETUP |
#line 322 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
yyextra->lexing_directive = 1; |
yyextra->space_tokens = 0; |
RETURN_TOKEN_NEVER_SKIP (IFDEF); |
} |
YY_BREAK |
case 15: |
YY_RULE_SETUP |
#line 329 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
yyextra->lexing_directive = 1; |
yyextra->space_tokens = 0; |
RETURN_TOKEN_NEVER_SKIP (IFNDEF); |
} |
YY_BREAK |
case 16: |
/* rule 16 can match eol */ |
*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ |
YY_LINENO_REWIND_TO(yy_bp + 2); |
yyg->yy_c_buf_p = yy_cp = yy_bp + 2; |
YY_DO_BEFORE_ACTION; /* set up yytext again */ |
YY_RULE_SETUP |
#line 336 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
yyextra->lexing_directive = 1; |
yyextra->space_tokens = 0; |
RETURN_TOKEN_NEVER_SKIP (IF); |
} |
YY_BREAK |
case 17: |
/* rule 17 can match eol */ |
*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ |
YY_LINENO_REWIND_TO(yy_bp + 4); |
yyg->yy_c_buf_p = yy_cp = yy_bp + 4; |
YY_DO_BEFORE_ACTION; /* set up yytext again */ |
YY_RULE_SETUP |
#line 343 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
yyextra->lexing_directive = 1; |
yyextra->space_tokens = 0; |
RETURN_TOKEN_NEVER_SKIP (ELIF); |
} |
YY_BREAK |
case 18: |
YY_RULE_SETUP |
#line 350 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
yyextra->space_tokens = 0; |
RETURN_TOKEN_NEVER_SKIP (ELSE); |
} |
YY_BREAK |
case 19: |
YY_RULE_SETUP |
#line 356 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
yyextra->space_tokens = 0; |
RETURN_TOKEN_NEVER_SKIP (ENDIF); |
} |
YY_BREAK |
case 20: |
YY_RULE_SETUP |
#line 362 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
RETURN_STRING_TOKEN (ERROR_TOKEN); |
} |
YY_BREAK |
/* After we see a "#define" we enter the <DEFINE> start state |
* for the lexer. Within <DEFINE> we are looking for the first |
* identifier and specifically checking whether the identifier |
* is followed by a '(' or not, (to lex either a |
* FUNC_IDENTIFIER or an OBJ_IDENITIFIER token). |
* |
* While in the <DEFINE> state we also need to explicitly |
* handle a few other things that may appear before the |
* identifier: |
* |
* * Comments, (handled above with the main support for |
* comments). |
* |
* * Whitespace (simply ignored) |
* |
* * Anything else, (not an identifier, not a comment, |
* and not whitespace). This will generate an error. |
*/ |
case 21: |
YY_RULE_SETUP |
#line 385 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
if (! parser->skipping) { |
BEGIN DEFINE; |
yyextra->space_tokens = 0; |
RETURN_TOKEN (DEFINE_TOKEN); |
} |
} |
YY_BREAK |
case 22: |
YY_RULE_SETUP |
#line 393 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
yyextra->space_tokens = 0; |
RETURN_TOKEN (UNDEF); |
} |
YY_BREAK |
case 23: |
YY_RULE_SETUP |
#line 399 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
/* Nothing to do here. Importantly, don't leave the <HASH> |
* start condition, since it's legal to have space between the |
* '#' and the directive.. */ |
} |
YY_BREAK |
/* This will catch any non-directive garbage after a HASH */ |
case 24: |
YY_RULE_SETUP |
#line 406 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
RETURN_TOKEN (GARBAGE); |
} |
YY_BREAK |
/* An identifier immediately followed by '(' */ |
case 25: |
*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ |
yyg->yy_c_buf_p = yy_cp -= 1; |
YY_DO_BEFORE_ACTION; /* set up yytext again */ |
YY_RULE_SETUP |
#line 412 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
RETURN_STRING_TOKEN (FUNC_IDENTIFIER); |
} |
YY_BREAK |
/* An identifier not immediately followed by '(' */ |
case 26: |
YY_RULE_SETUP |
#line 418 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
RETURN_STRING_TOKEN (OBJ_IDENTIFIER); |
} |
YY_BREAK |
/* Whitespace */ |
case 27: |
YY_RULE_SETUP |
#line 424 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
/* Just ignore it. Nothing to do here. */ |
} |
YY_BREAK |
/* '/' not followed by '*', so not a comment. This is an error. */ |
case 28: |
/* rule 28 can match eol */ |
YY_RULE_SETUP |
#line 429 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
glcpp_error(yylloc, yyextra, "#define followed by a non-identifier: %s", yytext); |
RETURN_STRING_TOKEN (INTEGER_STRING); |
} |
YY_BREAK |
/* A character that can't start an identifier, comment, or |
* space. This is an error. */ |
case 29: |
YY_RULE_SETUP |
#line 437 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
BEGIN INITIAL; |
glcpp_error(yylloc, yyextra, "#define followed by a non-identifier: %s", yytext); |
RETURN_STRING_TOKEN (INTEGER_STRING); |
} |
YY_BREAK |
case 30: |
YY_RULE_SETUP |
#line 443 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_STRING_TOKEN (INTEGER_STRING); |
} |
YY_BREAK |
case 31: |
YY_RULE_SETUP |
#line 447 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_STRING_TOKEN (INTEGER_STRING); |
} |
YY_BREAK |
case 32: |
YY_RULE_SETUP |
#line 451 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_STRING_TOKEN (INTEGER_STRING); |
} |
YY_BREAK |
case 33: |
YY_RULE_SETUP |
#line 455 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_TOKEN (LEFT_SHIFT); |
} |
YY_BREAK |
case 34: |
YY_RULE_SETUP |
#line 459 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_TOKEN (RIGHT_SHIFT); |
} |
YY_BREAK |
case 35: |
YY_RULE_SETUP |
#line 463 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_TOKEN (LESS_OR_EQUAL); |
} |
YY_BREAK |
case 36: |
YY_RULE_SETUP |
#line 467 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_TOKEN (GREATER_OR_EQUAL); |
} |
YY_BREAK |
case 37: |
YY_RULE_SETUP |
#line 471 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_TOKEN (EQUAL); |
} |
YY_BREAK |
case 38: |
YY_RULE_SETUP |
#line 475 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_TOKEN (NOT_EQUAL); |
} |
YY_BREAK |
case 39: |
YY_RULE_SETUP |
#line 479 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_TOKEN (AND); |
} |
YY_BREAK |
case 40: |
YY_RULE_SETUP |
#line 483 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_TOKEN (OR); |
} |
YY_BREAK |
case 41: |
YY_RULE_SETUP |
#line 487 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_TOKEN (PLUS_PLUS); |
} |
YY_BREAK |
case 42: |
YY_RULE_SETUP |
#line 491 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_TOKEN (MINUS_MINUS); |
} |
YY_BREAK |
case 43: |
YY_RULE_SETUP |
#line 495 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
if (! parser->skipping) { |
if (parser->is_gles) |
glcpp_error(yylloc, yyextra, "Token pasting (##) is illegal in GLES"); |
RETURN_TOKEN (PASTE); |
} |
} |
YY_BREAK |
case 44: |
YY_RULE_SETUP |
#line 503 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_TOKEN (DEFINED); |
} |
YY_BREAK |
case 45: |
YY_RULE_SETUP |
#line 507 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_STRING_TOKEN (IDENTIFIER); |
} |
YY_BREAK |
case 46: |
YY_RULE_SETUP |
#line 511 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_STRING_TOKEN (OTHER); |
} |
YY_BREAK |
case 47: |
YY_RULE_SETUP |
#line 515 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_TOKEN (yytext[0]); |
} |
YY_BREAK |
case 48: |
YY_RULE_SETUP |
#line 519 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
RETURN_STRING_TOKEN (OTHER); |
} |
YY_BREAK |
case 49: |
YY_RULE_SETUP |
#line 523 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
if (yyextra->space_tokens) { |
RETURN_TOKEN (SPACE); |
} |
} |
YY_BREAK |
/* We preserve all newlines, even between #if 0..#endif, so no |
skipping.. */ |
case 50: |
/* rule 50 can match eol */ |
YY_RULE_SETUP |
#line 531 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
if (parser->commented_newlines) { |
BEGIN NEWLINE_CATCHUP; |
} else { |
BEGIN INITIAL; |
} |
yyextra->space_tokens = 1; |
yyextra->lexing_directive = 0; |
yylineno++; |
yycolumn = 0; |
RETURN_TOKEN_NEVER_SKIP (NEWLINE); |
} |
YY_BREAK |
case YY_STATE_EOF(INITIAL): |
case YY_STATE_EOF(COMMENT): |
case YY_STATE_EOF(DEFINE): |
case YY_STATE_EOF(HASH): |
#line 544 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
if (YY_START == COMMENT) |
glcpp_error(yylloc, yyextra, "Unterminated comment"); |
BEGIN DONE; /* Don't keep matching this rule forever. */ |
yyextra->lexing_directive = 0; |
if (! parser->last_token_was_newline) |
RETURN_TOKEN (NEWLINE); |
} |
YY_BREAK |
/* This is a catch-all to avoid the annoying default flex action which |
* matches any character and prints it. If any input ever matches this |
* rule, then we have made a mistake above and need to fix one or more |
* of the preceding patterns to match that input. */ |
case 51: |
YY_RULE_SETUP |
#line 558 "../../../src/glsl/glcpp/glcpp-lex.l" |
{ |
glcpp_error(yylloc, yyextra, "Internal compiler error: Unexpected character: %s", yytext); |
/* We don't actually use the UNREACHABLE start condition. We |
only have this block here so that we can pretend to call some |
generated functions, (to avoid "defined but not used" |
warnings. */ |
if (YY_START == UNREACHABLE) { |
unput('.'); |
yy_top_state(yyextra); |
} |
} |
YY_BREAK |
case 52: |
YY_RULE_SETUP |
#line 571 "../../../src/glsl/glcpp/glcpp-lex.l" |
YY_FATAL_ERROR( "flex scanner jammed" ); |
YY_BREAK |
#line 1670 "glcpp/glcpp-lex.c" |
case YY_STATE_EOF(DONE): |
case YY_STATE_EOF(NEWLINE_CATCHUP): |
case YY_STATE_EOF(UNREACHABLE): |
yyterminate(); |
case YY_END_OF_BUFFER: |
{ |
/* Amount of text matched not including the EOB char. */ |
int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; |
/* Undo the effects of YY_DO_BEFORE_ACTION. */ |
*yy_cp = yyg->yy_hold_char; |
YY_RESTORE_YY_MORE_OFFSET |
if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) |
{ |
/* We're scanning a new file or input source. It's |
* possible that this happened because the user |
* just pointed yyin at a new source and called |
* glcpp_lex(). If so, then we have to assure |
* consistency between YY_CURRENT_BUFFER and our |
* globals. Here is the right place to do so, because |
* this is the first action (other than possibly a |
* back-up) that will match for the new input source. |
*/ |
yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; |
YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; |
YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; |
} |
/* Note that here we test for yy_c_buf_p "<=" to the position |
* of the first EOB in the buffer, since yy_c_buf_p will |
* already have been incremented past the NUL character |
* (since all states make transitions on EOB to the |
* end-of-buffer state). Contrast this with the test |
* in input(). |
*/ |
if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) |
{ /* This was really a NUL. */ |
yy_state_type yy_next_state; |
yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; |
yy_current_state = yy_get_previous_state( yyscanner ); |
/* Okay, we're now positioned to make the NUL |
* transition. We couldn't have |
* yy_get_previous_state() go ahead and do it |
* for us because it doesn't know how to deal |
* with the possibility of jamming (and we don't |
* want to build jamming into it because then it |
* will run more slowly). |
*/ |
yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); |
yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; |
if ( yy_next_state ) |
{ |
/* Consume the NUL. */ |
yy_cp = ++yyg->yy_c_buf_p; |
yy_current_state = yy_next_state; |
goto yy_match; |
} |
else |
{ |
yy_cp = yyg->yy_last_accepting_cpos; |
yy_current_state = yyg->yy_last_accepting_state; |
goto yy_find_action; |
} |
} |
else switch ( yy_get_next_buffer( yyscanner ) ) |
{ |
case EOB_ACT_END_OF_FILE: |
{ |
yyg->yy_did_buffer_switch_on_eof = 0; |
if ( glcpp_wrap(yyscanner ) ) |
{ |
/* Note: because we've taken care in |
* yy_get_next_buffer() to have set up |
* yytext, we can now set up |
* yy_c_buf_p so that if some total |
* hoser (like flex itself) wants to |
* call the scanner after we return the |
* YY_NULL, it'll still work - another |
* YY_NULL will get returned. |
*/ |
yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; |
yy_act = YY_STATE_EOF(YY_START); |
goto do_action; |
} |
else |
{ |
if ( ! yyg->yy_did_buffer_switch_on_eof ) |
YY_NEW_FILE; |
} |
break; |
} |
case EOB_ACT_CONTINUE_SCAN: |
yyg->yy_c_buf_p = |
yyg->yytext_ptr + yy_amount_of_matched_text; |
yy_current_state = yy_get_previous_state( yyscanner ); |
yy_cp = yyg->yy_c_buf_p; |
yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; |
goto yy_match; |
case EOB_ACT_LAST_MATCH: |
yyg->yy_c_buf_p = |
&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; |
yy_current_state = yy_get_previous_state( yyscanner ); |
yy_cp = yyg->yy_c_buf_p; |
yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; |
goto yy_find_action; |
} |
break; |
} |
default: |
YY_FATAL_ERROR( |
"fatal flex scanner internal error--no action found" ); |
} /* end of action switch */ |
} /* end of scanning one token */ |
} /* end of user's declarations */ |
} /* end of glcpp_lex */ |
/* yy_get_next_buffer - try to read in a new buffer |
* |
* Returns a code representing an action: |
* EOB_ACT_LAST_MATCH - |
* EOB_ACT_CONTINUE_SCAN - continue scanning from current position |
* EOB_ACT_END_OF_FILE - end of file |
*/ |
static int yy_get_next_buffer (yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; |
register char *source = yyg->yytext_ptr; |
register int number_to_move, i; |
int ret_val; |
if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) |
YY_FATAL_ERROR( |
"fatal flex scanner internal error--end of buffer missed" ); |
if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) |
{ /* Don't try to fill the buffer, so this is an EOF. */ |
if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) |
{ |
/* We matched a single character, the EOB, so |
* treat this as a final EOF. |
*/ |
return EOB_ACT_END_OF_FILE; |
} |
else |
{ |
/* We matched some text prior to the EOB, first |
* process it. |
*/ |
return EOB_ACT_LAST_MATCH; |
} |
} |
/* Try to read more data. */ |
/* First move last chars to start of buffer. */ |
number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; |
for ( i = 0; i < number_to_move; ++i ) |
*(dest++) = *(source++); |
if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) |
/* don't do the read, it's not guaranteed to return an EOF, |
* just force an EOF |
*/ |
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; |
else |
{ |
yy_size_t num_to_read = |
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; |
while ( num_to_read <= 0 ) |
{ /* Not enough room in the buffer - grow it. */ |
/* just a shorter name for the current buffer */ |
YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; |
int yy_c_buf_p_offset = |
(int) (yyg->yy_c_buf_p - b->yy_ch_buf); |
if ( b->yy_is_our_buffer ) |
{ |
yy_size_t new_size = b->yy_buf_size * 2; |
if ( new_size <= 0 ) |
b->yy_buf_size += b->yy_buf_size / 8; |
else |
b->yy_buf_size *= 2; |
b->yy_ch_buf = (char *) |
/* Include room in for 2 EOB chars. */ |
glcpp_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); |
} |
else |
/* Can't grow it, we don't own it. */ |
b->yy_ch_buf = 0; |
if ( ! b->yy_ch_buf ) |
YY_FATAL_ERROR( |
"fatal error - scanner input buffer overflow" ); |
yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; |
num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - |
number_to_move - 1; |
} |
if ( num_to_read > YY_READ_BUF_SIZE ) |
num_to_read = YY_READ_BUF_SIZE; |
/* Read in more data. */ |
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), |
yyg->yy_n_chars, num_to_read ); |
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; |
} |
if ( yyg->yy_n_chars == 0 ) |
{ |
if ( number_to_move == YY_MORE_ADJ ) |
{ |
ret_val = EOB_ACT_END_OF_FILE; |
glcpp_restart(yyin ,yyscanner); |
} |
else |
{ |
ret_val = EOB_ACT_LAST_MATCH; |
YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = |
YY_BUFFER_EOF_PENDING; |
} |
} |
else |
ret_val = EOB_ACT_CONTINUE_SCAN; |
if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { |
/* Extend the array by 50%, plus the number we really need. */ |
yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); |
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) glcpp_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); |
if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) |
YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); |
} |
yyg->yy_n_chars += number_to_move; |
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; |
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; |
yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; |
return ret_val; |
} |
/* yy_get_previous_state - get the state just before the EOB char was reached */ |
static yy_state_type yy_get_previous_state (yyscan_t yyscanner) |
{ |
register yy_state_type yy_current_state; |
register char *yy_cp; |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
yy_current_state = yyg->yy_start; |
for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) |
{ |
register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); |
if ( yy_accept[yy_current_state] ) |
{ |
yyg->yy_last_accepting_state = yy_current_state; |
yyg->yy_last_accepting_cpos = yy_cp; |
} |
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) |
{ |
yy_current_state = (int) yy_def[yy_current_state]; |
if ( yy_current_state >= 174 ) |
yy_c = yy_meta[(unsigned int) yy_c]; |
} |
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; |
} |
return yy_current_state; |
} |
/* yy_try_NUL_trans - try to make a transition on the NUL character |
* |
* synopsis |
* next_state = yy_try_NUL_trans( current_state ); |
*/ |
static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) |
{ |
register int yy_is_jam; |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ |
register char *yy_cp = yyg->yy_c_buf_p; |
register YY_CHAR yy_c = 1; |
if ( yy_accept[yy_current_state] ) |
{ |
yyg->yy_last_accepting_state = yy_current_state; |
yyg->yy_last_accepting_cpos = yy_cp; |
} |
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) |
{ |
yy_current_state = (int) yy_def[yy_current_state]; |
if ( yy_current_state >= 174 ) |
yy_c = yy_meta[(unsigned int) yy_c]; |
} |
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; |
yy_is_jam = (yy_current_state == 173); |
(void)yyg; |
return yy_is_jam ? 0 : yy_current_state; |
} |
static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) |
{ |
register char *yy_cp; |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
yy_cp = yyg->yy_c_buf_p; |
/* undo effects of setting up yytext */ |
*yy_cp = yyg->yy_hold_char; |
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) |
{ /* need to shift things up to make room */ |
/* +2 for EOB chars. */ |
register yy_size_t number_to_move = yyg->yy_n_chars + 2; |
register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ |
YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; |
register char *source = |
&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; |
while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) |
*--dest = *--source; |
yy_cp += (int) (dest - source); |
yy_bp += (int) (dest - source); |
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = |
yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; |
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) |
YY_FATAL_ERROR( "flex scanner push-back overflow" ); |
} |
*--yy_cp = (char) c; |
yyg->yytext_ptr = yy_bp; |
yyg->yy_hold_char = *yy_cp; |
yyg->yy_c_buf_p = yy_cp; |
} |
#ifndef YY_NO_INPUT |
#ifdef __cplusplus |
static int yyinput (yyscan_t yyscanner) |
#else |
static int input (yyscan_t yyscanner) |
#endif |
{ |
int c; |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
*yyg->yy_c_buf_p = yyg->yy_hold_char; |
if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) |
{ |
/* yy_c_buf_p now points to the character we want to return. |
* If this occurs *before* the EOB characters, then it's a |
* valid NUL; if not, then we've hit the end of the buffer. |
*/ |
if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) |
/* This was really a NUL. */ |
*yyg->yy_c_buf_p = '\0'; |
else |
{ /* need more input */ |
yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr; |
++yyg->yy_c_buf_p; |
switch ( yy_get_next_buffer( yyscanner ) ) |
{ |
case EOB_ACT_LAST_MATCH: |
/* This happens because yy_g_n_b() |
* sees that we've accumulated a |
* token and flags that we need to |
* try matching the token before |
* proceeding. But for input(), |
* there's no matching to consider. |
* So convert the EOB_ACT_LAST_MATCH |
* to EOB_ACT_END_OF_FILE. |
*/ |
/* Reset buffer status. */ |
glcpp_restart(yyin ,yyscanner); |
/*FALLTHROUGH*/ |
case EOB_ACT_END_OF_FILE: |
{ |
if ( glcpp_wrap(yyscanner ) ) |
return EOF; |
if ( ! yyg->yy_did_buffer_switch_on_eof ) |
YY_NEW_FILE; |
#ifdef __cplusplus |
return yyinput(yyscanner); |
#else |
return input(yyscanner); |
#endif |
} |
case EOB_ACT_CONTINUE_SCAN: |
yyg->yy_c_buf_p = yyg->yytext_ptr + offset; |
break; |
} |
} |
} |
c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ |
*yyg->yy_c_buf_p = '\0'; /* preserve yytext */ |
yyg->yy_hold_char = *++yyg->yy_c_buf_p; |
return c; |
} |
#endif /* ifndef YY_NO_INPUT */ |
/** Immediately switch to a different input stream. |
* @param input_file A readable stream. |
* @param yyscanner The scanner object. |
* @note This function does not reset the start condition to @c INITIAL . |
*/ |
void glcpp_restart (FILE * input_file , yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
if ( ! YY_CURRENT_BUFFER ){ |
glcpp_ensure_buffer_stack (yyscanner); |
YY_CURRENT_BUFFER_LVALUE = |
glcpp__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); |
} |
glcpp__init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); |
glcpp__load_buffer_state(yyscanner ); |
} |
/** Switch to a different input buffer. |
* @param new_buffer The new input buffer. |
* @param yyscanner The scanner object. |
*/ |
void glcpp__switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
/* TODO. We should be able to replace this entire function body |
* with |
* glcpp_pop_buffer_state(); |
* glcpp_push_buffer_state(new_buffer); |
*/ |
glcpp_ensure_buffer_stack (yyscanner); |
if ( YY_CURRENT_BUFFER == new_buffer ) |
return; |
if ( YY_CURRENT_BUFFER ) |
{ |
/* Flush out information for old buffer. */ |
*yyg->yy_c_buf_p = yyg->yy_hold_char; |
YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; |
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; |
} |
YY_CURRENT_BUFFER_LVALUE = new_buffer; |
glcpp__load_buffer_state(yyscanner ); |
/* We don't actually know whether we did this switch during |
* EOF (glcpp_wrap()) processing, but the only time this flag |
* is looked at is after glcpp_wrap() is called, so it's safe |
* to go ahead and always set it. |
*/ |
yyg->yy_did_buffer_switch_on_eof = 1; |
} |
static void glcpp__load_buffer_state (yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; |
yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; |
yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; |
yyg->yy_hold_char = *yyg->yy_c_buf_p; |
} |
/** Allocate and initialize an input buffer state. |
* @param file A readable stream. |
* @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. |
* @param yyscanner The scanner object. |
* @return the allocated buffer state. |
*/ |
YY_BUFFER_STATE glcpp__create_buffer (FILE * file, int size , yyscan_t yyscanner) |
{ |
YY_BUFFER_STATE b; |
b = (YY_BUFFER_STATE) glcpp_alloc(sizeof( struct yy_buffer_state ) ,yyscanner ); |
if ( ! b ) |
YY_FATAL_ERROR( "out of dynamic memory in glcpp__create_buffer()" ); |
b->yy_buf_size = size; |
/* yy_ch_buf has to be 2 characters longer than the size given because |
* we need to put in 2 end-of-buffer characters. |
*/ |
b->yy_ch_buf = (char *) glcpp_alloc(b->yy_buf_size + 2 ,yyscanner ); |
if ( ! b->yy_ch_buf ) |
YY_FATAL_ERROR( "out of dynamic memory in glcpp__create_buffer()" ); |
b->yy_is_our_buffer = 1; |
glcpp__init_buffer(b,file ,yyscanner); |
return b; |
} |
/** Destroy the buffer. |
* @param b a buffer created with glcpp__create_buffer() |
* @param yyscanner The scanner object. |
*/ |
void glcpp__delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
if ( ! b ) |
return; |
if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ |
YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; |
if ( b->yy_is_our_buffer ) |
glcpp_free((void *) b->yy_ch_buf ,yyscanner ); |
glcpp_free((void *) b ,yyscanner ); |
} |
/* Initializes or reinitializes a buffer. |
* This function is sometimes called more than once on the same buffer, |
* such as during a glcpp_restart() or at EOF. |
*/ |
static void glcpp__init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) |
{ |
int oerrno = errno; |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
glcpp__flush_buffer(b ,yyscanner); |
b->yy_input_file = file; |
b->yy_fill_buffer = 1; |
/* If b is the current buffer, then glcpp__init_buffer was _probably_ |
* called from glcpp_restart() or through yy_get_next_buffer. |
* In that case, we don't want to reset the lineno or column. |
*/ |
if (b != YY_CURRENT_BUFFER){ |
b->yy_bs_lineno = 1; |
b->yy_bs_column = 0; |
} |
b->yy_is_interactive = 0; |
errno = oerrno; |
} |
/** Discard all buffered characters. On the next scan, YY_INPUT will be called. |
* @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. |
* @param yyscanner The scanner object. |
*/ |
void glcpp__flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
if ( ! b ) |
return; |
b->yy_n_chars = 0; |
/* We always need two end-of-buffer characters. The first causes |
* a transition to the end-of-buffer state. The second causes |
* a jam in that state. |
*/ |
b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; |
b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; |
b->yy_buf_pos = &b->yy_ch_buf[0]; |
b->yy_at_bol = 1; |
b->yy_buffer_status = YY_BUFFER_NEW; |
if ( b == YY_CURRENT_BUFFER ) |
glcpp__load_buffer_state(yyscanner ); |
} |
/** Pushes the new state onto the stack. The new state becomes |
* the current state. This function will allocate the stack |
* if necessary. |
* @param new_buffer The new state. |
* @param yyscanner The scanner object. |
*/ |
void glcpp_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
if (new_buffer == NULL) |
return; |
glcpp_ensure_buffer_stack(yyscanner); |
/* This block is copied from glcpp__switch_to_buffer. */ |
if ( YY_CURRENT_BUFFER ) |
{ |
/* Flush out information for old buffer. */ |
*yyg->yy_c_buf_p = yyg->yy_hold_char; |
YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; |
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; |
} |
/* Only push if top exists. Otherwise, replace top. */ |
if (YY_CURRENT_BUFFER) |
yyg->yy_buffer_stack_top++; |
YY_CURRENT_BUFFER_LVALUE = new_buffer; |
/* copied from glcpp__switch_to_buffer. */ |
glcpp__load_buffer_state(yyscanner ); |
yyg->yy_did_buffer_switch_on_eof = 1; |
} |
/** Removes and deletes the top of the stack, if present. |
* The next element becomes the new top. |
* @param yyscanner The scanner object. |
*/ |
void glcpp_pop_buffer_state (yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
if (!YY_CURRENT_BUFFER) |
return; |
glcpp__delete_buffer(YY_CURRENT_BUFFER ,yyscanner); |
YY_CURRENT_BUFFER_LVALUE = NULL; |
if (yyg->yy_buffer_stack_top > 0) |
--yyg->yy_buffer_stack_top; |
if (YY_CURRENT_BUFFER) { |
glcpp__load_buffer_state(yyscanner ); |
yyg->yy_did_buffer_switch_on_eof = 1; |
} |
} |
/* Allocates the stack if it does not exist. |
* Guarantees space for at least one push. |
*/ |
static void glcpp_ensure_buffer_stack (yyscan_t yyscanner) |
{ |
yy_size_t num_to_alloc; |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
if (!yyg->yy_buffer_stack) { |
/* First allocation is just for 2 elements, since we don't know if this |
* scanner will even need a stack. We use 2 instead of 1 to avoid an |
* immediate realloc on the next call. |
*/ |
num_to_alloc = 1; |
yyg->yy_buffer_stack = (struct yy_buffer_state**)glcpp_alloc |
(num_to_alloc * sizeof(struct yy_buffer_state*) |
, yyscanner); |
if ( ! yyg->yy_buffer_stack ) |
YY_FATAL_ERROR( "out of dynamic memory in glcpp_ensure_buffer_stack()" ); |
memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); |
yyg->yy_buffer_stack_max = num_to_alloc; |
yyg->yy_buffer_stack_top = 0; |
return; |
} |
if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ |
/* Increase the buffer to prepare for a possible push. */ |
int grow_size = 8 /* arbitrary grow size */; |
num_to_alloc = yyg->yy_buffer_stack_max + grow_size; |
yyg->yy_buffer_stack = (struct yy_buffer_state**)glcpp_realloc |
(yyg->yy_buffer_stack, |
num_to_alloc * sizeof(struct yy_buffer_state*) |
, yyscanner); |
if ( ! yyg->yy_buffer_stack ) |
YY_FATAL_ERROR( "out of dynamic memory in glcpp_ensure_buffer_stack()" ); |
/* zero only the new slots.*/ |
memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); |
yyg->yy_buffer_stack_max = num_to_alloc; |
} |
} |
/** Setup the input buffer state to scan directly from a user-specified character buffer. |
* @param base the character buffer |
* @param size the size in bytes of the character buffer |
* @param yyscanner The scanner object. |
* @return the newly allocated buffer state object. |
*/ |
YY_BUFFER_STATE glcpp__scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) |
{ |
YY_BUFFER_STATE b; |
if ( size < 2 || |
base[size-2] != YY_END_OF_BUFFER_CHAR || |
base[size-1] != YY_END_OF_BUFFER_CHAR ) |
/* They forgot to leave room for the EOB's. */ |
return 0; |
b = (YY_BUFFER_STATE) glcpp_alloc(sizeof( struct yy_buffer_state ) ,yyscanner ); |
if ( ! b ) |
YY_FATAL_ERROR( "out of dynamic memory in glcpp__scan_buffer()" ); |
b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ |
b->yy_buf_pos = b->yy_ch_buf = base; |
b->yy_is_our_buffer = 0; |
b->yy_input_file = 0; |
b->yy_n_chars = b->yy_buf_size; |
b->yy_is_interactive = 0; |
b->yy_at_bol = 1; |
b->yy_fill_buffer = 0; |
b->yy_buffer_status = YY_BUFFER_NEW; |
glcpp__switch_to_buffer(b ,yyscanner ); |
return b; |
} |
/** Setup the input buffer state to scan a string. The next call to glcpp_lex() will |
* scan from a @e copy of @a str. |
* @param yystr a NUL-terminated string to scan |
* @param yyscanner The scanner object. |
* @return the newly allocated buffer state object. |
* @note If you want to scan bytes that may contain NUL values, then use |
* glcpp__scan_bytes() instead. |
*/ |
YY_BUFFER_STATE glcpp__scan_string (yyconst char * yystr , yyscan_t yyscanner) |
{ |
return glcpp__scan_bytes(yystr,strlen(yystr) ,yyscanner); |
} |
/** Setup the input buffer state to scan the given bytes. The next call to glcpp_lex() will |
* scan from a @e copy of @a bytes. |
* @param yybytes the byte buffer to scan |
* @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. |
* @param yyscanner The scanner object. |
* @return the newly allocated buffer state object. |
*/ |
YY_BUFFER_STATE glcpp__scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner) |
{ |
YY_BUFFER_STATE b; |
char *buf; |
yy_size_t n; |
yy_size_t i; |
/* Get memory for full buffer, including space for trailing EOB's. */ |
n = _yybytes_len + 2; |
buf = (char *) glcpp_alloc(n ,yyscanner ); |
if ( ! buf ) |
YY_FATAL_ERROR( "out of dynamic memory in glcpp__scan_bytes()" ); |
for ( i = 0; i < _yybytes_len; ++i ) |
buf[i] = yybytes[i]; |
buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; |
b = glcpp__scan_buffer(buf,n ,yyscanner); |
if ( ! b ) |
YY_FATAL_ERROR( "bad buffer in glcpp__scan_bytes()" ); |
/* It's okay to grow etc. this buffer, and we should throw it |
* away when we're done. |
*/ |
b->yy_is_our_buffer = 1; |
return b; |
} |
static void yy_push_state (int new_state , yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
if ( yyg->yy_start_stack_ptr >= yyg->yy_start_stack_depth ) |
{ |
yy_size_t new_size; |
yyg->yy_start_stack_depth += YY_START_STACK_INCR; |
new_size = yyg->yy_start_stack_depth * sizeof( int ); |
if ( ! yyg->yy_start_stack ) |
yyg->yy_start_stack = (int *) glcpp_alloc(new_size ,yyscanner ); |
else |
yyg->yy_start_stack = (int *) glcpp_realloc((void *) yyg->yy_start_stack,new_size ,yyscanner ); |
if ( ! yyg->yy_start_stack ) |
YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); |
} |
yyg->yy_start_stack[yyg->yy_start_stack_ptr++] = YY_START; |
BEGIN(new_state); |
} |
static void yy_pop_state (yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
if ( --yyg->yy_start_stack_ptr < 0 ) |
YY_FATAL_ERROR( "start-condition stack underflow" ); |
BEGIN(yyg->yy_start_stack[yyg->yy_start_stack_ptr]); |
} |
static int yy_top_state (yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
return yyg->yy_start_stack[yyg->yy_start_stack_ptr - 1]; |
} |
#ifndef YY_EXIT_FAILURE |
#define YY_EXIT_FAILURE 2 |
#endif |
static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) |
{ |
(void) fprintf( stderr, "%s\n", msg ); |
exit( YY_EXIT_FAILURE ); |
} |
/* Redefine yyless() so it works in section 3 code. */ |
#undef yyless |
#define yyless(n) \ |
do \ |
{ \ |
/* Undo effects of setting up yytext. */ \ |
int yyless_macro_arg = (n); \ |
YY_LESS_LINENO(yyless_macro_arg);\ |
yytext[yyleng] = yyg->yy_hold_char; \ |
yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ |
yyg->yy_hold_char = *yyg->yy_c_buf_p; \ |
*yyg->yy_c_buf_p = '\0'; \ |
yyleng = yyless_macro_arg; \ |
} \ |
while ( 0 ) |
/* Accessor methods (get/set functions) to struct members. */ |
/** Get the user-defined data for this scanner. |
* @param yyscanner The scanner object. |
*/ |
YY_EXTRA_TYPE glcpp_get_extra (yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
return yyextra; |
} |
/** Get the current line number. |
* @param yyscanner The scanner object. |
*/ |
int glcpp_get_lineno (yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
if (! YY_CURRENT_BUFFER) |
return 0; |
return yylineno; |
} |
/** Get the current column number. |
* @param yyscanner The scanner object. |
*/ |
int glcpp_get_column (yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
if (! YY_CURRENT_BUFFER) |
return 0; |
return yycolumn; |
} |
/** Get the input stream. |
* @param yyscanner The scanner object. |
*/ |
FILE *glcpp_get_in (yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
return yyin; |
} |
/** Get the output stream. |
* @param yyscanner The scanner object. |
*/ |
FILE *glcpp_get_out (yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
return yyout; |
} |
/** Get the length of the current token. |
* @param yyscanner The scanner object. |
*/ |
yy_size_t glcpp_get_leng (yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
return yyleng; |
} |
/** Get the current token. |
* @param yyscanner The scanner object. |
*/ |
char *glcpp_get_text (yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
return yytext; |
} |
/** Set the user-defined data. This data is never touched by the scanner. |
* @param user_defined The data to be associated with this scanner. |
* @param yyscanner The scanner object. |
*/ |
void glcpp_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
yyextra = user_defined ; |
} |
/** Set the current line number. |
* @param line_number |
* @param yyscanner The scanner object. |
*/ |
void glcpp_set_lineno (int line_number , yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
/* lineno is only valid if an input buffer exists. */ |
if (! YY_CURRENT_BUFFER ) |
YY_FATAL_ERROR( "glcpp_set_lineno called with no buffer" ); |
yylineno = line_number; |
} |
/** Set the current column. |
* @param line_number |
* @param yyscanner The scanner object. |
*/ |
void glcpp_set_column (int column_no , yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
/* column is only valid if an input buffer exists. */ |
if (! YY_CURRENT_BUFFER ) |
YY_FATAL_ERROR( "glcpp_set_column called with no buffer" ); |
yycolumn = column_no; |
} |
/** Set the input stream. This does not discard the current |
* input buffer. |
* @param in_str A readable stream. |
* @param yyscanner The scanner object. |
* @see glcpp__switch_to_buffer |
*/ |
void glcpp_set_in (FILE * in_str , yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
yyin = in_str ; |
} |
void glcpp_set_out (FILE * out_str , yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
yyout = out_str ; |
} |
int glcpp_get_debug (yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
return yy_flex_debug; |
} |
void glcpp_set_debug (int bdebug , yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
yy_flex_debug = bdebug ; |
} |
/* Accessor methods for yylval and yylloc */ |
YYSTYPE * glcpp_get_lval (yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
return yylval; |
} |
void glcpp_set_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
yylval = yylval_param; |
} |
YYLTYPE *glcpp_get_lloc (yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
return yylloc; |
} |
void glcpp_set_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
yylloc = yylloc_param; |
} |
/* User-visible API */ |
/* glcpp_lex_init is special because it creates the scanner itself, so it is |
* the ONLY reentrant function that doesn't take the scanner as the last argument. |
* That's why we explicitly handle the declaration, instead of using our macros. |
*/ |
int glcpp_lex_init(yyscan_t* ptr_yy_globals) |
{ |
if (ptr_yy_globals == NULL){ |
errno = EINVAL; |
return 1; |
} |
*ptr_yy_globals = (yyscan_t) glcpp_alloc ( sizeof( struct yyguts_t ), NULL ); |
if (*ptr_yy_globals == NULL){ |
errno = ENOMEM; |
return 1; |
} |
/* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ |
memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); |
return yy_init_globals ( *ptr_yy_globals ); |
} |
/* glcpp_lex_init_extra has the same functionality as glcpp_lex_init, but follows the |
* convention of taking the scanner as the last argument. Note however, that |
* this is a *pointer* to a scanner, as it will be allocated by this call (and |
* is the reason, too, why this function also must handle its own declaration). |
* The user defined value in the first argument will be available to glcpp_alloc in |
* the yyextra field. |
*/ |
int glcpp_lex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) |
{ |
struct yyguts_t dummy_yyguts; |
glcpp_set_extra (yy_user_defined, &dummy_yyguts); |
if (ptr_yy_globals == NULL){ |
errno = EINVAL; |
return 1; |
} |
*ptr_yy_globals = (yyscan_t) glcpp_alloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); |
if (*ptr_yy_globals == NULL){ |
errno = ENOMEM; |
return 1; |
} |
/* By setting to 0xAA, we expose bugs in |
yy_init_globals. Leave at 0x00 for releases. */ |
memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); |
glcpp_set_extra (yy_user_defined, *ptr_yy_globals); |
return yy_init_globals ( *ptr_yy_globals ); |
} |
static int yy_init_globals (yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
/* Initialization is the same as for the non-reentrant scanner. |
* This function is called from glcpp_lex_destroy(), so don't allocate here. |
*/ |
yyg->yy_buffer_stack = 0; |
yyg->yy_buffer_stack_top = 0; |
yyg->yy_buffer_stack_max = 0; |
yyg->yy_c_buf_p = (char *) 0; |
yyg->yy_init = 0; |
yyg->yy_start = 0; |
yyg->yy_start_stack_ptr = 0; |
yyg->yy_start_stack_depth = 0; |
yyg->yy_start_stack = NULL; |
/* Defined in main.c */ |
#ifdef YY_STDINIT |
yyin = stdin; |
yyout = stdout; |
#else |
yyin = (FILE *) 0; |
yyout = (FILE *) 0; |
#endif |
/* For future reference: Set errno on error, since we are called by |
* glcpp_lex_init() |
*/ |
return 0; |
} |
/* glcpp_lex_destroy is for both reentrant and non-reentrant scanners. */ |
int glcpp_lex_destroy (yyscan_t yyscanner) |
{ |
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; |
/* Pop the buffer stack, destroying each element. */ |
while(YY_CURRENT_BUFFER){ |
glcpp__delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); |
YY_CURRENT_BUFFER_LVALUE = NULL; |
glcpp_pop_buffer_state(yyscanner); |
} |
/* Destroy the stack itself. */ |
glcpp_free(yyg->yy_buffer_stack ,yyscanner); |
yyg->yy_buffer_stack = NULL; |
/* Destroy the start condition stack. */ |
glcpp_free(yyg->yy_start_stack ,yyscanner ); |
yyg->yy_start_stack = NULL; |
/* Reset the globals. This is important in a non-reentrant scanner so the next time |
* glcpp_lex() is called, initialization will occur. */ |
yy_init_globals( yyscanner); |
/* Destroy the main struct (reentrant only). */ |
glcpp_free ( yyscanner , yyscanner ); |
yyscanner = NULL; |
return 0; |
} |
/* |
* Internal utility routines. |
*/ |
#ifndef yytext_ptr |
static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) |
{ |
register int i; |
for ( i = 0; i < n; ++i ) |
s1[i] = s2[i]; |
} |
#endif |
#ifdef YY_NEED_STRLEN |
static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) |
{ |
register int n; |
for ( n = 0; s[n]; ++n ) |
; |
return n; |
} |
#endif |
void *glcpp_alloc (yy_size_t size , yyscan_t yyscanner) |
{ |
return (void *) malloc( size ); |
} |
void *glcpp_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner) |
{ |
/* The cast to (char *) in the following accommodates both |
* implementations that use char* generic pointers, and those |
* that use void* generic pointers. It works with the latter |
* because both ANSI C and C++ allow castless assignment from |
* any pointer type to void*, and deal with argument conversions |
* as though doing an assignment. |
*/ |
return (void *) realloc( (char *) ptr, size ); |
} |
void glcpp_free (void * ptr , yyscan_t yyscanner) |
{ |
free( (char *) ptr ); /* see glcpp_realloc() for (char *) cast */ |
} |
#define YYTABLES_NAME "yytables" |
#line 571 "../../../src/glsl/glcpp/glcpp-lex.l" |
void |
glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader) |
{ |
glcpp__scan_string(shader,parser->scanner); |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/glcpp-lex.l |
---|
0,0 → 1,577 |
%{ |
/* |
* Copyright © 2010 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#include <stdio.h> |
#include <string.h> |
#include <ctype.h> |
#include "glcpp.h" |
#include "glcpp-parse.h" |
/* Flex annoyingly generates some functions without making them |
* static. Let's declare them here. */ |
int glcpp_get_column (yyscan_t yyscanner); |
void glcpp_set_column (int column_no , yyscan_t yyscanner); |
#ifdef _MSC_VER |
#define YY_NO_UNISTD_H |
#endif |
#define YY_NO_INPUT |
#define YY_USER_ACTION \ |
do { \ |
if (parser->has_new_line_number) \ |
yylineno = parser->new_line_number; \ |
if (parser->has_new_source_number) \ |
yylloc->source = parser->new_source_number; \ |
yylloc->first_column = yycolumn + 1; \ |
yylloc->first_line = yylloc->last_line = yylineno; \ |
yycolumn += yyleng; \ |
yylloc->last_column = yycolumn + 1; \ |
parser->has_new_line_number = 0; \ |
parser->has_new_source_number = 0; \ |
} while(0); |
#define YY_USER_INIT \ |
do { \ |
yylineno = 1; \ |
yycolumn = 0; \ |
yylloc->source = 0; \ |
} while(0) |
/* It's ugly to have macros that have return statements inside of |
* them, but flex-based lexer generation is all built around the |
* return statement. |
* |
* To mitigate the ugliness, we defer as much of the logic as possible |
* to an actual function, not a macro (see |
* glcpplex_update_state_per_token) and we make the word RETURN |
* prominent in all of the macros which may return. |
* |
* The most-commonly-used macro is RETURN_TOKEN which will perform all |
* necessary state updates based on the provided token,, then |
* conditionally return the token. It will not return a token if the |
* parser is currently skipping tokens, (such as within #if |
* 0...#else). |
* |
* The RETURN_TOKEN_NEVER_SKIP macro is a lower-level variant that |
* makes the token returning unconditional. This is needed for things |
* like #if and the tokens of its condition, (since these must be |
* evaluated by the parser even when otherwise skipping). |
* |
* Finally, RETURN_STRING_TOKEN is a simple convenience wrapper on top |
* of RETURN_TOKEN that performs a string copy of yytext before the |
* return. |
*/ |
#define RETURN_TOKEN_NEVER_SKIP(token) \ |
do { \ |
if (glcpp_lex_update_state_per_token (parser, token)) \ |
return token; \ |
} while (0) |
#define RETURN_TOKEN(token) \ |
do { \ |
if (! parser->skipping) { \ |
RETURN_TOKEN_NEVER_SKIP(token); \ |
} \ |
} while(0) |
#define RETURN_STRING_TOKEN(token) \ |
do { \ |
if (! parser->skipping) { \ |
yylval->str = ralloc_strdup (yyextra, yytext); \ |
RETURN_TOKEN_NEVER_SKIP (token); \ |
} \ |
} while(0) |
/* Update all state necessary for each token being returned. |
* |
* Here we'll be tracking newlines and spaces so that the lexer can |
* alter its behavior as necessary, (for example, '#' has special |
* significance if it is the first non-whitespace, non-comment token |
* in a line, but does not otherwise). |
* |
* NOTE: If this function returns FALSE, then no token should be |
* returned at all. This is used to suprress duplicate SPACE tokens. |
*/ |
static int |
glcpp_lex_update_state_per_token (glcpp_parser_t *parser, int token) |
{ |
/* After the first non-space token in a line, we won't |
* allow any '#' to introduce a directive. */ |
if (token == NEWLINE) { |
parser->first_non_space_token_this_line = 1; |
} else if (token != SPACE) { |
parser->first_non_space_token_this_line = 0; |
} |
/* Track newlines just to know whether a newline needs |
* to be inserted if end-of-file comes early. */ |
if (token == NEWLINE) { |
parser->last_token_was_newline = 1; |
} else { |
parser->last_token_was_newline = 0; |
} |
/* Track spaces to avoid emitting multiple SPACE |
* tokens in a row. */ |
if (token == SPACE) { |
if (! parser->last_token_was_space) { |
parser->last_token_was_space = 1; |
return 1; |
} else { |
parser->last_token_was_space = 1; |
return 0; |
} |
} else { |
parser->last_token_was_space = 0; |
return 1; |
} |
} |
%} |
%option bison-bridge bison-locations reentrant noyywrap |
%option extra-type="glcpp_parser_t *" |
%option prefix="glcpp_" |
%option stack |
%option never-interactive |
%option warn nodefault |
/* Note: When adding any start conditions to this list, you must also |
* update the "Internal compiler error" catch-all rule near the end of |
* this file. */ |
%x COMMENT DEFINE DONE HASH NEWLINE_CATCHUP UNREACHABLE |
SPACE [[:space:]] |
NONSPACE [^[:space:]] |
HSPACE [ \t] |
HASH # |
NEWLINE (\r\n|\n\r|\r|\n) |
IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]* |
PP_NUMBER [.]?[0-9]([._a-zA-Z0-9]|[eEpP][-+])* |
PUNCTUATION [][(){}.&*~!/%<>^|;,=+-] |
/* The OTHER class is simply a catch-all for things that the CPP |
parser just doesn't care about. Since flex regular expressions that |
match longer strings take priority over those matching shorter |
strings, we have to be careful to avoid OTHER matching and hiding |
something that CPP does care about. So we simply exclude all |
characters that appear in any other expressions. */ |
OTHER [^][_#[:space:]#a-zA-Z0-9(){}.&*~!/%<>^|;,=+-] |
DIGITS [0-9][0-9]* |
DECIMAL_INTEGER [1-9][0-9]*[uU]? |
OCTAL_INTEGER 0[0-7]*[uU]? |
HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? |
%% |
glcpp_parser_t *parser = yyextra; |
/* When we lex a multi-line comment, we replace it (as |
* specified) with a single space. But if the comment spanned |
* multiple lines, then subsequent parsing stages will not |
* count correct line numbers. To avoid this problem we keep |
* track of all newlines that were commented out by a |
* multi-line comment, and we emit a NEWLINE token for each at |
* the next legal opportunity, (which is when the lexer would |
* be emitting a NEWLINE token anyway). |
*/ |
if (YY_START == NEWLINE_CATCHUP) { |
if (parser->commented_newlines) |
parser->commented_newlines--; |
if (parser->commented_newlines == 0) |
BEGIN INITIAL; |
RETURN_TOKEN_NEVER_SKIP (NEWLINE); |
} |
/* Set up the parser->skipping bit here before doing any lexing. |
* |
* This bit controls whether tokens are skipped, (as implemented by |
* RETURN_TOKEN), such as between "#if 0" and "#endif". |
* |
* The parser maintains a skip_stack indicating whether we should be |
* skipping, (and nested levels of #if/#ifdef/#ifndef/#endif) will |
* push and pop items from the stack. |
* |
* Here are the rules for determining whether we are skipping: |
* |
* 1. If the skip stack is NULL, we are outside of all #if blocks |
* and we are not skipping. |
* |
* 2. If the skip stack is non-NULL, the type of the top node in |
* the stack determines whether to skip. A type of |
* SKIP_NO_SKIP is used for blocks wheere we are emitting |
* tokens, (such as between #if 1 and #endif, or after the |
* #else of an #if 0, etc.). |
* |
* 3. The lexing_directive bit overrides the skip stack. This bit |
* is set when we are actively lexing the expression for a |
* pre-processor condition, (such as #if, #elif, or #else). In |
* this case, even if otherwise skipping, we need to emit the |
* tokens for this condition so that the parser can evaluate |
* the expression. (For, #else, there's no expression, but we |
* emit tokens so the parser can generate a nice error message |
* if there are any tokens here). |
*/ |
if (parser->skip_stack && |
parser->skip_stack->type != SKIP_NO_SKIP && |
! parser->lexing_directive) |
{ |
parser->skipping = 1; |
} else { |
parser->skipping = 0; |
} |
/* Single-line comments */ |
<INITIAL,DEFINE,HASH>"//"[^\r\n]* { |
} |
/* Multi-line comments */ |
<INITIAL,DEFINE,HASH>"/*" { yy_push_state(COMMENT, yyscanner); } |
<COMMENT>[^*\r\n]* |
<COMMENT>[^*\r\n]*{NEWLINE} { yylineno++; yycolumn = 0; parser->commented_newlines++; } |
<COMMENT>"*"+[^*/\r\n]* |
<COMMENT>"*"+[^*/\r\n]*{NEWLINE} { yylineno++; yycolumn = 0; parser->commented_newlines++; } |
<COMMENT>"*"+"/" { |
yy_pop_state(yyscanner); |
/* In the <HASH> start condition, we don't want any SPACE token. */ |
if (yyextra->space_tokens && YY_START != HASH) |
RETURN_TOKEN (SPACE); |
} |
{HASH} { |
/* If the '#' is the first non-whitespace, non-comment token on this |
* line, then it introduces a directive, switch to the <HASH> start |
* condition. |
* |
* Otherwise, this is just punctuation, so return the HASH_TOKEN |
* token. */ |
if (parser->first_non_space_token_this_line) { |
BEGIN HASH; |
} |
RETURN_TOKEN_NEVER_SKIP (HASH_TOKEN); |
} |
<HASH>version{HSPACE}+ { |
BEGIN INITIAL; |
yyextra->space_tokens = 0; |
RETURN_STRING_TOKEN (VERSION_TOKEN); |
} |
/* Swallow empty #pragma directives, (to avoid confusing the |
* downstream compiler). |
* |
* Note: We use a simple regular expression for the lookahead |
* here. Specifically, we cannot use the complete {NEWLINE} expression |
* since it uses alternation and we've found that there's a flex bug |
* where using alternation in the lookahead portion of a pattern |
* triggers a buffer overrun. */ |
<HASH>pragma{HSPACE}*/[\r\n] { |
BEGIN INITIAL; |
} |
/* glcpp doesn't handle #extension, #version, or #pragma directives. |
* Simply pass them through to the main compiler's lexer/parser. */ |
<HASH>(extension|pragma)[^\r\n]* { |
BEGIN INITIAL; |
RETURN_STRING_TOKEN (PRAGMA); |
} |
<HASH>line{HSPACE}+ { |
BEGIN INITIAL; |
RETURN_TOKEN (LINE); |
} |
<HASH>{NEWLINE} { |
BEGIN INITIAL; |
RETURN_TOKEN_NEVER_SKIP (NEWLINE); |
} |
/* For the pre-processor directives, we return these tokens |
* even when we are otherwise skipping. */ |
<HASH>ifdef { |
BEGIN INITIAL; |
yyextra->lexing_directive = 1; |
yyextra->space_tokens = 0; |
RETURN_TOKEN_NEVER_SKIP (IFDEF); |
} |
<HASH>ifndef { |
BEGIN INITIAL; |
yyextra->lexing_directive = 1; |
yyextra->space_tokens = 0; |
RETURN_TOKEN_NEVER_SKIP (IFNDEF); |
} |
<HASH>if/[^_a-zA-Z0-9] { |
BEGIN INITIAL; |
yyextra->lexing_directive = 1; |
yyextra->space_tokens = 0; |
RETURN_TOKEN_NEVER_SKIP (IF); |
} |
<HASH>elif/[^_a-zA-Z0-9] { |
BEGIN INITIAL; |
yyextra->lexing_directive = 1; |
yyextra->space_tokens = 0; |
RETURN_TOKEN_NEVER_SKIP (ELIF); |
} |
<HASH>else { |
BEGIN INITIAL; |
yyextra->space_tokens = 0; |
RETURN_TOKEN_NEVER_SKIP (ELSE); |
} |
<HASH>endif { |
BEGIN INITIAL; |
yyextra->space_tokens = 0; |
RETURN_TOKEN_NEVER_SKIP (ENDIF); |
} |
<HASH>error[^\r\n]* { |
BEGIN INITIAL; |
RETURN_STRING_TOKEN (ERROR_TOKEN); |
} |
/* After we see a "#define" we enter the <DEFINE> start state |
* for the lexer. Within <DEFINE> we are looking for the first |
* identifier and specifically checking whether the identifier |
* is followed by a '(' or not, (to lex either a |
* FUNC_IDENTIFIER or an OBJ_IDENITIFIER token). |
* |
* While in the <DEFINE> state we also need to explicitly |
* handle a few other things that may appear before the |
* identifier: |
* |
* * Comments, (handled above with the main support for |
* comments). |
* |
* * Whitespace (simply ignored) |
* |
* * Anything else, (not an identifier, not a comment, |
* and not whitespace). This will generate an error. |
*/ |
<HASH>define{HSPACE}* { |
if (! parser->skipping) { |
BEGIN DEFINE; |
yyextra->space_tokens = 0; |
RETURN_TOKEN (DEFINE_TOKEN); |
} |
} |
<HASH>undef { |
BEGIN INITIAL; |
yyextra->space_tokens = 0; |
RETURN_TOKEN (UNDEF); |
} |
<HASH>{HSPACE}+ { |
/* Nothing to do here. Importantly, don't leave the <HASH> |
* start condition, since it's legal to have space between the |
* '#' and the directive.. */ |
} |
/* This will catch any non-directive garbage after a HASH */ |
<HASH>{NONSPACE} { |
BEGIN INITIAL; |
RETURN_TOKEN (GARBAGE); |
} |
/* An identifier immediately followed by '(' */ |
<DEFINE>{IDENTIFIER}/"(" { |
BEGIN INITIAL; |
RETURN_STRING_TOKEN (FUNC_IDENTIFIER); |
} |
/* An identifier not immediately followed by '(' */ |
<DEFINE>{IDENTIFIER} { |
BEGIN INITIAL; |
RETURN_STRING_TOKEN (OBJ_IDENTIFIER); |
} |
/* Whitespace */ |
<DEFINE>{HSPACE}+ { |
/* Just ignore it. Nothing to do here. */ |
} |
/* '/' not followed by '*', so not a comment. This is an error. */ |
<DEFINE>[/][^*]{NONSPACE}* { |
BEGIN INITIAL; |
glcpp_error(yylloc, yyextra, "#define followed by a non-identifier: %s", yytext); |
RETURN_STRING_TOKEN (INTEGER_STRING); |
} |
/* A character that can't start an identifier, comment, or |
* space. This is an error. */ |
<DEFINE>[^_a-zA-Z/[:space:]]{NONSPACE}* { |
BEGIN INITIAL; |
glcpp_error(yylloc, yyextra, "#define followed by a non-identifier: %s", yytext); |
RETURN_STRING_TOKEN (INTEGER_STRING); |
} |
{DECIMAL_INTEGER} { |
RETURN_STRING_TOKEN (INTEGER_STRING); |
} |
{OCTAL_INTEGER} { |
RETURN_STRING_TOKEN (INTEGER_STRING); |
} |
{HEXADECIMAL_INTEGER} { |
RETURN_STRING_TOKEN (INTEGER_STRING); |
} |
"<<" { |
RETURN_TOKEN (LEFT_SHIFT); |
} |
">>" { |
RETURN_TOKEN (RIGHT_SHIFT); |
} |
"<=" { |
RETURN_TOKEN (LESS_OR_EQUAL); |
} |
">=" { |
RETURN_TOKEN (GREATER_OR_EQUAL); |
} |
"==" { |
RETURN_TOKEN (EQUAL); |
} |
"!=" { |
RETURN_TOKEN (NOT_EQUAL); |
} |
"&&" { |
RETURN_TOKEN (AND); |
} |
"||" { |
RETURN_TOKEN (OR); |
} |
"++" { |
RETURN_TOKEN (PLUS_PLUS); |
} |
"--" { |
RETURN_TOKEN (MINUS_MINUS); |
} |
"##" { |
if (! parser->skipping) { |
if (parser->is_gles) |
glcpp_error(yylloc, yyextra, "Token pasting (##) is illegal in GLES"); |
RETURN_TOKEN (PASTE); |
} |
} |
"defined" { |
RETURN_TOKEN (DEFINED); |
} |
{IDENTIFIER} { |
RETURN_STRING_TOKEN (IDENTIFIER); |
} |
{PP_NUMBER} { |
RETURN_STRING_TOKEN (OTHER); |
} |
{PUNCTUATION} { |
RETURN_TOKEN (yytext[0]); |
} |
{OTHER}+ { |
RETURN_STRING_TOKEN (OTHER); |
} |
{HSPACE} { |
if (yyextra->space_tokens) { |
RETURN_TOKEN (SPACE); |
} |
} |
/* We preserve all newlines, even between #if 0..#endif, so no |
skipping.. */ |
<*>{NEWLINE} { |
if (parser->commented_newlines) { |
BEGIN NEWLINE_CATCHUP; |
} else { |
BEGIN INITIAL; |
} |
yyextra->space_tokens = 1; |
yyextra->lexing_directive = 0; |
yylineno++; |
yycolumn = 0; |
RETURN_TOKEN_NEVER_SKIP (NEWLINE); |
} |
<INITIAL,COMMENT,DEFINE,HASH><<EOF>> { |
if (YY_START == COMMENT) |
glcpp_error(yylloc, yyextra, "Unterminated comment"); |
BEGIN DONE; /* Don't keep matching this rule forever. */ |
yyextra->lexing_directive = 0; |
if (! parser->last_token_was_newline) |
RETURN_TOKEN (NEWLINE); |
} |
/* This is a catch-all to avoid the annoying default flex action which |
* matches any character and prints it. If any input ever matches this |
* rule, then we have made a mistake above and need to fix one or more |
* of the preceding patterns to match that input. */ |
<*>. { |
glcpp_error(yylloc, yyextra, "Internal compiler error: Unexpected character: %s", yytext); |
/* We don't actually use the UNREACHABLE start condition. We |
only have this block here so that we can pretend to call some |
generated functions, (to avoid "defined but not used" |
warnings. */ |
if (YY_START == UNREACHABLE) { |
unput('.'); |
yy_top_state(yyextra); |
} |
} |
%% |
void |
glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader) |
{ |
yy_scan_string(shader, parser->scanner); |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/glcpp-parse.c |
---|
0,0 → 1,4793 |
/* A Bison parser, made by GNU Bison 3.0.4. */ |
/* Bison implementation for Yacc-like parsers in C |
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. |
This program is free software: you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation, either version 3 of the License, or |
(at your option) any later version. |
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
You should have received a copy of the GNU General Public License |
along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
/* As a special exception, you may create a larger work that contains |
part or all of the Bison parser skeleton and distribute that work |
under terms of your choice, so long as that work isn't itself a |
parser generator using the skeleton or a modified version thereof |
as a parser skeleton. Alternatively, if you modify or redistribute |
the parser skeleton itself, you may (at your option) remove this |
special exception, which will cause the skeleton and the resulting |
Bison output files to be licensed under the GNU General Public |
License without this special exception. |
This special exception was added by the Free Software Foundation in |
version 2.2 of Bison. */ |
/* C LALR(1) parser skeleton written by Richard Stallman, by |
simplifying the original so-called "semantic" parser. */ |
/* All symbols defined below should begin with yy or YY, to avoid |
infringing on user name space. This should be done even for local |
variables, as they might otherwise be expanded by user macros. |
There are some unavoidable exceptions within include files to |
define necessary library symbols; they are noted "INFRINGES ON |
USER NAME SPACE" below. */ |
/* Identify Bison output. */ |
#define YYBISON 1 |
/* Bison version. */ |
#define YYBISON_VERSION "3.0.4" |
/* Skeleton name. */ |
#define YYSKELETON_NAME "yacc.c" |
/* Pure parsers. */ |
#define YYPURE 1 |
/* Push parsers. */ |
#define YYPUSH 0 |
/* Pull parsers. */ |
#define YYPULL 1 |
/* Substitute the variable and function names. */ |
#define yyparse glcpp_parser_parse |
#define yylex glcpp_parser_lex |
#define yyerror glcpp_parser_error |
#define yydebug glcpp_parser_debug |
#define yynerrs glcpp_parser_nerrs |
/* Copy the first part of user declarations. */ |
#line 1 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:339 */ |
/* |
* Copyright © 2010 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <assert.h> |
#include <inttypes.h> |
#include "glcpp.h" |
#include "main/core.h" /* for struct gl_extensions */ |
#include "main/mtypes.h" /* for gl_api enum */ |
static void |
yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error); |
static void |
_define_object_macro (glcpp_parser_t *parser, |
YYLTYPE *loc, |
const char *macro, |
token_list_t *replacements); |
static void |
_define_function_macro (glcpp_parser_t *parser, |
YYLTYPE *loc, |
const char *macro, |
string_list_t *parameters, |
token_list_t *replacements); |
static string_list_t * |
_string_list_create (void *ctx); |
static void |
_string_list_append_item (string_list_t *list, const char *str); |
static int |
_string_list_contains (string_list_t *list, const char *member, int *index); |
static const char * |
_string_list_has_duplicate (string_list_t *list); |
static int |
_string_list_length (string_list_t *list); |
static int |
_string_list_equal (string_list_t *a, string_list_t *b); |
static argument_list_t * |
_argument_list_create (void *ctx); |
static void |
_argument_list_append (argument_list_t *list, token_list_t *argument); |
static int |
_argument_list_length (argument_list_t *list); |
static token_list_t * |
_argument_list_member_at (argument_list_t *list, int index); |
/* Note: This function ralloc_steal()s the str pointer. */ |
static token_t * |
_token_create_str (void *ctx, int type, char *str); |
static token_t * |
_token_create_ival (void *ctx, int type, int ival); |
static token_list_t * |
_token_list_create (void *ctx); |
static void |
_token_list_append (token_list_t *list, token_t *token); |
static void |
_token_list_append_list (token_list_t *list, token_list_t *tail); |
static int |
_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b); |
static void |
_parser_active_list_push (glcpp_parser_t *parser, |
const char *identifier, |
token_node_t *marker); |
static void |
_parser_active_list_pop (glcpp_parser_t *parser); |
static int |
_parser_active_list_contains (glcpp_parser_t *parser, const char *identifier); |
typedef enum { |
EXPANSION_MODE_IGNORE_DEFINED, |
EXPANSION_MODE_EVALUATE_DEFINED |
} expansion_mode_t; |
/* Expand list, and begin lexing from the result (after first |
* prefixing a token of type 'head_token_type'). |
*/ |
static void |
_glcpp_parser_expand_and_lex_from (glcpp_parser_t *parser, |
int head_token_type, |
token_list_t *list, |
expansion_mode_t mode); |
/* Perform macro expansion in-place on the given list. */ |
static void |
_glcpp_parser_expand_token_list (glcpp_parser_t *parser, |
token_list_t *list, |
expansion_mode_t mode); |
static void |
_glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser, |
token_list_t *list); |
static void |
_glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc, |
int condition); |
static void |
_glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc, |
const char *type, int condition); |
static void |
_glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc); |
static void |
_glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version, |
const char *ident, bool explicitly_set); |
static int |
glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser); |
static void |
glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list); |
static void |
add_builtin_define(glcpp_parser_t *parser, const char *name, int value); |
#line 232 "glcpp/glcpp-parse.c" /* yacc.c:339 */ |
# ifndef YY_NULLPTR |
# if defined __cplusplus && 201103L <= __cplusplus |
# define YY_NULLPTR nullptr |
# else |
# define YY_NULLPTR 0 |
# endif |
# endif |
/* Enabling verbose error messages. */ |
#ifdef YYERROR_VERBOSE |
# undef YYERROR_VERBOSE |
# define YYERROR_VERBOSE 1 |
#else |
# define YYERROR_VERBOSE 1 |
#endif |
/* In a future release of Bison, this section will be replaced |
by #include "glcpp-parse.h". */ |
#ifndef YY_GLCPP_PARSER_GLCPP_GLCPP_PARSE_H_INCLUDED |
# define YY_GLCPP_PARSER_GLCPP_GLCPP_PARSE_H_INCLUDED |
/* Debug traces. */ |
#ifndef YYDEBUG |
# define YYDEBUG 1 |
#endif |
#if YYDEBUG |
extern int glcpp_parser_debug; |
#endif |
/* Token type. */ |
#ifndef YYTOKENTYPE |
# define YYTOKENTYPE |
enum yytokentype |
{ |
DEFINED = 258, |
ELIF_EXPANDED = 259, |
HASH_TOKEN = 260, |
DEFINE_TOKEN = 261, |
FUNC_IDENTIFIER = 262, |
OBJ_IDENTIFIER = 263, |
ELIF = 264, |
ELSE = 265, |
ENDIF = 266, |
ERROR_TOKEN = 267, |
IF = 268, |
IFDEF = 269, |
IFNDEF = 270, |
LINE = 271, |
PRAGMA = 272, |
UNDEF = 273, |
VERSION_TOKEN = 274, |
GARBAGE = 275, |
IDENTIFIER = 276, |
IF_EXPANDED = 277, |
INTEGER = 278, |
INTEGER_STRING = 279, |
LINE_EXPANDED = 280, |
NEWLINE = 281, |
OTHER = 282, |
PLACEHOLDER = 283, |
SPACE = 284, |
PLUS_PLUS = 285, |
MINUS_MINUS = 286, |
PASTE = 287, |
OR = 288, |
AND = 289, |
EQUAL = 290, |
NOT_EQUAL = 291, |
LESS_OR_EQUAL = 292, |
GREATER_OR_EQUAL = 293, |
LEFT_SHIFT = 294, |
RIGHT_SHIFT = 295, |
UNARY = 296 |
}; |
#endif |
/* Value type. */ |
/* Location type. */ |
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED |
typedef struct YYLTYPE YYLTYPE; |
struct YYLTYPE |
{ |
int first_line; |
int first_column; |
int last_line; |
int last_column; |
}; |
# define YYLTYPE_IS_DECLARED 1 |
# define YYLTYPE_IS_TRIVIAL 1 |
#endif |
int glcpp_parser_parse (glcpp_parser_t *parser); |
#endif /* !YY_GLCPP_PARSER_GLCPP_GLCPP_PARSE_H_INCLUDED */ |
/* Copy the second part of user declarations. */ |
#line 333 "glcpp/glcpp-parse.c" /* yacc.c:358 */ |
#ifdef short |
# undef short |
#endif |
#ifdef YYTYPE_UINT8 |
typedef YYTYPE_UINT8 yytype_uint8; |
#else |
typedef unsigned char yytype_uint8; |
#endif |
#ifdef YYTYPE_INT8 |
typedef YYTYPE_INT8 yytype_int8; |
#else |
typedef signed char yytype_int8; |
#endif |
#ifdef YYTYPE_UINT16 |
typedef YYTYPE_UINT16 yytype_uint16; |
#else |
typedef unsigned short int yytype_uint16; |
#endif |
#ifdef YYTYPE_INT16 |
typedef YYTYPE_INT16 yytype_int16; |
#else |
typedef short int yytype_int16; |
#endif |
#ifndef YYSIZE_T |
# ifdef __SIZE_TYPE__ |
# define YYSIZE_T __SIZE_TYPE__ |
# elif defined size_t |
# define YYSIZE_T size_t |
# elif ! defined YYSIZE_T |
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ |
# define YYSIZE_T size_t |
# else |
# define YYSIZE_T unsigned int |
# endif |
#endif |
#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) |
#ifndef YY_ |
# if defined YYENABLE_NLS && YYENABLE_NLS |
# if ENABLE_NLS |
# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ |
# define YY_(Msgid) dgettext ("bison-runtime", Msgid) |
# endif |
# endif |
# ifndef YY_ |
# define YY_(Msgid) Msgid |
# endif |
#endif |
#ifndef YY_ATTRIBUTE |
# if (defined __GNUC__ \ |
&& (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ |
|| defined __SUNPRO_C && 0x5110 <= __SUNPRO_C |
# define YY_ATTRIBUTE(Spec) __attribute__(Spec) |
# else |
# define YY_ATTRIBUTE(Spec) /* empty */ |
# endif |
#endif |
#ifndef YY_ATTRIBUTE_PURE |
# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) |
#endif |
#ifndef YY_ATTRIBUTE_UNUSED |
# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) |
#endif |
#if !defined _Noreturn \ |
&& (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) |
# if defined _MSC_VER && 1200 <= _MSC_VER |
# define _Noreturn __declspec (noreturn) |
# else |
# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) |
# endif |
#endif |
/* Suppress unused-variable warnings by "using" E. */ |
#if ! defined lint || defined __GNUC__ |
# define YYUSE(E) ((void) (E)) |
#else |
# define YYUSE(E) /* empty */ |
#endif |
#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ |
/* Suppress an incorrect diagnostic about yylval being uninitialized. */ |
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ |
_Pragma ("GCC diagnostic push") \ |
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ |
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") |
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ |
_Pragma ("GCC diagnostic pop") |
#else |
# define YY_INITIAL_VALUE(Value) Value |
#endif |
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN |
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN |
# define YY_IGNORE_MAYBE_UNINITIALIZED_END |
#endif |
#ifndef YY_INITIAL_VALUE |
# define YY_INITIAL_VALUE(Value) /* Nothing. */ |
#endif |
#if ! defined yyoverflow || YYERROR_VERBOSE |
/* The parser invokes alloca or malloc; define the necessary symbols. */ |
# ifdef YYSTACK_USE_ALLOCA |
# if YYSTACK_USE_ALLOCA |
# ifdef __GNUC__ |
# define YYSTACK_ALLOC __builtin_alloca |
# elif defined __BUILTIN_VA_ARG_INCR |
# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ |
# elif defined _AIX |
# define YYSTACK_ALLOC __alloca |
# elif defined _MSC_VER |
# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ |
# define alloca _alloca |
# else |
# define YYSTACK_ALLOC alloca |
# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS |
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ |
/* Use EXIT_SUCCESS as a witness for stdlib.h. */ |
# ifndef EXIT_SUCCESS |
# define EXIT_SUCCESS 0 |
# endif |
# endif |
# endif |
# endif |
# endif |
# ifdef YYSTACK_ALLOC |
/* Pacify GCC's 'empty if-body' warning. */ |
# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) |
# ifndef YYSTACK_ALLOC_MAXIMUM |
/* The OS might guarantee only one guard page at the bottom of the stack, |
and a page size can be as small as 4096 bytes. So we cannot safely |
invoke alloca (N) if N exceeds 4096. Use a slightly smaller number |
to allow for a few compiler-allocated temporary stack slots. */ |
# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ |
# endif |
# else |
# define YYSTACK_ALLOC YYMALLOC |
# define YYSTACK_FREE YYFREE |
# ifndef YYSTACK_ALLOC_MAXIMUM |
# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM |
# endif |
# if (defined __cplusplus && ! defined EXIT_SUCCESS \ |
&& ! ((defined YYMALLOC || defined malloc) \ |
&& (defined YYFREE || defined free))) |
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ |
# ifndef EXIT_SUCCESS |
# define EXIT_SUCCESS 0 |
# endif |
# endif |
# ifndef YYMALLOC |
# define YYMALLOC malloc |
# if ! defined malloc && ! defined EXIT_SUCCESS |
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ |
# endif |
# endif |
# ifndef YYFREE |
# define YYFREE free |
# if ! defined free && ! defined EXIT_SUCCESS |
void free (void *); /* INFRINGES ON USER NAME SPACE */ |
# endif |
# endif |
# endif |
#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ |
#if (! defined yyoverflow \ |
&& (! defined __cplusplus \ |
|| (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ |
&& defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) |
/* A type that is properly aligned for any stack member. */ |
union yyalloc |
{ |
yytype_int16 yyss_alloc; |
YYSTYPE yyvs_alloc; |
YYLTYPE yyls_alloc; |
}; |
/* The size of the maximum gap between one aligned stack and the next. */ |
# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) |
/* The size of an array large to enough to hold all stacks, each with |
N elements. */ |
# define YYSTACK_BYTES(N) \ |
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ |
+ 2 * YYSTACK_GAP_MAXIMUM) |
# define YYCOPY_NEEDED 1 |
/* Relocate STACK from its old location to the new one. The |
local variables YYSIZE and YYSTACKSIZE give the old and new number of |
elements in the stack, and YYPTR gives the new location of the |
stack. Advance YYPTR to a properly aligned location for the next |
stack. */ |
# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ |
do \ |
{ \ |
YYSIZE_T yynewbytes; \ |
YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ |
Stack = &yyptr->Stack_alloc; \ |
yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ |
yyptr += yynewbytes / sizeof (*yyptr); \ |
} \ |
while (0) |
#endif |
#if defined YYCOPY_NEEDED && YYCOPY_NEEDED |
/* Copy COUNT objects from SRC to DST. The source and destination do |
not overlap. */ |
# ifndef YYCOPY |
# if defined __GNUC__ && 1 < __GNUC__ |
# define YYCOPY(Dst, Src, Count) \ |
__builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) |
# else |
# define YYCOPY(Dst, Src, Count) \ |
do \ |
{ \ |
YYSIZE_T yyi; \ |
for (yyi = 0; yyi < (Count); yyi++) \ |
(Dst)[yyi] = (Src)[yyi]; \ |
} \ |
while (0) |
# endif |
# endif |
#endif /* !YYCOPY_NEEDED */ |
/* YYFINAL -- State number of the termination state. */ |
#define YYFINAL 2 |
/* YYLAST -- Last index in YYTABLE. */ |
#define YYLAST 652 |
/* YYNTOKENS -- Number of terminals. */ |
#define YYNTOKENS 64 |
/* YYNNTS -- Number of nonterminals. */ |
#define YYNNTS 25 |
/* YYNRULES -- Number of rules. */ |
#define YYNRULES 118 |
/* YYNSTATES -- Number of states. */ |
#define YYNSTATES 185 |
/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned |
by yylex, with out-of-bounds checking. */ |
#define YYUNDEFTOK 2 |
#define YYMAXUTOK 296 |
#define YYTRANSLATE(YYX) \ |
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) |
/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM |
as returned by yylex, without out-of-bounds checking. */ |
static const yytype_uint8 yytranslate[] = |
{ |
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 54, 2, 2, 2, 50, 37, 2, |
52, 53, 48, 46, 56, 47, 61, 49, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 62, |
40, 63, 41, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 57, 2, 58, 36, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 59, 35, 60, 55, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 1, 2, 3, 4, |
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, |
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, |
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, |
38, 39, 42, 43, 44, 45, 51 |
}; |
#if YYDEBUG |
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ |
static const yytype_uint16 yyrline[] = |
{ |
0, 205, 205, 207, 211, 212, 213, 218, 222, 227, |
232, 240, 253, 256, 259, 265, 268, 269, 269, 284, |
284, 287, 287, 305, 305, 328, 338, 338, 345, 345, |
352, 378, 398, 398, 411, 411, 414, 420, 426, 429, |
435, 438, 441, 447, 456, 461, 465, 472, 483, 494, |
501, 508, 515, 522, 529, 536, 543, 550, 557, 564, |
571, 578, 585, 597, 609, 616, 620, 624, 628, 632, |
638, 643, 651, 652, 656, 657, 660, 662, 668, 673, |
680, 684, 688, 692, 696, 700, 707, 708, 709, 710, |
711, 712, 713, 714, 715, 716, 717, 718, 719, 720, |
721, 722, 723, 724, 725, 726, 727, 728, 729, 730, |
731, 732, 733, 734, 735, 736, 737, 738, 739 |
}; |
#endif |
#if YYDEBUG || YYERROR_VERBOSE || 1 |
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. |
First, the terminals, then, starting at YYNTOKENS, nonterminals. */ |
static const char *const yytname[] = |
{ |
"$end", "error", "$undefined", "DEFINED", "ELIF_EXPANDED", "HASH_TOKEN", |
"DEFINE_TOKEN", "FUNC_IDENTIFIER", "OBJ_IDENTIFIER", "ELIF", "ELSE", |
"ENDIF", "ERROR_TOKEN", "IF", "IFDEF", "IFNDEF", "LINE", "PRAGMA", |
"UNDEF", "VERSION_TOKEN", "GARBAGE", "IDENTIFIER", "IF_EXPANDED", |
"INTEGER", "INTEGER_STRING", "LINE_EXPANDED", "NEWLINE", "OTHER", |
"PLACEHOLDER", "SPACE", "PLUS_PLUS", "MINUS_MINUS", "PASTE", "OR", "AND", |
"'|'", "'^'", "'&'", "EQUAL", "NOT_EQUAL", "'<'", "'>'", "LESS_OR_EQUAL", |
"GREATER_OR_EQUAL", "LEFT_SHIFT", "RIGHT_SHIFT", "'+'", "'-'", "'*'", |
"'/'", "'%'", "UNARY", "'('", "')'", "'!'", "'~'", "','", "'['", "']'", |
"'{'", "'}'", "'.'", "';'", "'='", "$accept", "input", "line", |
"expanded_line", "define", "control_line", "$@1", "control_line_success", |
"$@2", "$@3", "$@4", "$@5", "$@6", "$@7", "$@8", "control_line_error", |
"integer_constant", "expression", "identifier_list", "text_line", |
"replacement_list", "junk", "pp_tokens", "preprocessing_token", |
"operator", YY_NULLPTR |
}; |
#endif |
# ifdef YYPRINT |
/* YYTOKNUM[NUM] -- (External) token number corresponding to the |
(internal) symbol number NUM (which must be that of a token). */ |
static const yytype_uint16 yytoknum[] = |
{ |
0, 256, 257, 258, 259, 260, 261, 262, 263, 264, |
265, 266, 267, 268, 269, 270, 271, 272, 273, 274, |
275, 276, 277, 278, 279, 280, 281, 282, 283, 284, |
285, 286, 287, 288, 289, 124, 94, 38, 290, 291, |
60, 62, 292, 293, 294, 295, 43, 45, 42, 47, |
37, 296, 40, 41, 33, 126, 44, 91, 93, 123, |
125, 46, 59, 61 |
}; |
# endif |
#define YYPACT_NINF -142 |
#define yypact_value_is_default(Yystate) \ |
(!!((Yystate) == (-142))) |
#define YYTABLE_NINF -1 |
#define yytable_value_is_error(Yytable_value) \ |
0 |
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing |
STATE-NUM. */ |
static const yytype_int16 yypact[] = |
{ |
-142, 134, -142, -142, -18, 578, -142, -18, -142, -15, |
-142, -142, 26, -142, -142, -142, -142, -142, -142, -142, |
-142, -142, -142, -142, -142, -142, -142, -142, -142, -142, |
-142, -142, -142, -142, -142, -142, -142, -142, -142, -142, |
-142, -142, -142, -142, -142, -142, -142, -142, -142, -142, |
-142, -142, 182, -142, -142, -142, -142, -142, -18, -18, |
-18, -18, -18, -142, 508, 7, 230, -142, -142, 9, |
25, -142, -142, -142, 35, -142, -15, 470, -142, 533, |
81, -142, -142, -142, -142, -142, -142, -23, -142, -142, |
-142, -18, -18, -18, -18, -18, -18, -18, -18, -18, |
-18, -18, -18, -18, -18, -18, -18, -18, -18, -142, |
65, -142, 278, 38, 58, -142, -142, 470, 90, 91, |
470, -142, 92, 37, 326, -142, -142, 89, -142, 571, |
587, 602, 83, 102, 0, 0, 33, 33, 33, 33, |
20, 20, 60, 60, -142, -142, -142, 66, 470, -142, |
-142, -142, -142, 374, 470, 470, 422, 109, 110, -142, |
-142, -142, -14, 131, 470, -142, 136, 470, 172, -142, |
-142, -142, -142, 470, 4, -142, -142, -142, 173, 470, |
179, -142, 175, -142, -142 |
}; |
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. |
Performed when YYTABLE does not specify something else to do. Zero |
means the default is an error. */ |
static const yytype_uint8 yydefact[] = |
{ |
2, 0, 1, 83, 0, 0, 80, 0, 81, 0, |
72, 84, 85, 117, 118, 116, 112, 111, 110, 109, |
93, 107, 108, 103, 104, 105, 106, 101, 102, 95, |
96, 94, 99, 100, 88, 89, 98, 97, 114, 86, |
87, 90, 91, 92, 113, 115, 3, 7, 4, 15, |
16, 6, 0, 78, 82, 46, 44, 43, 0, 0, |
0, 0, 0, 45, 0, 19, 0, 32, 34, 0, |
23, 26, 28, 17, 0, 21, 0, 0, 38, 0, |
0, 5, 73, 85, 79, 68, 67, 0, 65, 66, |
9, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, 0, 41, |
0, 31, 0, 0, 0, 40, 25, 0, 0, 0, |
0, 39, 0, 0, 0, 8, 10, 0, 69, 47, |
48, 49, 50, 51, 53, 52, 57, 56, 55, 54, |
59, 58, 61, 60, 64, 63, 62, 0, 74, 20, |
30, 33, 35, 0, 76, 76, 0, 0, 0, 36, |
42, 11, 0, 0, 75, 24, 0, 77, 0, 18, |
22, 37, 70, 74, 0, 12, 27, 29, 0, 74, |
0, 13, 0, 71, 14 |
}; |
/* YYPGOTO[NTERM-NUM]. */ |
static const yytype_int16 yypgoto[] = |
{ |
-142, -142, -142, -142, -142, 47, -142, -142, -142, -142, |
-142, -142, -142, -142, -142, -142, -5, -6, -142, -142, |
-141, 49, -1, -50, -142 |
}; |
/* YYDEFGOTO[NTERM-NUM]. */ |
static const yytype_int16 yydefgoto[] = |
{ |
-1, 1, 46, 47, 149, 48, 120, 49, 110, 122, |
117, 118, 119, 113, 114, 50, 63, 64, 174, 51, |
163, 166, 164, 53, 54 |
}; |
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If |
positive, shift that token. If negative, reduce the rule whose |
number is the opposite. If YYTABLE_NINF, syntax error. */ |
static const yytype_uint8 yytable[] = |
{ |
52, 79, 84, 55, 80, 56, 57, 172, 56, 57, |
91, 92, 93, 94, 95, 96, 97, 98, 99, 100, |
101, 102, 103, 104, 105, 106, 107, 108, 58, 59, |
128, 5, 178, 109, 60, 115, 61, 62, 182, 173, |
98, 99, 100, 101, 102, 103, 104, 105, 106, 107, |
108, 116, 85, 86, 87, 88, 89, 179, 158, 81, |
180, 121, 84, 159, 151, 112, 104, 105, 106, 107, |
108, 123, 147, 148, 84, 127, 124, 102, 103, 104, |
105, 106, 107, 108, 152, 129, 130, 131, 132, 133, |
134, 135, 136, 137, 138, 139, 140, 141, 142, 143, |
144, 145, 146, 84, 56, 57, 84, 126, 106, 107, |
108, 154, 155, 157, 84, 161, 153, 84, 162, 156, |
95, 96, 97, 98, 99, 100, 101, 102, 103, 104, |
105, 106, 107, 108, 2, 170, 171, 3, 4, 5, |
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, |
106, 107, 108, 167, 167, 6, 7, 175, 8, 9, |
10, 11, 176, 12, 13, 14, 15, 16, 17, 18, |
19, 20, 21, 22, 23, 24, 25, 26, 27, 28, |
29, 30, 31, 32, 33, 3, 34, 35, 36, 37, |
38, 39, 40, 41, 42, 43, 44, 45, 177, 181, |
183, 184, 0, 6, 168, 0, 8, 0, 82, 11, |
0, 83, 13, 14, 15, 16, 17, 18, 19, 20, |
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, |
31, 32, 33, 3, 34, 35, 36, 37, 38, 39, |
40, 41, 42, 43, 44, 45, 0, 0, 0, 0, |
0, 6, 0, 0, 8, 0, 111, 11, 0, 83, |
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, |
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, |
33, 3, 34, 35, 36, 37, 38, 39, 40, 41, |
42, 43, 44, 45, 0, 0, 0, 0, 0, 6, |
0, 0, 8, 0, 150, 11, 0, 83, 13, 14, |
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, |
25, 26, 27, 28, 29, 30, 31, 32, 33, 3, |
34, 35, 36, 37, 38, 39, 40, 41, 42, 43, |
44, 45, 0, 0, 0, 0, 0, 6, 0, 0, |
8, 0, 160, 11, 0, 83, 13, 14, 15, 16, |
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, |
27, 28, 29, 30, 31, 32, 33, 3, 34, 35, |
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, |
0, 0, 0, 0, 0, 6, 0, 0, 8, 0, |
165, 11, 0, 83, 13, 14, 15, 16, 17, 18, |
19, 20, 21, 22, 23, 24, 25, 26, 27, 28, |
29, 30, 31, 32, 33, 3, 34, 35, 36, 37, |
38, 39, 40, 41, 42, 43, 44, 45, 0, 0, |
0, 0, 0, 6, 0, 0, 8, 0, 169, 11, |
0, 83, 13, 14, 15, 16, 17, 18, 19, 20, |
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, |
31, 32, 33, 3, 34, 35, 36, 37, 38, 39, |
40, 41, 42, 43, 44, 45, 0, 0, 0, 0, |
0, 6, 0, 0, 8, 0, 0, 11, 0, 83, |
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, |
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, |
33, 0, 34, 35, 36, 37, 38, 39, 40, 41, |
42, 43, 44, 45, 90, 0, 0, 0, 0, 0, |
0, 91, 92, 93, 94, 95, 96, 97, 98, 99, |
100, 101, 102, 103, 104, 105, 106, 107, 108, 125, |
0, 0, 0, 0, 0, 0, 91, 92, 93, 94, |
95, 96, 97, 98, 99, 100, 101, 102, 103, 104, |
105, 106, 107, 108, 65, 0, 0, 66, 67, 68, |
69, 70, 71, 72, 73, 74, 75, 76, 77, 0, |
0, 0, 0, 0, 78, 92, 93, 94, 95, 96, |
97, 98, 99, 100, 101, 102, 103, 104, 105, 106, |
107, 108, 93, 94, 95, 96, 97, 98, 99, 100, |
101, 102, 103, 104, 105, 106, 107, 108, 94, 95, |
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, |
106, 107, 108 |
}; |
static const yytype_int16 yycheck[] = |
{ |
1, 7, 52, 21, 9, 23, 24, 21, 23, 24, |
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, |
43, 44, 45, 46, 47, 48, 49, 50, 46, 47, |
53, 5, 173, 26, 52, 26, 54, 55, 179, 53, |
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, |
50, 26, 58, 59, 60, 61, 62, 53, 21, 12, |
56, 26, 112, 26, 26, 66, 46, 47, 48, 49, |
50, 76, 7, 8, 124, 80, 77, 44, 45, 46, |
47, 48, 49, 50, 26, 91, 92, 93, 94, 95, |
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, |
106, 107, 108, 153, 23, 24, 156, 26, 48, 49, |
50, 21, 21, 21, 164, 26, 117, 167, 52, 120, |
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, |
47, 48, 49, 50, 0, 26, 26, 3, 4, 5, |
38, 39, 40, 41, 42, 43, 44, 45, 46, 47, |
48, 49, 50, 154, 155, 21, 22, 26, 24, 25, |
26, 27, 26, 29, 30, 31, 32, 33, 34, 35, |
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, |
46, 47, 48, 49, 50, 3, 52, 53, 54, 55, |
56, 57, 58, 59, 60, 61, 62, 63, 26, 26, |
21, 26, -1, 21, 155, -1, 24, -1, 26, 27, |
-1, 29, 30, 31, 32, 33, 34, 35, 36, 37, |
38, 39, 40, 41, 42, 43, 44, 45, 46, 47, |
48, 49, 50, 3, 52, 53, 54, 55, 56, 57, |
58, 59, 60, 61, 62, 63, -1, -1, -1, -1, |
-1, 21, -1, -1, 24, -1, 26, 27, -1, 29, |
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, |
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, |
50, 3, 52, 53, 54, 55, 56, 57, 58, 59, |
60, 61, 62, 63, -1, -1, -1, -1, -1, 21, |
-1, -1, 24, -1, 26, 27, -1, 29, 30, 31, |
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, |
42, 43, 44, 45, 46, 47, 48, 49, 50, 3, |
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, |
62, 63, -1, -1, -1, -1, -1, 21, -1, -1, |
24, -1, 26, 27, -1, 29, 30, 31, 32, 33, |
34, 35, 36, 37, 38, 39, 40, 41, 42, 43, |
44, 45, 46, 47, 48, 49, 50, 3, 52, 53, |
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, |
-1, -1, -1, -1, -1, 21, -1, -1, 24, -1, |
26, 27, -1, 29, 30, 31, 32, 33, 34, 35, |
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, |
46, 47, 48, 49, 50, 3, 52, 53, 54, 55, |
56, 57, 58, 59, 60, 61, 62, 63, -1, -1, |
-1, -1, -1, 21, -1, -1, 24, -1, 26, 27, |
-1, 29, 30, 31, 32, 33, 34, 35, 36, 37, |
38, 39, 40, 41, 42, 43, 44, 45, 46, 47, |
48, 49, 50, 3, 52, 53, 54, 55, 56, 57, |
58, 59, 60, 61, 62, 63, -1, -1, -1, -1, |
-1, 21, -1, -1, 24, -1, -1, 27, -1, 29, |
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, |
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, |
50, -1, 52, 53, 54, 55, 56, 57, 58, 59, |
60, 61, 62, 63, 26, -1, -1, -1, -1, -1, |
-1, 33, 34, 35, 36, 37, 38, 39, 40, 41, |
42, 43, 44, 45, 46, 47, 48, 49, 50, 26, |
-1, -1, -1, -1, -1, -1, 33, 34, 35, 36, |
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, |
47, 48, 49, 50, 6, -1, -1, 9, 10, 11, |
12, 13, 14, 15, 16, 17, 18, 19, 20, -1, |
-1, -1, -1, -1, 26, 34, 35, 36, 37, 38, |
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, |
49, 50, 35, 36, 37, 38, 39, 40, 41, 42, |
43, 44, 45, 46, 47, 48, 49, 50, 36, 37, |
38, 39, 40, 41, 42, 43, 44, 45, 46, 47, |
48, 49, 50 |
}; |
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing |
symbol of state STATE-NUM. */ |
static const yytype_uint8 yystos[] = |
{ |
0, 65, 0, 3, 4, 5, 21, 22, 24, 25, |
26, 27, 29, 30, 31, 32, 33, 34, 35, 36, |
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, |
47, 48, 49, 50, 52, 53, 54, 55, 56, 57, |
58, 59, 60, 61, 62, 63, 66, 67, 69, 71, |
79, 83, 86, 87, 88, 21, 23, 24, 46, 47, |
52, 54, 55, 80, 81, 6, 9, 10, 11, 12, |
13, 14, 15, 16, 17, 18, 19, 20, 26, 81, |
80, 69, 26, 29, 87, 81, 81, 81, 81, 81, |
26, 33, 34, 35, 36, 37, 38, 39, 40, 41, |
42, 43, 44, 45, 46, 47, 48, 49, 50, 26, |
72, 26, 86, 77, 78, 26, 26, 74, 75, 76, |
70, 26, 73, 80, 86, 26, 26, 80, 53, 81, |
81, 81, 81, 81, 81, 81, 81, 81, 81, 81, |
81, 81, 81, 81, 81, 81, 81, 7, 8, 68, |
26, 26, 26, 86, 21, 21, 86, 21, 21, 26, |
26, 26, 52, 84, 86, 26, 85, 86, 85, 26, |
26, 26, 21, 53, 82, 26, 26, 26, 84, 53, |
56, 26, 84, 21, 26 |
}; |
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ |
static const yytype_uint8 yyr1[] = |
{ |
0, 64, 65, 65, 66, 66, 66, 66, 67, 67, |
67, 67, 68, 68, 68, 69, 69, 70, 69, 72, |
71, 73, 71, 74, 71, 71, 75, 71, 76, 71, |
71, 71, 77, 71, 78, 71, 71, 71, 71, 71, |
79, 79, 79, 80, 80, 81, 81, 81, 81, 81, |
81, 81, 81, 81, 81, 81, 81, 81, 81, 81, |
81, 81, 81, 81, 81, 81, 81, 81, 81, 81, |
82, 82, 83, 83, 84, 84, 85, 85, 86, 86, |
87, 87, 87, 87, 87, 87, 88, 88, 88, 88, |
88, 88, 88, 88, 88, 88, 88, 88, 88, 88, |
88, 88, 88, 88, 88, 88, 88, 88, 88, 88, |
88, 88, 88, 88, 88, 88, 88, 88, 88 |
}; |
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ |
static const yytype_uint8 yyr2[] = |
{ |
0, 2, 0, 2, 1, 2, 1, 1, 3, 3, |
3, 4, 3, 5, 6, 1, 1, 0, 5, 0, |
4, 0, 5, 0, 5, 3, 0, 6, 0, 6, |
4, 3, 0, 4, 0, 4, 4, 5, 2, 3, |
3, 3, 4, 1, 1, 1, 1, 3, 3, 3, |
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, |
3, 3, 3, 3, 3, 2, 2, 2, 2, 3, |
1, 3, 1, 2, 0, 1, 0, 1, 1, 2, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1 |
}; |
#define yyerrok (yyerrstatus = 0) |
#define yyclearin (yychar = YYEMPTY) |
#define YYEMPTY (-2) |
#define YYEOF 0 |
#define YYACCEPT goto yyacceptlab |
#define YYABORT goto yyabortlab |
#define YYERROR goto yyerrorlab |
#define YYRECOVERING() (!!yyerrstatus) |
#define YYBACKUP(Token, Value) \ |
do \ |
if (yychar == YYEMPTY) \ |
{ \ |
yychar = (Token); \ |
yylval = (Value); \ |
YYPOPSTACK (yylen); \ |
yystate = *yyssp; \ |
goto yybackup; \ |
} \ |
else \ |
{ \ |
yyerror (&yylloc, parser, YY_("syntax error: cannot back up")); \ |
YYERROR; \ |
} \ |
while (0) |
/* Error token number */ |
#define YYTERROR 1 |
#define YYERRCODE 256 |
/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. |
If N is 0, then set CURRENT to the empty location which ends |
the previous symbol: RHS[0] (always defined). */ |
#ifndef YYLLOC_DEFAULT |
# define YYLLOC_DEFAULT(Current, Rhs, N) \ |
do \ |
if (N) \ |
{ \ |
(Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ |
(Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ |
(Current).last_line = YYRHSLOC (Rhs, N).last_line; \ |
(Current).last_column = YYRHSLOC (Rhs, N).last_column; \ |
} \ |
else \ |
{ \ |
(Current).first_line = (Current).last_line = \ |
YYRHSLOC (Rhs, 0).last_line; \ |
(Current).first_column = (Current).last_column = \ |
YYRHSLOC (Rhs, 0).last_column; \ |
} \ |
while (0) |
#endif |
#define YYRHSLOC(Rhs, K) ((Rhs)[K]) |
/* Enable debugging if requested. */ |
#if YYDEBUG |
# ifndef YYFPRINTF |
# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ |
# define YYFPRINTF fprintf |
# endif |
# define YYDPRINTF(Args) \ |
do { \ |
if (yydebug) \ |
YYFPRINTF Args; \ |
} while (0) |
/* YY_LOCATION_PRINT -- Print the location on the stream. |
This macro was not mandated originally: define only if we know |
we won't break user code: when these are the locations we know. */ |
#ifndef YY_LOCATION_PRINT |
# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL |
/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ |
YY_ATTRIBUTE_UNUSED |
static unsigned |
yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) |
{ |
unsigned res = 0; |
int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; |
if (0 <= yylocp->first_line) |
{ |
res += YYFPRINTF (yyo, "%d", yylocp->first_line); |
if (0 <= yylocp->first_column) |
res += YYFPRINTF (yyo, ".%d", yylocp->first_column); |
} |
if (0 <= yylocp->last_line) |
{ |
if (yylocp->first_line < yylocp->last_line) |
{ |
res += YYFPRINTF (yyo, "-%d", yylocp->last_line); |
if (0 <= end_col) |
res += YYFPRINTF (yyo, ".%d", end_col); |
} |
else if (0 <= end_col && yylocp->first_column < end_col) |
res += YYFPRINTF (yyo, "-%d", end_col); |
} |
return res; |
} |
# define YY_LOCATION_PRINT(File, Loc) \ |
yy_location_print_ (File, &(Loc)) |
# else |
# define YY_LOCATION_PRINT(File, Loc) ((void) 0) |
# endif |
#endif |
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ |
do { \ |
if (yydebug) \ |
{ \ |
YYFPRINTF (stderr, "%s ", Title); \ |
yy_symbol_print (stderr, \ |
Type, Value, Location, parser); \ |
YYFPRINTF (stderr, "\n"); \ |
} \ |
} while (0) |
/*----------------------------------------. |
| Print this symbol's value on YYOUTPUT. | |
`----------------------------------------*/ |
static void |
yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, glcpp_parser_t *parser) |
{ |
FILE *yyo = yyoutput; |
YYUSE (yyo); |
YYUSE (yylocationp); |
YYUSE (parser); |
if (!yyvaluep) |
return; |
# ifdef YYPRINT |
if (yytype < YYNTOKENS) |
YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); |
# endif |
YYUSE (yytype); |
} |
/*--------------------------------. |
| Print this symbol on YYOUTPUT. | |
`--------------------------------*/ |
static void |
yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, glcpp_parser_t *parser) |
{ |
YYFPRINTF (yyoutput, "%s %s (", |
yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); |
YY_LOCATION_PRINT (yyoutput, *yylocationp); |
YYFPRINTF (yyoutput, ": "); |
yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, parser); |
YYFPRINTF (yyoutput, ")"); |
} |
/*------------------------------------------------------------------. |
| yy_stack_print -- Print the state stack from its BOTTOM up to its | |
| TOP (included). | |
`------------------------------------------------------------------*/ |
static void |
yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) |
{ |
YYFPRINTF (stderr, "Stack now"); |
for (; yybottom <= yytop; yybottom++) |
{ |
int yybot = *yybottom; |
YYFPRINTF (stderr, " %d", yybot); |
} |
YYFPRINTF (stderr, "\n"); |
} |
# define YY_STACK_PRINT(Bottom, Top) \ |
do { \ |
if (yydebug) \ |
yy_stack_print ((Bottom), (Top)); \ |
} while (0) |
/*------------------------------------------------. |
| Report that the YYRULE is going to be reduced. | |
`------------------------------------------------*/ |
static void |
yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, glcpp_parser_t *parser) |
{ |
unsigned long int yylno = yyrline[yyrule]; |
int yynrhs = yyr2[yyrule]; |
int yyi; |
YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", |
yyrule - 1, yylno); |
/* The symbols being reduced. */ |
for (yyi = 0; yyi < yynrhs; yyi++) |
{ |
YYFPRINTF (stderr, " $%d = ", yyi + 1); |
yy_symbol_print (stderr, |
yystos[yyssp[yyi + 1 - yynrhs]], |
&(yyvsp[(yyi + 1) - (yynrhs)]) |
, &(yylsp[(yyi + 1) - (yynrhs)]) , parser); |
YYFPRINTF (stderr, "\n"); |
} |
} |
# define YY_REDUCE_PRINT(Rule) \ |
do { \ |
if (yydebug) \ |
yy_reduce_print (yyssp, yyvsp, yylsp, Rule, parser); \ |
} while (0) |
/* Nonzero means print parse trace. It is left uninitialized so that |
multiple parsers can coexist. */ |
int yydebug; |
#else /* !YYDEBUG */ |
# define YYDPRINTF(Args) |
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) |
# define YY_STACK_PRINT(Bottom, Top) |
# define YY_REDUCE_PRINT(Rule) |
#endif /* !YYDEBUG */ |
/* YYINITDEPTH -- initial size of the parser's stacks. */ |
#ifndef YYINITDEPTH |
# define YYINITDEPTH 200 |
#endif |
/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only |
if the built-in stack extension method is used). |
Do not make this value too large; the results are undefined if |
YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) |
evaluated with infinite-precision integer arithmetic. */ |
#ifndef YYMAXDEPTH |
# define YYMAXDEPTH 10000 |
#endif |
#if YYERROR_VERBOSE |
# ifndef yystrlen |
# if defined __GLIBC__ && defined _STRING_H |
# define yystrlen strlen |
# else |
/* Return the length of YYSTR. */ |
static YYSIZE_T |
yystrlen (const char *yystr) |
{ |
YYSIZE_T yylen; |
for (yylen = 0; yystr[yylen]; yylen++) |
continue; |
return yylen; |
} |
# endif |
# endif |
# ifndef yystpcpy |
# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE |
# define yystpcpy stpcpy |
# else |
/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in |
YYDEST. */ |
static char * |
yystpcpy (char *yydest, const char *yysrc) |
{ |
char *yyd = yydest; |
const char *yys = yysrc; |
while ((*yyd++ = *yys++) != '\0') |
continue; |
return yyd - 1; |
} |
# endif |
# endif |
# ifndef yytnamerr |
/* Copy to YYRES the contents of YYSTR after stripping away unnecessary |
quotes and backslashes, so that it's suitable for yyerror. The |
heuristic is that double-quoting is unnecessary unless the string |
contains an apostrophe, a comma, or backslash (other than |
backslash-backslash). YYSTR is taken from yytname. If YYRES is |
null, do not copy; instead, return the length of what the result |
would have been. */ |
static YYSIZE_T |
yytnamerr (char *yyres, const char *yystr) |
{ |
if (*yystr == '"') |
{ |
YYSIZE_T yyn = 0; |
char const *yyp = yystr; |
for (;;) |
switch (*++yyp) |
{ |
case '\'': |
case ',': |
goto do_not_strip_quotes; |
case '\\': |
if (*++yyp != '\\') |
goto do_not_strip_quotes; |
/* Fall through. */ |
default: |
if (yyres) |
yyres[yyn] = *yyp; |
yyn++; |
break; |
case '"': |
if (yyres) |
yyres[yyn] = '\0'; |
return yyn; |
} |
do_not_strip_quotes: ; |
} |
if (! yyres) |
return yystrlen (yystr); |
return yystpcpy (yyres, yystr) - yyres; |
} |
# endif |
/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message |
about the unexpected token YYTOKEN for the state stack whose top is |
YYSSP. |
Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is |
not large enough to hold the message. In that case, also set |
*YYMSG_ALLOC to the required number of bytes. Return 2 if the |
required number of bytes is too large to store. */ |
static int |
yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, |
yytype_int16 *yyssp, int yytoken) |
{ |
YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); |
YYSIZE_T yysize = yysize0; |
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; |
/* Internationalized format string. */ |
const char *yyformat = YY_NULLPTR; |
/* Arguments of yyformat. */ |
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; |
/* Number of reported tokens (one for the "unexpected", one per |
"expected"). */ |
int yycount = 0; |
/* There are many possibilities here to consider: |
- If this state is a consistent state with a default action, then |
the only way this function was invoked is if the default action |
is an error action. In that case, don't check for expected |
tokens because there are none. |
- The only way there can be no lookahead present (in yychar) is if |
this state is a consistent state with a default action. Thus, |
detecting the absence of a lookahead is sufficient to determine |
that there is no unexpected or expected token to report. In that |
case, just report a simple "syntax error". |
- Don't assume there isn't a lookahead just because this state is a |
consistent state with a default action. There might have been a |
previous inconsistent state, consistent state with a non-default |
action, or user semantic action that manipulated yychar. |
- Of course, the expected token list depends on states to have |
correct lookahead information, and it depends on the parser not |
to perform extra reductions after fetching a lookahead from the |
scanner and before detecting a syntax error. Thus, state merging |
(from LALR or IELR) and default reductions corrupt the expected |
token list. However, the list is correct for canonical LR with |
one exception: it will still contain any token that will not be |
accepted due to an error action in a later state. |
*/ |
if (yytoken != YYEMPTY) |
{ |
int yyn = yypact[*yyssp]; |
yyarg[yycount++] = yytname[yytoken]; |
if (!yypact_value_is_default (yyn)) |
{ |
/* Start YYX at -YYN if negative to avoid negative indexes in |
YYCHECK. In other words, skip the first -YYN actions for |
this state because they are default actions. */ |
int yyxbegin = yyn < 0 ? -yyn : 0; |
/* Stay within bounds of both yycheck and yytname. */ |
int yychecklim = YYLAST - yyn + 1; |
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; |
int yyx; |
for (yyx = yyxbegin; yyx < yyxend; ++yyx) |
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR |
&& !yytable_value_is_error (yytable[yyx + yyn])) |
{ |
if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) |
{ |
yycount = 1; |
yysize = yysize0; |
break; |
} |
yyarg[yycount++] = yytname[yyx]; |
{ |
YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); |
if (! (yysize <= yysize1 |
&& yysize1 <= YYSTACK_ALLOC_MAXIMUM)) |
return 2; |
yysize = yysize1; |
} |
} |
} |
} |
switch (yycount) |
{ |
# define YYCASE_(N, S) \ |
case N: \ |
yyformat = S; \ |
break |
YYCASE_(0, YY_("syntax error")); |
YYCASE_(1, YY_("syntax error, unexpected %s")); |
YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); |
YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); |
YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); |
YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); |
# undef YYCASE_ |
} |
{ |
YYSIZE_T yysize1 = yysize + yystrlen (yyformat); |
if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) |
return 2; |
yysize = yysize1; |
} |
if (*yymsg_alloc < yysize) |
{ |
*yymsg_alloc = 2 * yysize; |
if (! (yysize <= *yymsg_alloc |
&& *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) |
*yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; |
return 1; |
} |
/* Avoid sprintf, as that infringes on the user's name space. |
Don't have undefined behavior even if the translation |
produced a string with the wrong number of "%s"s. */ |
{ |
char *yyp = *yymsg; |
int yyi = 0; |
while ((*yyp = *yyformat) != '\0') |
if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) |
{ |
yyp += yytnamerr (yyp, yyarg[yyi++]); |
yyformat += 2; |
} |
else |
{ |
yyp++; |
yyformat++; |
} |
} |
return 0; |
} |
#endif /* YYERROR_VERBOSE */ |
/*-----------------------------------------------. |
| Release the memory associated to this symbol. | |
`-----------------------------------------------*/ |
static void |
yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, glcpp_parser_t *parser) |
{ |
YYUSE (yyvaluep); |
YYUSE (yylocationp); |
YYUSE (parser); |
if (!yymsg) |
yymsg = "Deleting"; |
YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); |
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN |
YYUSE (yytype); |
YY_IGNORE_MAYBE_UNINITIALIZED_END |
} |
/*----------. |
| yyparse. | |
`----------*/ |
int |
yyparse (glcpp_parser_t *parser) |
{ |
/* The lookahead symbol. */ |
int yychar; |
/* The semantic value of the lookahead symbol. */ |
/* Default value used for initialization, for pacifying older GCCs |
or non-GCC compilers. */ |
YY_INITIAL_VALUE (static YYSTYPE yyval_default;) |
YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); |
/* Location data for the lookahead symbol. */ |
static YYLTYPE yyloc_default |
# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL |
= { 1, 1, 1, 1 } |
# endif |
; |
YYLTYPE yylloc = yyloc_default; |
/* Number of syntax errors so far. */ |
int yynerrs; |
int yystate; |
/* Number of tokens to shift before error messages enabled. */ |
int yyerrstatus; |
/* The stacks and their tools: |
'yyss': related to states. |
'yyvs': related to semantic values. |
'yyls': related to locations. |
Refer to the stacks through separate pointers, to allow yyoverflow |
to reallocate them elsewhere. */ |
/* The state stack. */ |
yytype_int16 yyssa[YYINITDEPTH]; |
yytype_int16 *yyss; |
yytype_int16 *yyssp; |
/* The semantic value stack. */ |
YYSTYPE yyvsa[YYINITDEPTH]; |
YYSTYPE *yyvs; |
YYSTYPE *yyvsp; |
/* The location stack. */ |
YYLTYPE yylsa[YYINITDEPTH]; |
YYLTYPE *yyls; |
YYLTYPE *yylsp; |
/* The locations where the error started and ended. */ |
YYLTYPE yyerror_range[3]; |
YYSIZE_T yystacksize; |
int yyn; |
int yyresult; |
/* Lookahead token as an internal (translated) token number. */ |
int yytoken = 0; |
/* The variables used to return semantic value and location from the |
action routines. */ |
YYSTYPE yyval; |
YYLTYPE yyloc; |
#if YYERROR_VERBOSE |
/* Buffer for error messages, and its allocated size. */ |
char yymsgbuf[128]; |
char *yymsg = yymsgbuf; |
YYSIZE_T yymsg_alloc = sizeof yymsgbuf; |
#endif |
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) |
/* The number of symbols on the RHS of the reduced rule. |
Keep to zero when no symbol should be popped. */ |
int yylen = 0; |
yyssp = yyss = yyssa; |
yyvsp = yyvs = yyvsa; |
yylsp = yyls = yylsa; |
yystacksize = YYINITDEPTH; |
YYDPRINTF ((stderr, "Starting parse\n")); |
yystate = 0; |
yyerrstatus = 0; |
yynerrs = 0; |
yychar = YYEMPTY; /* Cause a token to be read. */ |
/* User initialization code. */ |
#line 165 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1429 */ |
{ |
yylloc.first_line = 1; |
yylloc.first_column = 1; |
yylloc.last_line = 1; |
yylloc.last_column = 1; |
yylloc.source = 0; |
} |
#line 1568 "glcpp/glcpp-parse.c" /* yacc.c:1429 */ |
yylsp[0] = yylloc; |
goto yysetstate; |
/*------------------------------------------------------------. |
| yynewstate -- Push a new state, which is found in yystate. | |
`------------------------------------------------------------*/ |
yynewstate: |
/* In all cases, when you get here, the value and location stacks |
have just been pushed. So pushing a state here evens the stacks. */ |
yyssp++; |
yysetstate: |
*yyssp = yystate; |
if (yyss + yystacksize - 1 <= yyssp) |
{ |
/* Get the current used size of the three stacks, in elements. */ |
YYSIZE_T yysize = yyssp - yyss + 1; |
#ifdef yyoverflow |
{ |
/* Give user a chance to reallocate the stack. Use copies of |
these so that the &'s don't force the real ones into |
memory. */ |
YYSTYPE *yyvs1 = yyvs; |
yytype_int16 *yyss1 = yyss; |
YYLTYPE *yyls1 = yyls; |
/* Each stack pointer address is followed by the size of the |
data in use in that stack, in bytes. This used to be a |
conditional around just the two extra args, but that might |
be undefined if yyoverflow is a macro. */ |
yyoverflow (YY_("memory exhausted"), |
&yyss1, yysize * sizeof (*yyssp), |
&yyvs1, yysize * sizeof (*yyvsp), |
&yyls1, yysize * sizeof (*yylsp), |
&yystacksize); |
yyls = yyls1; |
yyss = yyss1; |
yyvs = yyvs1; |
} |
#else /* no yyoverflow */ |
# ifndef YYSTACK_RELOCATE |
goto yyexhaustedlab; |
# else |
/* Extend the stack our own way. */ |
if (YYMAXDEPTH <= yystacksize) |
goto yyexhaustedlab; |
yystacksize *= 2; |
if (YYMAXDEPTH < yystacksize) |
yystacksize = YYMAXDEPTH; |
{ |
yytype_int16 *yyss1 = yyss; |
union yyalloc *yyptr = |
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); |
if (! yyptr) |
goto yyexhaustedlab; |
YYSTACK_RELOCATE (yyss_alloc, yyss); |
YYSTACK_RELOCATE (yyvs_alloc, yyvs); |
YYSTACK_RELOCATE (yyls_alloc, yyls); |
# undef YYSTACK_RELOCATE |
if (yyss1 != yyssa) |
YYSTACK_FREE (yyss1); |
} |
# endif |
#endif /* no yyoverflow */ |
yyssp = yyss + yysize - 1; |
yyvsp = yyvs + yysize - 1; |
yylsp = yyls + yysize - 1; |
YYDPRINTF ((stderr, "Stack size increased to %lu\n", |
(unsigned long int) yystacksize)); |
if (yyss + yystacksize - 1 <= yyssp) |
YYABORT; |
} |
YYDPRINTF ((stderr, "Entering state %d\n", yystate)); |
if (yystate == YYFINAL) |
YYACCEPT; |
goto yybackup; |
/*-----------. |
| yybackup. | |
`-----------*/ |
yybackup: |
/* Do appropriate processing given the current state. Read a |
lookahead token if we need one and don't already have one. */ |
/* First try to decide what to do without reference to lookahead token. */ |
yyn = yypact[yystate]; |
if (yypact_value_is_default (yyn)) |
goto yydefault; |
/* Not known => get a lookahead token if don't already have one. */ |
/* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ |
if (yychar == YYEMPTY) |
{ |
YYDPRINTF ((stderr, "Reading a token: ")); |
yychar = yylex (&yylval, &yylloc, parser); |
} |
if (yychar <= YYEOF) |
{ |
yychar = yytoken = YYEOF; |
YYDPRINTF ((stderr, "Now at end of input.\n")); |
} |
else |
{ |
yytoken = YYTRANSLATE (yychar); |
YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); |
} |
/* If the proper action on seeing token YYTOKEN is to reduce or to |
detect an error, take that action. */ |
yyn += yytoken; |
if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) |
goto yydefault; |
yyn = yytable[yyn]; |
if (yyn <= 0) |
{ |
if (yytable_value_is_error (yyn)) |
goto yyerrlab; |
yyn = -yyn; |
goto yyreduce; |
} |
/* Count tokens shifted since error; after three, turn off error |
status. */ |
if (yyerrstatus) |
yyerrstatus--; |
/* Shift the lookahead token. */ |
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); |
/* Discard the shifted token. */ |
yychar = YYEMPTY; |
yystate = yyn; |
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN |
*++yyvsp = yylval; |
YY_IGNORE_MAYBE_UNINITIALIZED_END |
*++yylsp = yylloc; |
goto yynewstate; |
/*-----------------------------------------------------------. |
| yydefault -- do the default action for the current state. | |
`-----------------------------------------------------------*/ |
yydefault: |
yyn = yydefact[yystate]; |
if (yyn == 0) |
goto yyerrlab; |
goto yyreduce; |
/*-----------------------------. |
| yyreduce -- Do a reduction. | |
`-----------------------------*/ |
yyreduce: |
/* yyn is the number of a rule to reduce with. */ |
yylen = yyr2[yyn]; |
/* If YYLEN is nonzero, implement the default value of the action: |
'$$ = $1'. |
Otherwise, the following line sets YYVAL to garbage. |
This behavior is undocumented and Bison |
users should not rely upon it. Assigning to YYVAL |
unconditionally makes the parser a bit smaller, and it avoids a |
GCC warning that YYVAL may be used uninitialized. */ |
yyval = yyvsp[1-yylen]; |
/* Default location. */ |
YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); |
YY_REDUCE_PRINT (yyn); |
switch (yyn) |
{ |
case 6: |
#line 213 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
_glcpp_parser_print_expanded_token_list (parser, (yyvsp[0].token_list)); |
ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n"); |
ralloc_free ((yyvsp[0].token_list)); |
} |
#line 1761 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 8: |
#line 222 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
if (parser->is_gles && (yyvsp[-1].expression_value).undefined_macro) |
glcpp_error(& (yylsp[-2]), parser, "undefined macro %s in expression (illegal in GLES)", (yyvsp[-1].expression_value).undefined_macro); |
_glcpp_parser_skip_stack_push_if (parser, & (yylsp[-2]), (yyvsp[-1].expression_value).value); |
} |
#line 1771 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 9: |
#line 227 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
if (parser->is_gles && (yyvsp[-1].expression_value).undefined_macro) |
glcpp_error(& (yylsp[-2]), parser, "undefined macro %s in expression (illegal in GLES)", (yyvsp[-1].expression_value).undefined_macro); |
_glcpp_parser_skip_stack_change_if (parser, & (yylsp[-2]), "elif", (yyvsp[-1].expression_value).value); |
} |
#line 1781 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 10: |
#line 232 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
parser->has_new_line_number = 1; |
parser->new_line_number = (yyvsp[-1].ival); |
ralloc_asprintf_rewrite_tail (&parser->output, |
&parser->output_length, |
"#line %" PRIiMAX "\n", |
(yyvsp[-1].ival)); |
} |
#line 1794 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 11: |
#line 240 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
parser->has_new_line_number = 1; |
parser->new_line_number = (yyvsp[-2].ival); |
parser->has_new_source_number = 1; |
parser->new_source_number = (yyvsp[-1].ival); |
ralloc_asprintf_rewrite_tail (&parser->output, |
&parser->output_length, |
"#line %" PRIiMAX " %" PRIiMAX "\n", |
(yyvsp[-2].ival), (yyvsp[-1].ival)); |
} |
#line 1809 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 12: |
#line 253 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
_define_object_macro (parser, & (yylsp[-2]), (yyvsp[-2].str), (yyvsp[-1].token_list)); |
} |
#line 1817 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 13: |
#line 256 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
_define_function_macro (parser, & (yylsp[-4]), (yyvsp[-4].str), NULL, (yyvsp[-1].token_list)); |
} |
#line 1825 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 14: |
#line 259 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
_define_function_macro (parser, & (yylsp[-5]), (yyvsp[-5].str), (yyvsp[-3].string_list), (yyvsp[-1].token_list)); |
} |
#line 1833 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 15: |
#line 265 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n"); |
} |
#line 1841 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 17: |
#line 269 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
glcpp_parser_resolve_implicit_version(parser); |
} |
#line 1849 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 18: |
#line 271 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
if (parser->skip_stack == NULL || |
parser->skip_stack->type == SKIP_NO_SKIP) |
{ |
_glcpp_parser_expand_and_lex_from (parser, |
LINE_EXPANDED, (yyvsp[-1].token_list), |
EXPANSION_MODE_IGNORE_DEFINED); |
} |
} |
#line 1864 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 19: |
#line 284 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
glcpp_parser_resolve_implicit_version(parser); |
} |
#line 1872 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 21: |
#line 287 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
glcpp_parser_resolve_implicit_version(parser); |
} |
#line 1880 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 22: |
#line 289 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
macro_t *macro; |
if (strcmp("__LINE__", (yyvsp[-1].str)) == 0 |
|| strcmp("__FILE__", (yyvsp[-1].str)) == 0 |
|| strcmp("__VERSION__", (yyvsp[-1].str)) == 0 |
|| strncmp("GL_", (yyvsp[-1].str), 3) == 0) |
glcpp_error(& (yylsp[-4]), parser, "Built-in (pre-defined)" |
" macro names cannot be undefined."); |
macro = hash_table_find (parser->defines, (yyvsp[-1].str)); |
if (macro) { |
hash_table_remove (parser->defines, (yyvsp[-1].str)); |
ralloc_free (macro); |
} |
ralloc_free ((yyvsp[-1].str)); |
} |
#line 1901 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 23: |
#line 305 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
glcpp_parser_resolve_implicit_version(parser); |
} |
#line 1909 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 24: |
#line 307 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
/* Be careful to only evaluate the 'if' expression if |
* we are not skipping. When we are skipping, we |
* simply push a new 0-valued 'if' onto the skip |
* stack. |
* |
* This avoids generating diagnostics for invalid |
* expressions that are being skipped. */ |
if (parser->skip_stack == NULL || |
parser->skip_stack->type == SKIP_NO_SKIP) |
{ |
_glcpp_parser_expand_and_lex_from (parser, |
IF_EXPANDED, (yyvsp[-1].token_list), |
EXPANSION_MODE_EVALUATE_DEFINED); |
} |
else |
{ |
_glcpp_parser_skip_stack_push_if (parser, & (yylsp[-4]), 0); |
parser->skip_stack->type = SKIP_TO_ENDIF; |
} |
} |
#line 1935 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 25: |
#line 328 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
/* #if without an expression is only an error if we |
* are not skipping */ |
if (parser->skip_stack == NULL || |
parser->skip_stack->type == SKIP_NO_SKIP) |
{ |
glcpp_error(& (yylsp[-2]), parser, "#if with no expression"); |
} |
_glcpp_parser_skip_stack_push_if (parser, & (yylsp[-2]), 0); |
} |
#line 1950 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 26: |
#line 338 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
glcpp_parser_resolve_implicit_version(parser); |
} |
#line 1958 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 27: |
#line 340 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
macro_t *macro = hash_table_find (parser->defines, (yyvsp[-2].str)); |
ralloc_free ((yyvsp[-2].str)); |
_glcpp_parser_skip_stack_push_if (parser, & (yylsp[-5]), macro != NULL); |
} |
#line 1968 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 28: |
#line 345 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
glcpp_parser_resolve_implicit_version(parser); |
} |
#line 1976 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 29: |
#line 347 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
macro_t *macro = hash_table_find (parser->defines, (yyvsp[-2].str)); |
ralloc_free ((yyvsp[-2].str)); |
_glcpp_parser_skip_stack_push_if (parser, & (yylsp[-3]), macro == NULL); |
} |
#line 1986 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 30: |
#line 352 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
/* Be careful to only evaluate the 'elif' expression |
* if we are not skipping. When we are skipping, we |
* simply change to a 0-valued 'elif' on the skip |
* stack. |
* |
* This avoids generating diagnostics for invalid |
* expressions that are being skipped. */ |
if (parser->skip_stack && |
parser->skip_stack->type == SKIP_TO_ELSE) |
{ |
_glcpp_parser_expand_and_lex_from (parser, |
ELIF_EXPANDED, (yyvsp[-1].token_list), |
EXPANSION_MODE_EVALUATE_DEFINED); |
} |
else if (parser->skip_stack && |
parser->skip_stack->has_else) |
{ |
glcpp_error(& (yylsp[-3]), parser, "#elif after #else"); |
} |
else |
{ |
_glcpp_parser_skip_stack_change_if (parser, & (yylsp[-3]), |
"elif", 0); |
} |
} |
#line 2017 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 31: |
#line 378 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
/* #elif without an expression is an error unless we |
* are skipping. */ |
if (parser->skip_stack && |
parser->skip_stack->type == SKIP_TO_ELSE) |
{ |
glcpp_error(& (yylsp[-2]), parser, "#elif with no expression"); |
} |
else if (parser->skip_stack && |
parser->skip_stack->has_else) |
{ |
glcpp_error(& (yylsp[-2]), parser, "#elif after #else"); |
} |
else |
{ |
_glcpp_parser_skip_stack_change_if (parser, & (yylsp[-2]), |
"elif", 0); |
glcpp_warning(& (yylsp[-2]), parser, "ignoring illegal #elif without expression"); |
} |
} |
#line 2042 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 32: |
#line 398 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ parser->lexing_directive = 1; } |
#line 2048 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 33: |
#line 398 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
if (parser->skip_stack && |
parser->skip_stack->has_else) |
{ |
glcpp_error(& (yylsp[-3]), parser, "multiple #else"); |
} |
else |
{ |
_glcpp_parser_skip_stack_change_if (parser, & (yylsp[-3]), "else", 1); |
if (parser->skip_stack) |
parser->skip_stack->has_else = true; |
} |
} |
#line 2066 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 34: |
#line 411 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
_glcpp_parser_skip_stack_pop (parser, & (yylsp[-1])); |
} |
#line 2074 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 36: |
#line 414 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
if (parser->version_resolved) { |
glcpp_error(& (yylsp[-3]), parser, "#version must appear on the first line"); |
} |
_glcpp_parser_handle_version_declaration(parser, (yyvsp[-1].ival), NULL, true); |
} |
#line 2085 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 37: |
#line 420 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
if (parser->version_resolved) { |
glcpp_error(& (yylsp[-4]), parser, "#version must appear on the first line"); |
} |
_glcpp_parser_handle_version_declaration(parser, (yyvsp[-2].ival), (yyvsp[-1].str), true); |
} |
#line 2096 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 38: |
#line 426 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
glcpp_parser_resolve_implicit_version(parser); |
} |
#line 2104 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 39: |
#line 429 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "#%s", (yyvsp[-1].str)); |
} |
#line 2112 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 40: |
#line 435 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
glcpp_error(& (yylsp[-2]), parser, "#%s", (yyvsp[-1].str)); |
} |
#line 2120 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 41: |
#line 438 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
glcpp_error (& (yylsp[-2]), parser, "#define without macro name"); |
} |
#line 2128 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 42: |
#line 441 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
glcpp_error (& (yylsp[-3]), parser, "Illegal non-directive after #"); |
} |
#line 2136 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 43: |
#line 447 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
if (strlen ((yyvsp[0].str)) >= 3 && strncmp ((yyvsp[0].str), "0x", 2) == 0) { |
(yyval.ival) = strtoll ((yyvsp[0].str) + 2, NULL, 16); |
} else if ((yyvsp[0].str)[0] == '0') { |
(yyval.ival) = strtoll ((yyvsp[0].str), NULL, 8); |
} else { |
(yyval.ival) = strtoll ((yyvsp[0].str), NULL, 10); |
} |
} |
#line 2150 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 44: |
#line 456 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.ival) = (yyvsp[0].ival); |
} |
#line 2158 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 45: |
#line 461 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = (yyvsp[0].ival); |
(yyval.expression_value).undefined_macro = NULL; |
} |
#line 2167 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 46: |
#line 465 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = 0; |
if (parser->is_gles) |
(yyval.expression_value).undefined_macro = ralloc_strdup (parser, (yyvsp[0].str)); |
else |
(yyval.expression_value).undefined_macro = NULL; |
} |
#line 2179 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 47: |
#line 472 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value || (yyvsp[0].expression_value).value; |
/* Short-circuit: Only flag undefined from right side |
* if left side evaluates to false. |
*/ |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else if (! (yyvsp[-2].expression_value).value) |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2195 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 48: |
#line 483 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value && (yyvsp[0].expression_value).value; |
/* Short-circuit: Only flag undefined from right-side |
* if left side evaluates to true. |
*/ |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else if ((yyvsp[-2].expression_value).value) |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2211 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 49: |
#line 494 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value | (yyvsp[0].expression_value).value; |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2223 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 50: |
#line 501 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value ^ (yyvsp[0].expression_value).value; |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2235 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 51: |
#line 508 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value & (yyvsp[0].expression_value).value; |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2247 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 52: |
#line 515 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value != (yyvsp[0].expression_value).value; |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2259 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 53: |
#line 522 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value == (yyvsp[0].expression_value).value; |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2271 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 54: |
#line 529 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value >= (yyvsp[0].expression_value).value; |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2283 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 55: |
#line 536 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value <= (yyvsp[0].expression_value).value; |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2295 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 56: |
#line 543 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value > (yyvsp[0].expression_value).value; |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2307 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 57: |
#line 550 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value < (yyvsp[0].expression_value).value; |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2319 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 58: |
#line 557 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value >> (yyvsp[0].expression_value).value; |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2331 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 59: |
#line 564 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value << (yyvsp[0].expression_value).value; |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2343 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 60: |
#line 571 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value - (yyvsp[0].expression_value).value; |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2355 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 61: |
#line 578 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value + (yyvsp[0].expression_value).value; |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2367 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 62: |
#line 585 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
if ((yyvsp[0].expression_value).value == 0) { |
yyerror (& (yylsp[-2]), parser, |
"zero modulus in preprocessor directive"); |
} else { |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value % (yyvsp[0].expression_value).value; |
} |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2384 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 63: |
#line 597 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
if ((yyvsp[0].expression_value).value == 0) { |
yyerror (& (yylsp[-2]), parser, |
"division by 0 in preprocessor directive"); |
} else { |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value / (yyvsp[0].expression_value).value; |
} |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2401 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 64: |
#line 609 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = (yyvsp[-2].expression_value).value * (yyvsp[0].expression_value).value; |
if ((yyvsp[-2].expression_value).undefined_macro) |
(yyval.expression_value).undefined_macro = (yyvsp[-2].expression_value).undefined_macro; |
else |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2413 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 65: |
#line 616 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = ! (yyvsp[0].expression_value).value; |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2422 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 66: |
#line 620 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = ~ (yyvsp[0].expression_value).value; |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2431 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 67: |
#line 624 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = - (yyvsp[0].expression_value).value; |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2440 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 68: |
#line 628 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value).value = + (yyvsp[0].expression_value).value; |
(yyval.expression_value).undefined_macro = (yyvsp[0].expression_value).undefined_macro; |
} |
#line 2449 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 69: |
#line 632 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.expression_value) = (yyvsp[-1].expression_value); |
} |
#line 2457 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 70: |
#line 638 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.string_list) = _string_list_create (parser); |
_string_list_append_item ((yyval.string_list), (yyvsp[0].str)); |
ralloc_steal ((yyval.string_list), (yyvsp[0].str)); |
} |
#line 2467 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 71: |
#line 643 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.string_list) = (yyvsp[-2].string_list); |
_string_list_append_item ((yyval.string_list), (yyvsp[0].str)); |
ralloc_steal ((yyval.string_list), (yyvsp[0].str)); |
} |
#line 2477 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 72: |
#line 651 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.token_list) = NULL; } |
#line 2483 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 74: |
#line 656 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.token_list) = NULL; } |
#line 2489 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 77: |
#line 662 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
glcpp_error(&(yylsp[0]), parser, "extra tokens at end of directive"); |
} |
#line 2497 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 78: |
#line 668 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
parser->space_tokens = 1; |
(yyval.token_list) = _token_list_create (parser); |
_token_list_append ((yyval.token_list), (yyvsp[0].token)); |
} |
#line 2507 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 79: |
#line 673 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.token_list) = (yyvsp[-1].token_list); |
_token_list_append ((yyval.token_list), (yyvsp[0].token)); |
} |
#line 2516 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 80: |
#line 680 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.token) = _token_create_str (parser, IDENTIFIER, (yyvsp[0].str)); |
(yyval.token)->location = yylloc; |
} |
#line 2525 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 81: |
#line 684 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.token) = _token_create_str (parser, INTEGER_STRING, (yyvsp[0].str)); |
(yyval.token)->location = yylloc; |
} |
#line 2534 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 82: |
#line 688 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.token) = _token_create_ival (parser, (yyvsp[0].ival), (yyvsp[0].ival)); |
(yyval.token)->location = yylloc; |
} |
#line 2543 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 83: |
#line 692 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.token) = _token_create_ival (parser, DEFINED, DEFINED); |
(yyval.token)->location = yylloc; |
} |
#line 2552 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 84: |
#line 696 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.token) = _token_create_str (parser, OTHER, (yyvsp[0].str)); |
(yyval.token)->location = yylloc; |
} |
#line 2561 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 85: |
#line 700 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ |
(yyval.token) = _token_create_ival (parser, SPACE, SPACE); |
(yyval.token)->location = yylloc; |
} |
#line 2570 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 86: |
#line 707 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '['; } |
#line 2576 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 87: |
#line 708 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = ']'; } |
#line 2582 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 88: |
#line 709 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '('; } |
#line 2588 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 89: |
#line 710 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = ')'; } |
#line 2594 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 90: |
#line 711 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '{'; } |
#line 2600 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 91: |
#line 712 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '}'; } |
#line 2606 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 92: |
#line 713 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '.'; } |
#line 2612 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 93: |
#line 714 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '&'; } |
#line 2618 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 94: |
#line 715 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '*'; } |
#line 2624 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 95: |
#line 716 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '+'; } |
#line 2630 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 96: |
#line 717 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '-'; } |
#line 2636 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 97: |
#line 718 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '~'; } |
#line 2642 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 98: |
#line 719 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '!'; } |
#line 2648 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 99: |
#line 720 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '/'; } |
#line 2654 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 100: |
#line 721 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '%'; } |
#line 2660 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 101: |
#line 722 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = LEFT_SHIFT; } |
#line 2666 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 102: |
#line 723 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = RIGHT_SHIFT; } |
#line 2672 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 103: |
#line 724 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '<'; } |
#line 2678 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 104: |
#line 725 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '>'; } |
#line 2684 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 105: |
#line 726 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = LESS_OR_EQUAL; } |
#line 2690 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 106: |
#line 727 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = GREATER_OR_EQUAL; } |
#line 2696 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 107: |
#line 728 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = EQUAL; } |
#line 2702 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 108: |
#line 729 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = NOT_EQUAL; } |
#line 2708 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 109: |
#line 730 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '^'; } |
#line 2714 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 110: |
#line 731 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '|'; } |
#line 2720 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 111: |
#line 732 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = AND; } |
#line 2726 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 112: |
#line 733 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = OR; } |
#line 2732 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 113: |
#line 734 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = ';'; } |
#line 2738 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 114: |
#line 735 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = ','; } |
#line 2744 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 115: |
#line 736 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = '='; } |
#line 2750 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 116: |
#line 737 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = PASTE; } |
#line 2756 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 117: |
#line 738 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = PLUS_PLUS; } |
#line 2762 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
case 118: |
#line 739 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1646 */ |
{ (yyval.ival) = MINUS_MINUS; } |
#line 2768 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
break; |
#line 2772 "glcpp/glcpp-parse.c" /* yacc.c:1646 */ |
default: break; |
} |
/* User semantic actions sometimes alter yychar, and that requires |
that yytoken be updated with the new translation. We take the |
approach of translating immediately before every use of yytoken. |
One alternative is translating here after every semantic action, |
but that translation would be missed if the semantic action invokes |
YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or |
if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an |
incorrect destructor might then be invoked immediately. In the |
case of YYERROR or YYBACKUP, subsequent parser actions might lead |
to an incorrect destructor call or verbose syntax error message |
before the lookahead is translated. */ |
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); |
YYPOPSTACK (yylen); |
yylen = 0; |
YY_STACK_PRINT (yyss, yyssp); |
*++yyvsp = yyval; |
*++yylsp = yyloc; |
/* Now 'shift' the result of the reduction. Determine what state |
that goes to, based on the state we popped back to and the rule |
number reduced by. */ |
yyn = yyr1[yyn]; |
yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; |
if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) |
yystate = yytable[yystate]; |
else |
yystate = yydefgoto[yyn - YYNTOKENS]; |
goto yynewstate; |
/*--------------------------------------. |
| yyerrlab -- here on detecting error. | |
`--------------------------------------*/ |
yyerrlab: |
/* Make sure we have latest lookahead translation. See comments at |
user semantic actions for why this is necessary. */ |
yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); |
/* If not already recovering from an error, report this error. */ |
if (!yyerrstatus) |
{ |
++yynerrs; |
#if ! YYERROR_VERBOSE |
yyerror (&yylloc, parser, YY_("syntax error")); |
#else |
# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ |
yyssp, yytoken) |
{ |
char const *yymsgp = YY_("syntax error"); |
int yysyntax_error_status; |
yysyntax_error_status = YYSYNTAX_ERROR; |
if (yysyntax_error_status == 0) |
yymsgp = yymsg; |
else if (yysyntax_error_status == 1) |
{ |
if (yymsg != yymsgbuf) |
YYSTACK_FREE (yymsg); |
yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); |
if (!yymsg) |
{ |
yymsg = yymsgbuf; |
yymsg_alloc = sizeof yymsgbuf; |
yysyntax_error_status = 2; |
} |
else |
{ |
yysyntax_error_status = YYSYNTAX_ERROR; |
yymsgp = yymsg; |
} |
} |
yyerror (&yylloc, parser, yymsgp); |
if (yysyntax_error_status == 2) |
goto yyexhaustedlab; |
} |
# undef YYSYNTAX_ERROR |
#endif |
} |
yyerror_range[1] = yylloc; |
if (yyerrstatus == 3) |
{ |
/* If just tried and failed to reuse lookahead token after an |
error, discard it. */ |
if (yychar <= YYEOF) |
{ |
/* Return failure if at end of input. */ |
if (yychar == YYEOF) |
YYABORT; |
} |
else |
{ |
yydestruct ("Error: discarding", |
yytoken, &yylval, &yylloc, parser); |
yychar = YYEMPTY; |
} |
} |
/* Else will try to reuse lookahead token after shifting the error |
token. */ |
goto yyerrlab1; |
/*---------------------------------------------------. |
| yyerrorlab -- error raised explicitly by YYERROR. | |
`---------------------------------------------------*/ |
yyerrorlab: |
/* Pacify compilers like GCC when the user code never invokes |
YYERROR and the label yyerrorlab therefore never appears in user |
code. */ |
if (/*CONSTCOND*/ 0) |
goto yyerrorlab; |
yyerror_range[1] = yylsp[1-yylen]; |
/* Do not reclaim the symbols of the rule whose action triggered |
this YYERROR. */ |
YYPOPSTACK (yylen); |
yylen = 0; |
YY_STACK_PRINT (yyss, yyssp); |
yystate = *yyssp; |
goto yyerrlab1; |
/*-------------------------------------------------------------. |
| yyerrlab1 -- common code for both syntax error and YYERROR. | |
`-------------------------------------------------------------*/ |
yyerrlab1: |
yyerrstatus = 3; /* Each real token shifted decrements this. */ |
for (;;) |
{ |
yyn = yypact[yystate]; |
if (!yypact_value_is_default (yyn)) |
{ |
yyn += YYTERROR; |
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) |
{ |
yyn = yytable[yyn]; |
if (0 < yyn) |
break; |
} |
} |
/* Pop the current state because it cannot handle the error token. */ |
if (yyssp == yyss) |
YYABORT; |
yyerror_range[1] = *yylsp; |
yydestruct ("Error: popping", |
yystos[yystate], yyvsp, yylsp, parser); |
YYPOPSTACK (1); |
yystate = *yyssp; |
YY_STACK_PRINT (yyss, yyssp); |
} |
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN |
*++yyvsp = yylval; |
YY_IGNORE_MAYBE_UNINITIALIZED_END |
yyerror_range[2] = yylloc; |
/* Using YYLLOC is tempting, but would change the location of |
the lookahead. YYLOC is available though. */ |
YYLLOC_DEFAULT (yyloc, yyerror_range, 2); |
*++yylsp = yyloc; |
/* Shift the error token. */ |
YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); |
yystate = yyn; |
goto yynewstate; |
/*-------------------------------------. |
| yyacceptlab -- YYACCEPT comes here. | |
`-------------------------------------*/ |
yyacceptlab: |
yyresult = 0; |
goto yyreturn; |
/*-----------------------------------. |
| yyabortlab -- YYABORT comes here. | |
`-----------------------------------*/ |
yyabortlab: |
yyresult = 1; |
goto yyreturn; |
#if !defined yyoverflow || YYERROR_VERBOSE |
/*-------------------------------------------------. |
| yyexhaustedlab -- memory exhaustion comes here. | |
`-------------------------------------------------*/ |
yyexhaustedlab: |
yyerror (&yylloc, parser, YY_("memory exhausted")); |
yyresult = 2; |
/* Fall through. */ |
#endif |
yyreturn: |
if (yychar != YYEMPTY) |
{ |
/* Make sure we have latest lookahead translation. See comments at |
user semantic actions for why this is necessary. */ |
yytoken = YYTRANSLATE (yychar); |
yydestruct ("Cleanup: discarding lookahead", |
yytoken, &yylval, &yylloc, parser); |
} |
/* Do not reclaim the symbols of the rule whose action triggered |
this YYABORT or YYACCEPT. */ |
YYPOPSTACK (yylen); |
YY_STACK_PRINT (yyss, yyssp); |
while (yyssp != yyss) |
{ |
yydestruct ("Cleanup: popping", |
yystos[*yyssp], yyvsp, yylsp, parser); |
YYPOPSTACK (1); |
} |
#ifndef yyoverflow |
if (yyss != yyssa) |
YYSTACK_FREE (yyss); |
#endif |
#if YYERROR_VERBOSE |
if (yymsg != yymsgbuf) |
YYSTACK_FREE (yymsg); |
#endif |
return yyresult; |
} |
#line 742 "../../../src/glsl/glcpp/glcpp-parse.y" /* yacc.c:1906 */ |
string_list_t * |
_string_list_create (void *ctx) |
{ |
string_list_t *list; |
list = ralloc (ctx, string_list_t); |
list->head = NULL; |
list->tail = NULL; |
return list; |
} |
void |
_string_list_append_item (string_list_t *list, const char *str) |
{ |
string_node_t *node; |
node = ralloc (list, string_node_t); |
node->str = ralloc_strdup (node, str); |
node->next = NULL; |
if (list->head == NULL) { |
list->head = node; |
} else { |
list->tail->next = node; |
} |
list->tail = node; |
} |
int |
_string_list_contains (string_list_t *list, const char *member, int *index) |
{ |
string_node_t *node; |
int i; |
if (list == NULL) |
return 0; |
for (i = 0, node = list->head; node; i++, node = node->next) { |
if (strcmp (node->str, member) == 0) { |
if (index) |
*index = i; |
return 1; |
} |
} |
return 0; |
} |
/* Return duplicate string in list (if any), NULL otherwise. */ |
const char * |
_string_list_has_duplicate (string_list_t *list) |
{ |
string_node_t *node, *dup; |
if (list == NULL) |
return NULL; |
for (node = list->head; node; node = node->next) { |
for (dup = node->next; dup; dup = dup->next) { |
if (strcmp (node->str, dup->str) == 0) |
return node->str; |
} |
} |
return NULL; |
} |
int |
_string_list_length (string_list_t *list) |
{ |
int length = 0; |
string_node_t *node; |
if (list == NULL) |
return 0; |
for (node = list->head; node; node = node->next) |
length++; |
return length; |
} |
int |
_string_list_equal (string_list_t *a, string_list_t *b) |
{ |
string_node_t *node_a, *node_b; |
if (a == NULL && b == NULL) |
return 1; |
if (a == NULL || b == NULL) |
return 0; |
for (node_a = a->head, node_b = b->head; |
node_a && node_b; |
node_a = node_a->next, node_b = node_b->next) |
{ |
if (strcmp (node_a->str, node_b->str)) |
return 0; |
} |
/* Catch the case of lists being different lengths, (which |
* would cause the loop above to terminate after the shorter |
* list). */ |
return node_a == node_b; |
} |
argument_list_t * |
_argument_list_create (void *ctx) |
{ |
argument_list_t *list; |
list = ralloc (ctx, argument_list_t); |
list->head = NULL; |
list->tail = NULL; |
return list; |
} |
void |
_argument_list_append (argument_list_t *list, token_list_t *argument) |
{ |
argument_node_t *node; |
node = ralloc (list, argument_node_t); |
node->argument = argument; |
node->next = NULL; |
if (list->head == NULL) { |
list->head = node; |
} else { |
list->tail->next = node; |
} |
list->tail = node; |
} |
int |
_argument_list_length (argument_list_t *list) |
{ |
int length = 0; |
argument_node_t *node; |
if (list == NULL) |
return 0; |
for (node = list->head; node; node = node->next) |
length++; |
return length; |
} |
token_list_t * |
_argument_list_member_at (argument_list_t *list, int index) |
{ |
argument_node_t *node; |
int i; |
if (list == NULL) |
return NULL; |
node = list->head; |
for (i = 0; i < index; i++) { |
node = node->next; |
if (node == NULL) |
break; |
} |
if (node) |
return node->argument; |
return NULL; |
} |
/* Note: This function ralloc_steal()s the str pointer. */ |
token_t * |
_token_create_str (void *ctx, int type, char *str) |
{ |
token_t *token; |
token = ralloc (ctx, token_t); |
token->type = type; |
token->value.str = str; |
ralloc_steal (token, str); |
return token; |
} |
token_t * |
_token_create_ival (void *ctx, int type, int ival) |
{ |
token_t *token; |
token = ralloc (ctx, token_t); |
token->type = type; |
token->value.ival = ival; |
return token; |
} |
token_list_t * |
_token_list_create (void *ctx) |
{ |
token_list_t *list; |
list = ralloc (ctx, token_list_t); |
list->head = NULL; |
list->tail = NULL; |
list->non_space_tail = NULL; |
return list; |
} |
void |
_token_list_append (token_list_t *list, token_t *token) |
{ |
token_node_t *node; |
node = ralloc (list, token_node_t); |
node->token = token; |
node->next = NULL; |
if (list->head == NULL) { |
list->head = node; |
} else { |
list->tail->next = node; |
} |
list->tail = node; |
if (token->type != SPACE) |
list->non_space_tail = node; |
} |
void |
_token_list_append_list (token_list_t *list, token_list_t *tail) |
{ |
if (tail == NULL || tail->head == NULL) |
return; |
if (list->head == NULL) { |
list->head = tail->head; |
} else { |
list->tail->next = tail->head; |
} |
list->tail = tail->tail; |
list->non_space_tail = tail->non_space_tail; |
} |
static token_list_t * |
_token_list_copy (void *ctx, token_list_t *other) |
{ |
token_list_t *copy; |
token_node_t *node; |
if (other == NULL) |
return NULL; |
copy = _token_list_create (ctx); |
for (node = other->head; node; node = node->next) { |
token_t *new_token = ralloc (copy, token_t); |
*new_token = *node->token; |
_token_list_append (copy, new_token); |
} |
return copy; |
} |
static void |
_token_list_trim_trailing_space (token_list_t *list) |
{ |
token_node_t *tail, *next; |
if (list->non_space_tail) { |
tail = list->non_space_tail->next; |
list->non_space_tail->next = NULL; |
list->tail = list->non_space_tail; |
while (tail) { |
next = tail->next; |
ralloc_free (tail); |
tail = next; |
} |
} |
} |
static int |
_token_list_is_empty_ignoring_space (token_list_t *l) |
{ |
token_node_t *n; |
if (l == NULL) |
return 1; |
n = l->head; |
while (n != NULL && n->token->type == SPACE) |
n = n->next; |
return n == NULL; |
} |
int |
_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b) |
{ |
token_node_t *node_a, *node_b; |
if (a == NULL || b == NULL) { |
int a_empty = _token_list_is_empty_ignoring_space(a); |
int b_empty = _token_list_is_empty_ignoring_space(b); |
return a_empty == b_empty; |
} |
node_a = a->head; |
node_b = b->head; |
while (1) |
{ |
if (node_a == NULL && node_b == NULL) |
break; |
if (node_a == NULL || node_b == NULL) |
return 0; |
/* Make sure whitespace appears in the same places in both. |
* It need not be exactly the same amount of whitespace, |
* though. |
*/ |
if (node_a->token->type == SPACE |
&& node_b->token->type == SPACE) { |
while (node_a->token->type == SPACE) |
node_a = node_a->next; |
while (node_b->token->type == SPACE) |
node_b = node_b->next; |
continue; |
} |
if (node_a->token->type != node_b->token->type) |
return 0; |
switch (node_a->token->type) { |
case INTEGER: |
if (node_a->token->value.ival != |
node_b->token->value.ival) |
{ |
return 0; |
} |
break; |
case IDENTIFIER: |
case INTEGER_STRING: |
case OTHER: |
if (strcmp (node_a->token->value.str, |
node_b->token->value.str)) |
{ |
return 0; |
} |
break; |
} |
node_a = node_a->next; |
node_b = node_b->next; |
} |
return 1; |
} |
static void |
_token_print (char **out, size_t *len, token_t *token) |
{ |
if (token->type < 256) { |
ralloc_asprintf_rewrite_tail (out, len, "%c", token->type); |
return; |
} |
switch (token->type) { |
case INTEGER: |
ralloc_asprintf_rewrite_tail (out, len, "%" PRIiMAX, token->value.ival); |
break; |
case IDENTIFIER: |
case INTEGER_STRING: |
case OTHER: |
ralloc_asprintf_rewrite_tail (out, len, "%s", token->value.str); |
break; |
case SPACE: |
ralloc_asprintf_rewrite_tail (out, len, " "); |
break; |
case LEFT_SHIFT: |
ralloc_asprintf_rewrite_tail (out, len, "<<"); |
break; |
case RIGHT_SHIFT: |
ralloc_asprintf_rewrite_tail (out, len, ">>"); |
break; |
case LESS_OR_EQUAL: |
ralloc_asprintf_rewrite_tail (out, len, "<="); |
break; |
case GREATER_OR_EQUAL: |
ralloc_asprintf_rewrite_tail (out, len, ">="); |
break; |
case EQUAL: |
ralloc_asprintf_rewrite_tail (out, len, "=="); |
break; |
case NOT_EQUAL: |
ralloc_asprintf_rewrite_tail (out, len, "!="); |
break; |
case AND: |
ralloc_asprintf_rewrite_tail (out, len, "&&"); |
break; |
case OR: |
ralloc_asprintf_rewrite_tail (out, len, "||"); |
break; |
case PASTE: |
ralloc_asprintf_rewrite_tail (out, len, "##"); |
break; |
case PLUS_PLUS: |
ralloc_asprintf_rewrite_tail (out, len, "++"); |
break; |
case MINUS_MINUS: |
ralloc_asprintf_rewrite_tail (out, len, "--"); |
break; |
case DEFINED: |
ralloc_asprintf_rewrite_tail (out, len, "defined"); |
break; |
case PLACEHOLDER: |
/* Nothing to print. */ |
break; |
default: |
assert(!"Error: Don't know how to print token."); |
break; |
} |
} |
/* Return a new token (ralloc()ed off of 'token') formed by pasting |
* 'token' and 'other'. Note that this function may return 'token' or |
* 'other' directly rather than allocating anything new. |
* |
* Caution: Only very cursory error-checking is performed to see if |
* the final result is a valid single token. */ |
static token_t * |
_token_paste (glcpp_parser_t *parser, token_t *token, token_t *other) |
{ |
token_t *combined = NULL; |
/* Pasting a placeholder onto anything makes no change. */ |
if (other->type == PLACEHOLDER) |
return token; |
/* When 'token' is a placeholder, just return 'other'. */ |
if (token->type == PLACEHOLDER) |
return other; |
/* A very few single-character punctuators can be combined |
* with another to form a multi-character punctuator. */ |
switch (token->type) { |
case '<': |
if (other->type == '<') |
combined = _token_create_ival (token, LEFT_SHIFT, LEFT_SHIFT); |
else if (other->type == '=') |
combined = _token_create_ival (token, LESS_OR_EQUAL, LESS_OR_EQUAL); |
break; |
case '>': |
if (other->type == '>') |
combined = _token_create_ival (token, RIGHT_SHIFT, RIGHT_SHIFT); |
else if (other->type == '=') |
combined = _token_create_ival (token, GREATER_OR_EQUAL, GREATER_OR_EQUAL); |
break; |
case '=': |
if (other->type == '=') |
combined = _token_create_ival (token, EQUAL, EQUAL); |
break; |
case '!': |
if (other->type == '=') |
combined = _token_create_ival (token, NOT_EQUAL, NOT_EQUAL); |
break; |
case '&': |
if (other->type == '&') |
combined = _token_create_ival (token, AND, AND); |
break; |
case '|': |
if (other->type == '|') |
combined = _token_create_ival (token, OR, OR); |
break; |
} |
if (combined != NULL) { |
/* Inherit the location from the first token */ |
combined->location = token->location; |
return combined; |
} |
/* Two string-valued (or integer) tokens can usually just be |
* mashed together. (We also handle a string followed by an |
* integer here as well.) |
* |
* There are some exceptions here. Notably, if the first token |
* is an integer (or a string representing an integer), then |
* the second token must also be an integer or must be a |
* string representing an integer that begins with a digit. |
*/ |
if ((token->type == IDENTIFIER || token->type == OTHER || token->type == INTEGER_STRING || token->type == INTEGER) && |
(other->type == IDENTIFIER || other->type == OTHER || other->type == INTEGER_STRING || other->type == INTEGER)) |
{ |
char *str; |
int combined_type; |
/* Check that pasting onto an integer doesn't create a |
* non-integer, (that is, only digits can be |
* pasted. */ |
if (token->type == INTEGER_STRING || token->type == INTEGER) |
{ |
switch (other->type) { |
case INTEGER_STRING: |
if (other->value.str[0] < '0' || |
other->value.str[0] > '9') |
goto FAIL; |
break; |
case INTEGER: |
if (other->value.ival < 0) |
goto FAIL; |
break; |
default: |
goto FAIL; |
} |
} |
if (token->type == INTEGER) |
str = ralloc_asprintf (token, "%" PRIiMAX, |
token->value.ival); |
else |
str = ralloc_strdup (token, token->value.str); |
if (other->type == INTEGER) |
ralloc_asprintf_append (&str, "%" PRIiMAX, |
other->value.ival); |
else |
ralloc_strcat (&str, other->value.str); |
/* New token is same type as original token, unless we |
* started with an integer, in which case we will be |
* creating an integer-string. */ |
combined_type = token->type; |
if (combined_type == INTEGER) |
combined_type = INTEGER_STRING; |
combined = _token_create_str (token, combined_type, str); |
combined->location = token->location; |
return combined; |
} |
FAIL: |
glcpp_error (&token->location, parser, ""); |
ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "Pasting \""); |
_token_print (&parser->info_log, &parser->info_log_length, token); |
ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "\" and \""); |
_token_print (&parser->info_log, &parser->info_log_length, other); |
ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "\" does not give a valid preprocessing token.\n"); |
return token; |
} |
static void |
_token_list_print (glcpp_parser_t *parser, token_list_t *list) |
{ |
token_node_t *node; |
if (list == NULL) |
return; |
for (node = list->head; node; node = node->next) |
_token_print (&parser->output, &parser->output_length, node->token); |
} |
void |
yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error) |
{ |
glcpp_error(locp, parser, "%s", error); |
} |
static void add_builtin_define(glcpp_parser_t *parser, |
const char *name, int value) |
{ |
token_t *tok; |
token_list_t *list; |
tok = _token_create_ival (parser, INTEGER, value); |
list = _token_list_create(parser); |
_token_list_append(list, tok); |
_define_object_macro(parser, NULL, name, list); |
} |
glcpp_parser_t * |
glcpp_parser_create (const struct gl_extensions *extensions, gl_api api) |
{ |
glcpp_parser_t *parser; |
parser = ralloc (NULL, glcpp_parser_t); |
glcpp_lex_init_extra (parser, &parser->scanner); |
parser->defines = hash_table_ctor (32, hash_table_string_hash, |
hash_table_string_compare); |
parser->active = NULL; |
parser->lexing_directive = 0; |
parser->space_tokens = 1; |
parser->last_token_was_newline = 0; |
parser->last_token_was_space = 0; |
parser->first_non_space_token_this_line = 1; |
parser->newline_as_space = 0; |
parser->in_control_line = 0; |
parser->paren_count = 0; |
parser->commented_newlines = 0; |
parser->skip_stack = NULL; |
parser->skipping = 0; |
parser->lex_from_list = NULL; |
parser->lex_from_node = NULL; |
parser->output = ralloc_strdup(parser, ""); |
parser->output_length = 0; |
parser->info_log = ralloc_strdup(parser, ""); |
parser->info_log_length = 0; |
parser->error = 0; |
parser->extensions = extensions; |
parser->api = api; |
parser->version_resolved = false; |
parser->has_new_line_number = 0; |
parser->new_line_number = 1; |
parser->has_new_source_number = 0; |
parser->new_source_number = 0; |
return parser; |
} |
void |
glcpp_parser_destroy (glcpp_parser_t *parser) |
{ |
glcpp_lex_destroy (parser->scanner); |
hash_table_dtor (parser->defines); |
ralloc_free (parser); |
} |
typedef enum function_status |
{ |
FUNCTION_STATUS_SUCCESS, |
FUNCTION_NOT_A_FUNCTION, |
FUNCTION_UNBALANCED_PARENTHESES |
} function_status_t; |
/* Find a set of function-like macro arguments by looking for a |
* balanced set of parentheses. |
* |
* When called, 'node' should be the opening-parenthesis token, (or |
* perhaps preceeding SPACE tokens). Upon successful return *last will |
* be the last consumed node, (corresponding to the closing right |
* parenthesis). |
* |
* Return values: |
* |
* FUNCTION_STATUS_SUCCESS: |
* |
* Successfully parsed a set of function arguments. |
* |
* FUNCTION_NOT_A_FUNCTION: |
* |
* Macro name not followed by a '('. This is not an error, but |
* simply that the macro name should be treated as a non-macro. |
* |
* FUNCTION_UNBALANCED_PARENTHESES |
* |
* Macro name is not followed by a balanced set of parentheses. |
*/ |
static function_status_t |
_arguments_parse (argument_list_t *arguments, |
token_node_t *node, |
token_node_t **last) |
{ |
token_list_t *argument; |
int paren_count; |
node = node->next; |
/* Ignore whitespace before first parenthesis. */ |
while (node && node->token->type == SPACE) |
node = node->next; |
if (node == NULL || node->token->type != '(') |
return FUNCTION_NOT_A_FUNCTION; |
node = node->next; |
argument = _token_list_create (arguments); |
_argument_list_append (arguments, argument); |
for (paren_count = 1; node; node = node->next) { |
if (node->token->type == '(') |
{ |
paren_count++; |
} |
else if (node->token->type == ')') |
{ |
paren_count--; |
if (paren_count == 0) |
break; |
} |
if (node->token->type == ',' && |
paren_count == 1) |
{ |
_token_list_trim_trailing_space (argument); |
argument = _token_list_create (arguments); |
_argument_list_append (arguments, argument); |
} |
else { |
if (argument->head == NULL) { |
/* Don't treat initial whitespace as |
* part of the argument. */ |
if (node->token->type == SPACE) |
continue; |
} |
_token_list_append (argument, node->token); |
} |
} |
if (paren_count) |
return FUNCTION_UNBALANCED_PARENTHESES; |
*last = node; |
return FUNCTION_STATUS_SUCCESS; |
} |
static token_list_t * |
_token_list_create_with_one_ival (void *ctx, int type, int ival) |
{ |
token_list_t *list; |
token_t *node; |
list = _token_list_create (ctx); |
node = _token_create_ival (list, type, ival); |
_token_list_append (list, node); |
return list; |
} |
static token_list_t * |
_token_list_create_with_one_space (void *ctx) |
{ |
return _token_list_create_with_one_ival (ctx, SPACE, SPACE); |
} |
static token_list_t * |
_token_list_create_with_one_integer (void *ctx, int ival) |
{ |
return _token_list_create_with_one_ival (ctx, INTEGER, ival); |
} |
/* Evaluate a DEFINED token node (based on subsequent tokens in the list). |
* |
* Note: This function must only be called when "node" is a DEFINED token, |
* (and will abort with an assertion failure otherwise). |
* |
* If "node" is followed, (ignoring any SPACE tokens), by an IDENTIFIER token |
* (optionally preceded and followed by '(' and ')' tokens) then the following |
* occurs: |
* |
* If the identifier is a defined macro, this function returns 1. |
* |
* If the identifier is not a defined macro, this function returns 0. |
* |
* In either case, *last will be updated to the last node in the list |
* consumed by the evaluation, (either the token of the identifier or the |
* token of the closing parenthesis). |
* |
* In all other cases, (such as "node is the final node of the list", or |
* "missing closing parenthesis", etc.), this function generates a |
* preprocessor error, returns -1 and *last will not be set. |
*/ |
static int |
_glcpp_parser_evaluate_defined (glcpp_parser_t *parser, |
token_node_t *node, |
token_node_t **last) |
{ |
token_node_t *argument, *defined = node; |
assert (node->token->type == DEFINED); |
node = node->next; |
/* Ignore whitespace after DEFINED token. */ |
while (node && node->token->type == SPACE) |
node = node->next; |
if (node == NULL) |
goto FAIL; |
if (node->token->type == IDENTIFIER || node->token->type == OTHER) { |
argument = node; |
} else if (node->token->type == '(') { |
node = node->next; |
/* Ignore whitespace after '(' token. */ |
while (node && node->token->type == SPACE) |
node = node->next; |
if (node == NULL || (node->token->type != IDENTIFIER && |
node->token->type != OTHER)) |
{ |
goto FAIL; |
} |
argument = node; |
node = node->next; |
/* Ignore whitespace after identifier, before ')' token. */ |
while (node && node->token->type == SPACE) |
node = node->next; |
if (node == NULL || node->token->type != ')') |
goto FAIL; |
} else { |
goto FAIL; |
} |
*last = node; |
return hash_table_find (parser->defines, |
argument->token->value.str) ? 1 : 0; |
FAIL: |
glcpp_error (&defined->token->location, parser, |
"\"defined\" not followed by an identifier"); |
return -1; |
} |
/* Evaluate all DEFINED nodes in a given list, modifying the list in place. |
*/ |
static void |
_glcpp_parser_evaluate_defined_in_list (glcpp_parser_t *parser, |
token_list_t *list) |
{ |
token_node_t *node, *node_prev, *replacement, *last = NULL; |
int value; |
if (list == NULL) |
return; |
node_prev = NULL; |
node = list->head; |
while (node) { |
if (node->token->type != DEFINED) |
goto NEXT; |
value = _glcpp_parser_evaluate_defined (parser, node, &last); |
if (value == -1) |
goto NEXT; |
replacement = ralloc (list, token_node_t); |
replacement->token = _token_create_ival (list, INTEGER, value); |
/* Splice replacement node into list, replacing from "node" |
* through "last". */ |
if (node_prev) |
node_prev->next = replacement; |
else |
list->head = replacement; |
replacement->next = last->next; |
if (last == list->tail) |
list->tail = replacement; |
node = replacement; |
NEXT: |
node_prev = node; |
node = node->next; |
} |
} |
/* Perform macro expansion on 'list', placing the resulting tokens |
* into a new list which is initialized with a first token of type |
* 'head_token_type'. Then begin lexing from the resulting list, |
* (return to the current lexing source when this list is exhausted). |
* |
* See the documentation of _glcpp_parser_expand_token_list for a description |
* of the "mode" parameter. |
*/ |
static void |
_glcpp_parser_expand_and_lex_from (glcpp_parser_t *parser, |
int head_token_type, |
token_list_t *list, |
expansion_mode_t mode) |
{ |
token_list_t *expanded; |
token_t *token; |
expanded = _token_list_create (parser); |
token = _token_create_ival (parser, head_token_type, head_token_type); |
_token_list_append (expanded, token); |
_glcpp_parser_expand_token_list (parser, list, mode); |
_token_list_append_list (expanded, list); |
glcpp_parser_lex_from (parser, expanded); |
} |
static void |
_glcpp_parser_apply_pastes (glcpp_parser_t *parser, token_list_t *list) |
{ |
token_node_t *node; |
node = list->head; |
while (node) |
{ |
token_node_t *next_non_space; |
/* Look ahead for a PASTE token, skipping space. */ |
next_non_space = node->next; |
while (next_non_space && next_non_space->token->type == SPACE) |
next_non_space = next_non_space->next; |
if (next_non_space == NULL) |
break; |
if (next_non_space->token->type != PASTE) { |
node = next_non_space; |
continue; |
} |
/* Now find the next non-space token after the PASTE. */ |
next_non_space = next_non_space->next; |
while (next_non_space && next_non_space->token->type == SPACE) |
next_non_space = next_non_space->next; |
if (next_non_space == NULL) { |
yyerror (&node->token->location, parser, "'##' cannot appear at either end of a macro expansion\n"); |
return; |
} |
node->token = _token_paste (parser, node->token, next_non_space->token); |
node->next = next_non_space->next; |
if (next_non_space == list->tail) |
list->tail = node; |
} |
list->non_space_tail = list->tail; |
} |
/* This is a helper function that's essentially part of the |
* implementation of _glcpp_parser_expand_node. It shouldn't be called |
* except for by that function. |
* |
* Returns NULL if node is a simple token with no expansion, (that is, |
* although 'node' corresponds to an identifier defined as a |
* function-like macro, it is not followed with a parenthesized |
* argument list). |
* |
* Compute the complete expansion of node (which is a function-like |
* macro) and subsequent nodes which are arguments. |
* |
* Returns the token list that results from the expansion and sets |
* *last to the last node in the list that was consumed by the |
* expansion. Specifically, *last will be set as follows: as the |
* token of the closing right parenthesis. |
* |
* See the documentation of _glcpp_parser_expand_token_list for a description |
* of the "mode" parameter. |
*/ |
static token_list_t * |
_glcpp_parser_expand_function (glcpp_parser_t *parser, |
token_node_t *node, |
token_node_t **last, |
expansion_mode_t mode) |
{ |
macro_t *macro; |
const char *identifier; |
argument_list_t *arguments; |
function_status_t status; |
token_list_t *substituted; |
int parameter_index; |
identifier = node->token->value.str; |
macro = hash_table_find (parser->defines, identifier); |
assert (macro->is_function); |
arguments = _argument_list_create (parser); |
status = _arguments_parse (arguments, node, last); |
switch (status) { |
case FUNCTION_STATUS_SUCCESS: |
break; |
case FUNCTION_NOT_A_FUNCTION: |
return NULL; |
case FUNCTION_UNBALANCED_PARENTHESES: |
glcpp_error (&node->token->location, parser, "Macro %s call has unbalanced parentheses\n", identifier); |
return NULL; |
} |
/* Replace a macro defined as empty with a SPACE token. */ |
if (macro->replacements == NULL) { |
ralloc_free (arguments); |
return _token_list_create_with_one_space (parser); |
} |
if (! ((_argument_list_length (arguments) == |
_string_list_length (macro->parameters)) || |
(_string_list_length (macro->parameters) == 0 && |
_argument_list_length (arguments) == 1 && |
arguments->head->argument->head == NULL))) |
{ |
glcpp_error (&node->token->location, parser, |
"Error: macro %s invoked with %d arguments (expected %d)\n", |
identifier, |
_argument_list_length (arguments), |
_string_list_length (macro->parameters)); |
return NULL; |
} |
/* Perform argument substitution on the replacement list. */ |
substituted = _token_list_create (arguments); |
for (node = macro->replacements->head; node; node = node->next) |
{ |
if (node->token->type == IDENTIFIER && |
_string_list_contains (macro->parameters, |
node->token->value.str, |
¶meter_index)) |
{ |
token_list_t *argument; |
argument = _argument_list_member_at (arguments, |
parameter_index); |
/* Before substituting, we expand the argument |
* tokens, or append a placeholder token for |
* an empty argument. */ |
if (argument->head) { |
token_list_t *expanded_argument; |
expanded_argument = _token_list_copy (parser, |
argument); |
_glcpp_parser_expand_token_list (parser, |
expanded_argument, |
mode); |
_token_list_append_list (substituted, |
expanded_argument); |
} else { |
token_t *new_token; |
new_token = _token_create_ival (substituted, |
PLACEHOLDER, |
PLACEHOLDER); |
_token_list_append (substituted, new_token); |
} |
} else { |
_token_list_append (substituted, node->token); |
} |
} |
/* After argument substitution, and before further expansion |
* below, implement token pasting. */ |
_token_list_trim_trailing_space (substituted); |
_glcpp_parser_apply_pastes (parser, substituted); |
return substituted; |
} |
/* Compute the complete expansion of node, (and subsequent nodes after |
* 'node' in the case that 'node' is a function-like macro and |
* subsequent nodes are arguments). |
* |
* Returns NULL if node is a simple token with no expansion. |
* |
* Otherwise, returns the token list that results from the expansion |
* and sets *last to the last node in the list that was consumed by |
* the expansion. Specifically, *last will be set as follows: |
* |
* As 'node' in the case of object-like macro expansion. |
* |
* As the token of the closing right parenthesis in the case of |
* function-like macro expansion. |
* |
* See the documentation of _glcpp_parser_expand_token_list for a description |
* of the "mode" parameter. |
*/ |
static token_list_t * |
_glcpp_parser_expand_node (glcpp_parser_t *parser, |
token_node_t *node, |
token_node_t **last, |
expansion_mode_t mode) |
{ |
token_t *token = node->token; |
const char *identifier; |
macro_t *macro; |
/* We only expand identifiers */ |
if (token->type != IDENTIFIER) { |
return NULL; |
} |
*last = node; |
identifier = token->value.str; |
/* Special handling for __LINE__ and __FILE__, (not through |
* the hash table). */ |
if (strcmp(identifier, "__LINE__") == 0) |
return _token_list_create_with_one_integer (parser, node->token->location.first_line); |
if (strcmp(identifier, "__FILE__") == 0) |
return _token_list_create_with_one_integer (parser, node->token->location.source); |
/* Look up this identifier in the hash table. */ |
macro = hash_table_find (parser->defines, identifier); |
/* Not a macro, so no expansion needed. */ |
if (macro == NULL) |
return NULL; |
/* Finally, don't expand this macro if we're already actively |
* expanding it, (to avoid infinite recursion). */ |
if (_parser_active_list_contains (parser, identifier)) { |
/* We change the token type here from IDENTIFIER to |
* OTHER to prevent any future expansion of this |
* unexpanded token. */ |
char *str; |
token_list_t *expansion; |
token_t *final; |
str = ralloc_strdup (parser, token->value.str); |
final = _token_create_str (parser, OTHER, str); |
expansion = _token_list_create (parser); |
_token_list_append (expansion, final); |
return expansion; |
} |
if (! macro->is_function) |
{ |
token_list_t *replacement; |
/* Replace a macro defined as empty with a SPACE token. */ |
if (macro->replacements == NULL) |
return _token_list_create_with_one_space (parser); |
replacement = _token_list_copy (parser, macro->replacements); |
_glcpp_parser_apply_pastes (parser, replacement); |
return replacement; |
} |
return _glcpp_parser_expand_function (parser, node, last, mode); |
} |
/* Push a new identifier onto the parser's active list. |
* |
* Here, 'marker' is the token node that appears in the list after the |
* expansion of 'identifier'. That is, when the list iterator begins |
* examining 'marker', then it is time to pop this node from the |
* active stack. |
*/ |
static void |
_parser_active_list_push (glcpp_parser_t *parser, |
const char *identifier, |
token_node_t *marker) |
{ |
active_list_t *node; |
node = ralloc (parser->active, active_list_t); |
node->identifier = ralloc_strdup (node, identifier); |
node->marker = marker; |
node->next = parser->active; |
parser->active = node; |
} |
static void |
_parser_active_list_pop (glcpp_parser_t *parser) |
{ |
active_list_t *node = parser->active; |
if (node == NULL) { |
parser->active = NULL; |
return; |
} |
node = parser->active->next; |
ralloc_free (parser->active); |
parser->active = node; |
} |
static int |
_parser_active_list_contains (glcpp_parser_t *parser, const char *identifier) |
{ |
active_list_t *node; |
if (parser->active == NULL) |
return 0; |
for (node = parser->active; node; node = node->next) |
if (strcmp (node->identifier, identifier) == 0) |
return 1; |
return 0; |
} |
/* Walk over the token list replacing nodes with their expansion. |
* Whenever nodes are expanded the walking will walk over the new |
* nodes, continuing to expand as necessary. The results are placed in |
* 'list' itself. |
* |
* The "mode" argument controls the handling of any DEFINED tokens that |
* result from expansion as follows: |
* |
* EXPANSION_MODE_IGNORE_DEFINED: Any resulting DEFINED tokens will be |
* left in the final list, unevaluated. This is the correct mode |
* for expanding any list in any context other than a |
* preprocessor conditional, (#if or #elif). |
* |
* EXPANSION_MODE_EVALUATE_DEFINED: Any resulting DEFINED tokens will be |
* evaluated to 0 or 1 tokens depending on whether the following |
* token is the name of a defined macro. If the DEFINED token is |
* not followed by an (optionally parenthesized) identifier, then |
* an error will be generated. This the correct mode for |
* expanding any list in the context of a preprocessor |
* conditional, (#if or #elif). |
*/ |
static void |
_glcpp_parser_expand_token_list (glcpp_parser_t *parser, |
token_list_t *list, |
expansion_mode_t mode) |
{ |
token_node_t *node_prev; |
token_node_t *node, *last = NULL; |
token_list_t *expansion; |
active_list_t *active_initial = parser->active; |
if (list == NULL) |
return; |
_token_list_trim_trailing_space (list); |
node_prev = NULL; |
node = list->head; |
if (mode == EXPANSION_MODE_EVALUATE_DEFINED) |
_glcpp_parser_evaluate_defined_in_list (parser, list); |
while (node) { |
while (parser->active && parser->active->marker == node) |
_parser_active_list_pop (parser); |
expansion = _glcpp_parser_expand_node (parser, node, &last, mode); |
if (expansion) { |
token_node_t *n; |
if (mode == EXPANSION_MODE_EVALUATE_DEFINED) { |
_glcpp_parser_evaluate_defined_in_list (parser, |
expansion); |
} |
for (n = node; n != last->next; n = n->next) |
while (parser->active && |
parser->active->marker == n) |
{ |
_parser_active_list_pop (parser); |
} |
_parser_active_list_push (parser, |
node->token->value.str, |
last->next); |
/* Splice expansion into list, supporting a |
* simple deletion if the expansion is |
* empty. */ |
if (expansion->head) { |
if (node_prev) |
node_prev->next = expansion->head; |
else |
list->head = expansion->head; |
expansion->tail->next = last->next; |
if (last == list->tail) |
list->tail = expansion->tail; |
} else { |
if (node_prev) |
node_prev->next = last->next; |
else |
list->head = last->next; |
if (last == list->tail) |
list->tail = NULL; |
} |
} else { |
node_prev = node; |
} |
node = node_prev ? node_prev->next : list->head; |
} |
/* Remove any lingering effects of this invocation on the |
* active list. That is, pop until the list looks like it did |
* at the beginning of this function. */ |
while (parser->active && parser->active != active_initial) |
_parser_active_list_pop (parser); |
list->non_space_tail = list->tail; |
} |
void |
_glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser, |
token_list_t *list) |
{ |
if (list == NULL) |
return; |
_glcpp_parser_expand_token_list (parser, list, EXPANSION_MODE_IGNORE_DEFINED); |
_token_list_trim_trailing_space (list); |
_token_list_print (parser, list); |
} |
static void |
_check_for_reserved_macro_name (glcpp_parser_t *parser, YYLTYPE *loc, |
const char *identifier) |
{ |
/* Section 3.3 (Preprocessor) of the GLSL 1.30 spec (and later) and |
* the GLSL ES spec (all versions) say: |
* |
* "All macro names containing two consecutive underscores ( __ ) |
* are reserved for future use as predefined macro names. All |
* macro names prefixed with "GL_" ("GL" followed by a single |
* underscore) are also reserved." |
* |
* The intention is that names containing __ are reserved for internal |
* use by the implementation, and names prefixed with GL_ are reserved |
* for use by Khronos. Since every extension adds a name prefixed |
* with GL_ (i.e., the name of the extension), that should be an |
* error. Names simply containing __ are dangerous to use, but should |
* be allowed. |
* |
* A future version of the GLSL specification will clarify this. |
*/ |
if (strstr(identifier, "__")) { |
glcpp_warning(loc, parser, |
"Macro names containing \"__\" are reserved " |
"for use by the implementation.\n"); |
} |
if (strncmp(identifier, "GL_", 3) == 0) { |
glcpp_error (loc, parser, "Macro names starting with \"GL_\" are reserved.\n"); |
} |
} |
static int |
_macro_equal (macro_t *a, macro_t *b) |
{ |
if (a->is_function != b->is_function) |
return 0; |
if (a->is_function) { |
if (! _string_list_equal (a->parameters, b->parameters)) |
return 0; |
} |
return _token_list_equal_ignoring_space (a->replacements, |
b->replacements); |
} |
void |
_define_object_macro (glcpp_parser_t *parser, |
YYLTYPE *loc, |
const char *identifier, |
token_list_t *replacements) |
{ |
macro_t *macro, *previous; |
/* We define pre-defined macros before we've started parsing the |
* actual file. So if there's no location defined yet, that's what |
* were doing and we don't want to generate an error for using the |
* reserved names. */ |
if (loc != NULL) |
_check_for_reserved_macro_name(parser, loc, identifier); |
macro = ralloc (parser, macro_t); |
macro->is_function = 0; |
macro->parameters = NULL; |
macro->identifier = ralloc_strdup (macro, identifier); |
macro->replacements = replacements; |
ralloc_steal (macro, replacements); |
previous = hash_table_find (parser->defines, identifier); |
if (previous) { |
if (_macro_equal (macro, previous)) { |
ralloc_free (macro); |
return; |
} |
glcpp_error (loc, parser, "Redefinition of macro %s\n", |
identifier); |
} |
hash_table_insert (parser->defines, macro, identifier); |
} |
void |
_define_function_macro (glcpp_parser_t *parser, |
YYLTYPE *loc, |
const char *identifier, |
string_list_t *parameters, |
token_list_t *replacements) |
{ |
macro_t *macro, *previous; |
const char *dup; |
_check_for_reserved_macro_name(parser, loc, identifier); |
/* Check for any duplicate parameter names. */ |
if ((dup = _string_list_has_duplicate (parameters)) != NULL) { |
glcpp_error (loc, parser, "Duplicate macro parameter \"%s\"", |
dup); |
} |
macro = ralloc (parser, macro_t); |
ralloc_steal (macro, parameters); |
ralloc_steal (macro, replacements); |
macro->is_function = 1; |
macro->parameters = parameters; |
macro->identifier = ralloc_strdup (macro, identifier); |
macro->replacements = replacements; |
previous = hash_table_find (parser->defines, identifier); |
if (previous) { |
if (_macro_equal (macro, previous)) { |
ralloc_free (macro); |
return; |
} |
glcpp_error (loc, parser, "Redefinition of macro %s\n", |
identifier); |
} |
hash_table_insert (parser->defines, macro, identifier); |
} |
static int |
glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser) |
{ |
token_node_t *node; |
int ret; |
if (parser->lex_from_list == NULL) { |
ret = glcpp_lex (yylval, yylloc, parser->scanner); |
/* XXX: This ugly block of code exists for the sole |
* purpose of converting a NEWLINE token into a SPACE |
* token, but only in the case where we have seen a |
* function-like macro name, but have not yet seen its |
* closing parenthesis. |
* |
* There's perhaps a more compact way to do this with |
* mid-rule actions in the grammar. |
* |
* I'm definitely not pleased with the complexity of |
* this code here. |
*/ |
if (parser->newline_as_space) |
{ |
if (ret == '(') { |
parser->paren_count++; |
} else if (ret == ')') { |
parser->paren_count--; |
if (parser->paren_count == 0) |
parser->newline_as_space = 0; |
} else if (ret == NEWLINE) { |
ret = SPACE; |
} else if (ret != SPACE) { |
if (parser->paren_count == 0) |
parser->newline_as_space = 0; |
} |
} |
else if (parser->in_control_line) |
{ |
if (ret == NEWLINE) |
parser->in_control_line = 0; |
} |
else if (ret == DEFINE_TOKEN || |
ret == UNDEF || ret == IF || |
ret == IFDEF || ret == IFNDEF || |
ret == ELIF || ret == ELSE || |
ret == ENDIF || ret == HASH_TOKEN) |
{ |
parser->in_control_line = 1; |
} |
else if (ret == IDENTIFIER) |
{ |
macro_t *macro; |
macro = hash_table_find (parser->defines, |
yylval->str); |
if (macro && macro->is_function) { |
parser->newline_as_space = 1; |
parser->paren_count = 0; |
} |
} |
return ret; |
} |
node = parser->lex_from_node; |
if (node == NULL) { |
ralloc_free (parser->lex_from_list); |
parser->lex_from_list = NULL; |
return NEWLINE; |
} |
*yylval = node->token->value; |
ret = node->token->type; |
parser->lex_from_node = node->next; |
return ret; |
} |
static void |
glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list) |
{ |
token_node_t *node; |
assert (parser->lex_from_list == NULL); |
/* Copy list, eliminating any space tokens. */ |
parser->lex_from_list = _token_list_create (parser); |
for (node = list->head; node; node = node->next) { |
if (node->token->type == SPACE) |
continue; |
_token_list_append (parser->lex_from_list, node->token); |
} |
ralloc_free (list); |
parser->lex_from_node = parser->lex_from_list->head; |
/* It's possible the list consisted of nothing but whitespace. */ |
if (parser->lex_from_node == NULL) { |
ralloc_free (parser->lex_from_list); |
parser->lex_from_list = NULL; |
} |
} |
static void |
_glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc, |
int condition) |
{ |
skip_type_t current = SKIP_NO_SKIP; |
skip_node_t *node; |
if (parser->skip_stack) |
current = parser->skip_stack->type; |
node = ralloc (parser, skip_node_t); |
node->loc = *loc; |
if (current == SKIP_NO_SKIP) { |
if (condition) |
node->type = SKIP_NO_SKIP; |
else |
node->type = SKIP_TO_ELSE; |
} else { |
node->type = SKIP_TO_ENDIF; |
} |
node->has_else = false; |
node->next = parser->skip_stack; |
parser->skip_stack = node; |
} |
static void |
_glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc, |
const char *type, int condition) |
{ |
if (parser->skip_stack == NULL) { |
glcpp_error (loc, parser, "#%s without #if\n", type); |
return; |
} |
if (parser->skip_stack->type == SKIP_TO_ELSE) { |
if (condition) |
parser->skip_stack->type = SKIP_NO_SKIP; |
} else { |
parser->skip_stack->type = SKIP_TO_ENDIF; |
} |
} |
static void |
_glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc) |
{ |
skip_node_t *node; |
if (parser->skip_stack == NULL) { |
glcpp_error (loc, parser, "#endif without #if\n"); |
return; |
} |
node = parser->skip_stack; |
parser->skip_stack = node->next; |
ralloc_free (node); |
} |
static void |
_glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version, |
const char *es_identifier, |
bool explicitly_set) |
{ |
const struct gl_extensions *extensions = parser->extensions; |
if (parser->version_resolved) |
return; |
parser->version_resolved = true; |
add_builtin_define (parser, "__VERSION__", version); |
parser->is_gles = (version == 100) || |
(es_identifier && |
(strcmp(es_identifier, "es") == 0)); |
/* Add pre-defined macros. */ |
if (parser->is_gles) { |
add_builtin_define(parser, "GL_ES", 1); |
add_builtin_define(parser, "GL_EXT_separate_shader_objects", 1); |
add_builtin_define(parser, "GL_EXT_draw_buffers", 1); |
if (extensions != NULL) { |
if (extensions->OES_EGL_image_external) |
add_builtin_define(parser, "GL_OES_EGL_image_external", 1); |
if (extensions->OES_standard_derivatives) |
add_builtin_define(parser, "GL_OES_standard_derivatives", 1); |
} |
} else { |
add_builtin_define(parser, "GL_ARB_draw_buffers", 1); |
add_builtin_define(parser, "GL_ARB_separate_shader_objects", 1); |
add_builtin_define(parser, "GL_ARB_texture_rectangle", 1); |
add_builtin_define(parser, "GL_AMD_shader_trinary_minmax", 1); |
if (extensions != NULL) { |
if (extensions->EXT_texture_array) |
add_builtin_define(parser, "GL_EXT_texture_array", 1); |
if (extensions->ARB_arrays_of_arrays) |
add_builtin_define(parser, "GL_ARB_arrays_of_arrays", 1); |
if (extensions->ARB_fragment_coord_conventions) |
add_builtin_define(parser, "GL_ARB_fragment_coord_conventions", |
1); |
if (extensions->ARB_fragment_layer_viewport) |
add_builtin_define(parser, "GL_ARB_fragment_layer_viewport", 1); |
if (extensions->ARB_explicit_attrib_location) |
add_builtin_define(parser, "GL_ARB_explicit_attrib_location", 1); |
if (extensions->ARB_explicit_uniform_location) |
add_builtin_define(parser, "GL_ARB_explicit_uniform_location", 1); |
if (extensions->ARB_shader_texture_lod) |
add_builtin_define(parser, "GL_ARB_shader_texture_lod", 1); |
if (extensions->ARB_draw_instanced) |
add_builtin_define(parser, "GL_ARB_draw_instanced", 1); |
if (extensions->ARB_conservative_depth) { |
add_builtin_define(parser, "GL_AMD_conservative_depth", 1); |
add_builtin_define(parser, "GL_ARB_conservative_depth", 1); |
} |
if (extensions->ARB_shader_bit_encoding) |
add_builtin_define(parser, "GL_ARB_shader_bit_encoding", 1); |
if (extensions->ARB_uniform_buffer_object) |
add_builtin_define(parser, "GL_ARB_uniform_buffer_object", 1); |
if (extensions->ARB_texture_cube_map_array) |
add_builtin_define(parser, "GL_ARB_texture_cube_map_array", 1); |
if (extensions->ARB_shading_language_packing) |
add_builtin_define(parser, "GL_ARB_shading_language_packing", 1); |
if (extensions->ARB_texture_multisample) |
add_builtin_define(parser, "GL_ARB_texture_multisample", 1); |
if (extensions->ARB_texture_query_levels) |
add_builtin_define(parser, "GL_ARB_texture_query_levels", 1); |
if (extensions->ARB_texture_query_lod) |
add_builtin_define(parser, "GL_ARB_texture_query_lod", 1); |
if (extensions->ARB_gpu_shader5) |
add_builtin_define(parser, "GL_ARB_gpu_shader5", 1); |
if (extensions->ARB_gpu_shader_fp64) |
add_builtin_define(parser, "GL_ARB_gpu_shader_fp64", 1); |
if (extensions->ARB_vertex_attrib_64bit) |
add_builtin_define(parser, "GL_ARB_vertex_attrib_64bit", 1); |
if (extensions->AMD_vertex_shader_layer) |
add_builtin_define(parser, "GL_AMD_vertex_shader_layer", 1); |
if (extensions->AMD_vertex_shader_viewport_index) |
add_builtin_define(parser, "GL_AMD_vertex_shader_viewport_index", 1); |
if (extensions->ARB_shading_language_420pack) |
add_builtin_define(parser, "GL_ARB_shading_language_420pack", 1); |
if (extensions->ARB_sample_shading) |
add_builtin_define(parser, "GL_ARB_sample_shading", 1); |
if (extensions->ARB_texture_gather) |
add_builtin_define(parser, "GL_ARB_texture_gather", 1); |
if (extensions->ARB_shader_atomic_counters) |
add_builtin_define(parser, "GL_ARB_shader_atomic_counters", 1); |
if (extensions->ARB_viewport_array) |
add_builtin_define(parser, "GL_ARB_viewport_array", 1); |
if (extensions->ARB_compute_shader) |
add_builtin_define(parser, "GL_ARB_compute_shader", 1); |
if (extensions->ARB_shader_image_load_store) |
add_builtin_define(parser, "GL_ARB_shader_image_load_store", 1); |
if (extensions->ARB_derivative_control) |
add_builtin_define(parser, "GL_ARB_derivative_control", 1); |
if (extensions->ARB_shader_precision) |
add_builtin_define(parser, "GL_ARB_shader_precision", 1); |
} |
} |
if (extensions != NULL) { |
if (extensions->EXT_shader_integer_mix) |
add_builtin_define(parser, "GL_EXT_shader_integer_mix", 1); |
} |
if (version >= 150) |
add_builtin_define(parser, "GL_core_profile", 1); |
/* Currently, all ES2/ES3 implementations support highp in the |
* fragment shader, so we always define this macro in ES2/ES3. |
* If we ever get a driver that doesn't support highp, we'll |
* need to add a flag to the gl_context and check that here. |
*/ |
if (version >= 130 || parser->is_gles) |
add_builtin_define (parser, "GL_FRAGMENT_PRECISION_HIGH", 1); |
if (explicitly_set) { |
ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, |
"#version %" PRIiMAX "%s%s", version, |
es_identifier ? " " : "", |
es_identifier ? es_identifier : ""); |
} |
} |
/* GLSL version if no version is explicitly specified. */ |
#define IMPLICIT_GLSL_VERSION 110 |
/* GLSL ES version if no version is explicitly specified. */ |
#define IMPLICIT_GLSL_ES_VERSION 100 |
void |
glcpp_parser_resolve_implicit_version(glcpp_parser_t *parser) |
{ |
int language_version = parser->api == API_OPENGLES2 ? |
IMPLICIT_GLSL_ES_VERSION : |
IMPLICIT_GLSL_VERSION; |
_glcpp_parser_handle_version_declaration(parser, language_version, |
NULL, false); |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/glcpp-parse.h |
---|
0,0 → 1,110 |
/* A Bison parser, made by GNU Bison 3.0.4. */ |
/* Bison interface for Yacc-like parsers in C |
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. |
This program is free software: you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation, either version 3 of the License, or |
(at your option) any later version. |
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
You should have received a copy of the GNU General Public License |
along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
/* As a special exception, you may create a larger work that contains |
part or all of the Bison parser skeleton and distribute that work |
under terms of your choice, so long as that work isn't itself a |
parser generator using the skeleton or a modified version thereof |
as a parser skeleton. Alternatively, if you modify or redistribute |
the parser skeleton itself, you may (at your option) remove this |
special exception, which will cause the skeleton and the resulting |
Bison output files to be licensed under the GNU General Public |
License without this special exception. |
This special exception was added by the Free Software Foundation in |
version 2.2 of Bison. */ |
#ifndef YY_GLCPP_PARSER_GLCPP_GLCPP_PARSE_H_INCLUDED |
# define YY_GLCPP_PARSER_GLCPP_GLCPP_PARSE_H_INCLUDED |
/* Debug traces. */ |
#ifndef YYDEBUG |
# define YYDEBUG 1 |
#endif |
#if YYDEBUG |
extern int glcpp_parser_debug; |
#endif |
/* Token type. */ |
#ifndef YYTOKENTYPE |
# define YYTOKENTYPE |
enum yytokentype |
{ |
DEFINED = 258, |
ELIF_EXPANDED = 259, |
HASH_TOKEN = 260, |
DEFINE_TOKEN = 261, |
FUNC_IDENTIFIER = 262, |
OBJ_IDENTIFIER = 263, |
ELIF = 264, |
ELSE = 265, |
ENDIF = 266, |
ERROR_TOKEN = 267, |
IF = 268, |
IFDEF = 269, |
IFNDEF = 270, |
LINE = 271, |
PRAGMA = 272, |
UNDEF = 273, |
VERSION_TOKEN = 274, |
GARBAGE = 275, |
IDENTIFIER = 276, |
IF_EXPANDED = 277, |
INTEGER = 278, |
INTEGER_STRING = 279, |
LINE_EXPANDED = 280, |
NEWLINE = 281, |
OTHER = 282, |
PLACEHOLDER = 283, |
SPACE = 284, |
PLUS_PLUS = 285, |
MINUS_MINUS = 286, |
PASTE = 287, |
OR = 288, |
AND = 289, |
EQUAL = 290, |
NOT_EQUAL = 291, |
LESS_OR_EQUAL = 292, |
GREATER_OR_EQUAL = 293, |
LEFT_SHIFT = 294, |
RIGHT_SHIFT = 295, |
UNARY = 296 |
}; |
#endif |
/* Value type. */ |
/* Location type. */ |
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED |
typedef struct YYLTYPE YYLTYPE; |
struct YYLTYPE |
{ |
int first_line; |
int first_column; |
int last_line; |
int last_column; |
}; |
# define YYLTYPE_IS_DECLARED 1 |
# define YYLTYPE_IS_TRIVIAL 1 |
#endif |
int glcpp_parser_parse (glcpp_parser_t *parser); |
#endif /* !YY_GLCPP_PARSER_GLCPP_GLCPP_PARSE_H_INCLUDED */ |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/glcpp-parse.y |
---|
0,0 → 1,2528 |
%{ |
/* |
* Copyright © 2010 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <assert.h> |
#include <inttypes.h> |
#include "glcpp.h" |
#include "main/core.h" /* for struct gl_extensions */ |
#include "main/mtypes.h" /* for gl_api enum */ |
static void |
yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error); |
static void |
_define_object_macro (glcpp_parser_t *parser, |
YYLTYPE *loc, |
const char *macro, |
token_list_t *replacements); |
static void |
_define_function_macro (glcpp_parser_t *parser, |
YYLTYPE *loc, |
const char *macro, |
string_list_t *parameters, |
token_list_t *replacements); |
static string_list_t * |
_string_list_create (void *ctx); |
static void |
_string_list_append_item (string_list_t *list, const char *str); |
static int |
_string_list_contains (string_list_t *list, const char *member, int *index); |
static const char * |
_string_list_has_duplicate (string_list_t *list); |
static int |
_string_list_length (string_list_t *list); |
static int |
_string_list_equal (string_list_t *a, string_list_t *b); |
static argument_list_t * |
_argument_list_create (void *ctx); |
static void |
_argument_list_append (argument_list_t *list, token_list_t *argument); |
static int |
_argument_list_length (argument_list_t *list); |
static token_list_t * |
_argument_list_member_at (argument_list_t *list, int index); |
/* Note: This function ralloc_steal()s the str pointer. */ |
static token_t * |
_token_create_str (void *ctx, int type, char *str); |
static token_t * |
_token_create_ival (void *ctx, int type, int ival); |
static token_list_t * |
_token_list_create (void *ctx); |
static void |
_token_list_append (token_list_t *list, token_t *token); |
static void |
_token_list_append_list (token_list_t *list, token_list_t *tail); |
static int |
_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b); |
static void |
_parser_active_list_push (glcpp_parser_t *parser, |
const char *identifier, |
token_node_t *marker); |
static void |
_parser_active_list_pop (glcpp_parser_t *parser); |
static int |
_parser_active_list_contains (glcpp_parser_t *parser, const char *identifier); |
typedef enum { |
EXPANSION_MODE_IGNORE_DEFINED, |
EXPANSION_MODE_EVALUATE_DEFINED |
} expansion_mode_t; |
/* Expand list, and begin lexing from the result (after first |
* prefixing a token of type 'head_token_type'). |
*/ |
static void |
_glcpp_parser_expand_and_lex_from (glcpp_parser_t *parser, |
int head_token_type, |
token_list_t *list, |
expansion_mode_t mode); |
/* Perform macro expansion in-place on the given list. */ |
static void |
_glcpp_parser_expand_token_list (glcpp_parser_t *parser, |
token_list_t *list, |
expansion_mode_t mode); |
static void |
_glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser, |
token_list_t *list); |
static void |
_glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc, |
int condition); |
static void |
_glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc, |
const char *type, int condition); |
static void |
_glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc); |
static void |
_glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version, |
const char *ident, bool explicitly_set); |
static int |
glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser); |
static void |
glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list); |
static void |
add_builtin_define(glcpp_parser_t *parser, const char *name, int value); |
%} |
%pure-parser |
%error-verbose |
%locations |
%initial-action { |
@$.first_line = 1; |
@$.first_column = 1; |
@$.last_line = 1; |
@$.last_column = 1; |
@$.source = 0; |
} |
%parse-param {glcpp_parser_t *parser} |
%lex-param {glcpp_parser_t *parser} |
%expect 0 |
/* We use HASH_TOKEN, DEFINE_TOKEN and VERSION_TOKEN (as opposed to |
* HASH, DEFINE, and VERSION) to avoid conflicts with other symbols, |
* (such as the <HASH> and <DEFINE> start conditions in the lexer). */ |
%token DEFINED ELIF_EXPANDED HASH_TOKEN DEFINE_TOKEN FUNC_IDENTIFIER OBJ_IDENTIFIER ELIF ELSE ENDIF ERROR_TOKEN IF IFDEF IFNDEF LINE PRAGMA UNDEF VERSION_TOKEN GARBAGE IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE PLUS_PLUS MINUS_MINUS |
%token PASTE |
%type <ival> INTEGER operator SPACE integer_constant |
%type <expression_value> expression |
%type <str> IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER ERROR_TOKEN PRAGMA |
%type <string_list> identifier_list |
%type <token> preprocessing_token |
%type <token_list> pp_tokens replacement_list text_line |
%left OR |
%left AND |
%left '|' |
%left '^' |
%left '&' |
%left EQUAL NOT_EQUAL |
%left '<' '>' LESS_OR_EQUAL GREATER_OR_EQUAL |
%left LEFT_SHIFT RIGHT_SHIFT |
%left '+' '-' |
%left '*' '/' '%' |
%right UNARY |
%debug |
%% |
input: |
/* empty */ |
| input line |
; |
line: |
control_line |
| SPACE control_line |
| text_line { |
_glcpp_parser_print_expanded_token_list (parser, $1); |
ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n"); |
ralloc_free ($1); |
} |
| expanded_line |
; |
expanded_line: |
IF_EXPANDED expression NEWLINE { |
if (parser->is_gles && $2.undefined_macro) |
glcpp_error(& @1, parser, "undefined macro %s in expression (illegal in GLES)", $2.undefined_macro); |
_glcpp_parser_skip_stack_push_if (parser, & @1, $2.value); |
} |
| ELIF_EXPANDED expression NEWLINE { |
if (parser->is_gles && $2.undefined_macro) |
glcpp_error(& @1, parser, "undefined macro %s in expression (illegal in GLES)", $2.undefined_macro); |
_glcpp_parser_skip_stack_change_if (parser, & @1, "elif", $2.value); |
} |
| LINE_EXPANDED integer_constant NEWLINE { |
parser->has_new_line_number = 1; |
parser->new_line_number = $2; |
ralloc_asprintf_rewrite_tail (&parser->output, |
&parser->output_length, |
"#line %" PRIiMAX "\n", |
$2); |
} |
| LINE_EXPANDED integer_constant integer_constant NEWLINE { |
parser->has_new_line_number = 1; |
parser->new_line_number = $2; |
parser->has_new_source_number = 1; |
parser->new_source_number = $3; |
ralloc_asprintf_rewrite_tail (&parser->output, |
&parser->output_length, |
"#line %" PRIiMAX " %" PRIiMAX "\n", |
$2, $3); |
} |
; |
define: |
OBJ_IDENTIFIER replacement_list NEWLINE { |
_define_object_macro (parser, & @1, $1, $2); |
} |
| FUNC_IDENTIFIER '(' ')' replacement_list NEWLINE { |
_define_function_macro (parser, & @1, $1, NULL, $4); |
} |
| FUNC_IDENTIFIER '(' identifier_list ')' replacement_list NEWLINE { |
_define_function_macro (parser, & @1, $1, $3, $5); |
} |
; |
control_line: |
control_line_success { |
ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n"); |
} |
| control_line_error |
| HASH_TOKEN LINE { |
glcpp_parser_resolve_implicit_version(parser); |
} pp_tokens NEWLINE { |
if (parser->skip_stack == NULL || |
parser->skip_stack->type == SKIP_NO_SKIP) |
{ |
_glcpp_parser_expand_and_lex_from (parser, |
LINE_EXPANDED, $4, |
EXPANSION_MODE_IGNORE_DEFINED); |
} |
} |
; |
control_line_success: |
HASH_TOKEN DEFINE_TOKEN { |
glcpp_parser_resolve_implicit_version(parser); |
} define |
| HASH_TOKEN UNDEF { |
glcpp_parser_resolve_implicit_version(parser); |
} IDENTIFIER NEWLINE { |
macro_t *macro; |
if (strcmp("__LINE__", $4) == 0 |
|| strcmp("__FILE__", $4) == 0 |
|| strcmp("__VERSION__", $4) == 0 |
|| strncmp("GL_", $4, 3) == 0) |
glcpp_error(& @1, parser, "Built-in (pre-defined)" |
" macro names cannot be undefined."); |
macro = hash_table_find (parser->defines, $4); |
if (macro) { |
hash_table_remove (parser->defines, $4); |
ralloc_free (macro); |
} |
ralloc_free ($4); |
} |
| HASH_TOKEN IF { |
glcpp_parser_resolve_implicit_version(parser); |
} pp_tokens NEWLINE { |
/* Be careful to only evaluate the 'if' expression if |
* we are not skipping. When we are skipping, we |
* simply push a new 0-valued 'if' onto the skip |
* stack. |
* |
* This avoids generating diagnostics for invalid |
* expressions that are being skipped. */ |
if (parser->skip_stack == NULL || |
parser->skip_stack->type == SKIP_NO_SKIP) |
{ |
_glcpp_parser_expand_and_lex_from (parser, |
IF_EXPANDED, $4, |
EXPANSION_MODE_EVALUATE_DEFINED); |
} |
else |
{ |
_glcpp_parser_skip_stack_push_if (parser, & @1, 0); |
parser->skip_stack->type = SKIP_TO_ENDIF; |
} |
} |
| HASH_TOKEN IF NEWLINE { |
/* #if without an expression is only an error if we |
* are not skipping */ |
if (parser->skip_stack == NULL || |
parser->skip_stack->type == SKIP_NO_SKIP) |
{ |
glcpp_error(& @1, parser, "#if with no expression"); |
} |
_glcpp_parser_skip_stack_push_if (parser, & @1, 0); |
} |
| HASH_TOKEN IFDEF { |
glcpp_parser_resolve_implicit_version(parser); |
} IDENTIFIER junk NEWLINE { |
macro_t *macro = hash_table_find (parser->defines, $4); |
ralloc_free ($4); |
_glcpp_parser_skip_stack_push_if (parser, & @1, macro != NULL); |
} |
| HASH_TOKEN IFNDEF { |
glcpp_parser_resolve_implicit_version(parser); |
} IDENTIFIER junk NEWLINE { |
macro_t *macro = hash_table_find (parser->defines, $4); |
ralloc_free ($4); |
_glcpp_parser_skip_stack_push_if (parser, & @3, macro == NULL); |
} |
| HASH_TOKEN ELIF pp_tokens NEWLINE { |
/* Be careful to only evaluate the 'elif' expression |
* if we are not skipping. When we are skipping, we |
* simply change to a 0-valued 'elif' on the skip |
* stack. |
* |
* This avoids generating diagnostics for invalid |
* expressions that are being skipped. */ |
if (parser->skip_stack && |
parser->skip_stack->type == SKIP_TO_ELSE) |
{ |
_glcpp_parser_expand_and_lex_from (parser, |
ELIF_EXPANDED, $3, |
EXPANSION_MODE_EVALUATE_DEFINED); |
} |
else if (parser->skip_stack && |
parser->skip_stack->has_else) |
{ |
glcpp_error(& @1, parser, "#elif after #else"); |
} |
else |
{ |
_glcpp_parser_skip_stack_change_if (parser, & @1, |
"elif", 0); |
} |
} |
| HASH_TOKEN ELIF NEWLINE { |
/* #elif without an expression is an error unless we |
* are skipping. */ |
if (parser->skip_stack && |
parser->skip_stack->type == SKIP_TO_ELSE) |
{ |
glcpp_error(& @1, parser, "#elif with no expression"); |
} |
else if (parser->skip_stack && |
parser->skip_stack->has_else) |
{ |
glcpp_error(& @1, parser, "#elif after #else"); |
} |
else |
{ |
_glcpp_parser_skip_stack_change_if (parser, & @1, |
"elif", 0); |
glcpp_warning(& @1, parser, "ignoring illegal #elif without expression"); |
} |
} |
| HASH_TOKEN ELSE { parser->lexing_directive = 1; } NEWLINE { |
if (parser->skip_stack && |
parser->skip_stack->has_else) |
{ |
glcpp_error(& @1, parser, "multiple #else"); |
} |
else |
{ |
_glcpp_parser_skip_stack_change_if (parser, & @1, "else", 1); |
if (parser->skip_stack) |
parser->skip_stack->has_else = true; |
} |
} |
| HASH_TOKEN ENDIF { |
_glcpp_parser_skip_stack_pop (parser, & @1); |
} NEWLINE |
| HASH_TOKEN VERSION_TOKEN integer_constant NEWLINE { |
if (parser->version_resolved) { |
glcpp_error(& @1, parser, "#version must appear on the first line"); |
} |
_glcpp_parser_handle_version_declaration(parser, $3, NULL, true); |
} |
| HASH_TOKEN VERSION_TOKEN integer_constant IDENTIFIER NEWLINE { |
if (parser->version_resolved) { |
glcpp_error(& @1, parser, "#version must appear on the first line"); |
} |
_glcpp_parser_handle_version_declaration(parser, $3, $4, true); |
} |
| HASH_TOKEN NEWLINE { |
glcpp_parser_resolve_implicit_version(parser); |
} |
| HASH_TOKEN PRAGMA NEWLINE { |
ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "#%s", $2); |
} |
; |
control_line_error: |
HASH_TOKEN ERROR_TOKEN NEWLINE { |
glcpp_error(& @1, parser, "#%s", $2); |
} |
| HASH_TOKEN DEFINE_TOKEN NEWLINE { |
glcpp_error (& @1, parser, "#define without macro name"); |
} |
| HASH_TOKEN GARBAGE pp_tokens NEWLINE { |
glcpp_error (& @1, parser, "Illegal non-directive after #"); |
} |
; |
integer_constant: |
INTEGER_STRING { |
if (strlen ($1) >= 3 && strncmp ($1, "0x", 2) == 0) { |
$$ = strtoll ($1 + 2, NULL, 16); |
} else if ($1[0] == '0') { |
$$ = strtoll ($1, NULL, 8); |
} else { |
$$ = strtoll ($1, NULL, 10); |
} |
} |
| INTEGER { |
$$ = $1; |
} |
expression: |
integer_constant { |
$$.value = $1; |
$$.undefined_macro = NULL; |
} |
| IDENTIFIER { |
$$.value = 0; |
if (parser->is_gles) |
$$.undefined_macro = ralloc_strdup (parser, $1); |
else |
$$.undefined_macro = NULL; |
} |
| expression OR expression { |
$$.value = $1.value || $3.value; |
/* Short-circuit: Only flag undefined from right side |
* if left side evaluates to false. |
*/ |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else if (! $1.value) |
$$.undefined_macro = $3.undefined_macro; |
} |
| expression AND expression { |
$$.value = $1.value && $3.value; |
/* Short-circuit: Only flag undefined from right-side |
* if left side evaluates to true. |
*/ |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else if ($1.value) |
$$.undefined_macro = $3.undefined_macro; |
} |
| expression '|' expression { |
$$.value = $1.value | $3.value; |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else |
$$.undefined_macro = $3.undefined_macro; |
} |
| expression '^' expression { |
$$.value = $1.value ^ $3.value; |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else |
$$.undefined_macro = $3.undefined_macro; |
} |
| expression '&' expression { |
$$.value = $1.value & $3.value; |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else |
$$.undefined_macro = $3.undefined_macro; |
} |
| expression NOT_EQUAL expression { |
$$.value = $1.value != $3.value; |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else |
$$.undefined_macro = $3.undefined_macro; |
} |
| expression EQUAL expression { |
$$.value = $1.value == $3.value; |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else |
$$.undefined_macro = $3.undefined_macro; |
} |
| expression GREATER_OR_EQUAL expression { |
$$.value = $1.value >= $3.value; |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else |
$$.undefined_macro = $3.undefined_macro; |
} |
| expression LESS_OR_EQUAL expression { |
$$.value = $1.value <= $3.value; |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else |
$$.undefined_macro = $3.undefined_macro; |
} |
| expression '>' expression { |
$$.value = $1.value > $3.value; |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else |
$$.undefined_macro = $3.undefined_macro; |
} |
| expression '<' expression { |
$$.value = $1.value < $3.value; |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else |
$$.undefined_macro = $3.undefined_macro; |
} |
| expression RIGHT_SHIFT expression { |
$$.value = $1.value >> $3.value; |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else |
$$.undefined_macro = $3.undefined_macro; |
} |
| expression LEFT_SHIFT expression { |
$$.value = $1.value << $3.value; |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else |
$$.undefined_macro = $3.undefined_macro; |
} |
| expression '-' expression { |
$$.value = $1.value - $3.value; |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else |
$$.undefined_macro = $3.undefined_macro; |
} |
| expression '+' expression { |
$$.value = $1.value + $3.value; |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else |
$$.undefined_macro = $3.undefined_macro; |
} |
| expression '%' expression { |
if ($3.value == 0) { |
yyerror (& @1, parser, |
"zero modulus in preprocessor directive"); |
} else { |
$$.value = $1.value % $3.value; |
} |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else |
$$.undefined_macro = $3.undefined_macro; |
} |
| expression '/' expression { |
if ($3.value == 0) { |
yyerror (& @1, parser, |
"division by 0 in preprocessor directive"); |
} else { |
$$.value = $1.value / $3.value; |
} |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else |
$$.undefined_macro = $3.undefined_macro; |
} |
| expression '*' expression { |
$$.value = $1.value * $3.value; |
if ($1.undefined_macro) |
$$.undefined_macro = $1.undefined_macro; |
else |
$$.undefined_macro = $3.undefined_macro; |
} |
| '!' expression %prec UNARY { |
$$.value = ! $2.value; |
$$.undefined_macro = $2.undefined_macro; |
} |
| '~' expression %prec UNARY { |
$$.value = ~ $2.value; |
$$.undefined_macro = $2.undefined_macro; |
} |
| '-' expression %prec UNARY { |
$$.value = - $2.value; |
$$.undefined_macro = $2.undefined_macro; |
} |
| '+' expression %prec UNARY { |
$$.value = + $2.value; |
$$.undefined_macro = $2.undefined_macro; |
} |
| '(' expression ')' { |
$$ = $2; |
} |
; |
identifier_list: |
IDENTIFIER { |
$$ = _string_list_create (parser); |
_string_list_append_item ($$, $1); |
ralloc_steal ($$, $1); |
} |
| identifier_list ',' IDENTIFIER { |
$$ = $1; |
_string_list_append_item ($$, $3); |
ralloc_steal ($$, $3); |
} |
; |
text_line: |
NEWLINE { $$ = NULL; } |
| pp_tokens NEWLINE |
; |
replacement_list: |
/* empty */ { $$ = NULL; } |
| pp_tokens |
; |
junk: |
/* empty */ |
| pp_tokens { |
glcpp_error(&@1, parser, "extra tokens at end of directive"); |
} |
; |
pp_tokens: |
preprocessing_token { |
parser->space_tokens = 1; |
$$ = _token_list_create (parser); |
_token_list_append ($$, $1); |
} |
| pp_tokens preprocessing_token { |
$$ = $1; |
_token_list_append ($$, $2); |
} |
; |
preprocessing_token: |
IDENTIFIER { |
$$ = _token_create_str (parser, IDENTIFIER, $1); |
$$->location = yylloc; |
} |
| INTEGER_STRING { |
$$ = _token_create_str (parser, INTEGER_STRING, $1); |
$$->location = yylloc; |
} |
| operator { |
$$ = _token_create_ival (parser, $1, $1); |
$$->location = yylloc; |
} |
| DEFINED { |
$$ = _token_create_ival (parser, DEFINED, DEFINED); |
$$->location = yylloc; |
} |
| OTHER { |
$$ = _token_create_str (parser, OTHER, $1); |
$$->location = yylloc; |
} |
| SPACE { |
$$ = _token_create_ival (parser, SPACE, SPACE); |
$$->location = yylloc; |
} |
; |
operator: |
'[' { $$ = '['; } |
| ']' { $$ = ']'; } |
| '(' { $$ = '('; } |
| ')' { $$ = ')'; } |
| '{' { $$ = '{'; } |
| '}' { $$ = '}'; } |
| '.' { $$ = '.'; } |
| '&' { $$ = '&'; } |
| '*' { $$ = '*'; } |
| '+' { $$ = '+'; } |
| '-' { $$ = '-'; } |
| '~' { $$ = '~'; } |
| '!' { $$ = '!'; } |
| '/' { $$ = '/'; } |
| '%' { $$ = '%'; } |
| LEFT_SHIFT { $$ = LEFT_SHIFT; } |
| RIGHT_SHIFT { $$ = RIGHT_SHIFT; } |
| '<' { $$ = '<'; } |
| '>' { $$ = '>'; } |
| LESS_OR_EQUAL { $$ = LESS_OR_EQUAL; } |
| GREATER_OR_EQUAL { $$ = GREATER_OR_EQUAL; } |
| EQUAL { $$ = EQUAL; } |
| NOT_EQUAL { $$ = NOT_EQUAL; } |
| '^' { $$ = '^'; } |
| '|' { $$ = '|'; } |
| AND { $$ = AND; } |
| OR { $$ = OR; } |
| ';' { $$ = ';'; } |
| ',' { $$ = ','; } |
| '=' { $$ = '='; } |
| PASTE { $$ = PASTE; } |
| PLUS_PLUS { $$ = PLUS_PLUS; } |
| MINUS_MINUS { $$ = MINUS_MINUS; } |
; |
%% |
string_list_t * |
_string_list_create (void *ctx) |
{ |
string_list_t *list; |
list = ralloc (ctx, string_list_t); |
list->head = NULL; |
list->tail = NULL; |
return list; |
} |
void |
_string_list_append_item (string_list_t *list, const char *str) |
{ |
string_node_t *node; |
node = ralloc (list, string_node_t); |
node->str = ralloc_strdup (node, str); |
node->next = NULL; |
if (list->head == NULL) { |
list->head = node; |
} else { |
list->tail->next = node; |
} |
list->tail = node; |
} |
int |
_string_list_contains (string_list_t *list, const char *member, int *index) |
{ |
string_node_t *node; |
int i; |
if (list == NULL) |
return 0; |
for (i = 0, node = list->head; node; i++, node = node->next) { |
if (strcmp (node->str, member) == 0) { |
if (index) |
*index = i; |
return 1; |
} |
} |
return 0; |
} |
/* Return duplicate string in list (if any), NULL otherwise. */ |
const char * |
_string_list_has_duplicate (string_list_t *list) |
{ |
string_node_t *node, *dup; |
if (list == NULL) |
return NULL; |
for (node = list->head; node; node = node->next) { |
for (dup = node->next; dup; dup = dup->next) { |
if (strcmp (node->str, dup->str) == 0) |
return node->str; |
} |
} |
return NULL; |
} |
int |
_string_list_length (string_list_t *list) |
{ |
int length = 0; |
string_node_t *node; |
if (list == NULL) |
return 0; |
for (node = list->head; node; node = node->next) |
length++; |
return length; |
} |
int |
_string_list_equal (string_list_t *a, string_list_t *b) |
{ |
string_node_t *node_a, *node_b; |
if (a == NULL && b == NULL) |
return 1; |
if (a == NULL || b == NULL) |
return 0; |
for (node_a = a->head, node_b = b->head; |
node_a && node_b; |
node_a = node_a->next, node_b = node_b->next) |
{ |
if (strcmp (node_a->str, node_b->str)) |
return 0; |
} |
/* Catch the case of lists being different lengths, (which |
* would cause the loop above to terminate after the shorter |
* list). */ |
return node_a == node_b; |
} |
argument_list_t * |
_argument_list_create (void *ctx) |
{ |
argument_list_t *list; |
list = ralloc (ctx, argument_list_t); |
list->head = NULL; |
list->tail = NULL; |
return list; |
} |
void |
_argument_list_append (argument_list_t *list, token_list_t *argument) |
{ |
argument_node_t *node; |
node = ralloc (list, argument_node_t); |
node->argument = argument; |
node->next = NULL; |
if (list->head == NULL) { |
list->head = node; |
} else { |
list->tail->next = node; |
} |
list->tail = node; |
} |
int |
_argument_list_length (argument_list_t *list) |
{ |
int length = 0; |
argument_node_t *node; |
if (list == NULL) |
return 0; |
for (node = list->head; node; node = node->next) |
length++; |
return length; |
} |
token_list_t * |
_argument_list_member_at (argument_list_t *list, int index) |
{ |
argument_node_t *node; |
int i; |
if (list == NULL) |
return NULL; |
node = list->head; |
for (i = 0; i < index; i++) { |
node = node->next; |
if (node == NULL) |
break; |
} |
if (node) |
return node->argument; |
return NULL; |
} |
/* Note: This function ralloc_steal()s the str pointer. */ |
token_t * |
_token_create_str (void *ctx, int type, char *str) |
{ |
token_t *token; |
token = ralloc (ctx, token_t); |
token->type = type; |
token->value.str = str; |
ralloc_steal (token, str); |
return token; |
} |
token_t * |
_token_create_ival (void *ctx, int type, int ival) |
{ |
token_t *token; |
token = ralloc (ctx, token_t); |
token->type = type; |
token->value.ival = ival; |
return token; |
} |
token_list_t * |
_token_list_create (void *ctx) |
{ |
token_list_t *list; |
list = ralloc (ctx, token_list_t); |
list->head = NULL; |
list->tail = NULL; |
list->non_space_tail = NULL; |
return list; |
} |
void |
_token_list_append (token_list_t *list, token_t *token) |
{ |
token_node_t *node; |
node = ralloc (list, token_node_t); |
node->token = token; |
node->next = NULL; |
if (list->head == NULL) { |
list->head = node; |
} else { |
list->tail->next = node; |
} |
list->tail = node; |
if (token->type != SPACE) |
list->non_space_tail = node; |
} |
void |
_token_list_append_list (token_list_t *list, token_list_t *tail) |
{ |
if (tail == NULL || tail->head == NULL) |
return; |
if (list->head == NULL) { |
list->head = tail->head; |
} else { |
list->tail->next = tail->head; |
} |
list->tail = tail->tail; |
list->non_space_tail = tail->non_space_tail; |
} |
static token_list_t * |
_token_list_copy (void *ctx, token_list_t *other) |
{ |
token_list_t *copy; |
token_node_t *node; |
if (other == NULL) |
return NULL; |
copy = _token_list_create (ctx); |
for (node = other->head; node; node = node->next) { |
token_t *new_token = ralloc (copy, token_t); |
*new_token = *node->token; |
_token_list_append (copy, new_token); |
} |
return copy; |
} |
static void |
_token_list_trim_trailing_space (token_list_t *list) |
{ |
token_node_t *tail, *next; |
if (list->non_space_tail) { |
tail = list->non_space_tail->next; |
list->non_space_tail->next = NULL; |
list->tail = list->non_space_tail; |
while (tail) { |
next = tail->next; |
ralloc_free (tail); |
tail = next; |
} |
} |
} |
static int |
_token_list_is_empty_ignoring_space (token_list_t *l) |
{ |
token_node_t *n; |
if (l == NULL) |
return 1; |
n = l->head; |
while (n != NULL && n->token->type == SPACE) |
n = n->next; |
return n == NULL; |
} |
int |
_token_list_equal_ignoring_space (token_list_t *a, token_list_t *b) |
{ |
token_node_t *node_a, *node_b; |
if (a == NULL || b == NULL) { |
int a_empty = _token_list_is_empty_ignoring_space(a); |
int b_empty = _token_list_is_empty_ignoring_space(b); |
return a_empty == b_empty; |
} |
node_a = a->head; |
node_b = b->head; |
while (1) |
{ |
if (node_a == NULL && node_b == NULL) |
break; |
if (node_a == NULL || node_b == NULL) |
return 0; |
/* Make sure whitespace appears in the same places in both. |
* It need not be exactly the same amount of whitespace, |
* though. |
*/ |
if (node_a->token->type == SPACE |
&& node_b->token->type == SPACE) { |
while (node_a->token->type == SPACE) |
node_a = node_a->next; |
while (node_b->token->type == SPACE) |
node_b = node_b->next; |
continue; |
} |
if (node_a->token->type != node_b->token->type) |
return 0; |
switch (node_a->token->type) { |
case INTEGER: |
if (node_a->token->value.ival != |
node_b->token->value.ival) |
{ |
return 0; |
} |
break; |
case IDENTIFIER: |
case INTEGER_STRING: |
case OTHER: |
if (strcmp (node_a->token->value.str, |
node_b->token->value.str)) |
{ |
return 0; |
} |
break; |
} |
node_a = node_a->next; |
node_b = node_b->next; |
} |
return 1; |
} |
static void |
_token_print (char **out, size_t *len, token_t *token) |
{ |
if (token->type < 256) { |
ralloc_asprintf_rewrite_tail (out, len, "%c", token->type); |
return; |
} |
switch (token->type) { |
case INTEGER: |
ralloc_asprintf_rewrite_tail (out, len, "%" PRIiMAX, token->value.ival); |
break; |
case IDENTIFIER: |
case INTEGER_STRING: |
case OTHER: |
ralloc_asprintf_rewrite_tail (out, len, "%s", token->value.str); |
break; |
case SPACE: |
ralloc_asprintf_rewrite_tail (out, len, " "); |
break; |
case LEFT_SHIFT: |
ralloc_asprintf_rewrite_tail (out, len, "<<"); |
break; |
case RIGHT_SHIFT: |
ralloc_asprintf_rewrite_tail (out, len, ">>"); |
break; |
case LESS_OR_EQUAL: |
ralloc_asprintf_rewrite_tail (out, len, "<="); |
break; |
case GREATER_OR_EQUAL: |
ralloc_asprintf_rewrite_tail (out, len, ">="); |
break; |
case EQUAL: |
ralloc_asprintf_rewrite_tail (out, len, "=="); |
break; |
case NOT_EQUAL: |
ralloc_asprintf_rewrite_tail (out, len, "!="); |
break; |
case AND: |
ralloc_asprintf_rewrite_tail (out, len, "&&"); |
break; |
case OR: |
ralloc_asprintf_rewrite_tail (out, len, "||"); |
break; |
case PASTE: |
ralloc_asprintf_rewrite_tail (out, len, "##"); |
break; |
case PLUS_PLUS: |
ralloc_asprintf_rewrite_tail (out, len, "++"); |
break; |
case MINUS_MINUS: |
ralloc_asprintf_rewrite_tail (out, len, "--"); |
break; |
case DEFINED: |
ralloc_asprintf_rewrite_tail (out, len, "defined"); |
break; |
case PLACEHOLDER: |
/* Nothing to print. */ |
break; |
default: |
assert(!"Error: Don't know how to print token."); |
break; |
} |
} |
/* Return a new token (ralloc()ed off of 'token') formed by pasting |
* 'token' and 'other'. Note that this function may return 'token' or |
* 'other' directly rather than allocating anything new. |
* |
* Caution: Only very cursory error-checking is performed to see if |
* the final result is a valid single token. */ |
static token_t * |
_token_paste (glcpp_parser_t *parser, token_t *token, token_t *other) |
{ |
token_t *combined = NULL; |
/* Pasting a placeholder onto anything makes no change. */ |
if (other->type == PLACEHOLDER) |
return token; |
/* When 'token' is a placeholder, just return 'other'. */ |
if (token->type == PLACEHOLDER) |
return other; |
/* A very few single-character punctuators can be combined |
* with another to form a multi-character punctuator. */ |
switch (token->type) { |
case '<': |
if (other->type == '<') |
combined = _token_create_ival (token, LEFT_SHIFT, LEFT_SHIFT); |
else if (other->type == '=') |
combined = _token_create_ival (token, LESS_OR_EQUAL, LESS_OR_EQUAL); |
break; |
case '>': |
if (other->type == '>') |
combined = _token_create_ival (token, RIGHT_SHIFT, RIGHT_SHIFT); |
else if (other->type == '=') |
combined = _token_create_ival (token, GREATER_OR_EQUAL, GREATER_OR_EQUAL); |
break; |
case '=': |
if (other->type == '=') |
combined = _token_create_ival (token, EQUAL, EQUAL); |
break; |
case '!': |
if (other->type == '=') |
combined = _token_create_ival (token, NOT_EQUAL, NOT_EQUAL); |
break; |
case '&': |
if (other->type == '&') |
combined = _token_create_ival (token, AND, AND); |
break; |
case '|': |
if (other->type == '|') |
combined = _token_create_ival (token, OR, OR); |
break; |
} |
if (combined != NULL) { |
/* Inherit the location from the first token */ |
combined->location = token->location; |
return combined; |
} |
/* Two string-valued (or integer) tokens can usually just be |
* mashed together. (We also handle a string followed by an |
* integer here as well.) |
* |
* There are some exceptions here. Notably, if the first token |
* is an integer (or a string representing an integer), then |
* the second token must also be an integer or must be a |
* string representing an integer that begins with a digit. |
*/ |
if ((token->type == IDENTIFIER || token->type == OTHER || token->type == INTEGER_STRING || token->type == INTEGER) && |
(other->type == IDENTIFIER || other->type == OTHER || other->type == INTEGER_STRING || other->type == INTEGER)) |
{ |
char *str; |
int combined_type; |
/* Check that pasting onto an integer doesn't create a |
* non-integer, (that is, only digits can be |
* pasted. */ |
if (token->type == INTEGER_STRING || token->type == INTEGER) |
{ |
switch (other->type) { |
case INTEGER_STRING: |
if (other->value.str[0] < '0' || |
other->value.str[0] > '9') |
goto FAIL; |
break; |
case INTEGER: |
if (other->value.ival < 0) |
goto FAIL; |
break; |
default: |
goto FAIL; |
} |
} |
if (token->type == INTEGER) |
str = ralloc_asprintf (token, "%" PRIiMAX, |
token->value.ival); |
else |
str = ralloc_strdup (token, token->value.str); |
if (other->type == INTEGER) |
ralloc_asprintf_append (&str, "%" PRIiMAX, |
other->value.ival); |
else |
ralloc_strcat (&str, other->value.str); |
/* New token is same type as original token, unless we |
* started with an integer, in which case we will be |
* creating an integer-string. */ |
combined_type = token->type; |
if (combined_type == INTEGER) |
combined_type = INTEGER_STRING; |
combined = _token_create_str (token, combined_type, str); |
combined->location = token->location; |
return combined; |
} |
FAIL: |
glcpp_error (&token->location, parser, ""); |
ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "Pasting \""); |
_token_print (&parser->info_log, &parser->info_log_length, token); |
ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "\" and \""); |
_token_print (&parser->info_log, &parser->info_log_length, other); |
ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "\" does not give a valid preprocessing token.\n"); |
return token; |
} |
static void |
_token_list_print (glcpp_parser_t *parser, token_list_t *list) |
{ |
token_node_t *node; |
if (list == NULL) |
return; |
for (node = list->head; node; node = node->next) |
_token_print (&parser->output, &parser->output_length, node->token); |
} |
void |
yyerror (YYLTYPE *locp, glcpp_parser_t *parser, const char *error) |
{ |
glcpp_error(locp, parser, "%s", error); |
} |
static void add_builtin_define(glcpp_parser_t *parser, |
const char *name, int value) |
{ |
token_t *tok; |
token_list_t *list; |
tok = _token_create_ival (parser, INTEGER, value); |
list = _token_list_create(parser); |
_token_list_append(list, tok); |
_define_object_macro(parser, NULL, name, list); |
} |
glcpp_parser_t * |
glcpp_parser_create (const struct gl_extensions *extensions, gl_api api) |
{ |
glcpp_parser_t *parser; |
parser = ralloc (NULL, glcpp_parser_t); |
glcpp_lex_init_extra (parser, &parser->scanner); |
parser->defines = hash_table_ctor (32, hash_table_string_hash, |
hash_table_string_compare); |
parser->active = NULL; |
parser->lexing_directive = 0; |
parser->space_tokens = 1; |
parser->last_token_was_newline = 0; |
parser->last_token_was_space = 0; |
parser->first_non_space_token_this_line = 1; |
parser->newline_as_space = 0; |
parser->in_control_line = 0; |
parser->paren_count = 0; |
parser->commented_newlines = 0; |
parser->skip_stack = NULL; |
parser->skipping = 0; |
parser->lex_from_list = NULL; |
parser->lex_from_node = NULL; |
parser->output = ralloc_strdup(parser, ""); |
parser->output_length = 0; |
parser->info_log = ralloc_strdup(parser, ""); |
parser->info_log_length = 0; |
parser->error = 0; |
parser->extensions = extensions; |
parser->api = api; |
parser->version_resolved = false; |
parser->has_new_line_number = 0; |
parser->new_line_number = 1; |
parser->has_new_source_number = 0; |
parser->new_source_number = 0; |
return parser; |
} |
void |
glcpp_parser_destroy (glcpp_parser_t *parser) |
{ |
glcpp_lex_destroy (parser->scanner); |
hash_table_dtor (parser->defines); |
ralloc_free (parser); |
} |
typedef enum function_status |
{ |
FUNCTION_STATUS_SUCCESS, |
FUNCTION_NOT_A_FUNCTION, |
FUNCTION_UNBALANCED_PARENTHESES |
} function_status_t; |
/* Find a set of function-like macro arguments by looking for a |
* balanced set of parentheses. |
* |
* When called, 'node' should be the opening-parenthesis token, (or |
* perhaps preceeding SPACE tokens). Upon successful return *last will |
* be the last consumed node, (corresponding to the closing right |
* parenthesis). |
* |
* Return values: |
* |
* FUNCTION_STATUS_SUCCESS: |
* |
* Successfully parsed a set of function arguments. |
* |
* FUNCTION_NOT_A_FUNCTION: |
* |
* Macro name not followed by a '('. This is not an error, but |
* simply that the macro name should be treated as a non-macro. |
* |
* FUNCTION_UNBALANCED_PARENTHESES |
* |
* Macro name is not followed by a balanced set of parentheses. |
*/ |
static function_status_t |
_arguments_parse (argument_list_t *arguments, |
token_node_t *node, |
token_node_t **last) |
{ |
token_list_t *argument; |
int paren_count; |
node = node->next; |
/* Ignore whitespace before first parenthesis. */ |
while (node && node->token->type == SPACE) |
node = node->next; |
if (node == NULL || node->token->type != '(') |
return FUNCTION_NOT_A_FUNCTION; |
node = node->next; |
argument = _token_list_create (arguments); |
_argument_list_append (arguments, argument); |
for (paren_count = 1; node; node = node->next) { |
if (node->token->type == '(') |
{ |
paren_count++; |
} |
else if (node->token->type == ')') |
{ |
paren_count--; |
if (paren_count == 0) |
break; |
} |
if (node->token->type == ',' && |
paren_count == 1) |
{ |
_token_list_trim_trailing_space (argument); |
argument = _token_list_create (arguments); |
_argument_list_append (arguments, argument); |
} |
else { |
if (argument->head == NULL) { |
/* Don't treat initial whitespace as |
* part of the argument. */ |
if (node->token->type == SPACE) |
continue; |
} |
_token_list_append (argument, node->token); |
} |
} |
if (paren_count) |
return FUNCTION_UNBALANCED_PARENTHESES; |
*last = node; |
return FUNCTION_STATUS_SUCCESS; |
} |
static token_list_t * |
_token_list_create_with_one_ival (void *ctx, int type, int ival) |
{ |
token_list_t *list; |
token_t *node; |
list = _token_list_create (ctx); |
node = _token_create_ival (list, type, ival); |
_token_list_append (list, node); |
return list; |
} |
static token_list_t * |
_token_list_create_with_one_space (void *ctx) |
{ |
return _token_list_create_with_one_ival (ctx, SPACE, SPACE); |
} |
static token_list_t * |
_token_list_create_with_one_integer (void *ctx, int ival) |
{ |
return _token_list_create_with_one_ival (ctx, INTEGER, ival); |
} |
/* Evaluate a DEFINED token node (based on subsequent tokens in the list). |
* |
* Note: This function must only be called when "node" is a DEFINED token, |
* (and will abort with an assertion failure otherwise). |
* |
* If "node" is followed, (ignoring any SPACE tokens), by an IDENTIFIER token |
* (optionally preceded and followed by '(' and ')' tokens) then the following |
* occurs: |
* |
* If the identifier is a defined macro, this function returns 1. |
* |
* If the identifier is not a defined macro, this function returns 0. |
* |
* In either case, *last will be updated to the last node in the list |
* consumed by the evaluation, (either the token of the identifier or the |
* token of the closing parenthesis). |
* |
* In all other cases, (such as "node is the final node of the list", or |
* "missing closing parenthesis", etc.), this function generates a |
* preprocessor error, returns -1 and *last will not be set. |
*/ |
static int |
_glcpp_parser_evaluate_defined (glcpp_parser_t *parser, |
token_node_t *node, |
token_node_t **last) |
{ |
token_node_t *argument, *defined = node; |
assert (node->token->type == DEFINED); |
node = node->next; |
/* Ignore whitespace after DEFINED token. */ |
while (node && node->token->type == SPACE) |
node = node->next; |
if (node == NULL) |
goto FAIL; |
if (node->token->type == IDENTIFIER || node->token->type == OTHER) { |
argument = node; |
} else if (node->token->type == '(') { |
node = node->next; |
/* Ignore whitespace after '(' token. */ |
while (node && node->token->type == SPACE) |
node = node->next; |
if (node == NULL || (node->token->type != IDENTIFIER && |
node->token->type != OTHER)) |
{ |
goto FAIL; |
} |
argument = node; |
node = node->next; |
/* Ignore whitespace after identifier, before ')' token. */ |
while (node && node->token->type == SPACE) |
node = node->next; |
if (node == NULL || node->token->type != ')') |
goto FAIL; |
} else { |
goto FAIL; |
} |
*last = node; |
return hash_table_find (parser->defines, |
argument->token->value.str) ? 1 : 0; |
FAIL: |
glcpp_error (&defined->token->location, parser, |
"\"defined\" not followed by an identifier"); |
return -1; |
} |
/* Evaluate all DEFINED nodes in a given list, modifying the list in place. |
*/ |
static void |
_glcpp_parser_evaluate_defined_in_list (glcpp_parser_t *parser, |
token_list_t *list) |
{ |
token_node_t *node, *node_prev, *replacement, *last = NULL; |
int value; |
if (list == NULL) |
return; |
node_prev = NULL; |
node = list->head; |
while (node) { |
if (node->token->type != DEFINED) |
goto NEXT; |
value = _glcpp_parser_evaluate_defined (parser, node, &last); |
if (value == -1) |
goto NEXT; |
replacement = ralloc (list, token_node_t); |
replacement->token = _token_create_ival (list, INTEGER, value); |
/* Splice replacement node into list, replacing from "node" |
* through "last". */ |
if (node_prev) |
node_prev->next = replacement; |
else |
list->head = replacement; |
replacement->next = last->next; |
if (last == list->tail) |
list->tail = replacement; |
node = replacement; |
NEXT: |
node_prev = node; |
node = node->next; |
} |
} |
/* Perform macro expansion on 'list', placing the resulting tokens |
* into a new list which is initialized with a first token of type |
* 'head_token_type'. Then begin lexing from the resulting list, |
* (return to the current lexing source when this list is exhausted). |
* |
* See the documentation of _glcpp_parser_expand_token_list for a description |
* of the "mode" parameter. |
*/ |
static void |
_glcpp_parser_expand_and_lex_from (glcpp_parser_t *parser, |
int head_token_type, |
token_list_t *list, |
expansion_mode_t mode) |
{ |
token_list_t *expanded; |
token_t *token; |
expanded = _token_list_create (parser); |
token = _token_create_ival (parser, head_token_type, head_token_type); |
_token_list_append (expanded, token); |
_glcpp_parser_expand_token_list (parser, list, mode); |
_token_list_append_list (expanded, list); |
glcpp_parser_lex_from (parser, expanded); |
} |
static void |
_glcpp_parser_apply_pastes (glcpp_parser_t *parser, token_list_t *list) |
{ |
token_node_t *node; |
node = list->head; |
while (node) |
{ |
token_node_t *next_non_space; |
/* Look ahead for a PASTE token, skipping space. */ |
next_non_space = node->next; |
while (next_non_space && next_non_space->token->type == SPACE) |
next_non_space = next_non_space->next; |
if (next_non_space == NULL) |
break; |
if (next_non_space->token->type != PASTE) { |
node = next_non_space; |
continue; |
} |
/* Now find the next non-space token after the PASTE. */ |
next_non_space = next_non_space->next; |
while (next_non_space && next_non_space->token->type == SPACE) |
next_non_space = next_non_space->next; |
if (next_non_space == NULL) { |
yyerror (&node->token->location, parser, "'##' cannot appear at either end of a macro expansion\n"); |
return; |
} |
node->token = _token_paste (parser, node->token, next_non_space->token); |
node->next = next_non_space->next; |
if (next_non_space == list->tail) |
list->tail = node; |
} |
list->non_space_tail = list->tail; |
} |
/* This is a helper function that's essentially part of the |
* implementation of _glcpp_parser_expand_node. It shouldn't be called |
* except for by that function. |
* |
* Returns NULL if node is a simple token with no expansion, (that is, |
* although 'node' corresponds to an identifier defined as a |
* function-like macro, it is not followed with a parenthesized |
* argument list). |
* |
* Compute the complete expansion of node (which is a function-like |
* macro) and subsequent nodes which are arguments. |
* |
* Returns the token list that results from the expansion and sets |
* *last to the last node in the list that was consumed by the |
* expansion. Specifically, *last will be set as follows: as the |
* token of the closing right parenthesis. |
* |
* See the documentation of _glcpp_parser_expand_token_list for a description |
* of the "mode" parameter. |
*/ |
static token_list_t * |
_glcpp_parser_expand_function (glcpp_parser_t *parser, |
token_node_t *node, |
token_node_t **last, |
expansion_mode_t mode) |
{ |
macro_t *macro; |
const char *identifier; |
argument_list_t *arguments; |
function_status_t status; |
token_list_t *substituted; |
int parameter_index; |
identifier = node->token->value.str; |
macro = hash_table_find (parser->defines, identifier); |
assert (macro->is_function); |
arguments = _argument_list_create (parser); |
status = _arguments_parse (arguments, node, last); |
switch (status) { |
case FUNCTION_STATUS_SUCCESS: |
break; |
case FUNCTION_NOT_A_FUNCTION: |
return NULL; |
case FUNCTION_UNBALANCED_PARENTHESES: |
glcpp_error (&node->token->location, parser, "Macro %s call has unbalanced parentheses\n", identifier); |
return NULL; |
} |
/* Replace a macro defined as empty with a SPACE token. */ |
if (macro->replacements == NULL) { |
ralloc_free (arguments); |
return _token_list_create_with_one_space (parser); |
} |
if (! ((_argument_list_length (arguments) == |
_string_list_length (macro->parameters)) || |
(_string_list_length (macro->parameters) == 0 && |
_argument_list_length (arguments) == 1 && |
arguments->head->argument->head == NULL))) |
{ |
glcpp_error (&node->token->location, parser, |
"Error: macro %s invoked with %d arguments (expected %d)\n", |
identifier, |
_argument_list_length (arguments), |
_string_list_length (macro->parameters)); |
return NULL; |
} |
/* Perform argument substitution on the replacement list. */ |
substituted = _token_list_create (arguments); |
for (node = macro->replacements->head; node; node = node->next) |
{ |
if (node->token->type == IDENTIFIER && |
_string_list_contains (macro->parameters, |
node->token->value.str, |
¶meter_index)) |
{ |
token_list_t *argument; |
argument = _argument_list_member_at (arguments, |
parameter_index); |
/* Before substituting, we expand the argument |
* tokens, or append a placeholder token for |
* an empty argument. */ |
if (argument->head) { |
token_list_t *expanded_argument; |
expanded_argument = _token_list_copy (parser, |
argument); |
_glcpp_parser_expand_token_list (parser, |
expanded_argument, |
mode); |
_token_list_append_list (substituted, |
expanded_argument); |
} else { |
token_t *new_token; |
new_token = _token_create_ival (substituted, |
PLACEHOLDER, |
PLACEHOLDER); |
_token_list_append (substituted, new_token); |
} |
} else { |
_token_list_append (substituted, node->token); |
} |
} |
/* After argument substitution, and before further expansion |
* below, implement token pasting. */ |
_token_list_trim_trailing_space (substituted); |
_glcpp_parser_apply_pastes (parser, substituted); |
return substituted; |
} |
/* Compute the complete expansion of node, (and subsequent nodes after |
* 'node' in the case that 'node' is a function-like macro and |
* subsequent nodes are arguments). |
* |
* Returns NULL if node is a simple token with no expansion. |
* |
* Otherwise, returns the token list that results from the expansion |
* and sets *last to the last node in the list that was consumed by |
* the expansion. Specifically, *last will be set as follows: |
* |
* As 'node' in the case of object-like macro expansion. |
* |
* As the token of the closing right parenthesis in the case of |
* function-like macro expansion. |
* |
* See the documentation of _glcpp_parser_expand_token_list for a description |
* of the "mode" parameter. |
*/ |
static token_list_t * |
_glcpp_parser_expand_node (glcpp_parser_t *parser, |
token_node_t *node, |
token_node_t **last, |
expansion_mode_t mode) |
{ |
token_t *token = node->token; |
const char *identifier; |
macro_t *macro; |
/* We only expand identifiers */ |
if (token->type != IDENTIFIER) { |
return NULL; |
} |
*last = node; |
identifier = token->value.str; |
/* Special handling for __LINE__ and __FILE__, (not through |
* the hash table). */ |
if (strcmp(identifier, "__LINE__") == 0) |
return _token_list_create_with_one_integer (parser, node->token->location.first_line); |
if (strcmp(identifier, "__FILE__") == 0) |
return _token_list_create_with_one_integer (parser, node->token->location.source); |
/* Look up this identifier in the hash table. */ |
macro = hash_table_find (parser->defines, identifier); |
/* Not a macro, so no expansion needed. */ |
if (macro == NULL) |
return NULL; |
/* Finally, don't expand this macro if we're already actively |
* expanding it, (to avoid infinite recursion). */ |
if (_parser_active_list_contains (parser, identifier)) { |
/* We change the token type here from IDENTIFIER to |
* OTHER to prevent any future expansion of this |
* unexpanded token. */ |
char *str; |
token_list_t *expansion; |
token_t *final; |
str = ralloc_strdup (parser, token->value.str); |
final = _token_create_str (parser, OTHER, str); |
expansion = _token_list_create (parser); |
_token_list_append (expansion, final); |
return expansion; |
} |
if (! macro->is_function) |
{ |
token_list_t *replacement; |
/* Replace a macro defined as empty with a SPACE token. */ |
if (macro->replacements == NULL) |
return _token_list_create_with_one_space (parser); |
replacement = _token_list_copy (parser, macro->replacements); |
_glcpp_parser_apply_pastes (parser, replacement); |
return replacement; |
} |
return _glcpp_parser_expand_function (parser, node, last, mode); |
} |
/* Push a new identifier onto the parser's active list. |
* |
* Here, 'marker' is the token node that appears in the list after the |
* expansion of 'identifier'. That is, when the list iterator begins |
* examining 'marker', then it is time to pop this node from the |
* active stack. |
*/ |
static void |
_parser_active_list_push (glcpp_parser_t *parser, |
const char *identifier, |
token_node_t *marker) |
{ |
active_list_t *node; |
node = ralloc (parser->active, active_list_t); |
node->identifier = ralloc_strdup (node, identifier); |
node->marker = marker; |
node->next = parser->active; |
parser->active = node; |
} |
static void |
_parser_active_list_pop (glcpp_parser_t *parser) |
{ |
active_list_t *node = parser->active; |
if (node == NULL) { |
parser->active = NULL; |
return; |
} |
node = parser->active->next; |
ralloc_free (parser->active); |
parser->active = node; |
} |
static int |
_parser_active_list_contains (glcpp_parser_t *parser, const char *identifier) |
{ |
active_list_t *node; |
if (parser->active == NULL) |
return 0; |
for (node = parser->active; node; node = node->next) |
if (strcmp (node->identifier, identifier) == 0) |
return 1; |
return 0; |
} |
/* Walk over the token list replacing nodes with their expansion. |
* Whenever nodes are expanded the walking will walk over the new |
* nodes, continuing to expand as necessary. The results are placed in |
* 'list' itself. |
* |
* The "mode" argument controls the handling of any DEFINED tokens that |
* result from expansion as follows: |
* |
* EXPANSION_MODE_IGNORE_DEFINED: Any resulting DEFINED tokens will be |
* left in the final list, unevaluated. This is the correct mode |
* for expanding any list in any context other than a |
* preprocessor conditional, (#if or #elif). |
* |
* EXPANSION_MODE_EVALUATE_DEFINED: Any resulting DEFINED tokens will be |
* evaluated to 0 or 1 tokens depending on whether the following |
* token is the name of a defined macro. If the DEFINED token is |
* not followed by an (optionally parenthesized) identifier, then |
* an error will be generated. This the correct mode for |
* expanding any list in the context of a preprocessor |
* conditional, (#if or #elif). |
*/ |
static void |
_glcpp_parser_expand_token_list (glcpp_parser_t *parser, |
token_list_t *list, |
expansion_mode_t mode) |
{ |
token_node_t *node_prev; |
token_node_t *node, *last = NULL; |
token_list_t *expansion; |
active_list_t *active_initial = parser->active; |
if (list == NULL) |
return; |
_token_list_trim_trailing_space (list); |
node_prev = NULL; |
node = list->head; |
if (mode == EXPANSION_MODE_EVALUATE_DEFINED) |
_glcpp_parser_evaluate_defined_in_list (parser, list); |
while (node) { |
while (parser->active && parser->active->marker == node) |
_parser_active_list_pop (parser); |
expansion = _glcpp_parser_expand_node (parser, node, &last, mode); |
if (expansion) { |
token_node_t *n; |
if (mode == EXPANSION_MODE_EVALUATE_DEFINED) { |
_glcpp_parser_evaluate_defined_in_list (parser, |
expansion); |
} |
for (n = node; n != last->next; n = n->next) |
while (parser->active && |
parser->active->marker == n) |
{ |
_parser_active_list_pop (parser); |
} |
_parser_active_list_push (parser, |
node->token->value.str, |
last->next); |
/* Splice expansion into list, supporting a |
* simple deletion if the expansion is |
* empty. */ |
if (expansion->head) { |
if (node_prev) |
node_prev->next = expansion->head; |
else |
list->head = expansion->head; |
expansion->tail->next = last->next; |
if (last == list->tail) |
list->tail = expansion->tail; |
} else { |
if (node_prev) |
node_prev->next = last->next; |
else |
list->head = last->next; |
if (last == list->tail) |
list->tail = NULL; |
} |
} else { |
node_prev = node; |
} |
node = node_prev ? node_prev->next : list->head; |
} |
/* Remove any lingering effects of this invocation on the |
* active list. That is, pop until the list looks like it did |
* at the beginning of this function. */ |
while (parser->active && parser->active != active_initial) |
_parser_active_list_pop (parser); |
list->non_space_tail = list->tail; |
} |
void |
_glcpp_parser_print_expanded_token_list (glcpp_parser_t *parser, |
token_list_t *list) |
{ |
if (list == NULL) |
return; |
_glcpp_parser_expand_token_list (parser, list, EXPANSION_MODE_IGNORE_DEFINED); |
_token_list_trim_trailing_space (list); |
_token_list_print (parser, list); |
} |
static void |
_check_for_reserved_macro_name (glcpp_parser_t *parser, YYLTYPE *loc, |
const char *identifier) |
{ |
/* Section 3.3 (Preprocessor) of the GLSL 1.30 spec (and later) and |
* the GLSL ES spec (all versions) say: |
* |
* "All macro names containing two consecutive underscores ( __ ) |
* are reserved for future use as predefined macro names. All |
* macro names prefixed with "GL_" ("GL" followed by a single |
* underscore) are also reserved." |
* |
* The intention is that names containing __ are reserved for internal |
* use by the implementation, and names prefixed with GL_ are reserved |
* for use by Khronos. Since every extension adds a name prefixed |
* with GL_ (i.e., the name of the extension), that should be an |
* error. Names simply containing __ are dangerous to use, but should |
* be allowed. |
* |
* A future version of the GLSL specification will clarify this. |
*/ |
if (strstr(identifier, "__")) { |
glcpp_warning(loc, parser, |
"Macro names containing \"__\" are reserved " |
"for use by the implementation.\n"); |
} |
if (strncmp(identifier, "GL_", 3) == 0) { |
glcpp_error (loc, parser, "Macro names starting with \"GL_\" are reserved.\n"); |
} |
} |
static int |
_macro_equal (macro_t *a, macro_t *b) |
{ |
if (a->is_function != b->is_function) |
return 0; |
if (a->is_function) { |
if (! _string_list_equal (a->parameters, b->parameters)) |
return 0; |
} |
return _token_list_equal_ignoring_space (a->replacements, |
b->replacements); |
} |
void |
_define_object_macro (glcpp_parser_t *parser, |
YYLTYPE *loc, |
const char *identifier, |
token_list_t *replacements) |
{ |
macro_t *macro, *previous; |
/* We define pre-defined macros before we've started parsing the |
* actual file. So if there's no location defined yet, that's what |
* were doing and we don't want to generate an error for using the |
* reserved names. */ |
if (loc != NULL) |
_check_for_reserved_macro_name(parser, loc, identifier); |
macro = ralloc (parser, macro_t); |
macro->is_function = 0; |
macro->parameters = NULL; |
macro->identifier = ralloc_strdup (macro, identifier); |
macro->replacements = replacements; |
ralloc_steal (macro, replacements); |
previous = hash_table_find (parser->defines, identifier); |
if (previous) { |
if (_macro_equal (macro, previous)) { |
ralloc_free (macro); |
return; |
} |
glcpp_error (loc, parser, "Redefinition of macro %s\n", |
identifier); |
} |
hash_table_insert (parser->defines, macro, identifier); |
} |
void |
_define_function_macro (glcpp_parser_t *parser, |
YYLTYPE *loc, |
const char *identifier, |
string_list_t *parameters, |
token_list_t *replacements) |
{ |
macro_t *macro, *previous; |
const char *dup; |
_check_for_reserved_macro_name(parser, loc, identifier); |
/* Check for any duplicate parameter names. */ |
if ((dup = _string_list_has_duplicate (parameters)) != NULL) { |
glcpp_error (loc, parser, "Duplicate macro parameter \"%s\"", |
dup); |
} |
macro = ralloc (parser, macro_t); |
ralloc_steal (macro, parameters); |
ralloc_steal (macro, replacements); |
macro->is_function = 1; |
macro->parameters = parameters; |
macro->identifier = ralloc_strdup (macro, identifier); |
macro->replacements = replacements; |
previous = hash_table_find (parser->defines, identifier); |
if (previous) { |
if (_macro_equal (macro, previous)) { |
ralloc_free (macro); |
return; |
} |
glcpp_error (loc, parser, "Redefinition of macro %s\n", |
identifier); |
} |
hash_table_insert (parser->defines, macro, identifier); |
} |
static int |
glcpp_parser_lex (YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser) |
{ |
token_node_t *node; |
int ret; |
if (parser->lex_from_list == NULL) { |
ret = glcpp_lex (yylval, yylloc, parser->scanner); |
/* XXX: This ugly block of code exists for the sole |
* purpose of converting a NEWLINE token into a SPACE |
* token, but only in the case where we have seen a |
* function-like macro name, but have not yet seen its |
* closing parenthesis. |
* |
* There's perhaps a more compact way to do this with |
* mid-rule actions in the grammar. |
* |
* I'm definitely not pleased with the complexity of |
* this code here. |
*/ |
if (parser->newline_as_space) |
{ |
if (ret == '(') { |
parser->paren_count++; |
} else if (ret == ')') { |
parser->paren_count--; |
if (parser->paren_count == 0) |
parser->newline_as_space = 0; |
} else if (ret == NEWLINE) { |
ret = SPACE; |
} else if (ret != SPACE) { |
if (parser->paren_count == 0) |
parser->newline_as_space = 0; |
} |
} |
else if (parser->in_control_line) |
{ |
if (ret == NEWLINE) |
parser->in_control_line = 0; |
} |
else if (ret == DEFINE_TOKEN || |
ret == UNDEF || ret == IF || |
ret == IFDEF || ret == IFNDEF || |
ret == ELIF || ret == ELSE || |
ret == ENDIF || ret == HASH_TOKEN) |
{ |
parser->in_control_line = 1; |
} |
else if (ret == IDENTIFIER) |
{ |
macro_t *macro; |
macro = hash_table_find (parser->defines, |
yylval->str); |
if (macro && macro->is_function) { |
parser->newline_as_space = 1; |
parser->paren_count = 0; |
} |
} |
return ret; |
} |
node = parser->lex_from_node; |
if (node == NULL) { |
ralloc_free (parser->lex_from_list); |
parser->lex_from_list = NULL; |
return NEWLINE; |
} |
*yylval = node->token->value; |
ret = node->token->type; |
parser->lex_from_node = node->next; |
return ret; |
} |
static void |
glcpp_parser_lex_from (glcpp_parser_t *parser, token_list_t *list) |
{ |
token_node_t *node; |
assert (parser->lex_from_list == NULL); |
/* Copy list, eliminating any space tokens. */ |
parser->lex_from_list = _token_list_create (parser); |
for (node = list->head; node; node = node->next) { |
if (node->token->type == SPACE) |
continue; |
_token_list_append (parser->lex_from_list, node->token); |
} |
ralloc_free (list); |
parser->lex_from_node = parser->lex_from_list->head; |
/* It's possible the list consisted of nothing but whitespace. */ |
if (parser->lex_from_node == NULL) { |
ralloc_free (parser->lex_from_list); |
parser->lex_from_list = NULL; |
} |
} |
static void |
_glcpp_parser_skip_stack_push_if (glcpp_parser_t *parser, YYLTYPE *loc, |
int condition) |
{ |
skip_type_t current = SKIP_NO_SKIP; |
skip_node_t *node; |
if (parser->skip_stack) |
current = parser->skip_stack->type; |
node = ralloc (parser, skip_node_t); |
node->loc = *loc; |
if (current == SKIP_NO_SKIP) { |
if (condition) |
node->type = SKIP_NO_SKIP; |
else |
node->type = SKIP_TO_ELSE; |
} else { |
node->type = SKIP_TO_ENDIF; |
} |
node->has_else = false; |
node->next = parser->skip_stack; |
parser->skip_stack = node; |
} |
static void |
_glcpp_parser_skip_stack_change_if (glcpp_parser_t *parser, YYLTYPE *loc, |
const char *type, int condition) |
{ |
if (parser->skip_stack == NULL) { |
glcpp_error (loc, parser, "#%s without #if\n", type); |
return; |
} |
if (parser->skip_stack->type == SKIP_TO_ELSE) { |
if (condition) |
parser->skip_stack->type = SKIP_NO_SKIP; |
} else { |
parser->skip_stack->type = SKIP_TO_ENDIF; |
} |
} |
static void |
_glcpp_parser_skip_stack_pop (glcpp_parser_t *parser, YYLTYPE *loc) |
{ |
skip_node_t *node; |
if (parser->skip_stack == NULL) { |
glcpp_error (loc, parser, "#endif without #if\n"); |
return; |
} |
node = parser->skip_stack; |
parser->skip_stack = node->next; |
ralloc_free (node); |
} |
static void |
_glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version, |
const char *es_identifier, |
bool explicitly_set) |
{ |
const struct gl_extensions *extensions = parser->extensions; |
if (parser->version_resolved) |
return; |
parser->version_resolved = true; |
add_builtin_define (parser, "__VERSION__", version); |
parser->is_gles = (version == 100) || |
(es_identifier && |
(strcmp(es_identifier, "es") == 0)); |
/* Add pre-defined macros. */ |
if (parser->is_gles) { |
add_builtin_define(parser, "GL_ES", 1); |
add_builtin_define(parser, "GL_EXT_separate_shader_objects", 1); |
add_builtin_define(parser, "GL_EXT_draw_buffers", 1); |
if (extensions != NULL) { |
if (extensions->OES_EGL_image_external) |
add_builtin_define(parser, "GL_OES_EGL_image_external", 1); |
if (extensions->OES_standard_derivatives) |
add_builtin_define(parser, "GL_OES_standard_derivatives", 1); |
} |
} else { |
add_builtin_define(parser, "GL_ARB_draw_buffers", 1); |
add_builtin_define(parser, "GL_ARB_separate_shader_objects", 1); |
add_builtin_define(parser, "GL_ARB_texture_rectangle", 1); |
add_builtin_define(parser, "GL_AMD_shader_trinary_minmax", 1); |
if (extensions != NULL) { |
if (extensions->EXT_texture_array) |
add_builtin_define(parser, "GL_EXT_texture_array", 1); |
if (extensions->ARB_arrays_of_arrays) |
add_builtin_define(parser, "GL_ARB_arrays_of_arrays", 1); |
if (extensions->ARB_fragment_coord_conventions) |
add_builtin_define(parser, "GL_ARB_fragment_coord_conventions", |
1); |
if (extensions->ARB_fragment_layer_viewport) |
add_builtin_define(parser, "GL_ARB_fragment_layer_viewport", 1); |
if (extensions->ARB_explicit_attrib_location) |
add_builtin_define(parser, "GL_ARB_explicit_attrib_location", 1); |
if (extensions->ARB_explicit_uniform_location) |
add_builtin_define(parser, "GL_ARB_explicit_uniform_location", 1); |
if (extensions->ARB_shader_texture_lod) |
add_builtin_define(parser, "GL_ARB_shader_texture_lod", 1); |
if (extensions->ARB_draw_instanced) |
add_builtin_define(parser, "GL_ARB_draw_instanced", 1); |
if (extensions->ARB_conservative_depth) { |
add_builtin_define(parser, "GL_AMD_conservative_depth", 1); |
add_builtin_define(parser, "GL_ARB_conservative_depth", 1); |
} |
if (extensions->ARB_shader_bit_encoding) |
add_builtin_define(parser, "GL_ARB_shader_bit_encoding", 1); |
if (extensions->ARB_uniform_buffer_object) |
add_builtin_define(parser, "GL_ARB_uniform_buffer_object", 1); |
if (extensions->ARB_texture_cube_map_array) |
add_builtin_define(parser, "GL_ARB_texture_cube_map_array", 1); |
if (extensions->ARB_shading_language_packing) |
add_builtin_define(parser, "GL_ARB_shading_language_packing", 1); |
if (extensions->ARB_texture_multisample) |
add_builtin_define(parser, "GL_ARB_texture_multisample", 1); |
if (extensions->ARB_texture_query_levels) |
add_builtin_define(parser, "GL_ARB_texture_query_levels", 1); |
if (extensions->ARB_texture_query_lod) |
add_builtin_define(parser, "GL_ARB_texture_query_lod", 1); |
if (extensions->ARB_gpu_shader5) |
add_builtin_define(parser, "GL_ARB_gpu_shader5", 1); |
if (extensions->ARB_gpu_shader_fp64) |
add_builtin_define(parser, "GL_ARB_gpu_shader_fp64", 1); |
if (extensions->ARB_vertex_attrib_64bit) |
add_builtin_define(parser, "GL_ARB_vertex_attrib_64bit", 1); |
if (extensions->AMD_vertex_shader_layer) |
add_builtin_define(parser, "GL_AMD_vertex_shader_layer", 1); |
if (extensions->AMD_vertex_shader_viewport_index) |
add_builtin_define(parser, "GL_AMD_vertex_shader_viewport_index", 1); |
if (extensions->ARB_shading_language_420pack) |
add_builtin_define(parser, "GL_ARB_shading_language_420pack", 1); |
if (extensions->ARB_sample_shading) |
add_builtin_define(parser, "GL_ARB_sample_shading", 1); |
if (extensions->ARB_texture_gather) |
add_builtin_define(parser, "GL_ARB_texture_gather", 1); |
if (extensions->ARB_shader_atomic_counters) |
add_builtin_define(parser, "GL_ARB_shader_atomic_counters", 1); |
if (extensions->ARB_viewport_array) |
add_builtin_define(parser, "GL_ARB_viewport_array", 1); |
if (extensions->ARB_compute_shader) |
add_builtin_define(parser, "GL_ARB_compute_shader", 1); |
if (extensions->ARB_shader_image_load_store) |
add_builtin_define(parser, "GL_ARB_shader_image_load_store", 1); |
if (extensions->ARB_derivative_control) |
add_builtin_define(parser, "GL_ARB_derivative_control", 1); |
if (extensions->ARB_shader_precision) |
add_builtin_define(parser, "GL_ARB_shader_precision", 1); |
} |
} |
if (extensions != NULL) { |
if (extensions->EXT_shader_integer_mix) |
add_builtin_define(parser, "GL_EXT_shader_integer_mix", 1); |
} |
if (version >= 150) |
add_builtin_define(parser, "GL_core_profile", 1); |
/* Currently, all ES2/ES3 implementations support highp in the |
* fragment shader, so we always define this macro in ES2/ES3. |
* If we ever get a driver that doesn't support highp, we'll |
* need to add a flag to the gl_context and check that here. |
*/ |
if (version >= 130 || parser->is_gles) |
add_builtin_define (parser, "GL_FRAGMENT_PRECISION_HIGH", 1); |
if (explicitly_set) { |
ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, |
"#version %" PRIiMAX "%s%s", version, |
es_identifier ? " " : "", |
es_identifier ? es_identifier : ""); |
} |
} |
/* GLSL version if no version is explicitly specified. */ |
#define IMPLICIT_GLSL_VERSION 110 |
/* GLSL ES version if no version is explicitly specified. */ |
#define IMPLICIT_GLSL_ES_VERSION 100 |
void |
glcpp_parser_resolve_implicit_version(glcpp_parser_t *parser) |
{ |
int language_version = parser->api == API_OPENGLES2 ? |
IMPLICIT_GLSL_ES_VERSION : |
IMPLICIT_GLSL_VERSION; |
_glcpp_parser_handle_version_declaration(parser, language_version, |
NULL, false); |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/glcpp.c |
---|
0,0 → 1,179 |
/* |
* Copyright © 2010 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#include <stdio.h> |
#include <string.h> |
#include <errno.h> |
#include <getopt.h> |
#include "glcpp.h" |
#include "main/mtypes.h" |
#include "main/shaderobj.h" |
extern int glcpp_parser_debug; |
void |
_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr, |
struct gl_shader *sh) |
{ |
(void) ctx; |
*ptr = sh; |
} |
/* Read from fp until EOF and return a string of everything read. |
*/ |
static char * |
load_text_fp (void *ctx, FILE *fp) |
{ |
#define CHUNK 4096 |
char *text = NULL; |
size_t text_size = 0; |
size_t total_read = 0; |
size_t bytes; |
while (1) { |
if (total_read + CHUNK + 1 > text_size) { |
text_size = text_size ? text_size * 2 : CHUNK + 1; |
text = reralloc_size (ctx, text, text_size); |
if (text == NULL) { |
fprintf (stderr, "Out of memory\n"); |
return NULL; |
} |
} |
bytes = fread (text + total_read, 1, CHUNK, fp); |
total_read += bytes; |
if (bytes < CHUNK) { |
break; |
} |
} |
text[total_read] = '\0'; |
return text; |
} |
static char * |
load_text_file(void *ctx, const char *filename) |
{ |
char *text; |
FILE *fp; |
if (filename == NULL || strcmp (filename, "-") == 0) |
return load_text_fp (ctx, stdin); |
fp = fopen (filename, "r"); |
if (fp == NULL) { |
fprintf (stderr, "Failed to open file %s: %s\n", |
filename, strerror (errno)); |
return NULL; |
} |
text = load_text_fp (ctx, fp); |
fclose(fp); |
return text; |
} |
/* Initialize only those things that glcpp cares about. |
*/ |
static void |
init_fake_gl_context (struct gl_context *gl_ctx) |
{ |
gl_ctx->API = API_OPENGL_COMPAT; |
gl_ctx->Const.DisableGLSLLineContinuations = false; |
} |
static void |
usage (void) |
{ |
fprintf (stderr, |
"Usage: glcpp [OPTIONS] [--] [<filename>]\n" |
"\n" |
"Pre-process the given filename (stdin if no filename given).\n" |
"The following options are supported:\n" |
" --disable-line-continuations Do not interpret lines ending with a\n" |
" backslash ('\\') as a line continuation.\n"); |
} |
enum { |
DISABLE_LINE_CONTINUATIONS_OPT = CHAR_MAX + 1 |
}; |
static const struct option |
long_options[] = { |
{"disable-line-continuations", no_argument, 0, DISABLE_LINE_CONTINUATIONS_OPT }, |
{"debug", no_argument, 0, 'd'}, |
{0, 0, 0, 0 } |
}; |
int |
main (int argc, char *argv[]) |
{ |
char *filename = NULL; |
void *ctx = ralloc(NULL, void*); |
char *info_log = ralloc_strdup(ctx, ""); |
const char *shader; |
int ret; |
struct gl_context gl_ctx; |
int c; |
init_fake_gl_context (&gl_ctx); |
while ((c = getopt_long(argc, argv, "d", long_options, NULL)) != -1) { |
switch (c) { |
case DISABLE_LINE_CONTINUATIONS_OPT: |
gl_ctx.Const.DisableGLSLLineContinuations = true; |
break; |
case 'd': |
glcpp_parser_debug = 1; |
break; |
default: |
usage (); |
exit (1); |
} |
} |
if (optind + 1 < argc) { |
printf ("Unexpected argument: %s\n", argv[optind+1]); |
usage (); |
exit (1); |
} |
if (optind < argc) { |
filename = argv[optind]; |
} |
shader = load_text_file (ctx, filename); |
if (shader == NULL) |
return 1; |
ret = glcpp_preprocess(ctx, &shader, &info_log, NULL, &gl_ctx); |
printf("%s", shader); |
fprintf(stderr, "%s", info_log); |
ralloc_free(ctx); |
return ret; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/glcpp.h |
---|
0,0 → 1,251 |
/* |
* Copyright © 2010 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#ifndef GLCPP_H |
#define GLCPP_H |
#include <stdint.h> |
#include <stdbool.h> |
#include "main/mtypes.h" |
#include "util/ralloc.h" |
#include "program/hash_table.h" |
#define yyscan_t void* |
/* Some data types used for parser values. */ |
typedef struct expression_value { |
intmax_t value; |
char *undefined_macro; |
} expression_value_t; |
typedef struct string_node { |
const char *str; |
struct string_node *next; |
} string_node_t; |
typedef struct string_list { |
string_node_t *head; |
string_node_t *tail; |
} string_list_t; |
typedef struct token token_t; |
typedef struct token_list token_list_t; |
typedef union YYSTYPE |
{ |
intmax_t ival; |
expression_value_t expression_value; |
char *str; |
string_list_t *string_list; |
token_t *token; |
token_list_t *token_list; |
} YYSTYPE; |
# define YYSTYPE_IS_TRIVIAL 1 |
# define YYSTYPE_IS_DECLARED 1 |
typedef struct YYLTYPE { |
int first_line; |
int first_column; |
int last_line; |
int last_column; |
unsigned source; |
} YYLTYPE; |
# define YYLTYPE_IS_DECLARED 1 |
# define YYLTYPE_IS_TRIVIAL 1 |
# define YYLLOC_DEFAULT(Current, Rhs, N) \ |
do { \ |
if (N) \ |
{ \ |
(Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ |
(Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ |
(Current).last_line = YYRHSLOC(Rhs, N).last_line; \ |
(Current).last_column = YYRHSLOC(Rhs, N).last_column; \ |
} \ |
else \ |
{ \ |
(Current).first_line = (Current).last_line = \ |
YYRHSLOC(Rhs, 0).last_line; \ |
(Current).first_column = (Current).last_column = \ |
YYRHSLOC(Rhs, 0).last_column; \ |
} \ |
(Current).source = 0; \ |
} while (0) |
struct token { |
int type; |
YYSTYPE value; |
YYLTYPE location; |
}; |
typedef struct token_node { |
token_t *token; |
struct token_node *next; |
} token_node_t; |
struct token_list { |
token_node_t *head; |
token_node_t *tail; |
token_node_t *non_space_tail; |
}; |
typedef struct argument_node { |
token_list_t *argument; |
struct argument_node *next; |
} argument_node_t; |
typedef struct argument_list { |
argument_node_t *head; |
argument_node_t *tail; |
} argument_list_t; |
typedef struct glcpp_parser glcpp_parser_t; |
typedef enum { |
TOKEN_CLASS_IDENTIFIER, |
TOKEN_CLASS_IDENTIFIER_FINALIZED, |
TOKEN_CLASS_FUNC_MACRO, |
TOKEN_CLASS_OBJ_MACRO |
} token_class_t; |
token_class_t |
glcpp_parser_classify_token (glcpp_parser_t *parser, |
const char *identifier, |
int *parameter_index); |
typedef struct { |
int is_function; |
string_list_t *parameters; |
const char *identifier; |
token_list_t *replacements; |
} macro_t; |
typedef struct expansion_node { |
macro_t *macro; |
token_node_t *replacements; |
struct expansion_node *next; |
} expansion_node_t; |
typedef enum skip_type { |
SKIP_NO_SKIP, |
SKIP_TO_ELSE, |
SKIP_TO_ENDIF |
} skip_type_t; |
typedef struct skip_node { |
skip_type_t type; |
bool has_else; |
YYLTYPE loc; /* location of the initial #if/#elif/... */ |
struct skip_node *next; |
} skip_node_t; |
typedef struct active_list { |
const char *identifier; |
token_node_t *marker; |
struct active_list *next; |
} active_list_t; |
struct glcpp_parser { |
yyscan_t scanner; |
struct hash_table *defines; |
active_list_t *active; |
int lexing_directive; |
int space_tokens; |
int last_token_was_newline; |
int last_token_was_space; |
int first_non_space_token_this_line; |
int newline_as_space; |
int in_control_line; |
int paren_count; |
int commented_newlines; |
skip_node_t *skip_stack; |
int skipping; |
token_list_t *lex_from_list; |
token_node_t *lex_from_node; |
char *output; |
char *info_log; |
size_t output_length; |
size_t info_log_length; |
int error; |
const struct gl_extensions *extensions; |
gl_api api; |
bool version_resolved; |
bool has_new_line_number; |
int new_line_number; |
bool has_new_source_number; |
int new_source_number; |
bool is_gles; |
}; |
struct gl_extensions; |
glcpp_parser_t * |
glcpp_parser_create (const struct gl_extensions *extensions, gl_api api); |
int |
glcpp_parser_parse (glcpp_parser_t *parser); |
void |
glcpp_parser_destroy (glcpp_parser_t *parser); |
void |
glcpp_parser_resolve_implicit_version(glcpp_parser_t *parser); |
int |
glcpp_preprocess(void *ralloc_ctx, const char **shader, char **info_log, |
const struct gl_extensions *extensions, struct gl_context *g_ctx); |
/* Functions for writing to the info log */ |
void |
glcpp_error (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...); |
void |
glcpp_warning (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...); |
/* Generated by glcpp-lex.l to glcpp-lex.c */ |
int |
glcpp_lex_init_extra (glcpp_parser_t *parser, yyscan_t* scanner); |
void |
glcpp_lex_set_source_string(glcpp_parser_t *parser, const char *shader); |
int |
glcpp_lex (YYSTYPE *lvalp, YYLTYPE *llocp, yyscan_t scanner); |
int |
glcpp_lex_destroy (yyscan_t scanner); |
/* Generated by glcpp-parse.y to glcpp-parse.c */ |
int |
yyparse (glcpp_parser_t *parser); |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/pp.c |
---|
0,0 → 1,241 |
/* |
* Copyright © 2010 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#include <assert.h> |
#include <string.h> |
#include <ctype.h> |
#include "glcpp.h" |
void |
glcpp_error (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...) |
{ |
va_list ap; |
parser->error = 1; |
ralloc_asprintf_rewrite_tail(&parser->info_log, |
&parser->info_log_length, |
"%u:%u(%u): " |
"preprocessor error: ", |
locp->source, |
locp->first_line, |
locp->first_column); |
va_start(ap, fmt); |
ralloc_vasprintf_rewrite_tail(&parser->info_log, |
&parser->info_log_length, |
fmt, ap); |
va_end(ap); |
ralloc_asprintf_rewrite_tail(&parser->info_log, |
&parser->info_log_length, "\n"); |
} |
void |
glcpp_warning (YYLTYPE *locp, glcpp_parser_t *parser, const char *fmt, ...) |
{ |
va_list ap; |
ralloc_asprintf_rewrite_tail(&parser->info_log, |
&parser->info_log_length, |
"%u:%u(%u): " |
"preprocessor warning: ", |
locp->source, |
locp->first_line, |
locp->first_column); |
va_start(ap, fmt); |
ralloc_vasprintf_rewrite_tail(&parser->info_log, |
&parser->info_log_length, |
fmt, ap); |
va_end(ap); |
ralloc_asprintf_rewrite_tail(&parser->info_log, |
&parser->info_log_length, "\n"); |
} |
/* Given str, (that's expected to start with a newline terminator of some |
* sort), return a pointer to the first character in str after the newline. |
* |
* A newline terminator can be any of the following sequences: |
* |
* "\r\n" |
* "\n\r" |
* "\n" |
* "\r" |
* |
* And the longest such sequence will be skipped. |
*/ |
static const char * |
skip_newline (const char *str) |
{ |
const char *ret = str; |
if (ret == NULL) |
return ret; |
if (*ret == '\0') |
return ret; |
if (*ret == '\r') { |
ret++; |
if (*ret && *ret == '\n') |
ret++; |
} else if (*ret == '\n') { |
ret++; |
if (*ret && *ret == '\r') |
ret++; |
} |
return ret; |
} |
/* Remove any line continuation characters in the shader, (whether in |
* preprocessing directives or in GLSL code). |
*/ |
static char * |
remove_line_continuations(glcpp_parser_t *ctx, const char *shader) |
{ |
char *clean = ralloc_strdup(ctx, ""); |
const char *backslash, *newline, *search_start; |
const char *cr, *lf; |
char newline_separator[3]; |
int collapsed_newlines = 0; |
search_start = shader; |
/* Determine what flavor of newlines this shader is using. GLSL |
* provides for 4 different possible ways to separate lines, (using |
* one or two characters): |
* |
* "\n" (line-feed, like Linux, Unix, and new Mac OS) |
* "\r" (carriage-return, like old Mac files) |
* "\r\n" (carriage-return + line-feed, like DOS files) |
* "\n\r" (line-feed + carriage-return, like nothing, really) |
* |
* This code explicitly supports a shader that uses a mixture of |
* newline terminators and will properly handle line continuation |
* backslashes followed by any of the above. |
* |
* But, since we must also insert additional newlines in the output |
* (for any collapsed lines) we attempt to maintain consistency by |
* examining the first encountered newline terminator, and using the |
* same terminator for any newlines we insert. |
*/ |
cr = strchr(search_start, '\r'); |
lf = strchr(search_start, '\n'); |
newline_separator[0] = '\n'; |
newline_separator[1] = '\0'; |
newline_separator[2] = '\0'; |
if (cr == NULL) { |
/* Nothing to do. */ |
} else if (lf == NULL) { |
newline_separator[0] = '\r'; |
} else if (lf == cr + 1) { |
newline_separator[0] = '\r'; |
newline_separator[1] = '\n'; |
} else if (cr == lf + 1) { |
newline_separator[0] = '\n'; |
newline_separator[1] = '\r'; |
} |
while (true) { |
backslash = strchr(search_start, '\\'); |
/* If we have previously collapsed any line-continuations, |
* then we want to insert additional newlines at the next |
* occurrence of a newline character to avoid changing any |
* line numbers. |
*/ |
if (collapsed_newlines) { |
cr = strchr (search_start, '\r'); |
lf = strchr (search_start, '\n'); |
if (cr && lf) |
newline = cr < lf ? cr : lf; |
else if (cr) |
newline = cr; |
else |
newline = lf; |
if (newline && |
(backslash == NULL || newline < backslash)) |
{ |
ralloc_strncat(&clean, shader, |
newline - shader + 1); |
while (collapsed_newlines) { |
ralloc_strcat(&clean, newline_separator); |
collapsed_newlines--; |
} |
shader = skip_newline (newline); |
search_start = shader; |
} |
} |
search_start = backslash + 1; |
if (backslash == NULL) |
break; |
/* At each line continuation, (backslash followed by a |
* newline), copy all preceding text to the output, then |
* advance the shader pointer to the character after the |
* newline. |
*/ |
if (backslash[1] == '\r' || backslash[1] == '\n') |
{ |
collapsed_newlines++; |
ralloc_strncat(&clean, shader, backslash - shader); |
shader = skip_newline (backslash + 1); |
search_start = shader; |
} |
} |
ralloc_strcat(&clean, shader); |
return clean; |
} |
int |
glcpp_preprocess(void *ralloc_ctx, const char **shader, char **info_log, |
const struct gl_extensions *extensions, struct gl_context *gl_ctx) |
{ |
int errors; |
glcpp_parser_t *parser = glcpp_parser_create (extensions, gl_ctx->API); |
if (! gl_ctx->Const.DisableGLSLLineContinuations) |
*shader = remove_line_continuations(parser, *shader); |
glcpp_lex_set_source_string (parser, *shader); |
glcpp_parser_parse (parser); |
if (parser->skip_stack) |
glcpp_error (&parser->skip_stack->loc, parser, "Unterminated #if\n"); |
glcpp_parser_resolve_implicit_version(parser); |
ralloc_strcat(info_log, parser->info_log); |
ralloc_steal(ralloc_ctx, parser->output); |
*shader = parser->output; |
errors = parser->error; |
glcpp_parser_destroy (parser); |
return errors; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/000-content-with-spaces.c |
---|
0,0 → 1,0 |
this is four tokens with spaces |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/000-content-with-spaces.c.expected |
---|
0,0 → 1,0 |
this is four tokens with spaces |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/001-define.c |
---|
0,0 → 1,2 |
#define foo 1 |
foo |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/001-define.c.expected |
---|
0,0 → 1,2 |
1 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/002-define-chain.c |
---|
0,0 → 1,3 |
#define foo 1 |
#define bar foo |
bar |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/002-define-chain.c.expected |
---|
0,0 → 1,3 |
1 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/003-define-chain-reverse.c |
---|
0,0 → 1,3 |
#define bar foo |
#define foo 1 |
bar |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/003-define-chain-reverse.c.expected |
---|
0,0 → 1,3 |
1 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/004-define-recursive.c |
---|
0,0 → 1,6 |
#define foo bar |
#define bar baz |
#define baz foo |
foo |
bar |
baz |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/004-define-recursive.c.expected |
---|
0,0 → 1,6 |
foo |
bar |
baz |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/005-define-composite-chain.c |
---|
0,0 → 1,3 |
#define foo 1 |
#define bar a foo |
bar |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/005-define-composite-chain.c.expected |
---|
0,0 → 1,3 |
a 1 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/006-define-composite-chain-reverse.c |
---|
0,0 → 1,3 |
#define bar a foo |
#define foo 1 |
bar |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/006-define-composite-chain-reverse.c.expected |
---|
0,0 → 1,3 |
a 1 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/007-define-composite-recursive.c |
---|
0,0 → 1,6 |
#define foo a bar |
#define bar b baz |
#define baz c foo |
foo |
bar |
baz |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/007-define-composite-recursive.c.expected |
---|
0,0 → 1,6 |
a b c foo |
b c a bar |
c a b baz |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/008-define-empty.c |
---|
0,0 → 1,2 |
#define foo |
foo |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/008-define-empty.c.expected |
---|
0,0 → 1,2 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/009-undef.c |
---|
0,0 → 1,4 |
#define foo 1 |
foo |
#undef foo |
foo |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/009-undef.c.expected |
---|
0,0 → 1,4 |
1 |
foo |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/010-undef-re-define.c |
---|
0,0 → 1,6 |
#define foo 1 |
foo |
#undef foo |
foo |
#define foo 2 |
foo |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/010-undef-re-define.c.expected |
---|
0,0 → 1,6 |
1 |
foo |
2 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/011-define-func-empty.c |
---|
0,0 → 1,2 |
#define foo() |
foo() |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/011-define-func-empty.c.expected |
---|
0,0 → 1,2 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/012-define-func-no-args.c |
---|
0,0 → 1,2 |
#define foo() bar |
foo() |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/012-define-func-no-args.c.expected |
---|
0,0 → 1,2 |
bar |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/013-define-func-1-arg-unused.c |
---|
0,0 → 1,2 |
#define foo(x) 1 |
foo(bar) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/013-define-func-1-arg-unused.c.expected |
---|
0,0 → 1,2 |
1 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/014-define-func-2-arg-unused.c |
---|
0,0 → 1,2 |
#define foo(x,y) 1 |
foo(bar,baz) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/014-define-func-2-arg-unused.c.expected |
---|
0,0 → 1,2 |
1 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/015-define-object-with-parens.c |
---|
0,0 → 1,4 |
#define foo ()1 |
foo() |
#define bar ()2 |
bar() |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/015-define-object-with-parens.c.expected |
---|
0,0 → 1,4 |
()1() |
()2() |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/016-define-func-1-arg.c |
---|
0,0 → 1,2 |
#define foo(x) ((x)+1) |
foo(bar) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/016-define-func-1-arg.c.expected |
---|
0,0 → 1,2 |
((bar)+1) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/017-define-func-2-args.c |
---|
0,0 → 1,2 |
#define foo(x,y) ((x)*(y)) |
foo(bar,baz) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/017-define-func-2-args.c.expected |
---|
0,0 → 1,2 |
((bar)*(baz)) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/018-define-func-macro-as-parameter.c |
---|
0,0 → 1,3 |
#define x 0 |
#define foo(x) x |
foo(1) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/018-define-func-macro-as-parameter.c.expected |
---|
0,0 → 1,3 |
1 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/019-define-func-1-arg-multi.c |
---|
0,0 → 1,2 |
#define foo(x) (x) |
foo(this is more than one word) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/019-define-func-1-arg-multi.c.expected |
---|
0,0 → 1,2 |
(this is more than one word) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/020-define-func-2-arg-multi.c |
---|
0,0 → 1,2 |
#define foo(x,y) x,two fish,red fish,y |
foo(one fish, blue fish) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/020-define-func-2-arg-multi.c.expected |
---|
0,0 → 1,2 |
one fish,two fish,red fish,blue fish |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/021-define-func-compose.c |
---|
0,0 → 1,3 |
#define bar(x) (1+(x)) |
#define foo(y) (2*(y)) |
foo(bar(3)) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/021-define-func-compose.c.expected |
---|
0,0 → 1,3 |
(2*((1+(3)))) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/022-define-func-arg-with-parens.c |
---|
0,0 → 1,2 |
#define foo(x) (x) |
foo(argument(including parens)for the win) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/022-define-func-arg-with-parens.c.expected |
---|
0,0 → 1,2 |
(argument(including parens)for the win) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/023-define-extra-whitespace.c |
---|
0,0 → 1,8 |
#define noargs() 1 |
# define onearg(foo) foo |
# define twoargs( x , y ) x y |
# define threeargs( a , b , c ) a b c |
noargs ( ) |
onearg ( 2 ) |
twoargs ( 3 , 4 ) |
threeargs ( 5 , 6 , 7 ) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/023-define-extra-whitespace.c.expected |
---|
0,0 → 1,8 |
1 |
2 |
3 4 |
5 6 7 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/024-define-chain-to-self-recursion.c |
---|
0,0 → 1,3 |
#define foo foo |
#define bar foo |
bar |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/024-define-chain-to-self-recursion.c.expected |
---|
0,0 → 1,3 |
foo |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/025-func-macro-as-non-macro.c |
---|
0,0 → 1,2 |
#define foo(bar) bar |
foo bar |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/025-func-macro-as-non-macro.c.expected |
---|
0,0 → 1,2 |
foo bar |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/026-define-func-extra-newlines.c |
---|
0,0 → 1,6 |
#define foo(a) bar |
foo |
( |
1 |
) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/026-define-func-extra-newlines.c.expected |
---|
0,0 → 1,3 |
bar |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/027-define-chain-obj-to-func.c |
---|
0,0 → 1,3 |
#define failure() success |
#define foo failure() |
foo |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/027-define-chain-obj-to-func.c.expected |
---|
0,0 → 1,3 |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/028-define-chain-obj-to-non-func.c |
---|
0,0 → 1,3 |
#define success() failure |
#define foo success |
foo |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/028-define-chain-obj-to-non-func.c.expected |
---|
0,0 → 1,3 |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/029-define-chain-obj-to-func-with-args.c |
---|
0,0 → 1,3 |
#define bar(failure) failure |
#define foo bar(success) |
foo |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/029-define-chain-obj-to-func-with-args.c.expected |
---|
0,0 → 1,3 |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/030-define-chain-obj-to-func-compose.c |
---|
0,0 → 1,4 |
#define baz(failure) failure |
#define bar(failure) failure |
#define foo bar(baz(success)) |
foo |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/030-define-chain-obj-to-func-compose.c.expected |
---|
0,0 → 1,4 |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/031-define-chain-func-to-func-compose.c |
---|
0,0 → 1,4 |
#define baz(failure) failure |
#define bar(failure) failure |
#define foo() bar(baz(success)) |
foo() |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/031-define-chain-func-to-func-compose.c.expected |
---|
0,0 → 1,4 |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/032-define-func-self-recurse.c |
---|
0,0 → 1,2 |
#define foo(a) foo(2*(a)) |
foo(3) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/032-define-func-self-recurse.c.expected |
---|
0,0 → 1,2 |
foo(2*(3)) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/033-define-func-self-compose.c |
---|
0,0 → 1,2 |
#define foo(a) foo(2*(a)) |
foo(foo(3)) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/033-define-func-self-compose.c.expected |
---|
0,0 → 1,2 |
foo(2*(foo(2*(3)))) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/034-define-func-self-compose-non-func.c |
---|
0,0 → 1,2 |
#define foo(bar) bar |
foo(foo) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/034-define-func-self-compose-non-func.c.expected |
---|
0,0 → 1,2 |
foo |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/035-define-func-self-compose-non-func-multi-token-argument.c |
---|
0,0 → 1,2 |
#define foo(bar) bar |
foo(1+foo) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/035-define-func-self-compose-non-func-multi-token-argument.c.expected |
---|
0,0 → 1,2 |
1+foo |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/036-define-func-non-macro-multi-token-argument.c |
---|
0,0 → 1,3 |
#define bar success |
#define foo(x) x |
foo(more bar) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/036-define-func-non-macro-multi-token-argument.c.expected |
---|
0,0 → 1,3 |
more success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/037-finalize-unexpanded-macro.c |
---|
0,0 → 1,3 |
#define expand(x) expand(x once) |
#define foo(x) x |
foo(expand(just)) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/037-finalize-unexpanded-macro.c.expected |
---|
0,0 → 1,3 |
expand(just once) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/038-func-arg-with-commas.c |
---|
0,0 → 1,2 |
#define foo(x) success |
foo(argument (with,embedded , commas) -- tricky) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/038-func-arg-with-commas.c.expected |
---|
0,0 → 1,2 |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/039-func-arg-obj-macro-with-comma.c |
---|
0,0 → 1,24 |
/* This works. */ |
#define foo(a) (a) |
#define bar two,words |
foo(bar) |
/* So does this. */ |
#define foo2(a,b) (a separate b) |
#define foo2_wrap(a) foo2(a) |
foo2_wrap(bar) |
/* But this generates an error. */ |
#define foo_wrap(a) foo(a) |
foo_wrap(bar) |
/* Adding parentheses to foo_wrap fixes it. */ |
#define foo_wrap_parens(a) foo((a)) |
foo_wrap_parens(bar) |
/* As does adding parentheses to bar */ |
#define bar_parens (two,words) |
foo_wrap(bar_parens) |
foo_wrap_parens(bar_parens) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/039-func-arg-obj-macro-with-comma.c.expected |
---|
0,0 → 1,26 |
0:12(21): preprocessor error: Error: macro foo invoked with 2 arguments (expected 1) |
(two,words) |
(two separate words) |
foo(two,words) |
((two,words)) |
((two,words)) |
(((two,words))) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/040-token-pasting.c |
---|
0,0 → 1,2 |
#define paste(a,b) a ## b |
paste(one , token) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/040-token-pasting.c.expected |
---|
0,0 → 1,2 |
onetoken |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/041-if-0.c |
---|
0,0 → 1,5 |
success_1 |
#if 0 |
failure |
#endif |
success_2 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/041-if-0.c.expected |
---|
0,0 → 1,5 |
success_1 |
success_2 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/042-if-1.c |
---|
0,0 → 1,5 |
success_1 |
#if 1 |
success_2 |
#endif |
success_3 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/042-if-1.c.expected |
---|
0,0 → 1,5 |
success_1 |
success_2 |
success_3 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/043-if-0-else.c |
---|
0,0 → 1,7 |
success_1 |
#if 0 |
failure |
#else |
success_2 |
#endif |
success_3 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/043-if-0-else.c.expected |
---|
0,0 → 1,7 |
success_1 |
success_2 |
success_3 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/044-if-1-else.c |
---|
0,0 → 1,7 |
success_1 |
#if 1 |
success_2 |
#else |
failure |
#endif |
success_3 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/044-if-1-else.c.expected |
---|
0,0 → 1,7 |
success_1 |
success_2 |
success_3 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/045-if-0-elif.c |
---|
0,0 → 1,11 |
success_1 |
#if 0 |
failure_1 |
#elif 0 |
failure_2 |
#elif 1 |
success_3 |
#elif 1 |
failure_3 |
#endif |
success_4 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/045-if-0-elif.c.expected |
---|
0,0 → 1,11 |
success_1 |
success_3 |
success_4 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/046-if-1-elsif.c |
---|
0,0 → 1,11 |
success_1 |
#if 1 |
success_2 |
#elif 0 |
failure_1 |
#elif 1 |
failure_2 |
#elif 0 |
failure_3 |
#endif |
success_3 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/046-if-1-elsif.c.expected |
---|
0,0 → 1,11 |
success_1 |
success_2 |
success_3 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/047-if-elif-else.c |
---|
0,0 → 1,11 |
success_1 |
#if 0 |
failure_1 |
#elif 0 |
failure_2 |
#elif 0 |
failure_3 |
#else |
success_2 |
#endif |
success_3 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/047-if-elif-else.c.expected |
---|
0,0 → 1,11 |
success_1 |
success_2 |
success_3 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/048-if-nested.c |
---|
0,0 → 1,11 |
success_1 |
#if 0 |
failure_1 |
#if 1 |
failure_2 |
#else |
failure_3 |
#endif |
failure_4 |
#endif |
success_2 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/048-if-nested.c.expected |
---|
0,0 → 1,11 |
success_1 |
success_2 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/049-if-expression-precedence.c |
---|
0,0 → 1,5 |
#if 1 + 2 * 3 + - (25 % 17 - + 1) |
failure with operator precedence |
#else |
success |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/049-if-expression-precedence.c.expected |
---|
0,0 → 1,5 |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/050-if-defined.c |
---|
0,0 → 1,17 |
#if defined foo |
failure_1 |
#else |
success_1 |
#endif |
#define foo |
#if defined foo |
success_2 |
#else |
failure_2 |
#endif |
#undef foo |
#if defined foo |
failure_3 |
#else |
success_3 |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/050-if-defined.c.expected |
---|
0,0 → 1,17 |
success_1 |
success_2 |
success_3 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/051-if-relational.c |
---|
0,0 → 1,35 |
#if 3 < 2 |
failure_1 |
#else |
success_1 |
#endif |
#if 3 >= 2 |
success_2 |
#else |
failure_2 |
#endif |
#if 2 + 3 <= 5 |
success_3 |
#else |
failure_3 |
#endif |
#if 3 - 2 == 1 |
success_3 |
#else |
failure_3 |
#endif |
#if 1 > 3 |
failure_4 |
#else |
success_4 |
#endif |
#if 1 != 5 |
success_5 |
#else |
failure_5 |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/051-if-relational.c.expected |
---|
0,0 → 1,35 |
success_1 |
success_2 |
success_3 |
success_3 |
success_4 |
success_5 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/052-if-bitwise.c |
---|
0,0 → 1,20 |
#if (0xaaaaaaaa | 0x55555555) != 4294967295 |
failure_1 |
#else |
success_1 |
#endif |
#if (0x12345678 ^ 0xfdecba98) == 4023971040 |
success_2 |
#else |
failure_2 |
#endif |
#if (~ 0xdeadbeef) != -3735928560 |
failure_3 |
#else |
success_3 |
#endif |
#if (0667 & 0733) == 403 |
success_4 |
#else |
failure_4 |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/052-if-bitwise.c.expected |
---|
0,0 → 1,20 |
success_1 |
success_2 |
success_3 |
success_4 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/053-if-divide-and-shift.c |
---|
0,0 → 1,15 |
#if (15 / 2) != 7 |
failure_1 |
#else |
success_1 |
#endif |
#if (1 << 12) == 4096 |
success_2 |
#else |
failure_2 |
#endif |
#if (31762 >> 8) != 124 |
failure_3 |
#else |
success_3 |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/053-if-divide-and-shift.c.expected |
---|
0,0 → 1,15 |
success_1 |
success_2 |
success_3 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/054-if-with-macros.c |
---|
0,0 → 1,34 |
#define one 1 |
#define two 2 |
#define three 3 |
#define five 5 |
#if five < two |
failure_1 |
#else |
success_1 |
#endif |
#if three >= two |
success_2 |
#else |
failure_2 |
#endif |
#if two + three <= five |
success_3 |
#else |
failure_3 |
#endif |
#if five - two == three |
success_4 |
#else |
failure_4 |
#endif |
#if one > three |
failure_5 |
#else |
success_5 |
#endif |
#if one != five |
success_6 |
#else |
failure_6 |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/054-if-with-macros.c.expected |
---|
0,0 → 1,34 |
success_1 |
success_2 |
success_3 |
success_4 |
success_5 |
success_6 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/055-define-chain-obj-to-func-parens-in-text.c |
---|
0,0 → 1,3 |
#define failure() success |
#define foo failure |
foo() |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/055-define-chain-obj-to-func-parens-in-text.c.expected |
---|
0,0 → 1,3 |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/056-macro-argument-with-comma.c |
---|
0,0 → 1,4 |
#define bar with,embedded,commas |
#define function(x) success |
#define foo function |
foo(bar) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/056-macro-argument-with-comma.c.expected |
---|
0,0 → 1,4 |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/057-empty-arguments.c |
---|
0,0 → 1,6 |
#define zero() success |
zero() |
#define one(x) success |
one() |
#define two(x,y) success |
two(,) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/057-empty-arguments.c.expected |
---|
0,0 → 1,6 |
success |
success |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/058-token-pasting-empty-arguments.c |
---|
0,0 → 1,5 |
#define paste(x,y) x ## y |
paste(a,b) |
paste(a,) |
paste(,b) |
paste(,) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/058-token-pasting-empty-arguments.c.expected |
---|
0,0 → 1,5 |
ab |
a |
b |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/059-token-pasting-integer.c |
---|
0,0 → 1,4 |
#define paste(x,y) x ## y |
paste(1,2) |
paste(1,000) |
paste(identifier,2) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/059-token-pasting-integer.c.expected |
---|
0,0 → 1,4 |
12 |
1000 |
identifier2 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/060-left-paren-in-macro-right-paren-in-text.c |
---|
0,0 → 1,3 |
#define double(a) a*2 |
#define foo double( |
foo 5) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/060-left-paren-in-macro-right-paren-in-text.c.expected |
---|
0,0 → 1,3 |
5*2 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/061-define-chain-obj-to-func-multi.c |
---|
0,0 → 1,5 |
#define foo(x) success |
#define bar foo |
#define baz bar |
#define joe baz |
joe (failure) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/061-define-chain-obj-to-func-multi.c.expected |
---|
0,0 → 1,5 |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/062-if-0-skips-garbage.c |
---|
0,0 → 1,5 |
#define foo(a,b) |
#if 0 |
foo(bar) |
foo( |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/062-if-0-skips-garbage.c.expected |
---|
0,0 → 1,5 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/063-comments.c |
---|
0,0 → 1,20 |
/* this is a comment */ |
// so is this |
// */ |
f = g/**//h; |
/*//*/l(); |
m = n//**/o |
+ p; |
/* this |
comment spans |
multiple lines and |
contains *** stars |
and slashes / *** / |
and other stuff. |
****/ |
more code here |
/* Test that /* nested |
comments */ |
are not treated like comments. |
/*/ this is a comment */ |
/*/*/ |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/063-comments.c.expected |
---|
0,0 → 1,20 |
f = g /h; |
l(); |
m = n |
+ p; |
more code here |
are not treated like comments. |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/064-version.c |
---|
0,0 → 1,2 |
#version 130 |
#define FOO |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/064-version.c.expected |
---|
0,0 → 1,2 |
#version 130 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/065-if-defined-parens.c |
---|
0,0 → 1,17 |
#if defined(foo) |
failure_1 |
#else |
success_1 |
#endif |
#define foo |
#if defined ( foo ) |
success_2 |
#else |
failure_2 |
#endif |
#undef foo |
#if defined (foo) |
failure_3 |
#else |
success_3 |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/065-if-defined-parens.c.expected |
---|
0,0 → 1,17 |
success_1 |
success_2 |
success_3 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/066-if-nospace-expression.c |
---|
0,0 → 1,3 |
#if(1) |
success |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/066-if-nospace-expression.c.expected |
---|
0,0 → 1,3 |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/067-nested-ifdef-ifndef.c |
---|
0,0 → 1,40 |
#define D1 |
#define D2 |
#define result success |
#ifdef U1 |
#ifdef U2 |
#undef result |
#define result failure |
#endif |
#endif |
result |
#ifndef D1 |
#ifndef D2 |
#undef result |
#define result failure |
#endif |
#endif |
result |
#undef result |
#define result failure |
#ifdef D1 |
#ifdef D2 |
#undef result |
#define result success |
#endif |
#endif |
result |
#undef result |
#define result failure |
#ifndef U1 |
#ifndef U2 |
#undef result |
#define result success |
#endif |
#endif |
result |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/067-nested-ifdef-ifndef.c.expected |
---|
0,0 → 1,40 |
success |
success |
success |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/068-accidental-pasting.c |
---|
0,0 → 1,11 |
#define empty |
<empty< |
<empty= |
>empty> |
>empty= |
=empty= |
!empty= |
&empty& |
|empty| |
+empty+ |
-empty- |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/068-accidental-pasting.c.expected |
---|
0,0 → 1,11 |
< < |
< = |
> > |
> = |
= = |
! = |
& & |
| | |
+ + |
- - |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/069-repeated-argument.c |
---|
0,0 → 1,2 |
#define double(x) x x |
double(1) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/069-repeated-argument.c.expected |
---|
0,0 → 1,2 |
1 1 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/070-undefined-macro-in-expression.c |
---|
0,0 → 1,5 |
#if UNDEFINED_MACRO |
Failure |
#else |
Success |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/070-undefined-macro-in-expression.c.expected |
---|
0,0 → 1,5 |
Success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/071-punctuator.c |
---|
0,0 → 1,0 |
a = b |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/071-punctuator.c.expected |
---|
0,0 → 1,0 |
a = b |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/072-token-pasting-same-line.c |
---|
0,0 → 1,2 |
#define paste(x) success_ ## x |
paste(1) paste(2) paste(3) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/072-token-pasting-same-line.c.expected |
---|
0,0 → 1,2 |
success_1 success_2 success_3 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/073-if-in-ifdef.c |
---|
0,0 → 1,4 |
#ifdef UNDEF |
#if UNDEF > 1 |
#endif |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/073-if-in-ifdef.c.expected |
---|
0,0 → 1,4 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/074-elif-undef.c |
---|
0,0 → 1,3 |
#ifndef UNDEF |
#elif UNDEF < 0 |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/074-elif-undef.c.expected |
---|
0,0 → 1,3 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/075-elif-elif-undef.c |
---|
0,0 → 1,4 |
#ifndef UNDEF |
#elif UNDEF < 0 |
#elif UNDEF == 3 |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/075-elif-elif-undef.c.expected |
---|
0,0 → 1,4 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/076-elif-undef-nested.c |
---|
0,0 → 1,5 |
#ifdef UNDEF |
#if UNDEF == 4 |
#elif UNDEF == 5 |
#endif |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/076-elif-undef-nested.c.expected |
---|
0,0 → 1,5 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/077-else-without-if.c |
---|
0,0 → 1,0 |
#else |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/077-else-without-if.c.expected |
---|
0,0 → 1,3 |
0:1(1): preprocessor error: #else without #if |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/078-elif-without-if.c |
---|
0,0 → 1,0 |
#elif defined FOO |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/078-elif-without-if.c.expected |
---|
0,0 → 1,3 |
0:1(1): preprocessor error: #elif without #if |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/079-endif-without-if.c |
---|
0,0 → 1,0 |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/079-endif-without-if.c.expected |
---|
0,0 → 1,3 |
0:1(1): preprocessor error: #endif without #if |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/080-if-without-expression.c |
---|
0,0 → 1,4 |
/* Error message for unskipped #if with no expression. */ |
#if |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/080-if-without-expression.c.expected |
---|
0,0 → 1,5 |
0:2(1): preprocessor error: #if with no expression |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/081-elif-without-expression.c |
---|
0,0 → 1,3 |
#if 0 |
#elif |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/081-elif-without-expression.c.expected |
---|
0,0 → 1,4 |
0:2(1): preprocessor error: #elif with no expression |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/082-invalid-paste.c |
---|
0,0 → 1,7 |
#define PASTE(x,y) x ## y |
PASTE(<,>) |
PASTE(0,abc) |
PASTE(1,=) |
PASTE(2,@) |
PASTE(3,-4) |
PASTE(4,+5.2) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/082-invalid-paste.c.expected |
---|
0,0 → 1,19 |
0:2(7): preprocessor error: |
Pasting "<" and ">" does not give a valid preprocessing token. |
0:3(7): preprocessor error: |
Pasting "0" and "abc" does not give a valid preprocessing token. |
0:4(7): preprocessor error: |
Pasting "1" and "=" does not give a valid preprocessing token. |
0:5(7): preprocessor error: |
Pasting "2" and "@" does not give a valid preprocessing token. |
0:6(7): preprocessor error: |
Pasting "3" and "-" does not give a valid preprocessing token. |
0:7(7): preprocessor error: |
Pasting "4" and "+" does not give a valid preprocessing token. |
< |
1 |
2 |
34 |
45.2 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/083-unterminated-if.c |
---|
0,0 → 1,2 |
#if 1 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/083-unterminated-if.c.expected |
---|
0,0 → 1,4 |
0:1(6): preprocessor error: Unterminated #if |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/084-unbalanced-parentheses.c |
---|
0,0 → 1,2 |
#define FUNC(x) (2*(x)) |
FUNC(23 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/084-unbalanced-parentheses.c.expected |
---|
0,0 → 1,2 |
0:2(8): preprocessor error: syntax error, unexpected $end |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/085-incorrect-argument-count.c |
---|
0,0 → 1,5 |
#define MULT(x,y) ((x)*(y)) |
MULT() |
MULT(1) |
MULT(1,2,3) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/085-incorrect-argument-count.c.expected |
---|
0,0 → 1,11 |
0:2(1): preprocessor error: Error: macro MULT invoked with 1 arguments (expected 2) |
0:3(1): preprocessor error: Error: macro MULT invoked with 1 arguments (expected 2) |
0:4(1): preprocessor error: Error: macro MULT invoked with 3 arguments (expected 2) |
MULT() |
MULT(1) |
MULT(1,2,3) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/086-reserved-macro-names.c |
---|
0,0 → 1,3 |
#define __BAD reserved |
#define GL_ALSO_BAD() also reserved |
#define THIS__TOO__IS__BAD reserved |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/086-reserved-macro-names.c.expected |
---|
0,0 → 1,9 |
0:1(9): preprocessor warning: Macro names containing "__" are reserved for use by the implementation. |
0:2(9): preprocessor error: Macro names starting with "GL_" are reserved. |
0:3(9): preprocessor warning: Macro names containing "__" are reserved for use by the implementation. |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/087-if-comments.c |
---|
0,0 → 1,5 |
#if (1 == 0) // dangerous comment |
fail |
#else |
win |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/087-if-comments.c.expected |
---|
0,0 → 1,5 |
win |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/088-redefine-macro-legitimate.c |
---|
0,0 → 1,5 |
#define abc 123 |
#define abc 123 |
#define foo(x) ( x ) + 23 |
#define foo(x) ( x ) + 23 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/088-redefine-macro-legitimate.c.expected |
---|
0,0 → 1,5 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/089-redefine-macro-error.c |
---|
0,0 → 1,17 |
#define x y |
#define x z |
#define abc 123 |
#define abc() 123 |
#define foo() bar |
#define foo(x) bar |
#define bar() baz |
#define bar baz |
#define biff(a,b) a+b |
#define biff(a,b,c) a+b |
#define oper(a,b) a+b |
#define oper(a,b) a*b |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/089-redefine-macro-error.c.expected |
---|
0,0 → 1,29 |
0:2(9): preprocessor error: Redefinition of macro x |
0:5(9): preprocessor error: Redefinition of macro abc |
0:8(9): preprocessor error: Redefinition of macro foo |
0:11(9): preprocessor error: Redefinition of macro bar |
0:14(9): preprocessor error: Redefinition of macro biff |
0:17(9): preprocessor error: Redefinition of macro oper |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/090-hash-error.c |
---|
0,0 → 1,0 |
#error human error |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/090-hash-error.c.expected |
---|
0,0 → 1,0 |
0:1(1): preprocessor error: #error human error |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/091-hash-line.c |
---|
0,0 → 1,14 |
#line 0 |
#error line 0 error |
#line 25 |
#error line 25 error |
#line 0 1 |
#error source 1, line 0 error |
#line 30 2 |
#error source 2, line 30 error |
#line 45 2 /* A line with a comment */ |
#define NINETY 90 |
#define TWO 2 |
#line NINETY TWO /* A #line line with macro expansion */ |
#define FUNCTION_LIKE_MACRO(source, line) source line |
#line FUNCTION_LIKE_MACRO(180,2) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/091-hash-line.c.expected |
---|
0,0 → 1,14 |
0:0(1): preprocessor error: #error line 0 error |
0:25(1): preprocessor error: #error line 25 error |
1:0(1): preprocessor error: #error source 1, line 0 error |
2:30(1): preprocessor error: #error source 2, line 30 error |
#line 0 |
#line 25 |
#line 0 1 |
#line 30 2 |
#line 45 2 |
#line 90 2 |
#line 180 2 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/092-redefine-macro-error-2.c |
---|
0,0 → 1,5 |
#define A |
#define A 1 |
#define B 1 |
#define B |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/092-redefine-macro-error-2.c.expected |
---|
0,0 → 1,9 |
0:2(9): preprocessor error: Redefinition of macro A |
0:5(9): preprocessor error: Redefinition of macro B |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/093-divide-by-zero.c |
---|
0,0 → 1,2 |
#if (1 / 0) |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/093-divide-by-zero.c.expected |
---|
0,0 → 1,3 |
0:1(12): preprocessor error: division by 0 in preprocessor directive |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/094-divide-by-zero-short-circuit.c |
---|
0,0 → 1,13 |
/* glcpp is generating a division-by-zero error for this case. It's |
* easy to argue that it should be short-circuiting the evaluation and |
* not generating the diagnostic (which happens to be what gcc does). |
* But it doesn't seem like we should force this behavior on our |
* pre-processor, (and, as always, the GLSL specification of the |
* pre-processor is too vague on this point). |
* |
* If a short-circuit evaluation optimization does get added to the |
* pre-processor then it would legitimate to update the expected file |
* for this test. |
*/ |
#if 1 || (1 / 0) |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/094-divide-by-zero-short-circuit.c.expected |
---|
0,0 → 1,14 |
0:12(17): preprocessor error: division by 0 in preprocessor directive |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/095-recursive-define.c |
---|
0,0 → 1,3 |
#define A(a, b) B(a, b) |
#define C A(0, C) |
C |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/095-recursive-define.c.expected |
---|
0,0 → 1,3 |
B(0, C) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/096-paste-twice.c |
---|
0,0 → 1,3 |
#define paste_twice(a,b,c) a ## b ## c |
paste_twice(just, one, token) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/096-paste-twice.c.expected |
---|
0,0 → 1,3 |
justonetoken |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/097-paste-with-non-function-macro.c |
---|
0,0 → 1,3 |
#define PASTE_MACRO one ## token |
PASTE_MACRO |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/097-paste-with-non-function-macro.c.expected |
---|
0,0 → 1,3 |
onetoken |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/098-elif-undefined.c |
---|
0,0 → 1,7 |
#if 0 |
Not this |
#elif UNDEFINED_MACRO |
Nor this |
#else |
Yes, this. |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/098-elif-undefined.c.expected |
---|
0,0 → 1,7 |
Yes, this. |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/099-c99-example.c |
---|
0,0 → 1,17 |
#define x 3 |
#define f(a) f(x * (a)) |
#undef x |
#define x 2 |
#define g f |
#define z z[0] |
#define h g(~ |
#define m(a) a(w) |
#define w 0,1 |
#define t(a) a |
#define p() int |
#define q(x) x |
#define r(x,y) x ## y |
f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); |
g(x +(3,4)-w) | h 5) & m |
(f)^m(m); |
p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,)}; |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/099-c99-example.c.expected |
---|
0,0 → 1,16 |
f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1); |
f(2 * (2 +(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1); |
int i[] = { 1, 23, 4, 5, }; |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/100-macro-with-colon.c |
---|
0,0 → 1,7 |
#define one 1 |
#define two 2 |
switch (1) { |
case one + two: |
break; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/100-macro-with-colon.c.expected |
---|
0,0 → 1,7 |
switch (1) { |
case 1 + 2: |
break; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/101-macros-used-twice.c |
---|
0,0 → 1,16 |
#define object 1 |
#define function(x) 1 |
#if object |
once |
#endif |
#if object |
twice |
#endif |
#if function(0) |
once |
#endif |
#if function(0) |
once again |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/101-macros-used-twice.c.expected |
---|
0,0 → 1,16 |
once |
twice |
once |
once again |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/102-garbage-after-endif.c |
---|
0,0 → 1,2 |
#if 0 |
#endif garbage |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/102-garbage-after-endif.c.expected |
---|
0,0 → 1,2 |
0:2(8): preprocessor error: syntax error, unexpected IDENTIFIER, expecting NEWLINE |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/103-garbage-after-else-0.c |
---|
0,0 → 1,3 |
#if 0 |
#else garbage |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/103-garbage-after-else-0.c.expected |
---|
0,0 → 1,4 |
0:2(7): preprocessor error: syntax error, unexpected IDENTIFIER, expecting NEWLINE |
0:1(6): preprocessor error: Unterminated #if |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/104-hash-line-followed-by-code.c |
---|
0,0 → 1,2 |
#line 2 |
int foo(); |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/104-hash-line-followed-by-code.c.expected |
---|
0,0 → 1,2 |
#line 2 |
int foo(); |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/105-multiline-hash-line.c |
---|
0,0 → 1,5 |
#define X(x) x |
#line X( \ |
1 \ |
) |
#line 2 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/105-multiline-hash-line.c.expected |
---|
0,0 → 1,5 |
#line 1 |
#line 2 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/106-multiline-hash-if.c |
---|
0,0 → 1,6 |
#define X(x) x |
#if X( \ |
1 \ |
) |
int foo(); |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/106-multiline-hash-if.c.expected |
---|
0,0 → 1,6 |
int foo(); |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/107-multiline-hash-elif.c |
---|
0,0 → 1,7 |
#define X(x) x |
#if 0 |
#elif X( \ |
1 \ |
) |
int foo(); |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/107-multiline-hash-elif.c.expected |
---|
0,0 → 1,7 |
int foo(); |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/108-no-space-after-hash-version.c |
---|
0,0 → 1,0 |
#version110 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/108-no-space-after-hash-version.c.expected |
---|
0,0 → 1,0 |
0:1(1): preprocessor error: Illegal non-directive after # |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/109-no-space-after-hash-line.c |
---|
0,0 → 1,0 |
#line2 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/109-no-space-after-hash-line.c.expected |
---|
0,0 → 1,0 |
0:1(1): preprocessor error: Illegal non-directive after # |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/110-no-space-digits-after-hash-elif.c |
---|
0,0 → 1,3 |
#if 1 |
#elif110 |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/110-no-space-digits-after-hash-elif.c.expected |
---|
0,0 → 1,3 |
0:2(1): preprocessor error: Illegal non-directive after # |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/111-no-space-operator-after-hash-if.c |
---|
0,0 → 1,19 |
#if(1) |
success |
#endif |
#if+1 |
success |
#endif |
#if-1 |
success |
#endif |
#if!1 |
success |
#endif |
#if~1 |
success |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/111-no-space-operator-after-hash-if.c.expected |
---|
0,0 → 1,19 |
success |
success |
success |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/112-no-space-operator-after-hash-elif.c |
---|
0,0 → 1,24 |
#if 0 |
#elif(1) |
success |
#endif |
#if 0 |
#elif+1 |
success |
#endif |
#if 0 |
#elif-1 |
success |
#endif |
#if 0 |
#elif!1 |
success |
#endif |
#if 0 |
#elif~1 |
success |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/112-no-space-operator-after-hash-elif.c.expected |
---|
0,0 → 1,24 |
success |
success |
success |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/113-line-and-file-macros.c |
---|
0,0 → 1,7 |
1. Number of dalmations: __LINE__ __FILE__ __LINE__ |
2. Nominal visual acuity: __LINE__ __FILE__ / __LINE__ __FILE__ |
3. Battle of Thermopylae, as film: __LINE__ __FILE__ __FILE__ |
4. HTTP code for "Not Found": __LINE__ __FILE__ __LINE__ |
5. Hexadecimal for 20560: __LINE__ __FILE__ __LINE__ __FILE__ |
6: Zip code for Nortonville, KS: __LINE__ __LINE__ __FILE__ __LINE__ __FILE__ |
7. James Bond, as a number: __FILE__ __FILE__ __LINE__ |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/113-line-and-file-macros.c.expected |
---|
0,0 → 1,7 |
1. Number of dalmations: 1 0 1 |
2. Nominal visual acuity: 2 0 / 2 0 |
3. Battle of Thermopylae, as film: 3 0 0 |
4. HTTP code for "Not Found": 4 0 4 |
5. Hexadecimal for 20560: 5 0 5 0 |
6: Zip code for Nortonville, KS: 6 6 0 6 0 |
7. James Bond, as a number: 0 0 7 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/114-paste-integer-tokens.c |
---|
0,0 → 1,7 |
#define PASTE3(a,b,c) a ## b ## c |
#define PASTE4(a,b,c,d) a ## b ## c ## d |
#define PASTE5(a,b,c,d,e) a ## b ## c ## d ## e |
4. HTTP code for "Not Found": PASTE3(__LINE__, __FILE__ , __LINE__) |
5. Hexadecimal for 20560: PASTE4(__LINE__, __FILE__, __LINE__, __FILE__) |
6: Zip code for Nortonville, KS: PASTE5(__LINE__, __LINE__, __FILE__, __LINE__, __FILE__) |
7. James Bond, as a number: PASTE3(__FILE__, __FILE__, __LINE__) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/114-paste-integer-tokens.c.expected |
---|
0,0 → 1,7 |
4. HTTP code for "Not Found": 404 |
5. Hexadecimal for 20560: 5050 |
6: Zip code for Nortonville, KS: 66060 |
7. James Bond, as a number: 007 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/115-line-continuations.c |
---|
0,0 → 1,9 |
// This comment continues to the next line, hiding the define \ |
#define CONTINUATION_UNSUPPORTED |
#ifdef CONTINUATION_UNSUPPORTED |
failure |
#else |
success |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/115-line-continuations.c.expected |
---|
0,0 → 1,9 |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/116-disable-line-continuations.c |
---|
0,0 → 1,13 |
// glcpp-args: --disable-line-continuations |
// This comments ends with a backslash \\ |
#define NO_CONTINUATION |
#ifdef NO_CONTINUATION |
success |
#else |
failure |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/116-disable-line-continuations.c.expected |
---|
0,0 → 1,13 |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/117-line-continuation-and-non-continuation-backslash.c |
---|
0,0 → 1,12 |
/* This test case is the minimal case to replicate the bug reported here: |
* |
* https://bugs.freedesktop.org/show_bug.cgi?id=65112 |
* |
* To trigger the bug, there must be a line-continuation sequence |
* (backslash newline), then an additional newline character, and |
* finally another backslash that is not part of a line-continuation |
* sequence. |
*/ |
\ |
/* \ */ |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/117-line-continuation-and-non-continuation-backslash.c.expected |
---|
0,0 → 1,12 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/118-comment-becomes-space.c |
---|
0,0 → 1,4 |
#define FOO first/* |
*/second |
FOO |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/118-comment-becomes-space.c.expected |
---|
0,0 → 1,4 |
first second |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/119-elif-after-else.c |
---|
0,0 → 1,6 |
#if 0 |
#else |
int foo; |
#elif 0 |
int bar; |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/119-elif-after-else.c.expected |
---|
0,0 → 1,7 |
0:4(1): preprocessor error: #elif after #else |
int foo; |
int bar; |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/120-undef-builtin.c |
---|
0,0 → 1,3 |
#undef __LINE__ |
#undef __FILE__ |
#undef __VERSION__ |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/120-undef-builtin.c.expected |
---|
0,0 → 1,6 |
0:1(1): preprocessor error: Built-in (pre-defined) macro names cannot be undefined. |
0:2(1): preprocessor error: Built-in (pre-defined) macro names cannot be undefined. |
0:3(1): preprocessor error: Built-in (pre-defined) macro names cannot be undefined. |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/121-comment-bug-72686.c |
---|
0,0 → 1,2 |
/* |
*/ // |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/121-comment-bug-72686.c.expected |
---|
0,0 → 1,2 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/122-redefine-whitespace.c |
---|
0,0 → 1,16 |
/* Original definitions. */ |
#define TWO ( 1+1 ) |
#define FOUR (2 + 2) |
#define SIX (3 + 3) |
/* Redefinitions with whitespace in same places, but different amounts, (so no |
* error). */ |
#define TWO ( 1+1 ) |
#define FOUR (2 + 2) |
#define SIX (3/*comment is whitespace*/+ /* collapsed */ /* to */ /* one */ /* space */ 3) |
/* Redefinitions with whitespace in different places. Each of these should |
* trigger an error. */ |
#define TWO (1 + 1) |
#define FOUR ( 2+2 ) |
#define SIX (/*not*/3 + 3/*expected*/) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/122-redefine-whitespace.c.expected |
---|
0,0 → 1,22 |
0:14(9): preprocessor error: Redefinition of macro TWO |
0:15(9): preprocessor error: Redefinition of macro FOUR |
0:16(9): preprocessor error: Redefinition of macro SIX |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/123-garbage-after-else-1.c |
---|
0,0 → 1,3 |
#if 1 |
#else garbage |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/123-garbage-after-else-1.c.expected |
---|
0,0 → 1,4 |
0:2(7): preprocessor error: syntax error, unexpected IDENTIFIER, expecting NEWLINE |
0:1(6): preprocessor error: Unterminated #if |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/124-preprocessing-numbers.c |
---|
0,0 → 1,37 |
#define e THIS_SHOULD_NOT_BE_EXPANDED |
#define E NOR_THIS |
#define p NOT_THIS_EITHER |
#define P AND_SURELY_NOT_THIS |
#define OK CRAZY_BUT_TRUE_THIS_NEITHER |
/* This one is actually meant to be expanded */ |
#define MUST_EXPAND GO |
/* The following are "preprocessing numbers" and should not trigger macro |
* expansion. */ |
1e |
1OK |
/* These are also "preprocessing numbers", so no expansion */ |
123e+OK |
.23E+OK |
1.3e-OK |
12.E-OK |
123p+OK |
.23P+OK |
1.3p-OK |
12.P-OK |
123..OK |
.23.OK.OK |
/* Importantly, just before the MUST_EXPAND in each of these, the preceding |
* "preprocessing number" ends and we have an actual expression. So the |
* MUST_EXPAND macro must be expanded (who would have though?) in each case. */ |
123ef+MUST_EXPAND |
.23E3-MUST_EXPAND |
1.3e--MUST_EXPAND |
12.E-&MUST_EXPAND |
123p+OK+MUST_EXPAND |
.23P+OK;MUST_EXPAND |
1.3p-OK-MUST_EXPAND |
12.P-OK&MUST_EXPAND |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/124-preprocessing-numbers.c.expected |
---|
0,0 → 1,37 |
1e |
1OK |
123e+OK |
.23E+OK |
1.3e-OK |
12.E-OK |
123p+OK |
.23P+OK |
1.3p-OK |
12.P-OK |
123..OK |
.23.OK.OK |
123ef+GO |
.23E3-GO |
1.3e--GO |
12.E-&GO |
123p+OK+GO |
.23P+OK;GO |
1.3p-OK-GO |
12.P-OK&GO |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/125-es-short-circuit-undefined.c |
---|
0,0 → 1,27 |
/* For GLSL in OpenGL ES, an undefined macro appearing in an #if or #elif |
* expression, (other than as an argument to defined) is an error. |
* |
* Except in the case of a short-circuiting && or || operator, where the |
* specification explicitly mandates that there be no error. |
*/ |
#version 300 es |
/* These yield errors */ |
#if NOT_DEFINED |
#endif |
#if 0 |
#elif ALSO_NOT_DEFINED |
#endif |
/* But these yield no errors */ |
#if 1 || STILL_NOT_DEFINED |
Success |
#endif |
#if 0 |
#elif 0 && WILL_ANYONE_DEFINE_ANYTHING |
#else |
More success |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/125-es-short-circuit-undefined.c.expected |
---|
0,0 → 1,29 |
0:10(16): preprocessor error: undefined macro NOT_DEFINED in expression (illegal in GLES) |
0:14(23): preprocessor error: undefined macro ALSO_NOT_DEFINED in expression (illegal in GLES) |
#version 300 es |
Success |
More success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/126-garbage-after-directive.c |
---|
0,0 → 1,5 |
#ifdef MACRO garbage |
#endif |
#ifndef MORE garbage |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/126-garbage-after-directive.c.expected |
---|
0,0 → 1,7 |
0:1(14): preprocessor error: extra tokens at end of directive |
0:4(14): preprocessor error: extra tokens at end of directive |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/127-pragma-empty.c |
---|
0,0 → 1,3 |
/* It seems an odd (and particularly useless) thing to have an empty pragma, |
* but we probably shouldn't trigger an error in this case. */ |
#pragma |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/127-pragma-empty.c.expected |
---|
0,0 → 1,3 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/128-space-before-hash.c |
---|
0,0 → 1,21 |
/* Any directive can be preceded by a space. */ |
#version 300 |
#pragma Testing spaces before hash |
# |
#line 3 |
#define FOO |
#ifdef FOO |
yes |
#endif |
#if 0 |
#elif defined FOO |
yes again |
#endif |
#if 0 |
#else |
for the third time, yes! |
#endif |
#undef FOO |
#ifndef FOO |
yes, of course |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/128-space-before-hash.c.expected |
---|
0,0 → 1,21 |
#version 300 |
#pragma Testing spaces before hash |
#line 3 |
yes |
yes again |
for the third time, yes! |
yes, of course |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/129-define-non-identifier.c |
---|
0,0 → 1,0 |
#define 123 456 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/129-define-non-identifier.c.expected |
---|
0,0 → 1,2 |
0:1(9): preprocessor error: #define followed by a non-identifier: 123 |
0:1(9): preprocessor error: syntax error, unexpected INTEGER_STRING, expecting FUNC_IDENTIFIER or OBJ_IDENTIFIER |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/130-define-comment.c |
---|
0,0 → 1,2 |
#define /*...*/ FUNC( /*...*/ x /*...*/ ) /*...*/ FOO( /*...*/ x /*...*/ ) |
FUNC(bar) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/130-define-comment.c.expected |
---|
0,0 → 1,2 |
FOO( bar ) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/131-eof-without-newline.c |
---|
0,0 → 1,0 |
this file ends with no newline |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/131-eof-without-newline.c.expected |
---|
0,0 → 1,0 |
this file ends with no newline |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/132-eof-without-newline-define.c |
---|
0,0 → 1,0 |
#define |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/132-eof-without-newline-define.c.expected |
---|
0,0 → 1,0 |
0:1(1): preprocessor error: #define without macro name |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/133-eof-without-newline-comment.c |
---|
0,0 → 1,0 |
This file ends with no newline within a comment /* |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/133-eof-without-newline-comment.c.expected |
---|
0,0 → 1,2 |
0:1(51): preprocessor error: Unterminated comment |
This file ends with no newline within a comment |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/134-hash-comment-directive.c |
---|
0,0 → 1,22 |
/*...*/ # /*...*/ version 300 |
/*...*/#/*...*/ extension whatever |
/*..*/ # /*..*/ pragma ignored |
/**/ # /**/ line 4 |
/*...*/# /*...*/ ifdef NOT_DEFINED |
/*...*/# /*...*/ else |
/*..*/ #/*..*/ endif |
/*...*/# /*...*/ ifndef ALSO_NOT_DEFINED |
/*...*/# /*...*/ else |
/*..*/ #/*..*/ endif |
/*...*/ # /*...*/ if 0 |
/*...*/#/*...*/ elif 1 |
/*..*/ # /*..*/ else |
/**/ # /**/ endif |
/*...*/# /*...*/ define FOO bar |
/*..*/ #/*..*/ define FUNC() baz |
/*..*/ # /*..*/ define FUNC2(a,b) b a |
FOO |
FUNC() |
FUNC2(x,y) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/134-hash-comment-directive.c.expected |
---|
0,0 → 1,22 |
#version 300 |
#extension whatever |
#pragma ignored |
#line 4 |
bar |
baz |
y x |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/135-duplicate-parameter.c |
---|
0,0 → 1,2 |
#define FOO(a,a) which a? |
#define BAR(x,y,z,x) so very x |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/135-duplicate-parameter.c.expected |
---|
0,0 → 1,4 |
0:1(9): preprocessor error: Duplicate macro parameter "a" |
0:2(9): preprocessor error: Duplicate macro parameter "x" |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/136-plus-plus-and-minus-minus.c |
---|
0,0 → 1,8 |
/* The body can include C expressions with ++ and -- */ |
a = x++; |
b = ++x; |
c = x--; |
d = --x; |
/* But these are not legal in preprocessor expressions. */ |
#if x++ > 4 |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/136-plus-plus-and-minus-minus.c.expected |
---|
0,0 → 1,8 |
0:7(12): preprocessor error: syntax error, unexpected PLUS_PLUS |
a = x++; |
b = ++x; |
c = x--; |
d = --x; |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/137-expand-macro-after-period.c |
---|
0,0 → 1,4 |
#define FIELD(x) foo.x |
#define FIELD_OF(s, x) s.x |
FIELD(bar) |
FIELD_OF(foo, bar) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/137-expand-macro-after-period.c.expected |
---|
0,0 → 1,4 |
foo.bar |
foo.bar |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/138-multi-line-comment-in-if-0.c |
---|
0,0 → 1,7 |
#if 0 |
/* |
* This multi-line comment needs to be 3 lines to test what's intended. |
*/ |
#else |
SUCCESS |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/138-multi-line-comment-in-if-0.c.expected |
---|
0,0 → 1,7 |
SUCCESS |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/139-define-without-macro-name.c |
---|
0,0 → 1,5 |
#define |
#define |
#define /*...*/ |
#define //... |
Errors expected because no macro name is ever given! |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/139-define-without-macro-name.c.expected |
---|
0,0 → 1,5 |
0:1(1): preprocessor error: #define without macro name |
0:2(1): preprocessor error: #define without macro name |
0:3(1): preprocessor error: #define without macro name |
0:4(1): preprocessor error: #define without macro name |
Errors expected because no macro name is ever given! |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/140-null-directive.c |
---|
0,0 → 1,9 |
/* GLSL accepts a null directive. Let's test that in several variations: */ |
# |
# |
/*....*/#/*....*/ |
/*..*/ # /*..*/ |
#//... |
# //... |
/*....*/#/**///.. |
/*..*/ # /**/ // |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/140-null-directive.c.expected |
---|
0,0 → 1,9 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/141-pragma-and-__LINE__.c |
---|
0,0 → 1,6 |
Line 1 /* Test for a bug where #pragma was throwing off the __LINE__ count. */ |
Line __LINE__ /* Line 2 */ |
#pragma Line 3 |
Line __LINE__ /* Line 4 */ |
#pragma Line 5 |
Line __LINE__ /* Line 6 */ |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/141-pragma-and-__LINE__.c.expected |
---|
0,0 → 1,6 |
Line 1 |
Line 2 |
#pragma Line 3 |
Line 4 |
#pragma Line 5 |
Line 6 |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/142-defined-within-macro.c |
---|
0,0 → 1,94 |
/* Macro using defined with a hard-coded identifier (no parentheses) */ |
#define is_foo_defined defined /*...*/ foo |
#undef foo |
#if is_foo_defined |
failure |
#else |
success |
#endif |
#define foo |
#if is_foo_defined |
success |
#else |
failure |
#endif |
/* Macro using defined with a hard-coded identifier within parentheses */ |
#define is_foo_defined_parens defined /*...*/ ( /*...*/ foo /*...*/ ) // |
#define foo |
#if is_foo_defined_parens |
success |
#else |
failure |
#endif |
#undef foo |
#if is_foo_defined_parens |
failure |
#else |
success |
#endif |
/* Macro using defined with an argument identifier (no parentheses) */ |
#define is_defined(arg) defined /*...*/ arg |
#define foo bar |
#undef bar |
#if is_defined(foo) |
failure |
#else |
success |
#endif |
#define bar bar |
#if is_defined(foo) |
success |
#else |
failure |
#endif |
/* Macro using defined with an argument identifier within parentheses */ |
#define is_defined_parens(arg) defined /*...*/ ( /*...*/ arg /*...*/ ) // |
#define foo bar |
#define bar bar |
#if is_defined_parens(foo) |
success |
#else |
failure |
#endif |
#undef bar |
#if is_defined_parens(foo) |
failure |
#else |
success |
#endif |
/* Multiple levels of macro resulting in defined */ |
#define X defined A && Y |
#define Y defined B && Z |
#define Z defined C |
#define A |
#define B |
#define C |
#if X |
success |
#else |
failure |
#endif |
#undef A |
#if X |
failure |
#else |
success |
#endif |
#define A |
#undef B |
#if X |
failure |
#else |
success |
#endif |
#define B |
#undef C |
#if X |
failure |
#else |
success |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/142-defined-within-macro.c.expected |
---|
0,0 → 1,94 |
success |
success |
success |
success |
success |
success |
success |
success |
success |
success |
success |
success |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/143-multiple-else.c |
---|
0,0 → 1,6 |
#if 0 |
#else |
int foo; |
#else |
int bar; |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/143-multiple-else.c.expected |
---|
0,0 → 1,7 |
0:4(1): preprocessor error: multiple #else |
int foo; |
int bar; |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/glcpp-test |
---|
0,0 → 1,110 |
#!/bin/sh |
if [ ! -z "$srcdir" ]; then |
testdir=$srcdir/glcpp/tests |
outdir=`pwd`/glcpp/tests |
glcpp=`pwd`/glcpp/glcpp |
else |
testdir=. |
outdir=. |
glcpp=../glcpp |
fi |
trap 'rm $test.valgrind-errors; exit 1' INT QUIT |
usage () |
{ |
cat <<EOF |
Usage: glcpp [options...] |
Run the test suite for mesa's GLSL pre-processor. |
Valid options include: |
--testdir=<DIR> Use tests in the given <DIR> (default is ".") |
--valgrind Run the test suite a second time under valgrind |
EOF |
} |
test_specific_args () |
{ |
test="$1" |
tr "\r" "\n" < "$test" | grep 'glcpp-args:' | sed -e 's,^.*glcpp-args: *,,' |
} |
# Parse command-line options |
for option; do |
case "${option}" in |
"--help") |
usage |
exit 0 |
;; |
"--valgrind") |
do_valgrind=yes |
;; |
"--testdir="*) |
testdir="${option#--testdir=}" |
outdir="${outdir}/${option#--testdir=}" |
;; |
*) |
echo "Unrecognized option: $option" >&2 |
echo >&2 |
usage |
exit 1 |
;; |
esac |
done |
total=0 |
pass=0 |
clean=0 |
mkdir -p $outdir |
echo "====== Testing for correctness ======" |
for test in $testdir/*.c; do |
out=$outdir/${test##*/}.out |
printf "Testing $test... > $out ($test.expected) " |
$glcpp $(test_specific_args $test) < $test > $out 2>&1 |
total=$((total+1)) |
if cmp $test.expected $out >/dev/null 2>&1; then |
echo "PASS" |
pass=$((pass+1)) |
else |
echo "FAIL" |
diff -u $test.expected $out |
fi |
done |
echo "" |
echo "$pass/$total tests returned correct results" |
echo "" |
if [ "$do_valgrind" = "yes" ]; then |
echo "====== Testing for valgrind cleanliness ======" |
for test in $testdir/*.c; do |
printf "Testing $test with valgrind..." |
valgrind --error-exitcode=31 --log-file=$test.valgrind-errors $glcpp $(test_specific_args $test) < $test >/dev/null 2>&1 |
if [ "$?" = "31" ]; then |
echo "ERRORS" |
cat $test.valgrind-errors |
else |
echo "CLEAN" |
clean=$((clean+1)) |
rm $test.valgrind-errors |
fi |
done |
echo "" |
echo "$pass/$total tests returned correct results" |
echo "$clean/$total tests are valgrind-clean" |
fi |
if [ "$pass" = "$total" ] && [ "$do_valgrind" != "yes" ] || [ "$pass" = "$total" ]; then |
exit 0 |
else |
exit 1 |
fi |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/glcpp/tests/glcpp-test-cr-lf |
---|
0,0 → 1,143 |
#!/bin/sh |
# The build system runs this test from a different working directory, and may |
# be in a build directory entirely separate from the source. So if the |
# "srcdir" variable is set, we must use it to locate the test files and the |
# glcpp-test script. |
if [ ! -z "$srcdir" ]; then |
testdir="$srcdir/glcpp/tests" |
glcpp_test="$srcdir/glcpp/tests/glcpp-test" |
else |
testdir=. |
glcpp_test=./glcpp-test |
fi |
total=0 |
pass=0 |
# This supports a pipe that doesn't destroy the exit status of first command |
# |
# http://unix.stackexchange.com/questions/14270/get-exit-status-of-process-thats-piped-to-another |
stdintoexitstatus() { |
read exitstatus |
return $exitstatus |
} |
run_test () |
{ |
cmd="$1" |
total=$((total+1)) |
if [ "$VERBOSE" = "yes" ]; then |
if $cmd; then |
echo "PASS" |
pass=$((pass+1)) |
else |
echo "FAIL" |
fi |
else |
# This is "$cmd | tail -2" but with the exit status of "$cmd" not "tail -2" |
if (((($cmd; echo $? >&3) | tail -2 | head -1 >&4) 3>&1) | stdintoexitstatus) 4>&1; then |
echo "PASS" |
pass=$((pass+1)) |
else |
echo "FAIL" |
fi |
fi |
} |
usage () |
{ |
cat <<EOF |
Usage: glcpp-cr-lf [options...] |
Run the entire glcpp-test suite several times, each time with each source |
file transformed to use a non-standard line-termination character. Each |
entire run with a different line-termination character is considered a |
single test. |
Valid options include: |
-v|--verbose Print all output from the various sub-tests |
EOF |
} |
# Parse command-line options |
for option; do |
case "${option}" in |
-v|--verbose) |
VERBOSE=yes; |
;; |
*) |
echo "Unrecognized option: $option" >&2 |
echo >&2 |
usage |
exit 1 |
;; |
esac |
done |
# All tests depend on the .out files being present. So first do a |
# normal run of the test suite, (silently) just to create the .out |
# files as a side effect. |
rm -rf ./subtest-lf |
mkdir subtest-lf |
for file in "$testdir"/*.c; do |
base=$(basename "$file") |
cp "$file" subtest-lf |
done |
${glcpp_test} --testdir=subtest-lf >/dev/null 2>&1 |
echo "===== Testing with \\\\r line terminators (old Mac format) =====" |
# Prepare test files with '\r' instead of '\n' |
rm -rf ./subtest-cr |
mkdir subtest-cr |
for file in "$testdir"/*.c; do |
base=$(basename "$file") |
tr "\n" "\r" < "$file" > subtest-cr/"$base" |
cp `pwd`/glcpp/tests/subtest-lf/"$base".out subtest-cr/"$base".expected |
done |
run_test "${glcpp_test} --testdir=subtest-cr" |
echo "===== Testing with \\\\r\\\\n line terminators (DOS format) =====" |
# Prepare test files with '\r\n' instead of '\n' |
rm -rf ./subtest-cr-lf |
mkdir subtest-cr-lf |
for file in "$testdir"/*.c; do |
base=$(basename "$file") |
+/' < "$file" > subtest-cr-lf/"$base" |
+ cp `pwd`/glcpp/tests/subtest-lf/"$base".out subtest-cr-lf/"$base".expected |
+done |
+ |
+run_test "${glcpp_test} --testdir=subtest-cr-lf" |
+ |
+echo "===== Testing with \\\\n\\\\r (bizarre, but allowed by GLSL spec.) =====" |
+ |
+# Prepare test files with '\n\r' instead of '\n' |
+rm -rf ./subtest-lf-cr |
+mkdir subtest-lf-cr |
+for file in "$testdir"/*.c; do |
+ base=$(basename "$file") |
+/' < "$file" | tr "\n\r" "\r\n" > subtest-lf-cr/"$base" |
+ cp `pwd`/glcpp/tests/subtest-lf/"$base".out subtest-lf-cr/"$base".expected |
+done |
+ |
+run_test "${glcpp_test} --testdir=subtest-lf-cr" |
+ |
+echo "" |
+echo "$pass/$total tests returned correct results" |
+echo "" |
+ |
+if [ "$pass" = "$total" ]; then |
+ exit 0 |
+else |
+ exit 1 |
+fi |