]> andersk Git - splint.git/blame - src/cscanner.l
Apparently splint does not correctly handle the case in which a #defined constant...
[splint.git] / src / cscanner.l
CommitLineData
ac0860d8 1/*;-*-C-*-;
11db3170 2** Splint - annotation-assisted static program checker
1b8ae690 3** Copyright (C) 1994-2002 University of Virginia,
11db3170 4** Massachusetts Institute of Technology
ac0860d8 5**
11db3170 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.
10**
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.
15**
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.
ac0860d8 19**
1b8ae690 20** For information on splint: splint@cs.virginia.edu
21** To report a bug: splint-bug@cs.virginia.edu
11db3170 22** For more information: http://www.splint.org
23*/
24/*
25** cscanner.l
ac0860d8 26**
11db3170 27** Flex lexer for C.
28** Based on a C lexer by Nate Osgood
29** from hacrat@catfish.lcs.mit.edu Mon Jun 14 13:06:32 1993
ac0860d8 30*/
31/*
11db3170 32** Modified by Herbert 08/19/97:
33** - added #include for IBM's OS/2 compiler.
34** - fixed weird bug with lookup of tmp files (OS/2 and MSDOS only).
35*/
ac0860d8 36/*
11db3170 37** Modified by Mike Smith
38** Corrected missing 'line' in scanf() calls in handleSpecial().
1b8ae690 39** Without this, I get an error when Splint hits a '#line' directive
11db3170 40** in the pre-pre-processed source files. For safety, I have made these
41** conditional on OS2 and MSDOS because I don't understand why noone else
42** has seen this problem.
43**
44** Modified by Mike Smith, 4th June 1997
45** Finally resolved the #line problem. The scanf() calls have been fixed to
46** allow the following #line forms:-
47**
48** #line 123 "filename"
49** #line 123
50** # 123 "filename"
51** # 123
52**
53** The last two are generated by the GNU pre-processor, apparently
54*/
ac0860d8 55
56Digit [0-9]
57Letter [a-zA-Z_$]
58H [a-fA-F0-9]
59E [Ee][+-]?{Digit}+
60U (u|U)
61L (l|L)
62FS (f|F|l|L)
63IS (u|U|l|L)*
64ULSuffix ({U}{L}|{L}{U})
65
66%{
1b8ae690 67# include "splintMacros.nf"
9622303f 68# if defined(OS2) && defined(__IBMC__)
69 /* needed for isatty()... */
70# include <io.h>
71# else
4dd72714 72
73/*
74** Win32 doesn't have unistd.h
75*/
76
77# ifndef WIN32
ac0860d8 78# include <unistd.h>
9622303f 79# endif
80
4dd72714 81# endif
82
ac0860d8 83# include "basic.h"
84
85# include "cgrammar.h"
86# include "cgrammar_tokens.h"
ac0860d8 87# include "portab.h"
88
ac0860d8 89static bool lastWasString = FALSE;
90static char savechar = '\0';
91
92/*@notfunction@*/
93# define yyinput() (incColumn (), getc (yyin))
94
95static /*@owned@*/ cstring lastidprocessed = cstring_undefined;
96static int lminput (void);
97static int tokLength = 0;
98static bool inSpecPart = FALSE;
99static bool continueLine = FALSE;
100
101static int ninput (void);
102static char processChar (void);
103static double processFloat (void);
e0b363ad 104static /*@only@*/ exprNode processString (void) ;
105static /*@only@*/ exprNode processWideString (void) ;
ac0860d8 106static long processDec (void);
107static long processHex (void);
108static long processOctal (void);
109static int processIdentifier (/*@only@*/ cstring)
110 /*@globals undef lastidprocessed@*/ ;
111static bool processHashIdentifier (/*@only@*/ cstring)
112 /*@globals undef lastidprocessed@*/ ;
113
114static int processSpec (int);
115static bool handleSpecial (char *);
116static int handleLlSpecial (void);
117static void handleMacro (void);
118static bool processMacro (void);
119static /*@only@*/ cstring makeIdentifier (char *);
120
121/* yes, this is exported! */
122bool g_expectingTypeName = TRUE; /* beginning of file can be type name! */
123
124static bool expectingMetaStateName = FALSE;
125
126static int returnInt (ctype, long);
127static int returnFloat (ctype, double);
128static int returnChar (char);
129static void setTokLength (int) /*@modifies g_currentloc@*/ ;
130static void setTokLengthT (size_t) /*@modifies g_currentloc@*/ ;
131
132static void advanceLine (void)
133{
134 tokLength = 0;
135 beginLine ();
136}
137
138/*@-allmacros@*/
139# define RETURN_INT(c,i) \
140 do { lastWasString = FALSE; \
141 return (returnInt (c, i)); } while (FALSE)
142
143# define RETURN_FLOAT(c,f) \
144 do { lastWasString = FALSE; \
145 return (returnFloat (c, f)); \
146 } while (FALSE)
147
148# define RETURN_CHAR(c) \
149 do { lastWasString = FALSE; \
150 return (returnChar (c)); \
151 } while (FALSE)
152
153# define RETURN_TOK(t) \
154 do { yylval.tok = lltok_create (t, fileloc_decColumn (g_currentloc, tokLength)); \
155 tokLength = 0; \
156 lastWasString = FALSE; \
157 return (t); } while (FALSE)
158
159# define RETURN_TYPE(t, ct) \
160 do { yylval.ctyp = ct; tokLength = 0; return (t); } while (FALSE)
161
162/* don't fileloc_decColumn (g_currentloc, tokLength));
163 the string could have \n's in it!
164*/
165
166# define RETURN_STRING(c) \
167 do { yylval.expr = exprNode_stringLiteral (c, fileloc_decColumn (g_currentloc, tokLength)); \
168 tokLength = 0; \
169 lastWasString = TRUE; \
170 return (CCONSTANT); } while (FALSE)
171
172# define RETURN_EXPR(e) \
173 do { yylval.expr = e; \
174 tokLength = 0; \
175 lastWasString = TRUE; \
176 return (CCONSTANT); } while (FALSE)
177
178/*@=allmacros@*/
179
180static void setTokLength (int len)
181{
182 addColumn (len);
183 tokLength = len;
184 DPRINTF (("Set tok length: %d", len));
185}
186
187static void setTokLengthT (size_t len)
188{
189 setTokLength (size_toInt (len));
190}
191
192# include "flex.head"
193
194/*@-unrecog@*/ /*@i5343@*/
195
196%}
197
198%%
199
b87215ab 200"/*" { llfatalerror (cstring_makeLiteral ("Comment in pre-processor output")); }
ac0860d8 201
202"#"{Letter}({Letter}|{Digit})* {
203 context_saveLocation ();
204 setTokLength (longUnsigned_toInt (mstring_length (yytext)));
205
206 if (processHashIdentifier (makeIdentifier (yytext + 1)))
207 {
208 if (lastWasString)
209 {
210 /* was nothing! */ /*@i32@*/
211 RETURN_STRING (cstring_makeLiteral ("\"\""));
212 }
213 else
214 {
215 RETURN_STRING (cstring_makeLiteral ("\"\""));
216 }
217 }
218 else
219 {
220 if (handleSpecial (yytext))
221 {
222 setTokLength (1);
223 RETURN_TOK (0);
224 }
225 }
226 }
227"#" { if (handleSpecial (yytext))
228 {
229 setTokLength (1); RETURN_TOK (0);
230 }
231 }
232"..." { setTokLength (3); RETURN_TOK (CTOK_ELIPSIS); }
233"break" { setTokLength (5); RETURN_TOK (BREAK); }
234"case" { setTokLength (4); RETURN_TOK (CASE); }
235"continue" { setTokLength (8); RETURN_TOK (CONTINUE); }
236"default" { setTokLength (7); RETURN_TOK (DEFAULT); }
237"do" { setTokLength (2); RETURN_TOK (DO); }
238"else" { setTokLength (4); RETURN_TOK (CELSE); }
239"for" { setTokLength (3); RETURN_TOK (CFOR); }
240"goto" { setTokLength (4); RETURN_TOK (GOTO); }
241"if" { setTokLength (2); RETURN_TOK (CIF); }
242"return" { setTokLength (6); RETURN_TOK (RETURN); }
243"sizeof" { setTokLength (6); RETURN_TOK (CSIZEOF); }
244"offsetof" { setTokLength (8); RETURN_TOK (COFFSETOF); }
245"switch" { setTokLength (6); RETURN_TOK (SWITCH); }
246"while" { setTokLength (5); RETURN_TOK (WHILE); }
247"va_arg" { setTokLength (6); RETURN_TOK (VA_ARG); }
248"va_dcl" { setTokLength (6); RETURN_TOK (VA_DCL); }
249"inline" {
250 /* gcc extension...this might not be appropriate */
251 setTokLength (6); RETURN_TOK (QINLINE); }
252
253"struct" { setTokLength (6); RETURN_TOK (CSTRUCT); }
254"typedef" { setTokLength (7); RETURN_TOK (CTYPEDEF); }
255
256"union" { setTokLength (5); RETURN_TOK (CUNION); }
257"enum" { setTokLength (4); RETURN_TOK (CENUM); }
258
259"void" { setTokLength (4); RETURN_TYPE (CVOID, ctype_void); }
260"int" { setTokLength (3); RETURN_TYPE (CINT, ctype_int); }
261"double" { setTokLength (6); RETURN_TYPE (CDOUBLE, ctype_double); }
262"char" { setTokLength (4); RETURN_TYPE (CGCHAR, ctype_char); }
263"float" { setTokLength (5); RETURN_TYPE (CGFLOAT, ctype_float); }
264
265"long" { setTokLength (4); RETURN_TOK (QLONG); }
266"short" { setTokLength (5); RETURN_TOK (QSHORT); }
267"unsigned" { setTokLength (8); RETURN_TOK (QUNSIGNED); }
268"signed" { setTokLength (6); RETURN_TOK (QSIGNED); }
269
270"volatile" { setTokLength (8); RETURN_TOK (QVOLATILE); }
271"const" { setTokLength (5); RETURN_TOK (QCONST); }
272
273 /* some systems expect this! [gack!] */
274"__const" { setTokLength (7); RETURN_TOK (QCONST); }
275
276"extern" { setTokLength (6); RETURN_TOK (QEXTERN); }
277"auto" { setTokLength (4); RETURN_TOK (QAUTO); }
278"register" { setTokLength (8); RETURN_TOK (QREGISTER); }
279"static" { setTokLength (6); RETURN_TOK (QSTATIC); }
280
281\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { RETURN_EXPR (processString ()); }
e0b363ad 282L\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { RETURN_EXPR (processWideString ()); }
ac0860d8 283"out" { return (processSpec (QOUT)); }
284"in" { return (processSpec (QIN)); }
285"partial" { return (processSpec (QPARTIAL)); }
286"special" { return (processSpec (QSPECIAL)); }
287"anytype" { return (processSpec (QANYTYPE)); }
288"integraltype" { return (processSpec (QINTEGRALTYPE)); }
289"unsignedintegraltype" { return (processSpec (QUNSIGNEDINTEGRALTYPE)); }
290"signedintegraltype" { return (processSpec (QSIGNEDINTEGRALTYPE)); }
291"keep" { return (processSpec (QKEEP)); }
292"null" { return (processSpec (QNULL)); }
293"notnull" { return (processSpec (QNOTNULL)); }
294"isnull" { return (processSpec (QISNULL)); }
295"truenull" { return (processSpec (QTRUENULL)); }
296"falsenull" { return (processSpec (QFALSENULL)); }
0e41eb0e 297"nullwhentrue" { return (processSpec (QTRUENULL)); }
298"nullwhenfalse" { return (processSpec (QFALSENULL)); }
ac0860d8 299"relnull" { return (processSpec (QRELNULL)); }
300"reldef" { return (processSpec (QRELDEF)); }
301"exposed" { return (processSpec (QEXPOSED)); }
302"newref" { return (processSpec (QNEWREF)); }
303"tempref" { return (processSpec (QTEMPREF)); }
304"killref" { return (processSpec (QKILLREF)); }
305"refcounted" { return (processSpec (QREFCOUNTED)); }
306"checked" { return (processSpec (QCHECKED)); }
307"checkmod" { return (processSpec (QCHECKMOD)); }
308"checkedstrict" { return (processSpec (QCHECKEDSTRICT)); }
309"unchecked" { return (processSpec (QUNCHECKED)); }
310"only" { return (processSpec (QONLY)); }
311"owned" { return (processSpec (QOWNED)); }
312"observer" { return (processSpec (QOBSERVER)); }
313"dependent" { return (processSpec (QDEPENDENT)); }
314"unused" { return (processSpec (QUNUSED)); }
315"external" { return (processSpec (QEXTERNAL)); }
316"sef" { return (processSpec (QSEF)); }
317"shared" { return (processSpec (QSHARED)); }
318"yield" { return (processSpec (QYIELD)); }
319"undef" { return (processSpec (QUNDEF)); }
320"killed" { return (processSpec (QKILLED)); }
321"nullterminated" { return (processSpec (QNULLTERMINATED));}
322"MaxSet" { return (processSpec (QMAXSET));}
323"MaxRead" { return (processSpec (QMAXREAD));}
324"maxSet" { return (processSpec (QMAXSET));}
325"maxRead" { return (processSpec (QMAXREAD));}
326
327{Letter}({Letter}|{Digit})* { int tok;
328 context_saveLocation ();
329 setTokLength (longUnsigned_toInt (mstring_length (yytext)));
330 tok = processIdentifier (makeIdentifier (yytext));
331 if (tok != BADTOK)
332 {
333 return (tok);
334 }
335 }
3360[xX]{H}+ { setTokLengthT (mstring_length (yytext));
337 RETURN_INT (ctype_int, processHex ()); /* evs 2000-05-17 was ctype_uint */
338 }
3390[xX]{H}+{L} { setTokLengthT (mstring_length (yytext));
340 RETURN_INT (ctype_lint, processHex ()); }
3410[xX]{H}+{L}{L} { setTokLengthT (mstring_length (yytext));
342 RETURN_INT (ctype_llint, processHex ()); }
3430[xX]{H}+{U} { setTokLengthT (mstring_length (yytext));
344 RETURN_INT (ctype_uint, processHex ()); }
3450[xX]{H}+{ULSuffix} { setTokLengthT (mstring_length (yytext));
346 RETURN_INT (ctype_ulint, processHex ()); }
3470[xX]{H}+{U}{L}{L} { setTokLengthT (mstring_length (yytext));
348 RETURN_INT (ctype_ullint, processHex ()); }
3490[xX]{H}+{L}{L}{U} { setTokLengthT (mstring_length (yytext));
350 RETURN_INT (ctype_ullint, processHex ()); }
3510{Digit}+ { setTokLengthT (mstring_length (yytext));
352 RETURN_INT (ctype_int, processOctal ()); }
3530{Digit}+{U} { setTokLengthT (mstring_length (yytext));
354 RETURN_INT (ctype_uint, processOctal ()); }
3550{Digit}+{L} { setTokLengthT (mstring_length (yytext));
356 RETURN_INT (ctype_lint, processOctal ()); }
3570{Digit}+{L}{L} { setTokLengthT (mstring_length (yytext));
358 RETURN_INT (ctype_llint, processOctal ()); }
3590{Digit}+{ULSuffix} { setTokLengthT (mstring_length (yytext));
360 RETURN_INT (ctype_ulint, processOctal ()); }
3610{Digit}+{U}{L}{L} { setTokLengthT (mstring_length (yytext));
362 RETURN_INT (ctype_ullint, processOctal ()); }
3630{Digit}+{L}{L}{U} { setTokLengthT (mstring_length (yytext));
364 RETURN_INT (ctype_ullint, processOctal ()); }
365{Digit}+ { setTokLengthT (mstring_length (yytext));
366 RETURN_INT (ctype_int, processDec ()); }
367{Digit}+{U} { setTokLengthT (mstring_length (yytext));
368 RETURN_INT (ctype_uint, processDec ()); }
369{Digit}+{L} { setTokLengthT (mstring_length (yytext));
370 RETURN_INT (ctype_lint, processDec ()); }
371{Digit}+{L}{L} { setTokLengthT (mstring_length (yytext));
372 RETURN_INT (ctype_llint, processDec ()); }
373{Digit}+{ULSuffix} { setTokLengthT (mstring_length (yytext));
374 RETURN_INT (ctype_ulint, processDec ()); }
375{Digit}+{U}{L}{L} { setTokLengthT (mstring_length (yytext));
376 RETURN_INT (ctype_ullint, processDec ()); }
377{Digit}+{L}{L}{U} { setTokLengthT (mstring_length (yytext));
378 RETURN_INT (ctype_ullint, processDec ()); }
379'(\\.|[^\\'])+' { setTokLengthT (mstring_length (yytext));
380 RETURN_CHAR (processChar ()); }
381L'(\\.|[^\\'])+' { setTokLengthT (mstring_length (yytext));
382 RETURN_CHAR (processChar ()); }
383{Digit}+{E}[fF] { setTokLengthT (mstring_length (yytext));
384 RETURN_FLOAT (ctype_float, processFloat ()); }
385{Digit}+{E}[lL] { setTokLengthT (mstring_length (yytext));
386 RETURN_FLOAT (ctype_ldouble, processFloat ()); }
387{Digit}+{E} { setTokLengthT (mstring_length (yytext));
388 RETURN_FLOAT (ctype_double, processFloat ()); }
389
390{Digit}*"."{Digit}+({E})?[fF] { setTokLengthT (mstring_length (yytext));
391 RETURN_FLOAT (ctype_float, processFloat ()); }
392{Digit}*"."{Digit}+({E})?[lL] { setTokLengthT (mstring_length (yytext));
393 RETURN_FLOAT (ctype_ldouble, processFloat ()); }
394{Digit}*"."{Digit}+({E})? { setTokLengthT (mstring_length (yytext));
395 RETURN_FLOAT (ctype_double, processFloat ()); }
396
397{Digit}+"."{Digit}*({E})?[fF] { setTokLengthT (mstring_length (yytext));
398 RETURN_FLOAT (ctype_float, processFloat ()); }
399{Digit}+"."{Digit}*({E})?[lL] { setTokLengthT (mstring_length (yytext));
400 RETURN_FLOAT (ctype_ldouble, processFloat ()); }
401{Digit}+"."{Digit}*({E})? { setTokLengthT (mstring_length (yytext));
402 RETURN_FLOAT (ctype_double, processFloat ()); }
403
404">>=" { setTokLength (3); RETURN_TOK (RIGHT_ASSIGN); }
405"<<=" { setTokLength (3); RETURN_TOK (LEFT_ASSIGN); }
406"+=" { setTokLength (2); RETURN_TOK (ADD_ASSIGN); }
407"-=" { setTokLength (2); RETURN_TOK (SUB_ASSIGN); }
408"*=" { setTokLength (2); RETURN_TOK (MUL_ASSIGN); }
409"/=" { setTokLength (2); RETURN_TOK (DIV_ASSIGN); }
410"%=" { setTokLength (2); RETURN_TOK (MOD_ASSIGN); }
411"&=" { setTokLength (2); RETURN_TOK (AND_ASSIGN); }
412"^=" { setTokLength (2); RETURN_TOK (XOR_ASSIGN); }
413"|=" { setTokLength (2); RETURN_TOK (OR_ASSIGN); }
414">>" { setTokLength (2); RETURN_TOK (RIGHT_OP); }
415"<<" { setTokLength (2); RETURN_TOK (LEFT_OP); }
416"++" { setTokLength (2); RETURN_TOK (INC_OP); }
417"--" { setTokLength (2); RETURN_TOK (DEC_OP); }
418"->" { setTokLength (2); RETURN_TOK (ARROW_OP); }
419"&&" { setTokLength (2); RETURN_TOK (AND_OP); }
420"||" { setTokLength (2); RETURN_TOK (OR_OP); }
421"<=" { setTokLength (2); RETURN_TOK (LE_OP); }
422">=" { setTokLength (2); RETURN_TOK (GE_OP); }
423"==" { setTokLength (2); RETURN_TOK (EQ_OP); }
424"!=" { setTokLength (2); RETURN_TOK (NE_OP); }
425";" { setTokLength (1); RETURN_TOK (TSEMI); }
426"{" { setTokLength (1); RETURN_TOK (TLBRACE); }
427"}" { setTokLength (1); RETURN_TOK (TRBRACE); }
428"," { setTokLength (1); RETURN_TOK (TCOMMA); }
429":" { setTokLength (1); RETURN_TOK (TCOLON); }
430"=" { setTokLength (1); RETURN_TOK (TASSIGN); }
431"(" { setTokLength (1); RETURN_TOK (TLPAREN); }
432")" { setTokLength (1); RETURN_TOK (TRPAREN); }
433"[" { setTokLength (1); RETURN_TOK (TLSQBR); }
434"]" { setTokLength (1); RETURN_TOK (TRSQBR); }
435"." { setTokLength (1); RETURN_TOK (TDOT); }
436"&" { setTokLength (1); RETURN_TOK (TAMPERSAND); }
437"!" { setTokLength (1); RETURN_TOK (TEXCL); }
438
439
440"~" { setTokLength (1); RETURN_TOK (TTILDE); }
441"-" { setTokLength (1); RETURN_TOK (TMINUS); }
442"+" { setTokLength (1); RETURN_TOK (TPLUS); }
443"*" { setTokLength (1); RETURN_TOK (TMULT); }
444"/" { setTokLength (1); RETURN_TOK (TDIV); }
445"%" { setTokLength (1); RETURN_TOK (TPERCENT); }
446"<" { setTokLength (1); RETURN_TOK (TLT); }
447">" { setTokLength (1); RETURN_TOK (TGT); }
448"^" { setTokLength (1); RETURN_TOK (TCIRC); }
449"|" { setTokLength (1); RETURN_TOK (TBAR); }
450"?" { setTokLength (1); RETURN_TOK (TQUEST); }
451
452
453"/\\" { setTokLength (1); RETURN_TOK (TCAND); }
454
455
456[ \t\v\f] { incColumn (); }
457\n { context_incLineno ();
458 if (tokLength != 0) {
459 tokLength = 0;
460 /* No error to report
461 voptgenerror
462 (FLG_SYNTAX,
463 message ("Likely parse error: token spans multiple lines."),
464 g_currentloc);
465 */
466 }
467
468 if (continueLine)
469 {
470 continueLine = FALSE;
471 }
472 else
473 {
474 if (context_inMacro ())
475 {
476 /* Don't use RETURN_TOK */
80489f0a 477 yylval.tok = lltok_create (TENDMACRO, fileloc_copy (g_currentloc)); /* !!! evans 2002-03-13 */
ac0860d8 478 lastWasString = FALSE;
479 return (TENDMACRO);
480 }
481 }
482 }
483"@@MR@@" { setTokLength (6);
484
485 if (processMacro ()) {
486 if (context_inIterDef ())
487 {
488 RETURN_TOK (LLMACROITER);
489 }
490 if (context_inIterEnd ())
491 {
492 RETURN_TOK (LLMACROEND);
493 }
494 if (context_inMacro ())
495 {
496 RETURN_TOK (LLMACRO);
497 }
498 }
499 }
500"@QLMR" { if (context_inHeader () || context_inFunction ())
501 {
502 handleMacro ();
503 }
504 else
505 {
506 int nspchar = ninput ();
507 int nspaces;
508
509 /*
510 ** This is a hack to get the column number correct.
511 */
512
513 llassert (nspchar >= '0' && nspchar <= '9');
514
515 nspaces = nspchar - '0';
516
517 setTokLength (5 + nspaces);
518
519 if (processMacro ())
520 {
a469ccf0 521 DPRINTF (("Here we are: %s", context_unparse ()));
522
ac0860d8 523 if (context_inIterDef ())
524 {
525 RETURN_TOK (LLMACROITER);
526 }
527 if (context_inIterEnd ())
528 {
529 RETURN_TOK (LLMACROEND);
530 }
531 if (context_inMacro ())
532 {
533 RETURN_TOK (LLMACRO);
534 }
535 }
536 }
537 }
538"@.CT" { setTokLength (4); lldiagmsg (ctype_unparseTable ()); }
539"@.FA" { setTokLength (4); lldiagmsg (message ("Access types: %q", typeIdSet_unparse (context_fileAccessTypes ()))); }
540"@.F" { setTokLength (3);
541 lldiagmsg (message ("%q: *** marker ***", fileloc_unparse (g_currentloc)));
542 }
543"@.L" { setTokLength (3); usymtab_printLocal (); }
544"@.A" { setTokLength (3); lldiagmsg (usymtab_unparseAliases ()); }
545"@.C" { setTokLength (3); lldiagmsg (context_unparse ()); }
546"@.W" { setTokLength (3); lldiagmsg (context_unparseClauses ()); }
547"@.G" { setTokLength (3); usymtab_printGuards (); }
548"@.S" { setTokLength (3); usymtab_printOut (); }
549"@.X" { setTokLength (3); usymtab_printAll (); }
550"@.Z" { setTokLength (3); usymtab_printComplete (); }
551"@.T" { setTokLength (3); usymtab_printTypes (); }
552"@.K" { setTokLength (3); lldiagmsg (usymtab_unparseStack ()); }
553"@.M" { setTokLength (3);
554 lldiagmsg (message ("Can modify: %q",
555 sRefSet_unparse (context_modList ())));
556 }
557"%{" { /* BEFORE_COMMENT_MARKER */
558 int tok;
559 incColumn (); incColumn ();
560 tok = handleLlSpecial ();
561
562 if (tok != BADTOK)
563 {
564 if (tok == CANNOTATION) {
565 return (tok);
566 } else {
567 /* Beware - this bashes yylval! */
568 RETURN_TOK (tok);
569 }
570 }
571 }
572"%}" { /* AFTER_COMMENT_MARKER */
573 setTokLength (2);
574 inSpecPart = FALSE;
575 RETURN_TOK (QENDMACRO); }
576"\\" { incColumn (); continueLine = TRUE; }
577. { incColumn ();
578 if ((int) *yytext == 13 ) {
579 ;
580 } else {
581 voptgenerror
582 (FLG_SYNTAX,
583 message ("Invalid character (ascii: %d), skipping character",
584 (int)(*yytext)),
585 g_currentloc);
586 }
587 }
588%%
589
590struct skeyword
591{
592 /*@null@*/ /*@observer@*/ char *name;
593 int token;
594} ;
595
596/*
597** These tokens are followed by syntax that is parsed by the
598** grammar proper.
599*/
600
601struct skeyword s_parsetable[] = {
602 { "modifies", QMODIFIES } ,
603 { "globals", QGLOBALS } ,
604 { "alt", QALT } ,
605 { "warn", QWARN } ,
606 { "constant", QCONSTANT } ,
607 { "function", QFUNCTION } ,
608 { "iter", QITER } ,
609 { "defines", QDEFINES } ,
610 { "uses", QUSES } ,
611 { "allocates", QALLOCATES } ,
612 { "sets", QSETS } ,
613 { "releases", QRELEASES } ,
614 { "pre", QPRECLAUSE } ,
615 { "post", QPOSTCLAUSE } ,
616 { "setBufferSize", QSETBUFFERSIZE},
617 { "setStringLength", QSETSTRINGLENGTH},
618 { "testinRange", QTESTINRANGE},
619 { "requires", QPRECLAUSE } ,
620 { "ensures", QPOSTCLAUSE } ,
86d93ed3 621 { "invariant", QINVARIANT} ,
ac0860d8 622 { NULL, BADTOK }
623} ;
624
625/*
626** These tokens are either stand-alone tokens, or followed by
627** token-specific text.
628*/
629
630struct skeyword s_keytable[] = {
631 { "anytype", QANYTYPE } ,
632 { "integraltype", QINTEGRALTYPE } ,
633 { "unsignedintegraltype", QUNSIGNEDINTEGRALTYPE } ,
634 { "signedintegraltype", QSIGNEDINTEGRALTYPE } ,
635 { "out", QOUT } ,
636 { "in", QIN } ,
637 { "only", QONLY } ,
638 { "owned", QOWNED } ,
639 { "dependent", QDEPENDENT } ,
640 { "partial", QPARTIAL } ,
641 { "special", QSPECIAL } ,
642 { "truenull", QTRUENULL } ,
643 { "falsenull", QFALSENULL } ,
0e41eb0e 644 { "nullwhentrue", QTRUENULL } ,
645 { "falsewhennull", QFALSENULL } ,
ac0860d8 646 { "keep", QKEEP } ,
647 { "kept", QKEPT } ,
648 { "notnull", QNOTNULL } ,
649 { "abstract", QABSTRACT } ,
650 { "concrete", QCONCRETE } ,
651 { "mutable", QMUTABLE } ,
652 { "immutable", QIMMUTABLE } ,
653 { "unused", QUNUSED } ,
654 { "external", QEXTERNAL } ,
655 { "sef", QSEF } ,
656 { "unique", QUNIQUE } ,
657 { "returned", QRETURNED } ,
658 { "exposed", QEXPOSED } ,
659 { "refcounted", QREFCOUNTED } ,
660 { "refs", QREFS } ,
661 { "newref", QNEWREF } ,
662 { "tempref", QTEMPREF } ,
663 { "killref", QKILLREF } ,
664 { "null", QNULL } ,
665 { "relnull", QRELNULL } ,
666 { "nullterminated", QNULLTERMINATED },
667 { "setBufferSize", QSETBUFFERSIZE },
668 { "testInRange", QTESTINRANGE},
669 { "MaxSet", QMAXSET},
670 { "MaxRead", QMAXREAD},
671 { "reldef", QRELDEF } ,
672 { "observer", QOBSERVER } ,
673 { "exits", QEXITS } ,
27c9e640 674 { "noreturn", QEXITS } ,
ac0860d8 675 { "mayexit", QMAYEXIT } ,
27c9e640 676 { "maynotreturn", QMAYEXIT } ,
ac0860d8 677 { "trueexit", QTRUEEXIT } ,
678 { "falseexit", QFALSEEXIT } ,
27c9e640 679 { "noreturnwhentrue", QTRUEEXIT } ,
680 { "noreturnwhenfalse", QFALSEEXIT } ,
ac0860d8 681 { "neverexit", QNEVEREXIT } ,
27c9e640 682 { "alwaysreturns", QNEVEREXIT } ,
ac0860d8 683 { "temp", QTEMP } ,
684 { "shared", QSHARED } ,
685 { "ref", QREF } ,
686 { "unchecked", QUNCHECKED } ,
687 { "checked", QCHECKED } ,
688 { "checkmod", QCHECKMOD } ,
689 { "checkedstrict", QCHECKEDSTRICT } ,
690 { "innercontinue", QINNERCONTINUE } ,
691 { "innerbreak", QINNERBREAK } ,
692 { "loopbreak", QLOOPBREAK } ,
693 { "switchbreak", QSWITCHBREAK } ,
694 { "safebreak", QSAFEBREAK } ,
695 { "fallthrough", QFALLTHROUGH } ,
696 { "l_fallthrou", QLINTFALLTHROUGH } ,
697 { "l_fallth", QLINTFALLTHRU } ,
698 { "notreached", QNOTREACHED } ,
699 { "l_notreach", QLINTNOTREACHED } ,
700 { "printflike", QPRINTFLIKE } ,
701 { "l_printfli", QLINTPRINTFLIKE } ,
702 { "scanflike", QSCANFLIKE } ,
703 { "messagelike", QMESSAGELIKE } ,
704 { "l_argsus", QARGSUSED } ,
705 { NULL, BADTOK }
706} ;
707
708/*
709** would be better if these weren't hard coded...
710*/
711
712static bool isArtificial (cstring s)
713{
714 return (cstring_equalLit (s, "modifies")
715 || cstring_equalLit (s, "globals")
716 || cstring_equalLit (s, "warn")
717 || cstring_equalLit (s, "alt"));
718}
719
720void swallowMacro (void)
721{
722 int i;
723 bool skipnext = FALSE;
724
725 while ((i = lminput ()) != EOF)
726 {
727 char c = (char) i;
728
729
730 if (c == '\\')
731 {
732 skipnext = TRUE;
733 }
734 else if (c == '\n')
735 {
736 if (skipnext)
737 {
738 skipnext = FALSE;
739 }
740 else
741 {
742 reader_checkUngetc (i, yyin);
743 return;
744 }
745 }
746 }
747
748 if (i != EOF)
749 {
750 reader_checkUngetc (i, yyin);
751 }
752}
753
754static int commentMarkerToken (cstring s)
755{
756 int i = 0;
757
758 while (s_parsetable[i].name != NULL)
759 {
760 DPRINTF (("Try :%s:%s:", s, s_parsetable[i].name));
761
762 if (cstring_equalLit (s, s_parsetable[i].name))
763 {
764 return s_parsetable[i].token;
765 }
766
767 i++;
768 }
769
770 return BADTOK;
771}
772
773static int tokenMacroCode (cstring s)
774{
775 int i = 0;
776
777 while (s_keytable[i].name != NULL)
778 {
779 if (cstring_equalLit (s, s_keytable[i].name))
780 {
781 if (s_keytable[i].token == QLINTFALLTHROUGH)
782 {
783 voptgenerror
784 (FLG_WARNLINTCOMMENTS,
785 cstring_makeLiteral
1b8ae690 786 ("Traditional lint comment /*FALLTHROUGH*/ used. "
787 "Splint interprets this in the same way as most Unix lints, but it is "
ac0860d8 788 "preferable to replace it with the /*@fallthrough@*/ "
789 "semantic comment"),
790 g_currentloc);
791 return QFALLTHROUGH;
792 }
793 else if (s_keytable[i].token == QLINTFALLTHRU)
794 {
795 voptgenerror
796 (FLG_WARNLINTCOMMENTS,
797 cstring_makeLiteral
1b8ae690 798 ("Traditional lint comment /*FALLTHRU*/ used. "
799 "Splint interprets this in the same way as most Unix lints, but it is "
ac0860d8 800 "preferable to replace it with the /*@fallthrough@*/ "
801 "semantic comment"),
802 g_currentloc);
803 return QFALLTHROUGH;
804 }
805 else if (s_keytable[i].token == QLINTNOTREACHED)
806 {
807 voptgenerror
808 (FLG_WARNLINTCOMMENTS,
809 cstring_makeLiteral
1b8ae690 810 ("Traditional lint comment /*NOTREACHED*/ used. "
811 "Splint interprets this in the same way as most Unix lints, but it is "
ac0860d8 812 "preferable to replace it with the /*@notreached@*/ "
813 "semantic comment."),
814 g_currentloc);
815
816 return QNOTREACHED;
817 }
818 else if (s_keytable[i].token == QPRINTFLIKE)
819 {
820 setSpecialFunction (qual_createPrintfLike ());
821 return SKIPTOK;
822 }
823 else if (s_keytable[i].token == QLINTPRINTFLIKE)
824 {
825 voptgenerror
826 (FLG_WARNLINTCOMMENTS,
827 cstring_makeLiteral
1b8ae690 828 ("Traditional lint comment /*PRINTFLIKE*/ used. "
829 "Splint interprets this in the same way as most Unix lints, but it is "
ac0860d8 830 "preferable to replace it with either /*@printflike@*/, "
831 "/*@scanflike@*/ or /*@messagelike@*/."),
832 g_currentloc);
833
834 setSpecialFunction (qual_createPrintfLike ());
835 return SKIPTOK;
836 }
837 else if (s_keytable[i].token == QSCANFLIKE)
838 {
839 setSpecialFunction (qual_createScanfLike ());
840 return SKIPTOK;
841 }
842 else if (s_keytable[i].token == QMESSAGELIKE)
843 {
844 setSpecialFunction (qual_createMessageLike ());
845 return SKIPTOK;
846 }
847 else if (s_keytable[i].token == QARGSUSED)
848 {
849 voptgenerror
850 (FLG_WARNLINTCOMMENTS,
851 cstring_makeLiteral
1b8ae690 852 ("Traditional lint comment /*ARGSUSED*/ used. "
853 "Splint interprets this in the same way as most Unix lints, but it is "
ac0860d8 854 "preferable to use /*@unused@*/ annotations on "
855 "the unused parameters."),
856 g_currentloc);
857
858 setArgsUsed ();
859 return SKIPTOK;
860 }
861
862 return s_keytable[i].token;
863 }
864
865 i++;
866 }
867
868 return BADTOK;
869}
870
871static int lminput ()
872{
873 if (savechar == '\0')
874 {
875 incColumn ();
876 return (input ());
877 }
878 else
879 {
880 int save = (int) savechar;
881 savechar = '\0';
882 return save;
883 }
884}
885
886static void lmsavechar (char c)
887{
888 if (savechar == '\0') savechar = c;
889 else
890 {
891 llbuglit ("lmsavechar: override");
892 }
893}
894
895static int returnFloat (ctype ct, double f)
896{
897 yylval.expr = exprNode_floatLiteral (f, ct, cstring_fromChars (yytext),
898 fileloc_decColumn (g_currentloc, tokLength));
899 tokLength = 0;
900 return (CCONSTANT);
901}
902
903static int returnInt (ctype ct, long i)
904{
905 ctype c = ct;
906
907 if (ctype_equal (ct, ctype_int))
908 {
909 if (i == 0)
910 {
911 c = context_typeofZero ();
912 }
913 else if (i == 1)
914 {
915 c = context_typeofOne ();
916 }
917 }
918
919 yylval.expr = exprNode_numLiteral (c, cstring_fromChars (yytext),
920 fileloc_decColumn (g_currentloc, tokLength), i);
921 tokLength = 0;
922 return (CCONSTANT);
923}
924
925static int returnChar (char c)
926{
927 yylval.expr = exprNode_charLiteral (c, cstring_fromChars (yytext),
928 fileloc_decColumn (g_currentloc, tokLength));
929 tokLength = 0;
930 return (CCONSTANT);
931}
932
933static int ninput ()
934{
935 int c = lminput ();
936
937 if (c != EOF && ((char)c == '\n'))
938 {
939 context_incLineno ();
940 }
941
942 return c;
943}
944
945static char macro_nextChar ()
946{
947 static bool in_quote = FALSE, in_escape = FALSE, in_char = FALSE;
948 int ic;
949 char c;
950
951 ic = lminput ();
952 c = char_fromInt (ic);
953
954 if (!in_quote && !in_char && (c == '\\' || c == BEFORE_COMMENT_MARKER[0]))
955 {
956 if (c == '\\')
957 {
958 while ((c = char_fromInt (lminput ())) != '\0' && c != '\n')
959 {
960 ; /* skip to newline */
961 }
962
963 context_incLineno ();
964
965 if (c != '\0')
966 {
967 return macro_nextChar ();
968 }
969 else
970 {
971 return c;
972 }
973 }
974 else /* if (c == '@') */
975 {
976 llassert (FALSE); /*@i23@*/
977 if (handleLlSpecial () != BADTOK)
978 {
979 llerrorlit (FLG_SYNTAX, "Macro cannot use special syntax");
980 }
981
982 return macro_nextChar ();
983 }
984 }
985 else if (!in_escape && c == '\"')
986 {
987 in_quote = !in_quote;
988 }
989 else if (!in_escape && c == '\'')
990 {
991 in_char = !in_char;
992 }
993 else if ((in_quote || in_char) && c == '\\')
994 {
995 in_escape = !in_escape;
996 }
997 else if ((in_quote || in_char) && in_escape)
998 {
999 in_escape = FALSE;
1000 }
1001 else if (!in_quote && c == '/')
1002 {
1003 char c2;
1004
1005 if ((c2 = char_fromInt (lminput ())) == '*')
1006 {
1007 while (c2 != '\0')
1008 {
1009 while ((c2 = char_fromInt (lminput ())) != '\0'
1010 && c2 != '\n' && c2 != '*')
1011 {
1012 ;
1013 }
1014
1015 if (c2 == '*')
1016 {
1017 while ((c2 = char_fromInt (lminput ())) != '\0'
1018 && c2 == '*')
1019 {
1020 ;
1021 }
1022
1023 if (c2 == '/')
1024 {
1025 goto outofcomment;
1026 }
1027 }
1028 else
1029 {
1030 llfatalerror (cstring_makeLiteral ("Macro: bad comment!"));
1031 }
1032 }
1033 outofcomment:
1034 return macro_nextChar ();
1035 }
1036 else
1037 {
1038 /*** putchar does not work! why? puts to stdio...??! ***/
1039 lmsavechar (c2);
1040 }
1041 }
1042 return c;
1043}
1044
1045/*
1046** keeps semantic comments
1047*/
1048
1049static char macro_nextCharC ()
1050{
1051 static bool in_quote = FALSE, in_escape = FALSE, in_char = FALSE;
1052 char c;
1053
1054 c = char_fromInt (lminput ());
1055
1056 if (!in_quote && !in_char && c == '\\')
1057 {
1058 while ((c = char_fromInt (lminput ())) != '\0' && c != '\n')
1059 {
1060 ; /* skip to newline */
1061 }
1062
1063 context_incLineno ();
1064
1065 if (c != '\0')
1066 {
1067 return macro_nextCharC ();
1068 }
1069 else
1070 {
1071 return c;
1072 }
1073 }
1074 else if (!in_escape && c == '\"')
1075 {
1076 in_quote = !in_quote;
1077 }
1078 else if (!in_escape && c == '\'')
1079 {
1080 in_char = !in_char;
1081 }
1082 else if ((in_quote || in_char) && c == '\\')
1083 {
1084 in_escape = !in_escape;
1085 }
1086 else if ((in_quote || in_char) && in_escape)
1087 {
1088 in_escape = FALSE;
1089 }
1090 else if (!in_quote && c == '/')
1091 {
1092 char c2;
1093
1094 if ((c2 = char_fromInt (lminput ())) == '*')
1095 {
1096 while (c2 != '\0')
1097 {
1098 while ((c2 = char_fromInt (lminput ())) != '\0'
1099 && c2 != '\n' && c2 != '*')
1100 {
1101 ;
1102 }
1103
1104 if (c2 == '*')
1105 {
1106 while ((c2 = char_fromInt (lminput ())) != '\0'
1107 && c2 == '*')
1108 {
1109 ;
1110 }
1111
1112 if (c2 == '/')
1113 {
1114 goto outofcomment;
1115 }
1116 }
1117 else
1118 {
1119 llfatalerror (cstring_makeLiteral ("Macro: bad comment!"));
1120 }
1121 }
1122 outofcomment:
1123 return macro_nextCharC ();
1124 }
1125 else
1126 {
1127 lmsavechar (c2);
1128 }
1129 }
1130 return c;
1131}
1132
1133/*
1134** skips whitespace (handles line continuations)
1135** returns first non-whitespace character
1136*/
1137
1138static char skip_whitespace ()
1139{
1140 char c;
1141
1142 while ((c = macro_nextChar ()) == ' ' || c == '\t')
1143 {
1144 ;
1145 }
1146
1147 return c;
1148}
1149
1150static void handleMacro ()
1151{
1152 cstring mac = cstring_undefined;
1153 int macrocode;
1154 char c;
1155
1156 while (currentColumn () > 2)
1157 {
1158 mac = cstring_appendChar (mac, ' ');
1159 setTokLength (-1);
1160 }
1161
1162 c = macro_nextCharC ();
1163
1164 if (c >= '0' && c <= '9')
1165 {
1166 int i;
1167
1168 for (i = 0; i < ((c - '0') + 1); i++)
1169 {
1170 mac = cstring_appendChar (mac, ' ');
1171 }
1172 }
1173 else
1174 {
1175 BADBRANCH;
1176 }
1177
1178 while (((c = macro_nextCharC ()) != '\0') && (c != '\n'))
1179 {
1180 mac = cstring_appendChar (mac, c);
1181 }
1182
1183
1184 macrocode = tokenMacroCode (mac);
1185
1186 if (macrocode == BADTOK && !isArtificial (mac))
1187 {
1188 context_addMacroCache (mac);
1189 }
1190 else
1191 {
1192 cstring_free (mac);
1193 }
1194
1195 if (c == '\n')
1196 {
1197 context_incLineno ();
1198 }
1199}
1200
1201static bool processMacro (void)
1202{
1203 uentry e2;
1204 ctype ct;
1205 int noparams = 0;
1206 cstring fname = cstring_undefined;
1207 bool res = TRUE;
1208 bool isspecfcn = FALSE;
1209 bool isiter = FALSE;
1210 bool skipparam = FALSE;
1211 bool isenditer = FALSE;
1212 bool unknownm = FALSE;
1213 bool hasParams = FALSE;
1214 bool emptyMacro = FALSE;
1215 char c = skip_whitespace ();
1216 fileloc loc = fileloc_noColumn (g_currentloc);
1217
1218 /* are both of these necessary? what do they mean? */
1219 uentryList specparams = uentryList_undefined;
1220 uentryList pn = uentryList_undefined;
1221
1222 context_resetMacroMissingParams ();
1223
1224 if (c == '\0' || c == '\n')
1225 {
1226 llcontbug (cstring_makeLiteral ("Bad macro"));
1227 fileloc_free (loc);
1228 return FALSE;
1229 }
1230
1231 fname = cstring_appendChar (fname, c);
1232
1233 while ((c = macro_nextChar ()) != '(' && c != '\0'
1234 && c != ' ' && c != '\t' && c != '\n')
1235 {
1236 fname = cstring_appendChar (fname, c);
1237 }
1238
1239 if (c == ' ' || c == '\t' || c == '\n')
1240 {
1241 char oldc = c;
1242
1243 if (c != '\n')
1244 {
1245 while (c == ' ' || c == '\t')
1246 {
1247 c = macro_nextChar ();
1248 }
1249 unput (c);
1250 }
1251
1252 if (c == '\n')
1253 {
1254 emptyMacro = TRUE;
1255 unput (c);
1256 }
1257
1258 c = oldc;
1259 }
1260
1261 hasParams = (c == '(');
1262
1263 if (usymtab_exists (fname))
1264 {
1265 e2 = usymtab_lookupExpose (fname);
1266 ct = uentry_getType (e2);
1267
1268 if (uentry_isCodeDefined (e2)
1269 && fileloc_isUser (uentry_whereDefined (e2)))
1270 {
1271 if (optgenerror
1272 (FLG_MACROREDEF,
1273 message ("Macro %s already defined", fname),
1274 loc))
1275 {
1276 uentry_showWhereDefined (e2);
1277 uentry_clearDefined (e2);
1278 }
1279
1280 if (uentry_isFunction (e2))
1281 {
1282 uentry_setType (e2, ctype_unknown);
1283 ct = ctype_unknown;
1284 unknownm = TRUE;
1285 context_enterUnknownMacro (e2);
1286 }
1287 else
1288 {
1289 context_enterConstantMacro (e2);
1290 }
1291 }
1292 else
1293 {
1294 if (uentry_isForward (e2) && uentry_isFunction (e2))
1295 {
1296 unknownm = TRUE;
1297
1298 voptgenerror
1299 (FLG_MACROFCNDECL,
1300 message
1301 ("Parameterized macro has no prototype or specification: %s ",
1302 fname),
1303 loc);
1304
1305 ct = ctype_unknown;
1306 uentry_setType (e2, ctype_unknown);
1307 uentry_setFunctionDefined (e2, loc);
1308 uentry_setUsed (e2, fileloc_undefined);
1309 context_enterUnknownMacro (e2);
1310 }
1311 else
1312 {
1313 if (uentry_isIter (e2))
1314 {
1315 isiter = TRUE;
1316 specparams = uentry_getParams (e2);
1317 noparams = uentryList_size (specparams);
1318 uentry_setDefined (e2, loc);
1319 context_enterIterDef (e2);
1320 }
1321 else if (uentry_isEndIter (e2))
1322 {
1323 isenditer = TRUE;
1324 uentry_setDefined (e2, loc);
1325 context_enterIterEnd (e2); /* don't care about it now */
1326 /* but should parse like an iter! */
1327 }
1328 else if (uentry_isConstant (e2))
1329 {
1330 if (hasParams)
1331 {
1332 voptgenerror
1333 (FLG_INCONDEFS,
1334 message ("Constant %s implemented as parameterized macro",
1335 fname),
1336 g_currentloc);
1337
1338 uentry_showWhereSpecified (e2);
1339 uentry_setType (e2, ctype_unknown);
1340 uentry_makeConstantFunction (e2);
1341 uentry_setDefined (e2, g_currentloc);
1342 uentry_setFunctionDefined (e2, g_currentloc);
1343 context_enterUnknownMacro (e2);
1344 }
1345 else
1346 {
1347 if (!uentry_isSpecified (e2))
1348 {
1349 fileloc oloc = uentry_whereDeclared (e2);
1350
1351 if (fileloc_isLib (oloc))
1352 {
1353 ;
1354 }
1355 else if (fileloc_isUndefined (oloc)
1356 || fileloc_isPreproc (oloc))
1357 {
1358 if (!emptyMacro)
1359 {
1360 voptgenerror
1361 (FLG_MACROCONSTDECL,
1362 message
1363 ("Macro constant %q not declared",
1364 uentry_getName (e2)),
1365 loc);
1366 }
1367 }
1368 else if (!fileloc_withinLines (oloc, loc, 2))
1369 { /* bogus! will give errors if there is too much whitespace */
1370 voptgenerror
1371 (FLG_SYNTAX,
1372 message
1373 ("Macro constant name %s does not match name in "
1374 "previous constant declaration. This constant "
1375 "is declared at %q", fname,
1376 fileloc_unparse (oloc)),
1377 loc);
1378 }
1379 }
1380
1381 context_enterConstantMacro (e2);
1382 cstring_free (fname);
1383 fileloc_free (loc);
1384 return res;
1385 }
1386
1387 }
1388 else if (ctype_isFunction (ct))
1389 {
1390 isspecfcn = TRUE;
1391 specparams = ctype_argsFunction (ct);
1392 noparams = uentryList_size (specparams);
1393
1394 uentry_setFunctionDefined (e2, loc);
1395 context_enterMacro (e2);
1396 }
1397 else if (uentry_isVar (e2))
1398 {
1399 if (hasParams)
1400 {
1401 voptgenerror
1402 (FLG_INCONDEFS,
1403 message ("Variable %s implemented as parameterized macro",
1404 fname),
1405 loc);
1406
1407 uentry_showWhereSpecified (e2);
1408 uentry_setType (e2, ctype_unknown);
1409 uentry_makeVarFunction (e2);
1410 uentry_setDefined (e2, g_currentloc);
1411 uentry_setFunctionDefined (e2, g_currentloc);
1412 context_enterUnknownMacro (e2);
1413 }
1414 else
1415 {
1416 uentry ucons = uentry_makeConstant (fname,
1417 ctype_unknown,
1418 loc);
1419 if (uentry_isExpandedMacro (e2))
1420 {
1421 ; /* okay */
1422 }
1423 else
1424 {
1425 if (optgenerror
1426 (FLG_INCONDEFS,
1427 message ("Variable %s implemented by a macro",
1428 fname),
1429 loc))
1430 {
1431 uentry_showWhereSpecified (e2);
1432 }
1433 }
1434
1435 uentry_setDefined (e2, loc);
1436 uentry_setUsed (ucons, loc);
1437
1438 context_enterConstantMacro (ucons);
1439 uentry_markOwned (ucons);
1440 cstring_free (fname);
1441 return res;
1442 }
1443 }
1444 else
1445 {
1446 if (uentry_isDatatype (e2))
1447 {
1448 vgenhinterror
1449 (FLG_SYNTAX,
1450 message ("Type implemented as macro: %x",
1451 uentry_getName (e2)),
1452 message ("A type is implemented using a macro definition. A "
1453 "typedef should be used instead."),
1454 g_currentloc);
1455
1456 swallowMacro ();
1457 /* Must exit scope (not sure why a new scope was entered?) */
1458 usymtab_quietExitScope (g_currentloc);
1459 uentry_setDefined (e2, g_currentloc);
1460 res = FALSE;
1461 }
1462 else
1463 {
1464 llcontbug
1465 (message ("Unexpanded macro not function or constant: %q",
1466 uentry_unparse (e2)));
1467 uentry_setType (e2, ctype_unknown);
1468
1469 if (hasParams)
1470 {
1471 uentry_makeVarFunction (e2);
1472 uentry_setDefined (e2, g_currentloc);
1473 uentry_setFunctionDefined (e2, g_currentloc);
1474 context_enterUnknownMacro (e2);
1475 }
1476 }
1477 }
1478 }
1479 }
1480 }
1481 else
1482 {
1483 uentry ce;
1484
1485 /* evans 2001-09-09 - if it has params, assume a function */
1486 if (hasParams)
1487 {
1488 voptgenerror
1489 (FLG_MACROMATCHNAME,
1490 message ("Unexpanded macro %s does not match name of a declared "
1491 "function. The name used in the control "
1492 "comment on the previous line should match.",
1493 fname),
1494 loc);
1495
1496 ce = uentry_makeFunction (fname, ctype_unknown,
1497 typeId_invalid,
1498 globSet_undefined,
1499 sRefSet_undefined,
1500 warnClause_undefined,
1501 fileloc_undefined);
1502 uentry_setUsed (ce, loc); /* perhaps bogus? */
1503 e2 = usymtab_supEntryReturn (ce);
1504 context_enterUnknownMacro (e2);
1505 }
1506 else
1507 {
1508 voptgenerror
1509 (FLG_MACROMATCHNAME,
1510 message ("Unexpanded macro %s does not match name of a constant "
1511 "or iter declaration. The name used in the control "
1512 "comment on the previous line should match. "
1513 "(Assuming macro defines a constant.)",
1514 fname),
1515 loc);
1516
1517 ce = uentry_makeConstant (fname, ctype_unknown, fileloc_undefined);
1518 uentry_setUsed (ce, loc); /* perhaps bogus? */
1519 e2 = usymtab_supEntryReturn (ce);
1520
1521 context_enterConstantMacro (e2);
1522 cstring_free (fname);
1523 fileloc_free (loc);
1524 return res;
1525 }
1526 }
1527
1528 /* in macros, ( must follow immediatetly after name */
1529
1530 if (hasParams)
1531 {
1532 int paramno = 0;
1533
1534 c = skip_whitespace ();
1535
1536 while (c != ')' && c != '\0')
1537 {
1538 uentry param;
1539 bool suppress = context_inSuppressRegion ();
1540 cstring paramname = cstring_undefined;
1541
1542 /*
1543 ** save the parameter location
1544 */
1545
1546 decColumn ();
1547 context_saveLocation ();
1548 incColumn ();
1549
1550 while (c != ' ' && c != '\t' && c != ',' && c != '\0' && c != ')')
1551 {
1552 paramname = cstring_appendChar (paramname, c);
1553 c = macro_nextChar ();
1554 }
1555
1556 if (c == ' ' || c == '\t') c = skip_whitespace ();
1557
1558 if (c == ',')
1559 {
1560 c = macro_nextChar ();
1561 if (c == ' ' || c == '\t') c = skip_whitespace ();
1562 }
1563
1564 if (c == '\0')
1565 {
1566 llfatalerror (cstring_makeLiteral
1567 ("Bad macro syntax: uentryList"));
1568 }
1569
1570 if ((isspecfcn || isiter) && (paramno < noparams)
1571 && !uentry_isElipsisMarker (uentryList_getN
1572 (specparams, paramno)))
1573 {
1574 fileloc sloc = context_getSaveLocation ();
1575 uentry decl = uentryList_getN (specparams, paramno);
1576 sRef sr;
1577
1578 param = uentry_nameCopy (paramname, decl);
1579
1580 uentry_setParam (param);
1581 sr = sRef_makeParam (paramno, uentry_getType (param), stateInfo_makeLoc (sloc));
1582
1583 if (sRef_getNullState (sr) == NS_ABSNULL)
1584 {
1585 ctype pt = ctype_realType (uentry_getType (param));
1586
1587 if (ctype_isUser (pt))
1588 {
1589 uentry te = usymtab_getTypeEntrySafe (ctype_typeId (pt));
1590
1591 if (uentry_isValid (te))
1592 {
1593 sRef_setStateFromUentry (sr, te);
1594 }
1595 }
1596 else
1597 {
1598 sRef_setNullState (sr, NS_UNKNOWN, sloc);
1599 }
1600 }
1601
1602 uentry_setSref (param, sr);
1603 uentry_setDeclaredForceOnly (param, sloc);
1604
1605 skipparam = isiter && uentry_isOut (uentryList_getN (specparams, paramno));
1606 }
1607 else
1608 {
1609 fileloc sloc = context_getSaveLocation ();
1610
1611 param = uentry_makeVariableSrefParam
1612 (paramname, ctype_unknown, fileloc_copy (sloc),
1613 sRef_makeParam (paramno, ctype_unknown, stateInfo_makeLoc (sloc)));
1614 DPRINTF (("Unknown param: %s", uentry_unparseFull (param)));
1615 cstring_free (paramname);
1616
1617 sRef_setPosNull (uentry_getSref (param), sloc);
1618 uentry_setDeclaredForce (param, sloc);
1619
1620 skipparam = FALSE;
1621 fileloc_free (sloc);
1622 }
1623
1624 if (!skipparam)
1625 {
1626 llassert (!uentry_isElipsisMarker (param));
1627
1628 if (!suppress)
1629 {
1630 sRef_makeUnsafe (uentry_getSref (param));
1631 }
1632
1633 pn = uentryList_add (pn, uentry_copy (param));
1634 usymtab_supEntry (param);
1635 }
1636 else
1637 {
1638 /* don't add param */
1639 uentry_free (param);
1640 }
1641
1642 if (c == ',')
1643 {
1644 (void) macro_nextChar ();
1645 c = skip_whitespace ();
1646 }
1647
1648 paramno++;
1649 }
1650
1651 if (c == ')')
1652 {
1653 if (isspecfcn || isiter)
1654 {
1655 if (paramno != noparams && noparams >= 0)
1656 {
1657 advanceLine ();
1658
1659 voptgenerror
1660 (FLG_INCONDEFS,
1661 message ("Macro %s specified with %d args, defined with %d",
1662 fname, noparams, paramno),
1663 g_currentloc);
1664
1665 uentry_showWhereSpecified (e2);
1666 uentry_resetParams (e2, pn);
1667 }
1668 }
1669 else
1670 {
1671 uentry_resetParams (e2, pn);
1672 }
1673 }
1674 }
1675 else
1676 {
1677 /*
1678 ** the form should be:
1679 **
1680 ** # define newname oldname
1681 ** where oldname refers to a function matching the specification
1682 ** of newname.
1683 */
1684
1685 if (unknownm)
1686 {
1687 sRef_setGlobalScope ();
1688 usymtab_supGlobalEntry (uentry_makeVariableLoc (fname, ctype_unknown));
1689 sRef_clearGlobalScope ();
1690 }
1691 else
1692 {
1693 context_setMacroMissingParams ();
1694 }
1695 }
1696
1697
1698 /* context_setuentryList (pn); */
1699 usymtab_enterScope ();
1700
1701 fileloc_free (loc);
1702 cstring_free (fname);
1703
1704 return res;
1705}
1706
1707static bool handleSpecial (char *yyt)
1708{
1709 char *l = mstring_create (MAX_NAME_LENGTH);
ac0860d8 1710 int lineno = 0;
1711 char c;
1712 char *ol;
1713 cstring olc;
ac0860d8 1714
fc97bef4 1715 int len_yyt;
1716
1717 len_yyt = strlen (yyt +1) ;
ac0860d8 1718
fc97bef4 1719 l = mstring_copy (yyt + 1);
ac0860d8 1720
1721 while ((c = char_fromInt (lminput ())) != '\n' && c != '\0')
1722 {
fc97bef4 1723 l = mstring_append(l, c);
ac0860d8 1724 }
1725
fc97bef4 1726 /* Need to safe original l for deallocating. */
1727 ol = l;
1728
1729 l += strlen (l);
1730
ac0860d8 1731 olc = cstring_fromChars (ol);
1732
1733 if (cstring_equalPrefixLit (olc, "pragma"))
1734 {
1735 char *pname = mstring_create (longUnsigned_fromInt (MAX_PRAGMA_LEN));
1736 char *opname = pname;
1737 char *ptr = ol + 6; /* pragma is six characters, plus space */
1738 int len = 0;
1739
1740
1741 /* skip whitespace */
1742 while (((c = *ptr) != '\0') && isspace (c))
1743 {
1744 ptr++;
1745 }
1746
1747
1748 while (((c = *ptr) != '\0') && !isspace (c))
1749 {
1750 len++;
1751
1752 if (len > MAX_PRAGMA_LEN)
1753 {
1754 break;
1755 }
1756
1757 ptr++;
1758 *pname++ = c;
1759 }
1760
1761 *pname = '\0';
1762
1763 if (len == PRAGMA_LEN_EXPAND
1764 && mstring_equal (opname, PRAGMA_EXPAND))
1765 {
1766 cstring exname = cstring_undefined;
1767 uentry ue;
1768
1769 ptr++;
1770 while (((c = *ptr) != '\0') && !isspace (c))
1771 {
1772 exname = cstring_appendChar (exname, c);
1773 ptr++;
1774 }
1775
1776
1777 ue = usymtab_lookupExposeGlob (exname);
1778
1779 if (uentry_isExpandedMacro (ue))
1780 {
1781 if (fileloc_isPreproc (uentry_whereDefined (ue)))
1782 {
1783 fileloc_setColumn (g_currentloc, 1);
1784 uentry_setDefined (ue, g_currentloc);
1785 }
1786 }
1787
1788 cstring_free (exname);
1789 }
1790 }
1791 else if (cstring_equalPrefixLit (olc, "ident"))
1792 {
1793 /* Some pre-processors will leave these in the code. Ignore rest of line */
1794 }
1795 /*
1796 ** Yuk...Win32 filenames can have spaces in them...we need to read
1797 ** to the matching end quote.
1798 */
1799 else if ((sscanf (ol, "line %d \"", &lineno) == 1)
1800 || (sscanf (ol, " %d \"", &lineno) == 1))
1801 {
1802 char *tmp = ol;
1803 cstring fname;
1804 fileId fid;
1805
1806 /*@access cstring@*/
1807 while (*tmp != '\"' && *tmp != '\0')
1808 {
1809 tmp++;
1810 }
1811
1812 llassert (*tmp == '\"');
1813
1814 tmp++;
1815
1816 fname = tmp;
1817
1818 while (*tmp != '\"' && *tmp != '\0')
1819 {
1820 tmp++;
1821 }
1822
1823 llassert (*tmp == '\"');
1824
1825 *tmp = '\0';
1826
1827# if defined(OS2) || defined(MSDOS) || defined(WIN32)
1828
1829 /*
1830 ** DOS-like path delimiters get delivered in pairs, something like
1831 ** \"..\\\\file.h\", so we have to make it normal again. We do NOT
1832 ** remove the pre dirs yet as we usually specify tmp paths relative
1833 ** to the current directory, so tmp files would not get found in
1834 ** the hash table. If this method fails we try it again later.
1835 */
1836
1837 {
1838 char *stmp = fname;
1839
1840 /*
1841 ** Skip past the drive marker.
1842 */
1843
1844 if (strchr (stmp, ':') != NULL)
1845 {
1846 stmp = strchr (stmp, ':') + 1;
1847 }
1848
1849 while ((stmp = strchr (stmp, CONNECTCHAR)) != NULL )
1850 {
1851 if (*(stmp+1) == CONNECTCHAR)
1852 {
1853 memmove (stmp, stmp+1, strlen (stmp));
1854 }
1855
1856 stmp++;
1857 }
1858
1859 fid = fileTable_lookupBase (context_fileTable (), fname);
1860 if (!(fileId_isValid (fid)))
1861 {
1862 fname = removePreDirs (fname);
1863 fid = fileTable_lookupBase (context_fileTable (), fname);
1864 }
1865 }
1866# else /* !defined(OS2) && !defined(MSDOS) */
1867 fname = removePreDirs (fname);
1868 fid = fileTable_lookupBase (context_fileTable (), fname);
1869# endif /* !defined(OS2) && !defined(MSDOS) */
1870
1871 if (!(fileId_isValid (fid)))
1872 {
1873 if (context_inXHFile ())
1874 {
1875 fid = fileTable_addXHFile (context_fileTable (), fname);
1876 }
1877 else if (isHeaderFile (fname))
1878 {
1879 fid = fileTable_addHeaderFile (context_fileTable (), fname);
1880 }
1881 else
1882 {
1883 fid = fileTable_addFile (context_fileTable (), fname);
1884 }
1885 }
1886
1887 setFileLine (fid, lineno);
1888 /*@noaccess cstring@*/
1889 }
1890 else if ((sscanf (ol, "line %d", &lineno) == 1)
1891 || (sscanf (ol, " %d", &lineno) == 1))
1892 {
1893 setLine (lineno); /* next line is <cr> */
1894 }
1895 else
1896 {
1897 if (mstring_equal (ol, "")) {
1898 DPRINTF (("Empty pp command!"));
1899 /*
1900 ** evs 2000-05-16: This is a horrible kludge, to get around a bug (well, difficulty) in the pre-processor.
1901 ** We handle a plain # in the input file, by echoing it, and ignoring it in the post-pp-file.
1902 */
1903 mstring_free (ol);
1904 return FALSE;
1905 } else {
4c9767b3 1906 voptgenerror
1907 (FLG_UNRECOGDIRECTIVE,
1908 message ("Unrecognized pre-processor directive: #%s",
1909 cstring_fromChars (ol)),
1910 g_currentloc);
ac0860d8 1911 }
1912
1913 sfree (ol);
4c9767b3 1914 return FALSE; /* evans 2001-12-30: was: TRUE; */
ac0860d8 1915 }
1916
1917 sfree (ol);
1918 return FALSE;
1919}
1920
1921static int handleLlSpecial ()
1922{
1923 bool hasnl = FALSE;
1924 int ic;
1925 char c;
1926 char *s = mstring_createEmpty ();
1927 char *os;
1928 int tok;
1929 int charsread = 0;
1930 fileloc loc;
1931
1932 loc = fileloc_copy (g_currentloc);
1933 DPRINTF (("Handle special: %s", fileloc_unparse (loc)));
1934
1935 while (((ic = ninput ()) != 0) && isalpha (ic))
1936 {
1937 c = (char) ic;
1938 s = mstring_append (s, c);
1939 charsread++;
1940 }
1941
1942 DPRINTF (("Read: %s / %s", s, fileloc_unparse (g_currentloc)));
1943 os = s;
1944
1945 if (charsread == 0 && ic == (int) AFTER_COMMENT_MARKER[0])
1946 {
1947 ic = ninput ();
1948
1949 llassert (ic == AFTER_COMMENT_MARKER[1]);
1950
1951 if (*s == '\0')
1952 {
1953 sfree (os);
1954 fileloc_free (loc);
1955 return QNOMODS; /* special token no modifications token */
1956 }
1957 }
1958
1959 DPRINTF (("Coment marker: %s", os));
1960 tok = commentMarkerToken (cstring_fromChars (os));
1961
1962 if (tok != BADTOK)
1963 {
1964 tokLength = charsread;
1965 sfree (os);
1966 inSpecPart = TRUE;
1967 fileloc_free (loc);
1968 return tok;
1969 }
1970
1971 DPRINTF (("Not a comment marker..."));
1972 /* Add rest of the comment */
1973
1974 if (ic != 0 && ic != EOF)
1975 {
1976 c = (char) ic;
1977
1978 s = mstring_append (s, c);
1979 charsread++;
1980
1981 while (((ic = ninput ()) != 0) && (ic != EOF)
1982 && (ic != AFTER_COMMENT_MARKER[0]))
1983 {
1984 c = (char) ic;
1985
1986 /* evans 2001-09-01 added to prevent assertion failures for uncloses syntactic comments */
1987
1988 if (c == '\n') {
1989 hasnl = TRUE; /* This prevents tokLength from being set later. */
1990 tokLength = 0;
1991
1992 voptgenerror
1993 (FLG_SYNTAX,
1994 message ("Likely parse error: syntactic comment token spans multiple lines: %s",
1995 cstring_fromChars (s)),
abd7f895 1996 loc);
ac0860d8 1997 }
1998
1999 s = mstring_append (s, c);
2000 charsread++;
2001 }
2002 }
2003
2004 DPRINTF (("Read: %s / %s", s, fileloc_unparse (g_currentloc)));
2005
2006 if (ic == AFTER_COMMENT_MARKER[0])
2007 {
2008 int nc = ninput ();
2009 llassert ((char) nc == AFTER_COMMENT_MARKER[1]);
2010 charsread++;
2011 }
2012
2013 os = s;
2014
2015 while (*s == ' ' || *s == '\t' || *s == '\n')
2016 {
2017 s++;
2018 }
2019
2020 if (*s == '-' || *s == '+' || *s == '=') /* setting flags */
2021 {
2022 c = *s;
2023
2024 while (c == '-' || c == '+' || c == '=')
2025 {
2026 ynm set = ynm_fromCodeChar (c);
2027 cstring thisflag;
2028
2029 s++;
2030
2031 thisflag = cstring_fromChars (s);
2032
2033 while ((c = *s) != '\0' && (c != '-') && (c != '=')
2034 && (c != '+') && (c != ' ') && (c != '\t') && (c != '\n'))
2035 {
2036 s++;
2037 }
2038
2039 *s = '\0';
2040
2041 if (!context_getFlag (FLG_NOCOMMENTS))
2042 {
2043 cstring flagname = thisflag;
27c9e640 2044 flagcode fflag = flags_identifyFlag (flagname);
77d37419 2045
ac0860d8 2046 if (flagcode_isSkip (fflag))
2047 {
2048 ;
2049 }
140c27a8 2050 else if (flagcode_isModeName (fflag))
ac0860d8 2051 {
140c27a8 2052 if (ynm_isMaybe (set))
ac0860d8 2053 {
140c27a8 2054 llerror
2055 (FLG_BADFLAG,
2056 message
2057 ("Semantic comment attempts to restore flag %s. "
2058 "A mode flag cannot be restored.",
2059 flagname));
ac0860d8 2060 }
2061 else
2062 {
140c27a8 2063 context_setMode (flagname);
ac0860d8 2064 }
2065 }
140c27a8 2066 else if (flagcode_isInvalid (fflag))
2067 {
2068 voptgenerror
2069 (FLG_UNRECOGFLAGCOMMENTS,
2070 message ("Unrecognized option in semantic comment: %s",
2071 flagname),
2072 loc);
2073 }
ac0860d8 2074 else if (flagcode_isGlobalFlag (fflag))
2075 {
2076 voptgenerror
2077 (FLG_BADFLAG,
2078 message
2079 ("Semantic comment attempts to set global flag %s. "
2080 "A global flag cannot be set locally.",
2081 flagname),
abd7f895 2082 loc);
ac0860d8 2083 }
2084 else
2085 {
abd7f895 2086 context_fileSetFlag (fflag, set, loc);
ac0860d8 2087
2088 if (flagcode_hasArgument (fflag))
2089 {
2090 if (ynm_isMaybe (set))
2091 {
2092 voptgenerror
2093 (FLG_BADFLAG,
2094 message
2095 ("Semantic comment attempts to restore flag %s. "
2096 "A flag for setting a value cannot be restored.",
2097 flagname),
abd7f895 2098 loc);
ac0860d8 2099 }
2100 else
2101 { /* cut-and-pastied from llmain...blecch */
2102 cstring extra = cstring_undefined;
2103 char *rest;
2104 char *orest;
2105 char rchar;
2106
2107 *s = c;
2108 rest = mstring_copy (s);
2109 orest = rest;
2110 *s = '\0';
2111
2112 while ((rchar = *rest) != '\0'
2113 && (isspace (rchar)))
2114 {
2115 rest++;
2116 s++;
2117 }
2118
2119 while ((rchar = *rest) != '\0'
2120 && !isspace (rchar))
2121 {
2122 extra = cstring_appendChar (extra, rchar);
2123 rest++;
2124 s++;
2125 }
2126
2127 sfree (orest);
2128
2129 if (cstring_isUndefined (extra))
2130 {
2131 llerror
2132 (FLG_BADFLAG,
2133 message
2134 ("Flag %s (in semantic comment) must be followed by an argument",
2135 flagcode_unparse (fflag)));
2136 }
2137 else
2138 {
2139 s--;
2140
4f43223c 2141 if (flagcode_hasNumber (fflag))
2142 {
2143 setValueFlag (fflag, extra);
2144 }
2145 else if (flagcode_hasChar (fflag))
ac0860d8 2146 {
2147 setValueFlag (fflag, extra);
2148 }
2149 else if (flagcode_hasString (fflag))
2150 {
2151 setStringFlag (fflag, extra);
2152 }
2153 else
2154 {
2155 BADEXIT;
2156 }
2157 }
2158 }
2159 }
2160 }
2161 }
2162 else
2163 {
2164 ;
2165 }
2166
2167 *s = c;
2168 while ((c == ' ') || (c == '\t') || (c == '\n'))
2169 {
2170 c = *(++s);
2171 }
2172 }
2173
2174 if (context_inHeader () && !isArtificial (cstring_fromChars (os)))
2175 {
2176 DPRINTF (("Here adding comment: %s", os));
abd7f895 2177 context_addComment (cstring_fromCharsNew (os), loc);
ac0860d8 2178 }
2179 else
2180 {
2181 ;
2182 }
2183 }
2184 else
2185 {
2186 char *t = s;
2187 int macrocode;
2188 char tchar = '\0';
2189 annotationInfo ainfo;
2190
2191 while (*s != '\0' && *s != ' ' && *s != '\t' && *s != '\n')
2192 {
2193 s++;
2194 }
2195
2196 if (*s != '\0')
2197 {
2198 tchar = *s;
2199 *s = '\0';
2200 s++;
2201 }
2202
2203 t = cstring_toCharsSafe (cstring_downcase (cstring_fromChars (t)));
2204 macrocode = tokenMacroCode (cstring_fromChars (t));
2205
2206 if (macrocode != BADTOK)
2207 {
2208 tokLength = hasnl ? 0 : mstring_length (t);
2209
2210 sfree (t);
2211 sfree (os);
2212 fileloc_free (loc);
2213
2214 if (macrocode == SKIPTOK)
2215 {
2216 return BADTOK;
2217 }
2218
2219 return macrocode;
2220 }
2221
2222 ainfo = context_lookupAnnotation (cstring_fromChars (os));
2223
2224 if (annotationInfo_isDefined (ainfo)) {
2225 DPRINTF (("Found annotation: %s", annotationInfo_unparse (ainfo)));
2226 /*@i324@*/ yylval.annotation = ainfo;
2227 tokLength = 0;
2228 sfree (os);
2229 sfree (t);
2230 fileloc_free (loc);
2231 return CANNOTATION;
2232 }
2233
2234 if (context_inHeader ())
2235 {
2236 if (tchar != '\0')
2237 {
2238 *(s-1) = tchar;
2239 }
2240
2241 if ((context_inMacro () || context_inGlobalContext ())
2242 && macrocode != SKIPTOK
2243 && !isArtificial (cstring_fromChars (os)))
2244 {
abd7f895 2245 if (context_processingMacros ())
2246 {
2247 /* evans 2002-02-24: don't add comments when procssing macros */
2248 }
2249 else
2250 {
2251 context_addComment (cstring_fromCharsNew (os), loc);
2252 }
ac0860d8 2253 }
2254 else
2255 {
2256 ;
2257 }
2258
2259 if (tchar != '\0')
2260 {
2261 *(s-1) = '\0';
2262 }
2263 }
2264
2265 if (mstring_equal (t, "ignore"))
2266 {
2267 if (!context_getFlag (FLG_NOCOMMENTS))
2268 {
abd7f895 2269 context_enterSuppressRegion (loc);
ac0860d8 2270 }
2271 }
2272 else if ((*t == 'i' || *t == 't')
2273 && (*(t + 1) == '\0'))
2274 {
2275 if (!context_getFlag (FLG_NOCOMMENTS)
2276 && (*t == 'i' || context_getFlag (FLG_TMPCOMMENTS)))
2277 {
abd7f895 2278 context_enterSuppressLine (-1, loc); /* infinite suppression */
ac0860d8 2279 }
2280 }
2281 else if (((*t == 'i') || (*t == 't'))
2282 && ((*(t + 1) >= '0' && *(t + 1) <= '9')))
2283 {
2284 bool tmpcomment = (*t == 't');
2285 int val = -1;
2286 char *tt = t; /* don't mangle t, since it is free'd */
2287 char lc = *(++tt);
2288
2289 if (lc >= '0' && lc <= '9')
2290 {
2291 val = (int)(lc - '0');
2292
2293 lc = *(++tt);
2294 while (lc >= '0' && lc <= '9')
2295 {
2296 val *= 10;
2297 val += lc - '0';
2298 lc = *(++tt);
2299 }
2300 }
ac0860d8 2301
2302 if (!context_getFlag (FLG_NOCOMMENTS)
2303 && (!tmpcomment || context_getFlag (FLG_TMPCOMMENTS)))
2304 {
abd7f895 2305 DPRINTF (("Here: enter suppress: %s", fileloc_unparse (loc)));
2306 context_enterSuppressLine (val, loc);
ac0860d8 2307 }
2308 }
2309 else if (mstring_equal (t, "end"))
2310 {
2311 if (!context_getFlag (FLG_NOCOMMENTS))
2312 {
abd7f895 2313 context_exitSuppressRegion (loc);
ac0860d8 2314 }
2315 }
2316 else if (mstring_equal (t, "notfunction"))
2317 {
2318 ; /* handled by pcpp */
2319 }
2320 else if (mstring_equal (t, "access"))
2321 {
2322 cstring tname;
2323
2324 while (TRUE)
2325 {
2326 while ((c = *s) && (c == ' ' || c == '\t' || c == '\n'))
2327 {
2328 s++;
2329 }
2330
2331 if (c == '\0')
2332 {
2333 break;
2334 }
2335
2336 tname = cstring_fromChars (s);
2337
2338 while ((c = *s) != '\0' && c != ' '
2339 && c != '\t' && c != '\n' && c != ',')
2340 {
2341 s++;
2342 }
2343
2344 *s = '\0';
2345
2346 DPRINTF (("Access %s", tname));
2347
2348 if (!context_getFlag (FLG_NOCOMMENTS)
2349 && !context_getFlag (FLG_NOACCESS))
2350 {
2351 if (usymtab_existsType (tname))
2352 {
2353 typeId uid = usymtab_getTypeId (tname);
2354 uentry ue = usymtab_getTypeEntry (uid);
2355
2356 if (uentry_isAbstractDatatype (ue))
2357 {
2358 context_addFileAccessType (uid);
2359 DPRINTF (("Adding access to: %s / %d", tname, uid));
2360 }
2361 else
2362 {
2363 voptgenerror
2364 (FLG_COMMENTERROR,
2365 message
2366 ("Non-abstract type %s used in access comment",
2367 tname),
abd7f895 2368 loc);
ac0860d8 2369 }
2370 }
2371 else
2372 {
2373 if (!(context_inSuppressRegion ()
abd7f895 2374 || context_inSuppressZone (loc)))
ac0860d8 2375 {
2376 voptgenerror
2377 (FLG_COMMENTERROR,
2378 message
2379 ("Unrecognized type %s used in access comment",
2380 tname),
abd7f895 2381 loc);
ac0860d8 2382 }
2383 }
2384 }
2385
2386 if (c != '\0')
2387 {
2388 s++;
2389 }
2390
2391 if (c != ',' && c != ' ')
2392 {
2393 break;
2394 }
2395 }
2396 }
2397 else if (mstring_equal (t, "noaccess"))
2398 {
2399 cstring tname;
2400 char lc;
2401
2402 while (TRUE)
2403 {
2404 while ((lc = *s) && (lc == ' ' || lc == '\t' || lc == '\n'))
2405 {
2406 s++;
2407 }
2408
2409 if (lc == '\0')
2410 {
2411 break;
2412 }
2413
2414 tname = cstring_fromChars (s);
2415
2416 while ((lc = *s) != '\0' && lc != ' ' && lc != '\t'
2417 && lc != '\n' && lc != ',')
2418 {
2419 s++;
2420 }
2421
2422 *s = '\0';
2423
2424 if (!context_getFlag (FLG_NOCOMMENTS)
2425 && !context_getFlag (FLG_NOACCESS))
2426 {
2427 if (usymtab_existsType (tname))
2428 {
2429 typeId tuid = usymtab_getTypeId (tname);
2430
2431 if (context_couldHaveAccess (tuid))
2432 {
2433 DPRINTF (("Removing access: %s", tname));
2434 context_removeFileAccessType (tuid);
2435 }
2436 else
2437 {
2438 if (!(context_inSuppressRegion ()
abd7f895 2439 || context_inSuppressZone (loc)))
ac0860d8 2440 {
2441 uentry ue = usymtab_getTypeEntry (tuid);
2442
2443 if (uentry_isAbstractDatatype (ue))
2444 {
2445 voptgenerror
2446 (FLG_COMMENTERROR,
2447 message
2448 ("Non-accessible abstract type %s used in noaccess comment",
2449 tname),
abd7f895 2450 loc);
ac0860d8 2451 }
2452 else
2453 {
2454 voptgenerror
2455 (FLG_COMMENTERROR,
2456 message
2457 ("Non-abstract type %s used in noaccess comment",
2458 tname),
abd7f895 2459 loc);
ac0860d8 2460 }
2461 }
2462 }
2463 }
2464 else
2465 {
2466 if (!(context_inSuppressRegion ()
abd7f895 2467 || context_inSuppressZone (loc)))
ac0860d8 2468 {
2469 voptgenerror
2470 (FLG_COMMENTERROR,
2471 message
2472 ("Unrecognized type %s used in noaccess comment",
2473 tname),
abd7f895 2474 loc);
ac0860d8 2475 }
2476 }
2477 }
2478
2479 if (lc != '\0')
2480 {
2481 s++;
2482 }
2483
2484 if (lc != ',' && lc != ' ')
2485 {
2486 break;
2487 }
2488 }
2489 }
2490 else
2491 {
2492 voptgenerror (FLG_UNRECOGCOMMENTS,
2493 message ("Semantic comment unrecognized: %s",
abd7f895 2494 cstring_fromChars (os)),
2495 loc);
ac0860d8 2496 }
abd7f895 2497
ac0860d8 2498 sfree (t);
2499 }
2500
2501 sfree (os);
2502 fileloc_free (loc);
2503 return BADTOK;
2504}
2505
2506static /*@only@*/ cstring makeIdentifier (char *s)
2507{
2508 char *c = mstring_create (size_toInt (strlen (s)) + 1);
2509 cstring id = cstring_fromChars (c);
2510
2511 while (isalnum (*s) || (*s == '_') || (*s == '$'))
2512 {
2513 *c++ = *s++;
2514 }
2515
2516 *c = '\0';
2517 return (id);
2518}
2519
2520/*@observer@*/ /*@dependent@*/ uentry coerceId (cstring cn)
2521{
2522 if (!(usymtab_exists (cn)))
2523 {
2524 fileloc loc = fileloc_createExternal ();
2525
2526 /*
2527 ** We need to put this in a global scope, otherwise the sRef will be deallocated.
2528 */
2529
2530 uentry ce = uentry_makeUnrecognized (cn, loc);
2531
2532 if (!context_inIterEnd ())
2533 {
2534 voptgenerror
2535 (FLG_SYSTEMUNRECOG,
2536 message ("Unrecognized (possibly system) identifier: %q",
2537 uentry_getName (ce)),
2538 g_currentloc);
2539 }
2540
2541 return ce;
2542 }
2543
2544 return (usymtab_lookup (cn));
2545}
2546
2547/*
2548** like, coerceId, but doesn't supercede for iters
2549*/
2550
2551/*@observer@*/ uentry coerceIterId (cstring cn)
2552{
2553 if (!(usymtab_exists (cn)))
2554 {
2555 return uentry_undefined;
2556 }
2557
2558 return (usymtab_lookup (cn));
2559}
2560
2561/*@observer@*/ cstring LastIdentifier ()
2562{
2563 return (lastidprocessed);
2564}
2565
2566static int processIdentifier (cstring id)
2567{
2568 uentry le;
2569
2570 if (context_getFlag (FLG_GRAMMAR))
2571 {
2572 lldiagmsg (message ("Process identifier: %s", id));
2573 }
2574
2575 context_clearJustPopped ();
2576 lastidprocessed = id;
2577
2578 if (context_inFunctionHeader ())
2579 {
2580 int tok = commentMarkerToken (id);
2581 DPRINTF (("in function decl..."));
2582
2583 if (tok != BADTOK)
2584 {
2585 return tok;
2586 }
2587 else
2588 {
2589 tok = tokenMacroCode (id);
2590
2591 if (tok != BADTOK)
2592 {
2593 return tok;
2594 }
2595 else
2596 {
2597 annotationInfo ainfo;
2598
2599 if (expectingMetaStateName)
2600 {
2601 metaStateInfo msinfo = context_lookupMetaStateInfo (id);
2602
2603 if (metaStateInfo_isDefined (msinfo))
2604 {
2605 yylval.msinfo = msinfo;
2606 return METASTATE_NAME;
2607 }
2608 else
2609 {
2610 DPRINTF (("Not meta state name: %s", cstring_toCharsSafe (id)));
2611 }
2612 }
2613
2614 ainfo = context_lookupAnnotation (id);
2615
2616 if (annotationInfo_isDefined (ainfo))
2617 {
2618 DPRINTF (("Found annotation: %s", annotationInfo_unparse (ainfo)));
2619 /*@i324@*/ yylval.annotation = ainfo;
2620 return CANNOTATION;
2621 }
2622 else
2623 {
2624 DPRINTF (("Not annotation: %s", id));
2625 }
2626 }
2627 }
2628 }
2629
2630 /* Consider handling: Defined by C99 as static const char __func__[] */
2631
2632 if (context_getFlag (FLG_GNUEXTENSIONS))
2633 {
2634 int tok = BADTOK;
2635
2636 if (cstring_equalLit (id, "__stdcall")
2637 || cstring_equalLit (id, "__cdecl")
2638 || cstring_equalLit (id, "__extension__"))
2639 {
2640 return BADTOK;
2641 }
2642 else if (cstring_equalLit (id, "__volatile__"))
2643 {
2644 tok = QVOLATILE;
2645 }
2646 else if (cstring_equalLit (id, "__signed"))
2647 {
2648 tok = QSIGNED;
2649 }
2650 else if (cstring_equalLit (id, "__unsigned"))
2651 {
2652 tok = QUNSIGNED;
2653 }
2654 else if (cstring_equalLit (id, "__const__"))
2655 {
2656 tok = QCONST;
2657 }
2658 else if (cstring_equalLit (id, "__alignof__"))
2659 {
2660 tok = CALIGNOF; /* alignof is parsed like sizeof */
2661 }
abd7f895 2662 else if (cstring_equalLit (id, "__typeof__"))
2663 {
2664 tok = CTYPEOF;
2665 }
2666 else if (cstring_equalLit (id, "typeof"))
2667 {
2668 tok = CTYPEOF;
2669 }
ac0860d8 2670 else if (cstring_equalLit (id, "__FUNCTION__")
2671 || cstring_equalLit (id, "__PRETTY_FUNCTION__"))
2672 {
2673 /* These tokens hold the name of the current function as strings */
5c2f3045 2674 /* evans 2001-12-30: changed from exprNode_stringLiteral; bug reported by Jim Zelenka. */
2675 yylval.expr = exprNode_makeConstantString (id, fileloc_copy (g_currentloc));
ac0860d8 2676 tokLength = 0;
2677 lastWasString = TRUE;
2678 tok = CCONSTANT;
2679 return tok;
2680 }
2681 else if (cstring_equalLit (id, "__attribute__")
2682 || cstring_equalLit (id, "__asm__")
2683 || cstring_equalLit (id, "_asm")
2684 || cstring_equalLit (id, "__asm")
2685 || cstring_equalLit (id, "__declspec"))
2686 {
2687 int depth = 0;
2688 bool useparens = FALSE;
2689 bool usebraces = FALSE;
2690 bool inquote = FALSE;
2691 bool inescape = FALSE;
2692 int ic;
2693
2694 while ((ic = input ()) != EOF)
2695 {
2696
2697 if (inescape)
2698 {
2699 inescape = FALSE;
2700 }
2701 else if (ic == '\\')
2702 {
2703 inescape = TRUE;
2704 }
2705 else if (ic == '\"')
2706 {
2707 inquote = !inquote;
2708 }
2709 else if (!inquote)
2710 {
2711 if (ic == '(')
2712 {
2713 if (!useparens)
2714 {
2715 if (!usebraces)
2716 {
2717 useparens = TRUE;
2718 }
2719 }
2720
2721 if (useparens)
2722 {
2723 depth++;
2724 }
2725 }
2726 else if (ic == '{')
2727 {
2728 if (!usebraces)
2729 {
2730 if (!useparens)
2731 {
2732 usebraces = TRUE;
2733 }
2734 }
2735
2736 if (usebraces)
2737 {
2738 depth++;
2739 }
2740 }
2741 else if (ic == ')' && useparens)
2742 {
2743 depth--;
2744 if (depth == 0) break;
2745 }
2746 else if (ic == '}' && usebraces)
2747 {
2748 depth--;
2749 if (depth == 0) break;
2750 }
2751 else if (ic == '}'
2752 && !usebraces && !useparens
2753 && cstring_equalLit (id, "__asm"))
2754 {
2755 /*
2756 ** We need this because some MS VC++ include files
2757 ** have __asm mov ... }
2758 ** Its a kludge, but otherwise would need to parse
2759 ** the asm code!
2760 */
2761 return TRBRACE;
2762 }
2763 }
2764
2765 if (ic == '\n')
2766 {
2767 context_incLineno ();
2768
2769 if (cstring_equalLit (id, "__asm")
2770 && !useparens && !usebraces)
2771 {
2772 break;
2773 }
2774 }
2775 }
2776
2777 llassert ((useparens && ic == ')')
2778 || (usebraces && ic == '}')
2779 || (!useparens && !usebraces));
2780
2781 return BADTOK;
2782 }
2783 else if (cstring_equalLit (id, "inline")
2784 || cstring_equalLit (id, "__inline")
2785 || cstring_equalLit (id, "_inline")
2786 || cstring_equalLit (id, "__inline__"))
2787 {
2788 tok = QINLINE;
2789 }
2790
2791 if (tok != BADTOK)
2792 {
2793 RETURN_TOK (tok);
2794 }
2795 }
2796
2797 le = usymtab_lookupSafe (id);
2798
2799 /*@-dependenttrans@*/
2800
2801 if (uentry_isIter (le))
2802 {
2803 /*@i32@*/ yylval.entry = le;
2804 return (ITER_NAME);
2805 }
2806 else if (uentry_isEndIter (le))
2807 {
2808 /*@i32@*/ yylval.entry = le;
2809 return (ITER_ENDNAME);
2810 }
2811 else if (uentry_isUndefined (le))
2812 {
2813 yylval.cname = id;
2814
2815 /* avoid parse errors for certain system built ins */
2816
2817 if (g_expectingTypeName && (cstring_firstChar (id) == '_')
2818 && (cstring_secondChar (id) == '_'))
2819 {
2820 return (TYPE_NAME_OR_ID);
2821 }
2822
2823 return (NEW_IDENTIFIER);
2824 }
2825 else if (!uentry_isDeclared (le) && !uentry_isCodeDefined (le))
2826 {
2827 if (uentry_isDatatype (le))
2828 {
2829 yylval.cname = id;
2830 return (NEW_IDENTIFIER);
2831 }
2832 else
2833 {
2834 /*@i32@*/ yylval.entry = le;
2835 return (IDENTIFIER);
2836 }
2837 }
2838 else if (uentry_isDatatype (le))
2839 {
2840 if (!g_expectingTypeName)
2841 {
2842 yylval.cname = id;
2843
2844 return (NEW_IDENTIFIER);
2845 }
2846 else
2847 {
2848 yylval.ctyp = uentry_getAbstractType (le);
2849
2850 uentry_setUsed (le, g_currentloc);
2851 return (TYPE_NAME);
2852 }
2853 }
2854 else
2855 {
2856 /*@i32@*/ yylval.entry = le;
2857 return (IDENTIFIER);
2858 }
2859
2860 /*@=dependenttrans@*/
2861}
2862
2863static bool processHashIdentifier (/*@only@*/ cstring id)
2864{
2865 if (context_inMacro () || context_inIterDef () ||
2866 context_inIterEnd ())
2867 {
2868 uentry le;
2869
2870 context_clearJustPopped ();
2871
2872 lastidprocessed = id;
2873 le = usymtab_lookupSafe (id);
2874
2875 if (uentry_isParam (le) || uentry_isRefParam (le))
2876 {
2877 return TRUE;
2878 }
2879 else
2880 {
2881 return FALSE;
2882 }
2883 }
2884 else
2885 {
4c9767b3 2886 /*
2887 ** Will be handled by handleLlSpecial
2888 */
2889
ac0860d8 2890 cstring_free (id);
2891 return FALSE;
2892 }
2893}
2894
2895
2896static /*@only@*/ exprNode processString ()
2897{
2898 exprNode res;
2899 fileloc loc;
2900 char *nl = strchr (yytext, '\n');
2901 cstring ns = cstring_fromCharsNew (yytext);
2902
2903 if (nl == NULL)
2904 {
2905 loc = fileloc_copy (g_currentloc);
2906 addColumn (cstring_length (ns));
2907 }
2908 else
2909 {
2910 char *lastnl = nl;
2911
2912 loc = fileloc_copy (g_currentloc);
2913
2914 context_incLineno ();
2915
2916 while ((nl = strchr ((nl + 1), '\n')) != NULL)
2917 {
2918 context_incLineno ();
2919 lastnl = nl;
2920 }
2921 }
2922
2923
2924 res = exprNode_stringLiteral (ns, loc);
2925 return (res);
2926}
2927
e0b363ad 2928/*
2929** process a wide character string L"...."
2930*/
2931
2932static /*@only@*/ exprNode processWideString ()
2933{
2934 exprNode res;
2935 fileloc loc;
2936 char *nl = strchr (yytext, '\n');
2937 cstring ns;
2938
2939 llassert (*yytext == 'L');
2940 yytext++;
2941
2942 ns = cstring_fromCharsNew (yytext);
2943
2944 if (nl == NULL)
2945 {
2946 loc = fileloc_copy (g_currentloc);
2947 addColumn (cstring_length (ns));
2948 }
2949 else
2950 {
2951 char *lastnl = nl;
2952
2953 loc = fileloc_copy (g_currentloc);
2954
2955 context_incLineno ();
2956
2957 while ((nl = strchr ((nl + 1), '\n')) != NULL)
2958 {
2959 context_incLineno ();
2960 lastnl = nl;
2961 }
2962 }
2963
2964 res = exprNode_wideStringLiteral (ns, loc);
2965 return (res);
2966}
2967
ac0860d8 2968static
2969char processChar ()
2970{
2971 char fchar;
2972 char next;
2973
2974 llassert (*yytext != '\0');
2975 fchar = *(yytext + 1);
2976 if (fchar != '\\') return fchar;
2977
2978 next = *(yytext + 2);
2979
2980 switch (next)
2981 {
2982 case 'n': return '\n';
2983 case 't': return '\t';
2984 case '\"': return '\"';
2985 case '\'': return '\'';
2986 case '\\': return '\\';
2987 default: return '\0';
2988 }
2989}
2990
2991static
2992double processFloat ()
2993{
2994 double ret = atof (yytext);
2995
2996 return (ret);
2997}
2998
2999static
3000long processHex ()
3001{
3002 int index = 2;
3003 long val = 0;
3004
3005 llassert (yytext[0] == '0'
3006 && (yytext[1] == 'X' || yytext[1] == 'x'));
3007
3008 while (yytext[index] != '\0') {
3009 int tval;
3010 char c = yytext[index];
3011
3012 if (c >= '0' && c <= '9') {
3013 tval = (int) c - (int) '0';
3014 } else if (c >= 'A' && c <= 'F') {
3015 tval = (int) c - (int) 'A' + 10;
3016 } else if (c >= 'a' && c <= 'f') {
3017 tval = (int) c - (int) 'a' + 10;
3018 } else if (c == 'U' || c == 'L' || c == 'u' || c == 'l') {
3019 index++;
3020 while (yytext[index] != '\0') {
3021 if (c == 'U' || c == 'L' || c == 'u' || c == 'l') {
3022 ;
3023 } else {
3024 voptgenerror
3025 (FLG_SYNTAX,
3026 message ("Invalid character (%c) following specifier in hex constant: %s",
3027 c, cstring_fromChars (yytext)),
3028 g_currentloc);
3029 }
3030 index++;
3031 }
3032
3033 break;
3034 } else {
3035 voptgenerror
3036 (FLG_SYNTAX,
3037 message ("Invalid character (%c) in hex constant: %s",
3038 c, cstring_fromChars (yytext)),
3039 g_currentloc);
3040 break;
3041 }
3042
3043 val = (val * 16) + tval;
3044 index++;
3045 }
3046
3047 DPRINTF (("Hex constant: %s = %ld", yytext, val));
3048 return val;
3049}
3050
3051static
3052long processOctal ()
3053{
3054 int index = 1;
3055 long val = 0;
3056
3057 llassert (yytext[0] == '0' && yytext[1] != 'X' && yytext[1] != 'x');
3058
3059 while (yytext[index] != '\0') {
3060 int tval;
3061 char c = yytext[index];
3062
3063 if (c >= '0' && c <= '7') {
3064 tval = (int) c - (int) '0';
ee229125 3065 } else if (c == 'U' || c == 'L' || c == 'u' || c == 'l') {
3066 index++;
3067 while (yytext[index] != '\0') {
3068 if (c == 'U' || c == 'L' || c == 'u' || c == 'l') {
3069 ;
3070 } else {
3071 voptgenerror
3072 (FLG_SYNTAX,
3073 message ("Invalid character (%c) following specifier in octal constant: %s",
3074 c, cstring_fromChars (yytext)),
3075 g_currentloc);
3076 }
3077 index++;
3078 }
3079
3080 break;
ac0860d8 3081 } else {
3082 voptgenerror
3083 (FLG_SYNTAX,
3084 message ("Invalid character (%c) in octal constant: %s",
3085 c, cstring_fromChars (yytext)),
3086 g_currentloc);
3087 break;
3088 }
3089
3090 val = (val * 8) + tval;
3091 index++;
3092 }
3093
3094 DPRINTF (("Octal constant: %s = %ld", yytext, val));
3095 return val;
3096}
3097
3098static
3099long processDec ()
3100{
3101 return (atol (yytext));
3102}
3103
3104static int
3105processSpec (int tok)
3106{
3107 size_t length = strlen (yytext);
3108
3109 if (inSpecPart)
3110 {
3111 setTokLengthT (length);
3112 RETURN_TOK (tok);
3113 }
3114 else
3115 {
3116
3117 context_saveLocation ();
3118 setTokLengthT (length);
3119 return (processIdentifier (makeIdentifier (yytext)));
3120 }
3121}
3122
3123void cscanner_expectingMetaStateName ()
3124{
3125 llassert (!expectingMetaStateName);
3126 llassert (context_inFunctionHeader ());
3127 expectingMetaStateName = TRUE;
3128}
3129
3130void cscanner_clearExpectingMetaStateName ()
3131{
3132 llassert (expectingMetaStateName);
3133 expectingMetaStateName = FALSE;
3134}
This page took 0.536619 seconds and 5 git commands to generate.