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