blob: acec131031a0edd1e9c19686ee39e3f52fe2d17d [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001/*
2//
3// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7*/
8/* Based on
9ANSI C grammar, Lex specification
10
11In 1985, Jeff Lee published this Lex specification together with a Yacc
12grammar for the April 30, 1985 ANSI C draft. Tom Stockfisch reposted
13both to net.sources in 1987; that original, as mentioned in the answer
14to question 17.25 of the comp.lang.c FAQ, can be ftp'ed from ftp.uu.net,
15file usenet/net.sources/ansi.c.grammar.Z.
16
17I intend to keep this version as close to the current C Standard grammar
18as possible; please let me know if you discover discrepancies.
19
20Jutta Degener, 1995
21*/
22
23D [0-9]
24L [a-zA-Z_]
25H [a-fA-F0-9]
26E [Ee][+-]?{D}+
27O [0-7]
28
29%option nounput
30%{
31#include <stdio.h>
32#include <stdlib.h>
alokp@chromium.orgeab1ef12010-04-23 17:33:49 +000033
daniel@transgaming.come6842292010-04-20 18:52:50 +000034#include "compiler/ParseHelper.h"
daniel@transgaming.com91ed1492010-10-29 03:11:43 +000035#include "compiler/util.h"
alokp@chromium.orgeab1ef12010-04-23 17:33:49 +000036#include "glslang_tab.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000037
38/* windows only pragma */
39#ifdef _MSC_VER
40#pragma warning(disable : 4102)
41#endif
42
43int yy_input(char* buf, int max_size);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000044
alokp@chromium.org29d56fb2010-04-06 15:42:22 +000045extern int yyparse(void*);
46#define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal)
47#define parseContext (*((TParseContext*)(parseContextLocal)))
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000048
49#define YY_INPUT(buf,result,max_size) (result = yy_input(buf, max_size))
50
51%}
52
alokp@chromium.org29d56fb2010-04-06 15:42:22 +000053/*
54TODO(alokp): yylineno is only here to support old flex.exe in compiler/tools.
55Remove it when we can exclusively use the newer version.
56*/
57%option yylineno
58
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000059%option noyywrap
60%option never-interactive
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000061%x FIELDS
62
63
64%%
65<*>"//"[^\n]*"\n" { /* ?? carriage and/or line-feed? */ };
66
67"invariant" { pyylval->lex.line = yylineno; return(INVARIANT); }
68"highp" { pyylval->lex.line = yylineno; return(HIGH_PRECISION); }
69"mediump" { pyylval->lex.line = yylineno; return(MEDIUM_PRECISION); }
70"lowp" { pyylval->lex.line = yylineno; return(LOW_PRECISION); }
71"precision" { pyylval->lex.line = yylineno; return(PRECISION); }
72
73"attribute" { pyylval->lex.line = yylineno; return(ATTRIBUTE); }
74"const" { pyylval->lex.line = yylineno; return(CONST_QUAL); }
75"uniform" { pyylval->lex.line = yylineno; return(UNIFORM); }
76"varying" { pyylval->lex.line = yylineno; return(VARYING); }
77
78"break" { pyylval->lex.line = yylineno; return(BREAK); }
79"continue" { pyylval->lex.line = yylineno; return(CONTINUE); }
80"do" { pyylval->lex.line = yylineno; return(DO); }
81"for" { pyylval->lex.line = yylineno; return(FOR); }
82"while" { pyylval->lex.line = yylineno; return(WHILE); }
83
84"if" { pyylval->lex.line = yylineno; return(IF); }
85"else" { pyylval->lex.line = yylineno; return(ELSE); }
86
87"in" { pyylval->lex.line = yylineno; return(IN_QUAL); }
88"out" { pyylval->lex.line = yylineno; return(OUT_QUAL); }
89"inout" { pyylval->lex.line = yylineno; return(INOUT_QUAL); }
90
91"float" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(FLOAT_TYPE); }
92"int" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(INT_TYPE); }
93"void" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(VOID_TYPE); }
94"bool" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(BOOL_TYPE); }
95"true" { pyylval->lex.line = yylineno; pyylval->lex.b = true; return(BOOLCONSTANT); }
96"false" { pyylval->lex.line = yylineno; pyylval->lex.b = false; return(BOOLCONSTANT); }
97
98"discard" { pyylval->lex.line = yylineno; return(DISCARD); }
99"return" { pyylval->lex.line = yylineno; return(RETURN); }
100
101"mat2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX2); }
102"mat3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX3); }
103"mat4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX4); }
104
105"vec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC2); }
106"vec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC3); }
107"vec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC4); }
108"ivec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC2); }
109"ivec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC3); }
110"ivec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC4); }
111"bvec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC2); }
112"bvec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC3); }
113"bvec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC4); }
114
115"sampler2D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2D; }
116"samplerCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERCUBE; }
117
daniel@transgaming.com8026c672010-05-20 19:17:48 +0000118"struct" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(STRUCT); }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000119
120"asm" { PaReservedWord(); return 0; }
121
122"class" { PaReservedWord(); return 0; }
123"union" { PaReservedWord(); return 0; }
124"enum" { PaReservedWord(); return 0; }
125"typedef" { PaReservedWord(); return 0; }
126"template" { PaReservedWord(); return 0; }
127"this" { PaReservedWord(); return 0; }
128"packed" { PaReservedWord(); return 0; }
129
130"goto" { PaReservedWord(); return 0; }
131"switch" { PaReservedWord(); return 0; }
132"default" { PaReservedWord(); return 0; }
133
134"inline" { PaReservedWord(); return 0; }
135"noinline" { PaReservedWord(); return 0; }
136"volatile" { PaReservedWord(); return 0; }
137"public" { PaReservedWord(); return 0; }
138"static" { PaReservedWord(); return 0; }
139"extern" { PaReservedWord(); return 0; }
140"external" { PaReservedWord(); return 0; }
141"interface" { PaReservedWord(); return 0; }
142
143"long" { PaReservedWord(); return 0; }
144"short" { PaReservedWord(); return 0; }
145"double" { PaReservedWord(); return 0; }
146"half" { PaReservedWord(); return 0; }
147"fixed" { PaReservedWord(); return 0; }
148"unsigned" { PaReservedWord(); return 0; }
149
150"input" { PaReservedWord(); return 0; }
151"output" { PaReservedWord(); return 0; }
152
153"hvec2" { PaReservedWord(); return 0; }
154"hvec3" { PaReservedWord(); return 0; }
155"hvec4" { PaReservedWord(); return 0; }
156"fvec2" { PaReservedWord(); return 0; }
157"fvec3" { PaReservedWord(); return 0; }
158"fvec4" { PaReservedWord(); return 0; }
159"dvec2" { PaReservedWord(); return 0; }
160"dvec3" { PaReservedWord(); return 0; }
161"dvec4" { PaReservedWord(); return 0; }
162
163"sizeof" { PaReservedWord(); return 0; }
164"cast" { PaReservedWord(); return 0; }
165
166"namespace" { PaReservedWord(); return 0; }
167"using" { PaReservedWord(); return 0; }
168
169{L}({L}|{D})* {
170 pyylval->lex.line = yylineno;
171 pyylval->lex.string = NewPoolTString(yytext);
172 return PaIdentOrType(*pyylval->lex.string, parseContext, pyylval->lex.symbol);
173}
174
1750[xX]{H}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
1760{O}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
1770{D}+ { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); parseContext.recover(); return 0;}
178{D}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
179
daniel@transgaming.com91ed1492010-10-29 03:11:43 +0000180{D}+{E} { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
181{D}+"."{D}*({E})? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
182"."{D}+({E})? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000183
184"/*" { int ret = PaParseComment(pyylval->lex.line, parseContext); if (!ret) return ret; }
185
186"+=" { pyylval->lex.line = yylineno; return(ADD_ASSIGN); }
187"-=" { pyylval->lex.line = yylineno; return(SUB_ASSIGN); }
188"*=" { pyylval->lex.line = yylineno; return(MUL_ASSIGN); }
189"/=" { pyylval->lex.line = yylineno; return(DIV_ASSIGN); }
190"%=" { pyylval->lex.line = yylineno; return(MOD_ASSIGN); }
191"<<=" { pyylval->lex.line = yylineno; return(LEFT_ASSIGN); }
192">>=" { pyylval->lex.line = yylineno; return(RIGHT_ASSIGN); }
193"&=" { pyylval->lex.line = yylineno; return(AND_ASSIGN); }
194"^=" { pyylval->lex.line = yylineno; return(XOR_ASSIGN); }
195"|=" { pyylval->lex.line = yylineno; return(OR_ASSIGN); }
196
197"++" { pyylval->lex.line = yylineno; return(INC_OP); }
198"--" { pyylval->lex.line = yylineno; return(DEC_OP); }
199"&&" { pyylval->lex.line = yylineno; return(AND_OP); }
200"||" { pyylval->lex.line = yylineno; return(OR_OP); }
201"^^" { pyylval->lex.line = yylineno; return(XOR_OP); }
202"<=" { pyylval->lex.line = yylineno; return(LE_OP); }
203">=" { pyylval->lex.line = yylineno; return(GE_OP); }
204"==" { pyylval->lex.line = yylineno; return(EQ_OP); }
205"!=" { pyylval->lex.line = yylineno; return(NE_OP); }
206"<<" { pyylval->lex.line = yylineno; return(LEFT_OP); }
207">>" { pyylval->lex.line = yylineno; return(RIGHT_OP); }
208";" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(SEMICOLON); }
209("{"|"<%") { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(LEFT_BRACE); }
210("}"|"%>") { pyylval->lex.line = yylineno; return(RIGHT_BRACE); }
211"," { pyylval->lex.line = yylineno; if (parseContext.inTypeParen) parseContext.lexAfterType = false; return(COMMA); }
212":" { pyylval->lex.line = yylineno; return(COLON); }
213"=" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(EQUAL); }
214"(" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; parseContext.inTypeParen = true; return(LEFT_PAREN); }
215")" { pyylval->lex.line = yylineno; parseContext.inTypeParen = false; return(RIGHT_PAREN); }
216("["|"<:") { pyylval->lex.line = yylineno; return(LEFT_BRACKET); }
217("]"|":>") { pyylval->lex.line = yylineno; return(RIGHT_BRACKET); }
218"." { BEGIN(FIELDS); return(DOT); }
219"!" { pyylval->lex.line = yylineno; return(BANG); }
220"-" { pyylval->lex.line = yylineno; return(DASH); }
221"~" { pyylval->lex.line = yylineno; return(TILDE); }
222"+" { pyylval->lex.line = yylineno; return(PLUS); }
223"*" { pyylval->lex.line = yylineno; return(STAR); }
224"/" { pyylval->lex.line = yylineno; return(SLASH); }
225"%" { pyylval->lex.line = yylineno; return(PERCENT); }
226"<" { pyylval->lex.line = yylineno; return(LEFT_ANGLE); }
227">" { pyylval->lex.line = yylineno; return(RIGHT_ANGLE); }
228"|" { pyylval->lex.line = yylineno; return(VERTICAL_BAR); }
229"^" { pyylval->lex.line = yylineno; return(CARET); }
230"&" { pyylval->lex.line = yylineno; return(AMPERSAND); }
231"?" { pyylval->lex.line = yylineno; return(QUESTION); }
232
233<FIELDS>{L}({L}|{D})* {
234BEGIN(INITIAL);
235 pyylval->lex.line = yylineno;
236 pyylval->lex.string = NewPoolTString(yytext);
237 return FIELD_SELECTION; }
238<FIELDS>[ \t\v\f\r] {}
239
240[ \t\v\n\f\r] { }
241<*><<EOF>> { (&parseContext)->AfterEOF = true; yy_delete_buffer(YY_CURRENT_BUFFER); yyterminate();}
242<*>. { parseContext.infoSink.info << "FLEX: Unknown char " << yytext << "\n";
243 return 0; }
244
245%%
246
247
248//Including Pre-processor.
249extern "C" {
daniel@transgaming.come6842292010-04-20 18:52:50 +0000250 #include "compiler/preprocessor/preprocess.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000251}
252
253//
254// The YY_INPUT macro just calls this. Maybe this could be just put into
255// the macro directly.
256//
257
258int yy_input(char* buf, int max_size)
259{
260 int len;
261
262 if ((len = yylex_CPP(buf, max_size)) == 0)
263 return 0;
264 if (len >= max_size)
265 YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
266
267 buf[len] = ' ';
268 return len+1;
269}
270
271
272//
273// Parse an array of strings using yyparse. We set up globals used by
274// yywrap.
275//
276// Returns 0 for success, as per yyparse().
277//
alokp@chromium.org07620a52010-09-23 17:53:56 +0000278int PaParseStrings(const char* const argv[], const int strLen[], int argc, TParseContext& parseContextLocal)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000279{
280 int argv0len;
281
282 ScanFromString(argv[0]);
283
284 //Storing the Current Compiler Parse context into the cpp structure.
285 cpp->pC = (void*)&parseContextLocal;
286
287 if (!argv || argc == 0)
288 return 1;
289
290 for (int i = 0; i < argc; ++i) {
291 if (!argv[i]) {
292 parseContextLocal.error(0, "Null shader source string", "", "");
293 parseContextLocal.recover();
294 return 1;
295 }
296 }
297
298 if (!strLen) {
299 argv0len = (int) strlen(argv[0]);
300 strLen = &argv0len;
301 }
302 yyrestart(0);
303 (&parseContextLocal)->AfterEOF = false;
304 cpp->PaWhichStr = 0;
305 cpp->PaArgv = argv;
306 cpp->PaArgc = argc;
307 cpp->PaStrLen = strLen;
daniel@transgaming.comdec19e22010-04-29 03:35:42 +0000308 cpp->pastFirstStatement = 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000309 yylineno = 1;
310
311 if (*cpp->PaStrLen >= 0) {
alokp@chromium.org29d56fb2010-04-06 15:42:22 +0000312 int ret = yyparse((void*)(&parseContextLocal));
alokp@chromium.org6eed5eb2010-08-09 22:29:59 +0000313 if (ret || cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000314 return 1;
315 else
316 return 0;
317 }
318 else
319 return 0;
320}
321
alokp@chromium.orgf5855c52010-10-21 16:31:18 +0000322void yyerror(const char *reason)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000323{
324 if (((TParseContext *)cpp->pC)->AfterEOF) {
alokp@chromium.orgf5855c52010-10-21 16:31:18 +0000325 if (cpp->tokensBeforeEOF == 1)
326 GlobalParseContext->error(yylineno, reason, "pre-mature EOF", "");
327 else
328 GlobalParseContext->error(yylineno, reason, "unexpected EOF", "");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000329 } else {
alokp@chromium.orgf5855c52010-10-21 16:31:18 +0000330 GlobalParseContext->error(yylineno, reason, yytext, "");
331 }
332 GlobalParseContext->recover();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000333}
334
335void PaReservedWord()
336{
337 GlobalParseContext->error(yylineno, "Reserved word.", yytext, "", "");
338 GlobalParseContext->recover();
339}
340
341int PaIdentOrType(TString& id, TParseContext& parseContextLocal, TSymbol*& symbol)
342{
343 symbol = parseContextLocal.symbolTable.find(id);
344 if (parseContextLocal.lexAfterType == false && symbol && symbol->isVariable()) {
345 TVariable* variable = static_cast<TVariable*>(symbol);
346 if (variable->isUserType()) {
347 parseContextLocal.lexAfterType = true;
348 return TYPE_NAME;
349 }
350 }
351
352 return IDENTIFIER;
353}
354
355int PaParseComment(int &lineno, TParseContext& parseContextLocal)
356{
357 int transitionFlag = 0;
358 int nextChar;
359
360 while (transitionFlag != 2) {
361 nextChar = yyinput();
362 if (nextChar == '\n')
363 lineno++;
364 switch (nextChar) {
365 case '*' :
366 transitionFlag = 1;
367 break;
368 case '/' : /* if star is the previous character, then it is the end of comment */
369 if (transitionFlag == 1) {
370 return 1 ;
371 }
372 break;
373 case EOF :
374 /* Raise error message here */
375 parseContextLocal.error(yylineno, "End of shader found before end of comment.", "", "", "");
376 GlobalParseContext->recover();
377 return YY_NULL;
378 default : /* Any other character will be a part of the comment */
379 transitionFlag = 0;
380 }
381 }
382 return 1;
383}
384
385extern "C" {
386
387void CPPDebugLogMsg(const char *msg)
388{
389 ((TParseContext *)cpp->pC)->infoSink.debug.message(EPrefixNone, msg);
390}
391
392void CPPWarningToInfoLog(const char *msg)
393{
394 ((TParseContext *)cpp->pC)->infoSink.info.message(EPrefixWarning, msg, yylineno);
395}
396
397void CPPShInfoLogMsg(const char *msg)
398{
399 ((TParseContext *)cpp->pC)->error(yylineno,"", "",msg,"");
400 GlobalParseContext->recover();
401}
402
403void CPPErrorToInfoLog(char *msg)
404{
405 ((TParseContext *)cpp->pC)->error(yylineno,"syntax error", "",msg,"");
406 GlobalParseContext->recover();
407}
408
409void SetLineNumber(int line)
410{
411 yylineno &= ~SourceLocLineMask;
412 yylineno |= line;
413}
414
415void SetStringNumber(int string)
416{
417 yylineno = (string << SourceLocStringShift) | (yylineno & SourceLocLineMask);
418}
419
420int GetStringNumber(void)
421{
422 return yylineno >> 16;
423}
424
425int GetLineNumber(void)
426{
427 return yylineno & SourceLocLineMask;
428}
429
430void IncLineNumber(void)
431{
432 if ((yylineno & SourceLocLineMask) <= SourceLocLineMask)
433 ++yylineno;
434}
435
436void DecLineNumber(void)
437{
438 if ((yylineno & SourceLocLineMask) > 0)
439 --yylineno;
440}
441
442void HandlePragma(const char **tokens, int numTokens)
443{
444 if (!strcmp(tokens[0], "optimize")) {
445 if (numTokens != 4) {
446 CPPShInfoLogMsg("optimize pragma syntax is incorrect");
447 return;
448 }
449
450 if (strcmp(tokens[1], "(")) {
451 CPPShInfoLogMsg("\"(\" expected after 'optimize' keyword");
452 return;
453 }
454
455 if (!strcmp(tokens[2], "on"))
456 ((TParseContext *)cpp->pC)->contextPragma.optimize = true;
457 else if (!strcmp(tokens[2], "off"))
458 ((TParseContext *)cpp->pC)->contextPragma.optimize = false;
459 else {
460 CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma");
461 return;
462 }
463
464 if (strcmp(tokens[3], ")")) {
465 CPPShInfoLogMsg("\")\" expected to end 'optimize' pragma");
466 return;
467 }
468 } else if (!strcmp(tokens[0], "debug")) {
469 if (numTokens != 4) {
470 CPPShInfoLogMsg("debug pragma syntax is incorrect");
471 return;
472 }
473
474 if (strcmp(tokens[1], "(")) {
475 CPPShInfoLogMsg("\"(\" expected after 'debug' keyword");
476 return;
477 }
478
479 if (!strcmp(tokens[2], "on"))
480 ((TParseContext *)cpp->pC)->contextPragma.debug = true;
481 else if (!strcmp(tokens[2], "off"))
482 ((TParseContext *)cpp->pC)->contextPragma.debug = false;
483 else {
484 CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma");
485 return;
486 }
487
488 if (strcmp(tokens[3], ")")) {
489 CPPShInfoLogMsg("\")\" expected to end 'debug' pragma");
490 return;
491 }
492 } else {
493
494#ifdef PRAGMA_TABLE
495 //
496 // implementation specific pragma
497 // use ((TParseContext *)cpp->pC)->contextPragma.pragmaTable to store the information about pragma
498 // For now, just ignore the pragma that the implementation cannot recognize
499 // An Example of one such implementation for a pragma that has a syntax like
500 // #pragma pragmaname(pragmavalue)
501 // This implementation stores the current pragmavalue against the pragma name in pragmaTable.
502 //
503 if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) {
504 TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable;
505 TPragmaTable::iterator iter;
506 iter = pragmaTable.find(TString(tokens[0]));
507 if (iter != pragmaTable.end()) {
508 iter->second = tokens[2];
509 } else {
alokp@chromium.org7e0ed772010-05-12 21:16:46 +0000510 pragmaTable[ tokens[0] ] = tokens[2];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000511 }
512 } else if (numTokens >= 2) {
513 TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable;
514 TPragmaTable::iterator iter;
515 iter = pragmaTable.find(TString(tokens[0]));
516 if (iter != pragmaTable.end()) {
517 iter->second = tokens[1];
518 } else {
alokp@chromium.org7e0ed772010-05-12 21:16:46 +0000519 pragmaTable[ tokens[0] ] = tokens[1];
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000520 }
521 }
522#endif // PRAGMA_TABLE
523 }
524}
525
526void StoreStr(char *string)
527{
528 TString strSrc;
529 strSrc = TString(string);
530
531 ((TParseContext *)cpp->pC)->HashErrMsg = ((TParseContext *)cpp->pC)->HashErrMsg + " " + strSrc;
532}
533
534const char* GetStrfromTStr(void)
535{
536 cpp->ErrMsg = (((TParseContext *)cpp->pC)->HashErrMsg).c_str();
537 return cpp->ErrMsg;
538}
539
540void ResetTString(void)
541{
542 ((TParseContext *)cpp->pC)->HashErrMsg = "";
543}
544
545TBehavior GetBehavior(const char* behavior)
546{
547 if (!strcmp("require", behavior))
548 return EBhRequire;
549 else if (!strcmp("enable", behavior))
550 return EBhEnable;
551 else if (!strcmp("disable", behavior))
552 return EBhDisable;
553 else if (!strcmp("warn", behavior))
554 return EBhWarn;
555 else {
556 CPPShInfoLogMsg((TString("behavior '") + behavior + "' is not supported").c_str());
557 return EBhDisable;
558 }
559}
560
561void updateExtensionBehavior(const char* extName, const char* behavior)
562{
563 TBehavior behaviorVal = GetBehavior(behavior);
564 TMap<TString, TBehavior>:: iterator iter;
565 TString msg;
566
567 // special cased for all extension
568 if (!strcmp(extName, "all")) {
569 if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) {
570 CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior");
571 return;
572 } else {
573 for (iter = ((TParseContext *)cpp->pC)->extensionBehavior.begin(); iter != ((TParseContext *)cpp->pC)->extensionBehavior.end(); ++iter)
574 iter->second = behaviorVal;
575 }
576 } else {
577 iter = ((TParseContext *)cpp->pC)->extensionBehavior.find(TString(extName));
578 if (iter == ((TParseContext *)cpp->pC)->extensionBehavior.end()) {
579 switch (behaviorVal) {
580 case EBhRequire:
581 CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str());
582 break;
583 case EBhEnable:
584 case EBhWarn:
585 case EBhDisable:
586 msg = TString("extension '") + extName + "' is not supported";
587 ((TParseContext *)cpp->pC)->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno);
588 break;
589 }
590 return;
591 } else
592 iter->second = behaviorVal;
593 }
594}
595
596} // extern "C"
597
598void setInitialState()
599{
600 yy_start = 1;
601}