1 : /****************************************************************************\
2 : Copyright (c) 2002, NVIDIA Corporation.
3 :
4 : NVIDIA Corporation("NVIDIA") supplies this software to you in
5 : consideration of your agreement to the following terms, and your use,
6 : installation, modification or redistribution of this NVIDIA software
7 : constitutes acceptance of these terms. If you do not agree with these
8 : terms, please do not use, install, modify or redistribute this NVIDIA
9 : software.
10 :
11 : In consideration of your agreement to abide by the following terms, and
12 : subject to these terms, NVIDIA grants you a personal, non-exclusive
13 : license, under NVIDIA's copyrights in this original NVIDIA software (the
14 : "NVIDIA Software"), to use, reproduce, modify and redistribute the
15 : NVIDIA Software, with or without modifications, in source and/or binary
16 : forms; provided that if you redistribute the NVIDIA Software, you must
17 : retain the copyright notice of NVIDIA, this notice and the following
18 : text and disclaimers in all such redistributions of the NVIDIA Software.
19 : Neither the name, trademarks, service marks nor logos of NVIDIA
20 : Corporation may be used to endorse or promote products derived from the
21 : NVIDIA Software without specific prior written permission from NVIDIA.
22 : Except as expressly stated in this notice, no other rights or licenses
23 : express or implied, are granted by NVIDIA herein, including but not
24 : limited to any patent rights that may be infringed by your derivative
25 : works or by other works in which the NVIDIA Software may be
26 : incorporated. No hardware is licensed hereunder.
27 :
28 : THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
29 : WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
30 : INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
31 : NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
32 : ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
33 : PRODUCTS.
34 :
35 : IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
36 : INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
37 : TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
38 : USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
39 : OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
40 : NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
41 : TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
42 : NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 : \****************************************************************************/
44 : //
45 : // scanner.c
46 : //
47 :
48 : #include <assert.h>
49 : #include <stdarg.h>
50 : #include <stdio.h>
51 : #include <stdlib.h>
52 : #include <string.h>
53 :
54 : #if 0
55 : #include <ieeefp.h>
56 : #else
57 : #define isinff(x) (((*(int *)&(x) & 0x7f800000L)==0x7f800000L) && \
58 : ((*(int *)&(x) & 0x007fffffL)==0000000000L))
59 : #endif
60 :
61 : #include "compiler/preprocessor/slglobals.h"
62 : #include "compiler/util.h"
63 :
64 : typedef struct StringInputSrc {
65 : InputSrc base;
66 : char *p;
67 : } StringInputSrc;
68 :
69 0 : static int eof_scan(InputSrc *is, yystypepp * yylvalpp)
70 : {
71 0 : return EOF;
72 : } // eof_scan
73 :
74 0 : static void noop(InputSrc *in, int ch, yystypepp * yylvalpp) {}
75 :
76 : static InputSrc eof_inputsrc = { 0, &eof_scan, &eof_scan, &noop };
77 :
78 : static int byte_scan(InputSrc *, yystypepp * yylvalpp);
79 :
80 : #define EOL_SY '\n'
81 :
82 : #if defined(_MSC_VER)
83 : #define DBG_BREAKPOINT() __asm int 3
84 : #elif defined(_M_AMD64)
85 : #define DBG_BREAKPOINT() assert(!"Dbg_Breakpoint");
86 : #else
87 : #define DBG_BREAKPOINT()
88 : #endif
89 :
90 : #if defined(_MSC_VER) && !defined(_M_AMD64)
91 : __int64 RDTSC ( void ) {
92 :
93 : __int64 v;
94 :
95 : __asm __emit 0x0f
96 : __asm __emit 0x31
97 : __asm mov dword ptr v, eax
98 : __asm mov dword ptr v+4, edx
99 :
100 : return v;
101 : }
102 : #endif
103 :
104 :
105 0 : int InitScanner(CPPStruct *cpp)
106 : {
107 : // Add various atoms needed by the CPP line scanner:
108 0 : if (!InitCPP())
109 0 : return 0;
110 :
111 0 : cpp->mostRecentToken = 0;
112 0 : cpp->tokenLoc = &cpp->ltokenLoc;
113 :
114 0 : cpp->ltokenLoc.file = 0;
115 0 : cpp->ltokenLoc.line = 0;
116 :
117 0 : cpp->currentInput = &eof_inputsrc;
118 0 : cpp->previous_token = '\n';
119 0 : cpp->pastFirstStatement = 0;
120 :
121 0 : return 1;
122 : } // InitScanner
123 :
124 0 : int FreeScanner(void)
125 : {
126 0 : return (FreeCPP());
127 : }
128 :
129 : /*
130 : * str_getch()
131 : * takes care of reading from multiple strings.
132 : * returns the next-char from the input stream.
133 : * returns EOF when the complete shader is parsed.
134 : */
135 0 : static int str_getch(StringInputSrc *in)
136 : {
137 : for(;;){
138 0 : if (*in->p){
139 0 : if (*in->p == '\n') {
140 0 : in->base.line++;
141 0 : IncLineNumber();
142 : }
143 0 : return *in->p++;
144 : }
145 0 : if(++(cpp->PaWhichStr) < cpp->PaArgc){
146 0 : free(in);
147 0 : SetStringNumber(cpp->PaWhichStr);
148 0 : SetLineNumber(1);
149 0 : ScanFromString(cpp->PaArgv[cpp->PaWhichStr]);
150 0 : in=(StringInputSrc*)cpp->currentInput;
151 0 : continue;
152 : }
153 : else{
154 0 : cpp->currentInput = in->base.prev;
155 0 : cpp->PaWhichStr=0;
156 0 : free(in);
157 0 : return EOF;
158 : }
159 0 : }
160 : } // str_getch
161 :
162 0 : static void str_ungetch(StringInputSrc *in, int ch, yystypepp *type) {
163 0 : if (in->p[-1] == ch)in->p--;
164 : else {
165 0 : *(in->p)='\0'; //this would take care of shifting to the previous string.
166 0 : cpp->PaWhichStr--;
167 : }
168 0 : if (ch == '\n') {
169 0 : in->base.line--;
170 0 : DecLineNumber();
171 : }
172 0 : } // str_ungetch
173 :
174 0 : int ScanFromString(const char *s)
175 : {
176 :
177 0 : StringInputSrc *in = malloc(sizeof(StringInputSrc));
178 0 : memset(in, 0, sizeof(StringInputSrc));
179 0 : in->p = (char*) s;
180 0 : in->base.line = 1;
181 0 : in->base.scan = byte_scan;
182 0 : in->base.getch = (int (*)(InputSrc *, yystypepp *))str_getch;
183 0 : in->base.ungetch = (void (*)(InputSrc *, int, yystypepp *))str_ungetch;
184 0 : in->base.prev = cpp->currentInput;
185 0 : cpp->currentInput = &in->base;
186 :
187 0 : return 1;
188 : } // ScanFromString;
189 :
190 :
191 : ///////////////////////////////////////////////////////////////////////////////////////////////
192 : /////////////////////////////////// Floating point constants: /////////////////////////////////
193 : ///////////////////////////////////////////////////////////////////////////////////////////////
194 :
195 : #define APPEND_CHAR_S(ch, str, len, max_len) \
196 : if (len < max_len) { \
197 : str[len++] = ch; \
198 : } else if (!alreadyComplained) { \
199 : CPPErrorToInfoLog("BUFFER OVERFLOW"); \
200 : alreadyComplained = 1; \
201 : }
202 :
203 : /*
204 : * lFloatConst() - Scan a floating point constant. Assumes that the scanner
205 : * has seen at least one digit, followed by either a decimal '.' or the
206 : * letter 'e'.
207 : * ch - '.' or 'e'
208 : * len - length of string already copied into yylvalpp->symbol_name.
209 : */
210 :
211 0 : static int lFloatConst(int ch, int len, yystypepp * yylvalpp)
212 : {
213 0 : int alreadyComplained = 0;
214 0 : assert((ch == '.') || (ch == 'e') || (ch == 'E'));
215 :
216 0 : if (ch == '.') {
217 : do {
218 0 : APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
219 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
220 0 : } while (ch >= '0' && ch <= '9');
221 : }
222 :
223 : // Exponent:
224 0 : if (ch == 'e' || ch == 'E') {
225 0 : APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
226 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
227 0 : if (ch == '+') {
228 0 : APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
229 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
230 0 : } else if (ch == '-') {
231 0 : APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
232 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
233 : }
234 0 : if (ch >= '0' && ch <= '9') {
235 0 : while (ch >= '0' && ch <= '9') {
236 0 : APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
237 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
238 : }
239 : } else {
240 0 : CPPErrorToInfoLog("EXPONENT INVALID");
241 : }
242 : }
243 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
244 :
245 0 : assert(len <= MAX_SYMBOL_NAME_LEN);
246 0 : yylvalpp->symbol_name[len] = '\0';
247 0 : yylvalpp->sc_fval = (float) atof_dot(yylvalpp->symbol_name);
248 0 : if (isinff(yylvalpp->sc_fval)) {
249 0 : CPPErrorToInfoLog("FLOAT CONSTANT OVERFLOW");
250 : }
251 0 : return CPP_FLOATCONSTANT;
252 : } // lFloatConst
253 :
254 : ///////////////////////////////////////////////////////////////////////////////////////////////
255 : ///////////////////////////////////////// Normal Scanner //////////////////////////////////////
256 : ///////////////////////////////////////////////////////////////////////////////////////////////
257 :
258 0 : static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
259 : {
260 : char string_val[MAX_STRING_LEN + 1];
261 0 : int alreadyComplained = 0;
262 0 : int len, ch, ii, ival = 0;
263 :
264 : for (;;) {
265 0 : yylvalpp->sc_int = 0;
266 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
267 :
268 0 : while (ch == ' ' || ch == '\t' || ch == '\r') {
269 0 : yylvalpp->sc_int = 1;
270 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
271 : }
272 :
273 0 : cpp->ltokenLoc.file = cpp->currentInput->name;
274 0 : cpp->ltokenLoc.line = cpp->currentInput->line;
275 0 : alreadyComplained = 0;
276 0 : len = 0;
277 0 : switch (ch) {
278 : default:
279 0 : return ch; // Single character token
280 : case EOF:
281 0 : return -1;
282 : case 'A': case 'B': case 'C': case 'D': case 'E':
283 : case 'F': case 'G': case 'H': case 'I': case 'J':
284 : case 'K': case 'L': case 'M': case 'N': case 'O':
285 : case 'P': case 'Q': case 'R': case 'S': case 'T':
286 : case 'U': case 'V': case 'W': case 'X': case 'Y':
287 : case 'Z': case '_':
288 : case 'a': case 'b': case 'c': case 'd': case 'e':
289 : case 'f': case 'g': case 'h': case 'i': case 'j':
290 : case 'k': case 'l': case 'm': case 'n': case 'o':
291 : case 'p': case 'q': case 'r': case 's': case 't':
292 : case 'u': case 'v': case 'w': case 'x': case 'y':
293 : case 'z':
294 : do {
295 0 : APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
296 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
297 0 : } while ((ch >= 'a' && ch <= 'z') ||
298 0 : (ch >= 'A' && ch <= 'Z') ||
299 0 : (ch >= '0' && ch <= '9') ||
300 0 : ch == '_');
301 0 : assert(len <= MAX_SYMBOL_NAME_LEN);
302 0 : yylvalpp->symbol_name[len] = '\0';
303 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
304 0 : yylvalpp->sc_ident = LookUpAddString(atable, yylvalpp->symbol_name);
305 0 : return CPP_IDENTIFIER;
306 : break;
307 : case '0':
308 0 : APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
309 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
310 0 : if (ch == 'x' || ch == 'X') { // hexadecimal integer constants
311 0 : APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
312 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
313 0 : if ((ch >= '0' && ch <= '9') ||
314 0 : (ch >= 'A' && ch <= 'F') ||
315 0 : (ch >= 'a' && ch <= 'f'))
316 : {
317 0 : ival = 0;
318 : do {
319 0 : if ((ival <= 0x0fffffff) && (len < MAX_SYMBOL_NAME_LEN)) {
320 0 : yylvalpp->symbol_name[len++] = ch;
321 0 : if (ch >= '0' && ch <= '9') {
322 0 : ii = ch - '0';
323 0 : } else if (ch >= 'A' && ch <= 'F') {
324 0 : ii = ch - 'A' + 10;
325 : } else {
326 0 : ii = ch - 'a' + 10;
327 : }
328 0 : ival = (ival << 4) | ii;
329 0 : } else if (!alreadyComplained) {
330 0 : CPPErrorToInfoLog("HEX CONSTANT OVERFLOW");
331 0 : alreadyComplained = 1;
332 : }
333 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
334 0 : } while ((ch >= '0' && ch <= '9') ||
335 0 : (ch >= 'A' && ch <= 'F') ||
336 0 : (ch >= 'a' && ch <= 'f'));
337 : } else {
338 0 : CPPErrorToInfoLog("HEX CONSTANT INVALID");
339 : }
340 0 : assert(len <= MAX_SYMBOL_NAME_LEN);
341 0 : yylvalpp->symbol_name[len] = '\0';
342 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
343 0 : yylvalpp->sc_int = ival;
344 0 : return CPP_INTCONSTANT;
345 0 : } else if (ch >= '0' && ch <= '7') { // octal integer constants
346 0 : ival = 0;
347 : do {
348 0 : if ((ival <= 0x1fffffff) && (len < MAX_SYMBOL_NAME_LEN)) {
349 0 : yylvalpp->symbol_name[len++] = ch;
350 0 : ii = ch - '0';
351 0 : ival = (ival << 3) | ii;
352 0 : } else if (!alreadyComplained) {
353 0 : CPPErrorToInfoLog("OCT CONSTANT OVERFLOW");
354 0 : alreadyComplained = 1;
355 : }
356 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
357 0 : } while (ch >= '0' && ch <= '7');
358 0 : if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E')
359 0 : return lFloatConst(ch, len, yylvalpp);
360 0 : assert(len <= MAX_SYMBOL_NAME_LEN);
361 0 : yylvalpp->symbol_name[len] = '\0';
362 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
363 0 : yylvalpp->sc_int = ival;
364 0 : return CPP_INTCONSTANT;
365 : } else {
366 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
367 0 : ch = '0';
368 : }
369 : // Fall through...
370 : case '1': case '2': case '3': case '4':
371 : case '5': case '6': case '7': case '8': case '9':
372 : do {
373 0 : APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
374 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
375 0 : } while (ch >= '0' && ch <= '9');
376 0 : if (ch == '.' || ch == 'e' || ch == 'E') {
377 0 : return lFloatConst(ch, len, yylvalpp);
378 : } else {
379 0 : assert(len <= MAX_SYMBOL_NAME_LEN);
380 0 : yylvalpp->symbol_name[len] = '\0';
381 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
382 0 : ival = 0;
383 0 : for (ii = 0; ii < len; ii++) {
384 0 : ch = yylvalpp->symbol_name[ii] - '0';
385 0 : ival = ival*10 + ch;
386 0 : if ((ival > 214748364) || (ival == 214748364 && ch >= 8)) {
387 0 : CPPErrorToInfoLog("INTEGER CONSTANT OVERFLOW");
388 0 : break;
389 : }
390 : }
391 0 : yylvalpp->sc_int = ival;
392 0 : if(ival==0)
393 0 : strcpy(yylvalpp->symbol_name,"0");
394 0 : return CPP_INTCONSTANT;
395 : }
396 : break;
397 : case '-':
398 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
399 0 : if (ch == '-') {
400 0 : return CPP_DEC_OP;
401 0 : } else if (ch == '=') {
402 0 : return CPP_SUB_ASSIGN;
403 : } else {
404 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
405 0 : return '-';
406 : }
407 : case '+':
408 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
409 0 : if (ch == '+') {
410 0 : return CPP_INC_OP;
411 0 : } else if (ch == '=') {
412 0 : return CPP_ADD_ASSIGN;
413 : } else {
414 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
415 0 : return '+';
416 : }
417 : case '*':
418 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
419 0 : if (ch == '=') {
420 0 : return CPP_MUL_ASSIGN;
421 : } else {
422 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
423 0 : return '*';
424 : }
425 : case '%':
426 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
427 0 : if (ch == '=') {
428 0 : return CPP_MOD_ASSIGN;
429 0 : } else if (ch == '>'){
430 0 : return CPP_RIGHT_BRACE;
431 : } else {
432 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
433 0 : return '%';
434 : }
435 : case ':':
436 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
437 0 : if (ch == '>') {
438 0 : return CPP_RIGHT_BRACKET;
439 : } else {
440 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
441 0 : return ':';
442 : }
443 : case '^':
444 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
445 0 : if (ch == '^') {
446 0 : return CPP_XOR_OP;
447 : } else {
448 0 : if (ch == '=')
449 0 : return CPP_XOR_ASSIGN;
450 : else{
451 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
452 0 : return '^';
453 : }
454 : }
455 :
456 : case '=':
457 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
458 0 : if (ch == '=') {
459 0 : return CPP_EQ_OP;
460 : } else {
461 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
462 0 : return '=';
463 : }
464 : case '!':
465 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
466 0 : if (ch == '=') {
467 0 : return CPP_NE_OP;
468 : } else {
469 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
470 0 : return '!';
471 : }
472 : case '|':
473 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
474 0 : if (ch == '|') {
475 0 : return CPP_OR_OP;
476 : } else {
477 0 : if (ch == '=')
478 0 : return CPP_OR_ASSIGN;
479 : else{
480 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
481 0 : return '|';
482 : }
483 : }
484 : case '&':
485 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
486 0 : if (ch == '&') {
487 0 : return CPP_AND_OP;
488 : } else {
489 0 : if (ch == '=')
490 0 : return CPP_AND_ASSIGN;
491 : else{
492 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
493 0 : return '&';
494 : }
495 : }
496 : case '<':
497 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
498 0 : if (ch == '<') {
499 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
500 0 : if(ch == '=')
501 0 : return CPP_LEFT_ASSIGN;
502 : else{
503 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
504 0 : return CPP_LEFT_OP;
505 : }
506 : } else {
507 0 : if (ch == '=') {
508 0 : return CPP_LE_OP;
509 : } else {
510 0 : if (ch == '%')
511 0 : return CPP_LEFT_BRACE;
512 0 : else if (ch == ':')
513 0 : return CPP_LEFT_BRACKET;
514 : else{
515 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
516 0 : return '<';
517 : }
518 : }
519 : }
520 : case '>':
521 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
522 0 : if (ch == '>') {
523 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
524 0 : if(ch == '=')
525 0 : return CPP_RIGHT_ASSIGN;
526 : else{
527 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
528 0 : return CPP_RIGHT_OP;
529 : }
530 : } else {
531 0 : if (ch == '=') {
532 0 : return CPP_GE_OP;
533 : } else {
534 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
535 0 : return '>';
536 : }
537 : }
538 : case '.':
539 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
540 0 : if (ch >= '0' && ch <= '9') {
541 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
542 0 : return lFloatConst('.', 0, yylvalpp);
543 : } else {
544 0 : if (ch == '.') {
545 0 : return -1; // Special EOF hack
546 : } else {
547 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
548 0 : return '.';
549 : }
550 : }
551 : case '/':
552 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
553 0 : if (ch == '/') {
554 : do {
555 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
556 0 : } while (ch != '\n' && ch != EOF);
557 0 : if (ch == EOF)
558 0 : return -1;
559 0 : return '\n';
560 0 : } else if (ch == '*') {
561 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
562 : do {
563 0 : while (ch != '*') {
564 0 : if (ch == EOF) {
565 0 : CPPErrorToInfoLog("EOF IN COMMENT");
566 0 : return -1;
567 : }
568 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
569 : }
570 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
571 0 : if (ch == EOF) {
572 0 : CPPErrorToInfoLog("EOF IN COMMENT");
573 0 : return -1;
574 : }
575 0 : } while (ch != '/');
576 : // Go try it again...
577 0 : } else if (ch == '=') {
578 0 : return CPP_DIV_ASSIGN;
579 : } else {
580 0 : cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
581 0 : return '/';
582 : }
583 : break;
584 : case '"':
585 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
586 0 : while (ch != '"' && ch != '\n' && ch != EOF) {
587 0 : if (ch == '\\') {
588 0 : CPPErrorToInfoLog("The line continuation character (\\) is not part of the OpenGL ES Shading Language");
589 0 : return -1;
590 : }
591 0 : APPEND_CHAR_S(ch, string_val, len, MAX_STRING_LEN);
592 0 : ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
593 : };
594 0 : assert(len <= MAX_STRING_LEN);
595 0 : string_val[len] = '\0';
596 0 : if (ch == '"') {
597 0 : yylvalpp->sc_ident = LookUpAddString(atable, string_val);
598 0 : return CPP_STRCONSTANT;
599 : } else {
600 0 : CPPErrorToInfoLog("EOL IN STRING");
601 0 : return ERROR_SY;
602 : }
603 : break;
604 : }
605 0 : }
606 : } // byte_scan
607 :
608 0 : int yylex_CPP(char* buf, int maxSize)
609 : {
610 : yystypepp yylvalpp;
611 0 : int token = '\n';
612 :
613 : for(;;) {
614 :
615 0 : char* tokenString = 0;
616 0 : token = cpp->currentInput->scan(cpp->currentInput, &yylvalpp);
617 0 : if(check_EOF(token))
618 0 : return 0;
619 0 : if (token < 0) {
620 : // This check may need to be improved to support UTF-8
621 : // characters in comments.
622 0 : CPPErrorToInfoLog("preprocessor encountered non-ASCII character in shader source");
623 0 : return 0;
624 : }
625 0 : if (token == '#') {
626 0 : if (cpp->previous_token == '\n'|| cpp->previous_token == 0) {
627 0 : token = readCPPline(&yylvalpp);
628 0 : if(check_EOF(token))
629 0 : return 0;
630 0 : continue;
631 : } else {
632 0 : CPPErrorToInfoLog("preprocessor command must not be preceded by any other statement in that line");
633 0 : return 0;
634 : }
635 : }
636 0 : cpp->previous_token = token;
637 : // expand macros
638 0 : if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp)) {
639 0 : cpp->pastFirstStatement = 1;
640 0 : continue;
641 : }
642 :
643 0 : if (token == '\n')
644 0 : continue;
645 0 : cpp->pastFirstStatement = 1;
646 :
647 0 : if (token == CPP_IDENTIFIER) {
648 0 : tokenString = GetStringOfAtom(atable,yylvalpp.sc_ident);
649 0 : } else if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){
650 0 : tokenString = yylvalpp.symbol_name;
651 : } else {
652 0 : tokenString = GetStringOfAtom(atable,token);
653 : }
654 :
655 0 : if (tokenString) {
656 0 : int len = strlen(tokenString);
657 0 : cpp->tokensBeforeEOF = 1;
658 0 : if (len >= maxSize) {
659 0 : return maxSize;
660 0 : } else if (len > 0) {
661 0 : strcpy(buf, tokenString);
662 0 : return len;
663 : }
664 :
665 0 : return 0;
666 : }
667 0 : }
668 :
669 : return 0;
670 : } // yylex
671 :
672 : //Checks if the token just read is EOF or not.
673 0 : int check_EOF(int token)
674 : {
675 0 : if(token==-1){
676 0 : if(cpp->ifdepth >0){
677 0 : CPPErrorToInfoLog("#endif missing!! Compilation stopped");
678 0 : cpp->CompileError=1;
679 : }
680 0 : return 1;
681 : }
682 0 : return 0;
683 : }
684 :
685 : ///////////////////////////////////////////////////////////////////////////////////////////////
686 : /////////////////////////////////////// End of scanner.c //////////////////////////////////////
687 : ///////////////////////////////////////////////////////////////////////////////////////////////
688 :
|