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