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