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