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