-/*;-*-C-*-; \r
-** Copyright (c) Massachusetts Institute of Technology 1994-1998.\r
-** All Rights Reserved.\r
-** Unpublished rights reserved under the copyright laws of\r
-** the United States.\r
-**\r
-** THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED\r
-** OR IMPLIED. ANY USE IS AT YOUR OWN RISK.\r
-**\r
-** This code is distributed freely and may be used freely under the \r
-** following conditions:\r
-**\r
-** 1. This notice may not be removed or altered.\r
-**\r
-** 2. Works derived from this code are not distributed for\r
-** commercial gain without explicit permission from MIT \r
-** (for permission contact lclint-request@sds.lcs.mit.edu).\r
-*/\r
-/*\r
- * Modified by Herbert 08/19/97:\r
- * - added #include for IBM's OS/2 compiler.\r
- * - fixed weird bug with lookup of tmp files (OS/2 and MSDOS only).\r
- */\r
-\r
-/*\r
- * Modified by Mike Smith \r
- * Corrected missing 'line' in scanf() calls in handleSpecial().\r
- * Without this, I get an error when LCLint hits a '#line' directive\r
- * in the pre-pre-processed source files. For safety, I have made these\r
- * conditional on OS2 and MSDOS because I don't understand why noone else\r
- * has seen this problem.\r
- *\r
- * Modified by Mike Smith, 4th June 1997\r
- * Finally resolved the #line problem. The scanf() calls have been fixed to\r
- * allow the following #line forms:-\r
- *\r
- * #line 123 "filename"\r
- * #line 123\r
- * # 123 "filename"\r
- * # 123\r
- *\r
- * The last two are generated by the GNU pre-processor, apparently\r
- */\r
-\r
-Digit [0-9]\r
-Letter [a-zA-Z_$]\r
-H [a-fA-F0-9]\r
-E [Ee][+-]?{Digit}+\r
-U (u|U)\r
-L (l|L)\r
-FS (f|F|l|L)\r
-IS (u|U|l|L)*\r
-ULSuffix ({U}{L}|{L}{U})\r
-\r
-%{\r
-/*\r
-** based on original C lexer by Nate Osgood\r
-** from hacrat@catfish.lcs.mit.edu Mon Jun 14 13:06:32 1993\r
-**\r
-*/\r
-\r
-# include "lclintMacros.nf"\r
-# if defined(OS2) && defined(__IBMC__)\r
- /* needed for isatty()... */\r
-# include <io.h>\r
-# else\r
-# include <unistd.h>\r
-# endif\r
-\r
-# include "basic.h"\r
-\r
-# include "cgrammar.h"\r
-# include "cgrammar_tokens.h"\r
-\r
-# include "fileIdList.h"\r
-# include "portab.h"\r
-\r
-static bool lastWasString = FALSE;\r
-static char savechar = '\0';\r
-\r
-/*@notfunction@*/\r
-# define yyinput() (incColumn (), getc (yyin))\r
-\r
-static /*@owned@*/ cstring lastidprocessed = cstring_undefined;\r
-static int lminput (void);\r
-static int tokLength = 0;\r
-static bool inSpecPart = FALSE;\r
-static bool continueLine = FALSE;\r
-\r
-static int ninput (void);\r
-static char processChar (void);\r
-static double processFloat (void);\r
-static /*@only@*/ exprNode processString (void);\r
-static long processDec (void);\r
-static long processHex (void);\r
-static long processOctal (void);\r
-static int processIdentifier (/*@only@*/ cstring)\r
- /*@globals undef lastidprocessed@*/ ;\r
-static bool processHashIdentifier (/*@only@*/ cstring)\r
- /*@globals undef lastidprocessed@*/ ;\r
-\r
-static int processSpec (int);\r
-static bool handleSpecial (char *);\r
-static int handleLlSpecial (void);\r
-static void handleMacro (void);\r
-static bool processMacro (void);\r
-static /*@only@*/ cstring makeIdentifier (char *);\r
-\r
-/* yes, this is exported! */\r
-bool g_expectingTypeName = TRUE; /* beginning of file can be type name! */\r
-\r
-static bool expectingMetaStateName = FALSE;\r
-\r
-static int returnInt (ctype, long);\r
-static int returnFloat (ctype, double);\r
-static int returnChar (char);\r
-static void setTokLength (int) /*@modifies g_currentloc@*/ ;\r
-static void setTokLengthT (size_t) /*@modifies g_currentloc@*/ ;\r
-\r
-static void advanceLine (void)\r
-{\r
- tokLength = 0;\r
- beginLine ();\r
-}\r
- \r
-/*@-allmacros@*/\r
-# define RETURN_INT(c,i) \\r
- do { lastWasString = FALSE; \\r
- return (returnInt (c, i)); } while (FALSE)\r
-\r
-# define RETURN_FLOAT(c,f) \\r
- do { lastWasString = FALSE; \\r
- return (returnFloat (c, f)); \\r
- } while (FALSE)\r
-\r
-# define RETURN_CHAR(c) \\r
- do { lastWasString = FALSE; \\r
- return (returnChar (c)); \\r
- } while (FALSE)\r
-\r
-# define RETURN_TOK(t) \\r
- do { yylval.tok = lltok_create (t, fileloc_decColumn (g_currentloc, tokLength)); \\r
- tokLength = 0; \\r
- lastWasString = FALSE; \\r
- return (t); } while (FALSE)\r
-\r
-# define RETURN_TYPE(t, ct) \\r
- do { yylval.ctyp = ct; tokLength = 0; return (t); } while (FALSE)\r
-\r
-/* don't fileloc_decColumn (g_currentloc, tokLength)); \r
- the string could have \n's in it!\r
-*/\r
-\r
-# define RETURN_STRING(c) \\r
- do { yylval.expr = exprNode_stringLiteral (c, fileloc_decColumn (g_currentloc, tokLength)); \\r
- tokLength = 0; \\r
- lastWasString = TRUE; \\r
- return (CCONSTANT); } while (FALSE)\r
-\r
-# define RETURN_EXPR(e) \\r
- do { yylval.expr = e; \\r
- tokLength = 0; \\r
- lastWasString = TRUE; \\r
- return (CCONSTANT); } while (FALSE)\r
-\r
-/*@=allmacros@*/\r
-\r
-static void setTokLength (int len) \r
-{\r
- addColumn (len);\r
- tokLength = len;\r
- DPRINTF (("Set tok length: %d", len));\r
-}\r
-\r
-static void setTokLengthT (size_t len)\r
-{\r
- setTokLength (size_toInt (len));\r
-}\r
-\r
-# include "flex.head"\r
-\r
-/*@-unrecog@*/ /*@i5343@*/\r
-\r
-%}\r
-\r
-%%\r
-\r
-"/*" { llfatalbug (cstring_makeLiteral ("Comment in pre-processor output")); }\r
-\r
-"#"{Letter}({Letter}|{Digit})* { \r
- context_saveLocation (); \r
- setTokLength (longUnsigned_toInt (mstring_length (yytext))); \r
-\r
- if (processHashIdentifier (makeIdentifier (yytext + 1)))\r
- {\r
- if (lastWasString)\r
- {\r
- /* was nothing! */ /*@i32@*/\r
- RETURN_STRING (cstring_makeLiteral ("\"\""));\r
- }\r
- else\r
- {\r
- RETURN_STRING (cstring_makeLiteral ("\"\""));\r
- }\r
- }\r
- else\r
- { \r
- if (handleSpecial (yytext)) \r
- { \r
- setTokLength (1); \r
- RETURN_TOK (0); \r
- }\r
- }\r
- } \r
-"#" { if (handleSpecial (yytext)) \r
- { \r
- setTokLength (1); RETURN_TOK (0); \r
- }\r
- }\r
-"..." { setTokLength (3); RETURN_TOK (CTOK_ELIPSIS); }\r
-"break" { setTokLength (5); RETURN_TOK (BREAK); }\r
-"case" { setTokLength (4); RETURN_TOK (CASE); }\r
-"continue" { setTokLength (8); RETURN_TOK (CONTINUE); }\r
-"default" { setTokLength (7); RETURN_TOK (DEFAULT); }\r
-"do" { setTokLength (2); RETURN_TOK (DO); }\r
-"else" { setTokLength (4); RETURN_TOK (CELSE); }\r
-"for" { setTokLength (3); RETURN_TOK (CFOR); }\r
-"goto" { setTokLength (4); RETURN_TOK (GOTO); }\r
-"if" { setTokLength (2); RETURN_TOK (CIF); }\r
-"return" { setTokLength (6); RETURN_TOK (RETURN); }\r
-"sizeof" { setTokLength (6); RETURN_TOK (CSIZEOF); }\r
-"offsetof" { setTokLength (8); RETURN_TOK (COFFSETOF); }\r
-"switch" { setTokLength (6); RETURN_TOK (SWITCH); }\r
-"while" { setTokLength (5); RETURN_TOK (WHILE); }\r
-"va_arg" { setTokLength (6); RETURN_TOK (VA_ARG); } \r
-"va_dcl" { setTokLength (6); RETURN_TOK (VA_DCL); } \r
-"inline" { \r
- /* gcc extension...this might not be appropriate */\r
- setTokLength (6); RETURN_TOK (QINLINE); }\r
-\r
-"struct" { setTokLength (6); RETURN_TOK (CSTRUCT); } \r
-"typedef" { setTokLength (7); RETURN_TOK (CTYPEDEF); }\r
-\r
-"union" { setTokLength (5); RETURN_TOK (CUNION); }\r
-"enum" { setTokLength (4); RETURN_TOK (CENUM); }\r
-\r
-"void" { setTokLength (4); RETURN_TYPE (CVOID, ctype_void); }\r
-"int" { setTokLength (3); RETURN_TYPE (CINT, ctype_int); }\r
-"double" { setTokLength (6); RETURN_TYPE (CDOUBLE, ctype_double); }\r
-"char" { setTokLength (4); RETURN_TYPE (CGCHAR, ctype_char); }\r
-"float" { setTokLength (5); RETURN_TYPE (CGFLOAT, ctype_float); }\r
-\r
-"long" { setTokLength (4); RETURN_TOK (QLONG); }\r
-"short" { setTokLength (5); RETURN_TOK (QSHORT); }\r
-"unsigned" { setTokLength (8); RETURN_TOK (QUNSIGNED); }\r
-"signed" { setTokLength (6); RETURN_TOK (QSIGNED); }\r
-\r
-"volatile" { setTokLength (8); RETURN_TOK (QVOLATILE); }\r
-"const" { setTokLength (5); RETURN_TOK (QCONST); }\r
-\r
- /* some systems expect this! [gack!] */ \r
-"__const" { setTokLength (7); RETURN_TOK (QCONST); }\r
-\r
-"extern" { setTokLength (6); RETURN_TOK (QEXTERN); }\r
-"auto" { setTokLength (4); RETURN_TOK (QAUTO); }\r
-"register" { setTokLength (8); RETURN_TOK (QREGISTER); }\r
-"static" { setTokLength (6); RETURN_TOK (QSTATIC); }\r
-\r
-\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { RETURN_EXPR (processString ()); }\r
-L\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { RETURN_EXPR (processString ()); }\r
-"out" { return (processSpec (QOUT)); }\r
-"in" { return (processSpec (QIN)); }\r
-"partial" { return (processSpec (QPARTIAL)); }\r
-"special" { return (processSpec (QSPECIAL)); }\r
-"anytype" { return (processSpec (QANYTYPE)); }\r
-"integraltype" { return (processSpec (QINTEGRALTYPE)); }\r
-"unsignedintegraltype" { return (processSpec (QUNSIGNEDINTEGRALTYPE)); }\r
-"signedintegraltype" { return (processSpec (QSIGNEDINTEGRALTYPE)); }\r
-"keep" { return (processSpec (QKEEP)); }\r
-"null" { return (processSpec (QNULL)); } \r
-"notnull" { return (processSpec (QNOTNULL)); } \r
-"isnull" { return (processSpec (QISNULL)); } \r
-"truenull" { return (processSpec (QTRUENULL)); } \r
-"falsenull" { return (processSpec (QFALSENULL)); } \r
-"relnull" { return (processSpec (QRELNULL)); }\r
-"reldef" { return (processSpec (QRELDEF)); }\r
-"exposed" { return (processSpec (QEXPOSED)); }\r
-"newref" { return (processSpec (QNEWREF)); }\r
-"tempref" { return (processSpec (QTEMPREF)); }\r
-"killref" { return (processSpec (QKILLREF)); }\r
-"refcounted" { return (processSpec (QREFCOUNTED)); }\r
-"checked" { return (processSpec (QCHECKED)); }\r
-"checkmod" { return (processSpec (QCHECKMOD)); }\r
-"checkedstrict" { return (processSpec (QCHECKEDSTRICT)); }\r
-"unchecked" { return (processSpec (QUNCHECKED)); }\r
-"only" { return (processSpec (QONLY)); }\r
-"owned" { return (processSpec (QOWNED)); }\r
-"observer" { return (processSpec (QOBSERVER)); }\r
-"dependent" { return (processSpec (QDEPENDENT)); }\r
-"unused" { return (processSpec (QUNUSED)); }\r
-"external" { return (processSpec (QEXTERNAL)); }\r
-"sef" { return (processSpec (QSEF)); }\r
-"shared" { return (processSpec (QSHARED)); }\r
-"yield" { return (processSpec (QYIELD)); }\r
-"undef" { return (processSpec (QUNDEF)); }\r
-"killed" { return (processSpec (QKILLED)); }\r
-"nullterminated" { return (processSpec (QNULLTERMINATED));}\r
-"MaxSet" { return (processSpec (QMAXSET));}\r
-"MaxRead" { return (processSpec (QMAXREAD));}\r
-"maxSet" { return (processSpec (QMAXSET));}\r
-"maxRead" { return (processSpec (QMAXREAD));}\r
-\r
-{Letter}({Letter}|{Digit})* { int tok; \r
- context_saveLocation (); \r
- setTokLength (longUnsigned_toInt (mstring_length (yytext))); \r
- tok = processIdentifier (makeIdentifier (yytext)); \r
- if (tok != BADTOK)\r
- {\r
- return (tok);\r
- }\r
- }\r
-0[xX]{H}+ { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_int, processHex ()); /* evs 2000-05-17 was ctype_uint */\r
- }\r
-0[xX]{H}+{L} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_lint, processHex ()); }\r
-0[xX]{H}+{L}{L} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_llint, processHex ()); }\r
-0[xX]{H}+{U} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_uint, processHex ()); }\r
-0[xX]{H}+{ULSuffix} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_ulint, processHex ()); }\r
-0[xX]{H}+{U}{L}{L} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_ullint, processHex ()); }\r
-0[xX]{H}+{L}{L}{U} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_ullint, processHex ()); }\r
-0{Digit}+ { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_int, processOctal ()); } \r
-0{Digit}+{U} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_uint, processOctal ()); } \r
-0{Digit}+{L} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_lint, processOctal ()); } \r
-0{Digit}+{L}{L} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_llint, processOctal ()); } \r
-0{Digit}+{ULSuffix} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_ulint, processOctal ()); } \r
-0{Digit}+{U}{L}{L} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_ullint, processOctal ()); } \r
-0{Digit}+{L}{L}{U} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_ullint, processOctal ()); } \r
-{Digit}+ { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_int, processDec ()); } \r
-{Digit}+{U} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_uint, processDec ()); } \r
-{Digit}+{L} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_lint, processDec ()); } \r
-{Digit}+{L}{L} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_llint, processDec ()); } \r
-{Digit}+{ULSuffix} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_ulint, processDec ()); } \r
-{Digit}+{U}{L}{L} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_ullint, processDec ()); } \r
-{Digit}+{L}{L}{U} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_INT (ctype_ullint, processDec ()); } \r
-'(\\.|[^\\'])+' { setTokLengthT (mstring_length (yytext)); \r
- RETURN_CHAR (processChar ()); }\r
-L'(\\.|[^\\'])+' { setTokLengthT (mstring_length (yytext)); \r
- RETURN_CHAR (processChar ()); }\r
-{Digit}+{E}[fF] { setTokLengthT (mstring_length (yytext)); \r
- RETURN_FLOAT (ctype_float, processFloat ()); }\r
-{Digit}+{E}[lL] { setTokLengthT (mstring_length (yytext)); \r
- RETURN_FLOAT (ctype_ldouble, processFloat ()); }\r
-{Digit}+{E} { setTokLengthT (mstring_length (yytext)); \r
- RETURN_FLOAT (ctype_double, processFloat ()); }\r
-\r
-{Digit}*"."{Digit}+({E})?[fF] { setTokLengthT (mstring_length (yytext)); \r
- RETURN_FLOAT (ctype_float, processFloat ()); }\r
-{Digit}*"."{Digit}+({E})?[lL] { setTokLengthT (mstring_length (yytext)); \r
- RETURN_FLOAT (ctype_ldouble, processFloat ()); }\r
-{Digit}*"."{Digit}+({E})? { setTokLengthT (mstring_length (yytext)); \r
- RETURN_FLOAT (ctype_double, processFloat ()); }\r
-\r
-{Digit}+"."{Digit}*({E})?[fF] { setTokLengthT (mstring_length (yytext)); \r
- RETURN_FLOAT (ctype_float, processFloat ()); }\r
-{Digit}+"."{Digit}*({E})?[lL] { setTokLengthT (mstring_length (yytext)); \r
- RETURN_FLOAT (ctype_ldouble, processFloat ()); }\r
-{Digit}+"."{Digit}*({E})? { setTokLengthT (mstring_length (yytext)); \r
- RETURN_FLOAT (ctype_double, processFloat ()); }\r
-\r
-">>=" { setTokLength (3); RETURN_TOK (RIGHT_ASSIGN); }\r
-"<<=" { setTokLength (3); RETURN_TOK (LEFT_ASSIGN); }\r
-"+=" { setTokLength (2); RETURN_TOK (ADD_ASSIGN); }\r
-"-=" { setTokLength (2); RETURN_TOK (SUB_ASSIGN); }\r
-"*=" { setTokLength (2); RETURN_TOK (MUL_ASSIGN); }\r
-"/=" { setTokLength (2); RETURN_TOK (DIV_ASSIGN); }\r
-"%=" { setTokLength (2); RETURN_TOK (MOD_ASSIGN); }\r
-"&=" { setTokLength (2); RETURN_TOK (AND_ASSIGN); }\r
-"^=" { setTokLength (2); RETURN_TOK (XOR_ASSIGN); }\r
-"|=" { setTokLength (2); RETURN_TOK (OR_ASSIGN); }\r
-">>" { setTokLength (2); RETURN_TOK (RIGHT_OP); }\r
-"<<" { setTokLength (2); RETURN_TOK (LEFT_OP); }\r
-"++" { setTokLength (2); RETURN_TOK (INC_OP); }\r
-"--" { setTokLength (2); RETURN_TOK (DEC_OP); }\r
-"->" { setTokLength (2); RETURN_TOK (ARROW_OP); }\r
-"&&" { setTokLength (2); RETURN_TOK (AND_OP); }\r
-"||" { setTokLength (2); RETURN_TOK (OR_OP); }\r
-"<=" { setTokLength (2); RETURN_TOK (LE_OP); }\r
-">=" { setTokLength (2); RETURN_TOK (GE_OP); }\r
-"==" { setTokLength (2); RETURN_TOK (EQ_OP); }\r
-"!=" { setTokLength (2); RETURN_TOK (NE_OP); }\r
-";" { setTokLength (1); RETURN_TOK (TSEMI); }\r
-"{" { setTokLength (1); RETURN_TOK (TLBRACE); }\r
-"}" { setTokLength (1); RETURN_TOK (TRBRACE); }\r
-"," { setTokLength (1); RETURN_TOK (TCOMMA); }\r
-":" { setTokLength (1); RETURN_TOK (TCOLON); }\r
-"=" { setTokLength (1); RETURN_TOK (TASSIGN); }\r
-"(" { setTokLength (1); RETURN_TOK (TLPAREN); }\r
-")" { setTokLength (1); RETURN_TOK (TRPAREN); }\r
-"[" { setTokLength (1); RETURN_TOK (TLSQBR); }\r
-"]" { setTokLength (1); RETURN_TOK (TRSQBR); }\r
-"." { setTokLength (1); RETURN_TOK (TDOT); }\r
-"&" { setTokLength (1); RETURN_TOK (TAMPERSAND); }\r
-"!" { setTokLength (1); RETURN_TOK (TEXCL); }\r
-\r
-\r
-"~" { setTokLength (1); RETURN_TOK (TTILDE); }\r
-"-" { setTokLength (1); RETURN_TOK (TMINUS); }\r
-"+" { setTokLength (1); RETURN_TOK (TPLUS); }\r
-"*" { setTokLength (1); RETURN_TOK (TMULT); }\r
-"/" { setTokLength (1); RETURN_TOK (TDIV); }\r
-"%" { setTokLength (1); RETURN_TOK (TPERCENT); }\r
-"<" { setTokLength (1); RETURN_TOK (TLT); }\r
-">" { setTokLength (1); RETURN_TOK (TGT); }\r
-"^" { setTokLength (1); RETURN_TOK (TCIRC); }\r
-"|" { setTokLength (1); RETURN_TOK (TBAR); }\r
-"?" { setTokLength (1); RETURN_TOK (TQUEST); }\r
-\r
-\r
-"/\\" { setTokLength (1); RETURN_TOK (TCAND); }\r
-\r
-\r
-[ \t\v\f] { incColumn (); }\r
-\n { context_incLineno ();\r
- if (tokLength != 0) { \r
- tokLength = 0; \r
- /* No error to report \r
- voptgenerror\r
- (FLG_SYNTAX, \r
- message ("Likely parse error: token spans multiple lines."),\r
- g_currentloc);\r
- */\r
- }\r
- \r
- if (continueLine)\r
- {\r
- continueLine = FALSE;\r
- }\r
- else \r
- {\r
- if (context_inMacro ())\r
- {\r
- /* Don't use RETURN_TOK */\r
- yylval.tok = lltok_create (TENDMACRO, g_currentloc);\r
- lastWasString = FALSE;\r
- return (TENDMACRO);\r
- } \r
- }\r
- }\r
-"@@MR@@" { setTokLength (6); \r
- \r
- if (processMacro ()) {\r
- if (context_inIterDef ()) \r
- { \r
- RETURN_TOK (LLMACROITER); \r
- }\r
- if (context_inIterEnd ())\r
- {\r
- RETURN_TOK (LLMACROEND); \r
- }\r
- if (context_inMacro ())\r
- {\r
- RETURN_TOK (LLMACRO); \r
- }\r
- }\r
- }\r
-"@QLMR" { if (context_inHeader () || context_inFunction ())\r
- { \r
- handleMacro ();\r
- }\r
- else\r
- {\r
- int nspchar = ninput ();\r
- int nspaces;\r
-\r
- /* \r
- ** This is a hack to get the column number correct.\r
- */\r
-\r
- llassert (nspchar >= '0' && nspchar <= '9');\r
- \r
- nspaces = nspchar - '0';\r
-\r
- setTokLength (5 + nspaces); \r
- \r
- if (processMacro ()) \r
- {\r
- if (context_inIterDef ()) \r
- {\r
- RETURN_TOK (LLMACROITER); \r
- }\r
- if (context_inIterEnd ())\r
- {\r
- RETURN_TOK (LLMACROEND); \r
- }\r
- if (context_inMacro ())\r
- { \r
- RETURN_TOK (LLMACRO); \r
- }\r
- }\r
- }\r
- }\r
-"@.CT" { setTokLength (4); lldiagmsg (ctype_unparseTable ()); }\r
-"@.FA" { setTokLength (4); lldiagmsg (message ("Access types: %q", typeIdSet_unparse (context_fileAccessTypes ()))); }\r
-"@.F" { setTokLength (3); \r
- lldiagmsg (message ("%q: *** marker ***", fileloc_unparse (g_currentloc)));\r
- }\r
-"@.L" { setTokLength (3); usymtab_printLocal (); }\r
-"@.A" { setTokLength (3); lldiagmsg (usymtab_unparseAliases ()); }\r
-"@.C" { setTokLength (3); lldiagmsg (context_unparse ()); }\r
-"@.W" { setTokLength (3); lldiagmsg (context_unparseClauses ()); }\r
-"@.G" { setTokLength (3); usymtab_printGuards (); }\r
-"@.S" { setTokLength (3); usymtab_printOut (); }\r
-"@.X" { setTokLength (3); usymtab_printAll (); }\r
-"@.Z" { setTokLength (3); usymtab_printComplete (); }\r
-"@.T" { setTokLength (3); usymtab_printTypes (); }\r
-"@.K" { setTokLength (3); lldiagmsg (usymtab_unparseStack ()); }\r
-"@.M" { setTokLength (3); \r
- lldiagmsg (message ("Can modify: %q", \r
- sRefSet_unparse (context_modList ()))); \r
- }\r
-"%{" { /* BEFORE_COMMENT_MARKER */\r
- int tok; \r
- incColumn (); incColumn ();\r
- tok = handleLlSpecial (); \r
-\r
- if (tok != BADTOK)\r
- {\r
- if (tok == CANNOTATION) {\r
- return (tok);\r
- } else {\r
- /* Beware - this bashes yylval! */\r
- RETURN_TOK (tok); \r
- }\r
- }\r
- }\r
-"%}" { /* AFTER_COMMENT_MARKER */ \r
- setTokLength (2);\r
- inSpecPart = FALSE;\r
- RETURN_TOK (QENDMACRO); }\r
-"\\" { incColumn (); continueLine = TRUE; }\r
-. { incColumn (); \r
- if ((int) *yytext == 13 ) {\r
- ;\r
- } else {\r
- voptgenerror\r
- (FLG_SYNTAX, \r
- message ("Invalid character (ascii: %d), skipping character",\r
- (int)(*yytext)),\r
- g_currentloc);\r
- }\r
- }\r
-%%\r
-\r
-struct skeyword\r
-{\r
- /*@null@*/ /*@observer@*/ char *name;\r
- int token;\r
-} ;\r
-\r
-/*\r
-** These tokens are followed by syntax that is parsed by the \r
-** grammar proper.\r
-*/\r
-\r
-struct skeyword s_parsetable[] = {\r
- { "modifies", QMODIFIES } ,\r
- { "globals", QGLOBALS } ,\r
- { "alt", QALT } ,\r
- { "warn", QWARN } ,\r
- { "constant", QCONSTANT } ,\r
- { "function", QFUNCTION } ,\r
- { "iter", QITER } ,\r
- { "defines", QDEFINES } ,\r
- { "uses", QUSES } ,\r
- { "allocates", QALLOCATES } ,\r
- { "sets", QSETS } ,\r
- { "releases", QRELEASES } ,\r
- { "pre", QPRECLAUSE } ,\r
- { "post", QPOSTCLAUSE } ,\r
- { "setBufferSize", QSETBUFFERSIZE},\r
- { "setStringLength", QSETSTRINGLENGTH},\r
- { "testinRange", QTESTINRANGE},\r
- { "requires", QPRECLAUSE } ,\r
- { "ensures", QPOSTCLAUSE } ,\r
- { NULL, BADTOK } \r
-} ;\r
-\r
-/*\r
-** These tokens are either stand-alone tokens, or followed by \r
-** token-specific text.\r
-*/\r
-\r
-struct skeyword s_keytable[] = {\r
- { "anytype", QANYTYPE } ,\r
- { "integraltype", QINTEGRALTYPE } ,\r
- { "unsignedintegraltype", QUNSIGNEDINTEGRALTYPE } ,\r
- { "signedintegraltype", QSIGNEDINTEGRALTYPE } ,\r
- { "out", QOUT } ,\r
- { "in", QIN } ,\r
- { "only", QONLY } , \r
- { "owned", QOWNED } ,\r
- { "dependent", QDEPENDENT } ,\r
- { "partial", QPARTIAL } ,\r
- { "special", QSPECIAL } ,\r
- { "truenull", QTRUENULL } ,\r
- { "falsenull", QFALSENULL } ,\r
- { "keep", QKEEP } ,\r
- { "kept", QKEPT } ,\r
- { "notnull", QNOTNULL } ,\r
- { "abstract", QABSTRACT } ,\r
- { "concrete", QCONCRETE } ,\r
- { "mutable", QMUTABLE } ,\r
- { "immutable", QIMMUTABLE } ,\r
- { "unused", QUNUSED } ,\r
- { "external", QEXTERNAL } ,\r
- { "sef", QSEF } ,\r
- { "unique", QUNIQUE } ,\r
- { "returned", QRETURNED } ,\r
- { "exposed", QEXPOSED } ,\r
- { "refcounted", QREFCOUNTED } ,\r
- { "refs", QREFS } ,\r
- { "newref", QNEWREF } ,\r
- { "tempref", QTEMPREF } ,\r
- { "killref", QKILLREF } ,\r
- { "null", QNULL } ,\r
- { "relnull", QRELNULL } ,\r
- { "nullterminated", QNULLTERMINATED }, \r
- { "setBufferSize", QSETBUFFERSIZE },\r
- { "testInRange", QTESTINRANGE},\r
- { "MaxSet", QMAXSET},\r
- { "MaxRead", QMAXREAD},\r
- { "reldef", QRELDEF } ,\r
- { "observer", QOBSERVER } ,\r
- { "exits", QEXITS } ,\r
- { "mayexit", QMAYEXIT } ,\r
- { "trueexit", QTRUEEXIT } ,\r
- { "falseexit", QFALSEEXIT } ,\r
- { "neverexit", QNEVEREXIT } ,\r
- { "temp", QTEMP } ,\r
- { "shared", QSHARED } ,\r
- { "ref", QREF } ,\r
- { "unchecked", QUNCHECKED } ,\r
- { "checked", QCHECKED } ,\r
- { "checkmod", QCHECKMOD } ,\r
- { "checkedstrict", QCHECKEDSTRICT } ,\r
- { "innercontinue", QINNERCONTINUE } ,\r
- { "innerbreak", QINNERBREAK } ,\r
- { "loopbreak", QLOOPBREAK } ,\r
- { "switchbreak", QSWITCHBREAK } ,\r
- { "safebreak", QSAFEBREAK } , \r
- { "fallthrough", QFALLTHROUGH } ,\r
- { "l_fallthrou", QLINTFALLTHROUGH } , \r
- { "l_fallth", QLINTFALLTHRU } ,\r
- { "notreached", QNOTREACHED } ,\r
- { "l_notreach", QLINTNOTREACHED } ,\r
- { "printflike", QPRINTFLIKE } ,\r
- { "l_printfli", QLINTPRINTFLIKE } ,\r
- { "scanflike", QSCANFLIKE } ,\r
- { "messagelike", QMESSAGELIKE } ,\r
- { "l_argsus", QARGSUSED } ,\r
- { NULL, BADTOK } \r
-} ;\r
-\r
-/*\r
-** would be better if these weren't hard coded...\r
-*/\r
-\r
-static bool isArtificial (cstring s)\r
-{\r
- return (cstring_equalLit (s, "modifies") \r
- || cstring_equalLit (s, "globals") \r
- || cstring_equalLit (s, "warn")\r
- || cstring_equalLit (s, "alt"));\r
-}\r
-\r
-void swallowMacro (void)\r
-{\r
- int i;\r
- bool skipnext = FALSE;\r
-\r
- while ((i = lminput ()) != EOF)\r
- {\r
- char c = (char) i;\r
- \r
- \r
- if (c == '\\')\r
- {\r
- skipnext = TRUE;\r
- }\r
- else if (c == '\n')\r
- {\r
- if (skipnext)\r
- {\r
- skipnext = FALSE;\r
- }\r
- else\r
- {\r
- reader_checkUngetc (i, yyin);\r
- return;\r
- }\r
- }\r
- }\r
-\r
- if (i != EOF)\r
- {\r
- reader_checkUngetc (i, yyin);\r
- }\r
-}\r
-\r
-static int commentMarkerToken (cstring s)\r
-{\r
- int i = 0;\r
- \r
- while (s_parsetable[i].name != NULL) \r
- {\r
- DPRINTF (("Try :%s:%s:", s, s_parsetable[i].name));\r
-\r
- if (cstring_equalLit (s, s_parsetable[i].name))\r
- {\r
- return s_parsetable[i].token;\r
- }\r
-\r
- i++;\r
- }\r
-\r
- return BADTOK;\r
-}\r
-\r
-static int tokenMacroCode (cstring s)\r
-{\r
- int i = 0;\r
- \r
- while (s_keytable[i].name != NULL) \r
- {\r
- if (cstring_equalLit (s, s_keytable[i].name)) \r
- {\r
- if (s_keytable[i].token == QLINTFALLTHROUGH) \r
- {\r
- voptgenerror\r
- (FLG_WARNLINTCOMMENTS,\r
- cstring_makeLiteral\r
- ("Traditional lint comment /*FALLTHROUGH*/ used. "\r
- "This is interpreted by "\r
- "LCLint in the same way as most Unix lints, but it is "\r
- "preferable to replace it with the /*@fallthrough@*/ "\r
- "semantic comment"),\r
- g_currentloc);\r
- return QFALLTHROUGH; \r
- }\r
- else if (s_keytable[i].token == QLINTFALLTHRU)\r
- {\r
- voptgenerror \r
- (FLG_WARNLINTCOMMENTS,\r
- cstring_makeLiteral\r
- ("Traditional lint comment /*FALLTHRU*/ used. "\r
- "This is interpreted by "\r
- "LCLint in the same way as most Unix lints, but it is "\r
- "preferable to replace it with the /*@fallthrough@*/ "\r
- "semantic comment"),\r
- g_currentloc);\r
- return QFALLTHROUGH;\r
- }\r
- else if (s_keytable[i].token == QLINTNOTREACHED)\r
- {\r
- voptgenerror \r
- (FLG_WARNLINTCOMMENTS,\r
- cstring_makeLiteral\r
- ("Traditional lint comment /*NOTREACHED*/ used. "\r
- "This is interpreted by "\r
- "LCLint in the same way as most Unix lints, but it is "\r
- "preferable to replace it with the /*@notreached@*/ "\r
- "semantic comment."),\r
- g_currentloc);\r
- \r
- return QNOTREACHED;\r
- }\r
- else if (s_keytable[i].token == QPRINTFLIKE)\r
- {\r
- setSpecialFunction (qual_createPrintfLike ());\r
- return SKIPTOK;\r
- }\r
- else if (s_keytable[i].token == QLINTPRINTFLIKE)\r
- { \r
- voptgenerror \r
- (FLG_WARNLINTCOMMENTS,\r
- cstring_makeLiteral\r
- ("Traditional lint comment /*PRINTFLIKE*/ used. "\r
- "This is interpreted by "\r
- "LCLint in the same way as most Unix lints, but it is "\r
- "preferable to replace it with either /*@printflike@*/, "\r
- "/*@scanflike@*/ or /*@messagelike@*/."),\r
- g_currentloc);\r
- \r
- setSpecialFunction (qual_createPrintfLike ());\r
- return SKIPTOK;\r
- }\r
- else if (s_keytable[i].token == QSCANFLIKE)\r
- {\r
- setSpecialFunction (qual_createScanfLike ());\r
- return SKIPTOK;\r
- }\r
- else if (s_keytable[i].token == QMESSAGELIKE)\r
- {\r
- setSpecialFunction (qual_createMessageLike ());\r
- return SKIPTOK;\r
- }\r
- else if (s_keytable[i].token == QARGSUSED)\r
- {\r
- voptgenerror\r
- (FLG_WARNLINTCOMMENTS,\r
- cstring_makeLiteral\r
- ("Traditional lint comment /*ARGSUSED*/ used. "\r
- "This is interpreted by "\r
- "LCLint in the same way as most Unix lints, but it is "\r
- "preferable to use /*@unused@*/ annotations on "\r
- "the unused parameters."),\r
- g_currentloc);\r
- \r
- setArgsUsed ();\r
- return SKIPTOK;\r
- }\r
- \r
- return s_keytable[i].token;\r
- }\r
- \r
- i++;\r
- }\r
- \r
- return BADTOK;\r
-}\r
-\r
-static int lminput ()\r
-{\r
- if (savechar == '\0')\r
- {\r
- incColumn ();\r
- return (input ());\r
- }\r
- else\r
- {\r
- int save = (int) savechar;\r
- savechar = '\0';\r
- return save;\r
- }\r
-}\r
-\r
-static void lmsavechar (char c)\r
-{\r
- if (savechar == '\0') savechar = c;\r
- else\r
- {\r
- llbuglit ("lmsavechar: override");\r
- }\r
-}\r
-\r
-static int returnFloat (ctype ct, double f)\r
-{\r
- yylval.expr = exprNode_floatLiteral (f, ct, cstring_fromChars (yytext), \r
- fileloc_decColumn (g_currentloc, tokLength));\r
- tokLength = 0; \r
- return (CCONSTANT);\r
-}\r
-\r
-static int returnInt (ctype ct, long i)\r
-{\r
- ctype c = ct;\r
-\r
- if (ctype_equal (ct, ctype_int))\r
- {\r
- if (i == 0)\r
- {\r
- c = context_typeofZero ();\r
- }\r
- else if (i == 1)\r
- {\r
- c = context_typeofOne ();\r
- }\r
- }\r
- \r
- yylval.expr = exprNode_numLiteral (c, cstring_fromChars (yytext), \r
- fileloc_decColumn (g_currentloc, tokLength), i); \r
- tokLength = 0; \r
- return (CCONSTANT);\r
-}\r
-\r
-static int returnChar (char c)\r
-{\r
- yylval.expr = exprNode_charLiteral (c, cstring_fromChars (yytext), \r
- fileloc_decColumn (g_currentloc, tokLength));\r
- tokLength = 0; \r
- return (CCONSTANT);\r
-}\r
-\r
-static int ninput () \r
-{\r
- int c = lminput ();\r
-\r
- if (c != EOF && ((char)c == '\n'))\r
- {\r
- context_incLineno ();\r
- }\r
-\r
- return c;\r
-}\r
-\r
-static char macro_nextChar ()\r
-{\r
- static bool in_quote = FALSE, in_escape = FALSE, in_char = FALSE;\r
- int ic;\r
- char c;\r
-\r
- ic = lminput ();\r
- c = char_fromInt (ic);\r
- \r
- if (!in_quote && !in_char && (c == '\\' || c == BEFORE_COMMENT_MARKER[0]))\r
- {\r
- if (c == '\\')\r
- {\r
- while ((c = char_fromInt (lminput ())) != '\0' && c != '\n')\r
- {\r
- ; /* skip to newline */\r
- }\r
- \r
- context_incLineno ();\r
- \r
- if (c != '\0')\r
- {\r
- return macro_nextChar ();\r
- }\r
- else \r
- {\r
- return c;\r
- }\r
- }\r
- else /* if (c == '@') */\r
- {\r
- llassert (FALSE); /*@i23@*/\r
- if (handleLlSpecial () != BADTOK)\r
- {\r
- llerrorlit (FLG_SYNTAX, "Macro cannot use special syntax");\r
- }\r
-\r
- return macro_nextChar ();\r
- }\r
- }\r
- else if (!in_escape && c == '\"')\r
- {\r
- in_quote = !in_quote;\r
- }\r
- else if (!in_escape && c == '\'')\r
- {\r
- in_char = !in_char;\r
- }\r
- else if ((in_quote || in_char) && c == '\\')\r
- {\r
- in_escape = !in_escape;\r
- }\r
- else if ((in_quote || in_char) && in_escape)\r
- {\r
- in_escape = FALSE;\r
- }\r
- else if (!in_quote && c == '/')\r
- {\r
- char c2;\r
- \r
- if ((c2 = char_fromInt (lminput ())) == '*')\r
- {\r
- while (c2 != '\0')\r
- {\r
- while ((c2 = char_fromInt (lminput ())) != '\0'\r
- && c2 != '\n' && c2 != '*')\r
- {\r
- ;\r
- }\r
- \r
- if (c2 == '*')\r
- {\r
- while ((c2 = char_fromInt (lminput ())) != '\0' \r
- && c2 == '*')\r
- {\r
- ;\r
- }\r
-\r
- if (c2 == '/')\r
- {\r
- goto outofcomment;\r
- }\r
- }\r
- else \r
- {\r
- llfatalerror (cstring_makeLiteral ("Macro: bad comment!"));\r
- }\r
- }\r
- outofcomment:\r
- return macro_nextChar ();\r
- }\r
- else\r
- {\r
- /*** putchar does not work! why? puts to stdio...??! ***/\r
- lmsavechar (c2);\r
- }\r
- }\r
- return c;\r
-}\r
-\r
-/*\r
-** keeps semantic comments\r
-*/\r
-\r
-static char macro_nextCharC ()\r
-{\r
- static bool in_quote = FALSE, in_escape = FALSE, in_char = FALSE;\r
- char c;\r
-\r
- c = char_fromInt (lminput ());\r
-\r
- if (!in_quote && !in_char && c == '\\')\r
- {\r
- while ((c = char_fromInt (lminput ())) != '\0' && c != '\n')\r
- {\r
- ; /* skip to newline */\r
- }\r
- \r
- context_incLineno ();\r
- \r
- if (c != '\0')\r
- {\r
- return macro_nextCharC ();\r
- }\r
- else\r
- {\r
- return c;\r
- }\r
- }\r
- else if (!in_escape && c == '\"')\r
- {\r
- in_quote = !in_quote;\r
- }\r
- else if (!in_escape && c == '\'')\r
- {\r
- in_char = !in_char;\r
- }\r
- else if ((in_quote || in_char) && c == '\\')\r
- {\r
- in_escape = !in_escape;\r
- }\r
- else if ((in_quote || in_char) && in_escape)\r
- {\r
- in_escape = FALSE;\r
- }\r
- else if (!in_quote && c == '/')\r
- {\r
- char c2;\r
- \r
- if ((c2 = char_fromInt (lminput ())) == '*')\r
- {\r
- while (c2 != '\0')\r
- {\r
- while ((c2 = char_fromInt (lminput ())) != '\0' \r
- && c2 != '\n' && c2 != '*')\r
- {\r
- ;\r
- }\r
- \r
- if (c2 == '*')\r
- {\r
- while ((c2 = char_fromInt (lminput ())) != '\0'\r
- && c2 == '*')\r
- {\r
- ;\r
- }\r
-\r
- if (c2 == '/') \r
- {\r
- goto outofcomment;\r
- }\r
- }\r
- else \r
- {\r
- llfatalerror (cstring_makeLiteral ("Macro: bad comment!"));\r
- }\r
- }\r
- outofcomment:\r
- return macro_nextCharC ();\r
- }\r
- else\r
- {\r
- lmsavechar (c2);\r
- }\r
- }\r
- return c;\r
-}\r
-\r
-/*\r
-** skips whitespace (handles line continuations)\r
-** returns first non-whitespace character\r
-*/\r
-\r
-static char skip_whitespace ()\r
-{\r
- char c;\r
-\r
- while ((c = macro_nextChar ()) == ' ' || c == '\t')\r
- {\r
- ;\r
- }\r
-\r
- return c;\r
-}\r
-\r
-static void handleMacro ()\r
-{\r
- cstring mac = cstring_undefined;\r
- int macrocode;\r
- char c;\r
-\r
- while (currentColumn () > 2)\r
- {\r
- mac = cstring_appendChar (mac, ' ');\r
- setTokLength (-1);\r
- }\r
-\r
- c = macro_nextCharC ();\r
-\r
- if (c >= '0' && c <= '9')\r
- {\r
- int i;\r
-\r
- for (i = 0; i < ((c - '0') + 1); i++)\r
- {\r
- mac = cstring_appendChar (mac, ' ');\r
- }\r
- }\r
- else\r
- {\r
- BADBRANCH;\r
- }\r
-\r
- while (((c = macro_nextCharC ()) != '\0') && (c != '\n'))\r
- {\r
- mac = cstring_appendChar (mac, c);\r
- }\r
-\r
- \r
- macrocode = tokenMacroCode (mac);\r
-\r
- if (macrocode == BADTOK && !isArtificial (mac))\r
- {\r
- context_addMacroCache (mac);\r
- }\r
- else\r
- {\r
- cstring_free (mac);\r
- }\r
-\r
- if (c == '\n')\r
- {\r
- context_incLineno ();\r
- }\r
-}\r
-\r
-static bool processMacro (void)\r
-{\r
- uentry e2;\r
- ctype ct;\r
- int noparams = 0;\r
- cstring fname = cstring_undefined;\r
- bool res = TRUE;\r
- bool isspecfcn = FALSE;\r
- bool isiter = FALSE;\r
- bool skipparam = FALSE;\r
- bool isenditer = FALSE;\r
- bool unknownm = FALSE;\r
- bool hasParams = FALSE;\r
- bool emptyMacro = FALSE;\r
- char c = skip_whitespace ();\r
- fileloc loc = fileloc_noColumn (g_currentloc);\r
-\r
- /* are both of these necessary? what do they mean? */\r
- uentryList specparams = uentryList_undefined;\r
- uentryList pn = uentryList_undefined;\r
-\r
- context_resetMacroMissingParams ();\r
-\r
- if (c == '\0' || c == '\n')\r
- {\r
- llcontbug (cstring_makeLiteral ("Bad macro"));\r
- fileloc_free (loc);\r
- return FALSE;\r
- }\r
- \r
- fname = cstring_appendChar (fname, c); \r
-\r
- while ((c = macro_nextChar ()) != '(' && c != '\0'\r
- && c != ' ' && c != '\t' && c != '\n')\r
- {\r
- fname = cstring_appendChar (fname, c);\r
- }\r
-\r
- if (c == ' ' || c == '\t' || c == '\n')\r
- {\r
- char oldc = c;\r
-\r
- if (c != '\n')\r
- {\r
- while (c == ' ' || c == '\t')\r
- {\r
- c = macro_nextChar ();\r
- }\r
- unput (c);\r
- }\r
-\r
- if (c == '\n')\r
- {\r
- emptyMacro = TRUE;\r
- unput (c);\r
- }\r
-\r
- c = oldc;\r
- }\r
-\r
- hasParams = (c == '(');\r
- \r
- if (usymtab_exists (fname))\r
- {\r
- e2 = usymtab_lookupExpose (fname);\r
- ct = uentry_getType (e2);\r
-\r
- if (uentry_isCodeDefined (e2) \r
- && fileloc_isUser (uentry_whereDefined (e2)))\r
- {\r
- if (optgenerror \r
- (FLG_MACROREDEF,\r
- message ("Macro %s already defined", fname),\r
- loc))\r
- {\r
- uentry_showWhereDefined (e2);\r
- uentry_clearDefined (e2);\r
- }\r
-\r
- if (uentry_isFunction (e2))\r
- {\r
- uentry_setType (e2, ctype_unknown);\r
- ct = ctype_unknown;\r
- unknownm = TRUE;\r
- context_enterUnknownMacro (e2); \r
- }\r
- else\r
- {\r
- context_enterConstantMacro (e2);\r
- }\r
- }\r
- else\r
- {\r
- if (uentry_isForward (e2) && uentry_isFunction (e2))\r
- {\r
- unknownm = TRUE;\r
-\r
- voptgenerror \r
- (FLG_MACROFCNDECL,\r
- message\r
- ("Parameterized macro has no prototype or specification: %s ", \r
- fname),\r
- loc);\r
- \r
- ct = ctype_unknown;\r
- uentry_setType (e2, ctype_unknown);\r
- uentry_setFunctionDefined (e2, loc); \r
- uentry_setUsed (e2, fileloc_undefined);\r
- context_enterUnknownMacro (e2); \r
- }\r
- else\r
- {\r
- if (uentry_isIter (e2))\r
- {\r
- isiter = TRUE;\r
- specparams = uentry_getParams (e2);\r
- noparams = uentryList_size (specparams);\r
- uentry_setDefined (e2, loc);\r
- context_enterIterDef (e2); \r
- }\r
- else if (uentry_isEndIter (e2))\r
- {\r
- isenditer = TRUE;\r
- uentry_setDefined (e2, loc);\r
- context_enterIterEnd (e2); /* don't care about it now */\r
- /* but should parse like an iter! */\r
- }\r
- else if (uentry_isConstant (e2))\r
- {\r
- if (hasParams)\r
- {\r
- voptgenerror \r
- (FLG_INCONDEFS, \r
- message ("Constant %s implemented as parameterized macro",\r
- fname),\r
- g_currentloc);\r
- \r
- uentry_showWhereSpecified (e2);\r
- uentry_setType (e2, ctype_unknown);\r
- uentry_makeConstantFunction (e2);\r
- uentry_setDefined (e2, g_currentloc);\r
- uentry_setFunctionDefined (e2, g_currentloc);\r
- context_enterUnknownMacro (e2); \r
- }\r
- else\r
- {\r
- if (!uentry_isSpecified (e2))\r
- {\r
- fileloc oloc = uentry_whereDeclared (e2);\r
-\r
- if (fileloc_isLib (oloc))\r
- {\r
- ;\r
- }\r
- else if (fileloc_isUndefined (oloc)\r
- || fileloc_isPreproc (oloc))\r
- {\r
- if (!emptyMacro)\r
- {\r
- voptgenerror\r
- (FLG_MACROCONSTDECL,\r
- message \r
- ("Macro constant %q not declared",\r
- uentry_getName (e2)),\r
- loc); \r
- }\r
- }\r
- else if (!fileloc_withinLines (oloc, loc, 2))\r
- { /* bogus! will give errors if there is too much whitespace */\r
- voptgenerror\r
- (FLG_SYNTAX,\r
- message \r
- ("Macro constant name %s does not match name in "\r
- "previous constant declaration. This constant "\r
- "is declared at %q", fname, \r
- fileloc_unparse (oloc)),\r
- loc);\r
- }\r
- }\r
-\r
- context_enterConstantMacro (e2); \r
- cstring_free (fname);\r
- fileloc_free (loc);\r
- return res;\r
- }\r
-\r
- }\r
- else if (ctype_isFunction (ct))\r
- {\r
- isspecfcn = TRUE;\r
- specparams = ctype_argsFunction (ct);\r
- noparams = uentryList_size (specparams);\r
- \r
- uentry_setFunctionDefined (e2, loc); \r
- context_enterMacro (e2);\r
- }\r
- else if (uentry_isVar (e2))\r
- {\r
- if (hasParams)\r
- {\r
- voptgenerror\r
- (FLG_INCONDEFS,\r
- message ("Variable %s implemented as parameterized macro", \r
- fname),\r
- loc);\r
-\r
- uentry_showWhereSpecified (e2);\r
- uentry_setType (e2, ctype_unknown);\r
- uentry_makeVarFunction (e2);\r
- uentry_setDefined (e2, g_currentloc);\r
- uentry_setFunctionDefined (e2, g_currentloc);\r
- context_enterUnknownMacro (e2); \r
- }\r
- else\r
- {\r
- uentry ucons = uentry_makeConstant (fname,\r
- ctype_unknown,\r
- loc);\r
- if (uentry_isExpandedMacro (e2))\r
- {\r
- ; /* okay */\r
- }\r
- else\r
- {\r
- if (optgenerror \r
- (FLG_INCONDEFS,\r
- message ("Variable %s implemented by a macro",\r
- fname),\r
- loc))\r
- {\r
- uentry_showWhereSpecified (e2);\r
- }\r
- }\r
-\r
- uentry_setDefined (e2, loc);\r
- uentry_setUsed (ucons, loc);\r
-\r
- context_enterConstantMacro (ucons);\r
- uentry_markOwned (ucons);\r
- cstring_free (fname);\r
- return res;\r
- }\r
- }\r
- else\r
- {\r
- if (uentry_isDatatype (e2))\r
- {\r
- vgenhinterror \r
- (FLG_SYNTAX,\r
- message ("Type implemented as macro: %x", \r
- uentry_getName (e2)),\r
- message ("A type is implemented using a macro definition. A "\r
- "typedef should be used instead."),\r
- g_currentloc);\r
-\r
- swallowMacro ();\r
- /* Must exit scope (not sure why a new scope was entered?) */\r
- usymtab_quietExitScope (g_currentloc);\r
- uentry_setDefined (e2, g_currentloc);\r
- res = FALSE;\r
- }\r
- else\r
- {\r
- llcontbug \r
- (message ("Unexpanded macro not function or constant: %q", \r
- uentry_unparse (e2)));\r
- uentry_setType (e2, ctype_unknown);\r
- \r
- if (hasParams)\r
- {\r
- uentry_makeVarFunction (e2);\r
- uentry_setDefined (e2, g_currentloc);\r
- uentry_setFunctionDefined (e2, g_currentloc);\r
- context_enterUnknownMacro (e2); \r
- }\r
- }\r
- }\r
- }\r
- }\r
- }\r
- else\r
- {\r
- uentry ce;\r
-\r
- /* evans 2001-09-09 - if it has params, assume a function */\r
- if (hasParams)\r
- {\r
- voptgenerror \r
- (FLG_MACROMATCHNAME,\r
- message ("Unexpanded macro %s does not match name of a declared "\r
- "function. The name used in the control "\r
- "comment on the previous line should match.",\r
- fname),\r
- loc);\r
- \r
- ce = uentry_makeFunction (fname, ctype_unknown, \r
- typeId_invalid,\r
- globSet_undefined,\r
- sRefSet_undefined,\r
- warnClause_undefined,\r
- fileloc_undefined); \r
- uentry_setUsed (ce, loc); /* perhaps bogus? */\r
- e2 = usymtab_supEntryReturn (ce);\r
- context_enterUnknownMacro (e2); \r
- }\r
- else\r
- {\r
- voptgenerror \r
- (FLG_MACROMATCHNAME,\r
- message ("Unexpanded macro %s does not match name of a constant "\r
- "or iter declaration. The name used in the control "\r
- "comment on the previous line should match. "\r
- "(Assuming macro defines a constant.)", \r
- fname),\r
- loc);\r
- \r
- ce = uentry_makeConstant (fname, ctype_unknown, fileloc_undefined); \r
- uentry_setUsed (ce, loc); /* perhaps bogus? */\r
- e2 = usymtab_supEntryReturn (ce);\r
- \r
- context_enterConstantMacro (e2); \r
- cstring_free (fname);\r
- fileloc_free (loc);\r
- return res;\r
- }\r
- }\r
- \r
- /* in macros, ( must follow immediatetly after name */\r
- \r
- if (hasParams)\r
- {\r
- int paramno = 0;\r
- \r
- c = skip_whitespace ();\r
-\r
- while (c != ')' && c != '\0')\r
- {\r
- uentry param;\r
- bool suppress = context_inSuppressRegion ();\r
- cstring paramname = cstring_undefined;\r
-\r
- /*\r
- ** save the parameter location\r
- */\r
-\r
- decColumn ();\r
- context_saveLocation ();\r
- incColumn ();\r
-\r
- while (c != ' ' && c != '\t' && c != ',' && c != '\0' && c != ')')\r
- {\r
- paramname = cstring_appendChar (paramname, c);\r
- c = macro_nextChar ();\r
- }\r
- \r
- if (c == ' ' || c == '\t') c = skip_whitespace ();\r
-\r
- if (c == ',')\r
- {\r
- c = macro_nextChar ();\r
- if (c == ' ' || c == '\t') c = skip_whitespace ();\r
- }\r
- \r
- if (c == '\0')\r
- {\r
- llfatalerror (cstring_makeLiteral\r
- ("Bad macro syntax: uentryList"));\r
- }\r
- \r
- if ((isspecfcn || isiter) && (paramno < noparams)\r
- && !uentry_isElipsisMarker (uentryList_getN \r
- (specparams, paramno)))\r
- {\r
- fileloc sloc = context_getSaveLocation ();\r
- uentry decl = uentryList_getN (specparams, paramno);\r
- sRef sr;\r
- \r
- param = uentry_nameCopy (paramname, decl);\r
- \r
- uentry_setParam (param);\r
- sr = sRef_makeParam (paramno, uentry_getType (param), stateInfo_makeLoc (sloc));\r
-\r
- if (sRef_getNullState (sr) == NS_ABSNULL)\r
- {\r
- ctype pt = ctype_realType (uentry_getType (param));\r
-\r
- if (ctype_isUser (pt))\r
- {\r
- uentry te = usymtab_getTypeEntrySafe (ctype_typeId (pt));\r
- \r
- if (uentry_isValid (te))\r
- {\r
- sRef_setStateFromUentry (sr, te);\r
- }\r
- }\r
- else\r
- {\r
- sRef_setNullState (sr, NS_UNKNOWN, sloc);\r
- }\r
- }\r
-\r
- uentry_setSref (param, sr);\r
- uentry_setDeclaredForceOnly (param, sloc);\r
-\r
- skipparam = isiter && uentry_isOut (uentryList_getN (specparams, paramno));\r
- }\r
- else\r
- {\r
- fileloc sloc = context_getSaveLocation ();\r
-\r
- param = uentry_makeVariableSrefParam \r
- (paramname, ctype_unknown, fileloc_copy (sloc), \r
- sRef_makeParam (paramno, ctype_unknown, stateInfo_makeLoc (sloc)));\r
- DPRINTF (("Unknown param: %s", uentry_unparseFull (param)));\r
- cstring_free (paramname);\r
-\r
- sRef_setPosNull (uentry_getSref (param), sloc);\r
- uentry_setDeclaredForce (param, sloc);\r
-\r
- skipparam = FALSE;\r
- fileloc_free (sloc);\r
- }\r
-\r
- if (!skipparam)\r
- {\r
- llassert (!uentry_isElipsisMarker (param));\r
-\r
- if (!suppress)\r
- {\r
- sRef_makeUnsafe (uentry_getSref (param));\r
- }\r
- \r
- pn = uentryList_add (pn, uentry_copy (param));\r
- usymtab_supEntry (param);\r
- }\r
- else\r
- {\r
- /* don't add param */\r
- uentry_free (param);\r
- }\r
-\r
- if (c == ',') \r
- {\r
- (void) macro_nextChar ();\r
- c = skip_whitespace ();\r
- }\r
-\r
- paramno++;\r
- }\r
- \r
- if (c == ')')\r
- {\r
- if (isspecfcn || isiter)\r
- {\r
- if (paramno != noparams && noparams >= 0)\r
- {\r
- advanceLine ();\r
-\r
- voptgenerror \r
- (FLG_INCONDEFS,\r
- message ("Macro %s specified with %d args, defined with %d", \r
- fname, noparams, paramno),\r
- g_currentloc);\r
-\r
- uentry_showWhereSpecified (e2);\r
- uentry_resetParams (e2, pn);\r
- }\r
- }\r
- else\r
- {\r
- uentry_resetParams (e2, pn);\r
- }\r
- }\r
- }\r
- else\r
- {\r
- /*\r
- ** the form should be:\r
- **\r
- ** # define newname oldname\r
- ** where oldname refers to a function matching the specification\r
- ** of newname.\r
- */\r
-\r
- if (unknownm)\r
- {\r
- sRef_setGlobalScope ();\r
- usymtab_supGlobalEntry (uentry_makeVariableLoc (fname, ctype_unknown));\r
- sRef_clearGlobalScope ();\r
- }\r
- else\r
- {\r
- context_setMacroMissingParams ();\r
- }\r
- }\r
- \r
- \r
- /* context_setuentryList (pn); */\r
- usymtab_enterScope ();\r
-\r
- fileloc_free (loc);\r
- cstring_free (fname);\r
-\r
- return res;\r
-}\r
-\r
-static bool handleSpecial (char *yyt)\r
-{\r
- char *l = mstring_create (MAX_NAME_LENGTH);\r
- static bool reportcpp = FALSE;\r
- int lineno = 0;\r
- char c;\r
- char *ol;\r
- cstring olc;\r
- \r
- strcpy (l, yyt + 1);\r
-\r
- /* Need to safe original l for deallocating. */\r
- ol = l;\r
-\r
- l += strlen (yyt) - 1;\r
- \r
- while ((c = char_fromInt (lminput ())) != '\n' && c != '\0')\r
- {\r
- *l++ = c;\r
- }\r
-\r
- *l = '\0';\r
- olc = cstring_fromChars (ol);\r
- \r
- if (cstring_equalPrefixLit (olc, "pragma"))\r
- {\r
- char *pname = mstring_create (longUnsigned_fromInt (MAX_PRAGMA_LEN));\r
- char *opname = pname;\r
- char *ptr = ol + 6; /* pragma is six characters, plus space */\r
- int len = 0;\r
- \r
- \r
- /* skip whitespace */\r
- while (((c = *ptr) != '\0') && isspace (c))\r
- {\r
- ptr++;\r
- }\r
-\r
- \r
- while (((c = *ptr) != '\0') && !isspace (c))\r
- {\r
- len++;\r
-\r
- if (len > MAX_PRAGMA_LEN)\r
- {\r
- break;\r
- }\r
-\r
- ptr++;\r
- *pname++ = c;\r
- }\r
-\r
- *pname = '\0';\r
- \r
- if (len == PRAGMA_LEN_EXPAND \r
- && mstring_equal (opname, PRAGMA_EXPAND))\r
- {\r
- cstring exname = cstring_undefined;\r
- uentry ue;\r
- \r
- ptr++; \r
- while (((c = *ptr) != '\0') && !isspace (c))\r
- {\r
- exname = cstring_appendChar (exname, c);\r
- ptr++;\r
- }\r
- \r
- \r
- ue = usymtab_lookupExposeGlob (exname);\r
- \r
- if (uentry_isExpandedMacro (ue))\r
- {\r
- if (fileloc_isPreproc (uentry_whereDefined (ue)))\r
- {\r
- fileloc_setColumn (g_currentloc, 1);\r
- uentry_setDefined (ue, g_currentloc);\r
- }\r
- }\r
-\r
- cstring_free (exname);\r
- }\r
- }\r
- else if (cstring_equalPrefixLit (olc, "ident"))\r
- {\r
- /* Some pre-processors will leave these in the code. Ignore rest of line */\r
- }\r
- /*\r
- ** Yuk...Win32 filenames can have spaces in them...we need to read\r
- ** to the matching end quote.\r
- */\r
- else if ((sscanf (ol, "line %d \"", &lineno) == 1)\r
- || (sscanf (ol, " %d \"", &lineno) == 1))\r
- {\r
- char *tmp = ol;\r
- cstring fname;\r
- fileId fid;\r
-\r
- /*@access cstring@*/\r
- while (*tmp != '\"' && *tmp != '\0')\r
- {\r
- tmp++;\r
- }\r
-\r
- llassert (*tmp == '\"');\r
-\r
- tmp++;\r
-\r
- fname = tmp;\r
- \r
- while (*tmp != '\"' && *tmp != '\0')\r
- {\r
- tmp++;\r
- }\r
-\r
- llassert (*tmp == '\"');\r
-\r
- *tmp = '\0';\r
-\r
-# if defined(OS2) || defined(MSDOS) || defined(WIN32)\r
-\r
- /*\r
- ** DOS-like path delimiters get delivered in pairs, something like \r
- ** \"..\\\\file.h\", so we have to make it normal again. We do NOT\r
- ** remove the pre dirs yet as we usually specify tmp paths relative\r
- ** to the current directory, so tmp files would not get found in\r
- ** the hash table. If this method fails we try it again later. \r
- */\r
-\r
- {\r
- char *stmp = fname;\r
- \r
- /*\r
- ** Skip past the drive marker.\r
- */\r
- \r
- if (strchr (stmp, ':') != NULL)\r
- {\r
- stmp = strchr (stmp, ':') + 1;\r
- }\r
- \r
- while ((stmp = strchr (stmp, CONNECTCHAR)) != NULL )\r
- {\r
- if (*(stmp+1) == CONNECTCHAR)\r
- {\r
- memmove (stmp, stmp+1, strlen (stmp));\r
- }\r
- \r
- stmp++;\r
- }\r
- \r
- fid = fileTable_lookupBase (context_fileTable (), fname);\r
- if (!(fileId_isValid (fid)))\r
- {\r
- fname = removePreDirs (fname);\r
- fid = fileTable_lookupBase (context_fileTable (), fname);\r
- }\r
- }\r
-# else /* !defined(OS2) && !defined(MSDOS) */\r
- fname = removePreDirs (fname);\r
- fid = fileTable_lookupBase (context_fileTable (), fname); \r
-# endif /* !defined(OS2) && !defined(MSDOS) */\r
- \r
- if (!(fileId_isValid (fid)))\r
- {\r
- if (context_inXHFile ())\r
- {\r
- fid = fileTable_addXHFile (context_fileTable (), fname);\r
- }\r
- else if (isHeaderFile (fname))\r
- {\r
- fid = fileTable_addHeaderFile (context_fileTable (), fname);\r
- }\r
- else\r
- {\r
- fid = fileTable_addFile (context_fileTable (), fname);\r
- }\r
- }\r
- \r
- setFileLine (fid, lineno);\r
- /*@noaccess cstring@*/\r
- }\r
- else if ((sscanf (ol, "line %d", &lineno) == 1) \r
- || (sscanf (ol, " %d", &lineno) == 1))\r
- {\r
- setLine (lineno); /* next line is <cr> */\r
- }\r
- else\r
- {\r
- if (mstring_equal (ol, "")) {\r
- DPRINTF (("Empty pp command!"));\r
- /*\r
- ** evs 2000-05-16: This is a horrible kludge, to get around a bug (well, difficulty) in the pre-processor.\r
- ** We handle a plain # in the input file, by echoing it, and ignoring it in the post-pp-file.\r
- */\r
- mstring_free (ol);\r
- return FALSE;\r
- } else {\r
- if (!reportcpp)\r
- {\r
- \r
- } else {\r
- llbug (message ("File contains preprocessor command: #%s", \r
- cstring_fromChars (ol)));\r
- reportcpp = TRUE;\r
- }\r
- }\r
- \r
- sfree (ol);\r
- return TRUE;\r
- }\r
-\r
- sfree (ol);\r
- return FALSE;\r
-}\r
- \r
-static int handleLlSpecial ()\r
-{ \r
- bool hasnl = FALSE;\r
- int ic; \r
- char c;\r
- char *s = mstring_createEmpty ();\r
- char *os; \r
- int tok;\r
- int charsread = 0;\r
- fileloc loc;\r
-\r
- loc = fileloc_copy (g_currentloc);\r
- DPRINTF (("Handle special: %s", fileloc_unparse (loc)));\r
-\r
- while (((ic = ninput ()) != 0) && isalpha (ic))\r
- {\r
- c = (char) ic;\r
- s = mstring_append (s, c);\r
- charsread++;\r
- }\r
-\r
- DPRINTF (("Read: %s / %s", s, fileloc_unparse (g_currentloc)));\r
- os = s;\r
-\r
- if (charsread == 0 && ic == (int) AFTER_COMMENT_MARKER[0])\r
- {\r
- ic = ninput ();\r
-\r
- llassert (ic == AFTER_COMMENT_MARKER[1]);\r
- \r
- if (*s == '\0')\r
- {\r
- sfree (os);\r
- fileloc_free (loc);\r
- return QNOMODS; /* special token no modifications token */\r
- }\r
- }\r
- \r
- DPRINTF (("Coment marker: %s", os));\r
- tok = commentMarkerToken (cstring_fromChars (os));\r
-\r
- if (tok != BADTOK)\r
- {\r
- tokLength = charsread;\r
- sfree (os);\r
- inSpecPart = TRUE;\r
- fileloc_free (loc);\r
- return tok;\r
- }\r
-\r
- DPRINTF (("Not a comment marker..."));\r
- /* Add rest of the comment */\r
- \r
- if (ic != 0 && ic != EOF)\r
- {\r
- c = (char) ic;\r
- \r
- s = mstring_append (s, c);\r
- charsread++;\r
-\r
- while (((ic = ninput ()) != 0) && (ic != EOF)\r
- && (ic != AFTER_COMMENT_MARKER[0]))\r
- {\r
- c = (char) ic;\r
-\r
- /* evans 2001-09-01 added to prevent assertion failures for uncloses syntactic comments */\r
-\r
- if (c == '\n') {\r
- hasnl = TRUE; /* This prevents tokLength from being set later. */\r
- tokLength = 0; \r
-\r
- voptgenerror\r
- (FLG_SYNTAX, \r
- message ("Likely parse error: syntactic comment token spans multiple lines: %s",\r
- cstring_fromChars (s)),\r
- g_currentloc);\r
- }\r
-\r
- s = mstring_append (s, c);\r
- charsread++;\r
- }\r
- }\r
-\r
- DPRINTF (("Read: %s / %s", s, fileloc_unparse (g_currentloc)));\r
-\r
- if (ic == AFTER_COMMENT_MARKER[0]) \r
- {\r
- int nc = ninput ();\r
- llassert ((char) nc == AFTER_COMMENT_MARKER[1]);\r
- charsread++;\r
- }\r
-\r
- os = s;\r
-\r
- while (*s == ' ' || *s == '\t' || *s == '\n') \r
- {\r
- s++;\r
- }\r
-\r
- if (*s == '-' || *s == '+' || *s == '=') /* setting flags */\r
- {\r
- c = *s;\r
-\r
- while (c == '-' || c == '+' || c == '=')\r
- {\r
- ynm set = ynm_fromCodeChar (c);\r
- cstring thisflag;\r
-\r
- s++;\r
- \r
- thisflag = cstring_fromChars (s);\r
- \r
- while ((c = *s) != '\0' && (c != '-') && (c != '=')\r
- && (c != '+') && (c != ' ') && (c != '\t') && (c != '\n'))\r
- {\r
- s++;\r
- }\r
-\r
- *s = '\0';\r
-\r
- if (!context_getFlag (FLG_NOCOMMENTS))\r
- {\r
- cstring flagname = thisflag;\r
- flagcode fflag = identifyFlag (flagname);\r
- \r
- if (flagcode_isSkip (fflag))\r
- {\r
- ;\r
- }\r
- else if (flagcode_isInvalid (fflag))\r
- {\r
- if (isMode (flagname))\r
- {\r
- if (ynm_isMaybe (set))\r
- {\r
- llerror\r
- (FLG_BADFLAG, \r
- message \r
- ("Semantic comment attempts to restore flag %s. "\r
- "A mode flag cannot be restored.",\r
- flagname));\r
- }\r
- else\r
- {\r
- context_setMode (flagname);\r
- }\r
- }\r
- else\r
- {\r
- voptgenerror\r
- (FLG_UNRECOGFLAGCOMMENTS,\r
- message ("Unrecognized option in semantic comment: %s", \r
- flagname),\r
- g_currentloc);\r
- }\r
- }\r
- else if (flagcode_isGlobalFlag (fflag))\r
- {\r
- voptgenerror\r
- (FLG_BADFLAG, \r
- message \r
- ("Semantic comment attempts to set global flag %s. "\r
- "A global flag cannot be set locally.",\r
- flagname),\r
- g_currentloc);\r
- }\r
- else\r
- {\r
- context_fileSetFlag (fflag, set);\r
- \r
- if (flagcode_hasArgument (fflag))\r
- {\r
- if (ynm_isMaybe (set))\r
- {\r
- voptgenerror\r
- (FLG_BADFLAG, \r
- message \r
- ("Semantic comment attempts to restore flag %s. "\r
- "A flag for setting a value cannot be restored.",\r
- flagname),\r
- g_currentloc);\r
- }\r
- else\r
- { /* cut-and-pastied from llmain...blecch */\r
- cstring extra = cstring_undefined;\r
- char *rest;\r
- char *orest;\r
- char rchar;\r
- \r
- *s = c;\r
- rest = mstring_copy (s);\r
- orest = rest;\r
- *s = '\0';\r
- \r
- while ((rchar = *rest) != '\0'\r
- && (isspace (rchar)))\r
- {\r
- rest++;\r
- s++;\r
- }\r
- \r
- while ((rchar = *rest) != '\0'\r
- && !isspace (rchar))\r
- {\r
- extra = cstring_appendChar (extra, rchar);\r
- rest++; \r
- s++;\r
- }\r
- \r
- sfree (orest);\r
- \r
- if (cstring_isUndefined (extra))\r
- {\r
- llerror \r
- (FLG_BADFLAG,\r
- message\r
- ("Flag %s (in semantic comment) must be followed by an argument",\r
- flagcode_unparse (fflag)));\r
- }\r
- else\r
- {\r
- s--;\r
- \r
- if (flagcode_hasValue (fflag))\r
- {\r
- setValueFlag (fflag, extra);\r
- }\r
- else if (flagcode_hasString (fflag))\r
- {\r
- setStringFlag (fflag, extra);\r
- }\r
- else\r
- {\r
- BADEXIT;\r
- }\r
- }\r
- }\r
- }\r
- }\r
- }\r
- else\r
- {\r
- ;\r
- }\r
-\r
- *s = c;\r
- while ((c == ' ') || (c == '\t') || (c == '\n'))\r
- {\r
- c = *(++s);\r
- }\r
- } \r
-\r
- if (context_inHeader () && !isArtificial (cstring_fromChars (os)))\r
- {\r
- DPRINTF (("Here adding comment: %s", os));\r
- context_addComment (cstring_fromCharsNew (os));\r
- }\r
- else\r
- {\r
- ;\r
- }\r
- }\r
- else\r
- {\r
- char *t = s;\r
- int macrocode;\r
- char tchar = '\0';\r
- annotationInfo ainfo;\r
-\r
- while (*s != '\0' && *s != ' ' && *s != '\t' && *s != '\n') \r
- {\r
- s++;\r
- }\r
-\r
- if (*s != '\0') \r
- {\r
- tchar = *s;\r
- *s = '\0';\r
- s++;\r
- }\r
- \r
- t = cstring_toCharsSafe (cstring_downcase (cstring_fromChars (t)));\r
- macrocode = tokenMacroCode (cstring_fromChars (t));\r
-\r
- if (macrocode != BADTOK)\r
- {\r
- tokLength = hasnl ? 0 : mstring_length (t);\r
- \r
- sfree (t);\r
- sfree (os);\r
- fileloc_free (loc);\r
-\r
- if (macrocode == SKIPTOK)\r
- {\r
- return BADTOK;\r
- }\r
-\r
- return macrocode;\r
- }\r
- \r
- ainfo = context_lookupAnnotation (cstring_fromChars (os));\r
- \r
- if (annotationInfo_isDefined (ainfo)) {\r
- DPRINTF (("Found annotation: %s", annotationInfo_unparse (ainfo)));\r
- /*@i324@*/ yylval.annotation = ainfo;\r
- tokLength = 0;\r
- sfree (os);\r
- sfree (t);\r
- fileloc_free (loc);\r
- return CANNOTATION;\r
- } \r
-\r
- if (context_inHeader ())\r
- {\r
- if (tchar != '\0')\r
- {\r
- *(s-1) = tchar;\r
- }\r
- \r
- if ((context_inMacro () || context_inGlobalContext ())\r
- && macrocode != SKIPTOK\r
- && !isArtificial (cstring_fromChars (os))) \r
- {\r
- DPRINTF (("Add comment: %s", os));\r
- context_addComment (cstring_fromCharsNew (os));\r
- }\r
- else\r
- {\r
- ; \r
- }\r
- \r
- if (tchar != '\0')\r
- {\r
- *(s-1) = '\0';\r
- }\r
- }\r
-\r
- if (mstring_equal (t, "ignore"))\r
- {\r
- if (!context_getFlag (FLG_NOCOMMENTS))\r
- {\r
- context_enterSuppressRegion ();\r
- }\r
- }\r
- else if ((*t == 'i' || *t == 't')\r
- && (*(t + 1) == '\0'))\r
- {\r
- if (!context_getFlag (FLG_NOCOMMENTS)\r
- && (*t == 'i' || context_getFlag (FLG_TMPCOMMENTS)))\r
- {\r
- context_enterSuppressLine (-1); /* infinite suppression */\r
- }\r
- }\r
- else if (((*t == 'i') || (*t == 't'))\r
- && ((*(t + 1) >= '0' && *(t + 1) <= '9')))\r
- {\r
- bool tmpcomment = (*t == 't');\r
- int val = -1; \r
- char *tt = t; /* don't mangle t, since it is free'd */\r
- char lc = *(++tt);\r
-\r
- if (lc >= '0' && lc <= '9')\r
- {\r
- val = (int)(lc - '0');\r
- \r
- lc = *(++tt); \r
- while (lc >= '0' && lc <= '9')\r
- {\r
- val *= 10;\r
- val += lc - '0';\r
- lc = *(++tt);\r
- }\r
- }\r
-\r
- \r
- if (!context_getFlag (FLG_NOCOMMENTS)\r
- && (!tmpcomment || context_getFlag (FLG_TMPCOMMENTS)))\r
- {\r
- context_enterSuppressLine (val);\r
- }\r
- }\r
- else if (mstring_equal (t, "end"))\r
- {\r
- if (!context_getFlag (FLG_NOCOMMENTS))\r
- {\r
- context_exitSuppressRegion ();\r
- }\r
- }\r
- else if (mstring_equal (t, "notfunction"))\r
- {\r
- ; /* handled by pcpp */\r
- }\r
- else if (mstring_equal (t, "access"))\r
- {\r
- cstring tname;\r
- \r
- while (TRUE)\r
- {\r
- while ((c = *s) && (c == ' ' || c == '\t' || c == '\n'))\r
- {\r
- s++;\r
- }\r
- \r
- if (c == '\0')\r
- {\r
- break;\r
- }\r
-\r
- tname = cstring_fromChars (s);\r
- \r
- while ((c = *s) != '\0' && c != ' ' \r
- && c != '\t' && c != '\n' && c != ',') \r
- {\r
- s++;\r
- }\r
-\r
- *s = '\0';\r
-\r
- DPRINTF (("Access %s", tname));\r
-\r
- if (!context_getFlag (FLG_NOCOMMENTS) \r
- && !context_getFlag (FLG_NOACCESS))\r
- {\r
- if (usymtab_existsType (tname))\r
- {\r
- typeId uid = usymtab_getTypeId (tname);\r
- uentry ue = usymtab_getTypeEntry (uid);\r
-\r
- if (uentry_isAbstractDatatype (ue))\r
- {\r
- context_addFileAccessType (uid);\r
- DPRINTF (("Adding access to: %s / %d", tname, uid));\r
- }\r
- else\r
- {\r
- voptgenerror\r
- (FLG_COMMENTERROR,\r
- message\r
- ("Non-abstract type %s used in access comment",\r
- tname),\r
- g_currentloc);\r
- }\r
- }\r
- else\r
- {\r
- if (!(context_inSuppressRegion ()\r
- || context_inSuppressZone (g_currentloc)))\r
- {\r
- voptgenerror\r
- (FLG_COMMENTERROR,\r
- message\r
- ("Unrecognized type %s used in access comment",\r
- tname),\r
- g_currentloc);\r
- }\r
- }\r
- }\r
- \r
- if (c != '\0') \r
- {\r
- s++;\r
- }\r
- \r
- if (c != ',' && c != ' ')\r
- {\r
- break;\r
- }\r
- }\r
- }\r
- else if (mstring_equal (t, "noaccess"))\r
- {\r
- cstring tname;\r
- char lc;\r
- \r
- while (TRUE)\r
- {\r
- while ((lc = *s) && (lc == ' ' || lc == '\t' || lc == '\n')) \r
- {\r
- s++;\r
- }\r
- \r
- if (lc == '\0')\r
- {\r
- break;\r
- }\r
-\r
- tname = cstring_fromChars (s);\r
- \r
- while ((lc = *s) != '\0' && lc != ' ' && lc != '\t' \r
- && lc != '\n' && lc != ',') \r
- {\r
- s++;\r
- }\r
-\r
- *s = '\0';\r
-\r
- if (!context_getFlag (FLG_NOCOMMENTS) \r
- && !context_getFlag (FLG_NOACCESS))\r
- {\r
- if (usymtab_existsType (tname))\r
- {\r
- typeId tuid = usymtab_getTypeId (tname);\r
- \r
- if (context_couldHaveAccess (tuid))\r
- {\r
- DPRINTF (("Removing access: %s", tname));\r
- context_removeFileAccessType (tuid);\r
- }\r
- else\r
- {\r
- if (!(context_inSuppressRegion () \r
- || context_inSuppressZone (g_currentloc)))\r
- {\r
- uentry ue = usymtab_getTypeEntry (tuid);\r
- \r
- if (uentry_isAbstractDatatype (ue))\r
- {\r
- voptgenerror\r
- (FLG_COMMENTERROR,\r
- message\r
- ("Non-accessible abstract type %s used in noaccess comment",\r
- tname),\r
- g_currentloc);\r
- }\r
- else\r
- {\r
- voptgenerror\r
- (FLG_COMMENTERROR,\r
- message\r
- ("Non-abstract type %s used in noaccess comment",\r
- tname),\r
- g_currentloc);\r
- }\r
- }\r
- }\r
- }\r
- else\r
- {\r
- if (!(context_inSuppressRegion () \r
- || context_inSuppressZone (g_currentloc)))\r
- {\r
- voptgenerror\r
- (FLG_COMMENTERROR,\r
- message\r
- ("Unrecognized type %s used in noaccess comment",\r
- tname),\r
- g_currentloc);\r
- }\r
- }\r
- }\r
- \r
- if (lc != '\0') \r
- {\r
- s++;\r
- }\r
- \r
- if (lc != ',' && lc != ' ')\r
- {\r
- break;\r
- }\r
- }\r
- }\r
- else\r
- {\r
- voptgenerror (FLG_UNRECOGCOMMENTS, \r
- message ("Semantic comment unrecognized: %s", \r
- cstring_fromChars (os)), loc);\r
- }\r
-\r
- sfree (t);\r
- }\r
- \r
- sfree (os);\r
- fileloc_free (loc);\r
- return BADTOK;\r
-}\r
-\r
-static /*@only@*/ cstring makeIdentifier (char *s)\r
-{\r
- char *c = mstring_create (size_toInt (strlen (s)) + 1);\r
- cstring id = cstring_fromChars (c);\r
-\r
- while (isalnum (*s) || (*s == '_') || (*s == '$')) \r
- {\r
- *c++ = *s++;\r
- }\r
-\r
- *c = '\0';\r
- return (id);\r
-}\r
-\r
-/*@observer@*/ /*@dependent@*/ uentry coerceId (cstring cn)\r
-{\r
- if (!(usymtab_exists (cn)))\r
- {\r
- fileloc loc = fileloc_createExternal ();\r
- \r
- /*\r
- ** We need to put this in a global scope, otherwise the sRef will be deallocated.\r
- */\r
- \r
- uentry ce = uentry_makeUnrecognized (cn, loc);\r
- \r
- if (!context_inIterEnd ())\r
- {\r
- voptgenerror \r
- (FLG_SYSTEMUNRECOG, \r
- message ("Unrecognized (possibly system) identifier: %q", \r
- uentry_getName (ce)), \r
- g_currentloc);\r
- }\r
- \r
- return ce;\r
- }\r
- \r
- return (usymtab_lookup (cn));\r
-}\r
-\r
-/*\r
-** like, coerceId, but doesn't supercede for iters\r
-*/\r
-\r
-/*@observer@*/ uentry coerceIterId (cstring cn)\r
-{\r
- if (!(usymtab_exists (cn)))\r
- {\r
- return uentry_undefined;\r
- }\r
- \r
- return (usymtab_lookup (cn));\r
-}\r
-\r
-/*@observer@*/ cstring LastIdentifier ()\r
-{\r
- return (lastidprocessed);\r
-}\r
-\r
-static int processIdentifier (cstring id)\r
-{\r
- uentry le;\r
-\r
- if (context_getFlag (FLG_GRAMMAR))\r
- {\r
- lldiagmsg (message ("Process identifier: %s", id));\r
- }\r
-\r
- context_clearJustPopped ();\r
- lastidprocessed = id; \r
-\r
- if (context_inFunctionHeader ())\r
- {\r
- int tok = commentMarkerToken (id);\r
- DPRINTF (("in function decl..."));\r
-\r
- if (tok != BADTOK)\r
- {\r
- return tok;\r
- }\r
- else \r
- {\r
- tok = tokenMacroCode (id);\r
-\r
- if (tok != BADTOK)\r
- {\r
- return tok;\r
- }\r
- else \r
- {\r
- annotationInfo ainfo;\r
-\r
- if (expectingMetaStateName) \r
- {\r
- metaStateInfo msinfo = context_lookupMetaStateInfo (id);\r
-\r
- if (metaStateInfo_isDefined (msinfo))\r
- {\r
- yylval.msinfo = msinfo;\r
- return METASTATE_NAME;\r
- }\r
- else\r
- {\r
- DPRINTF (("Not meta state name: %s", cstring_toCharsSafe (id)));\r
- }\r
- }\r
- \r
- ainfo = context_lookupAnnotation (id);\r
- \r
- if (annotationInfo_isDefined (ainfo)) \r
- {\r
- DPRINTF (("Found annotation: %s", annotationInfo_unparse (ainfo)));\r
- /*@i324@*/ yylval.annotation = ainfo;\r
- return CANNOTATION;\r
- }\r
- else\r
- {\r
- DPRINTF (("Not annotation: %s", id));\r
- }\r
- }\r
- }\r
- }\r
-\r
- /* Consider handling: Defined by C99 as static const char __func__[] */\r
-\r
- if (context_getFlag (FLG_GNUEXTENSIONS))\r
- {\r
- int tok = BADTOK;\r
- \r
- if (cstring_equalLit (id, "__stdcall")\r
- || cstring_equalLit (id, "__cdecl")\r
- || cstring_equalLit (id, "__extension__"))\r
- {\r
- return BADTOK;\r
- }\r
- else if (cstring_equalLit (id, "__volatile__"))\r
- {\r
- tok = QVOLATILE;\r
- }\r
- else if (cstring_equalLit (id, "__signed"))\r
- {\r
- tok = QSIGNED;\r
- }\r
- else if (cstring_equalLit (id, "__unsigned"))\r
- {\r
- tok = QUNSIGNED;\r
- }\r
- else if (cstring_equalLit (id, "__const__"))\r
- {\r
- tok = QCONST;\r
- }\r
- else if (cstring_equalLit (id, "__alignof__")) \r
- {\r
- tok = CALIGNOF; /* alignof is parsed like sizeof */\r
- }\r
- else if (cstring_equalLit (id, "__FUNCTION__")\r
- || cstring_equalLit (id, "__PRETTY_FUNCTION__")) \r
- {\r
- /* These tokens hold the name of the current function as strings */\r
- yylval.expr = exprNode_stringLiteral (id, fileloc_copy (g_currentloc));\r
- tokLength = 0;\r
- lastWasString = TRUE;\r
- tok = CCONSTANT;\r
- return tok;\r
- }\r
- else if (cstring_equalLit (id, "__attribute__")\r
- || cstring_equalLit (id, "__asm__")\r
- || cstring_equalLit (id, "_asm")\r
- || cstring_equalLit (id, "__asm")\r
- || cstring_equalLit (id, "__declspec"))\r
- {\r
- int depth = 0;\r
- bool useparens = FALSE;\r
- bool usebraces = FALSE;\r
- bool inquote = FALSE;\r
- bool inescape = FALSE;\r
- int ic;\r
-\r
- while ((ic = input ()) != EOF)\r
- {\r
- \r
- if (inescape)\r
- {\r
- inescape = FALSE;\r
- }\r
- else if (ic == '\\')\r
- {\r
- inescape = TRUE;\r
- }\r
- else if (ic == '\"')\r
- {\r
- inquote = !inquote;\r
- }\r
- else if (!inquote)\r
- {\r
- if (ic == '(')\r
- {\r
- if (!useparens)\r
- {\r
- if (!usebraces)\r
- {\r
- useparens = TRUE;\r
- }\r
- }\r
-\r
- if (useparens)\r
- {\r
- depth++;\r
- }\r
- }\r
- else if (ic == '{')\r
- {\r
- if (!usebraces)\r
- {\r
- if (!useparens)\r
- {\r
- usebraces = TRUE;\r
- }\r
- }\r
-\r
- if (usebraces)\r
- {\r
- depth++;\r
- }\r
- }\r
- else if (ic == ')' && useparens)\r
- {\r
- depth--;\r
- if (depth == 0) break;\r
- }\r
- else if (ic == '}' && usebraces)\r
- {\r
- depth--;\r
- if (depth == 0) break;\r
- }\r
- else if (ic == '}' \r
- && !usebraces && !useparens\r
- && cstring_equalLit (id, "__asm"))\r
- {\r
- /*\r
- ** We need this because some MS VC++ include files\r
- ** have __asm mov ... }\r
- ** Its a kludge, but otherwise would need to parse\r
- ** the asm code!\r
- */ \r
- return TRBRACE;\r
- }\r
- }\r
-\r
- if (ic == '\n')\r
- {\r
- context_incLineno ();\r
-\r
- if (cstring_equalLit (id, "__asm")\r
- && !useparens && !usebraces)\r
- {\r
- break;\r
- }\r
- }\r
- }\r
- \r
- llassert ((useparens && ic == ')')\r
- || (usebraces && ic == '}')\r
- || (!useparens && !usebraces));\r
-\r
- return BADTOK;\r
- }\r
- else if (cstring_equalLit (id, "inline")\r
- || cstring_equalLit (id, "__inline")\r
- || cstring_equalLit (id, "_inline")\r
- || cstring_equalLit (id, "__inline__"))\r
- {\r
- tok = QINLINE;\r
- }\r
- \r
- if (tok != BADTOK)\r
- {\r
- RETURN_TOK (tok);\r
- }\r
- }\r
-\r
- le = usymtab_lookupSafe (id);\r
-\r
- /*@-dependenttrans@*/\r
- \r
- if (uentry_isIter (le))\r
- {\r
- /*@i32@*/ yylval.entry = le;\r
- return (ITER_NAME);\r
- }\r
- else if (uentry_isEndIter (le))\r
- {\r
- /*@i32@*/ yylval.entry = le;\r
- return (ITER_ENDNAME);\r
- }\r
- else if (uentry_isUndefined (le))\r
- {\r
- yylval.cname = id;\r
-\r
- /* avoid parse errors for certain system built ins */\r
-\r
- if (g_expectingTypeName && (cstring_firstChar (id) == '_')\r
- && (cstring_secondChar (id) == '_'))\r
- {\r
- return (TYPE_NAME_OR_ID);\r
- }\r
-\r
- return (NEW_IDENTIFIER);\r
- }\r
- else if (!uentry_isDeclared (le) && !uentry_isCodeDefined (le))\r
- {\r
- if (uentry_isDatatype (le))\r
- {\r
- yylval.cname = id;\r
- return (NEW_IDENTIFIER);\r
- }\r
- else\r
- {\r
- /*@i32@*/ yylval.entry = le; \r
- return (IDENTIFIER); \r
- }\r
- }\r
- else if (uentry_isDatatype (le))\r
- {\r
- if (!g_expectingTypeName)\r
- {\r
- yylval.cname = id;\r
-\r
- return (NEW_IDENTIFIER);\r
- }\r
- else\r
- {\r
- yylval.ctyp = uentry_getAbstractType (le);\r
- \r
- uentry_setUsed (le, g_currentloc);\r
- return (TYPE_NAME);\r
- }\r
- }\r
- else\r
- {\r
- /*@i32@*/ yylval.entry = le; \r
- return (IDENTIFIER); \r
- }\r
-\r
- /*@=dependenttrans@*/\r
-}\r
-\r
-static bool processHashIdentifier (/*@only@*/ cstring id)\r
-{\r
- if (context_inMacro () || context_inIterDef () ||\r
- context_inIterEnd ())\r
- {\r
- uentry le;\r
- \r
- context_clearJustPopped ();\r
-\r
- lastidprocessed = id; \r
- le = usymtab_lookupSafe (id);\r
-\r
- if (uentry_isParam (le) || uentry_isRefParam (le))\r
- {\r
- return TRUE;\r
- }\r
- else\r
- {\r
- return FALSE;\r
- }\r
- }\r
- else\r
- {\r
- cstring_free (id);\r
- return FALSE;\r
- }\r
-}\r
-\r
-\r
-static /*@only@*/ exprNode processString ()\r
-{\r
- exprNode res;\r
- fileloc loc;\r
- char *nl = strchr (yytext, '\n');\r
- cstring ns = cstring_fromCharsNew (yytext);\r
-\r
- if (nl == NULL)\r
- {\r
- loc = fileloc_copy (g_currentloc);\r
- addColumn (cstring_length (ns));\r
- }\r
- else\r
- {\r
- char *lastnl = nl;\r
-\r
- loc = fileloc_copy (g_currentloc);\r
-\r
- context_incLineno ();\r
- \r
- while ((nl = strchr ((nl + 1), '\n')) != NULL)\r
- {\r
- context_incLineno ();\r
- lastnl = nl;\r
- }\r
- }\r
-\r
- \r
- res = exprNode_stringLiteral (ns, loc);\r
- return (res);\r
-}\r
-\r
-static \r
-char processChar ()\r
-{\r
- char fchar;\r
- char next;\r
-\r
- llassert (*yytext != '\0');\r
- fchar = *(yytext + 1);\r
- if (fchar != '\\') return fchar;\r
- \r
- next = *(yytext + 2);\r
- \r
- switch (next)\r
- {\r
- case 'n': return '\n';\r
- case 't': return '\t';\r
- case '\"': return '\"';\r
- case '\'': return '\'';\r
- case '\\': return '\\';\r
- default: return '\0';\r
- }\r
-}\r
-\r
-static\r
-double processFloat ()\r
-{\r
- double ret = atof (yytext);\r
-\r
- return (ret);\r
-}\r
-\r
-static\r
-long processHex ()\r
-{\r
- int index = 2;\r
- long val = 0;\r
-\r
- llassert (yytext[0] == '0'\r
- && (yytext[1] == 'X' || yytext[1] == 'x'));\r
-\r
- while (yytext[index] != '\0') {\r
- int tval;\r
- char c = yytext[index];\r
-\r
- if (c >= '0' && c <= '9') {\r
- tval = (int) c - (int) '0';\r
- } else if (c >= 'A' && c <= 'F') {\r
- tval = (int) c - (int) 'A' + 10;\r
- } else if (c >= 'a' && c <= 'f') {\r
- tval = (int) c - (int) 'a' + 10;\r
- } else if (c == 'U' || c == 'L' || c == 'u' || c == 'l') {\r
- index++;\r
- while (yytext[index] != '\0') {\r
- if (c == 'U' || c == 'L' || c == 'u' || c == 'l') {\r
- ;\r
- } else {\r
- voptgenerror\r
- (FLG_SYNTAX, \r
- message ("Invalid character (%c) following specifier in hex constant: %s",\r
- c, cstring_fromChars (yytext)),\r
- g_currentloc);\r
- }\r
- index++;\r
- }\r
-\r
- break;\r
- } else {\r
- voptgenerror\r
- (FLG_SYNTAX, \r
- message ("Invalid character (%c) in hex constant: %s",\r
- c, cstring_fromChars (yytext)),\r
- g_currentloc);\r
- break;\r
- }\r
-\r
- val = (val * 16) + tval;\r
- index++;\r
- }\r
-\r
- DPRINTF (("Hex constant: %s = %ld", yytext, val));\r
- return val;\r
-}\r
-\r
-static\r
-long processOctal ()\r
-{\r
- int index = 1;\r
- long val = 0;\r
-\r
- llassert (yytext[0] == '0' && yytext[1] != 'X' && yytext[1] != 'x');\r
- \r
- while (yytext[index] != '\0') {\r
- int tval;\r
- char c = yytext[index];\r
- \r
- if (c >= '0' && c <= '7') {\r
- tval = (int) c - (int) '0';\r
- } else {\r
- voptgenerror\r
- (FLG_SYNTAX, \r
- message ("Invalid character (%c) in octal constant: %s",\r
- c, cstring_fromChars (yytext)),\r
- g_currentloc);\r
- break;\r
- }\r
-\r
- val = (val * 8) + tval;\r
- index++;\r
- }\r
-\r
- DPRINTF (("Octal constant: %s = %ld", yytext, val));\r
- return val;\r
-}\r
-\r
-static\r
-long processDec ()\r
-{\r
- return (atol (yytext));\r
-}\r
-\r
-static int\r
-processSpec (int tok)\r
-{\r
- size_t length = strlen (yytext);\r
- \r
- if (inSpecPart)\r
- {\r
- setTokLengthT (length);\r
- RETURN_TOK (tok);\r
- }\r
- else\r
- {\r
- \r
- context_saveLocation ();\r
- setTokLengthT (length);\r
- return (processIdentifier (makeIdentifier (yytext)));\r
- }\r
-}\r
-\r
-void cscanner_expectingMetaStateName ()\r
-{\r
- llassert (!expectingMetaStateName);\r
- llassert (context_inFunctionHeader ());\r
- expectingMetaStateName = TRUE;\r
-}\r
-\r
-void cscanner_clearExpectingMetaStateName ()\r
-{\r
- llassert (expectingMetaStateName);\r
- expectingMetaStateName = FALSE;\r
-}\r
+/*;-*-C-*-;
+** Splint - annotation-assisted static program checker
+** Copyright (C) 1994-2003 University of Virginia,
+** Massachusetts Institute of Technology
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2 of the License, or (at your
+** option) any later version.
+**
+** This program is distributed in the hope that it will be useful, but
+** WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+**
+** The GNU General Public License is available from http://www.gnu.org/ or
+** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+** MA 02111-1307, USA.
+**
+** For information on splint: splint@cs.virginia.edu
+** To report a bug: splint-bug@cs.virginia.edu
+** For more information: http://www.splint.org
+*/
+/*
+** cscanner.l
+**
+** Flex lexer for C.
+** Based on a C lexer by Nate Osgood
+** from hacrat@catfish.lcs.mit.edu Mon Jun 14 13:06:32 1993
+*/
+/*
+** Modified by Herbert 08/19/97:
+** - added #include for IBM's OS/2 compiler.
+** - fixed weird bug with lookup of tmp files (OS/2 and MSDOS only).
+*/
+/*
+** Modified by Mike Smith
+** Corrected missing 'line' in scanf() calls in handleSpecial().
+** Without this, I get an error when Splint hits a '#line' directive
+** in the pre-pre-processed source files. For safety, I have made these
+** conditional on OS2 and MSDOS because I don't understand why noone else
+** has seen this problem.
+**
+** Modified by Mike Smith, 4th June 1997
+** Finally resolved the #line problem. The scanf() calls have been fixed to
+** allow the following #line forms:-
+**
+** #line 123 "filename"
+** #line 123
+** # 123 "filename"
+** # 123
+**
+** The last two are generated by the GNU pre-processor, apparently
+*/
+
+Digit [0-9]
+Letter [a-zA-Z_$]
+H [a-fA-F0-9]
+E [Ee][+-]?{Digit}+
+U (u|U)
+L (l|L)
+FS (f|F|l|L)
+IS (u|U|l|L)*
+ULSuffix ({U}{L}|{L}{U})
+
+%{
+# include "splintMacros.nf"
+# if defined(OS2) && defined(__IBMC__)
+ /* needed for isatty()... */
+# include <io.h>
+# else
+
+/*
+** Win32 doesn't have unistd.h
+*/
+
+# ifndef WIN32
+# include <unistd.h>
+# endif
+
+# endif
+
+# include "basic.h"
+
+# include "cscannerHelp.h"
+# include "cgrammar.h"
+# include "cgrammar_tokens.h"
+# include "osd.h"
+
+/*@notfunction@*/
+# define yyinput() (incColumn (), getc (yyin))
+
+# include "flex.head"
+
+%}
+
+%%
+
+"/*" { llfatalerror (cstring_makeLiteral ("Comment in pre-processor output")); }
+
+"#"{Letter}({Letter}|{Digit})* {
+ context_saveLocation ();
+ cscannerHelp_setTokLength (longUnsigned_toInt (mstring_length (yytext)));
+
+ if (cscannerHelp_processHashIdentifier
+ (cscannerHelp_makeIdentifier (yytext + 1)))
+ {
+ return cscannerHelp_returnString (cstring_makeLiteral ("\"\""));
+ }
+ else
+ {
+ if (cscannerHelp_handleSpecial (yytext))
+ {
+ cscannerHelp_setTokLength (1);
+ return cscannerHelp_returnToken (0);
+ }
+ }
+ }
+"#" { if (cscannerHelp_handleSpecial (yytext))
+ {
+ cscannerHelp_setTokLength (1); return cscannerHelp_returnToken (0);
+ }
+ }
+"..." { cscannerHelp_setTokLength (3); return cscannerHelp_returnToken (CTOK_ELIPSIS); }
+"break" { cscannerHelp_setTokLength (5); return cscannerHelp_returnToken (BREAK); }
+"case" { cscannerHelp_setTokLength (4); return cscannerHelp_returnToken (CASE); }
+"continue" { cscannerHelp_setTokLength (8); return cscannerHelp_returnToken (CONTINUE); }
+"default" { cscannerHelp_setTokLength (7); return cscannerHelp_returnToken (DEFAULT); }
+"do" { cscannerHelp_setTokLength (2); return cscannerHelp_returnToken (DO); }
+"else" { cscannerHelp_setTokLength (4); return cscannerHelp_returnToken (CELSE); }
+"for" { cscannerHelp_setTokLength (3); return cscannerHelp_returnToken (CFOR); }
+"goto" { cscannerHelp_setTokLength (4); return cscannerHelp_returnToken (GOTO); }
+"if" { cscannerHelp_setTokLength (2); return cscannerHelp_returnToken (CIF); }
+"return" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (RETURN); }
+"sizeof" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (CSIZEOF); }
+"offsetof" { cscannerHelp_setTokLength (8); return cscannerHelp_returnToken (COFFSETOF); }
+"switch" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (SWITCH); }
+"while" { cscannerHelp_setTokLength (5); return cscannerHelp_returnToken (WHILE); }
+"va_arg" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (VA_ARG); }
+"va_dcl" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (VA_DCL); }
+"inline" {
+ /* gcc extension...this might not be appropriate */
+ cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (QINLINE); }
+
+"struct" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (CSTRUCT); }
+"typedef" { cscannerHelp_setTokLength (7); return cscannerHelp_returnToken (CTYPEDEF); }
+
+"union" { cscannerHelp_setTokLength (5); return cscannerHelp_returnToken (CUNION); }
+"enum" { cscannerHelp_setTokLength (4); return cscannerHelp_returnToken (CENUM); }
+
+"void" { cscannerHelp_setTokLength (4); return cscannerHelp_returnType (CVOID, ctype_void); }
+"int" { cscannerHelp_setTokLength (3); return cscannerHelp_returnType (CINT, ctype_int); }
+"double" { cscannerHelp_setTokLength (6); return cscannerHelp_returnType (CDOUBLE, ctype_double); }
+"char" { cscannerHelp_setTokLength (4); return cscannerHelp_returnType (CGCHAR, ctype_char); }
+"float" { cscannerHelp_setTokLength (5); return cscannerHelp_returnType (CGFLOAT, ctype_float); }
+
+"long" { cscannerHelp_setTokLength (4); return cscannerHelp_returnToken (QLONG); }
+"short" { cscannerHelp_setTokLength (5); return cscannerHelp_returnToken (QSHORT); }
+"unsigned" { cscannerHelp_setTokLength (8); return cscannerHelp_returnToken (QUNSIGNED); }
+"signed" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (QSIGNED); }
+
+"volatile" { cscannerHelp_setTokLength (8); return cscannerHelp_returnToken (QVOLATILE); }
+"const" { cscannerHelp_setTokLength (5); return cscannerHelp_returnToken (QCONST); }
+"restrict" { cscannerHelp_setTokLength (8); return cscannerHelp_returnToken (QRESTRICT); }
+
+ /* some systems expect this! [gack!] */
+"__const" { cscannerHelp_setTokLength (7); return cscannerHelp_returnToken (QCONST); }
+
+"extern" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (QEXTERN); }
+"auto" { cscannerHelp_setTokLength (4); return cscannerHelp_returnToken (QAUTO); }
+"register" { cscannerHelp_setTokLength (8); return cscannerHelp_returnToken (QREGISTER); }
+"static" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (QSTATIC); }
+
+\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { return cscannerHelp_returnExpr (cscannerHelp_processString ()); }
+L\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { return cscannerHelp_returnExpr (cscannerHelp_processWideString ()); }
+"out" { return (cscannerHelp_processSpec (QOUT)); }
+"in" { return (cscannerHelp_processSpec (QIN)); }
+"partial" { return (cscannerHelp_processSpec (QPARTIAL)); }
+"special" { return (cscannerHelp_processSpec (QSPECIAL)); }
+"anytype" { return (cscannerHelp_processSpec (QANYTYPE)); }
+"integraltype" { return (cscannerHelp_processSpec (QINTEGRALTYPE)); }
+"unsignedintegraltype" { return (cscannerHelp_processSpec (QUNSIGNEDINTEGRALTYPE)); }
+"signedintegraltype" { return (cscannerHelp_processSpec (QSIGNEDINTEGRALTYPE)); }
+"keep" { return (cscannerHelp_processSpec (QKEEP)); }
+"null" { return (cscannerHelp_processSpec (QNULL)); }
+"notnull" { return (cscannerHelp_processSpec (QNOTNULL)); }
+"isnull" { return (cscannerHelp_processSpec (QISNULL)); }
+"truenull" { return (cscannerHelp_processSpec (QTRUENULL)); }
+"falsenull" { return (cscannerHelp_processSpec (QFALSENULL)); }
+"nullwhentrue" { return (cscannerHelp_processSpec (QTRUENULL)); }
+"nullwhenfalse" { return (cscannerHelp_processSpec (QFALSENULL)); }
+"relnull" { return (cscannerHelp_processSpec (QRELNULL)); }
+"reldef" { return (cscannerHelp_processSpec (QRELDEF)); }
+"exposed" { return (cscannerHelp_processSpec (QEXPOSED)); }
+"newref" { return (cscannerHelp_processSpec (QNEWREF)); }
+"tempref" { return (cscannerHelp_processSpec (QTEMPREF)); }
+"killref" { return (cscannerHelp_processSpec (QKILLREF)); }
+"refcounted" { return (cscannerHelp_processSpec (QREFCOUNTED)); }
+"checked" { return (cscannerHelp_processSpec (QCHECKED)); }
+"checkmod" { return (cscannerHelp_processSpec (QCHECKMOD)); }
+"checkedstrict" { return (cscannerHelp_processSpec (QCHECKEDSTRICT)); }
+"unchecked" { return (cscannerHelp_processSpec (QUNCHECKED)); }
+"only" { return (cscannerHelp_processSpec (QONLY)); }
+"owned" { return (cscannerHelp_processSpec (QOWNED)); }
+"observer" { return (cscannerHelp_processSpec (QOBSERVER)); }
+"dependent" { return (cscannerHelp_processSpec (QDEPENDENT)); }
+"unused" { return (cscannerHelp_processSpec (QUNUSED)); }
+"external" { return (cscannerHelp_processSpec (QEXTERNAL)); }
+"sef" { return (cscannerHelp_processSpec (QSEF)); }
+"shared" { return (cscannerHelp_processSpec (QSHARED)); }
+"yield" { return (cscannerHelp_processSpec (QYIELD)); }
+"undef" { return (cscannerHelp_processSpec (QUNDEF)); }
+"killed" { return (cscannerHelp_processSpec (QKILLED)); }
+"nullterminated" { return (cscannerHelp_processSpec (QNULLTERMINATED));}
+"MaxSet" { return (cscannerHelp_processSpec (QMAXSET));}
+"MaxRead" { return (cscannerHelp_processSpec (QMAXREAD));}
+"maxSet" { return (cscannerHelp_processSpec (QMAXSET));}
+"maxRead" { return (cscannerHelp_processSpec (QMAXREAD));}
+
+{Letter}({Letter}|{Digit})* { int tok = cscannerHelp_processTextIdentifier (yytext);
+ if (tok != BADTOK)
+ {
+ return (tok);
+ }
+ }
+0[xX]{H}+ { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_int, cscannerHelp_processHex ()); /* evs 2000-05-17 was ctype_uint */
+ }
+0[xX]{H}+{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_lint, cscannerHelp_processHex ()); }
+0[xX]{H}+{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_llint, cscannerHelp_processHex ()); }
+0[xX]{H}+{U} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_uint, cscannerHelp_processHex ()); }
+0[xX]{H}+{ULSuffix} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_ulint, cscannerHelp_processHex ()); }
+0[xX]{H}+{U}{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processHex ()); }
+0[xX]{H}+{L}{L}{U} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processHex ()); }
+0{Digit}+ { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_int, cscannerHelp_processOctal ()); }
+0{Digit}+{U} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_uint, cscannerHelp_processOctal ()); }
+0{Digit}+{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_lint, cscannerHelp_processOctal ()); }
+0{Digit}+{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_llint, cscannerHelp_processOctal ()); }
+0{Digit}+{ULSuffix} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_ulint, cscannerHelp_processOctal ()); }
+0{Digit}+{U}{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processOctal ()); }
+0{Digit}+{L}{L}{U} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processOctal ()); }
+{Digit}+ { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_int, cscannerHelp_processDec ()); }
+{Digit}+{U} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_uint, cscannerHelp_processDec ()); }
+{Digit}+{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_lint, cscannerHelp_processDec ()); }
+{Digit}+{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_llint, cscannerHelp_processDec ()); }
+{Digit}+{ULSuffix} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_ulint, cscannerHelp_processDec ()); }
+{Digit}+{U}{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processDec ()); }
+{Digit}+{L}{L}{U} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processDec ()); }
+'(\\.|[^\\'])+' { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnChar (cscannerHelp_processChar ()); }
+L'(\\.|[^\\'])+' { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnChar (cscannerHelp_processChar ()); }
+{Digit}+{E}[fF] { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnFloat (ctype_float, cscannerHelp_processFloat ()); }
+{Digit}+{E}[lL] { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnFloat (ctype_ldouble, cscannerHelp_processFloat ()); }
+{Digit}+{E} { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnFloat (ctype_double, cscannerHelp_processFloat ()); }
+
+{Digit}*"."{Digit}+({E})?[fF] { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnFloat (ctype_float, cscannerHelp_processFloat ()); }
+{Digit}*"."{Digit}+({E})?[lL] { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnFloat (ctype_ldouble, cscannerHelp_processFloat ()); }
+{Digit}*"."{Digit}+({E})? { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnFloat (ctype_double, cscannerHelp_processFloat ()); }
+
+{Digit}+"."{Digit}*({E})?[fF] { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnFloat (ctype_float, cscannerHelp_processFloat ()); }
+{Digit}+"."{Digit}*({E})?[lL] { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnFloat (ctype_ldouble, cscannerHelp_processFloat ()); }
+{Digit}+"."{Digit}*({E})? { cscannerHelp_setTokLengthT (mstring_length (yytext));
+ return cscannerHelp_returnFloat (ctype_double, cscannerHelp_processFloat ()); }
+
+">>=" { return cscannerHelp_returnTokenLength (RIGHT_ASSIGN, 3); }
+"<<=" { return cscannerHelp_returnTokenLength (LEFT_ASSIGN, 3); }
+"+=" { return cscannerHelp_returnTokenLength (ADD_ASSIGN, 2); }
+"-=" { return cscannerHelp_returnTokenLength (SUB_ASSIGN, 2); }
+"*=" { return cscannerHelp_returnTokenLength (MUL_ASSIGN, 2); }
+"/=" { return cscannerHelp_returnTokenLength (DIV_ASSIGN, 2); }
+"%=" { return cscannerHelp_returnTokenLength (MOD_ASSIGN, 2); }
+"&=" { return cscannerHelp_returnTokenLength (AND_ASSIGN, 2); }
+"^=" { return cscannerHelp_returnTokenLength (XOR_ASSIGN, 2); }
+"|=" { return cscannerHelp_returnTokenLength (OR_ASSIGN, 2); }
+">>" { return cscannerHelp_returnTokenLength (RIGHT_OP, 2); }
+"<<" { return cscannerHelp_returnTokenLength (LEFT_OP, 2); }
+"++" { return cscannerHelp_returnTokenLength (INC_OP, 2); }
+"--" { return cscannerHelp_returnTokenLength (DEC_OP, 2); }
+"->" { return cscannerHelp_returnTokenLength (ARROW_OP, 2); }
+"&&" { return cscannerHelp_returnTokenLength (AND_OP, 2); }
+"||" { return cscannerHelp_returnTokenLength (OR_OP, 2); }
+"/\\" { return cscannerHelp_returnTokenLength (TCAND, 2); }
+"<=" { return cscannerHelp_returnTokenLength (LE_OP, 2); }
+">=" { return cscannerHelp_returnTokenLength (GE_OP, 2); }
+"==" { return cscannerHelp_returnTokenLength (EQ_OP, 2); }
+"!=" { return cscannerHelp_returnTokenLength (NE_OP, 2); }
+";" { return cscannerHelp_returnTokenLength (TSEMI, 1); }
+"{" { return cscannerHelp_returnTokenLength (TLBRACE, 1); }
+"}" { return cscannerHelp_returnTokenLength (TRBRACE, 1); }
+"," { return cscannerHelp_returnTokenLength (TCOMMA, 1); }
+":" { return cscannerHelp_returnTokenLength (TCOLON, 1); }
+"=" { return cscannerHelp_returnTokenLength (TASSIGN, 1); }
+"(" { return cscannerHelp_returnTokenLength (TLPAREN, 1); }
+")" { return cscannerHelp_returnTokenLength (TRPAREN, 1); }
+"[" { return cscannerHelp_returnTokenLength (TLSQBR, 1); }
+"]" { return cscannerHelp_returnTokenLength (TRSQBR, 1); }
+"." { return cscannerHelp_returnTokenLength (TDOT, 1); }
+"&" { return cscannerHelp_returnTokenLength (TAMPERSAND, 1); }
+"!" { return cscannerHelp_returnTokenLength (TEXCL, 1); }
+"~" { return cscannerHelp_returnTokenLength (TTILDE, 1); }
+"-" { return cscannerHelp_returnTokenLength (TMINUS, 1); }
+"+" { return cscannerHelp_returnTokenLength (TPLUS, 1); }
+"*" { return cscannerHelp_returnTokenLength (TMULT, 1); }
+"/" { return cscannerHelp_returnTokenLength (TDIV, 1); }
+"%" { return cscannerHelp_returnTokenLength (TPERCENT, 1); }
+"<" { return cscannerHelp_returnTokenLength (TLT, 1); }
+">" { return cscannerHelp_returnTokenLength (TGT, 1); }
+"^" { return cscannerHelp_returnTokenLength (TCIRC, 1); }
+"|" { return cscannerHelp_returnTokenLength (TBAR, 1); }
+"?" { return cscannerHelp_returnTokenLength (TQUEST, 1); }
+
+[ \t\v\f] { incColumn (); }
+\n { int tok = cscannerHelp_handleNewLine ();
+ if (tok != BADTOK) return tok; }
+"@@MR@@" { cscannerHelp_setTokLength (6);
+
+ if (cscannerHelp_processMacro ()) {
+ if (context_inIterDef ())
+ {
+ return cscannerHelp_returnToken (LLMACROITER);
+ }
+ if (context_inIterEnd ())
+ {
+ return cscannerHelp_returnToken (LLMACROEND);
+ }
+ if (context_inMacro ())
+ {
+ return cscannerHelp_returnToken (LLMACRO);
+ }
+ }
+ }
+"@QLMR" { if (context_inHeader () || context_inFunction ())
+ {
+ cscannerHelp_handleMacro ();
+ }
+ else
+ {
+ int nspchar = cscannerHelp_ninput ();
+ int nspaces;
+
+ /*
+ ** This is a hack to get the column number correct.
+ */
+
+ llassert (nspchar >= '0' && nspchar <= '9');
+
+ nspaces = nspchar - '0';
+
+ cscannerHelp_setTokLength (5 + nspaces);
+
+ if (cscannerHelp_processMacro ())
+ {
+ DPRINTF (("Here we are: %s", context_unparse ()));
+
+ if (context_inIterDef ())
+ {
+ return cscannerHelp_returnToken (LLMACROITER);
+ }
+ if (context_inIterEnd ())
+ {
+ return cscannerHelp_returnToken (LLMACROEND);
+ }
+ if (context_inMacro ())
+ {
+ return cscannerHelp_returnToken (LLMACRO);
+ }
+ }
+ }
+ }
+"@.CT" { cscannerHelp_setTokLength (4); lldiagmsg (ctype_unparseTable ()); }
+"@.FA" { cscannerHelp_setTokLength (4); lldiagmsg (message ("Access types: %q", typeIdSet_unparse (context_fileAccessTypes ()))); }
+"@.F" { cscannerHelp_setTokLength (3);
+ lldiagmsg (message ("%q: *** marker ***", fileloc_unparse (g_currentloc)));
+ }
+"@.L" { cscannerHelp_setTokLength (3); usymtab_printLocal (); }
+"@.A" { cscannerHelp_setTokLength (3); lldiagmsg (usymtab_unparseAliases ()); }
+"@.C" { cscannerHelp_setTokLength (3); lldiagmsg (context_unparse ()); }
+"@.W" { cscannerHelp_setTokLength (3); lldiagmsg (context_unparseClauses ()); }
+"@.G" { cscannerHelp_setTokLength (3); usymtab_printGuards (); }
+"@.S" { cscannerHelp_setTokLength (3); usymtab_printOut (); }
+"@.X" { cscannerHelp_setTokLength (3); usymtab_printAll (); }
+"@.Z" { cscannerHelp_setTokLength (3); usymtab_printComplete (); }
+"@.T" { cscannerHelp_setTokLength (3); usymtab_printTypes (); }
+"@.K" { cscannerHelp_setTokLength (3); lldiagmsg (usymtab_unparseStack ()); }
+"@.M" { cscannerHelp_setTokLength (3);
+ lldiagmsg (message ("Can modify: %q",
+ sRefSet_unparse (context_modList ())));
+ }
+"%{" { /* BEFORE_COMMENT_MARKER */
+ int tok;
+ incColumn (); incColumn ();
+ tok = cscannerHelp_handleLlSpecial ();
+
+ if (tok != BADTOK)
+ {
+ if (tok == CANNOTATION) {
+ return (tok);
+ } else {
+ /* Beware - this bashes yylval! */
+ return cscannerHelp_returnToken (tok);
+ }
+ }
+ }
+"%}" { /* AFTER_COMMENT_MARKER */
+ cscannerHelp_setTokLength (2);
+ cscannerHelp_exitSpecPart ();
+ return cscannerHelp_returnToken (QENDMACRO); }
+"\\" { incColumn (); cscannerHelp_setContinueLine (); }
+. { incColumn ();
+ if ((int) *yytext == 13 ) {
+ ;
+ } else {
+ voptgenerror
+ (FLG_SYNTAX,
+ message ("Invalid character (ascii: %d), skipping character",
+ (int)(*yytext)),
+ g_currentloc);
+ }
+ }
+%%
+
+/*
+** These need to go here, after flex-generated code defined input and unput.
+*/
+
+int cscanner_input (void)
+{
+ return input (); /* input is a static procedure defined by flex-generated code */
+}
+
+void cscanner_unput (int c)
+{
+ unput (c); /* unput is a static procedure defined by flex-generated code */
+}
+
+
+