ref: 97d431d1f4ad404e282e3781bd195be3f053734d
dir: /src/asm/fstack.c/
/* * RGBAsm - FSTACK.C (FileStack routines) * * INCLUDES * */ #include <errno.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #ifndef STRL_IN_LIBC #define strlcpy rgbds_strlcpy #define strlcat rgbds_strlcat size_t strlcpy(char *, const char *, size_t); size_t strlcat(char *, const char *, size_t); #endif #include "asm/symbol.h" #include "asm/fstack.h" #include "asm/types.h" #include "asm/main.h" #include "asm/lexer.h" /* * RGBAsm - FSTACK.C (FileStack routines) * * VARIABLES * */ struct sContext *pFileStack; struct sSymbol *pCurrentMacro; YY_BUFFER_STATE CurrentFlexHandle; FILE *pCurrentFile; ULONG nCurrentStatus; char *tzCurrentFileName; char IncludePaths[MAXINCPATHS][_MAX_PATH + 1]; SLONG NextIncPath = 0; ULONG nMacroCount; char *pCurrentREPTBlock; ULONG nCurrentREPTBlockSize; ULONG nCurrentREPTBlockCount; ULONG ulMacroReturnValue; /* * defines for nCurrentStatus */ #define STAT_isInclude 0 #define STAT_isMacro 1 #define STAT_isMacroArg 2 #define STAT_isREPTBlock 3 /* * RGBAsm - FSTACK.C (FileStack routines) * * Context push and pop * */ void pushcontext(void) { struct sContext **ppFileStack; ppFileStack = &pFileStack; while (*ppFileStack) ppFileStack = &((*ppFileStack)->pNext); if ((*ppFileStack = (struct sContext *) malloc(sizeof(struct sContext))) != NULL) { (*ppFileStack)->FlexHandle = CurrentFlexHandle; (*ppFileStack)->pNext = NULL; (*ppFileStack)->tzFileName = tzCurrentFileName; (*ppFileStack)->nLine = nLineNo; switch ((*ppFileStack)->nStatus = nCurrentStatus) { case STAT_isMacroArg: case STAT_isMacro: sym_SaveCurrentMacroArgs((*ppFileStack)->tzMacroArgs); (*ppFileStack)->pMacro = pCurrentMacro; break; case STAT_isInclude: (*ppFileStack)->pFile = pCurrentFile; break; case STAT_isREPTBlock: sym_SaveCurrentMacroArgs((*ppFileStack)->tzMacroArgs); (*ppFileStack)->pREPTBlock = pCurrentREPTBlock; (*ppFileStack)->nREPTBlockSize = nCurrentREPTBlockSize; (*ppFileStack)->nREPTBlockCount = nCurrentREPTBlockCount; break; } nLineNo = 0; } else fatalerror("No memory for context"); } int popcontext(void) { struct sContext *pLastFile, **ppLastFile; if (nCurrentStatus == STAT_isREPTBlock) { if (--nCurrentREPTBlockCount) { yy_delete_buffer(CurrentFlexHandle); CurrentFlexHandle = yy_scan_bytes(pCurrentREPTBlock, nCurrentREPTBlockSize); yy_switch_to_buffer(CurrentFlexHandle); sym_UseCurrentMacroArgs(); sym_SetMacroArgID(nMacroCount++); sym_UseNewMacroArgs(); return (0); } } if ((pLastFile = pFileStack) != NULL) { ppLastFile = &pFileStack; while (pLastFile->pNext) { ppLastFile = &(pLastFile->pNext); pLastFile = *ppLastFile; } yy_delete_buffer(CurrentFlexHandle); nLineNo = pLastFile->nLine; if (nCurrentStatus == STAT_isInclude) fclose(pCurrentFile); if (nCurrentStatus == STAT_isMacro) { sym_FreeCurrentMacroArgs(); nLineNo += 1; } if (nCurrentStatus == STAT_isREPTBlock) nLineNo += 1; CurrentFlexHandle = pLastFile->FlexHandle; tzCurrentFileName = pLastFile->tzFileName; switch (nCurrentStatus = pLastFile->nStatus) { case STAT_isMacroArg: case STAT_isMacro: sym_RestoreCurrentMacroArgs(pLastFile->tzMacroArgs); pCurrentMacro = pLastFile->pMacro; break; case STAT_isInclude: pCurrentFile = pLastFile->pFile; break; case STAT_isREPTBlock: sym_RestoreCurrentMacroArgs(pLastFile->tzMacroArgs); pCurrentREPTBlock = pLastFile->pREPTBlock; nCurrentREPTBlockSize = pLastFile->nREPTBlockSize; nCurrentREPTBlockCount = pLastFile->nREPTBlockCount; break; } free(*ppLastFile); *ppLastFile = NULL; yy_switch_to_buffer(CurrentFlexHandle); return (0); } else return (1); } int yywrap(void) { return (popcontext()); } /* * RGBAsm - FSTACK.C (FileStack routines) * * Dump the context stack to stderr * */ void fstk_Dump(void) { struct sContext *pLastFile; pLastFile = pFileStack; while (pLastFile) { fprintf(stderr, "%s(%ld) -> ", pLastFile->tzFileName, pLastFile->nLine); pLastFile = pLastFile->pNext; } fprintf(stderr, "%s(%ld)", tzCurrentFileName, nLineNo); } /* * RGBAsm - FSTACK.C (FileStack routines) * * Extra includepath stuff * */ void fstk_AddIncludePath(char *s) { strcpy(IncludePaths[NextIncPath++], s); } FILE * fstk_FindFile(char *fname) { char path[PATH_MAX]; int i; FILE *f; if ((f = fopen(fname, "rb")) != NULL || errno != ENOENT) { return f; } for (i = 0; i < NextIncPath; ++i) { if (strlcpy(path, IncludePaths[i], sizeof path) >= sizeof path) { continue; } if (strlcat(path, fname, sizeof path) >= sizeof path) { continue; } if ((f = fopen(path, "rb")) != NULL || errno != ENOENT) { return f; } } errno = ENOENT; return NULL; } /* * RGBAsm - FSTACK.C (FileStack routines) * * Set up an include file for parsing * */ void fstk_RunInclude(char *tzFileName) { FILE *f; f = fstk_FindFile(tzFileName); if (f == NULL) { fprintf(stderr, "Unable to open included file '%s': ", tzFileName); perror(NULL); exit(1); } pushcontext(); nLineNo = 1; nCurrentStatus = STAT_isInclude; tzCurrentFileName = tzFileName; pCurrentFile = f; CurrentFlexHandle = yy_create_buffer(pCurrentFile); yy_switch_to_buffer(CurrentFlexHandle); //Dirty hack to give the INCLUDE directive a linefeed yyunput('\n'); nLineNo -= 1; } /* * RGBAsm - FSTACK.C (FileStack routines) * * Set up a macro for parsing * */ ULONG fstk_RunMacro(char *s) { struct sSymbol *sym; if ((sym = sym_FindMacro(s)) != NULL) { pushcontext(); sym_SetMacroArgID(nMacroCount++); nLineNo = -1; sym_UseNewMacroArgs(); nCurrentStatus = STAT_isMacro; tzCurrentFileName = s; pCurrentMacro = sym; CurrentFlexHandle = yy_scan_bytes(pCurrentMacro->pMacro, pCurrentMacro->ulMacroSize); yy_switch_to_buffer(CurrentFlexHandle); return (1); } else return (0); } /* * RGBAsm - FSTACK.C (FileStack routines) * * Set up a stringequate for parsing * */ void fstk_RunString(char *s) { struct sSymbol *pSym; if ((pSym = sym_FindSymbol(s)) != NULL) { pushcontext(); nCurrentStatus = STAT_isMacroArg; tzCurrentFileName = s; CurrentFlexHandle = yy_scan_bytes(pSym->pMacro, strlen(pSym->pMacro)); yy_switch_to_buffer(CurrentFlexHandle); } else yyerror("No such string symbol '%s'", s); } /* * RGBAsm - FSTACK.C (FileStack routines) * * Set up a repeat block for parsing * */ void fstk_RunRept(ULONG count) { if (count) { pushcontext(); sym_UseCurrentMacroArgs(); sym_SetMacroArgID(nMacroCount++); sym_UseNewMacroArgs(); nCurrentREPTBlockCount = count; nCurrentStatus = STAT_isREPTBlock; nCurrentREPTBlockSize = ulNewMacroSize; pCurrentREPTBlock = tzNewMacro; CurrentFlexHandle = yy_scan_bytes(pCurrentREPTBlock, nCurrentREPTBlockSize); yy_switch_to_buffer(CurrentFlexHandle); } } /* * RGBAsm - FSTACK.C (FileStack routines) * * Initialize the filestack routines * */ void fstk_Init(char *s) { char tzFileName[_MAX_PATH + 1]; sym_AddString("__FILE__", s); strcpy(tzFileName, s); pFileStack = NULL; pCurrentFile = fopen(tzFileName, "rb"); if (pCurrentFile == NULL) { fprintf(stderr, "Unable to open file '%s': ", tzFileName); perror(NULL); exit(1); } nMacroCount = 0; nCurrentStatus = STAT_isInclude; tzCurrentFileName = tzFileName; CurrentFlexHandle = yy_create_buffer(pCurrentFile); yy_switch_to_buffer(CurrentFlexHandle); nLineNo = 1; }