2
/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */
3
/*All rights reserved. */
5
/*Redistribution and use in source and binary forms, with or without */
6
/*modification, are permitted provided that the following conditions */
9
/* Redistributions of source code must retain the above copyright */
10
/* notice, this list of conditions and the following disclaimer. */
12
/* Redistributions in binary form must reproduce the above */
13
/* copyright notice, this list of conditions and the following */
14
/* disclaimer in the documentation and/or other materials provided */
15
/* with the distribution. */
17
/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */
18
/* contributors may be used to endorse or promote products derived */
19
/* from this software without specific prior written permission. */
21
/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
22
/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
23
/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
24
/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */
25
/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
26
/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
27
/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
28
/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
29
/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
30
/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
31
/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
32
/*POSSIBILITY OF SUCH DAMAGE. */
34
/****************************************************************************\
35
Copyright (c) 2002, NVIDIA Corporation.
37
NVIDIA Corporation("NVIDIA") supplies this software to you in
38
consideration of your agreement to the following terms, and your use,
39
installation, modification or redistribution of this NVIDIA software
40
constitutes acceptance of these terms. If you do not agree with these
41
terms, please do not use, install, modify or redistribute this NVIDIA
44
In consideration of your agreement to abide by the following terms, and
45
subject to these terms, NVIDIA grants you a personal, non-exclusive
46
license, under NVIDIA's copyrights in this original NVIDIA software (the
47
"NVIDIA Software"), to use, reproduce, modify and redistribute the
48
NVIDIA Software, with or without modifications, in source and/or binary
49
forms; provided that if you redistribute the NVIDIA Software, you must
50
retain the copyright notice of NVIDIA, this notice and the following
51
text and disclaimers in all such redistributions of the NVIDIA Software.
52
Neither the name, trademarks, service marks nor logos of NVIDIA
53
Corporation may be used to endorse or promote products derived from the
54
NVIDIA Software without specific prior written permission from NVIDIA.
55
Except as expressly stated in this notice, no other rights or licenses
56
express or implied, are granted by NVIDIA herein, including but not
57
limited to any patent rights that may be infringed by your derivative
58
works or by other works in which the NVIDIA Software may be
59
incorporated. No hardware is licensed hereunder.
61
THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
62
WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
63
INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
64
NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
65
ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
68
IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
69
INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
70
TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
71
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
72
OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
73
NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
74
TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
75
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76
\****************************************************************************/
89
#define isinff(x) (((*(long *)&(x) & 0x7f800000L)==0x7f800000L) && \
90
((*(long *)&(x) & 0x007fffffL)==0000000000L))
93
#include "slglobals.h"
96
typedef struct StringInputSrc {
101
static int eof_scan(InputSrc *is, yystypepp * yylvalpp)
106
static void noop(InputSrc *in, int ch, yystypepp * yylvalpp) {}
108
static InputSrc eof_inputsrc = { 0, &eof_scan, &eof_scan, &noop };
110
static int byte_scan(InputSrc *, yystypepp * yylvalpp);
115
#define DBG_BREAKPOINT() __asm int 3
116
#elif defined(_M_AMD64)
117
#define DBG_BREAKPOINT() assert(!"Dbg_Breakpoint");
119
#define DBG_BREAKPOINT()
122
#if defined(_WIN32) && !defined(_M_AMD64)
123
__int64 RDTSC ( void ) {
129
__asm mov dword ptr v, eax
130
__asm mov dword ptr v+4, edx
137
int InitScanner(CPPStruct *cpp)
139
/* Add various atoms needed by the CPP line scanner: */
143
cpp->mostRecentToken = 0;
144
cpp->tokenLoc = &cpp->ltokenLoc;
146
cpp->ltokenLoc.file = 0;
147
cpp->ltokenLoc.line = 0;
149
cpp->currentInput = &eof_inputsrc;
150
cpp->previous_token = '\n';
151
cpp->notAVersionToken = 0;
156
int FreeScanner(void)
163
* takes care of reading from multiple strings.
164
* returns the next-char from the input stream.
165
* returns EOF when the complete shader is parsed.
167
static int str_getch(StringInputSrc *in)
171
if (*in->p == '\n') {
177
if(++(cpp->PaWhichStr) < cpp->PaArgc){
179
SetStringNumber(cpp->PaWhichStr);
181
ScanFromString(cpp->PaArgv[cpp->PaWhichStr]);
182
in=(StringInputSrc*)cpp->currentInput;
186
cpp->currentInput = in->base.prev;
194
static void str_ungetch(StringInputSrc *in, int ch, yystypepp *type) {
195
if (in->p[-1] == ch)in->p--;
197
*(in->p)='\0'; /*this would take care of shifting to the previous string. */
206
int ScanFromString(char *s)
209
StringInputSrc *in = malloc(sizeof(StringInputSrc));
210
memset(in, 0, sizeof(StringInputSrc));
213
in->base.scan = byte_scan;
214
in->base.getch = (int (*)(InputSrc *, yystypepp *))str_getch;
215
in->base.ungetch = (void (*)(InputSrc *, int, yystypepp *))str_ungetch;
216
in->base.prev = cpp->currentInput;
217
cpp->currentInput = &in->base;
220
} /* ScanFromString; */
223
/*///////////////////////////////////////////////////////////////////////////////////////////// */
224
/*///////////////////////////////// Floating point constants: ///////////////////////////////// */
225
/*///////////////////////////////////////////////////////////////////////////////////////////// */
227
* lBuildFloatValue() - Quick and dirty conversion to floating point. Since all
228
* we need is single precision this should be quite precise.
231
static float lBuildFloatValue(const char *str, int len, int exp)
233
double val, expval, ten;
234
int ii, llen, absexp;
239
for (ii = 0; ii < len; ii++)
240
val = val*10.0 + (str[ii] - '0');
242
absexp = exp > 0 ? exp : -exp;
259
CPPErrorToInfoLog(" ERROR___FP_CONST_OVERFLOW");
262
} /* lBuildFloatValue */
266
* lFloatConst() - Scan a floating point constant. Assumes that the scanner
267
* has seen at least one digit, followed by either a decimal '.' or the
271
static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
273
int HasDecimal, declen, exp, ExpSign;
285
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
286
while (ch >= '0' && ch <= '9') {
287
if (len < MAX_SYMBOL_NAME_LEN) {
289
if (len > 0 || ch != '0') {
293
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
295
CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG");
303
if (ch == 'e' || ch == 'E') {
306
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
309
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
310
} else if (ch == '-') {
313
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
315
if (ch >= '0' && ch <= '9') {
316
while (ch >= '0' && ch <= '9') {
317
exp = exp*10 + ch - '0';
319
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
322
CPPErrorToInfoLog("ERROR___ERROR_IN_EXPONENT");
332
lval = lBuildFloatValue(str, str_len, exp - declen);
336
yylvalpp->sc_fval = lval;
337
strcpy(yylvalpp->symbol_name,str);
338
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
339
return CPP_FLOATCONSTANT;
342
/*///////////////////////////////////////////////////////////////////////////////////////////// */
343
/*/////////////////////////////////////// Normal Scanner ////////////////////////////////////// */
344
/*///////////////////////////////////////////////////////////////////////////////////////////// */
346
static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
348
char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
349
char string_val[MAX_STRING_LEN + 1];
350
int AlreadyComplained;
351
int len, ch, ii, ival = 0;
354
yylvalpp->sc_int = 0;
355
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
357
while (ch == ' ' || ch == '\t' || ch == '\r') {
358
yylvalpp->sc_int = 1;
359
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
362
cpp->ltokenLoc.file = cpp->currentInput->name;
363
cpp->ltokenLoc.line = cpp->currentInput->line;
367
return ch; /* Single character token */
370
case 'A': case 'B': case 'C': case 'D': case 'E':
371
case 'F': case 'G': case 'H': case 'I': case 'J':
372
case 'K': case 'L': case 'M': case 'N': case 'O':
373
case 'P': case 'Q': case 'R': case 'S': case 'T':
374
case 'U': case 'V': case 'W': case 'X': case 'Y':
376
case 'a': case 'b': case 'c': case 'd': case 'e':
377
case 'f': case 'g': case 'h': case 'i': case 'j':
378
case 'k': case 'l': case 'm': case 'n': case 'o':
379
case 'p': case 'q': case 'r': case 's': case 't':
380
case 'u': case 'v': case 'w': case 'x': case 'y':
383
if (len < MAX_SYMBOL_NAME_LEN) {
384
symbol_name[len] = ch;
386
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
388
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
390
} while ((ch >= 'a' && ch <= 'z') ||
391
(ch >= 'A' && ch <= 'Z') ||
392
(ch >= '0' && ch <= '9') ||
394
if (len >= MAX_SYMBOL_NAME_LEN)
395
len = MAX_SYMBOL_NAME_LEN - 1;
396
symbol_name[len] = '\0';
397
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
398
yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
399
return CPP_IDENTIFIER;
402
yylvalpp->symbol_name[len++] = ch;
403
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
404
if (ch == 'x' || ch == 'X') {
405
yylvalpp->symbol_name[len++] = ch;
406
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
407
if ((ch >= '0' && ch <= '9') ||
408
(ch >= 'A' && ch <= 'F') ||
409
(ch >= 'a' && ch <= 'f'))
411
AlreadyComplained = 0;
414
yylvalpp->symbol_name[len++] = ch;
415
if (ival <= 0x0fffffff) {
416
if (ch >= '0' && ch <= '9') {
418
} else if (ch >= 'A' && ch <= 'F') {
423
ival = (ival << 4) | ii;
425
if (!AlreadyComplained)
426
CPPErrorToInfoLog("ERROR___HEX_CONST_OVERFLOW");
427
AlreadyComplained = 1;
429
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
430
} while ((ch >= '0' && ch <= '9') ||
431
(ch >= 'A' && ch <= 'F') ||
432
(ch >= 'a' && ch <= 'f'));
434
CPPErrorToInfoLog("ERROR___ERROR_IN_HEX_CONSTANT");
436
yylvalpp->symbol_name[len] = '\0';
437
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
438
yylvalpp->sc_int = ival;
439
return CPP_INTCONSTANT;
440
} else if (ch >= '0' && ch <= '7') { /* octal integer constants */
441
AlreadyComplained = 0;
444
yylvalpp->symbol_name[len++] = ch;
445
if (ival <= 0x1fffffff) {
447
ival = (ival << 3) | ii;
449
if (!AlreadyComplained)
450
CPPErrorToInfoLog("ERROR___OCT_CONST_OVERFLOW");
451
AlreadyComplained = 1;
453
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
454
} while (ch >= '0' && ch <= '7');
455
if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E')
456
return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
457
yylvalpp->symbol_name[len] = '\0';
458
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
459
yylvalpp->sc_int = ival;
460
return CPP_INTCONSTANT;
462
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
465
/* Fall through... */
466
case '1': case '2': case '3': case '4':
467
case '5': case '6': case '7': case '8': case '9':
469
if (len < MAX_SYMBOL_NAME_LEN) {
470
if (len > 0 || ch != '0') {
471
yylvalpp->symbol_name[len] = ch;
474
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
476
} while (ch >= '0' && ch <= '9');
477
if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E') {
478
return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
480
yylvalpp->symbol_name[len] = '\0';
481
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
483
AlreadyComplained = 0;
484
for (ii = 0; ii < len; ii++) {
485
ch = yylvalpp->symbol_name[ii] - '0';
486
if ((ival > 214748364) || (ival == 214748364 && ch >= 8)) {
487
if (!AlreadyComplained)
488
CPPErrorToInfoLog("ERROR___INTEGER_CONST_OVERFLOW");
489
AlreadyComplained = 1;
493
yylvalpp->sc_int = ival;
495
strcpy(yylvalpp->symbol_name,"0");
496
return CPP_INTCONSTANT;
500
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
503
} else if (ch == '=') {
504
return CPP_SUB_ASSIGN;
506
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
510
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
513
} else if (ch == '=') {
514
return CPP_ADD_ASSIGN;
516
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
520
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
522
return CPP_MUL_ASSIGN;
524
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
528
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
530
return CPP_MOD_ASSIGN;
531
} else if (ch == '>'){
532
return CPP_RIGHT_BRACE;
534
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
538
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
540
return CPP_RIGHT_BRACKET;
542
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
546
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
551
return CPP_XOR_ASSIGN;
553
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
559
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
563
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
567
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
571
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
575
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
580
return CPP_OR_ASSIGN;
582
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
587
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
592
return CPP_AND_ASSIGN;
594
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
599
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
601
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
603
return CPP_LEFT_ASSIGN;
605
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
613
return CPP_LEFT_BRACE;
615
return CPP_LEFT_BRACKET;
617
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
623
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
625
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
627
return CPP_RIGHT_ASSIGN;
629
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
636
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
641
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
642
if (ch >= '0' && ch <= '9') {
643
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
644
return lFloatConst(yylvalpp->symbol_name, 0, '.', yylvalpp);
647
return -1; /* Special EOF hack */
649
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
654
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
657
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
658
} while (ch != '\n' && ch != EOF);
662
} else if (ch == '*') {
664
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
667
if (ch == '\n') nlcount++;
669
CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
672
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
674
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
676
CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
683
/* Go try it again... */
684
} else if (ch == '=') {
685
return CPP_DIV_ASSIGN;
687
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
692
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
693
while (ch != '"' && ch != '\n' && ch != EOF) {
695
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
696
if (ch == '\n' || ch == EOF) {
700
if (len < MAX_STRING_LEN) {
701
string_val[len] = ch;
703
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
706
string_val[len] = '\0';
708
yylvalpp->sc_ident = LookUpAddString(atable, string_val);
709
return CPP_STRCONSTANT;
711
CPPErrorToInfoLog("ERROR___CPP_EOL_IN_STRING");
718
int yylex_CPP(char* buf, int maxSize)
725
char* tokenString = 0;
726
token = cpp->currentInput->scan(cpp->currentInput, &yylvalpp);
729
if (token == '#' && (cpp->previous_token == '\n'||cpp->previous_token==0)) {
730
token = readCPPline(&yylvalpp);
735
cpp->previous_token = token;
737
if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp)) {
738
cpp->notAVersionToken = 1;
745
if (token == CPP_IDENTIFIER) {
746
cpp->notAVersionToken = 1;
747
tokenString = GetStringOfAtom(atable,yylvalpp.sc_ident);
748
} else if (token == CPP_FLOATCONSTANT||token == CPP_INTCONSTANT){
749
cpp->notAVersionToken = 1;
750
tokenString = yylvalpp.symbol_name;
752
cpp->notAVersionToken = 1;
753
tokenString = GetStringOfAtom(atable,token);
757
if ((signed)strlen(tokenString) >= maxSize) {
758
cpp->tokensBeforeEOF = 1;
760
} else if (strlen(tokenString) > 0) {
761
strcpy(buf, tokenString);
762
cpp->tokensBeforeEOF = 1;
763
return (int)strlen(tokenString);
773
/*Checks if the token just read is EOF or not. */
774
int check_EOF(int token)
778
CPPErrorToInfoLog("#endif missing!! Compilation stopped");
786
/*///////////////////////////////////////////////////////////////////////////////////////////// */
787
/*///////////////////////////////////// End of scanner.c ////////////////////////////////////// */
788
/*///////////////////////////////////////////////////////////////////////////////////////////// */