shithub: rgbds

ref: 06c4e1fb4b06c2a019d78752d114da70e8d41509
dir: /src/asm/fstack.c/

View raw version
/*
 * RGBAsm - FSTACK.C (FileStack routines)
 *
 * INCLUDES
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#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[_MAX_PATH + 1];
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

ULONG 
filesize(char *s)
{
	FILE *f;
	ULONG size = 0;

	if ((f = fopen(s, "rt")) != NULL) {
		fseek(f, 0, SEEK_END);
		size = ftell(f);
		fclose(f);
	}
	return (size);
}
/*
 * 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;
		strcpy((char *) (*ppFileStack)->tzFileName,
		    (char *) 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;
		strcpy((char *) tzCurrentFileName,
		    (char *) 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 stdout
 *
 */

void 
fstk_Dump(void)
{
	struct sContext *pLastFile;

	pLastFile = pFileStack;

	while (pLastFile) {
		printf("%s(%ld) -> ", pLastFile->tzFileName, pLastFile->nLine);
		pLastFile = pLastFile->pNext;
	}

	printf("%s(%ld)", tzCurrentFileName, nLineNo);
}
/*
 * RGBAsm - FSTACK.C (FileStack routines)
 *
 * Extra includepath stuff
 *
 */

void 
fstk_AddIncludePath(char *s)
{
	strcpy(IncludePaths[NextIncPath++], s);
}

void 
fstk_FindFile(char *s)
{
	char t[_MAX_PATH + 1];
	SLONG i = -1;

	strcpy(t, s);

	while (i < NextIncPath) {
		FILE *f;

		if ((f = fopen(t, "rb")) != NULL) {
			fclose(f);
			strcpy(s, t);
			return;
		}
		i += 1;
		if (i < NextIncPath) {
			strcpy(t, IncludePaths[i]);
			strcat(t, s);
		}
	}
}
/*
 * RGBAsm - FSTACK.C (FileStack routines)
 *
 * Set up an include file for parsing
 *
 */

ULONG 
fstk_RunInclude(char *s)
{
	FILE *f;
	char tzFileName[_MAX_PATH + 1];

	//printf("INCLUDE: %s\n", s);

	strcpy(tzFileName, s);
	fstk_FindFile(tzFileName);
	//printf("INCLUDING: %s\n", tzFileName);

	if ((f = fopen(tzFileName, "rt")) != NULL) {
		pushcontext();
		nLineNo = 1;
		nCurrentStatus = STAT_isInclude;
		strcpy(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;

		return (1);
	} else
		return (0);
}
/*
 * 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;
		strcpy(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 macroargument for parsing
 *
 */

void 
fstk_RunMacroArg(SLONG s)
{
	char *sym;

	if (s == '@')
		s = -1;
	else
		s -= '0';

	if ((sym = sym_FindMacroArg(s)) != NULL) {
		pushcontext();
		nCurrentStatus = STAT_isMacroArg;
		sprintf(tzCurrentFileName, "%c", (UBYTE) s);
		CurrentFlexHandle = yy_scan_bytes(sym, strlen(sym));
		yy_switch_to_buffer(CurrentFlexHandle);
	} else
		fatalerror("No such macroargument");
}
/*
 * 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;
		strcpy(tzCurrentFileName, s);
		CurrentFlexHandle =
		    yy_scan_bytes(pSym->pMacro, strlen(pSym->pMacro));
		yy_switch_to_buffer(CurrentFlexHandle);
	} else
		yyerror("No such string symbol");
}
/*
 * 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
 *
 */

ULONG 
fstk_Init(char *s)
{
	char tzFileName[_MAX_PATH + 1];

	sym_AddString("__FILE__", s);

	strcpy(tzFileName, s);
	fstk_FindFile(tzFileName);

	pFileStack = NULL;
	if ((pCurrentFile = fopen(tzFileName, "rt")) != NULL) {
		nMacroCount = 0;
		nCurrentStatus = STAT_isInclude;
		strcpy(tzCurrentFileName, tzFileName);
		CurrentFlexHandle = yy_create_buffer(pCurrentFile);
		yy_switch_to_buffer(CurrentFlexHandle);
		nLineNo = 1;
		return (1);
	} else
		return (0);
}