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