]>
Commit | Line | Data |
---|---|---|
fbd2eda1 GM |
1 | /* do not edit automatically generated by mc from mcLexBuf. */ |
2 | /* mcLexBuf.mod provides a buffer for the all the tokens created by m2.lex. | |
3 | ||
a945c346 | 4 | Copyright (C) 2015-2024 Free Software Foundation, Inc. |
fbd2eda1 GM |
5 | Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>. |
6 | ||
7 | This file is part of GNU Modula-2. | |
8 | ||
9 | GNU Modula-2 is free software; you can redistribute it and/or modify | |
10 | it under the terms of the GNU General Public License as published by | |
11 | the Free Software Foundation; either version 3, or (at your option) | |
12 | any later version. | |
13 | ||
14 | GNU Modula-2 is distributed in the hope that it will be useful, but | |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 | General Public License for more details. | |
18 | ||
19 | You should have received a copy of the GNU General Public License | |
20 | along with GNU Modula-2; see the file COPYING3. If not see | |
21 | <http://www.gnu.org/licenses/>. */ | |
22 | ||
23 | #include "config.h" | |
24 | #include "system.h" | |
431c0669 | 25 | #include <stdbool.h> |
fbd2eda1 GM |
26 | # if !defined (PROC_D) |
27 | # define PROC_D | |
28 | typedef void (*PROC_t) (void); | |
29 | typedef struct { PROC_t proc; } PROC; | |
30 | # endif | |
31 | ||
32 | # if !defined (TRUE) | |
33 | # define TRUE (1==1) | |
34 | # endif | |
35 | ||
36 | # if !defined (FALSE) | |
37 | # define FALSE (1==0) | |
38 | # endif | |
39 | ||
40 | # include "GStorage.h" | |
41 | #if defined(__cplusplus) | |
42 | # undef NULL | |
43 | # define NULL 0 | |
44 | #endif | |
45 | #define _mcLexBuf_H | |
46 | #define _mcLexBuf_C | |
47 | ||
48 | # include "Gmcflex.h" | |
49 | # include "Glibc.h" | |
50 | # include "GSYSTEM.h" | |
51 | # include "GStorage.h" | |
52 | # include "GDynamicStrings.h" | |
53 | # include "GFormatStrings.h" | |
54 | # include "GnameKey.h" | |
55 | # include "GmcReserved.h" | |
56 | # include "GmcComment.h" | |
57 | # include "GmcPrintf.h" | |
58 | # include "GmcDebug.h" | |
59 | # include "GM2RTS.h" | |
60 | ||
61 | mcComment_commentDesc mcLexBuf_currentcomment; | |
62 | mcComment_commentDesc mcLexBuf_lastcomment; | |
63 | int mcLexBuf_currentinteger; | |
64 | unsigned int mcLexBuf_currentcolumn; | |
65 | void * mcLexBuf_currentstring; | |
66 | mcReserved_toktype mcLexBuf_currenttoken; | |
67 | # define MaxBucketSize 100 | |
431c0669 | 68 | # define Debugging false |
fbd2eda1 GM |
69 | typedef struct mcLexBuf_tokenDesc_r mcLexBuf_tokenDesc; |
70 | ||
71 | typedef struct mcLexBuf_listDesc_r mcLexBuf_listDesc; | |
72 | ||
73 | typedef struct mcLexBuf__T1_r mcLexBuf__T1; | |
74 | ||
75 | typedef mcLexBuf__T1 *mcLexBuf_sourceList; | |
76 | ||
77 | typedef struct mcLexBuf__T2_r mcLexBuf__T2; | |
78 | ||
79 | typedef mcLexBuf__T2 *mcLexBuf_tokenBucket; | |
80 | ||
81 | typedef struct mcLexBuf__T3_a mcLexBuf__T3; | |
82 | ||
83 | struct mcLexBuf_tokenDesc_r { | |
84 | mcReserved_toktype token; | |
85 | nameKey_Name str; | |
86 | int int_; | |
87 | mcComment_commentDesc com; | |
88 | unsigned int line; | |
89 | unsigned int col; | |
90 | mcLexBuf_sourceList file; | |
91 | }; | |
92 | ||
93 | struct mcLexBuf_listDesc_r { | |
94 | mcLexBuf_tokenBucket head; | |
95 | mcLexBuf_tokenBucket tail; | |
96 | unsigned int lastBucketOffset; | |
97 | }; | |
98 | ||
99 | struct mcLexBuf__T1_r { | |
100 | mcLexBuf_sourceList left; | |
101 | mcLexBuf_sourceList right; | |
102 | DynamicStrings_String name; | |
103 | unsigned int line; | |
104 | unsigned int col; | |
105 | }; | |
106 | ||
107 | struct mcLexBuf__T3_a { mcLexBuf_tokenDesc array[MaxBucketSize+1]; }; | |
108 | struct mcLexBuf__T2_r { | |
109 | mcLexBuf__T3 buf; | |
110 | unsigned int len; | |
111 | mcLexBuf_tokenBucket next; | |
112 | }; | |
113 | ||
114 | static mcComment_commentDesc procedureComment; | |
115 | static mcComment_commentDesc bodyComment; | |
116 | static mcComment_commentDesc afterComment; | |
117 | static mcLexBuf_sourceList currentSource; | |
431c0669 GM |
118 | static bool useBufferedTokens; |
119 | static bool currentUsed; | |
fbd2eda1 GM |
120 | static mcLexBuf_listDesc listOfTokens; |
121 | static unsigned int nextTokNo; | |
122 | ||
123 | /* | |
124 | getProcedureComment - returns the procedure comment if it exists, | |
125 | or NIL otherwise. | |
126 | */ | |
127 | ||
128 | extern "C" mcComment_commentDesc mcLexBuf_getProcedureComment (void); | |
129 | ||
130 | /* | |
131 | getBodyComment - returns the body comment if it exists, | |
132 | or NIL otherwise. The body comment is | |
133 | removed if found. | |
134 | */ | |
135 | ||
136 | extern "C" mcComment_commentDesc mcLexBuf_getBodyComment (void); | |
137 | ||
138 | /* | |
139 | getAfterComment - returns the after comment if it exists, | |
140 | or NIL otherwise. The after comment is | |
141 | removed if found. | |
142 | */ | |
143 | ||
144 | extern "C" mcComment_commentDesc mcLexBuf_getAfterComment (void); | |
145 | ||
146 | /* | |
147 | openSource - attempts to open the source file, s. | |
148 | The success of the operation is returned. | |
149 | */ | |
150 | ||
431c0669 | 151 | extern "C" bool mcLexBuf_openSource (DynamicStrings_String s); |
fbd2eda1 GM |
152 | |
153 | /* | |
154 | closeSource - closes the current open file. | |
155 | */ | |
156 | ||
157 | extern "C" void mcLexBuf_closeSource (void); | |
158 | ||
159 | /* | |
160 | reInitialize - re-initialize the all the data structures. | |
161 | */ | |
162 | ||
163 | extern "C" void mcLexBuf_reInitialize (void); | |
164 | ||
165 | /* | |
166 | resetForNewPass - reset the buffer pointers to the beginning ready for | |
167 | a new pass | |
168 | */ | |
169 | ||
170 | extern "C" void mcLexBuf_resetForNewPass (void); | |
171 | ||
172 | /* | |
173 | getToken - gets the next token into currenttoken. | |
174 | */ | |
175 | ||
176 | extern "C" void mcLexBuf_getToken (void); | |
177 | ||
178 | /* | |
179 | insertToken - inserts a symbol, token, infront of the current token | |
180 | ready for the next pass. | |
181 | */ | |
182 | ||
183 | extern "C" void mcLexBuf_insertToken (mcReserved_toktype token); | |
184 | ||
185 | /* | |
186 | insertTokenAndRewind - inserts a symbol, token, infront of the current token | |
187 | and then moves the token stream back onto the inserted token. | |
188 | */ | |
189 | ||
190 | extern "C" void mcLexBuf_insertTokenAndRewind (mcReserved_toktype token); | |
191 | ||
192 | /* | |
193 | getPreviousTokenLineNo - returns the line number of the previous token. | |
194 | */ | |
195 | ||
196 | extern "C" unsigned int mcLexBuf_getPreviousTokenLineNo (void); | |
197 | ||
198 | /* | |
199 | getLineNo - returns the current line number where the symbol occurs in | |
200 | the source file. | |
201 | */ | |
202 | ||
203 | extern "C" unsigned int mcLexBuf_getLineNo (void); | |
204 | ||
205 | /* | |
206 | getTokenNo - returns the current token number. | |
207 | */ | |
208 | ||
209 | extern "C" unsigned int mcLexBuf_getTokenNo (void); | |
210 | ||
211 | /* | |
212 | tokenToLineNo - returns the line number of the current file for the | |
213 | tokenNo. The depth refers to the include depth. | |
214 | A depth of 0 is the current file, depth of 1 is the file | |
215 | which included the current file. Zero is returned if the | |
216 | depth exceeds the file nesting level. | |
217 | */ | |
218 | ||
219 | extern "C" unsigned int mcLexBuf_tokenToLineNo (unsigned int tokenNo, unsigned int depth); | |
220 | ||
221 | /* | |
222 | getColumnNo - returns the current column where the symbol occurs in | |
223 | the source file. | |
224 | */ | |
225 | ||
226 | extern "C" unsigned int mcLexBuf_getColumnNo (void); | |
227 | ||
228 | /* | |
229 | tokenToColumnNo - returns the column number of the current file for the | |
230 | tokenNo. The depth refers to the include depth. | |
231 | A depth of 0 is the current file, depth of 1 is the file | |
232 | which included the current file. Zero is returned if the | |
233 | depth exceeds the file nesting level. | |
234 | */ | |
235 | ||
236 | extern "C" unsigned int mcLexBuf_tokenToColumnNo (unsigned int tokenNo, unsigned int depth); | |
237 | ||
238 | /* | |
239 | findFileNameFromToken - returns the complete FileName for the appropriate | |
240 | source file yields the token number, tokenNo. | |
241 | The, Depth, indicates the include level: 0..n | |
242 | Level 0 is the current. NIL is returned if n+1 | |
243 | is requested. | |
244 | */ | |
245 | ||
246 | extern "C" DynamicStrings_String mcLexBuf_findFileNameFromToken (unsigned int tokenNo, unsigned int depth); | |
247 | ||
248 | /* | |
249 | getFileName - returns a String defining the current file. | |
250 | */ | |
251 | ||
252 | extern "C" DynamicStrings_String mcLexBuf_getFileName (void); | |
253 | ||
254 | /* | |
255 | addTok - adds a token to the buffer. | |
256 | */ | |
257 | ||
258 | extern "C" void mcLexBuf_addTok (mcReserved_toktype t); | |
259 | ||
260 | /* | |
261 | addTokCharStar - adds a token to the buffer and an additional string, s. | |
262 | A copy of string, s, is made. | |
263 | */ | |
264 | ||
265 | extern "C" void mcLexBuf_addTokCharStar (mcReserved_toktype t, void * s); | |
266 | ||
267 | /* | |
268 | addTokInteger - adds a token and an integer to the buffer. | |
269 | */ | |
270 | ||
271 | extern "C" void mcLexBuf_addTokInteger (mcReserved_toktype t, int i); | |
272 | ||
273 | /* | |
274 | addTokComment - adds a token to the buffer and a comment descriptor, com. | |
275 | */ | |
276 | ||
277 | extern "C" void mcLexBuf_addTokComment (mcReserved_toktype t, mcComment_commentDesc com); | |
278 | ||
279 | /* | |
280 | setFile - sets the current filename to, filename. | |
281 | */ | |
282 | ||
283 | extern "C" void mcLexBuf_setFile (void * filename); | |
284 | ||
285 | /* | |
286 | pushFile - indicates that, filename, has just been included. | |
287 | */ | |
288 | ||
289 | extern "C" void mcLexBuf_pushFile (void * filename); | |
290 | ||
291 | /* | |
292 | popFile - indicates that we are returning to, filename, having finished | |
293 | an include. | |
294 | */ | |
295 | ||
296 | extern "C" void mcLexBuf_popFile (void * filename); | |
297 | ||
298 | /* | |
299 | debugLex - display the last, n, tokens. | |
300 | */ | |
301 | ||
302 | static void debugLex (unsigned int n); | |
303 | ||
304 | /* | |
305 | seekTo - | |
306 | */ | |
307 | ||
308 | static void seekTo (unsigned int t); | |
309 | ||
310 | /* | |
311 | peeptokenBucket - | |
312 | */ | |
313 | ||
314 | static mcLexBuf_tokenBucket peeptokenBucket (unsigned int *t); | |
315 | ||
316 | /* | |
317 | peepAfterComment - peeps ahead looking for an after statement comment. It stops at an END token | |
318 | or if the line number changes. | |
319 | */ | |
320 | ||
321 | static void peepAfterComment (void); | |
322 | ||
323 | /* | |
324 | init - initializes the token list and source list. | |
325 | */ | |
326 | ||
327 | static void init (void); | |
328 | ||
329 | /* | |
330 | addTo - adds a new element to the end of sourceList, currentSource. | |
331 | */ | |
332 | ||
333 | static void addTo (mcLexBuf_sourceList l); | |
334 | ||
335 | /* | |
336 | subFrom - subtracts, l, from the source list. | |
337 | */ | |
338 | ||
339 | static void subFrom (mcLexBuf_sourceList l); | |
340 | ||
341 | /* | |
342 | newElement - returns a new sourceList | |
343 | */ | |
344 | ||
345 | static mcLexBuf_sourceList newElement (void * s); | |
346 | ||
347 | /* | |
348 | newList - initializes an empty list with the classic dummy header element. | |
349 | */ | |
350 | ||
351 | static mcLexBuf_sourceList newList (void); | |
352 | ||
353 | /* | |
354 | checkIfNeedToDuplicate - checks to see whether the currentSource has | |
355 | been used, if it has then duplicate the list. | |
356 | */ | |
357 | ||
358 | static void checkIfNeedToDuplicate (void); | |
359 | ||
360 | /* | |
361 | killList - kills the sourceList providing that it has not been used. | |
362 | */ | |
363 | ||
364 | static void killList (void); | |
365 | ||
366 | /* | |
367 | displayToken - | |
368 | */ | |
369 | ||
370 | static void displayToken (mcReserved_toktype t); | |
371 | ||
372 | /* | |
373 | updateFromBucket - updates the global variables: currenttoken, | |
374 | currentstring, currentcolumn and currentinteger | |
375 | from tokenBucket, b, and, offset. | |
376 | */ | |
377 | ||
378 | static void updateFromBucket (mcLexBuf_tokenBucket b, unsigned int offset); | |
379 | ||
380 | /* | |
381 | doGetToken - fetch the next token into currenttoken. | |
382 | */ | |
383 | ||
384 | static void doGetToken (void); | |
385 | ||
386 | /* | |
387 | syncOpenWithBuffer - synchronise the buffer with the start of a file. | |
388 | Skips all the tokens to do with the previous file. | |
389 | */ | |
390 | ||
391 | static void syncOpenWithBuffer (void); | |
392 | ||
393 | /* | |
394 | findtokenBucket - returns the tokenBucket corresponding to the tokenNo. | |
395 | */ | |
396 | ||
397 | static mcLexBuf_tokenBucket findtokenBucket (unsigned int *tokenNo); | |
398 | ||
399 | /* | |
400 | getFileName - returns a String defining the current file. | |
401 | */ | |
402 | ||
403 | static void stop (void); | |
404 | ||
405 | /* | |
406 | addTokToList - adds a token to a dynamic list. | |
407 | */ | |
408 | ||
409 | static void addTokToList (mcReserved_toktype t, nameKey_Name n, int i, mcComment_commentDesc comment, unsigned int l, unsigned int c, mcLexBuf_sourceList f); | |
410 | ||
411 | /* | |
412 | isLastTokenEof - returns TRUE if the last token was an eoftok | |
413 | */ | |
414 | ||
431c0669 | 415 | static bool isLastTokenEof (void); |
fbd2eda1 GM |
416 | |
417 | ||
418 | /* | |
419 | debugLex - display the last, n, tokens. | |
420 | */ | |
421 | ||
422 | static void debugLex (unsigned int n) | |
423 | { | |
424 | unsigned int c; | |
425 | unsigned int i; | |
426 | unsigned int o; | |
427 | unsigned int t; | |
428 | mcLexBuf_tokenBucket b; | |
429 | ||
430 | if (nextTokNo > n) | |
431 | { | |
432 | o = nextTokNo-n; | |
433 | } | |
434 | else | |
435 | { | |
436 | o = 0; | |
437 | } | |
438 | i = 0; | |
439 | do { | |
440 | t = o+i; | |
441 | if (nextTokNo == t) | |
442 | { | |
443 | mcPrintf_printf0 ((const char *) "nextTokNo ", 10); | |
444 | } | |
445 | b = findtokenBucket (&t); | |
446 | if (b == NULL) | |
447 | { | |
448 | t = o+i; | |
449 | mcPrintf_printf1 ((const char *) "end of buf (%d is further ahead than the buffer contents)\\n", 60, (const unsigned char *) &t, (sizeof (t)-1)); | |
450 | } | |
451 | else | |
452 | { | |
453 | c = o+i; | |
454 | mcPrintf_printf2 ((const char *) "entry %d %d ", 13, (const unsigned char *) &c, (sizeof (c)-1), (const unsigned char *) &t, (sizeof (t)-1)); | |
455 | displayToken (b->buf.array[t].token); | |
456 | mcPrintf_printf0 ((const char *) "\\n", 2); | |
457 | i += 1; | |
458 | } | |
459 | } while (! (b == NULL)); | |
460 | } | |
461 | ||
462 | ||
463 | /* | |
464 | seekTo - | |
465 | */ | |
466 | ||
467 | static void seekTo (unsigned int t) | |
468 | { | |
469 | mcLexBuf_tokenBucket b; | |
470 | ||
471 | nextTokNo = t; | |
472 | if (t > 0) | |
473 | { | |
474 | t -= 1; | |
475 | b = findtokenBucket (&t); | |
476 | if (b == NULL) | |
477 | { | |
478 | updateFromBucket (b, t); | |
479 | } | |
480 | } | |
481 | } | |
482 | ||
483 | ||
484 | /* | |
485 | peeptokenBucket - | |
486 | */ | |
487 | ||
488 | static mcLexBuf_tokenBucket peeptokenBucket (unsigned int *t) | |
489 | { | |
490 | mcReserved_toktype ct; | |
491 | unsigned int old; | |
492 | unsigned int n; | |
493 | mcLexBuf_tokenBucket b; | |
494 | mcLexBuf_tokenBucket c; | |
495 | ||
496 | ct = mcLexBuf_currenttoken; | |
497 | if (Debugging) | |
498 | { | |
499 | debugLex (5); | |
500 | } | |
501 | old = mcLexBuf_getTokenNo (); | |
502 | do { | |
503 | n = (*t); | |
504 | b = findtokenBucket (&n); | |
505 | if (b == NULL) | |
506 | { | |
507 | doGetToken (); | |
508 | n = (*t); | |
509 | b = findtokenBucket (&n); | |
510 | if ((b == NULL) || (mcLexBuf_currenttoken == mcReserved_eoftok)) | |
511 | { | |
512 | /* bailing out. */ | |
513 | nextTokNo = old+1; | |
514 | b = findtokenBucket (&old); | |
515 | updateFromBucket (b, old); | |
516 | return NULL; | |
517 | } | |
518 | } | |
519 | } while (! ((b != NULL) || (mcLexBuf_currenttoken == mcReserved_eoftok))); | |
520 | (*t) = n; | |
521 | nextTokNo = old+1; | |
522 | if (Debugging) | |
523 | { | |
524 | mcPrintf_printf2 ((const char *) "nextTokNo = %d, old = %d\\n", 26, (const unsigned char *) &nextTokNo, (sizeof (nextTokNo)-1), (const unsigned char *) &old, (sizeof (old)-1)); | |
525 | } | |
526 | b = findtokenBucket (&old); | |
527 | if (Debugging) | |
528 | { | |
529 | mcPrintf_printf1 ((const char *) " adjusted old = %d\\n", 21, (const unsigned char *) &old, (sizeof (old)-1)); | |
530 | } | |
531 | if (b != NULL) | |
532 | { | |
533 | updateFromBucket (b, old); | |
534 | } | |
535 | if (Debugging) | |
536 | { | |
537 | debugLex (5); | |
538 | } | |
539 | mcDebug_assert (ct == mcLexBuf_currenttoken); | |
540 | return b; | |
541 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
542 | __builtin_unreachable (); | |
543 | } | |
544 | ||
545 | ||
546 | /* | |
547 | peepAfterComment - peeps ahead looking for an after statement comment. It stops at an END token | |
548 | or if the line number changes. | |
549 | */ | |
550 | ||
551 | static void peepAfterComment (void) | |
552 | { | |
553 | unsigned int oldTokNo; | |
554 | unsigned int t; | |
555 | unsigned int peep; | |
556 | unsigned int cno; | |
557 | unsigned int nextline; | |
558 | unsigned int curline; | |
559 | mcLexBuf_tokenBucket b; | |
431c0669 | 560 | bool finished; |
fbd2eda1 GM |
561 | |
562 | oldTokNo = nextTokNo; | |
563 | cno = mcLexBuf_getTokenNo (); | |
564 | curline = mcLexBuf_tokenToLineNo (cno, 0); | |
565 | nextline = curline; | |
566 | peep = 0; | |
431c0669 | 567 | finished = false; |
fbd2eda1 GM |
568 | do { |
569 | t = cno+peep; | |
570 | b = peeptokenBucket (&t); | |
571 | if ((b == NULL) || (mcLexBuf_currenttoken == mcReserved_eoftok)) | |
572 | { | |
431c0669 | 573 | finished = true; |
fbd2eda1 GM |
574 | } |
575 | else | |
576 | { | |
577 | nextline = b->buf.array[t].line; | |
578 | if (nextline == curline) | |
579 | { | |
580 | switch (b->buf.array[t].token) | |
581 | { | |
582 | case mcReserved_eoftok: | |
583 | case mcReserved_endtok: | |
431c0669 | 584 | finished = true; |
fbd2eda1 GM |
585 | break; |
586 | ||
587 | case mcReserved_commenttok: | |
588 | if (mcComment_isAfterComment (b->buf.array[t].com)) | |
589 | { | |
590 | afterComment = b->buf.array[t].com; | |
591 | } | |
592 | break; | |
593 | ||
594 | ||
595 | default: | |
596 | break; | |
597 | } | |
598 | } | |
599 | else | |
600 | { | |
431c0669 | 601 | finished = true; |
fbd2eda1 GM |
602 | } |
603 | } | |
604 | peep += 1; | |
605 | } while (! (finished)); | |
606 | seekTo (oldTokNo); | |
607 | } | |
608 | ||
609 | ||
610 | /* | |
611 | init - initializes the token list and source list. | |
612 | */ | |
613 | ||
614 | static void init (void) | |
615 | { | |
616 | mcLexBuf_currenttoken = mcReserved_eoftok; | |
617 | nextTokNo = 0; | |
618 | currentSource = NULL; | |
619 | listOfTokens.head = NULL; | |
620 | listOfTokens.tail = NULL; | |
431c0669 | 621 | useBufferedTokens = false; |
fbd2eda1 GM |
622 | procedureComment = static_cast<mcComment_commentDesc> (NULL); |
623 | bodyComment = static_cast<mcComment_commentDesc> (NULL); | |
624 | afterComment = static_cast<mcComment_commentDesc> (NULL); | |
625 | mcLexBuf_lastcomment = static_cast<mcComment_commentDesc> (NULL); | |
626 | } | |
627 | ||
628 | ||
629 | /* | |
630 | addTo - adds a new element to the end of sourceList, currentSource. | |
631 | */ | |
632 | ||
633 | static void addTo (mcLexBuf_sourceList l) | |
634 | { | |
635 | l->right = currentSource; | |
636 | l->left = currentSource->left; | |
637 | currentSource->left->right = l; | |
638 | currentSource->left = l; | |
639 | l->left->line = mcflex_getLineNo (); | |
640 | l->left->col = mcflex_getColumnNo (); | |
641 | } | |
642 | ||
643 | ||
644 | /* | |
645 | subFrom - subtracts, l, from the source list. | |
646 | */ | |
647 | ||
648 | static void subFrom (mcLexBuf_sourceList l) | |
649 | { | |
650 | l->left->right = l->right; | |
651 | l->right->left = l->left; | |
652 | } | |
653 | ||
654 | ||
655 | /* | |
656 | newElement - returns a new sourceList | |
657 | */ | |
658 | ||
659 | static mcLexBuf_sourceList newElement (void * s) | |
660 | { | |
661 | mcLexBuf_sourceList l; | |
662 | ||
663 | Storage_ALLOCATE ((void **) &l, sizeof (mcLexBuf__T1)); | |
664 | if (l == NULL) | |
665 | { | |
666 | M2RTS_HALT (-1); | |
667 | __builtin_unreachable (); | |
668 | } | |
669 | else | |
670 | { | |
671 | l->name = DynamicStrings_InitStringCharStar (s); | |
672 | l->left = NULL; | |
673 | l->right = NULL; | |
674 | } | |
675 | return l; | |
676 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
677 | __builtin_unreachable (); | |
678 | } | |
679 | ||
680 | ||
681 | /* | |
682 | newList - initializes an empty list with the classic dummy header element. | |
683 | */ | |
684 | ||
685 | static mcLexBuf_sourceList newList (void) | |
686 | { | |
687 | mcLexBuf_sourceList l; | |
688 | ||
689 | Storage_ALLOCATE ((void **) &l, sizeof (mcLexBuf__T1)); | |
690 | l->left = l; | |
691 | l->right = l; | |
692 | l->name = static_cast<DynamicStrings_String> (NULL); | |
693 | return l; | |
694 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
695 | __builtin_unreachable (); | |
696 | } | |
697 | ||
698 | ||
699 | /* | |
700 | checkIfNeedToDuplicate - checks to see whether the currentSource has | |
701 | been used, if it has then duplicate the list. | |
702 | */ | |
703 | ||
704 | static void checkIfNeedToDuplicate (void) | |
705 | { | |
706 | mcLexBuf_sourceList l; | |
707 | mcLexBuf_sourceList h; | |
708 | ||
709 | if (currentUsed) | |
710 | { | |
711 | l = currentSource->right; | |
712 | h = currentSource; | |
713 | currentSource = newList (); | |
714 | while (l != h) | |
715 | { | |
716 | addTo (newElement (reinterpret_cast<void *> (l->name))); | |
717 | l = l->right; | |
718 | } | |
719 | } | |
720 | } | |
721 | ||
722 | ||
723 | /* | |
724 | killList - kills the sourceList providing that it has not been used. | |
725 | */ | |
726 | ||
727 | static void killList (void) | |
728 | { | |
729 | mcLexBuf_sourceList l; | |
730 | mcLexBuf_sourceList k; | |
731 | ||
732 | if (! currentUsed && (currentSource != NULL)) | |
733 | { | |
734 | l = currentSource; | |
735 | do { | |
736 | k = l; | |
737 | l = l->right; | |
738 | Storage_DEALLOCATE ((void **) &k, sizeof (mcLexBuf__T1)); | |
739 | } while (! (l == currentSource)); | |
740 | } | |
741 | } | |
742 | ||
743 | ||
744 | /* | |
745 | displayToken - | |
746 | */ | |
747 | ||
748 | static void displayToken (mcReserved_toktype t) | |
749 | { | |
750 | switch (t) | |
751 | { | |
752 | case mcReserved_eoftok: | |
753 | mcPrintf_printf0 ((const char *) "eoftok\\n", 8); | |
754 | break; | |
755 | ||
756 | case mcReserved_plustok: | |
757 | mcPrintf_printf0 ((const char *) "plustok\\n", 9); | |
758 | break; | |
759 | ||
760 | case mcReserved_minustok: | |
761 | mcPrintf_printf0 ((const char *) "minustok\\n", 10); | |
762 | break; | |
763 | ||
764 | case mcReserved_timestok: | |
765 | mcPrintf_printf0 ((const char *) "timestok\\n", 10); | |
766 | break; | |
767 | ||
768 | case mcReserved_dividetok: | |
769 | mcPrintf_printf0 ((const char *) "dividetok\\n", 11); | |
770 | break; | |
771 | ||
772 | case mcReserved_becomestok: | |
773 | mcPrintf_printf0 ((const char *) "becomestok\\n", 12); | |
774 | break; | |
775 | ||
776 | case mcReserved_ambersandtok: | |
777 | mcPrintf_printf0 ((const char *) "ambersandtok\\n", 14); | |
778 | break; | |
779 | ||
780 | case mcReserved_periodtok: | |
781 | mcPrintf_printf0 ((const char *) "periodtok\\n", 11); | |
782 | break; | |
783 | ||
784 | case mcReserved_commatok: | |
785 | mcPrintf_printf0 ((const char *) "commatok\\n", 10); | |
786 | break; | |
787 | ||
788 | case mcReserved_commenttok: | |
789 | mcPrintf_printf0 ((const char *) "commenttok\\n", 12); | |
790 | break; | |
791 | ||
792 | case mcReserved_semicolontok: | |
793 | mcPrintf_printf0 ((const char *) "semicolontok\\n", 14); | |
794 | break; | |
795 | ||
796 | case mcReserved_lparatok: | |
797 | mcPrintf_printf0 ((const char *) "lparatok\\n", 10); | |
798 | break; | |
799 | ||
800 | case mcReserved_rparatok: | |
801 | mcPrintf_printf0 ((const char *) "rparatok\\n", 10); | |
802 | break; | |
803 | ||
804 | case mcReserved_lsbratok: | |
805 | mcPrintf_printf0 ((const char *) "lsbratok\\n", 10); | |
806 | break; | |
807 | ||
808 | case mcReserved_rsbratok: | |
809 | mcPrintf_printf0 ((const char *) "rsbratok\\n", 10); | |
810 | break; | |
811 | ||
812 | case mcReserved_lcbratok: | |
813 | mcPrintf_printf0 ((const char *) "lcbratok\\n", 10); | |
814 | break; | |
815 | ||
816 | case mcReserved_rcbratok: | |
817 | mcPrintf_printf0 ((const char *) "rcbratok\\n", 10); | |
818 | break; | |
819 | ||
820 | case mcReserved_uparrowtok: | |
821 | mcPrintf_printf0 ((const char *) "uparrowtok\\n", 12); | |
822 | break; | |
823 | ||
824 | case mcReserved_singlequotetok: | |
825 | mcPrintf_printf0 ((const char *) "singlequotetok\\n", 16); | |
826 | break; | |
827 | ||
828 | case mcReserved_equaltok: | |
829 | mcPrintf_printf0 ((const char *) "equaltok\\n", 10); | |
830 | break; | |
831 | ||
832 | case mcReserved_hashtok: | |
833 | mcPrintf_printf0 ((const char *) "hashtok\\n", 9); | |
834 | break; | |
835 | ||
836 | case mcReserved_lesstok: | |
837 | mcPrintf_printf0 ((const char *) "lesstok\\n", 9); | |
838 | break; | |
839 | ||
840 | case mcReserved_greatertok: | |
841 | mcPrintf_printf0 ((const char *) "greatertok\\n", 12); | |
842 | break; | |
843 | ||
844 | case mcReserved_lessgreatertok: | |
845 | mcPrintf_printf0 ((const char *) "lessgreatertok\\n", 16); | |
846 | break; | |
847 | ||
848 | case mcReserved_lessequaltok: | |
849 | mcPrintf_printf0 ((const char *) "lessequaltok\\n", 14); | |
850 | break; | |
851 | ||
852 | case mcReserved_greaterequaltok: | |
853 | mcPrintf_printf0 ((const char *) "greaterequaltok\\n", 17); | |
854 | break; | |
855 | ||
856 | case mcReserved_periodperiodtok: | |
857 | mcPrintf_printf0 ((const char *) "periodperiodtok\\n", 17); | |
858 | break; | |
859 | ||
860 | case mcReserved_colontok: | |
861 | mcPrintf_printf0 ((const char *) "colontok\\n", 10); | |
862 | break; | |
863 | ||
864 | case mcReserved_doublequotestok: | |
865 | mcPrintf_printf0 ((const char *) "doublequotestok\\n", 17); | |
866 | break; | |
867 | ||
868 | case mcReserved_bartok: | |
869 | mcPrintf_printf0 ((const char *) "bartok\\n", 8); | |
870 | break; | |
871 | ||
872 | case mcReserved_andtok: | |
873 | mcPrintf_printf0 ((const char *) "andtok\\n", 8); | |
874 | break; | |
875 | ||
876 | case mcReserved_arraytok: | |
877 | mcPrintf_printf0 ((const char *) "arraytok\\n", 10); | |
878 | break; | |
879 | ||
880 | case mcReserved_begintok: | |
881 | mcPrintf_printf0 ((const char *) "begintok\\n", 10); | |
882 | break; | |
883 | ||
884 | case mcReserved_bytok: | |
885 | mcPrintf_printf0 ((const char *) "bytok\\n", 7); | |
886 | break; | |
887 | ||
888 | case mcReserved_casetok: | |
889 | mcPrintf_printf0 ((const char *) "casetok\\n", 9); | |
890 | break; | |
891 | ||
892 | case mcReserved_consttok: | |
893 | mcPrintf_printf0 ((const char *) "consttok\\n", 10); | |
894 | break; | |
895 | ||
896 | case mcReserved_definitiontok: | |
897 | mcPrintf_printf0 ((const char *) "definitiontok\\n", 15); | |
898 | break; | |
899 | ||
900 | case mcReserved_divtok: | |
901 | mcPrintf_printf0 ((const char *) "divtok\\n", 8); | |
902 | break; | |
903 | ||
904 | case mcReserved_dotok: | |
905 | mcPrintf_printf0 ((const char *) "dotok\\n", 7); | |
906 | break; | |
907 | ||
908 | case mcReserved_elsetok: | |
909 | mcPrintf_printf0 ((const char *) "elsetok\\n", 9); | |
910 | break; | |
911 | ||
912 | case mcReserved_elsiftok: | |
913 | mcPrintf_printf0 ((const char *) "elsiftok\\n", 10); | |
914 | break; | |
915 | ||
916 | case mcReserved_endtok: | |
917 | mcPrintf_printf0 ((const char *) "endtok\\n", 8); | |
918 | break; | |
919 | ||
920 | case mcReserved_exittok: | |
921 | mcPrintf_printf0 ((const char *) "exittok\\n", 9); | |
922 | break; | |
923 | ||
924 | case mcReserved_exporttok: | |
925 | mcPrintf_printf0 ((const char *) "exporttok\\n", 11); | |
926 | break; | |
927 | ||
928 | case mcReserved_fortok: | |
929 | mcPrintf_printf0 ((const char *) "fortok\\n", 8); | |
930 | break; | |
931 | ||
932 | case mcReserved_fromtok: | |
933 | mcPrintf_printf0 ((const char *) "fromtok\\n", 9); | |
934 | break; | |
935 | ||
936 | case mcReserved_iftok: | |
937 | mcPrintf_printf0 ((const char *) "iftok\\n", 7); | |
938 | break; | |
939 | ||
940 | case mcReserved_implementationtok: | |
941 | mcPrintf_printf0 ((const char *) "implementationtok\\n", 19); | |
942 | break; | |
943 | ||
944 | case mcReserved_importtok: | |
945 | mcPrintf_printf0 ((const char *) "importtok\\n", 11); | |
946 | break; | |
947 | ||
948 | case mcReserved_intok: | |
949 | mcPrintf_printf0 ((const char *) "intok\\n", 7); | |
950 | break; | |
951 | ||
952 | case mcReserved_looptok: | |
953 | mcPrintf_printf0 ((const char *) "looptok\\n", 9); | |
954 | break; | |
955 | ||
956 | case mcReserved_modtok: | |
957 | mcPrintf_printf0 ((const char *) "modtok\\n", 8); | |
958 | break; | |
959 | ||
960 | case mcReserved_moduletok: | |
961 | mcPrintf_printf0 ((const char *) "moduletok\\n", 11); | |
962 | break; | |
963 | ||
964 | case mcReserved_nottok: | |
965 | mcPrintf_printf0 ((const char *) "nottok\\n", 8); | |
966 | break; | |
967 | ||
968 | case mcReserved_oftok: | |
969 | mcPrintf_printf0 ((const char *) "oftok\\n", 7); | |
970 | break; | |
971 | ||
972 | case mcReserved_ortok: | |
973 | mcPrintf_printf0 ((const char *) "ortok\\n", 7); | |
974 | break; | |
975 | ||
976 | case mcReserved_pointertok: | |
977 | mcPrintf_printf0 ((const char *) "pointertok\\n", 12); | |
978 | break; | |
979 | ||
980 | case mcReserved_proceduretok: | |
981 | mcPrintf_printf0 ((const char *) "proceduretok\\n", 14); | |
982 | break; | |
983 | ||
984 | case mcReserved_qualifiedtok: | |
985 | mcPrintf_printf0 ((const char *) "qualifiedtok\\n", 14); | |
986 | break; | |
987 | ||
988 | case mcReserved_unqualifiedtok: | |
989 | mcPrintf_printf0 ((const char *) "unqualifiedtok\\n", 16); | |
990 | break; | |
991 | ||
992 | case mcReserved_recordtok: | |
993 | mcPrintf_printf0 ((const char *) "recordtok\\n", 11); | |
994 | break; | |
995 | ||
996 | case mcReserved_repeattok: | |
997 | mcPrintf_printf0 ((const char *) "repeattok\\n", 11); | |
998 | break; | |
999 | ||
1000 | case mcReserved_returntok: | |
1001 | mcPrintf_printf0 ((const char *) "returntok\\n", 11); | |
1002 | break; | |
1003 | ||
1004 | case mcReserved_settok: | |
1005 | mcPrintf_printf0 ((const char *) "settok\\n", 8); | |
1006 | break; | |
1007 | ||
1008 | case mcReserved_thentok: | |
1009 | mcPrintf_printf0 ((const char *) "thentok\\n", 9); | |
1010 | break; | |
1011 | ||
1012 | case mcReserved_totok: | |
1013 | mcPrintf_printf0 ((const char *) "totok\\n", 7); | |
1014 | break; | |
1015 | ||
1016 | case mcReserved_typetok: | |
1017 | mcPrintf_printf0 ((const char *) "typetok\\n", 9); | |
1018 | break; | |
1019 | ||
1020 | case mcReserved_untiltok: | |
1021 | mcPrintf_printf0 ((const char *) "untiltok\\n", 10); | |
1022 | break; | |
1023 | ||
1024 | case mcReserved_vartok: | |
1025 | mcPrintf_printf0 ((const char *) "vartok\\n", 8); | |
1026 | break; | |
1027 | ||
1028 | case mcReserved_whiletok: | |
1029 | mcPrintf_printf0 ((const char *) "whiletok\\n", 10); | |
1030 | break; | |
1031 | ||
1032 | case mcReserved_withtok: | |
1033 | mcPrintf_printf0 ((const char *) "withtok\\n", 9); | |
1034 | break; | |
1035 | ||
1036 | case mcReserved_asmtok: | |
1037 | mcPrintf_printf0 ((const char *) "asmtok\\n", 8); | |
1038 | break; | |
1039 | ||
1040 | case mcReserved_volatiletok: | |
1041 | mcPrintf_printf0 ((const char *) "volatiletok\\n", 13); | |
1042 | break; | |
1043 | ||
1044 | case mcReserved_periodperiodperiodtok: | |
1045 | mcPrintf_printf0 ((const char *) "periodperiodperiodtok\\n", 23); | |
1046 | break; | |
1047 | ||
1048 | case mcReserved_datetok: | |
1049 | mcPrintf_printf0 ((const char *) "datetok\\n", 9); | |
1050 | break; | |
1051 | ||
1052 | case mcReserved_linetok: | |
1053 | mcPrintf_printf0 ((const char *) "linetok\\n", 9); | |
1054 | break; | |
1055 | ||
1056 | case mcReserved_filetok: | |
1057 | mcPrintf_printf0 ((const char *) "filetok\\n", 9); | |
1058 | break; | |
1059 | ||
1060 | case mcReserved_integertok: | |
1061 | mcPrintf_printf0 ((const char *) "integertok\\n", 12); | |
1062 | break; | |
1063 | ||
1064 | case mcReserved_identtok: | |
1065 | mcPrintf_printf0 ((const char *) "identtok\\n", 10); | |
1066 | break; | |
1067 | ||
1068 | case mcReserved_realtok: | |
1069 | mcPrintf_printf0 ((const char *) "realtok\\n", 9); | |
1070 | break; | |
1071 | ||
1072 | case mcReserved_stringtok: | |
1073 | mcPrintf_printf0 ((const char *) "stringtok\\n", 11); | |
1074 | break; | |
1075 | ||
1076 | ||
1077 | default: | |
1078 | mcPrintf_printf0 ((const char *) "unknown tok (--fixme--)\\n", 25); | |
1079 | break; | |
1080 | } | |
1081 | } | |
1082 | ||
1083 | ||
1084 | /* | |
1085 | updateFromBucket - updates the global variables: currenttoken, | |
1086 | currentstring, currentcolumn and currentinteger | |
1087 | from tokenBucket, b, and, offset. | |
1088 | */ | |
1089 | ||
1090 | static void updateFromBucket (mcLexBuf_tokenBucket b, unsigned int offset) | |
1091 | { | |
1092 | mcLexBuf_currenttoken = b->buf.array[offset].token; | |
1093 | mcLexBuf_currentstring = nameKey_keyToCharStar (b->buf.array[offset].str); | |
1094 | mcLexBuf_currentcolumn = b->buf.array[offset].col; | |
1095 | mcLexBuf_currentinteger = b->buf.array[offset].int_; | |
1096 | mcLexBuf_currentcomment = b->buf.array[offset].com; | |
1097 | if (mcLexBuf_currentcomment != NULL) | |
1098 | { | |
1099 | mcLexBuf_lastcomment = mcLexBuf_currentcomment; | |
1100 | } | |
1101 | if (Debugging) | |
1102 | { | |
1103 | mcPrintf_printf3 ((const char *) "line %d (# %d %d) ", 19, (const unsigned char *) &b->buf.array[offset].line, (sizeof (b->buf.array[offset].line)-1), (const unsigned char *) &offset, (sizeof (offset)-1), (const unsigned char *) &nextTokNo, (sizeof (nextTokNo)-1)); | |
1104 | } | |
1105 | } | |
1106 | ||
1107 | ||
1108 | /* | |
1109 | doGetToken - fetch the next token into currenttoken. | |
1110 | */ | |
1111 | ||
1112 | static void doGetToken (void) | |
1113 | { | |
1114 | void * a; | |
1115 | unsigned int t; | |
1116 | mcLexBuf_tokenBucket b; | |
1117 | ||
1118 | if (useBufferedTokens) | |
1119 | { | |
1120 | t = nextTokNo; | |
1121 | b = findtokenBucket (&t); | |
1122 | updateFromBucket (b, t); | |
1123 | } | |
1124 | else | |
1125 | { | |
1126 | if (listOfTokens.tail == NULL) | |
1127 | { | |
1128 | a = mcflex_getToken (); | |
1129 | if (listOfTokens.tail == NULL) | |
1130 | { | |
1131 | M2RTS_HALT (-1); | |
1132 | __builtin_unreachable (); | |
1133 | } | |
1134 | } | |
1135 | if (nextTokNo >= listOfTokens.lastBucketOffset) | |
1136 | { | |
1137 | /* nextTokNo is in the last bucket or needs to be read. */ | |
1138 | if ((nextTokNo-listOfTokens.lastBucketOffset) < listOfTokens.tail->len) | |
1139 | { | |
1140 | if (Debugging) | |
1141 | { | |
1142 | mcPrintf_printf0 ((const char *) "fetching token from buffer (updateFromBucket)\\n", 47); | |
1143 | } | |
1144 | updateFromBucket (listOfTokens.tail, nextTokNo-listOfTokens.lastBucketOffset); | |
1145 | } | |
1146 | else | |
1147 | { | |
1148 | if (Debugging) | |
1149 | { | |
1150 | mcPrintf_printf0 ((const char *) "calling flex to place token into buffer\\n", 41); | |
1151 | } | |
1152 | /* call the lexical phase to place a new token into the last bucket. */ | |
1153 | a = mcflex_getToken (); | |
1154 | mcLexBuf_getToken (); /* and call ourselves again to collect the token from bucket. */ | |
1155 | return ; /* and call ourselves again to collect the token from bucket. */ | |
1156 | } | |
1157 | } | |
1158 | else | |
1159 | { | |
1160 | if (Debugging) | |
1161 | { | |
1162 | mcPrintf_printf0 ((const char *) "fetching token from buffer\\n", 28); | |
1163 | } | |
1164 | t = nextTokNo; | |
1165 | b = findtokenBucket (&t); | |
1166 | updateFromBucket (b, t); | |
1167 | } | |
1168 | } | |
1169 | if (Debugging) | |
1170 | { | |
1171 | displayToken (mcLexBuf_currenttoken); | |
1172 | } | |
1173 | nextTokNo += 1; | |
1174 | } | |
1175 | ||
1176 | ||
1177 | /* | |
1178 | syncOpenWithBuffer - synchronise the buffer with the start of a file. | |
1179 | Skips all the tokens to do with the previous file. | |
1180 | */ | |
1181 | ||
1182 | static void syncOpenWithBuffer (void) | |
1183 | { | |
1184 | if (listOfTokens.tail != NULL) | |
1185 | { | |
1186 | nextTokNo = listOfTokens.lastBucketOffset+listOfTokens.tail->len; | |
1187 | } | |
1188 | } | |
1189 | ||
1190 | ||
1191 | /* | |
1192 | findtokenBucket - returns the tokenBucket corresponding to the tokenNo. | |
1193 | */ | |
1194 | ||
1195 | static mcLexBuf_tokenBucket findtokenBucket (unsigned int *tokenNo) | |
1196 | { | |
1197 | mcLexBuf_tokenBucket b; | |
1198 | ||
1199 | b = listOfTokens.head; | |
1200 | while (b != NULL) | |
1201 | { | |
1202 | if ((*tokenNo) < b->len) | |
1203 | { | |
1204 | return b; | |
1205 | } | |
1206 | else | |
1207 | { | |
1208 | (*tokenNo) -= b->len; | |
1209 | } | |
1210 | b = b->next; | |
1211 | } | |
1212 | return NULL; | |
1213 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
1214 | __builtin_unreachable (); | |
1215 | } | |
1216 | ||
1217 | ||
1218 | /* | |
1219 | getFileName - returns a String defining the current file. | |
1220 | */ | |
1221 | ||
1222 | static void stop (void) | |
1223 | { | |
1224 | } | |
1225 | ||
1226 | ||
1227 | /* | |
1228 | addTokToList - adds a token to a dynamic list. | |
1229 | */ | |
1230 | ||
1231 | static void addTokToList (mcReserved_toktype t, nameKey_Name n, int i, mcComment_commentDesc comment, unsigned int l, unsigned int c, mcLexBuf_sourceList f) | |
1232 | { | |
1233 | mcLexBuf_tokenBucket b; | |
1234 | ||
1235 | if (listOfTokens.head == NULL) | |
1236 | { | |
1237 | Storage_ALLOCATE ((void **) &listOfTokens.head, sizeof (mcLexBuf__T2)); | |
1238 | if (listOfTokens.head == NULL) | |
1239 | {} /* empty. */ | |
1240 | /* list error */ | |
1241 | listOfTokens.tail = listOfTokens.head; | |
1242 | listOfTokens.tail->len = 0; | |
1243 | } | |
1244 | else if (listOfTokens.tail->len == MaxBucketSize) | |
1245 | { | |
1246 | /* avoid dangling else. */ | |
1247 | mcDebug_assert (listOfTokens.tail->next == NULL); | |
1248 | Storage_ALLOCATE ((void **) &listOfTokens.tail->next, sizeof (mcLexBuf__T2)); | |
1249 | if (listOfTokens.tail->next == NULL) | |
1250 | {} /* empty. */ | |
1251 | else | |
1252 | { | |
1253 | /* list error */ | |
1254 | listOfTokens.tail = listOfTokens.tail->next; | |
1255 | listOfTokens.tail->len = 0; | |
1256 | } | |
1257 | listOfTokens.lastBucketOffset += MaxBucketSize; | |
1258 | } | |
1259 | listOfTokens.tail->next = NULL; | |
1260 | mcDebug_assert (listOfTokens.tail->len != MaxBucketSize); | |
1261 | listOfTokens.tail->buf.array[listOfTokens.tail->len].token = t; | |
1262 | listOfTokens.tail->buf.array[listOfTokens.tail->len].str = n; | |
1263 | listOfTokens.tail->buf.array[listOfTokens.tail->len].int_ = i; | |
1264 | listOfTokens.tail->buf.array[listOfTokens.tail->len].com = comment; | |
1265 | listOfTokens.tail->buf.array[listOfTokens.tail->len].line = l; | |
1266 | listOfTokens.tail->buf.array[listOfTokens.tail->len].col = c; | |
1267 | listOfTokens.tail->buf.array[listOfTokens.tail->len].file = f; | |
1268 | listOfTokens.tail->len += 1; | |
1269 | } | |
1270 | ||
1271 | ||
1272 | /* | |
1273 | isLastTokenEof - returns TRUE if the last token was an eoftok | |
1274 | */ | |
1275 | ||
431c0669 | 1276 | static bool isLastTokenEof (void) |
fbd2eda1 GM |
1277 | { |
1278 | unsigned int t; | |
1279 | mcLexBuf_tokenBucket b; | |
1280 | ||
1281 | if (listOfTokens.tail != NULL) | |
1282 | { | |
1283 | if (listOfTokens.tail->len == 0) | |
1284 | { | |
1285 | b = listOfTokens.head; | |
1286 | if (b == listOfTokens.tail) | |
1287 | { | |
431c0669 | 1288 | return false; |
fbd2eda1 GM |
1289 | } |
1290 | while (b->next != listOfTokens.tail) | |
1291 | { | |
1292 | b = b->next; | |
1293 | } | |
1294 | } | |
1295 | else | |
1296 | { | |
1297 | b = listOfTokens.tail; | |
1298 | } | |
1299 | mcDebug_assert (b->len > 0); /* len should always be >0 */ | |
1300 | return b->buf.array[b->len-1].token == mcReserved_eoftok; /* len should always be >0 */ | |
1301 | } | |
431c0669 | 1302 | return false; |
fbd2eda1 GM |
1303 | /* static analysis guarentees a RETURN statement will be used before here. */ |
1304 | __builtin_unreachable (); | |
1305 | } | |
1306 | ||
1307 | ||
1308 | /* | |
1309 | getProcedureComment - returns the procedure comment if it exists, | |
1310 | or NIL otherwise. | |
1311 | */ | |
1312 | ||
1313 | extern "C" mcComment_commentDesc mcLexBuf_getProcedureComment (void) | |
1314 | { | |
1315 | return procedureComment; | |
1316 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
1317 | __builtin_unreachable (); | |
1318 | } | |
1319 | ||
1320 | ||
1321 | /* | |
1322 | getBodyComment - returns the body comment if it exists, | |
1323 | or NIL otherwise. The body comment is | |
1324 | removed if found. | |
1325 | */ | |
1326 | ||
1327 | extern "C" mcComment_commentDesc mcLexBuf_getBodyComment (void) | |
1328 | { | |
1329 | mcComment_commentDesc b; | |
1330 | ||
1331 | b = bodyComment; | |
1332 | bodyComment = static_cast<mcComment_commentDesc> (NULL); | |
1333 | return b; | |
1334 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
1335 | __builtin_unreachable (); | |
1336 | } | |
1337 | ||
1338 | ||
1339 | /* | |
1340 | getAfterComment - returns the after comment if it exists, | |
1341 | or NIL otherwise. The after comment is | |
1342 | removed if found. | |
1343 | */ | |
1344 | ||
1345 | extern "C" mcComment_commentDesc mcLexBuf_getAfterComment (void) | |
1346 | { | |
1347 | mcComment_commentDesc a; | |
1348 | ||
1349 | peepAfterComment (); | |
1350 | a = afterComment; | |
1351 | afterComment = static_cast<mcComment_commentDesc> (NULL); | |
1352 | return a; | |
1353 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
1354 | __builtin_unreachable (); | |
1355 | } | |
1356 | ||
1357 | ||
1358 | /* | |
1359 | openSource - attempts to open the source file, s. | |
1360 | The success of the operation is returned. | |
1361 | */ | |
1362 | ||
431c0669 | 1363 | extern "C" bool mcLexBuf_openSource (DynamicStrings_String s) |
fbd2eda1 GM |
1364 | { |
1365 | if (useBufferedTokens) | |
1366 | { | |
1367 | mcLexBuf_getToken (); | |
431c0669 | 1368 | return true; |
fbd2eda1 GM |
1369 | } |
1370 | else | |
1371 | { | |
1372 | if (mcflex_openSource (DynamicStrings_string (s))) | |
1373 | { | |
1374 | mcLexBuf_setFile (DynamicStrings_string (s)); | |
1375 | syncOpenWithBuffer (); | |
1376 | mcLexBuf_getToken (); | |
431c0669 | 1377 | return true; |
fbd2eda1 GM |
1378 | } |
1379 | else | |
1380 | { | |
431c0669 | 1381 | return false; |
fbd2eda1 GM |
1382 | } |
1383 | } | |
1384 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
1385 | __builtin_unreachable (); | |
1386 | } | |
1387 | ||
1388 | ||
1389 | /* | |
1390 | closeSource - closes the current open file. | |
1391 | */ | |
1392 | ||
1393 | extern "C" void mcLexBuf_closeSource (void) | |
1394 | { | |
1395 | if (useBufferedTokens) | |
1396 | { | |
1397 | while (mcLexBuf_currenttoken != mcReserved_eoftok) | |
1398 | { | |
1399 | mcLexBuf_getToken (); | |
1400 | } | |
1401 | } | |
1402 | /* a subsequent call to mcflex.OpenSource will really close the file */ | |
1403 | } | |
1404 | ||
1405 | ||
1406 | /* | |
1407 | reInitialize - re-initialize the all the data structures. | |
1408 | */ | |
1409 | ||
1410 | extern "C" void mcLexBuf_reInitialize (void) | |
1411 | { | |
1412 | mcLexBuf_tokenBucket s; | |
1413 | mcLexBuf_tokenBucket t; | |
1414 | ||
1415 | if (listOfTokens.head != NULL) | |
1416 | { | |
1417 | t = listOfTokens.head; | |
1418 | do { | |
1419 | s = t; | |
1420 | t = t->next; | |
1421 | Storage_DEALLOCATE ((void **) &s, sizeof (mcLexBuf__T2)); | |
1422 | } while (! (t == NULL)); | |
431c0669 | 1423 | currentUsed = false; |
fbd2eda1 GM |
1424 | killList (); |
1425 | } | |
1426 | init (); | |
1427 | } | |
1428 | ||
1429 | ||
1430 | /* | |
1431 | resetForNewPass - reset the buffer pointers to the beginning ready for | |
1432 | a new pass | |
1433 | */ | |
1434 | ||
1435 | extern "C" void mcLexBuf_resetForNewPass (void) | |
1436 | { | |
1437 | nextTokNo = 0; | |
431c0669 | 1438 | useBufferedTokens = true; |
fbd2eda1 GM |
1439 | } |
1440 | ||
1441 | ||
1442 | /* | |
1443 | getToken - gets the next token into currenttoken. | |
1444 | */ | |
1445 | ||
1446 | extern "C" void mcLexBuf_getToken (void) | |
1447 | { | |
1448 | do { | |
1449 | doGetToken (); | |
1450 | if (mcLexBuf_currenttoken == mcReserved_commenttok) | |
1451 | { | |
1452 | /* avoid gcc warning by using compound statement even if not strictly necessary. */ | |
1453 | if (mcComment_isProcedureComment (mcLexBuf_currentcomment)) | |
1454 | { | |
1455 | procedureComment = mcLexBuf_currentcomment; | |
1456 | bodyComment = static_cast<mcComment_commentDesc> (NULL); | |
1457 | afterComment = static_cast<mcComment_commentDesc> (NULL); | |
1458 | } | |
1459 | else if (mcComment_isBodyComment (mcLexBuf_currentcomment)) | |
1460 | { | |
1461 | /* avoid dangling else. */ | |
1462 | bodyComment = mcLexBuf_currentcomment; | |
1463 | afterComment = static_cast<mcComment_commentDesc> (NULL); | |
1464 | } | |
1465 | else if (mcComment_isAfterComment (mcLexBuf_currentcomment)) | |
1466 | { | |
1467 | /* avoid dangling else. */ | |
1468 | procedureComment = static_cast<mcComment_commentDesc> (NULL); | |
1469 | bodyComment = static_cast<mcComment_commentDesc> (NULL); | |
1470 | afterComment = mcLexBuf_currentcomment; | |
1471 | } | |
1472 | } | |
1473 | } while (! (mcLexBuf_currenttoken != mcReserved_commenttok)); | |
1474 | } | |
1475 | ||
1476 | ||
1477 | /* | |
1478 | insertToken - inserts a symbol, token, infront of the current token | |
1479 | ready for the next pass. | |
1480 | */ | |
1481 | ||
1482 | extern "C" void mcLexBuf_insertToken (mcReserved_toktype token) | |
1483 | { | |
1484 | if (listOfTokens.tail != NULL) | |
1485 | { | |
1486 | if (listOfTokens.tail->len > 0) | |
1487 | { | |
1488 | listOfTokens.tail->buf.array[listOfTokens.tail->len-1].token = token; | |
1489 | } | |
1490 | addTokToList (mcLexBuf_currenttoken, nameKey_NulName, 0, static_cast<mcComment_commentDesc> (NULL), mcLexBuf_getLineNo (), mcLexBuf_getColumnNo (), currentSource); | |
1491 | mcLexBuf_getToken (); | |
1492 | } | |
1493 | } | |
1494 | ||
1495 | ||
1496 | /* | |
1497 | insertTokenAndRewind - inserts a symbol, token, infront of the current token | |
1498 | and then moves the token stream back onto the inserted token. | |
1499 | */ | |
1500 | ||
1501 | extern "C" void mcLexBuf_insertTokenAndRewind (mcReserved_toktype token) | |
1502 | { | |
1503 | if (listOfTokens.tail != NULL) | |
1504 | { | |
1505 | if (listOfTokens.tail->len > 0) | |
1506 | { | |
1507 | listOfTokens.tail->buf.array[listOfTokens.tail->len-1].token = token; | |
1508 | } | |
1509 | addTokToList (mcLexBuf_currenttoken, nameKey_NulName, 0, static_cast<mcComment_commentDesc> (NULL), mcLexBuf_getLineNo (), mcLexBuf_getColumnNo (), currentSource); | |
1510 | mcLexBuf_currenttoken = token; | |
1511 | } | |
1512 | } | |
1513 | ||
1514 | ||
1515 | /* | |
1516 | getPreviousTokenLineNo - returns the line number of the previous token. | |
1517 | */ | |
1518 | ||
1519 | extern "C" unsigned int mcLexBuf_getPreviousTokenLineNo (void) | |
1520 | { | |
1521 | return mcLexBuf_getLineNo (); | |
1522 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
1523 | __builtin_unreachable (); | |
1524 | } | |
1525 | ||
1526 | ||
1527 | /* | |
1528 | getLineNo - returns the current line number where the symbol occurs in | |
1529 | the source file. | |
1530 | */ | |
1531 | ||
1532 | extern "C" unsigned int mcLexBuf_getLineNo (void) | |
1533 | { | |
1534 | if (nextTokNo == 0) | |
1535 | { | |
1536 | return 0; | |
1537 | } | |
1538 | else | |
1539 | { | |
1540 | return mcLexBuf_tokenToLineNo (mcLexBuf_getTokenNo (), 0); | |
1541 | } | |
1542 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
1543 | __builtin_unreachable (); | |
1544 | } | |
1545 | ||
1546 | ||
1547 | /* | |
1548 | getTokenNo - returns the current token number. | |
1549 | */ | |
1550 | ||
1551 | extern "C" unsigned int mcLexBuf_getTokenNo (void) | |
1552 | { | |
1553 | if (nextTokNo == 0) | |
1554 | { | |
1555 | return 0; | |
1556 | } | |
1557 | else | |
1558 | { | |
1559 | return nextTokNo-1; | |
1560 | } | |
1561 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
1562 | __builtin_unreachable (); | |
1563 | } | |
1564 | ||
1565 | ||
1566 | /* | |
1567 | tokenToLineNo - returns the line number of the current file for the | |
1568 | tokenNo. The depth refers to the include depth. | |
1569 | A depth of 0 is the current file, depth of 1 is the file | |
1570 | which included the current file. Zero is returned if the | |
1571 | depth exceeds the file nesting level. | |
1572 | */ | |
1573 | ||
1574 | extern "C" unsigned int mcLexBuf_tokenToLineNo (unsigned int tokenNo, unsigned int depth) | |
1575 | { | |
1576 | mcLexBuf_tokenBucket b; | |
1577 | mcLexBuf_sourceList l; | |
1578 | ||
1579 | b = findtokenBucket (&tokenNo); | |
1580 | if (b == NULL) | |
1581 | { | |
1582 | return 0; | |
1583 | } | |
1584 | else | |
1585 | { | |
1586 | if (depth == 0) | |
1587 | { | |
1588 | return b->buf.array[tokenNo].line; | |
1589 | } | |
1590 | else | |
1591 | { | |
1592 | l = b->buf.array[tokenNo].file->left; | |
1593 | while (depth > 0) | |
1594 | { | |
1595 | l = l->left; | |
1596 | if (l == b->buf.array[tokenNo].file->left) | |
1597 | { | |
1598 | return 0; | |
1599 | } | |
1600 | depth -= 1; | |
1601 | } | |
1602 | return l->line; | |
1603 | } | |
1604 | } | |
1605 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
1606 | __builtin_unreachable (); | |
1607 | } | |
1608 | ||
1609 | ||
1610 | /* | |
1611 | getColumnNo - returns the current column where the symbol occurs in | |
1612 | the source file. | |
1613 | */ | |
1614 | ||
1615 | extern "C" unsigned int mcLexBuf_getColumnNo (void) | |
1616 | { | |
1617 | if (nextTokNo == 0) | |
1618 | { | |
1619 | return 0; | |
1620 | } | |
1621 | else | |
1622 | { | |
1623 | return mcLexBuf_tokenToColumnNo (mcLexBuf_getTokenNo (), 0); | |
1624 | } | |
1625 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
1626 | __builtin_unreachable (); | |
1627 | } | |
1628 | ||
1629 | ||
1630 | /* | |
1631 | tokenToColumnNo - returns the column number of the current file for the | |
1632 | tokenNo. The depth refers to the include depth. | |
1633 | A depth of 0 is the current file, depth of 1 is the file | |
1634 | which included the current file. Zero is returned if the | |
1635 | depth exceeds the file nesting level. | |
1636 | */ | |
1637 | ||
1638 | extern "C" unsigned int mcLexBuf_tokenToColumnNo (unsigned int tokenNo, unsigned int depth) | |
1639 | { | |
1640 | mcLexBuf_tokenBucket b; | |
1641 | mcLexBuf_sourceList l; | |
1642 | ||
1643 | b = findtokenBucket (&tokenNo); | |
1644 | if (b == NULL) | |
1645 | { | |
1646 | return 0; | |
1647 | } | |
1648 | else | |
1649 | { | |
1650 | if (depth == 0) | |
1651 | { | |
1652 | return b->buf.array[tokenNo].col; | |
1653 | } | |
1654 | else | |
1655 | { | |
1656 | l = b->buf.array[tokenNo].file->left; | |
1657 | while (depth > 0) | |
1658 | { | |
1659 | l = l->left; | |
1660 | if (l == b->buf.array[tokenNo].file->left) | |
1661 | { | |
1662 | return 0; | |
1663 | } | |
1664 | depth -= 1; | |
1665 | } | |
1666 | return l->col; | |
1667 | } | |
1668 | } | |
1669 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
1670 | __builtin_unreachable (); | |
1671 | } | |
1672 | ||
1673 | ||
1674 | /* | |
1675 | findFileNameFromToken - returns the complete FileName for the appropriate | |
1676 | source file yields the token number, tokenNo. | |
1677 | The, Depth, indicates the include level: 0..n | |
1678 | Level 0 is the current. NIL is returned if n+1 | |
1679 | is requested. | |
1680 | */ | |
1681 | ||
1682 | extern "C" DynamicStrings_String mcLexBuf_findFileNameFromToken (unsigned int tokenNo, unsigned int depth) | |
1683 | { | |
1684 | mcLexBuf_tokenBucket b; | |
1685 | mcLexBuf_sourceList l; | |
1686 | ||
1687 | b = findtokenBucket (&tokenNo); | |
1688 | if (b == NULL) | |
1689 | { | |
1690 | return static_cast<DynamicStrings_String> (NULL); | |
1691 | } | |
1692 | else | |
1693 | { | |
1694 | l = b->buf.array[tokenNo].file->left; | |
1695 | while (depth > 0) | |
1696 | { | |
1697 | l = l->left; | |
1698 | if (l == b->buf.array[tokenNo].file->left) | |
1699 | { | |
1700 | return static_cast<DynamicStrings_String> (NULL); | |
1701 | } | |
1702 | depth -= 1; | |
1703 | } | |
1704 | return l->name; | |
1705 | } | |
1706 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
1707 | __builtin_unreachable (); | |
1708 | } | |
1709 | ||
1710 | ||
1711 | /* | |
1712 | getFileName - returns a String defining the current file. | |
1713 | */ | |
1714 | ||
1715 | extern "C" DynamicStrings_String mcLexBuf_getFileName (void) | |
1716 | { | |
1717 | return mcLexBuf_findFileNameFromToken (mcLexBuf_getTokenNo (), 0); | |
1718 | /* static analysis guarentees a RETURN statement will be used before here. */ | |
1719 | __builtin_unreachable (); | |
1720 | } | |
1721 | ||
1722 | ||
1723 | /* | |
1724 | addTok - adds a token to the buffer. | |
1725 | */ | |
1726 | ||
1727 | extern "C" void mcLexBuf_addTok (mcReserved_toktype t) | |
1728 | { | |
1729 | if (! ((t == mcReserved_eoftok) && (isLastTokenEof ()))) | |
1730 | { | |
1731 | addTokToList (t, nameKey_NulName, 0, static_cast<mcComment_commentDesc> (NULL), mcflex_getLineNo (), mcflex_getColumnNo (), currentSource); | |
431c0669 | 1732 | currentUsed = true; |
fbd2eda1 GM |
1733 | } |
1734 | } | |
1735 | ||
1736 | ||
1737 | /* | |
1738 | addTokCharStar - adds a token to the buffer and an additional string, s. | |
1739 | A copy of string, s, is made. | |
1740 | */ | |
1741 | ||
1742 | extern "C" void mcLexBuf_addTokCharStar (mcReserved_toktype t, void * s) | |
1743 | { | |
1744 | if ((libc_strlen (s)) > 80) | |
1745 | { | |
1746 | stop (); | |
1747 | } | |
1748 | addTokToList (t, nameKey_makekey (s), 0, static_cast<mcComment_commentDesc> (NULL), mcflex_getLineNo (), mcflex_getColumnNo (), currentSource); | |
431c0669 | 1749 | currentUsed = true; |
fbd2eda1 GM |
1750 | } |
1751 | ||
1752 | ||
1753 | /* | |
1754 | addTokInteger - adds a token and an integer to the buffer. | |
1755 | */ | |
1756 | ||
1757 | extern "C" void mcLexBuf_addTokInteger (mcReserved_toktype t, int i) | |
1758 | { | |
1759 | DynamicStrings_String s; | |
1760 | unsigned int c; | |
1761 | unsigned int l; | |
1762 | ||
1763 | l = mcflex_getLineNo (); | |
1764 | c = mcflex_getColumnNo (); | |
1765 | s = FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "%d", 2)), (const unsigned char *) &i, (sizeof (i)-1)); | |
1766 | addTokToList (t, nameKey_makekey (DynamicStrings_string (s)), i, static_cast<mcComment_commentDesc> (NULL), l, c, currentSource); | |
1767 | s = DynamicStrings_KillString (s); | |
431c0669 | 1768 | currentUsed = true; |
fbd2eda1 GM |
1769 | } |
1770 | ||
1771 | ||
1772 | /* | |
1773 | addTokComment - adds a token to the buffer and a comment descriptor, com. | |
1774 | */ | |
1775 | ||
1776 | extern "C" void mcLexBuf_addTokComment (mcReserved_toktype t, mcComment_commentDesc com) | |
1777 | { | |
1778 | addTokToList (t, nameKey_NulName, 0, com, mcflex_getLineNo (), mcflex_getColumnNo (), currentSource); | |
431c0669 | 1779 | currentUsed = true; |
fbd2eda1 GM |
1780 | } |
1781 | ||
1782 | ||
1783 | /* | |
1784 | setFile - sets the current filename to, filename. | |
1785 | */ | |
1786 | ||
1787 | extern "C" void mcLexBuf_setFile (void * filename) | |
1788 | { | |
1789 | killList (); | |
431c0669 | 1790 | currentUsed = false; |
fbd2eda1 GM |
1791 | currentSource = newList (); |
1792 | addTo (newElement (filename)); | |
1793 | } | |
1794 | ||
1795 | ||
1796 | /* | |
1797 | pushFile - indicates that, filename, has just been included. | |
1798 | */ | |
1799 | ||
1800 | extern "C" void mcLexBuf_pushFile (void * filename) | |
1801 | { | |
1802 | mcLexBuf_sourceList l; | |
1803 | ||
1804 | checkIfNeedToDuplicate (); | |
1805 | addTo (newElement (filename)); | |
1806 | if (Debugging) | |
1807 | { | |
1808 | if (currentSource->right != currentSource) | |
1809 | { | |
1810 | l = currentSource; | |
1811 | do { | |
1812 | mcPrintf_printf3 ((const char *) "name = %s, line = %d, col = %d\\n", 32, (const unsigned char *) &l->name, (sizeof (l->name)-1), (const unsigned char *) &l->line, (sizeof (l->line)-1), (const unsigned char *) &l->col, (sizeof (l->col)-1)); | |
1813 | l = l->right; | |
1814 | } while (! (l == currentSource)); | |
1815 | } | |
1816 | } | |
1817 | } | |
1818 | ||
1819 | ||
1820 | /* | |
1821 | popFile - indicates that we are returning to, filename, having finished | |
1822 | an include. | |
1823 | */ | |
1824 | ||
1825 | extern "C" void mcLexBuf_popFile (void * filename) | |
1826 | { | |
1827 | mcLexBuf_sourceList l; | |
1828 | ||
1829 | checkIfNeedToDuplicate (); | |
1830 | if ((currentSource != NULL) && (currentSource->left != currentSource)) | |
1831 | { | |
1832 | /* avoid dangling else. */ | |
1833 | l = currentSource->left; /* last element */ | |
1834 | subFrom (l); /* last element */ | |
1835 | Storage_DEALLOCATE ((void **) &l, sizeof (mcLexBuf__T1)); | |
1836 | if ((currentSource->left != currentSource) && (! (DynamicStrings_Equal (currentSource->name, DynamicStrings_Mark (DynamicStrings_InitStringCharStar (filename)))))) | |
1837 | {} /* empty. */ | |
1838 | /* mismatch in source file names after preprocessing files */ | |
1839 | } | |
1840 | /* source file list is empty, cannot pop an include.. */ | |
1841 | } | |
1842 | ||
1843 | extern "C" void _M2_mcLexBuf_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) | |
1844 | { | |
1845 | init (); | |
1846 | } | |
1847 | ||
1848 | extern "C" void _M2_mcLexBuf_fini (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) | |
1849 | { | |
1850 | } |