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