LCOV - app.info - gfx/angle/src/compiler/preprocessor/cpp.c

LCOV - code coverage report
| Current view: | directory - gfx/angle/src/compiler/preprocessor - cpp.c (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 676 | 0 | 0.0 %
| Date: | 2012-07-07 | Functions: | 47 | 0 | 0.0 %

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

Generated by: LCOV version 1.7