Branch data Line data Source code
1 : : %{
2 : : /* m2.flex implements lexical analysis for Modula-2.
3 : :
4 : : Copyright (C) 2004-2025 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 : 2981574 : "(*" { updatepos();
125 : 2981574 : commentLevel=1; pushLine(); skippos();
126 : 2981574 : BEGIN COMMENT; }
127 : 6095135 : <COMMENT>"*)" { endOfComment(); }
128 : 3245560 : <COMMENT>"(*" { commentLevel++; pushLine(); updatepos(); skippos(); }
129 : 3128802 : <COMMENT>"<*" { if (commentLevel == 1) {
130 : 147234 : updatepos();
131 : 30476 : pushLine();
132 : 15235 : skippos();
133 : 15235 : BEGIN COMMENT1;
134 : : } else {
135 : 6 : updatepos(); skippos();
136 : : }
137 : : }
138 : 13168203 : <COMMENT>\n.* { consumeLine(); }
139 : 560128407 : <COMMENT>. { updatepos(); skippos(); }
140 : 152350 : <COMMENT1>. { updatepos(); skippos(); }
141 : 560143642 : <COMMENT1>"*>" { updatepos(); skippos(); finishedLine(); BEGIN COMMENT; }
142 : 152350 : <COMMENT1>\n.* { consumeLine(); }
143 : 15235 : <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 : 15388 : ^\#.* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */
167 : 15388 : if (M2Options_GetLineDirectives ())
168 : 30776 : BEGIN LINE0;
169 : : }
170 : 12158 : \n\#.* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */
171 : 12158 : if (M2Options_GetLineDirectives ())
172 : 12158 : BEGIN LINE0;
173 : 12158 : }
174 : 12158 : <LINE0>\#[ \t]* { updatepos(); }
175 : 39704 : <LINE0>[0-9]+[ \t]*\" { updatepos(); lineno=atoi(yytext); BEGIN LINE1; }
176 : 39704 : <LINE0>\n { m2flex_M2Error("missing initial quote after #line directive"); resetpos(); BEGIN INITIAL; }
177 : 27546 : <LINE0>[^\n]
178 : 0 : <LINE1>[^\"\n]+ { m2flex_M2Error("missing final quote after #line directive"); resetpos(); BEGIN INITIAL; }
179 : 42934 : <LINE1>.*\" { updatepos();
180 : 27546 : filename = (char *)xrealloc(filename, yyleng+1);
181 : 27546 : strcpy(filename, yytext);
182 : 27546 : filename[yyleng-1] = (char)0; /* remove trailing quote */
183 : 27546 : START_FILE (filename, lineno);
184 : 27546 : BEGIN LINE2;
185 : : }
186 : 27546 : <LINE2>[ \t]* { updatepos(); }
187 : 27546 : <LINE2>\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
188 : 30414 : <LINE2>2[ \t]*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
189 : 2868 : <LINE2>1[ \t]*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
190 : 16074 : <LINE2>1[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
191 : 5736 : <LINE2>2[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
192 : 8604 : <LINE2>3[ \t]*.*\n { M2LexBuf_SetFile(filename); updatepos(); BEGIN INITIAL; }
193 : 11472 :
194 : 0 : \n[^\#].* { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */ }
195 : 29470476 : \n { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */ }
196 : 29648893 :
197 : 312465 : \"[^\"\n]*\" { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
198 : 499486 : \"[^\"\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 : 456202 : '[^'\n]*' { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
205 : 456208 : '[^'\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 : 187470 : <<EOF>> { updatepos(); M2LexBuf_AddTok(M2Reserved_eoftok); return; }
212 : 184760 : \+ { updatepos(); M2LexBuf_AddTok(M2Reserved_plustok); return; }
213 : 184312 : - { updatepos(); M2LexBuf_AddTok(M2Reserved_minustok); return; }
214 : 255686 : "*" { updatepos(); M2LexBuf_AddTok(M2Reserved_timestok); return; }
215 : 372738 : \/ { updatepos(); M2LexBuf_AddTok(M2Reserved_dividetok); return; }
216 : 2173978 : := { updatepos(); M2LexBuf_AddTok(M2Reserved_becomestok); return; }
217 : 956 : \& { updatepos(); M2LexBuf_AddTok(M2Reserved_ambersandtok); return; }
218 : 3435739 : \. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodtok); return; }
219 : 7685259 : \, { updatepos(); M2LexBuf_AddTok(M2Reserved_commatok); return; }
220 : 13088758 : \; { updatepos(); M2LexBuf_AddTok(M2Reserved_semicolontok); return; }
221 : 15479311 : \( { updatepos(); M2LexBuf_AddTok(M2Reserved_lparatok); return; }
222 : 19550129 : \) { updatepos(); M2LexBuf_AddTok(M2Reserved_rparatok); return; }
223 : 8633397 : \[ { updatepos(); M2LexBuf_AddTok(M2Reserved_lsbratok); return; }
224 : 8633377 : \] { updatepos(); M2LexBuf_AddTok(M2Reserved_rsbratok); return; }
225 : 839345 : \(\! { updatepos(); M2LexBuf_AddTok(M2Reserved_lsbratok); return; }
226 : 839319 : \!\) { updatepos(); M2LexBuf_AddTok(M2Reserved_rsbratok); return; }
227 : 752404 : \^ { updatepos(); M2LexBuf_AddTok(M2Reserved_uparrowtok); return; }
228 : 0 : \@ { updatepos(); M2LexBuf_AddTok(M2Reserved_uparrowtok); return; }
229 : 774474 : \{ { updatepos(); M2LexBuf_AddTok(M2Reserved_lcbratok); return; }
230 : 22070 : \} { updatepos(); M2LexBuf_AddTok(M2Reserved_rcbratok); return; }
231 : 22070 : \(\: { updatepos(); M2LexBuf_AddTok(M2Reserved_lcbratok); return; }
232 : 22070 : \:\) { updatepos(); M2LexBuf_AddTok(M2Reserved_rcbratok); return; }
233 : 0 : \' { updatepos(); M2LexBuf_AddTok(M2Reserved_singlequotetok); return; }
234 : 953673 : \= { updatepos(); M2LexBuf_AddTok(M2Reserved_equaltok); return; }
235 : 367146 : \# { updatepos(); M2LexBuf_AddTok(M2Reserved_hashtok); return; }
236 : 1160933 : \< { updatepos(); M2LexBuf_AddTok(M2Reserved_lesstok); return; }
237 : 521146 : \> { updatepos(); M2LexBuf_AddTok(M2Reserved_greatertok); return; }
238 : 207344 : \<\> { updatepos(); M2LexBuf_AddTok(M2Reserved_lessgreatertok); return; }
239 : 305562 : \<\= { updatepos(); M2LexBuf_AddTok(M2Reserved_lessequaltok); return; }
240 : 55506 : \>\= { updatepos(); M2LexBuf_AddTok(M2Reserved_greaterequaltok); return; }
241 : 633786 : "<*" { updatepos(); M2LexBuf_AddTok(M2Reserved_ldirectivetok); return; }
242 : 537646 : "*>" { updatepos(); M2LexBuf_AddTok(M2Reserved_rdirectivetok); return; }
243 : 567540 : \.\. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodperiodtok); return; }
244 : 493308 : \.\.\. { updatepos(); M2LexBuf_AddTok(M2Reserved_periodperiodperiodtok); return; }
245 : 7486372 : \: { updatepos(); M2LexBuf_AddTok(M2Reserved_colontok); return; }
246 : 11084 : \" { updatepos(); M2LexBuf_AddTok(M2Reserved_doublequotestok); return; }
247 : 7410910 : \| { updatepos(); M2LexBuf_AddTok(M2Reserved_bartok); return; }
248 : 0 : \! { updatepos(); M2LexBuf_AddTok(M2Reserved_bartok); return; }
249 : 9854 : \~ { updatepos(); M2LexBuf_AddTok(M2Reserved_nottok); return; }
250 : 256910 : AND { updatepos(); M2LexBuf_AddTok(M2Reserved_andtok); return; }
251 : 610695 : ARRAY { updatepos(); M2LexBuf_AddTok(M2Reserved_arraytok); return; }
252 : 1264979 : BEGIN { updatepos(); M2LexBuf_AddTok(M2Reserved_begintok); return; }
253 : 611067 : BY { updatepos(); M2LexBuf_AddTok(M2Reserved_bytok); return; }
254 : 1012893 : CASE { updatepos(); M2LexBuf_AddTok(M2Reserved_casetok); return; }
255 : 55879 : CONST { updatepos(); M2LexBuf_AddTok(M2Reserved_consttok); return; }
256 : 126341 : DEFINITION { updatepos(); isDefinitionModule = true;
257 : 177024 : M2LexBuf_AddTok(M2Reserved_definitiontok); return; }
258 : 163767 : DIV { updatepos(); M2LexBuf_AddTok(M2Reserved_divtok); return; }
259 : 338100 : DO { updatepos(); M2LexBuf_AddTok(M2Reserved_dotok); return; }
260 : 480038 : ELSE { updatepos(); M2LexBuf_AddTok(M2Reserved_elsetok); return; }
261 : 432034 : ELSIF { updatepos(); M2LexBuf_AddTok(M2Reserved_elsiftok); return; }
262 : 3062670 : END { updatepos(); seenEnd=true;
263 : 2718816 : M2LexBuf_AddTok(M2Reserved_endtok); return; }
264 : 2625116 : EXCEPT { updatepos(); M2LexBuf_AddTok(M2Reserved_excepttok); return; }
265 : 106 : EXIT { updatepos(); M2LexBuf_AddTok(M2Reserved_exittok); return; }
266 : 71657 : EXPORT { updatepos(); M2LexBuf_AddTok(M2Reserved_exporttok); return; }
267 : 5882 : FINALLY { updatepos(); M2LexBuf_AddTok(M2Reserved_finallytok); return; }
268 : 92549 : FOR { updatepos(); M2LexBuf_AddTok(M2Reserved_fortok); return; }
269 : 5836 : FORWARD { updatepos(); M2LexBuf_AddTok(M2Reserved_forwardtok); return; }
270 : 276457 : FROM { updatepos(); M2LexBuf_AddTok(M2Reserved_fromtok); return; }
271 : 1061389 : IF { updatepos(); M2LexBuf_AddTok(M2Reserved_iftok); return; }
272 : 313311 : IMPLEMENTATION { updatepos(); M2LexBuf_AddTok(M2Reserved_implementationtok); return; }
273 : 1351358 : IMPORT { updatepos(); M2LexBuf_AddTok(M2Reserved_importtok); return; }
274 : 69512 : IN { updatepos(); M2LexBuf_AddTok(M2Reserved_intok); return; }
275 : 298489 : LOOP { updatepos(); M2LexBuf_AddTok(M2Reserved_looptok); return; }
276 : 78124 : MOD { updatepos(); M2LexBuf_AddTok(M2Reserved_modtok); return; }
277 : 211615 : MODULE { updatepos(); seenModuleStart=true;
278 : 269747 : M2LexBuf_AddTok(M2Reserved_moduletok); return; }
279 : 277103 : NOT { updatepos(); M2LexBuf_AddTok(M2Reserved_nottok); return; }
280 : 617423 : OF { updatepos(); M2LexBuf_AddTok(M2Reserved_oftok); return; }
281 : 178870 : OR { updatepos(); M2LexBuf_AddTok(M2Reserved_ortok); return; }
282 : 617537 : PACKEDSET { updatepos(); M2LexBuf_AddTok(M2Reserved_packedsettok); return; }
283 : 183742 : POINTER { updatepos(); M2LexBuf_AddTok(M2Reserved_pointertok); return; }
284 : 3072014 : PROCEDURE { updatepos(); seenFunctionStart=true;
285 : 3150720 : M2LexBuf_AddTok(M2Reserved_proceduretok); return; }
286 : 3136455 : QUALIFIED { updatepos(); M2LexBuf_AddTok(M2Reserved_qualifiedtok); return; }
287 : 6574 : UNQUALIFIED { updatepos(); M2LexBuf_AddTok(M2Reserved_unqualifiedtok); return; }
288 : 114726 : RECORD { updatepos(); M2LexBuf_AddTok(M2Reserved_recordtok); return; }
289 : 6670 : REM { updatepos(); M2LexBuf_AddTok(M2Reserved_remtok); return; }
290 : 105409 : REPEAT { updatepos(); M2LexBuf_AddTok(M2Reserved_repeattok); return; }
291 : 270 : RETRY { updatepos(); M2LexBuf_AddTok(M2Reserved_retrytok); return; }
292 : 598047 : RETURN { updatepos(); M2LexBuf_AddTok(M2Reserved_returntok); return; }
293 : 1958 : SET { updatepos(); M2LexBuf_AddTok(M2Reserved_settok); return; }
294 : 1698072 : THEN { updatepos(); M2LexBuf_AddTok(M2Reserved_thentok); return; }
295 : 93708 : TO { updatepos(); M2LexBuf_AddTok(M2Reserved_totok); return; }
296 : 1249679 : TYPE { updatepos(); M2LexBuf_AddTok(M2Reserved_typetok); return; }
297 : 147162 : UNTIL { updatepos(); M2LexBuf_AddTok(M2Reserved_untiltok); return; }
298 : 1020766 : VAR { updatepos(); M2LexBuf_AddTok(M2Reserved_vartok); return; }
299 : 244854 : WHILE { updatepos(); M2LexBuf_AddTok(M2Reserved_whiletok); return; }
300 : 1061724 : WITH { updatepos(); M2LexBuf_AddTok(M2Reserved_withtok); return; }
301 : 189643 : ASM { updatepos(); M2LexBuf_AddTok(M2Reserved_asmtok); return; }
302 : 135389 : VOLATILE { updatepos(); M2LexBuf_AddTok(M2Reserved_volatiletok); return; }
303 : 27 : \_\_DATE\_\_ { updatepos(); handleDate(); return; }
304 : 82535 : \_\_LINE\_\_ { updatepos(); handleLine(); return; }
305 : 79148 : \_\_FILE\_\_ { updatepos(); handleFile(); return; }
306 : 159928 : \_\_FUNCTION\_\_ { updatepos(); handleFunction(); return; }
307 : 132168 : \_\_COLUMN\_\_ { updatepos(); handleColumn(); return; }
308 : 161966 : \_\_ATTRIBUTE\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_attributetok); return; }
309 : 191242 : \_\_BUILTIN\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_builtintok); return; }
310 : 84558 : \_\_INLINE\_\_ { updatepos(); M2LexBuf_AddTok(M2Reserved_inlinetok); return; }
311 : 138222 :
312 : 0 :
313 : 9226 : (([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 : 41413591 : [a-zA-Z_][a-zA-Z0-9_]* { checkFunction(); updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_identtok, yytext); return; }
316 : 1171988 : [0-9]+ { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
317 : 41413615 : [0-1]+A { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
318 : 1174644 : [0-9]+B { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
319 : 130226 : [0-9]+C { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
320 : 13814 : [0-9A-F]+H { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
321 : 130202 : [\t\r ]+ { currentLine->tokenpos += yyleng; /* Ignore space. */; }
322 : 63496851 : . { updatepos(); m2flex_M2Error("unrecognised symbol"); skippos(); }
323 : 63485699 :
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 : 79148 : static void handleFile (void)
338 : : {
339 : 79148 : char *s = (char *)alloca(strlen(filename)+2+1);
340 : :
341 : 79148 : strcpy(s, "\"");
342 : 79148 : strcat(s, filename);
343 : 79148 : strcat(s, "\"");
344 : 79148 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
345 : 79148 : }
346 : :
347 : : /*
348 : : * handleLine - handles the __LINE__ construct by passing an integer to
349 : : * the token buffer.
350 : : */
351 : :
352 : 82520 : static void handleLine (void)
353 : : {
354 : 82520 : M2LexBuf_AddTokInteger(M2Reserved_integertok, lineno);
355 : 82520 : }
356 : :
357 : : /*
358 : : * handleColumn - handles the __COLUMN__ construct by passing an integer to
359 : : * the token buffer.
360 : : */
361 : :
362 : 53020 : static void handleColumn (void)
363 : : {
364 : 53020 : M2LexBuf_AddTokInteger(M2Reserved_integertok, m2flex_GetColumnNo());
365 : 53020 : }
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 : 77408 : static void handleFunction (void)
395 : : {
396 : 77408 : if (currentFunction == NULL)
397 : 0 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, const_cast<char *>("\"\""));
398 : 77408 : 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 : 77402 : char *function = currentFunction->name;
407 : 77402 : char *s = (char *)alloca(strlen(function)+2+1);
408 : 77402 : strcpy(s, "\"");
409 : 77402 : strcat(s, function);
410 : 77402 : strcat(s, "\"");
411 : 77402 : M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
412 : : }
413 : 77408 : }
414 : :
415 : : /*
416 : : * pushFunction - pushes the function name onto the stack.
417 : : */
418 : :
419 : 1001720 : static void pushFunction (char *function, bool module)
420 : : {
421 : 1001720 : if (currentFunction == NULL) {
422 : 81212 : currentFunction = (struct functionInfo *)xmalloc (sizeof (struct functionInfo));
423 : 81212 : currentFunction->name = xstrdup(function);
424 : 81212 : currentFunction->next = NULL;
425 : 81212 : currentFunction->module = module;
426 : : } else {
427 : 920508 : struct functionInfo *f = (struct functionInfo *)xmalloc (sizeof (struct functionInfo));
428 : 920508 : f->name = xstrdup(function);
429 : 920508 : f->next = currentFunction;
430 : 920508 : f->module = module;
431 : 920508 : currentFunction = f;
432 : : }
433 : 1001720 : }
434 : :
435 : : /*
436 : : * popFunction - pops the current function.
437 : : */
438 : :
439 : 986293 : static void popFunction (void)
440 : : {
441 : 986293 : if (currentFunction != NULL && currentFunction->next != NULL) {
442 : 920430 : struct functionInfo *f = currentFunction;
443 : :
444 : 920430 : currentFunction = currentFunction->next;
445 : 920430 : if (f->name != NULL)
446 : 920430 : free(f->name);
447 : 920430 : free(f);
448 : : }
449 : 986293 : }
450 : :
451 : : /*
452 : : * endOfComment - handles the end of comment
453 : : */
454 : :
455 : 3113561 : static void endOfComment (void)
456 : : {
457 : 3113561 : commentLevel--;
458 : 3113561 : updatepos();
459 : 3113561 : skippos();
460 : 3113561 : if (commentLevel==0) {
461 : 2981562 : BEGIN INITIAL;
462 : 2981562 : finishedLine();
463 : : } else
464 : 131999 : popLine();
465 : 3113561 : }
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 : 42844642 : traceLine (void)
535 : : {
536 : 42844642 : 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 : 42844642 : }
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 : 42844642 : static void consumeLine (void)
552 : : {
553 : 42844642 : if (currentLine->linelen<yyleng) {
554 : 282032 : currentLine->linebuf = (char *)xrealloc (currentLine->linebuf, yyleng);
555 : 282032 : currentLine->linelen = yyleng;
556 : : }
557 : 42844642 : strcpy(currentLine->linebuf, yytext+1); /* copy all except the initial \n */
558 : 42844642 : lineno++;
559 : 42844642 : totalLines++;
560 : 42844642 : currentLine->lineno = lineno;
561 : 42844642 : currentLine->tokenpos=0;
562 : 42844642 : currentLine->nextpos=0;
563 : 42844642 : currentLine->column=FIRST_COLUMN;
564 : 42844642 : START_LINE (lineno, yyleng);
565 : 42844642 : yyless(1); /* push back all but the \n */
566 : 42844642 : traceLine ();
567 : 42844642 : }
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 : 664583624 : static void updatepos (void)
620 : : {
621 : 664583624 : seenFunctionStart = false;
622 : 664583624 : seenEnd = false;
623 : 664583624 : seenModuleStart = false;
624 : 664583624 : currentLine->nextpos = currentLine->tokenpos+yyleng;
625 : 664583624 : currentLine->toklen = yyleng;
626 : 664583624 : currentLine->column = currentLine->tokenpos+1;
627 : 1993750872 : currentLine->location =
628 : 664583624 : M2Options_OverrideLocation (GET_LOCATION (currentLine->column,
629 : : currentLine->column+currentLine->toklen-1));
630 : 664583624 : assert_location (GET_LOCATION (currentLine->column,
631 : : currentLine->column+currentLine->toklen-1));
632 : 664583624 : }
633 : :
634 : : /*
635 : : * checkFunction - checks to see whether we have seen the start
636 : : * or end of a function.
637 : : */
638 : :
639 : 41413591 : static void checkFunction (void)
640 : : {
641 : 41413591 : if (! isDefinitionModule) {
642 : 26288563 : if (seenModuleStart)
643 : 81638 : pushFunction(yytext, 1);
644 : 26288563 : if (seenFunctionStart)
645 : 920082 : pushFunction(yytext, 0);
646 : 26288563 : if (seenEnd && currentFunction != NULL &&
647 : 1040481 : (strcmp(currentFunction->name, yytext) == 0))
648 : 986293 : popFunction();
649 : : }
650 : 41413591 : seenFunctionStart = false;
651 : 41413591 : seenEnd = false;
652 : 41413591 : seenModuleStart = false;
653 : 41413591 : }
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 : 553370164 : static void skippos (void)
661 : : {
662 : 6110370 : currentLine->tokenpos = currentLine->nextpos;
663 : 547244559 : }
664 : :
665 : : /*
666 : : * initLine - initializes a currentLine
667 : : */
668 : :
669 : 15259 : static void initLine (void)
670 : : {
671 : 15259 : currentLine = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
672 : :
673 : 15259 : if (currentLine == NULL)
674 : : perror("xmalloc");
675 : 15259 : currentLine->linebuf = NULL;
676 : 15259 : currentLine->linelen = 0;
677 : 15259 : currentLine->tokenpos = 0;
678 : 15259 : currentLine->toklen = 0;
679 : 15259 : currentLine->nextpos = 0;
680 : 15259 : currentLine->lineno = lineno;
681 : 15259 : currentLine->column = FIRST_COLUMN;
682 : 15259 : currentLine->inuse = true;
683 : 15259 : currentLine->next = NULL;
684 : 15259 : }
685 : :
686 : : /*
687 : : * pushLine - pushes a new line structure.
688 : : */
689 : :
690 : 3144067 : static void pushLine (void)
691 : : {
692 : 3144067 : if (currentLine == NULL)
693 : 15259 : initLine();
694 : 3128808 : else if (currentLine->inuse) {
695 : 147258 : struct lineInfo *l = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
696 : :
697 : 147258 : if (currentLine->linebuf == NULL) {
698 : 14723 : l->linebuf = NULL;
699 : 14723 : l->linelen = 0;
700 : : } else {
701 : 132535 : l->linebuf = (char *)xstrdup (currentLine->linebuf);
702 : 132535 : l->linelen = strlen (l->linebuf)+1;
703 : : }
704 : 147258 : l->tokenpos = currentLine->tokenpos;
705 : 147258 : l->toklen = currentLine->toklen;
706 : 147258 : l->nextpos = currentLine->nextpos;
707 : 147258 : l->lineno = currentLine->lineno;
708 : 147258 : l->column = currentLine->column;
709 : 147258 : l->next = currentLine;
710 : 147258 : currentLine = l;
711 : : }
712 : 3144067 : currentLine->inuse = true;
713 : 3144067 : }
714 : :
715 : : /*
716 : : * popLine - pops a line structure.
717 : : */
718 : :
719 : 132011 : static void popLine (void)
720 : : {
721 : 132011 : if (currentLine != NULL) {
722 : 132011 : struct lineInfo *l = currentLine;
723 : :
724 : 132011 : if (currentLine->linebuf != NULL)
725 : 132011 : free(currentLine->linebuf);
726 : 132011 : currentLine = l->next;
727 : 132011 : free(l);
728 : : }
729 : 132011 : }
730 : :
731 : : /*
732 : : * resetpos - resets the position of the next token to the start of the line.
733 : : */
734 : :
735 : 202741 : static void resetpos (void)
736 : : {
737 : 6 : if (currentLine != NULL)
738 : 202741 : 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 : 2996797 : static void finishedLine (void)
747 : : {
748 : 15235 : currentLine->inuse = false;
749 : 2981562 : }
750 : :
751 : : /*
752 : : * m2flex_GetToken - returns a new token.
753 : : */
754 : :
755 : 110916842 : EXTERN char *m2flex_GetToken (void)
756 : : {
757 : 110916842 : TIMEVAR_PUSH_LEX;
758 : 110916842 : if (currentLine == NULL)
759 : 0 : initLine();
760 : 110916842 : currentLine->tokenpos = currentLine->nextpos;
761 : 110916842 : yylex();
762 : 110916842 : TIMEVAR_POP_LEX;
763 : 110916842 : 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 : 202736 : EXTERN bool m2flex_OpenSource (char *s)
781 : : {
782 : 202736 : FILE *f = fopen(s, "r");
783 : :
784 : 202736 : if (f == NULL)
785 : : return( false );
786 : : else {
787 : 202735 : isDefinitionModule = false;
788 : 275995 : while (currentFunction != NULL)
789 : : {
790 : 73260 : struct functionInfo *f = currentFunction;
791 : 73260 : currentFunction = f->next;
792 : 73260 : if (f->name != NULL)
793 : 73260 : free(f->name);
794 : 73260 : free(f);
795 : : }
796 : 202735 : yy_delete_buffer (YY_CURRENT_BUFFER);
797 : 202735 : yy_switch_to_buffer (yy_create_buffer(f, YY_BUF_SIZE));
798 : 202735 : filename = xstrdup (s);
799 : 202735 : lineno = 1;
800 : 202735 : if (currentLine == NULL)
801 : 15259 : pushLine ();
802 : : else
803 : 187476 : currentLine->lineno = lineno;
804 : 202735 : START_FILE (filename, lineno);
805 : 202735 : BEGIN INITIAL; resetpos ();
806 : 202735 : return true;
807 : : }
808 : : }
809 : :
810 : : /*
811 : : * m2flex_GetLineNo - returns the current line number.
812 : : */
813 : :
814 : 111147123 : EXTERN int m2flex_GetLineNo (void)
815 : : {
816 : 111147123 : if (currentLine == NULL)
817 : : return 0;
818 : : else
819 : 111147123 : return currentLine->lineno;
820 : : }
821 : :
822 : : /*
823 : : * m2flex_GetColumnNo - returns the column where the current
824 : : * token starts.
825 : : */
826 : :
827 : 111200143 : EXTERN int m2flex_GetColumnNo (void)
828 : : {
829 : 111200143 : if (currentLine == NULL)
830 : : return FIRST_COLUMN;
831 : : else
832 : 111200143 : return currentLine->column;
833 : : }
834 : :
835 : : /*
836 : : * m2flex_GetLocation - returns the gcc location_t of the current token.
837 : : */
838 : :
839 : 110916842 : EXTERN location_t m2flex_GetLocation (void)
840 : : {
841 : 110916842 : if (currentLine == NULL)
842 : : return 0;
843 : : else
844 : 110916842 : 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 : 187482 : int yywrap (void)
862 : : {
863 : 187482 : 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) {}
|