xfail scan-tree-dump-not throw in g++.dg/pr99966.C on hppa*64*-*-*
[official-gcc.git] / gcc / m2 / m2.flex
blobf8f5ce64ad3628dd231c76c5afd6bc26d41ab656
1 %{
2 /* m2.flex implements lexical analysis for Modula-2.
4 Copyright (C) 2004-2024 Free Software Foundation, Inc.
5 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
7 This file is part of GNU Modula-2.
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.
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.
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/>.  */
23 #include "gm2-gcc/gcc-consolidation.h"
25 #include "GM2Reserved.h"
26 #include "GM2LexBuf.h"
27 #include "input.h"
28 #include "m2options.h"
30 static int cpreprocessor = 0;  /* Replace this with correct getter.  */
32 #if defined(GM2USEGGC)
33 #  include "ggc.h"
34 #endif
36 #include "timevar.h"
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)
46 #ifdef __cplusplus
47 #define EXTERN extern "C"
48 #endif
50   /* m2.flex provides a lexical analyser for GNU Modula-2.  */
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     bool             inuse;            /* do we need to keep this line info? */
61     location_t       location;         /* the corresponding gcc location_t */
62     struct lineInfo *next;
63   };
65   struct functionInfo {
66     char                *name;         /* function name */
67     bool                 module;       /* is it really a module? */
68     struct functionInfo *next;         /* list of nested functions */
69   };
71   static int                  lineno      =1;   /* a running count of the file line number */
72   static char                *filename    =NULL;
73   static int                  commentLevel=0;
74   static int                  commentCLevel=0;
75   static struct lineInfo     *currentLine=NULL;
76   static struct functionInfo *currentFunction=NULL;
77   static bool                 seenFunctionStart=false;
78   static bool                 seenEnd=false;
79   static bool                 seenModuleStart=false;
80   static bool                 isDefinitionModule=false;
81   static int                  totalLines=0;
83 static  void pushLine                 (void);
84 static  void popLine                  (void);
85 static  void finishedLine             (void);
86 static  void resetpos                 (void);
87 static  void consumeLine              (void);
88 static  void updatepos                (void);
89 static  void skippos                  (void);
90 static  void poperrorskip             (const char *);
91 static  void endOfComment             (void);
92 static  void endOfCComment            (void);
93 static  void splitSlashStar           (void);
94 static  void handleDate               (void);
95 static  void handleLine               (void);
96 static  void handleFile               (void);
97 static  void handleFunction           (void);
98 static  void handleColumn             (void);
99 static  void pushFunction             (char *function, bool module);
100 static  void popFunction              (void);
101 static  void checkFunction            (void);
102 EXTERN  void m2flex_M2Error           (const char *);
103 EXTERN  location_t m2flex_GetLocation (void);
104 EXTERN  int  m2flex_GetColumnNo       (void);
105 EXTERN  bool m2flex_OpenSource        (char *s);
106 EXTERN  int  m2flex_GetLineNo         (void);
107 EXTERN  void m2flex_CloseSource       (void);
108 EXTERN  char *m2flex_GetToken         (void);
109 EXTERN  void _M2_m2flex_init          (void);
110 EXTERN  int  m2flex_GetTotalLines     (void);
111 extern  void  yylex                   (void);
113 #define YY_DECL void yylex (void)
116 %option nounput
117 %x COMMENT COMMENT1 COMMENTC LINE0 LINE1 LINE2
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;
131                              } else {
132                                updatepos(); skippos();
133                              }
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; }
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(); }
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(); }
166 <LINE0>[0-9]+[ \t]*\"      { updatepos(); lineno=atoi(yytext); BEGIN LINE1; }
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; }
185 \n[^\#].*                  { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */ }
186 \n                         { consumeLine(); /* printf("found: %s\n", currentLine->linebuf); */ }
188 \"[^\"\n]*\"               { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
189 \"[^\"\n]*$                { updatepos();
190                              m2flex_M2Error("missing terminating quote, \"");
191                              resetpos(); return;
192                            }
194 '[^'\n]*'                  { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_stringtok, yytext); return; }
195 '[^'\n]*$                  { updatepos();
196                              m2flex_M2Error("missing terminating quote, '");
197                              resetpos(); return;
198                            }
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; }
239 AND                        { updatepos(); M2LexBuf_AddTok(M2Reserved_andtok); return; }
240 ARRAY                      { updatepos(); M2LexBuf_AddTok(M2Reserved_arraytok); return; }
241 BEGIN                      { updatepos(); M2LexBuf_AddTok(M2Reserved_begintok); return; }
242 BY                         { updatepos(); M2LexBuf_AddTok(M2Reserved_bytok); return; }
243 CASE                       { updatepos(); M2LexBuf_AddTok(M2Reserved_casetok); return; }
244 CONST                      { updatepos(); M2LexBuf_AddTok(M2Reserved_consttok); return; }
245 DEFINITION                 { updatepos(); isDefinitionModule = true;
246                              M2LexBuf_AddTok(M2Reserved_definitiontok); return; }
247 DIV                        { updatepos(); M2LexBuf_AddTok(M2Reserved_divtok); return; }
248 DO                         { updatepos(); M2LexBuf_AddTok(M2Reserved_dotok); return; }
249 ELSE                       { updatepos(); M2LexBuf_AddTok(M2Reserved_elsetok); return; }
250 ELSIF                      { updatepos(); M2LexBuf_AddTok(M2Reserved_elsiftok); return; }
251 END                        { updatepos(); seenEnd=true;
252                              M2LexBuf_AddTok(M2Reserved_endtok); return; }
253 EXCEPT                     { updatepos(); M2LexBuf_AddTok(M2Reserved_excepttok); return; }
254 EXIT                       { updatepos(); M2LexBuf_AddTok(M2Reserved_exittok); return; }
255 EXPORT                     { updatepos(); M2LexBuf_AddTok(M2Reserved_exporttok); return; }
256 FINALLY                    { updatepos(); M2LexBuf_AddTok(M2Reserved_finallytok); return; }
257 FOR                        { updatepos(); M2LexBuf_AddTok(M2Reserved_fortok); return; }
258 FROM                       { updatepos(); M2LexBuf_AddTok(M2Reserved_fromtok); return; }
259 IF                         { updatepos(); M2LexBuf_AddTok(M2Reserved_iftok); return; }
260 IMPLEMENTATION             { updatepos(); M2LexBuf_AddTok(M2Reserved_implementationtok); return; }
261 IMPORT                     { updatepos(); M2LexBuf_AddTok(M2Reserved_importtok); return; }
262 IN                         { updatepos(); M2LexBuf_AddTok(M2Reserved_intok); return; }
263 LOOP                       { updatepos(); M2LexBuf_AddTok(M2Reserved_looptok); return; }
264 MOD                        { updatepos(); M2LexBuf_AddTok(M2Reserved_modtok); return; }
265 MODULE                     { updatepos(); seenModuleStart=true;
266                              M2LexBuf_AddTok(M2Reserved_moduletok); return; }
267 NOT                        { updatepos(); M2LexBuf_AddTok(M2Reserved_nottok); return; }
268 OF                         { updatepos(); M2LexBuf_AddTok(M2Reserved_oftok); return; }
269 OR                         { updatepos(); M2LexBuf_AddTok(M2Reserved_ortok); return; }
270 PACKEDSET                  { updatepos(); M2LexBuf_AddTok(M2Reserved_packedsettok); return; }
271 POINTER                    { updatepos(); M2LexBuf_AddTok(M2Reserved_pointertok); return; }
272 PROCEDURE                  { updatepos(); seenFunctionStart=true;
273                              M2LexBuf_AddTok(M2Reserved_proceduretok); return; }
274 QUALIFIED                  { updatepos(); M2LexBuf_AddTok(M2Reserved_qualifiedtok); return; }
275 UNQUALIFIED                { updatepos(); M2LexBuf_AddTok(M2Reserved_unqualifiedtok); return; }
276 RECORD                     { updatepos(); M2LexBuf_AddTok(M2Reserved_recordtok); return; }
277 REM                        { updatepos(); M2LexBuf_AddTok(M2Reserved_remtok); return; }
278 REPEAT                     { updatepos(); M2LexBuf_AddTok(M2Reserved_repeattok); return; }
279 RETRY                      { updatepos(); M2LexBuf_AddTok(M2Reserved_retrytok); return; }
280 RETURN                     { updatepos(); M2LexBuf_AddTok(M2Reserved_returntok); return; }
281 SET                        { updatepos(); M2LexBuf_AddTok(M2Reserved_settok); return; }
282 THEN                       { updatepos(); M2LexBuf_AddTok(M2Reserved_thentok); return; }
283 TO                         { updatepos(); M2LexBuf_AddTok(M2Reserved_totok); return; }
284 TYPE                       { updatepos(); M2LexBuf_AddTok(M2Reserved_typetok); return; }
285 UNTIL                      { updatepos(); M2LexBuf_AddTok(M2Reserved_untiltok); return; }
286 VAR                        { updatepos(); M2LexBuf_AddTok(M2Reserved_vartok); return; }
287 WHILE                      { updatepos(); M2LexBuf_AddTok(M2Reserved_whiletok); return; }
288 WITH                       { updatepos(); M2LexBuf_AddTok(M2Reserved_withtok); return; }
289 ASM                        { updatepos(); M2LexBuf_AddTok(M2Reserved_asmtok); return; }
290 VOLATILE                   { 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; }
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; }
305 [0-1]+A                    { updatepos(); M2LexBuf_AddTokCharStar(M2Reserved_integertok, yytext); return; }
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(); }
314 /* have removed the -? from the beginning of the real/integer constant literal rules */
317  *  hand built routines
318  */
321  *  handleFile - handles the __FILE__ construct by wraping it in double quotes and putting
322  *               it into the token buffer as a string.
323  */
325 static void handleFile (void)
327   char *s = (char *)alloca(strlen(filename)+2+1);
329   strcpy(s, "\"");
330   strcat(s, filename);
331   strcat(s, "\"");
332   M2LexBuf_AddTokCharStar(M2Reserved_stringtok, s);
336  *  handleLine - handles the __LINE__ construct by passing an integer to
337  *               the token buffer.
338  */
340 static void handleLine (void)
342   M2LexBuf_AddTokInteger(M2Reserved_integertok, lineno);
346  *  handleColumn - handles the __COLUMN__ construct by passing an integer to
347  *                 the token buffer.
348  */
350 static void handleColumn (void)
352   M2LexBuf_AddTokInteger(M2Reserved_integertok, m2flex_GetColumnNo());
356  *  handleDate - handles the __DATE__ construct by passing the date
357  *               as a string to the token buffer.
358  */
360 static void handleDate (void)
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');
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);
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  */
382 static void handleFunction (void)
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   }
404  *  pushFunction - pushes the function name onto the stack.
405  */
407 static void pushFunction (char *function, bool module)
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   }
424  *  popFunction - pops the current function.
425  */
427 static void popFunction (void)
429   if (currentFunction != NULL && currentFunction->next != NULL) {
430     struct functionInfo *f = currentFunction;
432     currentFunction = currentFunction->next;
433     if (f->name != NULL)
434       free(f->name);
435     free(f);
436   }
440  *  endOfComment - handles the end of comment
441  */
443 static void endOfComment (void)
445   commentLevel--;
446   updatepos();
447   skippos();
448   if (commentLevel==0) {
449     BEGIN INITIAL;
450     finishedLine();
451   } else
452     popLine();
456  *  endOfCComment - handles the end of C comment.
457  */
459 static void endOfCComment (void)
461   commentCLevel = 0;
462   updatepos();
463   skippos();
464   BEGIN INITIAL;
465   finishedLine();
469  *  m2flex_M2Error - displays the error message, s, after the code line and pointer
470  *                   to the erroneous token.
471  */
473 EXTERN void m2flex_M2Error (const char *s)
475   if (currentLine->linebuf != NULL) {
476     int i=1;
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);
489 static void poperrorskip (const char *s)
491   int nextpos =currentLine->nextpos;
492   int tokenpos=currentLine->tokenpos;
494   popLine();
495   m2flex_M2Error(s);
496   if (currentLine != NULL) {
497     currentLine->nextpos  = nextpos;
498     currentLine->tokenpos = tokenpos;
499   }
503  *  consumeLine - reads a line into a buffer, it then pushes back the whole
504  *                line except the initial \n.
505  */
507 static void consumeLine (void)
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 */
524 static void assert_location (location_t location ATTRIBUTE_UNUSED)
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
537  *  splitSlashStar - called if we are not tokenizing source code after it
538  *                   has been preprocessed by cpp.  It is only called
539  *                   if the current token was a / immediately followed by * and
540  *                   therefore it will be split into two m2 tokens:  / and *.
541  */
543 static void splitSlashStar (void)
545   seenFunctionStart    = false;
546   seenEnd              = false;
547   seenModuleStart      = false;
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);
570  *  updatepos - updates the current token position.
571  *              Should be used when a rule matches a token.
572  */
574 static void updatepos (void)
576   seenFunctionStart    = false;
577   seenEnd              = false;
578   seenModuleStart      = false;
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));
591  *  checkFunction - checks to see whether we have seen the start
592  *                  or end of a function.
593  */
595 static void checkFunction (void)
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   }
606   seenFunctionStart = false;
607   seenEnd           = false;
608   seenModuleStart   = false;
612  *  skippos - skips over this token. This function should be called
613  *            if we are not returning and thus not calling getToken.
614  */
616 static void skippos (void)
618   currentLine->tokenpos = currentLine->nextpos;
622  *  initLine - initializes a currentLine
623  */
625 static void initLine (void)
627   currentLine = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
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;
638   currentLine->inuse      = true;
639   currentLine->next       = NULL;
643  *  pushLine - pushes a new line structure.
644  */
646 static void pushLine (void)
648   if (currentLine == NULL)
649     initLine();
650   else if (currentLine->inuse) {
651       struct lineInfo *l = (struct lineInfo *)xmalloc (sizeof(struct lineInfo));
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   }
668   currentLine->inuse = true;
672  *  popLine - pops a line structure.
673  */
675 static void popLine (void)
677   if (currentLine != NULL) {
678     struct lineInfo *l = currentLine;
680     if (currentLine->linebuf != NULL)
681       free(currentLine->linebuf);
682     currentLine = l->next;
683     free(l);
684   }
688  *  resetpos - resets the position of the next token to the start of the line.
689  */
691 static void resetpos (void)
693   if (currentLine != NULL)
694     currentLine->nextpos = 0;
698  *  finishedLine - indicates that the current line does not need to be
699  *                 preserved when a pushLine occurs.
700  */
702 static void finishedLine (void)
704   currentLine->inuse = false;
708  *  m2flex_GetToken - returns a new token.
709  */
711 EXTERN char *m2flex_GetToken (void)
713   TIMEVAR_PUSH_LEX;
714   if (currentLine == NULL)
715     initLine();
716   currentLine->tokenpos = currentLine->nextpos;
717   yylex();
718   TIMEVAR_POP_LEX;
719   return yytext;
723  *  CloseSource - provided for semantic sugar
724  */
726 EXTERN void m2flex_CloseSource (void)
728   END_FILE ();
732  *  OpenSource - returns true if file s can be opened and
733  *               all tokens are taken from this file.
734  */
736 EXTERN bool m2flex_OpenSource (char *s)
738   FILE *f = fopen(s, "r");
740   if (f == NULL)
741     return( false );
742   else {
743     isDefinitionModule = false;
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 ();
762     return true;
763   }
767  *  m2flex_GetLineNo - returns the current line number.
768  */
770 EXTERN int m2flex_GetLineNo (void)
772   if (currentLine != NULL)
773     return currentLine->lineno;
774   else
775     return 0;
779  *  m2flex_GetColumnNo - returns the column where the current
780  *                       token starts.
781  */
783 EXTERN int m2flex_GetColumnNo (void)
785   if (currentLine != NULL)
786     return currentLine->column;
787   else
788     return 0;
792  *  m2flex_GetLocation - returns the gcc location_t of the current token.
793  */
795 EXTERN location_t m2flex_GetLocation (void)
797   if (currentLine != NULL)
798     return currentLine->location;
799   else
800     return 0;
804  *  GetTotalLines - returns the total number of lines parsed.
805  */
807 EXTERN int m2flex_GetTotalLines (void)
809   return totalLines;
813  *  yywrap is called when end of file is seen. We push an eof token
814  *         and tell the lexical analysis to stop.
815  */
817 int yywrap (void)
819   updatepos(); M2LexBuf_AddTok(M2Reserved_eoftok); return 1;
822 EXTERN void _M2_m2flex_init (void) {}
823 EXTERN void _M2_m2flex_fini (void) {}