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 static int eof_scan(InputSrc *is, yystypepp * yylvalpp) 70 { 71 return EOF; 72 } // eof_scan 73 74 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 int InitScanner(CPPStruct *cpp) 106 { 107 // Add various atoms needed by the CPP line scanner: 108 if (!InitCPP()) 109 return 0; 110 111 cpp->mostRecentToken = 0; 112 cpp->tokenLoc = &cpp->ltokenLoc; 113 114 cpp->ltokenLoc.file = 0; 115 cpp->ltokenLoc.line = 0; 116 117 cpp->currentInput = &eof_inputsrc; 118 cpp->previous_token = '\n'; 119 cpp->pastFirstStatement = 0; 120 121 return 1; 122 } // InitScanner 123 124 int FreeScanner(void) 125 { 126 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 static int str_getch(StringInputSrc *in) 136 { 137 for(;;){ 138 if (*in->p){ 139 if (*in->p == '\n') { 140 in->base.line++; 141 IncLineNumber(); 142 } 143 return *in->p++; 144 } 145 if(++(cpp->PaWhichStr) < cpp->PaArgc){ 146 free(in); 147 SetStringNumber(cpp->PaWhichStr); 148 SetLineNumber(1); 149 ScanFromString(cpp->PaArgv[cpp->PaWhichStr]); 150 in=(StringInputSrc*)cpp->currentInput; 151 continue; 152 } 153 else{ 154 cpp->currentInput = in->base.prev; 155 cpp->PaWhichStr=0; 156 free(in); 157 return EOF; 158 } 159 } 160 } // str_getch 161 162 static void str_ungetch(StringInputSrc *in, int ch, yystypepp *type) { 163 if (in->p[-1] == ch)in->p--; 164 else { 165 *(in->p)='\0'; //this would take care of shifting to the previous string. 166 cpp->PaWhichStr--; 167 } 168 if (ch == '\n') { 169 in->base.line--; 170 DecLineNumber(); 171 } 172 } // str_ungetch 173 174 int ScanFromString(const char *s) 175 { 176 177 StringInputSrc *in = malloc(sizeof(StringInputSrc)); 178 memset(in, 0, sizeof(StringInputSrc)); 179 in->p = (char*) s; 180 in->base.line = 1; 181 in->base.scan = byte_scan; 182 in->base.getch = (int (*)(InputSrc *, yystypepp *))str_getch; 183 in->base.ungetch = (void (*)(InputSrc *, int, yystypepp *))str_ungetch; 184 in->base.prev = cpp->currentInput; 185 cpp->currentInput = &in->base; 186 187 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 static int lFloatConst(int ch, int len, yystypepp * yylvalpp) 212 { 213 int alreadyComplained = 0; 214 assert((ch == '.') || (ch == 'e') || (ch == 'E')); 215 216 if (ch == '.') { 217 do { 218 APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN); 219 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 220 } while (ch >= '0' && ch <= '9'); 221 } 222 223 // Exponent: 224 if (ch == 'e' || ch == 'E') { 225 APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN); 226 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 227 if (ch == '+') { 228 APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN); 229 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 230 } else if (ch == '-') { 231 APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN); 232 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 233 } 234 if (ch >= '0' && ch <= '9') { 235 while (ch >= '0' && ch <= '9') { 236 APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN); 237 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 238 } 239 } else { 240 CPPErrorToInfoLog("EXPONENT INVALID"); 241 } 242 } 243 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 244 245 assert(len <= MAX_SYMBOL_NAME_LEN); 246 yylvalpp->symbol_name[len] = '\0'; 247 yylvalpp->sc_fval = (float) atof_dot(yylvalpp->symbol_name); 248 if (isinff(yylvalpp->sc_fval)) { 249 CPPErrorToInfoLog("FLOAT CONSTANT OVERFLOW"); 250 } 251 return CPP_FLOATCONSTANT; 252 } // lFloatConst 253 254 /////////////////////////////////////////////////////////////////////////////////////////////// 255 ///////////////////////////////////////// Normal Scanner ////////////////////////////////////// 256 /////////////////////////////////////////////////////////////////////////////////////////////// 257 258 static int byte_scan(InputSrc *in, yystypepp * yylvalpp) 259 { 260 char string_val[MAX_STRING_LEN + 1]; 261 int alreadyComplained = 0; 262 int len, ch, ii, ival = 0; 263 264 for (;;) { 265 yylvalpp->sc_int = 0; 266 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 267 268 while (ch == ' ' || ch == '\t' || ch == '\r') { 269 yylvalpp->sc_int = 1; 270 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 271 } 272 273 cpp->ltokenLoc.file = cpp->currentInput->name; 274 cpp->ltokenLoc.line = cpp->currentInput->line; 275 alreadyComplained = 0; 276 len = 0; 277 switch (ch) { 278 default: 279 return ch; // Single character token 280 case EOF: 281 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 APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN); 296 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 297 } while ((ch >= 'a' && ch <= 'z') || 298 (ch >= 'A' && ch <= 'Z') || 299 (ch >= '0' && ch <= '9') || 300 ch == '_'); 301 assert(len <= MAX_SYMBOL_NAME_LEN); 302 yylvalpp->symbol_name[len] = '\0'; 303 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 304 yylvalpp->sc_ident = LookUpAddString(atable, yylvalpp->symbol_name); 305 return CPP_IDENTIFIER; 306 break; 307 case '0': 308 APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN); 309 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 310 if (ch == 'x' || ch == 'X') { // hexadecimal integer constants 311 APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN); 312 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 313 if ((ch >= '0' && ch <= '9') || 314 (ch >= 'A' && ch <= 'F') || 315 (ch >= 'a' && ch <= 'f')) 316 { 317 ival = 0; 318 do { 319 if ((ival <= 0x0fffffff) && (len < MAX_SYMBOL_NAME_LEN)) { 320 yylvalpp->symbol_name[len++] = ch; 321 if (ch >= '0' && ch <= '9') { 322 ii = ch - '0'; 323 } else if (ch >= 'A' && ch <= 'F') { 324 ii = ch - 'A' + 10; 325 } else { 326 ii = ch - 'a' + 10; 327 } 328 ival = (ival << 4) | ii; 329 } else if (!alreadyComplained) { 330 CPPErrorToInfoLog("HEX CONSTANT OVERFLOW"); 331 alreadyComplained = 1; 332 } 333 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 334 } while ((ch >= '0' && ch <= '9') || 335 (ch >= 'A' && ch <= 'F') || 336 (ch >= 'a' && ch <= 'f')); 337 } else { 338 CPPErrorToInfoLog("HEX CONSTANT INVALID"); 339 } 340 assert(len <= MAX_SYMBOL_NAME_LEN); 341 yylvalpp->symbol_name[len] = '\0'; 342 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 343 yylvalpp->sc_int = ival; 344 return CPP_INTCONSTANT; 345 } else if (ch >= '0' && ch <= '7') { // octal integer constants 346 ival = 0; 347 do { 348 if ((ival <= 0x1fffffff) && (len < MAX_SYMBOL_NAME_LEN)) { 349 yylvalpp->symbol_name[len++] = ch; 350 ii = ch - '0'; 351 ival = (ival << 3) | ii; 352 } else if (!alreadyComplained) { 353 CPPErrorToInfoLog("OCT CONSTANT OVERFLOW"); 354 alreadyComplained = 1; 355 } 356 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 357 } while (ch >= '0' && ch <= '7'); 358 if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E') 359 return lFloatConst(ch, len, yylvalpp); 360 assert(len <= MAX_SYMBOL_NAME_LEN); 361 yylvalpp->symbol_name[len] = '\0'; 362 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 363 yylvalpp->sc_int = ival; 364 return CPP_INTCONSTANT; 365 } else { 366 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 367 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 APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN); 374 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 375 } while (ch >= '0' && ch <= '9'); 376 if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E') { 377 return lFloatConst(ch, len, yylvalpp); 378 } else { 379 assert(len <= MAX_SYMBOL_NAME_LEN); 380 yylvalpp->symbol_name[len] = '\0'; 381 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 382 ival = 0; 383 for (ii = 0; ii < len; ii++) { 384 ch = yylvalpp->symbol_name[ii] - '0'; 385 ival = ival*10 + ch; 386 if ((ival > 214748364) || (ival == 214748364 && ch >= 8)) { 387 CPPErrorToInfoLog("INTEGER CONSTANT OVERFLOW"); 388 break; 389 } 390 } 391 yylvalpp->sc_int = ival; 392 if(ival==0) 393 strcpy(yylvalpp->symbol_name,"0"); 394 return CPP_INTCONSTANT; 395 } 396 break; 397 case '-': 398 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 399 if (ch == '-') { 400 return CPP_DEC_OP; 401 } else if (ch == '=') { 402 return CPP_SUB_ASSIGN; 403 } else { 404 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 405 return '-'; 406 } 407 case '+': 408 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 409 if (ch == '+') { 410 return CPP_INC_OP; 411 } else if (ch == '=') { 412 return CPP_ADD_ASSIGN; 413 } else { 414 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 415 return '+'; 416 } 417 case '*': 418 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 419 if (ch == '=') { 420 return CPP_MUL_ASSIGN; 421 } else { 422 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 423 return '*'; 424 } 425 case '%': 426 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 427 if (ch == '=') { 428 return CPP_MOD_ASSIGN; 429 } else if (ch == '>'){ 430 return CPP_RIGHT_BRACE; 431 } else { 432 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 433 return '%'; 434 } 435 case ':': 436 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 437 if (ch == '>') { 438 return CPP_RIGHT_BRACKET; 439 } else { 440 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 441 return ':'; 442 } 443 case '^': 444 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 445 if (ch == '^') { 446 return CPP_XOR_OP; 447 } else { 448 if (ch == '=') 449 return CPP_XOR_ASSIGN; 450 else{ 451 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 452 return '^'; 453 } 454 } 455 456 case '=': 457 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 458 if (ch == '=') { 459 return CPP_EQ_OP; 460 } else { 461 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 462 return '='; 463 } 464 case '!': 465 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 466 if (ch == '=') { 467 return CPP_NE_OP; 468 } else { 469 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 470 return '!'; 471 } 472 case '|': 473 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 474 if (ch == '|') { 475 return CPP_OR_OP; 476 } else { 477 if (ch == '=') 478 return CPP_OR_ASSIGN; 479 else{ 480 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 481 return '|'; 482 } 483 } 484 case '&': 485 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 486 if (ch == '&') { 487 return CPP_AND_OP; 488 } else { 489 if (ch == '=') 490 return CPP_AND_ASSIGN; 491 else{ 492 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 493 return '&'; 494 } 495 } 496 case '<': 497 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 498 if (ch == '<') { 499 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 500 if(ch == '=') 501 return CPP_LEFT_ASSIGN; 502 else{ 503 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 504 return CPP_LEFT_OP; 505 } 506 } else { 507 if (ch == '=') { 508 return CPP_LE_OP; 509 } else { 510 if (ch == '%') 511 return CPP_LEFT_BRACE; 512 else if (ch == ':') 513 return CPP_LEFT_BRACKET; 514 else{ 515 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 516 return '<'; 517 } 518 } 519 } 520 case '>': 521 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 522 if (ch == '>') { 523 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 524 if(ch == '=') 525 return CPP_RIGHT_ASSIGN; 526 else{ 527 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 528 return CPP_RIGHT_OP; 529 } 530 } else { 531 if (ch == '=') { 532 return CPP_GE_OP; 533 } else { 534 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 535 return '>'; 536 } 537 } 538 case '.': 539 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 540 if (ch >= '0' && ch <= '9') { 541 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 542 return lFloatConst('.', 0, yylvalpp); 543 } else { 544 if (ch == '.') { 545 return -1; // Special EOF hack 546 } else { 547 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 548 return '.'; 549 } 550 } 551 case '/': 552 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 553 if (ch == '/') { 554 do { 555 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 556 } while (ch != '\n' && ch != EOF); 557 if (ch == EOF) 558 return -1; 559 return '\n'; 560 } else if (ch == '*') { 561 int nlcount = 0; 562 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 563 do { 564 while (ch != '*') { 565 if (ch == '\n') nlcount++; 566 if (ch == EOF) { 567 CPPErrorToInfoLog("EOF IN COMMENT"); 568 return -1; 569 } 570 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 571 } 572 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 573 if (ch == EOF) { 574 CPPErrorToInfoLog("EOF IN COMMENT"); 575 return -1; 576 } 577 } while (ch != '/'); 578 if (nlcount) { 579 return '\n'; 580 } 581 // Go try it again... 582 } else if (ch == '=') { 583 return CPP_DIV_ASSIGN; 584 } else { 585 cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); 586 return '/'; 587 } 588 break; 589 case '"': 590 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 591 while (ch != '"' && ch != '\n' && ch != EOF) { 592 if (ch == '\\') { 593 CPPErrorToInfoLog("The line continuation character (\\) is not part of the OpenGL ES Shading Language"); 594 return -1; 595 } 596 APPEND_CHAR_S(ch, string_val, len, MAX_STRING_LEN); 597 ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); 598 }; 599 assert(len <= MAX_STRING_LEN); 600 string_val[len] = '\0'; 601 if (ch == '"') { 602 yylvalpp->sc_ident = LookUpAddString(atable, string_val); 603 return CPP_STRCONSTANT; 604 } else { 605 CPPErrorToInfoLog("EOL IN STRING"); 606 return ERROR_SY; 607 } 608 break; 609 } 610 } 611 } // byte_scan 612 613 int yylex_CPP(char* buf, int maxSize) 614 { 615 yystypepp yylvalpp; 616 int token = '\n'; 617 618 for(;;) { 619 620 char* tokenString = 0; 621 token = cpp->currentInput->scan(cpp->currentInput, &yylvalpp); 622 if(check_EOF(token)) 623 return 0; 624 if (token == '#') { 625 if (cpp->previous_token == '\n'|| cpp->previous_token == 0) { 626 token = readCPPline(&yylvalpp); 627 if(check_EOF(token)) 628 return 0; 629 continue; 630 } else { 631 CPPErrorToInfoLog("preprocessor command must not be preceded by any other statement in that line"); 632 return 0; 633 } 634 } 635 cpp->previous_token = token; 636 // expand macros 637 if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp)) { 638 cpp->pastFirstStatement = 1; 639 continue; 640 } 641 642 if (token == '\n') 643 continue; 644 cpp->pastFirstStatement = 1; 645 646 if (token == CPP_IDENTIFIER) { 647 tokenString = GetStringOfAtom(atable,yylvalpp.sc_ident); 648 } else if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){ 649 tokenString = yylvalpp.symbol_name; 650 } else { 651 tokenString = GetStringOfAtom(atable,token); 652 } 653 654 if (tokenString) { 655 int len = strlen(tokenString); 656 cpp->tokensBeforeEOF = 1; 657 if (len >= maxSize) { 658 return maxSize; 659 } else if (len > 0) { 660 strcpy(buf, tokenString); 661 return len; 662 } 663 664 return 0; 665 } 666 } 667 668 return 0; 669 } // yylex 670 671 //Checks if the token just read is EOF or not. 672 int check_EOF(int token) 673 { 674 if(token==-1){ 675 if(cpp->ifdepth >0){ 676 CPPErrorToInfoLog("#endif missing!! Compilation stopped"); 677 cpp->CompileError=1; 678 } 679 return 1; 680 } 681 return 0; 682 } 683 684 /////////////////////////////////////////////////////////////////////////////////////////////// 685 /////////////////////////////////////// End of scanner.c ////////////////////////////////////// 686 /////////////////////////////////////////////////////////////////////////////////////////////// 687 688