Line data Source code
1 : %{
2 : /* m2.flex implements lexical analysis for Modula-2.
3 :
4 : Copyright (C) 2004-2026 Free Software Foundation, Inc.
5 : Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 :
7 : This file is part of GNU Modula-2.
8 :
9 : GNU Modula-2 is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3, or (at your option)
12 : any later version.
13 :
14 : GNU Modula-2 is distributed in the hope that it will be useful, but
15 : WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with GNU Modula-2; see the file COPYING3. If not see
21 : <http://www.gnu.org/licenses/>. */
22 :
23 : #include "gm2-gcc/gcc-consolidation.h"
24 :
25 : #include "GM2Reserved.h"
26 : #include "GM2LexBuf.h"
27 : #include "input.h"
28 : #include "m2options.h"
29 : #include "Gm2linemap.h"
30 :
31 : static int cpreprocessor = 0; /* Replace this with correct getter. */
32 :
33 : #if defined(GM2USEGGC)
34 : # include "ggc.h"
35 : #endif
36 :
37 : #include "timevar.h"
38 :
39 : #define START_FILE(F,L) m2linemap_StartFile(F,L)
40 : #define END_FILE() m2linemap_EndFile()
41 : #define START_LINE(N,S) m2linemap_StartLine(N,S)
42 : #define GET_LOCATION(COLUMN_START,COLUMN_END) \
43 : m2linemap_GetLocationRange(COLUMN_START,COLUMN_END)
44 : #define TIMEVAR_PUSH_LEX timevar_push (TV_LEX)
45 : #define TIMEVAR_POP_LEX timevar_pop (TV_LEX)
46 :
47 : #ifdef __cplusplus
48 : #define EXTERN extern "C"
49 : #endif
50 :
51 : #define FIRST_COLUMN 1
52 :
53 : /* m2.flex provides a lexical analyser for GNU Modula-2. */
54 :
55 : struct lineInfo {
56 : char *linebuf; /* line contents */
57 : int linelen; /* length */
58 : int tokenpos; /* start position of token within line */
59 : int toklen; /* a copy of yylen (length of token) */
60 : int nextpos; /* position after token */
61 : int lineno; /* line number of this line */
62 : int column; /* first column number of token on this line */
63 : bool inuse; /* do we need to keep this line info? */
64 : location_t location; /* the corresponding gcc location_t */
65 : struct lineInfo *next;
66 : };
67 :
68 : struct functionInfo {
69 : char *name; /* function name */
70 : bool module; /* is it really a module? */
71 : struct functionInfo *next; /* list of nested functions */
72 : };
73 :
74 : static int lineno =1; /* a running count of the file line number */
75 : static char *filename =NULL;
76 : static int commentLevel=0;
77 : static int commentCLevel=0;
78 : static struct lineInfo *currentLine=NULL;
79 : static struct functionInfo *currentFunction=NULL;
80 : static bool seenFunctionStart=false;
81 : static bool seenEnd=false;
82 : static bool seenModuleStart=false;
83 : static bool isDefinitionModule=false;
84 : static int totalLines=0;
85 :
86 : static void pushLine (void);
87 : static void popLine (void);
88 : static void finishedLine (void);
89 : static void resetpos (void);
90 : static void consumeLine (void);
91 : static void updatepos (void);
92 : static void skippos (void);
93 : static void poperrorskip (const char *);
94 : static void endOfComment (void);
95 : static void endOfCComment (void);
96 : static void splitSlashStar (void);
97 : static void handleDate (void);
98 : static void handleLine (void);
99 : static void handleFile (void);
100 : static void handleFunction (void);
101 : static void handleColumn (void);
102 : static void pushFunction (char *function, bool module);
103 : static void popFunction (void);
104 : static void checkFunction (void);
105 : EXTERN void m2flex_M2Error (const char *);
106 : EXTERN location_t m2flex_GetLocation (void);
107 : EXTERN int m2flex_GetColumnNo (void);
108 : EXTERN bool m2flex_OpenSource (char *s);
109 : EXTERN int m2flex_GetLineNo (void);
110 : EXTERN void m2flex_CloseSource (void);
111 : EXTERN char *m2flex_GetToken (void);
112 : EXTERN void _M2_m2flex_init (void);
113 : EXTERN int m2flex_GetTotalLines (void);
114 : extern void yylex (void);
115 :
116 : #define YY_DECL void yylex (void)
117 : %}
118 :
119 : %option nounput
120 : %x COMMENT COMMENT1 COMMENTC LINE0 LINE1 LINE2
121 :
122 : %%
123 :
124 4480916 : "(*" { updatepos();
125 4480916 : commentLevel=1; pushLine(); skippos();
126 4480916 : BEGIN COMMENT; }
127 9107476 : <COMMENT>"*)" { endOfComment(); }
128 4772216 : <COMMENT>"(*" { commentLevel++; pushLine(); updatepos(); skippos(); }
129 4643565 : <COMMENT>"<*" { if (commentLevel == 1) {
130 162655 : updatepos();
131 34004 : pushLine();
132 16999 : skippos();
133 16999 : BEGIN COMMENT1;
134 : } else {
135 6 : updatepos(); skippos();
136 : }
137 : }
138 18714391 : <COMMENT>\n.* { consumeLine(); }
139 790732421 : <COMMENT>. { updatepos(); skippos(); }
140 169990 : <COMMENT1>. { updatepos(); skippos(); }
141 790749420 : <COMMENT1>"*>" { updatepos(); skippos(); finishedLine(); BEGIN COMMENT; }
142 169990 : <COMMENT1>\n.* { consumeLine(); }
143 16999 : <COMMENT1>"*)" { poperrorskip("unterminated source code directive, missing *>");
144 0 : endOfComment(); }
145 0 : <COMMENT1><<EOF>> { poperrorskip("unterminated source code directive, missing *>"); BEGIN COMMENT; }
146 0 : <COMMENT><<EOF>> { poperrorskip("unterminated comment found at the end of the file, missing *)"); BEGIN INITIAL; }
147 12 :
148 0 : "/*" { /* Possibly handle C preprocessor comment. */
149 0 : if (cpreprocessor)
150 : {
151 0 : updatepos ();
152 0 : commentCLevel++;
153 0 : if (commentCLevel == 1)
154 : {
155 0 : pushLine ();
156 0 : skippos ();
157 : }
158 0 : BEGIN COMMENTC;
159 : }
160 : else
161 0 : splitSlashStar ();
162 : }
163 0 : <COMMENTC>. { updatepos(); skippos(); }
164 0 : <COMMENTC>\n.* { consumeLine(); }
165 0 : <COMMENTC>"*/" { endOfCComment(); }
166 18254 : ^\#.* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */
167 18254 : if (M2Options_GetLineDirectives ())
168 36508 : BEGIN LINE0;
169 : }
170 14695 : \n\#.* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */
171 14695 : if (M2Options_GetLineDirectives ())
172 14695 : BEGIN LINE0;
173 14695 : }
174 14695 : <LINE0>\#[ \t]* { updatepos(); }
175 47644 : <LINE0>[0-9]+[ \t]*\" { updatepos(); lineno=atoi(yytext); BEGIN LINE1; }
176 47644 : <LINE0>\n { m2flex_M2Error("missing initial quote after #line directive"); resetpos(); BEGIN INITIAL; }
177 32949 : <LINE0>[^\n]
178 0 : <LINE1>[^\"\n]+ { m2flex_M2Error("missing final quote after #line directive"); resetpos(); BEGIN INITIAL; }
179 51203 : <LINE1>.*\" { updatepos();
180 32949 : filename = (char *)xrealloc(filename, yyleng+1);
181 32949 : strcpy(filename, yytext);
182 32949 : filename[yyleng-1] = (char)0; /* remove trailing quote */
183 32949 : START_FILE (filename, lineno);
184 32949 : BEGIN LINE2;
185 : }
186 32949 : <LINE2>[ \t]* { updatepos(); }
187 32949 : <LINE2>\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
188 36345 : <LINE2>2[ \t]*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
189 3396 : <LINE2>1[ \t]*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
190 19365 : <LINE2>1[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
191 6792 : <LINE2>2[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
192 10188 : <LINE2>3[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
193 13584 :
194 0 : \n[^\#].* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */ }
195 48827743 : \n { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */ }
196 49075850 :
197 456006 : \"[^\"\n]*\" { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
198 714301 : \"[^\"\n]*$ { updatepos();
199 0 : m2flex_M2Error("missing terminating quote, \"");
200 0 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext);
201 0 : resetpos(); return;
202 0 : }
203 0 :
204 1000556 : '[^'\n]*' { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
205 1000562 : '[^'\n]*$ { updatepos();
206 6 : m2flex_M2Error("missing terminating quote, '");
207 6 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext);
208 12 : resetpos(); return;
209 6 : }
210 6 :
211 258756 : <<EOF>> { updatepos(); M2LexBuf_AddTok(M2Reserved_eoftok); return; }
212 438480 : \+ { updatepos(); M2LexBuf_AddTok(M2Reserved_plustok); return; }
213 420474 : - { updatepos(); M2LexBuf_AddTok(M2Reserved_minustok); return; }
214 562329 : "*" { updatepos(); M2LexBuf_AddTok(M2Reserved_timestok); return; }
215 693472 : \/ { updatepos(); M2LexBuf_AddTok(M2Reserved_dividetok); return; }
216 3951227 : := { updatepos(); M2LexBuf_AddTok(M2Reserved_becomestok); return; }
217 14242 : \& { updatepos(); M2LexBuf_AddTok(M2Reserved_ambersandtok); return; }
218 6480646 : \. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodtok); return; }
219 11888194 : \, { updatepos(); M2LexBuf_AddTok(M2Reserved_commatok); return; }
220 22205531 : \; { updatepos(); M2LexBuf_AddTok(M2Reserved_semicolontok); return; }
221 27069614 : \( { updatepos(); M2LexBuf_AddTok(M2Reserved_lparatok); return; }
222 34733689 : \) { updatepos(); M2LexBuf_AddTok(M2Reserved_rparatok); return; }
223 16324118 : \[ { updatepos(); M2LexBuf_AddTok(M2Reserved_lsbratok); return; }
224 16324098 : \] { updatepos(); M2LexBuf_AddTok(M2Reserved_rsbratok); return; }
225 1142698 : \(\! { updatepos(); M2LexBuf_AddTok(M2Reserved_lsbratok); return; }
226 1142672 : \!\) { updatepos(); M2LexBuf_AddTok(M2Reserved_rsbratok); return; }
227 1361153 : \^ { updatepos(); M2LexBuf_AddTok(M2Reserved_uparrowtok); return; }
228 0 : \@ { updatepos(); M2LexBuf_AddTok(M2Reserved_uparrowtok); return; }
229 1398013 : \{ { updatepos(); M2LexBuf_AddTok(M2Reserved_lcbratok); return; }
230 36860 : \} { updatepos(); M2LexBuf_AddTok(M2Reserved_rcbratok); return; }
231 36860 : \(\: { updatepos(); M2LexBuf_AddTok(M2Reserved_lcbratok); return; }
232 36860 : \:\) { updatepos(); M2LexBuf_AddTok(M2Reserved_rcbratok); return; }
233 0 : \' { updatepos(); M2LexBuf_AddTok(M2Reserved_singlequotetok); return; }
234 1371954 : \= { updatepos(); M2LexBuf_AddTok(M2Reserved_equaltok); return; }
235 573129 : \# { updatepos(); M2LexBuf_AddTok(M2Reserved_hashtok); return; }
236 1803459 : \< { updatepos(); M2LexBuf_AddTok(M2Reserved_lesstok); return; }
237 852001 : \> { updatepos(); M2LexBuf_AddTok(M2Reserved_greatertok); return; }
238 431589 : \<\> { updatepos(); M2LexBuf_AddTok(M2Reserved_lessgreatertok); return; }
239 505530 : \<\= { updatepos(); M2LexBuf_AddTok(M2Reserved_lessequaltok); return; }
240 113538 : \>\= { updatepos(); M2LexBuf_AddTok(M2Reserved_greaterequaltok); return; }
241 762499 : "<*" { updatepos(); M2LexBuf_AddTok(M2Reserved_ldirectivetok); return; }
242 649295 : "*>" { updatepos(); M2LexBuf_AddTok(M2Reserved_rdirectivetok); return; }
243 639612 : \.\. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodperiodtok); return; }
244 547269 : \.\.\. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodperiodperiodtok); return; }
245 13670346 : \: { updatepos(); M2LexBuf_AddTok(M2Reserved_colontok); return; }
246 11428 : \" { updatepos(); M2LexBuf_AddTok(M2Reserved_doublequotestok); return; }
247 13640463 : \| { updatepos(); M2LexBuf_AddTok(M2Reserved_bartok); return; }
248 0 : \! { updatepos(); M2LexBuf_AddTok(M2Reserved_bartok); return; }
249 73888 : \~ { updatepos(); M2LexBuf_AddTok(M2Reserved_nottok); return; }
250 451708 : AND { updatepos(); M2LexBuf_AddTok(M2Reserved_andtok); return; }
251 1190995 : ARRAY { updatepos(); M2LexBuf_AddTok(M2Reserved_arraytok); return; }
252 2380816 : BEGIN { updatepos(); M2LexBuf_AddTok(M2Reserved_begintok); return; }
253 1191391 : BY { updatepos(); M2LexBuf_AddTok(M2Reserved_bytok); return; }
254 1974281 : CASE { updatepos(); M2LexBuf_AddTok(M2Reserved_casetok); return; }
255 73309 : CONST { updatepos(); M2LexBuf_AddTok(M2Reserved_consttok); return; }
256 219044 : DEFINITION { updatepos(); isDefinitionModule = true;
257 246784 : M2LexBuf_AddTok(M2Reserved_definitiontok); return; }
258 259928 : DIV { updatepos(); M2LexBuf_AddTok(M2Reserved_divtok); return; }
259 622482 : DO { updatepos(); M2LexBuf_AddTok(M2Reserved_dotok); return; }
260 896688 : ELSE { updatepos(); M2LexBuf_AddTok(M2Reserved_elsetok); return; }
261 767520 : ELSIF { updatepos(); M2LexBuf_AddTok(M2Reserved_elsiftok); return; }
262 5649596 : END { updatepos(); seenEnd=true;
263 4984003 : M2LexBuf_AddTok(M2Reserved_endtok); return; }
264 4839199 : EXCEPT { updatepos(); M2LexBuf_AddTok(M2Reserved_excepttok); return; }
265 106 : EXIT { updatepos(); M2LexBuf_AddTok(M2Reserved_exittok); return; }
266 91860 : EXPORT { updatepos(); M2LexBuf_AddTok(M2Reserved_exporttok); return; }
267 6078 : FINALLY { updatepos(); M2LexBuf_AddTok(M2Reserved_finallytok); return; }
268 148614 : FOR { updatepos(); M2LexBuf_AddTok(M2Reserved_fortok); return; }
269 6032 : FORWARD { updatepos(); M2LexBuf_AddTok(M2Reserved_forwardtok); return; }
270 418532 : FROM { updatepos(); M2LexBuf_AddTok(M2Reserved_fromtok); return; }
271 1939669 : IF { updatepos(); M2LexBuf_AddTok(M2Reserved_iftok); return; }
272 439708 : IMPLEMENTATION { updatepos(); M2LexBuf_AddTok(M2Reserved_implementationtok); return; }
273 2350564 : IMPORT { updatepos(); M2LexBuf_AddTok(M2Reserved_importtok); return; }
274 161658 : IN { updatepos(); M2LexBuf_AddTok(M2Reserved_intok); return; }
275 419702 : LOOP { updatepos(); M2LexBuf_AddTok(M2Reserved_looptok); return; }
276 216348 : MOD { updatepos(); M2LexBuf_AddTok(M2Reserved_modtok); return; }
277 284960 : MODULE { updatepos(); seenModuleStart=true;
278 409067 : M2LexBuf_AddTok(M2Reserved_moduletok); return; }
279 412897 : NOT { updatepos(); M2LexBuf_AddTok(M2Reserved_nottok); return; }
280 1240999 : OF { updatepos(); M2LexBuf_AddTok(M2Reserved_oftok); return; }
281 287874 : OR { updatepos(); M2LexBuf_AddTok(M2Reserved_ortok); return; }
282 1243831 : PACKEDSET { updatepos(); M2LexBuf_AddTok(M2Reserved_packedsettok); return; }
283 253373 : POINTER { updatepos(); M2LexBuf_AddTok(M2Reserved_pointertok); return; }
284 5423752 : PROCEDURE { updatepos(); seenFunctionStart=true;
285 5523103 : M2LexBuf_AddTok(M2Reserved_proceduretok); return; }
286 5500578 : QUALIFIED { updatepos(); M2LexBuf_AddTok(M2Reserved_qualifiedtok); return; }
287 11674 : UNQUALIFIED { updatepos(); M2LexBuf_AddTok(M2Reserved_unqualifiedtok); return; }
288 152073 : RECORD { updatepos(); M2LexBuf_AddTok(M2Reserved_recordtok); return; }
289 11770 : REM { updatepos(); M2LexBuf_AddTok(M2Reserved_remtok); return; }
290 144332 : REPEAT { updatepos(); M2LexBuf_AddTok(M2Reserved_repeattok); return; }
291 270 : RETRY { updatepos(); M2LexBuf_AddTok(M2Reserved_retrytok); return; }
292 1531570 : RETURN { updatepos(); M2LexBuf_AddTok(M2Reserved_returntok); return; }
293 2167 : SET { updatepos(); M2LexBuf_AddTok(M2Reserved_settok); return; }
294 3544300 : THEN { updatepos(); M2LexBuf_AddTok(M2Reserved_thentok); return; }
295 147898 : TO { updatepos(); M2LexBuf_AddTok(M2Reserved_totok); return; }
296 2206219 : TYPE { updatepos(); M2LexBuf_AddTok(M2Reserved_typetok); return; }
297 217822 : UNTIL { updatepos(); M2LexBuf_AddTok(M2Reserved_untiltok); return; }
298 1747224 : VAR { updatepos(); M2LexBuf_AddTok(M2Reserved_vartok); return; }
299 453668 : WHILE { updatepos(); M2LexBuf_AddTok(M2Reserved_whiletok); return; }
300 1822655 : WITH { updatepos(); M2LexBuf_AddTok(M2Reserved_withtok); return; }
301 381778 : ASM { updatepos(); M2LexBuf_AddTok(M2Reserved_asmtok); return; }
302 197018 : VOLATILE { updatepos(); M2LexBuf_AddTok(M2Reserved_volatiletok); return; }
303 27 : \_\_DATE\_\_ { updatepos(); handleDate(); return; }
304 128299 : \_\_LINE\_\_ { updatepos(); handleLine(); return; }
305 124696 : \_\_FILE\_\_ { updatepos(); handleFile(); return; }
306 251246 : \_\_FUNCTION\_\_ { updatepos(); handleFunction(); return; }
307 179304 : \_\_COLUMN\_\_ { updatepos(); handleColumn(); return; }
308 597750 : \_\_ATTRIBUTE\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_attributetok); return; }
309 969922 : \_\_BUILTIN\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_builtintok); return; }
310 474788 : \_\_INLINE\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_inlinetok); return; }
311 915314 :
312 0 :
313 28982 : (([0-9]*\.[0-9]+)(E[+-]?[0-9]+)?) { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_realtok, yytext); return; }
314 6 : [0-9]*\.E[+-]?[0-9]+ { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_realtok, yytext); return; }
315 71949870 : [a-zA-Z_][a-zA-Z0-9_]* { checkFunction(); updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_identtok, yytext); return; }
316 2421796 : [0-9]+ { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
317 71949894 : [0-1]+A { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
318 2424536 : [0-9]+B { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
319 136415 : [0-9]+C { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
320 14272 : [0-9A-F]+H { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
321 136391 : [\t\r ]+ { currentLine->tokenpos += yyleng; /* Ignore space. */; }
322 113037286 : . { updatepos(); m2flex_M2Error("unrecognised symbol"); skippos(); }
323 113025760 :
324 0 : %%
325 0 :
326 : /* have removed the -? from the beginning of the real/integer constant literal rules */
327 :
328 : /*
329 : * hand built routines
330 : */
331 :
332 : /*
333 : * handleFile - handles the __FILE__ construct by wraping it in double quotes and putting
334 : * it into the token buffer as a string.
335 : */
336 :
337 124696 : static void handleFile (void)
338 : {
339 124696 : char *s = (char *)alloca(strlen(filename)+2+1);
340 :
341 124696 : strcpy(s, "\"");
342 124696 : strcat(s, filename);
343 124696 : strcat(s, "\"");
344 124696 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
345 124696 : }
346 :
347 : /*
348 : * handleLine - handles the __LINE__ construct by passing an integer to
349 : * the token buffer.
350 : */
351 :
352 128284 : static void handleLine (void)
353 : {
354 128284 : M2LexBuf_AddTokInteger(M2Reserved_integertok, lineno);
355 128284 : }
356 :
357 : /*
358 : * handleColumn - handles the __COLUMN__ construct by passing an integer to
359 : * the token buffer.
360 : */
361 :
362 54608 : static void handleColumn (void)
363 : {
364 54608 : M2LexBuf_AddTokInteger(M2Reserved_integertok, m2flex_GetColumnNo());
365 54608 : }
366 :
367 : /*
368 : * handleDate - handles the __DATE__ construct by passing the date
369 : * as a string to the token buffer.
370 : */
371 :
372 0 : static void handleDate (void)
373 : {
374 0 : time_t clock = time ((time_t *)0);
375 0 : char *sdate = ctime (&clock);
376 0 : char *s = (char *) alloca (strlen (sdate) + 2 + 1);
377 0 : char *p = index (sdate, '\n');
378 :
379 0 : if (p != NULL) {
380 0 : *p = (char) 0;
381 : }
382 0 : strcpy(s, "\"");
383 0 : strcat(s, sdate);
384 0 : strcat(s, "\"");
385 0 : M2LexBuf_AddTokCharStar (M2Reserved_stringtok, s);
386 0 : }
387 :
388 : /*
389 : * handleFunction - handles the __FUNCTION__ construct by wrapping
390 : * it in double quotes and putting it into the token
391 : * buffer as a string.
392 : */
393 :
394 122962 : static void handleFunction (void)
395 : {
396 122962 : if (currentFunction == NULL)
397 0 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, const_cast<char *>("\"\""));
398 122962 : else if (currentFunction->module) {
399 6 : char *s = (char *) alloca(strlen(yytext) +
400 : strlen("\"module initialization\"") + 1);
401 6 : strcpy(s, "\"module ");
402 6 : strcat(s, currentFunction->name);
403 6 : strcat(s, " initialization\"");
404 6 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
405 : } else {
406 122956 : char *function = currentFunction->name;
407 122956 : char *s = (char *)alloca(strlen(function)+2+1);
408 122956 : strcpy(s, "\"");
409 122956 : strcat(s, function);
410 122956 : strcat(s, "\"");
411 122956 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
412 : }
413 122962 : }
414 :
415 : /*
416 : * pushFunction - pushes the function name onto the stack.
417 : */
418 :
419 1552809 : static void pushFunction (char *function, bool module)
420 : {
421 1552809 : if (currentFunction == NULL) {
422 101908 : currentFunction = (struct functionInfo *)xmalloc (sizeof (struct functionInfo));
423 101908 : currentFunction->name = xstrdup(function);
424 101908 : currentFunction->next = NULL;
425 101908 : currentFunction->module = module;
426 : } else {
427 1450901 : struct functionInfo *f = (struct functionInfo *)xmalloc (sizeof (struct functionInfo));
428 1450901 : f->name = xstrdup(function);
429 1450901 : f->next = currentFunction;
430 1450901 : f->module = module;
431 1450901 : currentFunction = f;
432 : }
433 1552809 : }
434 :
435 : /*
436 : * popFunction - pops the current function.
437 : */
438 :
439 1535618 : static void popFunction (void)
440 : {
441 1535618 : if (currentFunction != NULL && currentFunction->next != NULL) {
442 1450823 : struct functionInfo *f = currentFunction;
443 :
444 1450823 : currentFunction = currentFunction->next;
445 1450823 : if (f->name != NULL)
446 1450823 : free(f->name);
447 1450823 : free(f);
448 : }
449 1535618 : }
450 :
451 : /*
452 : * endOfComment - handles the end of comment
453 : */
454 :
455 4626560 : static void endOfComment (void)
456 : {
457 4626560 : commentLevel--;
458 4626560 : updatepos();
459 4626560 : skippos();
460 4626560 : if (commentLevel==0) {
461 4480904 : BEGIN INITIAL;
462 4480904 : finishedLine();
463 : } else
464 145656 : popLine();
465 4626560 : }
466 :
467 : /*
468 : * endOfCComment - handles the end of C comment.
469 : */
470 :
471 0 : static void endOfCComment (void)
472 : {
473 0 : commentCLevel = 0;
474 0 : updatepos();
475 0 : skippos();
476 0 : BEGIN INITIAL;
477 0 : finishedLine();
478 0 : }
479 :
480 : /*
481 : * m2flex_M2Error - displays the error message, s, after the code line and pointer
482 : * to the erroneous token.
483 : */
484 :
485 24 : EXTERN void m2flex_M2Error (const char *s)
486 : {
487 24 : if (currentLine->linebuf != NULL) {
488 12 : int i=1;
489 :
490 12 : printf("%s:%d:%s\n", filename, currentLine->lineno, currentLine->linebuf);
491 12 : printf("%s:%d:%*s", filename, currentLine->lineno, 1+currentLine->tokenpos, "^");
492 60 : while (i<currentLine->toklen) {
493 36 : putchar('^');
494 36 : i++;
495 : }
496 12 : putchar('\n');
497 : }
498 24 : if (s == NULL)
499 0 : printf("%s:%d\n", filename, currentLine->lineno);
500 : else
501 24 : printf("%s:%d:%s\n", filename, currentLine->lineno, s);
502 24 : }
503 :
504 12 : static void poperrorskip (const char *s)
505 : {
506 12 : int nextpos =currentLine->nextpos;
507 12 : int tokenpos=currentLine->tokenpos;
508 :
509 12 : popLine();
510 12 : m2flex_M2Error(s);
511 12 : if (currentLine != NULL) {
512 12 : currentLine->nextpos = nextpos;
513 12 : currentLine->tokenpos = tokenpos;
514 : }
515 12 : }
516 :
517 : /* skipnewline skips all '\n' at the start of the line and returns
518 : the new position. */
519 :
520 : static
521 : char *
522 0 : skipnewline (char *line)
523 : {
524 0 : while (((*line) != (char)0) && ((*line) == '\n'))
525 0 : line++;
526 0 : return line;
527 : }
528 :
529 : /* traceLine display the source line providing -fdebug-trace-line was
530 : enabled. */
531 :
532 : static
533 : void
534 67823190 : traceLine (void)
535 : {
536 67823190 : if (M2Options_GetDebugTraceLine ())
537 : {
538 0 : char *line = skipnewline (currentLine->linebuf);
539 0 : if (filename == NULL)
540 0 : printf("<stdin>:%d:%s\n", currentLine->lineno, line);
541 : else
542 0 : printf("%s:%d:%s\n", filename, currentLine->lineno, line);
543 : }
544 67823190 : }
545 :
546 : /*
547 : * consumeLine - reads a line into a buffer, it then pushes back the whole
548 : * line except the initial \n.
549 : */
550 :
551 67823190 : static void consumeLine (void)
552 : {
553 67823190 : if (currentLine->linelen<yyleng) {
554 315286 : currentLine->linebuf = (char *)xrealloc (currentLine->linebuf, yyleng);
555 315286 : currentLine->linelen = yyleng;
556 : }
557 67823190 : strcpy(currentLine->linebuf, yytext+1); /* copy all except the initial \n */
558 67823190 : lineno++;
559 67823190 : totalLines++;
560 67823190 : currentLine->lineno = lineno;
561 67823190 : currentLine->tokenpos=0;
562 67823190 : currentLine->nextpos=0;
563 67823190 : currentLine->column=FIRST_COLUMN;
564 67823190 : START_LINE (lineno, yyleng);
565 67823190 : yyless(1); /* push back all but the \n */
566 67823190 : traceLine ();
567 67823190 : }
568 :
569 0 : static void assert_location (location_t location ATTRIBUTE_UNUSED)
570 : {
571 : #if 0
572 : if ((location != BUILTINS_LOCATION) && (location != UNKNOWN_LOCATION) && (! M2Options_GetCpp ())) {
573 : expanded_location xl = expand_location (location);
574 : if (xl.line != currentLine->lineno) {
575 : m2flex_M2Error ("mismatched gcc location and front end token number");
576 : }
577 : }
578 : #endif
579 0 : }
580 :
581 : /*
582 : * splitSlashStar - called if we are not tokenizing source code after it
583 : * has been preprocessed by cpp. It is only called
584 : * if the current token was a / immediately followed by * and
585 : * therefore it will be split into two m2 tokens: / and *.
586 : */
587 :
588 0 : static void splitSlashStar (void)
589 : {
590 0 : seenFunctionStart = false;
591 0 : seenEnd = false;
592 0 : seenModuleStart = false;
593 0 : currentLine->nextpos = currentLine->tokenpos+1; /* "/". */
594 0 : currentLine->toklen = 1;
595 0 : currentLine->column = currentLine->tokenpos+1;
596 0 : currentLine->location =
597 0 : M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
598 : currentLine->column+currentLine->toklen-1));
599 0 : assert_location (GET_LOCATION (currentLine->column,
600 : currentLine->column+currentLine->toklen-1));
601 0 : M2LexBuf_AddTok (M2Reserved_dividetok);
602 0 : currentLine->nextpos = currentLine->tokenpos+1; /* "*". */
603 0 : currentLine->toklen = 1;
604 0 : currentLine->column = currentLine->tokenpos+1;
605 0 : currentLine->location =
606 0 : M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
607 : currentLine->column+currentLine->toklen-1));
608 0 : assert_location (GET_LOCATION (currentLine->column,
609 : currentLine->column+currentLine->toklen-1));
610 0 : M2LexBuf_AddTok (M2Reserved_timestok);
611 0 : }
612 :
613 :
614 : /*
615 : * updatepos - updates the current token position.
616 : * Should be used when a rule matches a token.
617 : */
618 :
619 977970774 : static void updatepos (void)
620 : {
621 977970774 : seenFunctionStart = false;
622 977970774 : seenEnd = false;
623 977970774 : seenModuleStart = false;
624 977970774 : currentLine->nextpos = currentLine->tokenpos+yyleng;
625 977970774 : currentLine->toklen = yyleng;
626 977970774 : currentLine->column = currentLine->tokenpos+1;
627 2933912322 : currentLine->location =
628 977970774 : M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
629 : currentLine->column+currentLine->toklen-1));
630 977970774 : assert_location (GET_LOCATION (currentLine->column,
631 : currentLine->column+currentLine->toklen-1));
632 977970774 : }
633 :
634 : /*
635 : * checkFunction - checks to see whether we have seen the start
636 : * or end of a function.
637 : */
638 :
639 71949870 : static void checkFunction (void)
640 : {
641 71949870 : if (! isDefinitionModule) {
642 48255164 : if (seenModuleStart)
643 102342 : pushFunction(yytext, 1);
644 48255164 : if (seenFunctionStart)
645 1450467 : pushFunction(yytext, 0);
646 48255164 : if (seenEnd && currentFunction != NULL &&
647 1976668 : (strcmp(currentFunction->name, yytext) == 0))
648 1535618 : popFunction();
649 : }
650 71949870 : seenFunctionStart = false;
651 71949870 : seenEnd = false;
652 71949870 : seenModuleStart = false;
653 71949870 : }
654 :
655 : /*
656 : * skippos - skips over this token. This function should be called
657 : * if we are not returning and thus not calling getToken.
658 : */
659 :
660 781475156 : static void skippos (void)
661 : {
662 9124475 : currentLine->tokenpos = currentLine->nextpos;
663 772333682 : }
664 :
665 : /*
666 : * initLine - initializes a currentLine
667 : */
668 :
669 17023 : static void initLine (void)
670 : {
671 17023 : currentLine = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
672 :
673 17023 : if (currentLine == NULL)
674 : perror("xmalloc");
675 17023 : currentLine->linebuf = NULL;
676 17023 : currentLine->linelen = 0;
677 17023 : currentLine->tokenpos = 0;
678 17023 : currentLine->toklen = 0;
679 17023 : currentLine->nextpos = 0;
680 17023 : currentLine->lineno = lineno;
681 17023 : currentLine->column = FIRST_COLUMN;
682 17023 : currentLine->inuse = true;
683 17023 : currentLine->next = NULL;
684 17023 : }
685 :
686 : /*
687 : * pushLine - pushes a new line structure.
688 : */
689 :
690 4660594 : static void pushLine (void)
691 : {
692 4660594 : if (currentLine == NULL)
693 17023 : initLine();
694 4643571 : else if (currentLine->inuse) {
695 162679 : struct lineInfo *l = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
696 :
697 162679 : if (currentLine->linebuf == NULL) {
698 16480 : l->linebuf = NULL;
699 16480 : l->linelen = 0;
700 : } else {
701 146199 : l->linebuf = (char *)xstrdup (currentLine->linebuf);
702 146199 : l->linelen = strlen (l->linebuf)+1;
703 : }
704 162679 : l->tokenpos = currentLine->tokenpos;
705 162679 : l->toklen = currentLine->toklen;
706 162679 : l->nextpos = currentLine->nextpos;
707 162679 : l->lineno = currentLine->lineno;
708 162679 : l->column = currentLine->column;
709 162679 : l->next = currentLine;
710 162679 : currentLine = l;
711 : }
712 4660594 : currentLine->inuse = true;
713 4660594 : }
714 :
715 : /*
716 : * popLine - pops a line structure.
717 : */
718 :
719 145668 : static void popLine (void)
720 : {
721 145668 : if (currentLine != NULL) {
722 145668 : struct lineInfo *l = currentLine;
723 :
724 145668 : if (currentLine->linebuf != NULL)
725 145668 : free(currentLine->linebuf);
726 145668 : currentLine = l->next;
727 145668 : free(l);
728 : }
729 145668 : }
730 :
731 : /*
732 : * resetpos - resets the position of the next token to the start of the line.
733 : */
734 :
735 275791 : static void resetpos (void)
736 : {
737 6 : if (currentLine != NULL)
738 275791 : currentLine->nextpos = 0;
739 0 : }
740 :
741 : /*
742 : * finishedLine - indicates that the current line does not need to be
743 : * preserved when a pushLine occurs.
744 : */
745 :
746 4497903 : static void finishedLine (void)
747 : {
748 16999 : currentLine->inuse = false;
749 4480904 : }
750 :
751 : /*
752 : * m2flex_GetToken - returns a new token.
753 : */
754 :
755 196106328 : EXTERN char *m2flex_GetToken (void)
756 : {
757 196106328 : TIMEVAR_PUSH_LEX;
758 196106328 : if (currentLine == NULL)
759 0 : initLine();
760 196106328 : currentLine->tokenpos = currentLine->nextpos;
761 196106328 : yylex();
762 196106328 : TIMEVAR_POP_LEX;
763 196106328 : return yytext;
764 : }
765 :
766 : /*
767 : * CloseSource - provided for semantic sugar
768 : */
769 :
770 0 : EXTERN void m2flex_CloseSource (void)
771 : {
772 0 : END_FILE ();
773 0 : }
774 :
775 : /*
776 : * OpenSource - returns true if file s can be opened and
777 : * all tokens are taken from this file.
778 : */
779 :
780 275786 : EXTERN bool m2flex_OpenSource (char *s)
781 : {
782 275786 : FILE *f = fopen(s, "r");
783 :
784 275786 : if (f == NULL)
785 : return( false );
786 : else {
787 275785 : isDefinitionModule = false;
788 368420 : while (currentFunction != NULL)
789 : {
790 92635 : struct functionInfo *f = currentFunction;
791 92635 : currentFunction = f->next;
792 92635 : if (f->name != NULL)
793 92635 : free(f->name);
794 92635 : free(f);
795 : }
796 275785 : yy_delete_buffer (YY_CURRENT_BUFFER);
797 275785 : yy_switch_to_buffer (yy_create_buffer(f, YY_BUF_SIZE));
798 275785 : filename = xstrdup (s);
799 275785 : lineno = 1;
800 275785 : if (currentLine == NULL)
801 17023 : pushLine ();
802 : else
803 258762 : currentLine->lineno = lineno;
804 275785 : START_FILE (filename, lineno);
805 275785 : BEGIN INITIAL; resetpos ();
806 275785 : return true;
807 : }
808 : }
809 :
810 : /*
811 : * m2flex_GetLineNo - returns the current line number.
812 : */
813 :
814 196415062 : EXTERN int m2flex_GetLineNo (void)
815 : {
816 196415062 : if (currentLine == NULL)
817 : return 0;
818 : else
819 196415062 : return currentLine->lineno;
820 : }
821 :
822 : /*
823 : * m2flex_GetColumnNo - returns the column where the current
824 : * token starts.
825 : */
826 :
827 196469670 : EXTERN int m2flex_GetColumnNo (void)
828 : {
829 196469670 : if (currentLine == NULL)
830 : return FIRST_COLUMN;
831 : else
832 196469670 : return currentLine->column;
833 : }
834 :
835 : /*
836 : * m2flex_GetLocation - returns the gcc location_t of the current token.
837 : */
838 :
839 196106328 : EXTERN location_t m2flex_GetLocation (void)
840 : {
841 196106328 : if (currentLine == NULL)
842 : return 0;
843 : else
844 196106328 : return currentLine->location;
845 : }
846 :
847 : /*
848 : * GetTotalLines - returns the total number of lines parsed.
849 : */
850 :
851 0 : EXTERN int m2flex_GetTotalLines (void)
852 : {
853 0 : return totalLines;
854 : }
855 :
856 : /*
857 : * yywrap is called when end of file is seen. We push an eof token
858 : * and tell the lexical analysis to stop.
859 : */
860 :
861 258768 : int yywrap (void)
862 : {
863 258768 : updatepos(); M2LexBuf_AddTok(M2Reserved_eoftok); return 1;
864 : }
865 :
866 0 : EXTERN void _M2_m2flex_init (void) {}
867 0 : EXTERN void _M2_m2flex_fini (void) {}
|