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