/* 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-2024 Free Software Foundation, Inc. Contributed by Gaius Mulley . 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 . */ #include "config.h" #include "system.h" #include # 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_H #define _mcLexBuf_C # 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" mcComment_commentDesc mcLexBuf_currentcomment; mcComment_commentDesc mcLexBuf_lastcomment; int mcLexBuf_currentinteger; unsigned int mcLexBuf_currentcolumn; void * mcLexBuf_currentstring; mcReserved_toktype mcLexBuf_currenttoken; # 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 (NULL); bodyComment = static_cast (NULL); afterComment = static_cast (NULL); mcLexBuf_lastcomment = static_cast (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 (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 (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 (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 (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 (NULL); afterComment = static_cast (NULL); } else if (mcComment_isBodyComment (mcLexBuf_currentcomment)) { /* avoid dangling else. */ bodyComment = mcLexBuf_currentcomment; afterComment = static_cast (NULL); } else if (mcComment_isAfterComment (mcLexBuf_currentcomment)) { /* avoid dangling else. */ procedureComment = static_cast (NULL); bodyComment = static_cast (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 (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 (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 (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 (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 (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 (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 (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[]) { }