blob: 1aa165281c88d3852beb831cee2a1f2f1408a366 [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// cpp.c
46//
47
48#include <stdarg.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include <string.h>
52#include <ctype.h>
53
daniel@transgaming.come6842292010-04-20 18:52:50 +000054#include "compiler/preprocessor/slglobals.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000055
apatrick@chromium.orga1d80592012-01-25 21:52:10 +000056#if defined(_MSC_VER)
57#pragma warning(disable: 4054)
58#pragma warning(disable: 4152)
59#pragma warning(disable: 4706)
60#endif
61
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000062static int CPPif(yystypepp * yylvalpp);
63
64/* Don't use memory.c's replacements, as we clean up properly here */
65#undef malloc
66#undef free
67
68static int bindAtom = 0;
69static int constAtom = 0;
70static int defaultAtom = 0;
71static int defineAtom = 0;
72static int definedAtom = 0;
73static int elseAtom = 0;
74static int elifAtom = 0;
75static int endifAtom = 0;
76static int ifAtom = 0;
77static int ifdefAtom = 0;
78static int ifndefAtom = 0;
79static int includeAtom = 0;
80static int lineAtom = 0;
81static int pragmaAtom = 0;
82static int texunitAtom = 0;
83static int undefAtom = 0;
84static int errorAtom = 0;
85static int __LINE__Atom = 0;
86static int __FILE__Atom = 0;
87static int __VERSION__Atom = 0;
88static int versionAtom = 0;
89static int extensionAtom = 0;
90
91static Scope *macros = 0;
92#define MAX_MACRO_ARGS 64
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000093
94static SourceLoc ifloc; /* outermost #if */
95
96int InitCPP(void)
97{
98 char buffer[64], *t;
99 const char *f;
daniel@transgaming.comd8e93722010-05-14 17:31:09 +0000100
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000101 // Add various atoms needed by the CPP line scanner:
102 bindAtom = LookUpAddString(atable, "bind");
103 constAtom = LookUpAddString(atable, "const");
104 defaultAtom = LookUpAddString(atable, "default");
105 defineAtom = LookUpAddString(atable, "define");
106 definedAtom = LookUpAddString(atable, "defined");
107 elifAtom = LookUpAddString(atable, "elif");
108 elseAtom = LookUpAddString(atable, "else");
109 endifAtom = LookUpAddString(atable, "endif");
110 ifAtom = LookUpAddString(atable, "if");
111 ifdefAtom = LookUpAddString(atable, "ifdef");
112 ifndefAtom = LookUpAddString(atable, "ifndef");
113 includeAtom = LookUpAddString(atable, "include");
114 lineAtom = LookUpAddString(atable, "line");
115 pragmaAtom = LookUpAddString(atable, "pragma");
116 texunitAtom = LookUpAddString(atable, "texunit");
117 undefAtom = LookUpAddString(atable, "undef");
118 errorAtom = LookUpAddString(atable, "error");
119 __LINE__Atom = LookUpAddString(atable, "__LINE__");
120 __FILE__Atom = LookUpAddString(atable, "__FILE__");
121 __VERSION__Atom = LookUpAddString(atable, "__VERSION__");
122 versionAtom = LookUpAddString(atable, "version");
123 extensionAtom = LookUpAddString(atable, "extension");
124 macros = NewScopeInPool(mem_CreatePool(0, 0));
125 strcpy(buffer, "PROFILE_");
126 t = buffer + strlen(buffer);
127 f = cpp->options.profileString;
128 while ((isalnum(*f) || *f == '_') && t < buffer + sizeof(buffer) - 1)
129 *t++ = toupper(*f++);
130 *t = 0;
daniel@transgaming.comd8e93722010-05-14 17:31:09 +0000131
daniel@transgaming.comcd0a9a82010-05-18 18:51:59 +0000132 PredefineIntMacro("GL_ES", 1);
133 PredefineIntMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
daniel@transgaming.comd8e93722010-05-14 17:31:09 +0000134
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000135 return 1;
136} // InitCPP
137
138int FreeCPP(void)
139{
140 if (macros)
141 {
142 mem_FreePool(macros->pool);
143 macros = 0;
144 }
145
146 return 1;
147}
148
149int FinalCPP(void)
150{
151 if (cpp->ifdepth)
152 CPPErrorToInfoLog("#if mismatch");
153 return 1;
154}
155
156static int CPPdefine(yystypepp * yylvalpp)
157{
158 int token, name, args[MAX_MACRO_ARGS], argc;
159 const char *message;
160 MacroSymbol mac;
161 Symbol *symb;
162 SourceLoc dummyLoc;
163 memset(&mac, 0, sizeof(mac));
164 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
165 if (token != CPP_IDENTIFIER) {
166 CPPErrorToInfoLog("#define");
167 return token;
168 }
169 name = yylvalpp->sc_ident;
170 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
171 if (token == '(' && !yylvalpp->sc_int) {
172 // gather arguments
173 argc = 0;
174 do {
175 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
176 if (argc == 0 && token == ')') break;
177 if (token != CPP_IDENTIFIER) {
178 CPPErrorToInfoLog("#define");
179 return token;
180 }
181 if (argc < MAX_MACRO_ARGS)
182 args[argc++] = yylvalpp->sc_ident;
183 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
184 } while (token == ',');
185 if (token != ')') {
186 CPPErrorToInfoLog("#define");
187 return token;
188 }
189 mac.argc = argc;
190 mac.args = mem_Alloc(macros->pool, argc * sizeof(int));
191 memcpy(mac.args, args, argc * sizeof(int));
192 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
193 }
194 mac.body = NewTokenStream(GetAtomString(atable, name), macros->pool);
195 while (token != '\n') {
daniel@transgaming.comedff8dc2010-05-14 17:30:27 +0000196 if (token == '\\') {
197 CPPErrorToInfoLog("The line continuation character (\\) is not part of the OpenGL ES Shading Language");
198 return token;
daniel@transgaming.com5efd8b42010-12-13 14:48:03 +0000199 } else if (token <= 0) { // EOF or error
200 CPPErrorToInfoLog("unexpected end of input in #define preprocessor directive - expected a newline");
201 return 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000202 }
203 RecordToken(mac.body, token, yylvalpp);
204 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
205 };
206
207 symb = LookUpSymbol(macros, name);
208 if (symb) {
209 if (!symb->details.mac.undef) {
210 // already defined -- need to make sure they are identical
211 if (symb->details.mac.argc != mac.argc) goto error;
212 for (argc=0; argc < mac.argc; argc++)
213 if (symb->details.mac.args[argc] != mac.args[argc])
214 goto error;
215 RewindTokenStream(symb->details.mac.body);
216 RewindTokenStream(mac.body);
217 do {
218 int old_lval, old_token;
219 old_token = ReadToken(symb->details.mac.body, yylvalpp);
220 old_lval = yylvalpp->sc_int;
221 token = ReadToken(mac.body, yylvalpp);
222 if (token != old_token || yylvalpp->sc_int != old_lval) {
223 error:
224 StoreStr("Macro Redefined");
225 StoreStr(GetStringOfAtom(atable,name));
226 message=GetStrfromTStr();
227 DecLineNumber();
228 CPPShInfoLogMsg(message);
229 IncLineNumber();
230 ResetTString();
231 break; }
232 } while (token > 0);
233 }
234 //FreeMacro(&symb->details.mac);
235 } else {
236 dummyLoc.file = 0;
237 dummyLoc.line = 0;
238 symb = AddSymbol(&dummyLoc, macros, name, MACRO_S);
239 }
240 symb->details.mac = mac;
241 return '\n';
242} // CPPdefine
243
244static int CPPundef(yystypepp * yylvalpp)
245{
246 int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
247 Symbol *symb;
248 if(token == '\n'){
249 CPPErrorToInfoLog("#undef");
250 return token;
251 }
252 if (token != CPP_IDENTIFIER)
253 goto error;
254 symb = LookUpSymbol(macros, yylvalpp->sc_ident);
255 if (symb) {
256 symb->details.mac.undef = 1;
257 }
258 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
259 if (token != '\n') {
260 error:
261 CPPErrorToInfoLog("#undef");
262 }
263 return token;
264} // CPPundef
265
266/* CPPelse -- skip forward to appropriate spot. This is actually used
267** to skip to and #endif after seeing an #else, AND to skip to a #else,
268** #elif, or #endif after a #if/#ifdef/#ifndef/#elif test was false
269*/
270
271static int CPPelse(int matchelse, yystypepp * yylvalpp)
272{
273 int atom,depth=0;
274 int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
275
276 while (token > 0) {
277 if (token != '#') {
daniel@transgaming.com5efd8b42010-12-13 14:48:03 +0000278 while (token != '\n') {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000279 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
daniel@transgaming.com5efd8b42010-12-13 14:48:03 +0000280 if (token <= 0) { // EOF or error
281 CPPErrorToInfoLog("unexpected end of input in #else preprocessor directive - expected a newline");
282 return 0;
283 }
284 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000285 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
286 continue;
287 }
288 if ((token = cpp->currentInput->scan(cpp->currentInput, yylvalpp)) != CPP_IDENTIFIER)
289 continue;
290 atom = yylvalpp->sc_ident;
291 if (atom == ifAtom || atom == ifdefAtom || atom == ifndefAtom){
292 depth++; cpp->ifdepth++; cpp->elsetracker++;
daniel@transgaming.come9874052011-01-26 17:32:26 +0000293 if (cpp->ifdepth > MAX_IF_NESTING) {
294 CPPErrorToInfoLog("max #if nesting depth exceeded");
295 cpp->CompileError = 1;
296 return 0;
297 }
298 // sanity check elsetracker
299 if (cpp->elsetracker < 0 || cpp->elsetracker >= MAX_IF_NESTING) {
300 CPPErrorToInfoLog("mismatched #if/#endif statements");
301 cpp->CompileError = 1;
302 return 0;
303 }
daniel@transgaming.com9e78e5e2010-04-29 03:39:02 +0000304 cpp->elsedepth[cpp->elsetracker] = 0;
daniel@transgaming.come9874052011-01-26 17:32:26 +0000305 }
306 else if (atom == endifAtom) {
daniel@transgaming.com9e78e5e2010-04-29 03:39:02 +0000307 if(--depth<0){
daniel@transgaming.come9874052011-01-26 17:32:26 +0000308 if (cpp->elsetracker)
309 --cpp->elsetracker;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000310 if (cpp->ifdepth)
311 --cpp->ifdepth;
312 break;
313 }
daniel@transgaming.come9874052011-01-26 17:32:26 +0000314 --cpp->elsetracker;
315 --cpp->ifdepth;
316 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000317 else if (((int)(matchelse) != 0)&& depth==0) {
318 if (atom == elseAtom ) {
319 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
320 if (token != '\n') {
321 CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
daniel@transgaming.com5efd8b42010-12-13 14:48:03 +0000322 while (token != '\n') {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000323 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
daniel@transgaming.com5efd8b42010-12-13 14:48:03 +0000324 if (token <= 0) { // EOF or error
325 CPPErrorToInfoLog("unexpected end of input following #else preprocessor directive - expected a newline");
326 return 0;
327 }
328 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000329 }
330 break;
331 }
332 else if (atom == elifAtom) {
333 /* we decrement cpp->ifdepth here, because CPPif will increment
334 * it and we really want to leave it alone */
335 if (cpp->ifdepth){
336 --cpp->ifdepth;
337 --cpp->elsetracker;
338 }
339 return CPPif(yylvalpp);
340 }
341 }
342 else if((atom==elseAtom) && (!ChkCorrectElseNesting())){
343 CPPErrorToInfoLog("#else after a #else");
344 cpp->CompileError=1;
daniel@transgaming.come9874052011-01-26 17:32:26 +0000345 return 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000346 }
347 };
348 return token;
349}
350
351enum eval_prec {
352 MIN_PREC,
353 COND, LOGOR, LOGAND, OR, XOR, AND, EQUAL, RELATION, SHIFT, ADD, MUL, UNARY,
354 MAX_PREC
355};
356
357static int op_logor(int a, int b) { return a || b; }
358static int op_logand(int a, int b) { return a && b; }
359static int op_or(int a, int b) { return a | b; }
360static int op_xor(int a, int b) { return a ^ b; }
361static int op_and(int a, int b) { return a & b; }
362static int op_eq(int a, int b) { return a == b; }
363static int op_ne(int a, int b) { return a != b; }
364static int op_ge(int a, int b) { return a >= b; }
365static int op_le(int a, int b) { return a <= b; }
366static int op_gt(int a, int b) { return a > b; }
367static int op_lt(int a, int b) { return a < b; }
368static int op_shl(int a, int b) { return a << b; }
369static int op_shr(int a, int b) { return a >> b; }
370static int op_add(int a, int b) { return a + b; }
371static int op_sub(int a, int b) { return a - b; }
372static int op_mul(int a, int b) { return a * b; }
373static int op_div(int a, int b) { return a / b; }
374static int op_mod(int a, int b) { return a % b; }
375static int op_pos(int a) { return a; }
376static int op_neg(int a) { return -a; }
377static int op_cmpl(int a) { return ~a; }
378static int op_not(int a) { return !a; }
379
380struct {
381 int token, prec, (*op)(int, int);
382} binop[] = {
383 { CPP_OR_OP, LOGOR, op_logor },
384 { CPP_AND_OP, LOGAND, op_logand },
385 { '|', OR, op_or },
386 { '^', XOR, op_xor },
387 { '&', AND, op_and },
388 { CPP_EQ_OP, EQUAL, op_eq },
389 { CPP_NE_OP, EQUAL, op_ne },
390 { '>', RELATION, op_gt },
391 { CPP_GE_OP, RELATION, op_ge },
392 { '<', RELATION, op_lt },
393 { CPP_LE_OP, RELATION, op_le },
394 { CPP_LEFT_OP, SHIFT, op_shl },
395 { CPP_RIGHT_OP, SHIFT, op_shr },
396 { '+', ADD, op_add },
397 { '-', ADD, op_sub },
398 { '*', MUL, op_mul },
399 { '/', MUL, op_div },
400 { '%', MUL, op_mod },
401};
402
403struct {
404 int token, (*op)(int);
405} unop[] = {
406 { '+', op_pos },
407 { '-', op_neg },
408 { '~', op_cmpl },
409 { '!', op_not },
410};
411
412#define ALEN(A) (sizeof(A)/sizeof(A[0]))
413
414static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp)
415{
416 int i, val;
417 Symbol *s;
418 if (token == CPP_IDENTIFIER) {
419 if (yylvalpp->sc_ident == definedAtom) {
420 int needclose = 0;
421 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
422 if (token == '(') {
423 needclose = 1;
424 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
425 }
426 if (token != CPP_IDENTIFIER)
427 goto error;
428 *res = (s = LookUpSymbol(macros, yylvalpp->sc_ident))
429 ? !s->details.mac.undef : 0;
430 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
431 if (needclose) {
432 if (token != ')')
433 goto error;
434 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
435 }
436 } else if (MacroExpand(yylvalpp->sc_ident, yylvalpp)) {
437 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
438 return eval(token, prec, res, err, yylvalpp);
439 } else {
440 goto error;
441 }
442 } else if (token == CPP_INTCONSTANT) {
443 *res = yylvalpp->sc_int;
444 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
445 } else if (token == '(') {
446 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
447 token = eval(token, MIN_PREC, res, err, yylvalpp);
448 if (!*err) {
449 if (token != ')')
450 goto error;
451 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
452 }
453 } else {
454 for (i = ALEN(unop) - 1; i >= 0; i--) {
455 if (unop[i].token == token)
456 break;
457 }
458 if (i >= 0) {
459 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
460 token = eval(token, UNARY, res, err, yylvalpp);
461 *res = unop[i].op(*res);
462 } else {
463 goto error;
464 }
465 }
466 while (!*err) {
467 if (token == ')' || token == '\n') break;
468 for (i = ALEN(binop) - 1; i >= 0; i--) {
469 if (binop[i].token == token)
470 break;
471 }
472 if (i < 0 || binop[i].prec <= prec)
473 break;
474 val = *res;
475 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
476 token = eval(token, binop[i].prec, res, err, yylvalpp);
daniel@transgaming.com3b5643c2011-02-28 15:06:55 +0000477
478 if (binop[i].op == op_div || binop[i].op == op_mod)
479 {
480 if (*res == 0)
481 {
482 CPPErrorToInfoLog("preprocessor divide or modulo by zero");
483 *err = 1;
484 return token;
485 }
486 }
487
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000488 *res = binop[i].op(val, *res);
489 }
490 return token;
491error:
492 CPPErrorToInfoLog("incorrect preprocessor directive");
493 *err = 1;
494 *res = 0;
495 return token;
496} // eval
497
498static int CPPif(yystypepp * yylvalpp) {
499 int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
500 int res = 0, err = 0;
daniel@transgaming.come9874052011-01-26 17:32:26 +0000501
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000502 if (!cpp->ifdepth++)
503 ifloc = *cpp->tokenLoc;
daniel@transgaming.come9874052011-01-26 17:32:26 +0000504 if(cpp->ifdepth > MAX_IF_NESTING){
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000505 CPPErrorToInfoLog("max #if nesting depth exceeded");
daniel@transgaming.come9874052011-01-26 17:32:26 +0000506 cpp->CompileError = 1;
507 return 0;
508 }
509 cpp->elsetracker++;
510 // sanity check elsetracker
511 if (cpp->elsetracker < 0 || cpp->elsetracker >= MAX_IF_NESTING) {
512 CPPErrorToInfoLog("mismatched #if/#endif statements");
513 cpp->CompileError = 1;
514 return 0;
515 }
516 cpp->elsedepth[cpp->elsetracker] = 0;
517
518 token = eval(token, MIN_PREC, &res, &err, yylvalpp);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000519 if (token != '\n') {
daniel@transgaming.com5efd8b42010-12-13 14:48:03 +0000520 CPPWarningToInfoLog("unexpected tokens following #if preprocessor directive - expected a newline");
521 while (token != '\n') {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000522 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
daniel@transgaming.com5efd8b42010-12-13 14:48:03 +0000523 if (token <= 0) { // EOF or error
524 CPPErrorToInfoLog("unexpected end of input in #if preprocessor directive - expected a newline");
525 return 0;
526 }
527 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000528 }
529 if (!res && !err) {
530 token = CPPelse(1, yylvalpp);
531 }
532
533 return token;
534} // CPPif
535
536static int CPPifdef(int defined, yystypepp * yylvalpp)
537{
538 int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
539 int name = yylvalpp->sc_ident;
daniel@transgaming.come9874052011-01-26 17:32:26 +0000540 if(++cpp->ifdepth > MAX_IF_NESTING){
541 CPPErrorToInfoLog("max #if nesting depth exceeded");
542 cpp->CompileError = 1;
543 return 0;
544 }
545 cpp->elsetracker++;
546 // sanity check elsetracker
547 if (cpp->elsetracker < 0 || cpp->elsetracker >= MAX_IF_NESTING) {
548 CPPErrorToInfoLog("mismatched #if/#endif statements");
549 cpp->CompileError = 1;
550 return 0;
551 }
daniel@transgaming.com9e78e5e2010-04-29 03:39:02 +0000552 cpp->elsedepth[cpp->elsetracker] = 0;
daniel@transgaming.come9874052011-01-26 17:32:26 +0000553
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000554 if (token != CPP_IDENTIFIER) {
555 defined ? CPPErrorToInfoLog("ifdef"):CPPErrorToInfoLog("ifndef");
556 } else {
557 Symbol *s = LookUpSymbol(macros, name);
558 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
559 if (token != '\n') {
560 CPPWarningToInfoLog("unexpected tokens following #ifdef preprocessor directive - expected a newline");
daniel@transgaming.com5efd8b42010-12-13 14:48:03 +0000561 while (token != '\n') {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000562 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
daniel@transgaming.com5efd8b42010-12-13 14:48:03 +0000563 if (token <= 0) { // EOF or error
564 CPPErrorToInfoLog("unexpected end of input in #ifdef preprocessor directive - expected a newline");
565 return 0;
566 }
567 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000568 }
569 if (((s && !s->details.mac.undef) ? 1 : 0) != defined)
570 token = CPPelse(1, yylvalpp);
571 }
572 return token;
573} // CPPifdef
574
575static int CPPline(yystypepp * yylvalpp)
576{
577 int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
578 if(token=='\n'){
579 DecLineNumber();
580 CPPErrorToInfoLog("#line");
581 IncLineNumber();
582 return token;
583 }
584 else if (token == CPP_INTCONSTANT) {
585 yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
586 SetLineNumber(yylvalpp->sc_int);
587 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
588
589 if (token == CPP_INTCONSTANT) {
590 yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
591 SetStringNumber(yylvalpp->sc_int);
592 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
593 if(token!='\n')
594 CPPErrorToInfoLog("#line");
595 }
596 else if (token == '\n'){
597 return token;
598 }
599 else{
600 CPPErrorToInfoLog("#line");
601 }
602 }
603 else{
604 CPPErrorToInfoLog("#line");
605 }
606 return token;
607}
608
609static int CPPerror(yystypepp * yylvalpp) {
610
611 int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
612 const char *message;
613
614 while (token != '\n') {
daniel@transgaming.com5efd8b42010-12-13 14:48:03 +0000615 if (token <= 0){
616 CPPErrorToInfoLog("unexpected end of input in #error preprocessor directive - expected a newline");
617 return 0;
618 }else if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000619 StoreStr(yylvalpp->symbol_name);
620 }else if(token == CPP_IDENTIFIER || token == CPP_STRCONSTANT){
621 StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident));
622 }else {
623 StoreStr(GetStringOfAtom(atable,token));
624 }
625 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
626 }
627 DecLineNumber();
628 //store this msg into the shader's information log..set the Compile Error flag!!!!
629 message=GetStrfromTStr();
630 CPPShInfoLogMsg(message);
631 ResetTString();
632 cpp->CompileError=1;
633 IncLineNumber();
634 return '\n';
635}//CPPerror
636
637static int CPPpragma(yystypepp * yylvalpp)
638{
639 char SrcStrName[2];
640 char** allTokens;
641 int tokenCount = 0;
642 int maxTokenCount = 10;
643 const char* SrcStr;
644 int i;
645
646 int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
647
648 if (token=='\n') {
649 DecLineNumber();
650 CPPErrorToInfoLog("#pragma");
651 IncLineNumber();
652 return token;
653 }
654
655 allTokens = (char**)malloc(sizeof(char*) * maxTokenCount);
656
657 while (token != '\n') {
658 if (tokenCount >= maxTokenCount) {
659 maxTokenCount *= 2;
660 allTokens = (char**)realloc((char**)allTokens, sizeof(char*) * maxTokenCount);
661 }
662 switch (token) {
663 case CPP_IDENTIFIER:
664 SrcStr = GetAtomString(atable, yylvalpp->sc_ident);
665 allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
666 strcpy(allTokens[tokenCount++], SrcStr);
667 break;
668 case CPP_INTCONSTANT:
669 SrcStr = yylvalpp->symbol_name;
670 allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
671 strcpy(allTokens[tokenCount++], SrcStr);
672 break;
673 case CPP_FLOATCONSTANT:
674 SrcStr = yylvalpp->symbol_name;
675 allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
676 strcpy(allTokens[tokenCount++], SrcStr);
677 break;
678 case -1:
679 // EOF
680 CPPShInfoLogMsg("#pragma directive must end with a newline");
681 return token;
682 default:
683 SrcStrName[0] = token;
684 SrcStrName[1] = '\0';
685 allTokens[tokenCount] = (char*)malloc(2);
686 strcpy(allTokens[tokenCount++], SrcStrName);
687 }
688 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
689 }
690
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000691 HandlePragma((const char**)allTokens, tokenCount);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000692
693 for (i = 0; i < tokenCount; ++i) {
694 free (allTokens[i]);
695 }
696 free (allTokens);
697
698 return token;
699} // CPPpragma
700
daniel@transgaming.com76039472010-04-15 20:45:18 +0000701#define ESSL_VERSION_NUMBER 100
702#define ESSL_VERSION_STRING "100"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000703
704static int CPPversion(yystypepp * yylvalpp)
705{
706
707 int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
708
daniel@transgaming.comdec19e22010-04-29 03:35:42 +0000709 if (cpp->pastFirstStatement == 1)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000710 CPPShInfoLogMsg("#version must occur before any other statement in the program");
711
712 if(token=='\n'){
713 DecLineNumber();
714 CPPErrorToInfoLog("#version");
715 IncLineNumber();
716 return token;
717 }
718 if (token != CPP_INTCONSTANT)
719 CPPErrorToInfoLog("#version");
720
721 yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
722 //SetVersionNumber(yylvalpp->sc_int);
723
daniel@transgaming.com76039472010-04-15 20:45:18 +0000724 if (yylvalpp->sc_int != ESSL_VERSION_NUMBER)
725 CPPShInfoLogMsg("Version number not supported by ESSL");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000726
727 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
728
729 if (token == '\n'){
730 return token;
731 }
732 else{
733 CPPErrorToInfoLog("#version");
734 }
735 return token;
736} // CPPversion
737
738static int CPPextension(yystypepp * yylvalpp)
739{
740
741 int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000742 char extensionName[MAX_SYMBOL_NAME_LEN + 1];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000743
744 if(token=='\n'){
745 DecLineNumber();
746 CPPShInfoLogMsg("extension name not specified");
747 IncLineNumber();
748 return token;
749 }
750
751 if (token != CPP_IDENTIFIER)
752 CPPErrorToInfoLog("#extension");
753
alokp@chromium.org43668cd2010-10-20 20:55:53 +0000754 strncpy(extensionName, GetAtomString(atable, yylvalpp->sc_ident), MAX_SYMBOL_NAME_LEN);
755 extensionName[MAX_SYMBOL_NAME_LEN] = '\0';
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000756
757 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
758 if (token != ':') {
759 CPPShInfoLogMsg("':' missing after extension name");
760 return token;
761 }
762
763 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
764 if (token != CPP_IDENTIFIER) {
765 CPPShInfoLogMsg("behavior for extension not specified");
766 return token;
767 }
768
769 updateExtensionBehavior(extensionName, GetAtomString(atable, yylvalpp->sc_ident));
770
771 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
772 if (token == '\n'){
773 return token;
774 }
775 else{
776 CPPErrorToInfoLog("#extension");
777 }
778 return token;
779} // CPPextension
780
781int readCPPline(yystypepp * yylvalpp)
782{
783 int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
784 const char *message;
785 int isVersion = 0;
786
787 if (token == CPP_IDENTIFIER) {
788 if (yylvalpp->sc_ident == defineAtom) {
789 token = CPPdefine(yylvalpp);
790 } else if (yylvalpp->sc_ident == elseAtom) {
791 if(ChkCorrectElseNesting()){
792 if (!cpp->ifdepth ){
793 CPPErrorToInfoLog("#else mismatch");
794 cpp->CompileError=1;
daniel@transgaming.come9874052011-01-26 17:32:26 +0000795 return 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000796 }
797 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
798 if (token != '\n') {
799 CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
daniel@transgaming.com5efd8b42010-12-13 14:48:03 +0000800 while (token != '\n') {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000801 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
daniel@transgaming.com5efd8b42010-12-13 14:48:03 +0000802 if (token <= 0) { // EOF or error
803 CPPErrorToInfoLog("unexpected end of input in #ifdef preprocessor directive - expected a newline");
804 return 0;
805 }
806 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000807 }
808 token = CPPelse(0, yylvalpp);
809 }else{
810 CPPErrorToInfoLog("#else after a #else");
daniel@transgaming.come9874052011-01-26 17:32:26 +0000811 cpp->ifdepth = 0;
812 cpp->elsetracker = 0;
daniel@transgaming.comdec19e22010-04-29 03:35:42 +0000813 cpp->pastFirstStatement = 1;
daniel@transgaming.come9874052011-01-26 17:32:26 +0000814 cpp->CompileError = 1;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000815 return 0;
816 }
817 } else if (yylvalpp->sc_ident == elifAtom) {
818 if (!cpp->ifdepth){
819 CPPErrorToInfoLog("#elif mismatch");
820 cpp->CompileError=1;
daniel@transgaming.come9874052011-01-26 17:32:26 +0000821 return 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000822 }
823 // this token is really a dont care, but we still need to eat the tokens
824 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
daniel@transgaming.com5efd8b42010-12-13 14:48:03 +0000825 while (token != '\n') {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000826 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
daniel@transgaming.com5efd8b42010-12-13 14:48:03 +0000827 if (token <= 0) { // EOF or error
828 CPPErrorToInfoLog("unexpect tokens following #elif preprocessor directive - expected a newline");
829 cpp->CompileError = 1;
daniel@transgaming.come9874052011-01-26 17:32:26 +0000830 return 0;
daniel@transgaming.com5efd8b42010-12-13 14:48:03 +0000831 }
832 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000833 token = CPPelse(0, yylvalpp);
834 } else if (yylvalpp->sc_ident == endifAtom) {
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000835 if (!cpp->ifdepth){
836 CPPErrorToInfoLog("#endif mismatch");
837 cpp->CompileError=1;
daniel@transgaming.come9874052011-01-26 17:32:26 +0000838 return 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000839 }
840 else
daniel@transgaming.come9874052011-01-26 17:32:26 +0000841 --cpp->ifdepth;
842
843 if (cpp->elsetracker)
844 --cpp->elsetracker;
845
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000846 } else if (yylvalpp->sc_ident == ifAtom) {
847 token = CPPif(yylvalpp);
848 } else if (yylvalpp->sc_ident == ifdefAtom) {
849 token = CPPifdef(1, yylvalpp);
850 } else if (yylvalpp->sc_ident == ifndefAtom) {
851 token = CPPifdef(0, yylvalpp);
852 } else if (yylvalpp->sc_ident == lineAtom) {
853 token = CPPline(yylvalpp);
854 } else if (yylvalpp->sc_ident == pragmaAtom) {
855 token = CPPpragma(yylvalpp);
856 } else if (yylvalpp->sc_ident == undefAtom) {
857 token = CPPundef(yylvalpp);
858 } else if (yylvalpp->sc_ident == errorAtom) {
859 token = CPPerror(yylvalpp);
860 } else if (yylvalpp->sc_ident == versionAtom) {
861 token = CPPversion(yylvalpp);
862 isVersion = 1;
863 } else if (yylvalpp->sc_ident == extensionAtom) {
864 token = CPPextension(yylvalpp);
865 } else {
866 StoreStr("Invalid Directive");
867 StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident));
868 message=GetStrfromTStr();
869 CPPShInfoLogMsg(message);
870 ResetTString();
871 }
872 }
873 while (token != '\n' && token != 0 && token != EOF) {
874 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
875 }
876
daniel@transgaming.comdec19e22010-04-29 03:35:42 +0000877 cpp->pastFirstStatement = 1;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000878
879 return token;
880} // readCPPline
881
882void FreeMacro(MacroSymbol *s) {
883 DeleteTokenStream(s->body);
884}
885
daniel@transgaming.comcd0a9a82010-05-18 18:51:59 +0000886void PredefineIntMacro(const char *name, int value) {
887 SourceLoc location = {0};
888 Symbol *symbol = NULL;
889 MacroSymbol macro = {0};
890 yystypepp val = {0};
891 int atom = 0;
892
893 macro.body = NewTokenStream(name, macros->pool);
894 val.sc_int = value;
kbr@chromium.orgddb6e8e2012-04-25 00:48:13 +0000895 snprintf(val.symbol_name, MAX_SYMBOL_NAME_LEN+1, "%d", value);
daniel@transgaming.comcd0a9a82010-05-18 18:51:59 +0000896 RecordToken(macro.body, CPP_INTCONSTANT, &val);
897 atom = LookUpAddString(atable, name);
898 symbol = AddSymbol(&location, macros, atom, MACRO_S);
899 symbol->details.mac = macro;
900}
901
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000902static int eof_scan(InputSrc *in, yystypepp * yylvalpp) { return -1; }
903static void noop(InputSrc *in, int ch, yystypepp * yylvalpp) { }
904
905static void PushEofSrc() {
906 InputSrc *in = malloc(sizeof(InputSrc));
907 memset(in, 0, sizeof(InputSrc));
908 in->scan = eof_scan;
909 in->getch = eof_scan;
910 in->ungetch = noop;
911 in->prev = cpp->currentInput;
912 cpp->currentInput = in;
913}
914
915static void PopEofSrc() {
916 if (cpp->currentInput->scan == eof_scan) {
917 InputSrc *in = cpp->currentInput;
918 cpp->currentInput = in->prev;
919 free(in);
920 }
921}
922
923static TokenStream *PrescanMacroArg(TokenStream *a, yystypepp * yylvalpp) {
924 int token;
925 TokenStream *n;
926 RewindTokenStream(a);
927 do {
928 token = ReadToken(a, yylvalpp);
929 if (token == CPP_IDENTIFIER && LookUpSymbol(macros, yylvalpp->sc_ident))
930 break;
931 } while (token > 0);
932 if (token <= 0) return a;
933 n = NewTokenStream("macro arg", 0);
934 PushEofSrc();
935 ReadFromTokenStream(a, 0, 0);
936 while ((token = cpp->currentInput->scan(cpp->currentInput, yylvalpp)) > 0) {
937 if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp->sc_ident, yylvalpp))
938 continue;
939 RecordToken(n, token, yylvalpp);
940 }
941 PopEofSrc();
942 DeleteTokenStream(a);
943 return n;
944} // PrescanMacroArg
945
946typedef struct MacroInputSrc {
947 InputSrc base;
948 MacroSymbol *mac;
949 TokenStream **args;
950} MacroInputSrc;
951
952/* macro_scan ---
953** return the next token for a macro expanion, handling macro args
954*/
955static int macro_scan(MacroInputSrc *in, yystypepp * yylvalpp) {
956 int i;
957 int token = ReadToken(in->mac->body, yylvalpp);
958 if (token == CPP_IDENTIFIER) {
959 for (i = in->mac->argc-1; i>=0; i--)
960 if (in->mac->args[i] == yylvalpp->sc_ident) break;
961 if (i >= 0) {
962 ReadFromTokenStream(in->args[i], yylvalpp->sc_ident, 0);
963 return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
964 }
965 }
966 if (token > 0) return token;
967 in->mac->busy = 0;
968 cpp->currentInput = in->base.prev;
969 if (in->args) {
970 for (i=in->mac->argc-1; i>=0; i--)
971 DeleteTokenStream(in->args[i]);
972 free(in->args);
973 }
974 free(in);
975 return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
976} // macro_scan
977
978/* MacroExpand
979** check an identifier (atom) to see if it a macro that should be expanded.
980** If it is, push an InputSrc that will produce the appropriate expansion
981** and return TRUE. If not, return FALSE.
982*/
983
984int MacroExpand(int atom, yystypepp * yylvalpp)
985{
986 Symbol *sym = LookUpSymbol(macros, atom);
987 MacroInputSrc *in;
988 int i,j, token, depth=0;
989 const char *message;
990 if (atom == __LINE__Atom) {
991 yylvalpp->sc_int = GetLineNumber();
kbr@chromium.orgddb6e8e2012-04-25 00:48:13 +0000992 snprintf(yylvalpp->symbol_name, MAX_SYMBOL_NAME_LEN+1, "%d", yylvalpp->sc_int);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000993 UngetToken(CPP_INTCONSTANT, yylvalpp);
994 return 1;
995 }
996 if (atom == __FILE__Atom) {
997 yylvalpp->sc_int = GetStringNumber();
kbr@chromium.orgddb6e8e2012-04-25 00:48:13 +0000998 snprintf(yylvalpp->symbol_name, MAX_SYMBOL_NAME_LEN+1, "%d", yylvalpp->sc_int);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000999 UngetToken(CPP_INTCONSTANT, yylvalpp);
1000 return 1;
1001 }
1002 if (atom == __VERSION__Atom) {
daniel@transgaming.com76039472010-04-15 20:45:18 +00001003 strcpy(yylvalpp->symbol_name,ESSL_VERSION_STRING);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001004 yylvalpp->sc_int = atoi(yylvalpp->symbol_name);
1005 UngetToken(CPP_INTCONSTANT, yylvalpp);
1006 return 1;
1007 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001008 if (!sym || sym->details.mac.undef) return 0;
1009 if (sym->details.mac.busy) return 0; // no recursive expansions
1010 in = malloc(sizeof(*in));
1011 memset(in, 0, sizeof(*in));
1012 in->base.scan = (void *)macro_scan;
1013 in->base.line = cpp->currentInput->line;
1014 in->base.name = cpp->currentInput->name;
1015 in->mac = &sym->details.mac;
1016 if (sym->details.mac.args) {
1017 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
1018 if (token != '(') {
1019 UngetToken(token, yylvalpp);
1020 yylvalpp->sc_ident = atom;
1021 return 0;
1022 }
1023 in->args = malloc(in->mac->argc * sizeof(TokenStream *));
1024 for (i=0; i<in->mac->argc; i++)
1025 in->args[i] = NewTokenStream("macro arg", 0);
1026 i=0;j=0;
1027 do{
1028 depth = 0;
1029 while(1) {
1030 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
1031 if (token <= 0) {
1032 StoreStr("EOF in Macro ");
1033 StoreStr(GetStringOfAtom(atable,atom));
1034 message=GetStrfromTStr();
1035 CPPShInfoLogMsg(message);
1036 ResetTString();
1037 return 1;
1038 }
1039 if((in->mac->argc==0) && (token!=')')) break;
1040 if (depth == 0 && (token == ',' || token == ')')) break;
1041 if (token == '(') depth++;
1042 if (token == ')') depth--;
1043 RecordToken(in->args[i], token, yylvalpp);
1044 j=1;
1045 }
1046 if (token == ')') {
1047 if((in->mac->argc==1) &&j==0)
1048 break;
1049 i++;
1050 break;
1051 }
1052 i++;
1053 }while(i < in->mac->argc);
1054
1055 if (i < in->mac->argc) {
1056 StoreStr("Too few args in Macro ");
1057 StoreStr(GetStringOfAtom(atable,atom));
1058 message=GetStrfromTStr();
1059 CPPShInfoLogMsg(message);
1060 ResetTString();
1061 } else if (token != ')') {
1062 depth=0;
1063 while (token >= 0 && (depth > 0 || token != ')')) {
1064 if (token == ')') depth--;
1065 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
1066 if (token == '(') depth++;
1067 }
1068
1069 if (token <= 0) {
1070 StoreStr("EOF in Macro ");
1071 StoreStr(GetStringOfAtom(atable,atom));
1072 message=GetStrfromTStr();
1073 CPPShInfoLogMsg(message);
1074 ResetTString();
1075 return 1;
1076 }
1077 StoreStr("Too many args in Macro ");
1078 StoreStr(GetStringOfAtom(atable,atom));
1079 message=GetStrfromTStr();
1080 CPPShInfoLogMsg(message);
1081 ResetTString();
1082 }
1083 for (i=0; i<in->mac->argc; i++) {
1084 in->args[i] = PrescanMacroArg(in->args[i], yylvalpp);
1085 }
1086 }
1087#if 0
1088 printf(" <%s:%d>found macro %s\n", GetAtomString(atable, loc.file),
1089 loc.line, GetAtomString(atable, atom));
1090 for (i=0; i<in->mac->argc; i++) {
1091 printf("\targ %s = '", GetAtomString(atable, in->mac->args[i]));
1092 DumpTokenStream(stdout, in->args[i]);
1093 printf("'\n");
1094 }
1095#endif
1096 /*retain the input source*/
1097 in->base.prev = cpp->currentInput;
1098 sym->details.mac.busy = 1;
1099 RewindTokenStream(sym->details.mac.body);
1100 cpp->currentInput = &in->base;
1101 return 1;
1102} // MacroExpand
1103
1104int ChkCorrectElseNesting(void)
1105{
daniel@transgaming.come9874052011-01-26 17:32:26 +00001106 // sanity check to make sure elsetracker is in a valid range
1107 if (cpp->elsetracker < 0 || cpp->elsetracker >= MAX_IF_NESTING) {
1108 return 0;
1109 }
1110
1111 if (cpp->elsedepth[cpp->elsetracker] == 0) {
1112 cpp->elsedepth[cpp->elsetracker] = 1;
1113 return 1;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001114 }
1115 return 0;
1116}
1117
1118