2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 ** Massachusetts Institute of Technology
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on splint: splint@cs.virginia.edu
21 ** To report a bug: splint-bug@cs.virginia.edu
22 ** For more information: http://www.splint.org
28 ** Based on a C lexer by Nate Osgood
29 ** from hacrat@catfish.lcs.mit.edu Mon Jun 14 13:06:32 1993
32 ** Modified by Mike Smith
33 ** Corrected missing 'line' in scanf() calls in handleSpecial().
34 ** Without this, I get an error when Splint hits a '#line' directive
35 ** in the pre-pre-processed source files.
37 ** Modified by Mike Smith, 4th June 1997
38 ** Finally resolved the #line problem. The scanf() calls have been fixed to
39 ** allow the following #line forms:-
41 ** #line 123 "filename"
46 ** The last two are generated by the GNU pre-processor, apparently
57 ULSuffix ({U}{L}|{L}{U})
58 ConstStr \"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")*
61 # include "splintMacros.nf"
64 # include "cscannerHelp.h"
65 # include "cgrammar.h"
68 # define yyinput() (incColumn (), getc (yyin))
75 %option never-interactive
78 /* prefix option above would transform outfile to "lex.c_.c";
79 * sadly, auto{conf,make} expect "lex.yy.c" */
80 %option outfile="lex.yy.c"
86 "/*" { llfatalerror (cstring_makeLiteral ("Comment in pre-processor output")); }
88 "#"{Letter}({Letter}|{Digit})* {
89 context_saveLocation ();
90 cscannerHelp_setTokLengthT (mstring_length (yytext));
92 if (cscannerHelp_processHashIdentifier
93 (cscannerHelp_makeIdentifier (yytext + 1)))
95 return cscannerHelp_returnString (cstring_makeLiteral (""));
99 if (cscannerHelp_handleSpecial (yytext))
101 return cscannerHelp_returnTokenLength (0, 1);
105 "#" { if (cscannerHelp_handleSpecial (yytext))
107 return cscannerHelp_returnTokenLength (0, 1);
110 "..." { return cscannerHelp_returnTokenLength (CTOK_ELIPSIS, 3); }
111 "break" { return cscannerHelp_returnTokenLength (BREAK, 5); }
112 "case" { return cscannerHelp_returnTokenLength (CASE, 4); }
113 "continue" { return cscannerHelp_returnTokenLength (CONTINUE, 8); }
114 "default" { return cscannerHelp_returnTokenLength (DEFAULT, 7); }
115 "do" { return cscannerHelp_returnTokenLength (DO, 2); }
116 "else" { return cscannerHelp_returnTokenLength (CELSE, 4); }
117 "for" { return cscannerHelp_returnTokenLength (CFOR, 3); }
118 "goto" { return cscannerHelp_returnTokenLength (GOTO, 4); }
119 "if" { return cscannerHelp_returnTokenLength (CIF, 2); }
120 "return" { return cscannerHelp_returnTokenLength (RETURN, 6); }
121 "sizeof" { return cscannerHelp_returnTokenLength (CSIZEOF, 6); }
122 "offsetof" { return cscannerHelp_returnTokenLength (COFFSETOF, 8); }
123 "switch" { return cscannerHelp_returnTokenLength (SWITCH, 6); }
124 "while" { return cscannerHelp_returnTokenLength (WHILE, 5); }
125 "va_arg" { return cscannerHelp_returnTokenLength (VA_ARG, 6); }
126 "va_dcl" { return cscannerHelp_returnTokenLength (VA_DCL, 6); }
127 "inline" { return cscannerHelp_returnTokenLength (QINLINE, 6); }
129 "struct" { return cscannerHelp_returnTokenLength (CSTRUCT, 6); }
130 "union" { return cscannerHelp_returnTokenLength (CUNION, 5); }
131 "enum" { return cscannerHelp_returnTokenLength (CENUM, 4); }
132 "typedef" { return cscannerHelp_returnTokenLength (CTYPEDEF, 7); }
134 "void" { cscannerHelp_setTokLength (4); return cscannerHelp_returnType (CVOID, ctype_void); }
135 "int" { cscannerHelp_setTokLength (3); return cscannerHelp_returnType (CINT, ctype_int); }
136 "double" { cscannerHelp_setTokLength (6); return cscannerHelp_returnType (CDOUBLE, ctype_double); }
137 "char" { cscannerHelp_setTokLength (4); return cscannerHelp_returnType (CGCHAR, ctype_char); }
138 "float" { cscannerHelp_setTokLength (5); return cscannerHelp_returnType (CGFLOAT, ctype_float); }
140 "long" { return cscannerHelp_returnTokenLength (QLONG, 4); }
141 "short" { return cscannerHelp_returnTokenLength (QSHORT, 5); }
142 "unsigned" { return cscannerHelp_returnTokenLength (QUNSIGNED, 8); }
143 "signed" { return cscannerHelp_returnTokenLength (QSIGNED, 6); }
145 "volatile" { return cscannerHelp_returnTokenLength (QVOLATILE, 8); }
146 "const" { return cscannerHelp_returnTokenLength (QCONST, 5); }
147 "restrict" { return cscannerHelp_returnTokenLength (QRESTRICT, 8); }
149 "extern" { return cscannerHelp_returnTokenLength (QEXTERN, 6); }
150 "auto" { return cscannerHelp_returnTokenLength (QAUTO, 4); }
151 "register" { return cscannerHelp_returnTokenLength (QREGISTER, 8); }
152 "static" { return cscannerHelp_returnTokenLength (QSTATIC, 6); }
154 "__func__" { cscannerHelp_setTokLength (8); return cscannerHelp_returnFunctionName (yytext); }
156 {ConstStr} { return cscannerHelp_returnExpr (cscannerHelp_processString ()); }
157 L{ConstStr} { return cscannerHelp_returnExpr (cscannerHelp_processWideString ()); }
159 "out" { return (cscannerHelp_processSpec (QOUT)); }
160 "in" { return (cscannerHelp_processSpec (QIN)); }
161 "partial" { return (cscannerHelp_processSpec (QPARTIAL)); }
162 "special" { return (cscannerHelp_processSpec (QSPECIAL)); }
163 "anytype" { return (cscannerHelp_processSpec (QANYTYPE)); }
164 "integraltype" { return (cscannerHelp_processSpec (QINTEGRALTYPE)); }
165 "unsignedintegraltype" { return (cscannerHelp_processSpec (QUNSIGNEDINTEGRALTYPE)); }
166 "signedintegraltype" { return (cscannerHelp_processSpec (QSIGNEDINTEGRALTYPE)); }
167 "keep" { return (cscannerHelp_processSpec (QKEEP)); }
168 "null" { return (cscannerHelp_processSpec (QNULL)); }
169 "notnull" { return (cscannerHelp_processSpec (QNOTNULL)); }
170 "isnull" { return (cscannerHelp_processSpec (QISNULL)); }
171 "truenull" { return (cscannerHelp_processSpec (QTRUENULL)); }
172 "falsenull" { return (cscannerHelp_processSpec (QFALSENULL)); }
173 "nullwhentrue" { return (cscannerHelp_processSpec (QTRUENULL)); }
174 "nullwhenfalse" { return (cscannerHelp_processSpec (QFALSENULL)); }
175 "relnull" { return (cscannerHelp_processSpec (QRELNULL)); }
176 "reldef" { return (cscannerHelp_processSpec (QRELDEF)); }
177 "exposed" { return (cscannerHelp_processSpec (QEXPOSED)); }
178 "newref" { return (cscannerHelp_processSpec (QNEWREF)); }
179 "tempref" { return (cscannerHelp_processSpec (QTEMPREF)); }
180 "killref" { return (cscannerHelp_processSpec (QKILLREF)); }
181 "refcounted" { return (cscannerHelp_processSpec (QREFCOUNTED)); }
182 "checked" { return (cscannerHelp_processSpec (QCHECKED)); }
183 "checkmod" { return (cscannerHelp_processSpec (QCHECKMOD)); }
184 "checkedstrict" { return (cscannerHelp_processSpec (QCHECKEDSTRICT)); }
185 "unchecked" { return (cscannerHelp_processSpec (QUNCHECKED)); }
186 "only" { return (cscannerHelp_processSpec (QONLY)); }
187 "owned" { return (cscannerHelp_processSpec (QOWNED)); }
188 "observer" { return (cscannerHelp_processSpec (QOBSERVER)); }
189 "dependent" { return (cscannerHelp_processSpec (QDEPENDENT)); }
190 "unused" { return (cscannerHelp_processSpec (QUNUSED)); }
191 "external" { return (cscannerHelp_processSpec (QEXTERNAL)); }
192 "sef" { return (cscannerHelp_processSpec (QSEF)); }
193 "shared" { return (cscannerHelp_processSpec (QSHARED)); }
194 "yield" { return (cscannerHelp_processSpec (QYIELD)); }
195 "undef" { return (cscannerHelp_processSpec (QUNDEF)); }
196 "killed" { return (cscannerHelp_processSpec (QKILLED)); }
197 "nullterminated" { return (cscannerHelp_processSpec (QNULLTERMINATED));}
198 "MaxSet" { return (cscannerHelp_processSpec (QMAXSET));}
199 "MaxRead" { return (cscannerHelp_processSpec (QMAXREAD));}
200 "maxSet" { return (cscannerHelp_processSpec (QMAXSET));}
201 "maxRead" { return (cscannerHelp_processSpec (QMAXREAD));}
203 {Letter}({Letter}|{Digit})* { int tok = cscannerHelp_processTextIdentifier (yytext);
209 0[xX]{H}+ { cscannerHelp_setTokLengthT (mstring_length (yytext));
210 return cscannerHelp_returnInt (ctype_int, cscannerHelp_processHex ()); }
211 0[xX]{H}+{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
212 return cscannerHelp_returnInt (ctype_lint, cscannerHelp_processHex ()); }
213 0[xX]{H}+{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
214 return cscannerHelp_returnInt (ctype_llint, cscannerHelp_processHex ()); }
215 0[xX]{H}+{U} { cscannerHelp_setTokLengthT (mstring_length (yytext));
216 return cscannerHelp_returnInt (ctype_uint, cscannerHelp_processHex ()); }
217 0[xX]{H}+{ULSuffix} { cscannerHelp_setTokLengthT (mstring_length (yytext));
218 return cscannerHelp_returnInt (ctype_ulint, cscannerHelp_processHex ()); }
219 0[xX]{H}+{U}{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
220 return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processHex ()); }
221 0[xX]{H}+{L}{L}{U} { cscannerHelp_setTokLengthT (mstring_length (yytext));
222 return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processHex ()); }
223 0{Digit}+ { cscannerHelp_setTokLengthT (mstring_length (yytext));
224 return cscannerHelp_returnInt (ctype_int, cscannerHelp_processOctal ()); }
225 0{Digit}+{U} { cscannerHelp_setTokLengthT (mstring_length (yytext));
226 return cscannerHelp_returnInt (ctype_uint, cscannerHelp_processOctal ()); }
227 0{Digit}+{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
228 return cscannerHelp_returnInt (ctype_lint, cscannerHelp_processOctal ()); }
229 0{Digit}+{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
230 return cscannerHelp_returnInt (ctype_llint, cscannerHelp_processOctal ()); }
231 0{Digit}+{ULSuffix} { cscannerHelp_setTokLengthT (mstring_length (yytext));
232 return cscannerHelp_returnInt (ctype_ulint, cscannerHelp_processOctal ()); }
233 0{Digit}+{U}{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
234 return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processOctal ()); }
235 0{Digit}+{L}{L}{U} { cscannerHelp_setTokLengthT (mstring_length (yytext));
236 return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processOctal ()); }
237 {Digit}+ { cscannerHelp_setTokLengthT (mstring_length (yytext));
238 return cscannerHelp_returnInt (ctype_int, cscannerHelp_processDec ()); }
239 {Digit}+{U} { cscannerHelp_setTokLengthT (mstring_length (yytext));
240 return cscannerHelp_returnInt (ctype_uint, cscannerHelp_processDec ()); }
241 {Digit}+{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
242 return cscannerHelp_returnInt (ctype_lint, cscannerHelp_processDec ()); }
243 {Digit}+{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
244 return cscannerHelp_returnInt (ctype_llint, cscannerHelp_processDec ()); }
245 {Digit}+{ULSuffix} { cscannerHelp_setTokLengthT (mstring_length (yytext));
246 return cscannerHelp_returnInt (ctype_ulint, cscannerHelp_processDec ()); }
247 {Digit}+{U}{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext));
248 return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processDec ()); }
249 {Digit}+{L}{L}{U} { cscannerHelp_setTokLengthT (mstring_length (yytext));
250 return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processDec ()); }
251 '(\\.|[^\\'])+' { cscannerHelp_setTokLengthT (mstring_length (yytext));
252 return cscannerHelp_returnChar (cscannerHelp_processChar ()); }
253 L'(\\.|[^\\'])+' { cscannerHelp_setTokLengthT (mstring_length (yytext));
254 return cscannerHelp_returnChar (cscannerHelp_processChar ()); }
255 {Digit}+{E}[fF] { cscannerHelp_setTokLengthT (mstring_length (yytext));
256 return cscannerHelp_returnFloat (ctype_float, cscannerHelp_processFloat ()); }
257 {Digit}+{E}[lL] { cscannerHelp_setTokLengthT (mstring_length (yytext));
258 return cscannerHelp_returnFloat (ctype_ldouble, cscannerHelp_processFloat ()); }
259 {Digit}+{E} { cscannerHelp_setTokLengthT (mstring_length (yytext));
260 return cscannerHelp_returnFloat (ctype_double, cscannerHelp_processFloat ()); }
262 {Digit}*"."{Digit}+({E})?[fF] { cscannerHelp_setTokLengthT (mstring_length (yytext));
263 return cscannerHelp_returnFloat (ctype_float, cscannerHelp_processFloat ()); }
264 {Digit}*"."{Digit}+({E})?[lL] { cscannerHelp_setTokLengthT (mstring_length (yytext));
265 return cscannerHelp_returnFloat (ctype_ldouble, cscannerHelp_processFloat ()); }
266 {Digit}*"."{Digit}+({E})? { cscannerHelp_setTokLengthT (mstring_length (yytext));
267 return cscannerHelp_returnFloat (ctype_double, cscannerHelp_processFloat ()); }
269 {Digit}+"."{Digit}*({E})?[fF] { cscannerHelp_setTokLengthT (mstring_length (yytext));
270 return cscannerHelp_returnFloat (ctype_float, cscannerHelp_processFloat ()); }
271 {Digit}+"."{Digit}*({E})?[lL] { cscannerHelp_setTokLengthT (mstring_length (yytext));
272 return cscannerHelp_returnFloat (ctype_ldouble, cscannerHelp_processFloat ()); }
273 {Digit}+"."{Digit}*({E})? { cscannerHelp_setTokLengthT (mstring_length (yytext));
274 return cscannerHelp_returnFloat (ctype_double, cscannerHelp_processFloat ()); }
276 ">>=" { return cscannerHelp_returnTokenLength (RIGHT_ASSIGN, 3); }
277 "<<=" { return cscannerHelp_returnTokenLength (LEFT_ASSIGN, 3); }
278 "+=" { return cscannerHelp_returnTokenLength (ADD_ASSIGN, 2); }
279 "-=" { return cscannerHelp_returnTokenLength (SUB_ASSIGN, 2); }
280 "*=" { return cscannerHelp_returnTokenLength (MUL_ASSIGN, 2); }
281 "/=" { return cscannerHelp_returnTokenLength (DIV_ASSIGN, 2); }
282 "%=" { return cscannerHelp_returnTokenLength (MOD_ASSIGN, 2); }
283 "&=" { return cscannerHelp_returnTokenLength (AND_ASSIGN, 2); }
284 "^=" { return cscannerHelp_returnTokenLength (XOR_ASSIGN, 2); }
285 "|=" { return cscannerHelp_returnTokenLength (OR_ASSIGN, 2); }
286 ">>" { return cscannerHelp_returnTokenLength (RIGHT_OP, 2); }
287 "<<" { return cscannerHelp_returnTokenLength (LEFT_OP, 2); }
288 "++" { return cscannerHelp_returnTokenLength (INC_OP, 2); }
289 "--" { return cscannerHelp_returnTokenLength (DEC_OP, 2); }
290 "->" { return cscannerHelp_returnTokenLength (ARROW_OP, 2); }
291 "&&" { return cscannerHelp_returnTokenLength (AND_OP, 2); }
292 "||" { return cscannerHelp_returnTokenLength (OR_OP, 2); }
293 "/\\" { return cscannerHelp_returnTokenLength (TCAND, 2); }
294 "<=" { return cscannerHelp_returnTokenLength (LE_OP, 2); }
295 ">=" { return cscannerHelp_returnTokenLength (GE_OP, 2); }
296 "==" { return cscannerHelp_returnTokenLength (EQ_OP, 2); }
297 "!=" { return cscannerHelp_returnTokenLength (NE_OP, 2); }
298 ";" { return cscannerHelp_returnTokenLength (TSEMI, 1); }
299 "{" { return cscannerHelp_returnTokenLength (TLBRACE, 1); }
300 "}" { return cscannerHelp_returnTokenLength (TRBRACE, 1); }
301 "," { return cscannerHelp_returnTokenLength (TCOMMA, 1); }
302 ":" { return cscannerHelp_returnTokenLength (TCOLON, 1); }
303 "=" { return cscannerHelp_returnTokenLength (TASSIGN, 1); }
304 "(" { return cscannerHelp_returnTokenLength (TLPAREN, 1); }
305 ")" { return cscannerHelp_returnTokenLength (TRPAREN, 1); }
306 "[" { return cscannerHelp_returnTokenLength (TLSQBR, 1); }
307 "]" { return cscannerHelp_returnTokenLength (TRSQBR, 1); }
308 "." { return cscannerHelp_returnTokenLength (TDOT, 1); }
309 "&" { return cscannerHelp_returnTokenLength (TAMPERSAND, 1); }
310 "!" { return cscannerHelp_returnTokenLength (TEXCL, 1); }
311 "~" { return cscannerHelp_returnTokenLength (TTILDE, 1); }
312 "-" { return cscannerHelp_returnTokenLength (TMINUS, 1); }
313 "+" { return cscannerHelp_returnTokenLength (TPLUS, 1); }
314 "*" { return cscannerHelp_returnTokenLength (TMULT, 1); }
315 "/" { return cscannerHelp_returnTokenLength (TDIV, 1); }
316 "%" { return cscannerHelp_returnTokenLength (TPERCENT, 1); }
317 "<" { return cscannerHelp_returnTokenLength (TLT, 1); }
318 ">" { return cscannerHelp_returnTokenLength (TGT, 1); }
319 "^" { return cscannerHelp_returnTokenLength (TCIRC, 1); }
320 "|" { return cscannerHelp_returnTokenLength (TBAR, 1); }
321 "?" { return cscannerHelp_returnTokenLength (TQUEST, 1); }
323 [ \t\v\f] { incColumn (); }
324 \n { int tok = cscannerHelp_handleNewLine ();
325 if (tok != BADTOK) return tok; }
326 "@@MR@@" { cscannerHelp_setTokLength (6);
328 if (cscannerHelp_processMacro ()) {
329 if (context_inIterDef ())
331 return cscannerHelp_returnToken (LLMACROITER);
333 if (context_inIterEnd ())
335 return cscannerHelp_returnToken (LLMACROEND);
337 if (context_inMacro ())
339 return cscannerHelp_returnToken (LLMACRO);
343 "@QLMR" { if (context_inHeader () || context_inFunction ())
345 cscannerHelp_handleMacro ();
349 int nspchar = cscannerHelp_ninput ();
353 ** This is a hack to get the column number correct.
356 llassert (nspchar >= '0' && nspchar <= '9');
358 nspaces = nspchar - '0';
360 cscannerHelp_setTokLength (5 + nspaces);
362 if (cscannerHelp_processMacro ())
364 DPRINTF (("Here we are: %s", context_unparse ()));
366 if (context_inIterDef ())
368 return cscannerHelp_returnToken (LLMACROITER);
370 if (context_inIterEnd ())
372 return cscannerHelp_returnToken (LLMACROEND);
374 if (context_inMacro ())
376 return cscannerHelp_returnToken (LLMACRO);
381 "@.CT" { cscannerHelp_setTokLength (4); lldiagmsg (ctype_unparseTable ()); }
382 "@.FA" { cscannerHelp_setTokLength (4); lldiagmsg (message ("Access types: %q", typeIdSet_unparse (context_fileAccessTypes ()))); }
383 "@.F" { cscannerHelp_setTokLength (3);
384 lldiagmsg (message ("%q: *** marker ***", fileloc_unparse (g_currentloc)));
386 "@.L" { cscannerHelp_setTokLength (3); usymtab_printLocal (); }
387 "@.A" { cscannerHelp_setTokLength (3); lldiagmsg (usymtab_unparseAliases ()); }
388 "@.C" { cscannerHelp_setTokLength (3); lldiagmsg (context_unparse ()); }
389 "@.W" { cscannerHelp_setTokLength (3); lldiagmsg (context_unparseClauses ()); }
390 "@.G" { cscannerHelp_setTokLength (3); usymtab_printGuards (); }
391 "@.S" { cscannerHelp_setTokLength (3); usymtab_printOut (); }
392 "@.X" { cscannerHelp_setTokLength (3); usymtab_printAll (); }
393 "@.Z" { cscannerHelp_setTokLength (3); usymtab_printComplete (); }
394 "@.T" { cscannerHelp_setTokLength (3); usymtab_printTypes (); }
395 "@.K" { cscannerHelp_setTokLength (3); lldiagmsg (usymtab_unparseStack ()); }
396 "@.R" { cscannerHelp_setTokLength (3); return cscannerHelp_returnToken (QDREVEALSTATE); }
397 "@.M" { cscannerHelp_setTokLength (3);
398 lldiagmsg (message ("Can modify: %q",
399 sRefSet_unparse (context_modList ())));
401 "%{" { /* BEFORE_COMMENT_MARKER */
403 incColumn (); incColumn ();
404 tok = cscannerHelp_handleLlSpecial ();
408 if (tok == CANNOTATION) {
411 /* Beware - this bashes yylval! */
412 return cscannerHelp_returnToken (tok);
416 "%}" { /* AFTER_COMMENT_MARKER */
417 cscannerHelp_exitSpecPart ();
418 return cscannerHelp_returnTokenLength (QENDMACRO, 2); }
419 "\\" { incColumn (); cscannerHelp_setContinueLine (); }
421 if ((int) *yytext == 13 ) {
426 message ("Invalid character (ascii: %d), skipping character",
434 ** These need to go here, after flex-generated code defined input and unput.
437 int cscanner_input (void)
439 return input (); /* input is a static procedure defined by flex-generated code */
442 void cscanner_unput (int c)
444 unput (c); /* unput is a static procedure defined by flex-generated code */