| /* do not edit automatically generated by mc from mcLexBuf. */ |
| /* mcLexBuf.mod provides a buffer for the all the tokens created by m2.lex. |
| |
| Copyright (C) 2015-2025 Free Software Foundation, Inc. |
| Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>. |
| |
| This file is part of GNU Modula-2. |
| |
| GNU Modula-2 is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3, or (at your option) |
| any later version. |
| |
| GNU Modula-2 is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GNU Modula-2; see the file COPYING3. If not see |
| <http://www.gnu.org/licenses/>. */ |
| |
| #include "config.h" |
| #include "system.h" |
| #include <stdbool.h> |
| # if !defined (PROC_D) |
| # define PROC_D |
| typedef void (*PROC_t) (void); |
| typedef struct { PROC_t proc; } PROC; |
| # endif |
| |
| # if !defined (TRUE) |
| # define TRUE (1==1) |
| # endif |
| |
| # if !defined (FALSE) |
| # define FALSE (1==0) |
| # endif |
| |
| # include "GStorage.h" |
| #if defined(__cplusplus) |
| # undef NULL |
| # define NULL 0 |
| #endif |
| #define _mcLexBuf_C |
| |
| #include "GmcLexBuf.h" |
| # include "Gmcflex.h" |
| # include "Glibc.h" |
| # include "GSYSTEM.h" |
| # include "GStorage.h" |
| # include "GDynamicStrings.h" |
| # include "GFormatStrings.h" |
| # include "GnameKey.h" |
| # include "GmcReserved.h" |
| # include "GmcComment.h" |
| # include "GmcPrintf.h" |
| # include "GmcDebug.h" |
| # include "GM2RTS.h" |
| |
| # define MaxBucketSize 100 |
| # define Debugging false |
| typedef struct mcLexBuf_tokenDesc_r mcLexBuf_tokenDesc; |
| |
| typedef struct mcLexBuf_listDesc_r mcLexBuf_listDesc; |
| |
| typedef struct mcLexBuf__T1_r mcLexBuf__T1; |
| |
| typedef mcLexBuf__T1 *mcLexBuf_sourceList; |
| |
| typedef struct mcLexBuf__T2_r mcLexBuf__T2; |
| |
| typedef mcLexBuf__T2 *mcLexBuf_tokenBucket; |
| |
| typedef struct mcLexBuf__T3_a mcLexBuf__T3; |
| |
| struct mcLexBuf_tokenDesc_r { |
| mcReserved_toktype token; |
| nameKey_Name str; |
| int int_; |
| mcComment_commentDesc com; |
| unsigned int line; |
| unsigned int col; |
| mcLexBuf_sourceList file; |
| }; |
| |
| struct mcLexBuf_listDesc_r { |
| mcLexBuf_tokenBucket head; |
| mcLexBuf_tokenBucket tail; |
| unsigned int lastBucketOffset; |
| }; |
| |
| struct mcLexBuf__T1_r { |
| mcLexBuf_sourceList left; |
| mcLexBuf_sourceList right; |
| DynamicStrings_String name; |
| unsigned int line; |
| unsigned int col; |
| }; |
| |
| struct mcLexBuf__T3_a { mcLexBuf_tokenDesc array[MaxBucketSize+1]; }; |
| struct mcLexBuf__T2_r { |
| mcLexBuf__T3 buf; |
| unsigned int len; |
| mcLexBuf_tokenBucket next; |
| }; |
| |
| static mcComment_commentDesc procedureComment; |
| static mcComment_commentDesc bodyComment; |
| static mcComment_commentDesc afterComment; |
| static mcLexBuf_sourceList currentSource; |
| static bool useBufferedTokens; |
| static bool currentUsed; |
| static mcLexBuf_listDesc listOfTokens; |
| static unsigned int nextTokNo; |
| |
| /* |
| getProcedureComment - returns the procedure comment if it exists, |
| or NIL otherwise. |
| */ |
| |
| extern "C" mcComment_commentDesc mcLexBuf_getProcedureComment (void); |
| |
| /* |
| getBodyComment - returns the body comment if it exists, |
| or NIL otherwise. The body comment is |
| removed if found. |
| */ |
| |
| extern "C" mcComment_commentDesc mcLexBuf_getBodyComment (void); |
| |
| /* |
| getAfterComment - returns the after comment if it exists, |
| or NIL otherwise. The after comment is |
| removed if found. |
| */ |
| |
| extern "C" mcComment_commentDesc mcLexBuf_getAfterComment (void); |
| |
| /* |
| openSource - attempts to open the source file, s. |
| The success of the operation is returned. |
| */ |
| |
| extern "C" bool mcLexBuf_openSource (DynamicStrings_String s); |
| |
| /* |
| closeSource - closes the current open file. |
| */ |
| |
| extern "C" void mcLexBuf_closeSource (void); |
| |
| /* |
| reInitialize - re-initialize the all the data structures. |
| */ |
| |
| extern "C" void mcLexBuf_reInitialize (void); |
| |
| /* |
| resetForNewPass - reset the buffer pointers to the beginning ready for |
| a new pass |
| */ |
| |
| extern "C" void mcLexBuf_resetForNewPass (void); |
| |
| /* |
| getToken - gets the next token into currenttoken. |
| */ |
| |
| extern "C" void mcLexBuf_getToken (void); |
| |
| /* |
| insertToken - inserts a symbol, token, infront of the current token |
| ready for the next pass. |
| */ |
| |
| extern "C" void mcLexBuf_insertToken (mcReserved_toktype token); |
| |
| /* |
| insertTokenAndRewind - inserts a symbol, token, infront of the current token |
| and then moves the token stream back onto the inserted token. |
| */ |
| |
| extern "C" void mcLexBuf_insertTokenAndRewind (mcReserved_toktype token); |
| |
| /* |
| getPreviousTokenLineNo - returns the line number of the previous token. |
| */ |
| |
| extern "C" unsigned int mcLexBuf_getPreviousTokenLineNo (void); |
| |
| /* |
| getLineNo - returns the current line number where the symbol occurs in |
| the source file. |
| */ |
| |
| extern "C" unsigned int mcLexBuf_getLineNo (void); |
| |
| /* |
| getTokenNo - returns the current token number. |
| */ |
| |
| extern "C" unsigned int mcLexBuf_getTokenNo (void); |
| |
| /* |
| tokenToLineNo - returns the line number of the current file for the |
| tokenNo. The depth refers to the include depth. |
| A depth of 0 is the current file, depth of 1 is the file |
| which included the current file. Zero is returned if the |
| depth exceeds the file nesting level. |
| */ |
| |
| extern "C" unsigned int mcLexBuf_tokenToLineNo (unsigned int tokenNo, unsigned int depth); |
| |
| /* |
| getColumnNo - returns the current column where the symbol occurs in |
| the source file. |
| */ |
| |
| extern "C" unsigned int mcLexBuf_getColumnNo (void); |
| |
| /* |
| tokenToColumnNo - returns the column number of the current file for the |
| tokenNo. The depth refers to the include depth. |
| A depth of 0 is the current file, depth of 1 is the file |
| which included the current file. Zero is returned if the |
| depth exceeds the file nesting level. |
| */ |
| |
| extern "C" unsigned int mcLexBuf_tokenToColumnNo (unsigned int tokenNo, unsigned int depth); |
| |
| /* |
| findFileNameFromToken - returns the complete FileName for the appropriate |
| source file yields the token number, tokenNo. |
| The, Depth, indicates the include level: 0..n |
| Level 0 is the current. NIL is returned if n+1 |
| is requested. |
| */ |
| |
| extern "C" DynamicStrings_String mcLexBuf_findFileNameFromToken (unsigned int tokenNo, unsigned int depth); |
| |
| /* |
| getFileName - returns a String defining the current file. |
| */ |
| |
| extern "C" DynamicStrings_String mcLexBuf_getFileName (void); |
| |
| /* |
| addTok - adds a token to the buffer. |
| */ |
| |
| extern "C" void mcLexBuf_addTok (mcReserved_toktype t); |
| |
| /* |
| addTokCharStar - adds a token to the buffer and an additional string, s. |
| A copy of string, s, is made. |
| */ |
| |
| extern "C" void mcLexBuf_addTokCharStar (mcReserved_toktype t, void * s); |
| |
| /* |
| addTokInteger - adds a token and an integer to the buffer. |
| */ |
| |
| extern "C" void mcLexBuf_addTokInteger (mcReserved_toktype t, int i); |
| |
| /* |
| addTokComment - adds a token to the buffer and a comment descriptor, com. |
| */ |
| |
| extern "C" void mcLexBuf_addTokComment (mcReserved_toktype t, mcComment_commentDesc com); |
| |
| /* |
| setFile - sets the current filename to, filename. |
| */ |
| |
| extern "C" void mcLexBuf_setFile (void * filename); |
| |
| /* |
| pushFile - indicates that, filename, has just been included. |
| */ |
| |
| extern "C" void mcLexBuf_pushFile (void * filename); |
| |
| /* |
| popFile - indicates that we are returning to, filename, having finished |
| an include. |
| */ |
| |
| extern "C" void mcLexBuf_popFile (void * filename); |
| |
| /* |
| debugLex - display the last, n, tokens. |
| */ |
| |
| static void debugLex (unsigned int n); |
| |
| /* |
| seekTo - |
| */ |
| |
| static void seekTo (unsigned int t); |
| |
| /* |
| peeptokenBucket - |
| */ |
| |
| static mcLexBuf_tokenBucket peeptokenBucket (unsigned int *t); |
| |
| /* |
| peepAfterComment - peeps ahead looking for an after statement comment. It stops at an END token |
| or if the line number changes. |
| */ |
| |
| static void peepAfterComment (void); |
| |
| /* |
| init - initializes the token list and source list. |
| */ |
| |
| static void init (void); |
| |
| /* |
| addTo - adds a new element to the end of sourceList, currentSource. |
| */ |
| |
| static void addTo (mcLexBuf_sourceList l); |
| |
| /* |
| subFrom - subtracts, l, from the source list. |
| */ |
| |
| static void subFrom (mcLexBuf_sourceList l); |
| |
| /* |
| newElement - returns a new sourceList |
| */ |
| |
| static mcLexBuf_sourceList newElement (void * s); |
| |
| /* |
| newList - initializes an empty list with the classic dummy header element. |
| */ |
| |
| static mcLexBuf_sourceList newList (void); |
| |
| /* |
| checkIfNeedToDuplicate - checks to see whether the currentSource has |
| been used, if it has then duplicate the list. |
| */ |
| |
| static void checkIfNeedToDuplicate (void); |
| |
| /* |
| killList - kills the sourceList providing that it has not been used. |
| */ |
| |
| static void killList (void); |
| |
| /* |
| displayToken - |
| */ |
| |
| static void displayToken (mcReserved_toktype t); |
| |
| /* |
| updateFromBucket - updates the global variables: currenttoken, |
| currentstring, currentcolumn and currentinteger |
| from tokenBucket, b, and, offset. |
| */ |
| |
| static void updateFromBucket (mcLexBuf_tokenBucket b, unsigned int offset); |
| |
| /* |
| doGetToken - fetch the next token into currenttoken. |
| */ |
| |
| static void doGetToken (void); |
| |
| /* |
| syncOpenWithBuffer - synchronise the buffer with the start of a file. |
| Skips all the tokens to do with the previous file. |
| */ |
| |
| static void syncOpenWithBuffer (void); |
| |
| /* |
| findtokenBucket - returns the tokenBucket corresponding to the tokenNo. |
| */ |
| |
| static mcLexBuf_tokenBucket findtokenBucket (unsigned int *tokenNo); |
| |
| /* |
| getFileName - returns a String defining the current file. |
| */ |
| |
| static void stop (void); |
| |
| /* |
| addTokToList - adds a token to a dynamic list. |
| */ |
| |
| static void addTokToList (mcReserved_toktype t, nameKey_Name n, int i, mcComment_commentDesc comment, unsigned int l, unsigned int c, mcLexBuf_sourceList f); |
| |
| /* |
| isLastTokenEof - returns TRUE if the last token was an eoftok |
| */ |
| |
| static bool isLastTokenEof (void); |
| |
| |
| /* |
| debugLex - display the last, n, tokens. |
| */ |
| |
| static void debugLex (unsigned int n) |
| { |
| unsigned int c; |
| unsigned int i; |
| unsigned int o; |
| unsigned int t; |
| mcLexBuf_tokenBucket b; |
| |
| if (nextTokNo > n) |
| { |
| o = nextTokNo-n; |
| } |
| else |
| { |
| o = 0; |
| } |
| i = 0; |
| do { |
| t = o+i; |
| if (nextTokNo == t) |
| { |
| mcPrintf_printf0 ((const char *) "nextTokNo ", 10); |
| } |
| b = findtokenBucket (&t); |
| if (b == NULL) |
| { |
| t = o+i; |
| mcPrintf_printf1 ((const char *) "end of buf (%d is further ahead than the buffer contents)\\n", 60, (const unsigned char *) &t, (sizeof (t)-1)); |
| } |
| else |
| { |
| c = o+i; |
| mcPrintf_printf2 ((const char *) "entry %d %d ", 13, (const unsigned char *) &c, (sizeof (c)-1), (const unsigned char *) &t, (sizeof (t)-1)); |
| displayToken (b->buf.array[t].token); |
| mcPrintf_printf0 ((const char *) "\\n", 2); |
| i += 1; |
| } |
| } while (! (b == NULL)); |
| } |
| |
| |
| /* |
| seekTo - |
| */ |
| |
| static void seekTo (unsigned int t) |
| { |
| mcLexBuf_tokenBucket b; |
| |
| nextTokNo = t; |
| if (t > 0) |
| { |
| t -= 1; |
| b = findtokenBucket (&t); |
| if (b == NULL) |
| { |
| updateFromBucket (b, t); |
| } |
| } |
| } |
| |
| |
| /* |
| peeptokenBucket - |
| */ |
| |
| static mcLexBuf_tokenBucket peeptokenBucket (unsigned int *t) |
| { |
| mcReserved_toktype ct; |
| unsigned int old; |
| unsigned int n; |
| mcLexBuf_tokenBucket b; |
| mcLexBuf_tokenBucket c; |
| |
| ct = mcLexBuf_currenttoken; |
| if (Debugging) |
| { |
| debugLex (5); |
| } |
| old = mcLexBuf_getTokenNo (); |
| do { |
| n = (*t); |
| b = findtokenBucket (&n); |
| if (b == NULL) |
| { |
| doGetToken (); |
| n = (*t); |
| b = findtokenBucket (&n); |
| if ((b == NULL) || (mcLexBuf_currenttoken == mcReserved_eoftok)) |
| { |
| /* bailing out. */ |
| nextTokNo = old+1; |
| b = findtokenBucket (&old); |
| updateFromBucket (b, old); |
| return NULL; |
| } |
| } |
| } while (! ((b != NULL) || (mcLexBuf_currenttoken == mcReserved_eoftok))); |
| (*t) = n; |
| nextTokNo = old+1; |
| if (Debugging) |
| { |
| mcPrintf_printf2 ((const char *) "nextTokNo = %d, old = %d\\n", 26, (const unsigned char *) &nextTokNo, (sizeof (nextTokNo)-1), (const unsigned char *) &old, (sizeof (old)-1)); |
| } |
| b = findtokenBucket (&old); |
| if (Debugging) |
| { |
| mcPrintf_printf1 ((const char *) " adjusted old = %d\\n", 21, (const unsigned char *) &old, (sizeof (old)-1)); |
| } |
| if (b != NULL) |
| { |
| updateFromBucket (b, old); |
| } |
| if (Debugging) |
| { |
| debugLex (5); |
| } |
| mcDebug_assert (ct == mcLexBuf_currenttoken); |
| return b; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| peepAfterComment - peeps ahead looking for an after statement comment. It stops at an END token |
| or if the line number changes. |
| */ |
| |
| static void peepAfterComment (void) |
| { |
| unsigned int oldTokNo; |
| unsigned int t; |
| unsigned int peep; |
| unsigned int cno; |
| unsigned int nextline; |
| unsigned int curline; |
| mcLexBuf_tokenBucket b; |
| bool finished; |
| |
| oldTokNo = nextTokNo; |
| cno = mcLexBuf_getTokenNo (); |
| curline = mcLexBuf_tokenToLineNo (cno, 0); |
| nextline = curline; |
| peep = 0; |
| finished = false; |
| do { |
| t = cno+peep; |
| b = peeptokenBucket (&t); |
| if ((b == NULL) || (mcLexBuf_currenttoken == mcReserved_eoftok)) |
| { |
| finished = true; |
| } |
| else |
| { |
| nextline = b->buf.array[t].line; |
| if (nextline == curline) |
| { |
| switch (b->buf.array[t].token) |
| { |
| case mcReserved_eoftok: |
| case mcReserved_endtok: |
| finished = true; |
| break; |
| |
| case mcReserved_commenttok: |
| if (mcComment_isAfterComment (b->buf.array[t].com)) |
| { |
| afterComment = b->buf.array[t].com; |
| } |
| break; |
| |
| |
| default: |
| break; |
| } |
| } |
| else |
| { |
| finished = true; |
| } |
| } |
| peep += 1; |
| } while (! (finished)); |
| seekTo (oldTokNo); |
| } |
| |
| |
| /* |
| init - initializes the token list and source list. |
| */ |
| |
| static void init (void) |
| { |
| mcLexBuf_currenttoken = mcReserved_eoftok; |
| nextTokNo = 0; |
| currentSource = NULL; |
| listOfTokens.head = NULL; |
| listOfTokens.tail = NULL; |
| useBufferedTokens = false; |
| procedureComment = static_cast<mcComment_commentDesc> (NULL); |
| bodyComment = static_cast<mcComment_commentDesc> (NULL); |
| afterComment = static_cast<mcComment_commentDesc> (NULL); |
| mcLexBuf_lastcomment = static_cast<mcComment_commentDesc> (NULL); |
| } |
| |
| |
| /* |
| addTo - adds a new element to the end of sourceList, currentSource. |
| */ |
| |
| static void addTo (mcLexBuf_sourceList l) |
| { |
| l->right = currentSource; |
| l->left = currentSource->left; |
| currentSource->left->right = l; |
| currentSource->left = l; |
| l->left->line = mcflex_getLineNo (); |
| l->left->col = mcflex_getColumnNo (); |
| } |
| |
| |
| /* |
| subFrom - subtracts, l, from the source list. |
| */ |
| |
| static void subFrom (mcLexBuf_sourceList l) |
| { |
| l->left->right = l->right; |
| l->right->left = l->left; |
| } |
| |
| |
| /* |
| newElement - returns a new sourceList |
| */ |
| |
| static mcLexBuf_sourceList newElement (void * s) |
| { |
| mcLexBuf_sourceList l; |
| |
| Storage_ALLOCATE ((void **) &l, sizeof (mcLexBuf__T1)); |
| if (l == NULL) |
| { |
| M2RTS_HALT (-1); |
| __builtin_unreachable (); |
| } |
| else |
| { |
| l->name = DynamicStrings_InitStringCharStar (s); |
| l->left = NULL; |
| l->right = NULL; |
| } |
| return l; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| newList - initializes an empty list with the classic dummy header element. |
| */ |
| |
| static mcLexBuf_sourceList newList (void) |
| { |
| mcLexBuf_sourceList l; |
| |
| Storage_ALLOCATE ((void **) &l, sizeof (mcLexBuf__T1)); |
| l->left = l; |
| l->right = l; |
| l->name = static_cast<DynamicStrings_String> (NULL); |
| return l; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| checkIfNeedToDuplicate - checks to see whether the currentSource has |
| been used, if it has then duplicate the list. |
| */ |
| |
| static void checkIfNeedToDuplicate (void) |
| { |
| mcLexBuf_sourceList l; |
| mcLexBuf_sourceList h; |
| |
| if (currentUsed) |
| { |
| l = currentSource->right; |
| h = currentSource; |
| currentSource = newList (); |
| while (l != h) |
| { |
| addTo (newElement (reinterpret_cast <void *> (l->name))); |
| l = l->right; |
| } |
| } |
| } |
| |
| |
| /* |
| killList - kills the sourceList providing that it has not been used. |
| */ |
| |
| static void killList (void) |
| { |
| mcLexBuf_sourceList l; |
| mcLexBuf_sourceList k; |
| |
| if (! currentUsed && (currentSource != NULL)) |
| { |
| l = currentSource; |
| do { |
| k = l; |
| l = l->right; |
| Storage_DEALLOCATE ((void **) &k, sizeof (mcLexBuf__T1)); |
| } while (! (l == currentSource)); |
| } |
| } |
| |
| |
| /* |
| displayToken - |
| */ |
| |
| static void displayToken (mcReserved_toktype t) |
| { |
| switch (t) |
| { |
| case mcReserved_eoftok: |
| mcPrintf_printf0 ((const char *) "eoftok\\n", 8); |
| break; |
| |
| case mcReserved_plustok: |
| mcPrintf_printf0 ((const char *) "plustok\\n", 9); |
| break; |
| |
| case mcReserved_minustok: |
| mcPrintf_printf0 ((const char *) "minustok\\n", 10); |
| break; |
| |
| case mcReserved_timestok: |
| mcPrintf_printf0 ((const char *) "timestok\\n", 10); |
| break; |
| |
| case mcReserved_dividetok: |
| mcPrintf_printf0 ((const char *) "dividetok\\n", 11); |
| break; |
| |
| case mcReserved_becomestok: |
| mcPrintf_printf0 ((const char *) "becomestok\\n", 12); |
| break; |
| |
| case mcReserved_ambersandtok: |
| mcPrintf_printf0 ((const char *) "ambersandtok\\n", 14); |
| break; |
| |
| case mcReserved_periodtok: |
| mcPrintf_printf0 ((const char *) "periodtok\\n", 11); |
| break; |
| |
| case mcReserved_commatok: |
| mcPrintf_printf0 ((const char *) "commatok\\n", 10); |
| break; |
| |
| case mcReserved_commenttok: |
| mcPrintf_printf0 ((const char *) "commenttok\\n", 12); |
| break; |
| |
| case mcReserved_semicolontok: |
| mcPrintf_printf0 ((const char *) "semicolontok\\n", 14); |
| break; |
| |
| case mcReserved_lparatok: |
| mcPrintf_printf0 ((const char *) "lparatok\\n", 10); |
| break; |
| |
| case mcReserved_rparatok: |
| mcPrintf_printf0 ((const char *) "rparatok\\n", 10); |
| break; |
| |
| case mcReserved_lsbratok: |
| mcPrintf_printf0 ((const char *) "lsbratok\\n", 10); |
| break; |
| |
| case mcReserved_rsbratok: |
| mcPrintf_printf0 ((const char *) "rsbratok\\n", 10); |
| break; |
| |
| case mcReserved_lcbratok: |
| mcPrintf_printf0 ((const char *) "lcbratok\\n", 10); |
| break; |
| |
| case mcReserved_rcbratok: |
| mcPrintf_printf0 ((const char *) "rcbratok\\n", 10); |
| break; |
| |
| case mcReserved_uparrowtok: |
| mcPrintf_printf0 ((const char *) "uparrowtok\\n", 12); |
| break; |
| |
| case mcReserved_singlequotetok: |
| mcPrintf_printf0 ((const char *) "singlequotetok\\n", 16); |
| break; |
| |
| case mcReserved_equaltok: |
| mcPrintf_printf0 ((const char *) "equaltok\\n", 10); |
| break; |
| |
| case mcReserved_hashtok: |
| mcPrintf_printf0 ((const char *) "hashtok\\n", 9); |
| break; |
| |
| case mcReserved_lesstok: |
| mcPrintf_printf0 ((const char *) "lesstok\\n", 9); |
| break; |
| |
| case mcReserved_greatertok: |
| mcPrintf_printf0 ((const char *) "greatertok\\n", 12); |
| break; |
| |
| case mcReserved_lessgreatertok: |
| mcPrintf_printf0 ((const char *) "lessgreatertok\\n", 16); |
| break; |
| |
| case mcReserved_lessequaltok: |
| mcPrintf_printf0 ((const char *) "lessequaltok\\n", 14); |
| break; |
| |
| case mcReserved_greaterequaltok: |
| mcPrintf_printf0 ((const char *) "greaterequaltok\\n", 17); |
| break; |
| |
| case mcReserved_periodperiodtok: |
| mcPrintf_printf0 ((const char *) "periodperiodtok\\n", 17); |
| break; |
| |
| case mcReserved_colontok: |
| mcPrintf_printf0 ((const char *) "colontok\\n", 10); |
| break; |
| |
| case mcReserved_doublequotestok: |
| mcPrintf_printf0 ((const char *) "doublequotestok\\n", 17); |
| break; |
| |
| case mcReserved_bartok: |
| mcPrintf_printf0 ((const char *) "bartok\\n", 8); |
| break; |
| |
| case mcReserved_andtok: |
| mcPrintf_printf0 ((const char *) "andtok\\n", 8); |
| break; |
| |
| case mcReserved_arraytok: |
| mcPrintf_printf0 ((const char *) "arraytok\\n", 10); |
| break; |
| |
| case mcReserved_begintok: |
| mcPrintf_printf0 ((const char *) "begintok\\n", 10); |
| break; |
| |
| case mcReserved_bytok: |
| mcPrintf_printf0 ((const char *) "bytok\\n", 7); |
| break; |
| |
| case mcReserved_casetok: |
| mcPrintf_printf0 ((const char *) "casetok\\n", 9); |
| break; |
| |
| case mcReserved_consttok: |
| mcPrintf_printf0 ((const char *) "consttok\\n", 10); |
| break; |
| |
| case mcReserved_definitiontok: |
| mcPrintf_printf0 ((const char *) "definitiontok\\n", 15); |
| break; |
| |
| case mcReserved_divtok: |
| mcPrintf_printf0 ((const char *) "divtok\\n", 8); |
| break; |
| |
| case mcReserved_dotok: |
| mcPrintf_printf0 ((const char *) "dotok\\n", 7); |
| break; |
| |
| case mcReserved_elsetok: |
| mcPrintf_printf0 ((const char *) "elsetok\\n", 9); |
| break; |
| |
| case mcReserved_elsiftok: |
| mcPrintf_printf0 ((const char *) "elsiftok\\n", 10); |
| break; |
| |
| case mcReserved_endtok: |
| mcPrintf_printf0 ((const char *) "endtok\\n", 8); |
| break; |
| |
| case mcReserved_exittok: |
| mcPrintf_printf0 ((const char *) "exittok\\n", 9); |
| break; |
| |
| case mcReserved_exporttok: |
| mcPrintf_printf0 ((const char *) "exporttok\\n", 11); |
| break; |
| |
| case mcReserved_fortok: |
| mcPrintf_printf0 ((const char *) "fortok\\n", 8); |
| break; |
| |
| case mcReserved_fromtok: |
| mcPrintf_printf0 ((const char *) "fromtok\\n", 9); |
| break; |
| |
| case mcReserved_iftok: |
| mcPrintf_printf0 ((const char *) "iftok\\n", 7); |
| break; |
| |
| case mcReserved_implementationtok: |
| mcPrintf_printf0 ((const char *) "implementationtok\\n", 19); |
| break; |
| |
| case mcReserved_importtok: |
| mcPrintf_printf0 ((const char *) "importtok\\n", 11); |
| break; |
| |
| case mcReserved_intok: |
| mcPrintf_printf0 ((const char *) "intok\\n", 7); |
| break; |
| |
| case mcReserved_looptok: |
| mcPrintf_printf0 ((const char *) "looptok\\n", 9); |
| break; |
| |
| case mcReserved_modtok: |
| mcPrintf_printf0 ((const char *) "modtok\\n", 8); |
| break; |
| |
| case mcReserved_moduletok: |
| mcPrintf_printf0 ((const char *) "moduletok\\n", 11); |
| break; |
| |
| case mcReserved_nottok: |
| mcPrintf_printf0 ((const char *) "nottok\\n", 8); |
| break; |
| |
| case mcReserved_oftok: |
| mcPrintf_printf0 ((const char *) "oftok\\n", 7); |
| break; |
| |
| case mcReserved_ortok: |
| mcPrintf_printf0 ((const char *) "ortok\\n", 7); |
| break; |
| |
| case mcReserved_pointertok: |
| mcPrintf_printf0 ((const char *) "pointertok\\n", 12); |
| break; |
| |
| case mcReserved_proceduretok: |
| mcPrintf_printf0 ((const char *) "proceduretok\\n", 14); |
| break; |
| |
| case mcReserved_qualifiedtok: |
| mcPrintf_printf0 ((const char *) "qualifiedtok\\n", 14); |
| break; |
| |
| case mcReserved_unqualifiedtok: |
| mcPrintf_printf0 ((const char *) "unqualifiedtok\\n", 16); |
| break; |
| |
| case mcReserved_recordtok: |
| mcPrintf_printf0 ((const char *) "recordtok\\n", 11); |
| break; |
| |
| case mcReserved_repeattok: |
| mcPrintf_printf0 ((const char *) "repeattok\\n", 11); |
| break; |
| |
| case mcReserved_returntok: |
| mcPrintf_printf0 ((const char *) "returntok\\n", 11); |
| break; |
| |
| case mcReserved_settok: |
| mcPrintf_printf0 ((const char *) "settok\\n", 8); |
| break; |
| |
| case mcReserved_thentok: |
| mcPrintf_printf0 ((const char *) "thentok\\n", 9); |
| break; |
| |
| case mcReserved_totok: |
| mcPrintf_printf0 ((const char *) "totok\\n", 7); |
| break; |
| |
| case mcReserved_typetok: |
| mcPrintf_printf0 ((const char *) "typetok\\n", 9); |
| break; |
| |
| case mcReserved_untiltok: |
| mcPrintf_printf0 ((const char *) "untiltok\\n", 10); |
| break; |
| |
| case mcReserved_vartok: |
| mcPrintf_printf0 ((const char *) "vartok\\n", 8); |
| break; |
| |
| case mcReserved_whiletok: |
| mcPrintf_printf0 ((const char *) "whiletok\\n", 10); |
| break; |
| |
| case mcReserved_withtok: |
| mcPrintf_printf0 ((const char *) "withtok\\n", 9); |
| break; |
| |
| case mcReserved_asmtok: |
| mcPrintf_printf0 ((const char *) "asmtok\\n", 8); |
| break; |
| |
| case mcReserved_volatiletok: |
| mcPrintf_printf0 ((const char *) "volatiletok\\n", 13); |
| break; |
| |
| case mcReserved_periodperiodperiodtok: |
| mcPrintf_printf0 ((const char *) "periodperiodperiodtok\\n", 23); |
| break; |
| |
| case mcReserved_datetok: |
| mcPrintf_printf0 ((const char *) "datetok\\n", 9); |
| break; |
| |
| case mcReserved_linetok: |
| mcPrintf_printf0 ((const char *) "linetok\\n", 9); |
| break; |
| |
| case mcReserved_filetok: |
| mcPrintf_printf0 ((const char *) "filetok\\n", 9); |
| break; |
| |
| case mcReserved_integertok: |
| mcPrintf_printf0 ((const char *) "integertok\\n", 12); |
| break; |
| |
| case mcReserved_identtok: |
| mcPrintf_printf0 ((const char *) "identtok\\n", 10); |
| break; |
| |
| case mcReserved_realtok: |
| mcPrintf_printf0 ((const char *) "realtok\\n", 9); |
| break; |
| |
| case mcReserved_stringtok: |
| mcPrintf_printf0 ((const char *) "stringtok\\n", 11); |
| break; |
| |
| |
| default: |
| mcPrintf_printf0 ((const char *) "unknown tok (--fixme--)\\n", 25); |
| break; |
| } |
| } |
| |
| |
| /* |
| updateFromBucket - updates the global variables: currenttoken, |
| currentstring, currentcolumn and currentinteger |
| from tokenBucket, b, and, offset. |
| */ |
| |
| static void updateFromBucket (mcLexBuf_tokenBucket b, unsigned int offset) |
| { |
| mcLexBuf_currenttoken = b->buf.array[offset].token; |
| mcLexBuf_currentstring = nameKey_keyToCharStar (b->buf.array[offset].str); |
| mcLexBuf_currentcolumn = b->buf.array[offset].col; |
| mcLexBuf_currentinteger = b->buf.array[offset].int_; |
| mcLexBuf_currentcomment = b->buf.array[offset].com; |
| if (mcLexBuf_currentcomment != NULL) |
| { |
| mcLexBuf_lastcomment = mcLexBuf_currentcomment; |
| } |
| if (Debugging) |
| { |
| 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)); |
| } |
| } |
| |
| |
| /* |
| doGetToken - fetch the next token into currenttoken. |
| */ |
| |
| static void doGetToken (void) |
| { |
| void * a; |
| unsigned int t; |
| mcLexBuf_tokenBucket b; |
| |
| if (useBufferedTokens) |
| { |
| t = nextTokNo; |
| b = findtokenBucket (&t); |
| updateFromBucket (b, t); |
| } |
| else |
| { |
| if (listOfTokens.tail == NULL) |
| { |
| a = mcflex_getToken (); |
| if (listOfTokens.tail == NULL) |
| { |
| M2RTS_HALT (-1); |
| __builtin_unreachable (); |
| } |
| } |
| if (nextTokNo >= listOfTokens.lastBucketOffset) |
| { |
| /* nextTokNo is in the last bucket or needs to be read. */ |
| if ((nextTokNo-listOfTokens.lastBucketOffset) < listOfTokens.tail->len) |
| { |
| if (Debugging) |
| { |
| mcPrintf_printf0 ((const char *) "fetching token from buffer (updateFromBucket)\\n", 47); |
| } |
| updateFromBucket (listOfTokens.tail, nextTokNo-listOfTokens.lastBucketOffset); |
| } |
| else |
| { |
| if (Debugging) |
| { |
| mcPrintf_printf0 ((const char *) "calling flex to place token into buffer\\n", 41); |
| } |
| /* call the lexical phase to place a new token into the last bucket. */ |
| a = mcflex_getToken (); |
| mcLexBuf_getToken (); /* and call ourselves again to collect the token from bucket. */ |
| return; /* and call ourselves again to collect the token from bucket. */ |
| } |
| } |
| else |
| { |
| if (Debugging) |
| { |
| mcPrintf_printf0 ((const char *) "fetching token from buffer\\n", 28); |
| } |
| t = nextTokNo; |
| b = findtokenBucket (&t); |
| updateFromBucket (b, t); |
| } |
| } |
| if (Debugging) |
| { |
| displayToken (mcLexBuf_currenttoken); |
| } |
| nextTokNo += 1; |
| } |
| |
| |
| /* |
| syncOpenWithBuffer - synchronise the buffer with the start of a file. |
| Skips all the tokens to do with the previous file. |
| */ |
| |
| static void syncOpenWithBuffer (void) |
| { |
| if (listOfTokens.tail != NULL) |
| { |
| nextTokNo = listOfTokens.lastBucketOffset+listOfTokens.tail->len; |
| } |
| } |
| |
| |
| /* |
| findtokenBucket - returns the tokenBucket corresponding to the tokenNo. |
| */ |
| |
| static mcLexBuf_tokenBucket findtokenBucket (unsigned int *tokenNo) |
| { |
| mcLexBuf_tokenBucket b; |
| |
| b = listOfTokens.head; |
| while (b != NULL) |
| { |
| if ((*tokenNo) < b->len) |
| { |
| return b; |
| } |
| else |
| { |
| (*tokenNo) -= b->len; |
| } |
| b = b->next; |
| } |
| return NULL; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| getFileName - returns a String defining the current file. |
| */ |
| |
| static void stop (void) |
| { |
| } |
| |
| |
| /* |
| addTokToList - adds a token to a dynamic list. |
| */ |
| |
| static void addTokToList (mcReserved_toktype t, nameKey_Name n, int i, mcComment_commentDesc comment, unsigned int l, unsigned int c, mcLexBuf_sourceList f) |
| { |
| mcLexBuf_tokenBucket b; |
| |
| if (listOfTokens.head == NULL) |
| { |
| Storage_ALLOCATE ((void **) &listOfTokens.head, sizeof (mcLexBuf__T2)); |
| if (listOfTokens.head == NULL) |
| {} /* empty. */ |
| /* list error */ |
| listOfTokens.tail = listOfTokens.head; |
| listOfTokens.tail->len = 0; |
| } |
| else if (listOfTokens.tail->len == MaxBucketSize) |
| { |
| /* avoid dangling else. */ |
| mcDebug_assert (listOfTokens.tail->next == NULL); |
| Storage_ALLOCATE ((void **) &listOfTokens.tail->next, sizeof (mcLexBuf__T2)); |
| if (listOfTokens.tail->next == NULL) |
| {} /* empty. */ |
| else |
| { |
| /* list error */ |
| listOfTokens.tail = listOfTokens.tail->next; |
| listOfTokens.tail->len = 0; |
| } |
| listOfTokens.lastBucketOffset += MaxBucketSize; |
| } |
| listOfTokens.tail->next = NULL; |
| mcDebug_assert (listOfTokens.tail->len != MaxBucketSize); |
| listOfTokens.tail->buf.array[listOfTokens.tail->len].token = t; |
| listOfTokens.tail->buf.array[listOfTokens.tail->len].str = n; |
| listOfTokens.tail->buf.array[listOfTokens.tail->len].int_ = i; |
| listOfTokens.tail->buf.array[listOfTokens.tail->len].com = comment; |
| listOfTokens.tail->buf.array[listOfTokens.tail->len].line = l; |
| listOfTokens.tail->buf.array[listOfTokens.tail->len].col = c; |
| listOfTokens.tail->buf.array[listOfTokens.tail->len].file = f; |
| listOfTokens.tail->len += 1; |
| } |
| |
| |
| /* |
| isLastTokenEof - returns TRUE if the last token was an eoftok |
| */ |
| |
| static bool isLastTokenEof (void) |
| { |
| unsigned int t; |
| mcLexBuf_tokenBucket b; |
| |
| if (listOfTokens.tail != NULL) |
| { |
| if (listOfTokens.tail->len == 0) |
| { |
| b = listOfTokens.head; |
| if (b == listOfTokens.tail) |
| { |
| return false; |
| } |
| while (b->next != listOfTokens.tail) |
| { |
| b = b->next; |
| } |
| } |
| else |
| { |
| b = listOfTokens.tail; |
| } |
| mcDebug_assert (b->len > 0); /* len should always be >0 */ |
| return b->buf.array[b->len-1].token == mcReserved_eoftok; /* len should always be >0 */ |
| } |
| return false; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| getProcedureComment - returns the procedure comment if it exists, |
| or NIL otherwise. |
| */ |
| |
| extern "C" mcComment_commentDesc mcLexBuf_getProcedureComment (void) |
| { |
| return procedureComment; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| getBodyComment - returns the body comment if it exists, |
| or NIL otherwise. The body comment is |
| removed if found. |
| */ |
| |
| extern "C" mcComment_commentDesc mcLexBuf_getBodyComment (void) |
| { |
| mcComment_commentDesc b; |
| |
| b = bodyComment; |
| bodyComment = static_cast<mcComment_commentDesc> (NULL); |
| return b; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| getAfterComment - returns the after comment if it exists, |
| or NIL otherwise. The after comment is |
| removed if found. |
| */ |
| |
| extern "C" mcComment_commentDesc mcLexBuf_getAfterComment (void) |
| { |
| mcComment_commentDesc a; |
| |
| peepAfterComment (); |
| a = afterComment; |
| afterComment = static_cast<mcComment_commentDesc> (NULL); |
| return a; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| openSource - attempts to open the source file, s. |
| The success of the operation is returned. |
| */ |
| |
| extern "C" bool mcLexBuf_openSource (DynamicStrings_String s) |
| { |
| if (useBufferedTokens) |
| { |
| mcLexBuf_getToken (); |
| return true; |
| } |
| else |
| { |
| if (mcflex_openSource (DynamicStrings_string (s))) |
| { |
| mcLexBuf_setFile (DynamicStrings_string (s)); |
| syncOpenWithBuffer (); |
| mcLexBuf_getToken (); |
| return true; |
| } |
| else |
| { |
| return false; |
| } |
| } |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| closeSource - closes the current open file. |
| */ |
| |
| extern "C" void mcLexBuf_closeSource (void) |
| { |
| if (useBufferedTokens) |
| { |
| while (mcLexBuf_currenttoken != mcReserved_eoftok) |
| { |
| mcLexBuf_getToken (); |
| } |
| } |
| /* a subsequent call to mcflex.OpenSource will really close the file */ |
| } |
| |
| |
| /* |
| reInitialize - re-initialize the all the data structures. |
| */ |
| |
| extern "C" void mcLexBuf_reInitialize (void) |
| { |
| mcLexBuf_tokenBucket s; |
| mcLexBuf_tokenBucket t; |
| |
| if (listOfTokens.head != NULL) |
| { |
| t = listOfTokens.head; |
| do { |
| s = t; |
| t = t->next; |
| Storage_DEALLOCATE ((void **) &s, sizeof (mcLexBuf__T2)); |
| } while (! (t == NULL)); |
| currentUsed = false; |
| killList (); |
| } |
| init (); |
| } |
| |
| |
| /* |
| resetForNewPass - reset the buffer pointers to the beginning ready for |
| a new pass |
| */ |
| |
| extern "C" void mcLexBuf_resetForNewPass (void) |
| { |
| nextTokNo = 0; |
| useBufferedTokens = true; |
| } |
| |
| |
| /* |
| getToken - gets the next token into currenttoken. |
| */ |
| |
| extern "C" void mcLexBuf_getToken (void) |
| { |
| do { |
| doGetToken (); |
| if (mcLexBuf_currenttoken == mcReserved_commenttok) |
| { |
| /* avoid gcc warning by using compound statement even if not strictly necessary. */ |
| if (mcComment_isProcedureComment (mcLexBuf_currentcomment)) |
| { |
| procedureComment = mcLexBuf_currentcomment; |
| bodyComment = static_cast<mcComment_commentDesc> (NULL); |
| afterComment = static_cast<mcComment_commentDesc> (NULL); |
| } |
| else if (mcComment_isBodyComment (mcLexBuf_currentcomment)) |
| { |
| /* avoid dangling else. */ |
| bodyComment = mcLexBuf_currentcomment; |
| afterComment = static_cast<mcComment_commentDesc> (NULL); |
| } |
| else if (mcComment_isAfterComment (mcLexBuf_currentcomment)) |
| { |
| /* avoid dangling else. */ |
| procedureComment = static_cast<mcComment_commentDesc> (NULL); |
| bodyComment = static_cast<mcComment_commentDesc> (NULL); |
| afterComment = mcLexBuf_currentcomment; |
| } |
| } |
| } while (! (mcLexBuf_currenttoken != mcReserved_commenttok)); |
| } |
| |
| |
| /* |
| insertToken - inserts a symbol, token, infront of the current token |
| ready for the next pass. |
| */ |
| |
| extern "C" void mcLexBuf_insertToken (mcReserved_toktype token) |
| { |
| if (listOfTokens.tail != NULL) |
| { |
| if (listOfTokens.tail->len > 0) |
| { |
| listOfTokens.tail->buf.array[listOfTokens.tail->len-1].token = token; |
| } |
| addTokToList (mcLexBuf_currenttoken, nameKey_NulName, 0, static_cast<mcComment_commentDesc> (NULL), mcLexBuf_getLineNo (), mcLexBuf_getColumnNo (), currentSource); |
| mcLexBuf_getToken (); |
| } |
| } |
| |
| |
| /* |
| insertTokenAndRewind - inserts a symbol, token, infront of the current token |
| and then moves the token stream back onto the inserted token. |
| */ |
| |
| extern "C" void mcLexBuf_insertTokenAndRewind (mcReserved_toktype token) |
| { |
| if (listOfTokens.tail != NULL) |
| { |
| if (listOfTokens.tail->len > 0) |
| { |
| listOfTokens.tail->buf.array[listOfTokens.tail->len-1].token = token; |
| } |
| addTokToList (mcLexBuf_currenttoken, nameKey_NulName, 0, static_cast<mcComment_commentDesc> (NULL), mcLexBuf_getLineNo (), mcLexBuf_getColumnNo (), currentSource); |
| mcLexBuf_currenttoken = token; |
| } |
| } |
| |
| |
| /* |
| getPreviousTokenLineNo - returns the line number of the previous token. |
| */ |
| |
| extern "C" unsigned int mcLexBuf_getPreviousTokenLineNo (void) |
| { |
| return mcLexBuf_getLineNo (); |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| getLineNo - returns the current line number where the symbol occurs in |
| the source file. |
| */ |
| |
| extern "C" unsigned int mcLexBuf_getLineNo (void) |
| { |
| if (nextTokNo == 0) |
| { |
| return 0; |
| } |
| else |
| { |
| return mcLexBuf_tokenToLineNo (mcLexBuf_getTokenNo (), 0); |
| } |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| getTokenNo - returns the current token number. |
| */ |
| |
| extern "C" unsigned int mcLexBuf_getTokenNo (void) |
| { |
| if (nextTokNo == 0) |
| { |
| return 0; |
| } |
| else |
| { |
| return nextTokNo-1; |
| } |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| tokenToLineNo - returns the line number of the current file for the |
| tokenNo. The depth refers to the include depth. |
| A depth of 0 is the current file, depth of 1 is the file |
| which included the current file. Zero is returned if the |
| depth exceeds the file nesting level. |
| */ |
| |
| extern "C" unsigned int mcLexBuf_tokenToLineNo (unsigned int tokenNo, unsigned int depth) |
| { |
| mcLexBuf_tokenBucket b; |
| mcLexBuf_sourceList l; |
| |
| b = findtokenBucket (&tokenNo); |
| if (b == NULL) |
| { |
| return 0; |
| } |
| else |
| { |
| if (depth == 0) |
| { |
| return b->buf.array[tokenNo].line; |
| } |
| else |
| { |
| l = b->buf.array[tokenNo].file->left; |
| while (depth > 0) |
| { |
| l = l->left; |
| if (l == b->buf.array[tokenNo].file->left) |
| { |
| return 0; |
| } |
| depth -= 1; |
| } |
| return l->line; |
| } |
| } |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| getColumnNo - returns the current column where the symbol occurs in |
| the source file. |
| */ |
| |
| extern "C" unsigned int mcLexBuf_getColumnNo (void) |
| { |
| if (nextTokNo == 0) |
| { |
| return 0; |
| } |
| else |
| { |
| return mcLexBuf_tokenToColumnNo (mcLexBuf_getTokenNo (), 0); |
| } |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| tokenToColumnNo - returns the column number of the current file for the |
| tokenNo. The depth refers to the include depth. |
| A depth of 0 is the current file, depth of 1 is the file |
| which included the current file. Zero is returned if the |
| depth exceeds the file nesting level. |
| */ |
| |
| extern "C" unsigned int mcLexBuf_tokenToColumnNo (unsigned int tokenNo, unsigned int depth) |
| { |
| mcLexBuf_tokenBucket b; |
| mcLexBuf_sourceList l; |
| |
| b = findtokenBucket (&tokenNo); |
| if (b == NULL) |
| { |
| return 0; |
| } |
| else |
| { |
| if (depth == 0) |
| { |
| return b->buf.array[tokenNo].col; |
| } |
| else |
| { |
| l = b->buf.array[tokenNo].file->left; |
| while (depth > 0) |
| { |
| l = l->left; |
| if (l == b->buf.array[tokenNo].file->left) |
| { |
| return 0; |
| } |
| depth -= 1; |
| } |
| return l->col; |
| } |
| } |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| findFileNameFromToken - returns the complete FileName for the appropriate |
| source file yields the token number, tokenNo. |
| The, Depth, indicates the include level: 0..n |
| Level 0 is the current. NIL is returned if n+1 |
| is requested. |
| */ |
| |
| extern "C" DynamicStrings_String mcLexBuf_findFileNameFromToken (unsigned int tokenNo, unsigned int depth) |
| { |
| mcLexBuf_tokenBucket b; |
| mcLexBuf_sourceList l; |
| |
| b = findtokenBucket (&tokenNo); |
| if (b == NULL) |
| { |
| return static_cast<DynamicStrings_String> (NULL); |
| } |
| else |
| { |
| l = b->buf.array[tokenNo].file->left; |
| while (depth > 0) |
| { |
| l = l->left; |
| if (l == b->buf.array[tokenNo].file->left) |
| { |
| return static_cast<DynamicStrings_String> (NULL); |
| } |
| depth -= 1; |
| } |
| return l->name; |
| } |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| getFileName - returns a String defining the current file. |
| */ |
| |
| extern "C" DynamicStrings_String mcLexBuf_getFileName (void) |
| { |
| return mcLexBuf_findFileNameFromToken (mcLexBuf_getTokenNo (), 0); |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| addTok - adds a token to the buffer. |
| */ |
| |
| extern "C" void mcLexBuf_addTok (mcReserved_toktype t) |
| { |
| if (! ((t == mcReserved_eoftok) && (isLastTokenEof ()))) |
| { |
| addTokToList (t, nameKey_NulName, 0, static_cast<mcComment_commentDesc> (NULL), mcflex_getLineNo (), mcflex_getColumnNo (), currentSource); |
| currentUsed = true; |
| } |
| } |
| |
| |
| /* |
| addTokCharStar - adds a token to the buffer and an additional string, s. |
| A copy of string, s, is made. |
| */ |
| |
| extern "C" void mcLexBuf_addTokCharStar (mcReserved_toktype t, void * s) |
| { |
| if ((libc_strlen (s)) > 80) |
| { |
| stop (); |
| } |
| addTokToList (t, nameKey_makekey (s), 0, static_cast<mcComment_commentDesc> (NULL), mcflex_getLineNo (), mcflex_getColumnNo (), currentSource); |
| currentUsed = true; |
| } |
| |
| |
| /* |
| addTokInteger - adds a token and an integer to the buffer. |
| */ |
| |
| extern "C" void mcLexBuf_addTokInteger (mcReserved_toktype t, int i) |
| { |
| DynamicStrings_String s; |
| unsigned int c; |
| unsigned int l; |
| |
| l = mcflex_getLineNo (); |
| c = mcflex_getColumnNo (); |
| s = FormatStrings_Sprintf1 (DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "%d", 2)), (const unsigned char *) &i, (sizeof (i)-1)); |
| addTokToList (t, nameKey_makekey (DynamicStrings_string (s)), i, static_cast<mcComment_commentDesc> (NULL), l, c, currentSource); |
| s = DynamicStrings_KillString (s); |
| currentUsed = true; |
| } |
| |
| |
| /* |
| addTokComment - adds a token to the buffer and a comment descriptor, com. |
| */ |
| |
| extern "C" void mcLexBuf_addTokComment (mcReserved_toktype t, mcComment_commentDesc com) |
| { |
| addTokToList (t, nameKey_NulName, 0, com, mcflex_getLineNo (), mcflex_getColumnNo (), currentSource); |
| currentUsed = true; |
| } |
| |
| |
| /* |
| setFile - sets the current filename to, filename. |
| */ |
| |
| extern "C" void mcLexBuf_setFile (void * filename) |
| { |
| killList (); |
| currentUsed = false; |
| currentSource = newList (); |
| addTo (newElement (filename)); |
| } |
| |
| |
| /* |
| pushFile - indicates that, filename, has just been included. |
| */ |
| |
| extern "C" void mcLexBuf_pushFile (void * filename) |
| { |
| mcLexBuf_sourceList l; |
| |
| checkIfNeedToDuplicate (); |
| addTo (newElement (filename)); |
| if (Debugging) |
| { |
| if (currentSource->right != currentSource) |
| { |
| l = currentSource; |
| do { |
| 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)); |
| l = l->right; |
| } while (! (l == currentSource)); |
| } |
| } |
| } |
| |
| |
| /* |
| popFile - indicates that we are returning to, filename, having finished |
| an include. |
| */ |
| |
| extern "C" void mcLexBuf_popFile (void * filename) |
| { |
| mcLexBuf_sourceList l; |
| |
| checkIfNeedToDuplicate (); |
| if ((currentSource != NULL) && (currentSource->left != currentSource)) |
| { |
| /* avoid dangling else. */ |
| l = currentSource->left; /* last element */ |
| subFrom (l); /* last element */ |
| Storage_DEALLOCATE ((void **) &l, sizeof (mcLexBuf__T1)); |
| if ((currentSource->left != currentSource) && (! (DynamicStrings_Equal (currentSource->name, DynamicStrings_Mark (DynamicStrings_InitStringCharStar (filename)))))) |
| {} /* empty. */ |
| /* mismatch in source file names after preprocessing files */ |
| } |
| /* source file list is empty, cannot pop an include.. */ |
| } |
| |
| extern "C" void _M2_mcLexBuf_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[]) |
| { |
| init (); |
| } |
| |
| extern "C" void _M2_mcLexBuf_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[]) |
| { |
| } |