mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-23 11:32:07 +00:00
Files that weren't found with the absolute path weren't added as dependencies even if they were found after considering the list of include directories. This patch makes rgbasm print the complete path (including the include directory path) in these cases. Signed-off-by: Antonio Niño Díaz <antonio_nd@outlook.com>
376 lines
7.8 KiB
C
376 lines
7.8 KiB
C
/*
|
|
* FileStack routines
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <limits.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "asm/symbol.h"
|
|
#include "asm/fstack.h"
|
|
#include "types.h"
|
|
#include "asm/main.h"
|
|
#include "asm/lexer.h"
|
|
#include "extern/err.h"
|
|
#include "extern/strl.h"
|
|
|
|
#ifndef PATH_MAX
|
|
#define PATH_MAX 256
|
|
#endif
|
|
|
|
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;
|
|
|
|
extern char *tzObjectname;
|
|
extern FILE *dependfile;
|
|
|
|
/*
|
|
* defines for nCurrentStatus
|
|
*/
|
|
#define STAT_isInclude 0
|
|
#define STAT_isMacro 1
|
|
#define STAT_isMacroArg 2
|
|
#define STAT_isREPTBlock 3
|
|
|
|
/*
|
|
* Context push and pop
|
|
*/
|
|
void
|
|
pushcontext(void)
|
|
{
|
|
struct sContext **ppFileStack;
|
|
|
|
ppFileStack = &pFileStack;
|
|
while (*ppFileStack)
|
|
ppFileStack = &((*ppFileStack)->pNext);
|
|
|
|
if ((*ppFileStack = 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());
|
|
}
|
|
|
|
/*
|
|
* 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);
|
|
}
|
|
|
|
/*
|
|
* Extra includepath stuff
|
|
*/
|
|
void
|
|
fstk_AddIncludePath(char *s)
|
|
{
|
|
if (NextIncPath == MAXINCPATHS) {
|
|
fatalerror("Too many include directories passed from command line");
|
|
return;
|
|
}
|
|
|
|
if (strlcpy(IncludePaths[NextIncPath++], s, _MAX_PATH) >= _MAX_PATH) {
|
|
fatalerror("Include path too long '%s'",s);
|
|
return;
|
|
}
|
|
}
|
|
|
|
FILE *
|
|
fstk_FindFile(char *fname)
|
|
{
|
|
char path[PATH_MAX];
|
|
int i;
|
|
FILE *f;
|
|
|
|
if ((f = fopen(fname, "rb")) != NULL || errno != ENOENT) {
|
|
if (dependfile) {
|
|
fprintf(dependfile, "%s: %s\n", tzObjectname, fname);
|
|
}
|
|
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) {
|
|
if (dependfile) {
|
|
fprintf(dependfile, "%s: %s\n", tzObjectname, path);
|
|
}
|
|
return f;
|
|
}
|
|
}
|
|
|
|
errno = ENOENT;
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* Set up an include file for parsing
|
|
*/
|
|
void
|
|
fstk_RunInclude(char *tzFileName)
|
|
{
|
|
FILE *f;
|
|
|
|
f = fstk_FindFile(tzFileName);
|
|
|
|
if (f == NULL) {
|
|
err(1, "Unable to open included file '%s'",
|
|
tzFileName);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
/*
|
|
* 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);
|
|
if (sym->pMacro == NULL)
|
|
return 0;
|
|
pCurrentMacro = sym;
|
|
CurrentFlexHandle =
|
|
yy_scan_bytes(pCurrentMacro->pMacro,
|
|
strlen(pCurrentMacro->pMacro));
|
|
yy_switch_to_buffer(CurrentFlexHandle);
|
|
return (1);
|
|
} else
|
|
return (0);
|
|
}
|
|
|
|
/*
|
|
* 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");
|
|
}
|
|
|
|
/*
|
|
* 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 '%s'", s);
|
|
}
|
|
|
|
/*
|
|
* 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);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Initialize the filestack routines
|
|
*/
|
|
void
|
|
fstk_Init(char *s)
|
|
{
|
|
char tzFileName[_MAX_PATH + 1];
|
|
|
|
char tzSymFileName[_MAX_PATH + 1 + 2];
|
|
snprintf(tzSymFileName, sizeof(tzSymFileName), "\"%s\"", s);
|
|
sym_AddString("__FILE__", tzSymFileName);
|
|
|
|
strcpy(tzFileName, s);
|
|
pFileStack = NULL;
|
|
pCurrentFile = fopen(tzFileName, "rb");
|
|
if (pCurrentFile == NULL) {
|
|
err(1, "Unable to open file '%s'", tzFileName);
|
|
}
|
|
|
|
nMacroCount = 0;
|
|
nCurrentStatus = STAT_isInclude;
|
|
strcpy(tzCurrentFileName, tzFileName);
|
|
CurrentFlexHandle = yy_create_buffer(pCurrentFile);
|
|
yy_switch_to_buffer(CurrentFlexHandle);
|
|
nLineNo = 1;
|
|
}
|