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