Improve error stack

The old error stack was fairly obtuse and hard to use for debugging.
This improves it notably by ensuring all line numbers are relative
to the file, and not, say, the macro definition.
This is a breaking change if you were parsing the old stack, but
the change should be painless, and the new stack only brings more info.
The syntax is unchanged for files, macros see their name prefixed
with the file they're defined in and a pair of colors, REPT blocks
simply append a '::REPT~n' to the context they're in, where 'n' is
the number of iterations the REPT has done.
This is especially helpful in macro-heavy code such as rgbds-structs.
This commit is contained in:
ISSOtm
2019-08-29 17:03:50 +02:00
parent 4ef27a0d23
commit 37089ef940
15 changed files with 100 additions and 36 deletions

View File

@@ -33,6 +33,8 @@ struct sContext {
char *pREPTBlock; char *pREPTBlock;
uint32_t nREPTBlockCount; uint32_t nREPTBlockCount;
uint32_t nREPTBlockSize; uint32_t nREPTBlockSize;
int32_t nREPTBodyFirstLine;
int32_t nREPTBodyLastLine;
}; };
extern unsigned int nMaxRecursionDepth; extern unsigned int nMaxRecursionDepth;
@@ -43,7 +45,7 @@ void fstk_Init(char *s);
void fstk_Dump(void); void fstk_Dump(void);
void fstk_AddIncludePath(char *s); void fstk_AddIncludePath(char *s);
uint32_t fstk_RunMacro(char *s); uint32_t fstk_RunMacro(char *s);
void fstk_RunRept(uint32_t count); void fstk_RunRept(uint32_t count, int32_t nReptLineNo);
FILE *fstk_FindFile(char *fname, char **incPathUsed); FILE *fstk_FindFile(char *fname, char **incPathUsed);
int32_t fstk_GetLine(void); int32_t fstk_GetLine(void);

View File

@@ -74,7 +74,7 @@ char *sym_GetStringValue(char *tzSym);
void sym_UseCurrentMacroArgs(void); void sym_UseCurrentMacroArgs(void);
void sym_SetMacroArgID(uint32_t nMacroCount); void sym_SetMacroArgID(uint32_t nMacroCount);
uint32_t sym_isString(char *tzSym); uint32_t sym_isString(char *tzSym);
void sym_AddMacro(char *tzSym); void sym_AddMacro(char *tzSym, int32_t nDefLineNo);
void sym_Ref(char *tzSym); void sym_Ref(char *tzSym);
void sym_ShiftCurrentMacroArgs(void); void sym_ShiftCurrentMacroArgs(void);
void sym_AddString(char *tzSym, char *tzValue); void sym_AddString(char *tzSym, char *tzValue);

View File

@@ -816,15 +816,17 @@ shift : T_POP_SHIFT { sym_ShiftCurrentMacroArgs(); }
rept : T_POP_REPT uconst rept : T_POP_REPT uconst
{ {
uint32_t nDefinitionLineNo = nLineNo;
copyrept(); copyrept();
fstk_RunRept($2); fstk_RunRept($2, nDefinitionLineNo);
} }
; ;
macrodef : T_LABEL ':' T_POP_MACRO macrodef : T_LABEL ':' T_POP_MACRO
{ {
int32_t nDefinitionLineNo = nLineNo;
copymacro(); copymacro();
sym_AddMacro($1); sym_AddMacro($1, nDefinitionLineNo);
} }
; ;

View File

@@ -42,6 +42,8 @@ static uint32_t nMacroCount;
static char *pCurrentREPTBlock; static char *pCurrentREPTBlock;
static uint32_t nCurrentREPTBlockSize; static uint32_t nCurrentREPTBlockSize;
static uint32_t nCurrentREPTBlockCount; static uint32_t nCurrentREPTBlockCount;
static int32_t nCurrentREPTBodyFirstLine;
static int32_t nCurrentREPTBodyLastLine;
uint32_t ulMacroReturnValue; uint32_t ulMacroReturnValue;
@@ -93,6 +95,8 @@ static void pushcontext(void)
(*ppFileStack)->pREPTBlock = pCurrentREPTBlock; (*ppFileStack)->pREPTBlock = pCurrentREPTBlock;
(*ppFileStack)->nREPTBlockSize = nCurrentREPTBlockSize; (*ppFileStack)->nREPTBlockSize = nCurrentREPTBlockSize;
(*ppFileStack)->nREPTBlockCount = nCurrentREPTBlockCount; (*ppFileStack)->nREPTBlockCount = nCurrentREPTBlockCount;
(*ppFileStack)->nREPTBodyFirstLine = nCurrentREPTBodyFirstLine;
(*ppFileStack)->nREPTBodyLastLine = nCurrentREPTBodyLastLine;
break; break;
default: default:
fatalerror("%s: Internal error.", __func__); fatalerror("%s: Internal error.", __func__);
@@ -107,6 +111,11 @@ static int32_t popcontext(void)
if (nCurrentStatus == STAT_isREPTBlock) { if (nCurrentStatus == STAT_isREPTBlock) {
if (--nCurrentREPTBlockCount) { if (--nCurrentREPTBlockCount) {
char *pREPTIterationWritePtr;
unsigned long nREPTIterationNo;
int nNbCharsWritten;
int nNbCharsLeft;
yy_delete_buffer(CurrentFlexHandle); yy_delete_buffer(CurrentFlexHandle);
CurrentFlexHandle = CurrentFlexHandle =
yy_scan_bytes(pCurrentREPTBlock, yy_scan_bytes(pCurrentREPTBlock,
@@ -115,6 +124,29 @@ static int32_t popcontext(void)
sym_UseCurrentMacroArgs(); sym_UseCurrentMacroArgs();
sym_SetMacroArgID(nMacroCount++); sym_SetMacroArgID(nMacroCount++);
sym_UseNewMacroArgs(); sym_UseNewMacroArgs();
/* Increment REPT count in file path */
pREPTIterationWritePtr =
strrchr(tzCurrentFileName, '~') + 1;
nREPTIterationNo =
strtoul(pREPTIterationWritePtr, NULL, 10);
nNbCharsLeft = sizeof(tzCurrentFileName)
- (pREPTIterationWritePtr - tzCurrentFileName);
nNbCharsWritten = snprintf(pREPTIterationWritePtr,
nNbCharsLeft, "%lu",
nREPTIterationNo + 1);
if (nNbCharsWritten >= nNbCharsLeft) {
/*
* The string is probably corrupted somehow,
* revert the change to avoid a bad error
* output.
*/
sprintf(pREPTIterationWritePtr, "%lu",
nREPTIterationNo);
fatalerror("Cannot write REPT count to file path");
}
nLineNo = nCurrentREPTBodyFirstLine;
return 0; return 0;
} }
} }
@@ -156,6 +188,9 @@ static int32_t popcontext(void)
pCurrentREPTBlock = pLastFile->pREPTBlock; pCurrentREPTBlock = pLastFile->pREPTBlock;
nCurrentREPTBlockSize = pLastFile->nREPTBlockSize; nCurrentREPTBlockSize = pLastFile->nREPTBlockSize;
nCurrentREPTBlockCount = pLastFile->nREPTBlockCount; nCurrentREPTBlockCount = pLastFile->nREPTBlockCount;
nCurrentREPTBodyFirstLine = pLastFile->nREPTBodyFirstLine;
/* + 1 to account for the `ENDR` line */
nLineNo = pLastFile->nREPTBodyLastLine + 1;
break; break;
default: default:
fatalerror("%s: Internal error.", __func__); fatalerror("%s: Internal error.", __func__);
@@ -322,16 +357,23 @@ void fstk_RunInclude(char *tzFileName)
uint32_t fstk_RunMacro(char *s) uint32_t fstk_RunMacro(char *s)
{ {
struct sSymbol *sym = sym_FindMacro(s); struct sSymbol *sym = sym_FindMacro(s);
int nPrintedChars;
if (sym == NULL || sym->pMacro == NULL) if (sym == NULL || sym->pMacro == NULL)
return 0; return 0;
pushcontext(); pushcontext();
sym_SetMacroArgID(nMacroCount++); sym_SetMacroArgID(nMacroCount++);
nLineNo = -1; /* Minus 1 because there is a newline at the beginning of the buffer */
nLineNo = sym->nFileLine - 1;
sym_UseNewMacroArgs(); sym_UseNewMacroArgs();
nCurrentStatus = STAT_isMacro; nCurrentStatus = STAT_isMacro;
strcpy(tzCurrentFileName, s); nPrintedChars = snprintf(tzCurrentFileName, _MAX_PATH + 1,
"%s::%s", sym->tzFileName, s);
if (nPrintedChars > _MAX_PATH) {
popcontext();
fatalerror("File name + macro name is too large to fit into buffer");
}
pCurrentMacro = sym; pCurrentMacro = sym;
CurrentFlexHandle = yy_scan_bytes(pCurrentMacro->pMacro, CurrentFlexHandle = yy_scan_bytes(pCurrentMacro->pMacro,
@@ -387,9 +429,14 @@ void fstk_RunString(char *s)
/* /*
* Set up a repeat block for parsing * Set up a repeat block for parsing
*/ */
void fstk_RunRept(uint32_t count) void fstk_RunRept(uint32_t count, int32_t nReptLineNo)
{ {
if (count) { if (count) {
static const char *tzReptStr = "::REPT~1";
/* For error printing to make sense, fake nLineNo */
nCurrentREPTBodyLastLine = nLineNo;
nLineNo = nReptLineNo;
sym_UseCurrentMacroArgs(); sym_UseCurrentMacroArgs();
pushcontext(); pushcontext();
sym_SetMacroArgID(nMacroCount++); sym_SetMacroArgID(nMacroCount++);
@@ -398,6 +445,14 @@ void fstk_RunRept(uint32_t count)
nCurrentStatus = STAT_isREPTBlock; nCurrentStatus = STAT_isREPTBlock;
nCurrentREPTBlockSize = ulNewMacroSize; nCurrentREPTBlockSize = ulNewMacroSize;
pCurrentREPTBlock = tzNewMacro; pCurrentREPTBlock = tzNewMacro;
nCurrentREPTBodyFirstLine = nReptLineNo + 1;
nLineNo = nReptLineNo;
if (strlen(tzCurrentFileName) + strlen(tzReptStr) > _MAX_PATH)
fatalerror("Cannot append \"%s\" to file path",
tzReptStr);
strcat(tzCurrentFileName, tzReptStr);
CurrentFlexHandle = CurrentFlexHandle =
yy_scan_bytes(pCurrentREPTBlock, nCurrentREPTBlockSize); yy_scan_bytes(pCurrentREPTBlock, nCurrentREPTBlockSize);
yy_switch_to_buffer(CurrentFlexHandle); yy_switch_to_buffer(CurrentFlexHandle);

View File

@@ -705,7 +705,7 @@ void sym_Export(char *tzSym)
/* /*
* Add a macro definition * Add a macro definition
*/ */
void sym_AddMacro(char *tzSym) void sym_AddMacro(char *tzSym, int32_t nDefLineNo)
{ {
struct sSymbol *nsym = createNonrelocSymbol(tzSym); struct sSymbol *nsym = createNonrelocSymbol(tzSym);
@@ -715,6 +715,11 @@ void sym_AddMacro(char *tzSym)
nsym->ulMacroSize = ulNewMacroSize; nsym->ulMacroSize = ulNewMacroSize;
nsym->pMacro = tzNewMacro; nsym->pMacro = tzNewMacro;
updateSymbolFilename(nsym); updateSymbolFilename(nsym);
/*
* The symbol is created at the line after the `endm`,
* override this with the actual definition line
*/
nsym->nFileLine = nDefLineNo;
} }
} }

View File

@@ -1,4 +1,4 @@
ERROR: label-macro-arg.asm(45) -> test_char(2): ERROR: label-macro-arg.asm(45) -> label-macro-arg.asm::test_char(31):
Macro 'something' not defined Macro 'something' not defined
$5 $5
$6 $6

View File

@@ -1,4 +1,4 @@
ERROR: -(45) -> test_char(2): ERROR: -(45) -> -::test_char(31):
Macro 'something' not defined Macro 'something' not defined
$5 $5
$6 $6

View File

@@ -1,3 +1,3 @@
ERROR: label-redefinition.asm(7): ERROR: label-redefinition.asm(7):
'Sym' already defined in m(6) 'Sym' already defined in label-redefinition.asm::m(6)
error: Assembly aborted (1 errors)! error: Assembly aborted (1 errors)!

View File

@@ -1,3 +1,3 @@
ERROR: -(7): ERROR: -(7):
'Sym' already defined in m(6) 'Sym' already defined in -::m(6)
error: Assembly aborted (1 errors)! error: Assembly aborted (1 errors)!

View File

@@ -1,2 +1,2 @@
ERROR: macro-recursion.asm(4) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1): ERROR: macro-recursion.asm(4) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2) -> macro-recursion.asm::recurse(2):
Recursion limit (64) exceeded Recursion limit (64) exceeded

View File

@@ -1,2 +1,2 @@
ERROR: -(4) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1) -> recurse(1): ERROR: -(4) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2) -> -::recurse(2):
Recursion limit (64) exceeded Recursion limit (64) exceeded

View File

@@ -1,10 +1,10 @@
warning: multiple-charmaps.asm(75): warning: multiple-charmaps.asm(75):
Using 'charmap' within a section when the current charmap is 'main' is deprecated Using 'charmap' within a section when the current charmap is 'main' is deprecated
ERROR: multiple-charmaps.asm(100) -> new_(6): ERROR: multiple-charmaps.asm(100) -> multiple-charmaps.asm::new_(7):
Charmap 'map1' already exists Charmap 'map1' already exists
ERROR: multiple-charmaps.asm(102) -> set_(2): ERROR: multiple-charmaps.asm(102) -> multiple-charmaps.asm::set_(13):
Charmap 'map5' doesn't exist Charmap 'map5' doesn't exist
ERROR: multiple-charmaps.asm(104) -> pop_(2): ERROR: multiple-charmaps.asm(104) -> multiple-charmaps.asm::pop_(23):
No entries in the charmap stack No entries in the charmap stack
main charmap main charmap
$0 $0

View File

@@ -1,10 +1,10 @@
warning: -(75): warning: -(75):
Using 'charmap' within a section when the current charmap is 'main' is deprecated Using 'charmap' within a section when the current charmap is 'main' is deprecated
ERROR: -(100) -> new_(6): ERROR: -(100) -> -::new_(7):
Charmap 'map1' already exists Charmap 'map1' already exists
ERROR: -(102) -> set_(2): ERROR: -(102) -> -::set_(13):
Charmap 'map5' doesn't exist Charmap 'map5' doesn't exist
ERROR: -(104) -> pop_(2): ERROR: -(104) -> -::pop_(23):
No entries in the charmap stack No entries in the charmap stack
main charmap main charmap
$0 $0

View File

@@ -1,18 +1,18 @@
warning: strsub.asm(13) -> xstrsub(1): warning: strsub.asm(13) -> strsub.asm::xstrsub(4):
STRSUB: Length too big: 32 STRSUB: Length too big: 32
warning: strsub.asm(14) -> xstrsub(1): warning: strsub.asm(14) -> strsub.asm::xstrsub(4):
STRSUB: Length too big: 300 STRSUB: Length too big: 300
warning: strsub.asm(15) -> xstrsub(1): warning: strsub.asm(15) -> strsub.asm::xstrsub(4):
STRSUB: Position starts at 1 STRSUB: Position starts at 1
warning: strsub.asm(15) -> xstrsub(1): warning: strsub.asm(15) -> strsub.asm::xstrsub(4):
STRSUB: Length too big: 300 STRSUB: Length too big: 300
warning: strsub.asm(16) -> xstrsub(1): warning: strsub.asm(16) -> strsub.asm::xstrsub(4):
STRSUB: Position 4 is past the end of the string STRSUB: Position 4 is past the end of the string
warning: strsub.asm(17) -> xstrsub(1): warning: strsub.asm(17) -> strsub.asm::xstrsub(4):
STRSUB: Position 4 is past the end of the string STRSUB: Position 4 is past the end of the string
warning: strsub.asm(17) -> xstrsub(1): warning: strsub.asm(17) -> strsub.asm::xstrsub(4):
STRSUB: Length too big: 1 STRSUB: Length too big: 1
warning: strsub.asm(20) -> xstrsub(1): warning: strsub.asm(20) -> strsub.asm::xstrsub(4):
STRSUB: Length too big: 10 STRSUB: Length too big: 10
A A
B B

View File

@@ -1,18 +1,18 @@
warning: -(13) -> xstrsub(1): warning: -(13) -> -::xstrsub(4):
STRSUB: Length too big: 32 STRSUB: Length too big: 32
warning: -(14) -> xstrsub(1): warning: -(14) -> -::xstrsub(4):
STRSUB: Length too big: 300 STRSUB: Length too big: 300
warning: -(15) -> xstrsub(1): warning: -(15) -> -::xstrsub(4):
STRSUB: Position starts at 1 STRSUB: Position starts at 1
warning: -(15) -> xstrsub(1): warning: -(15) -> -::xstrsub(4):
STRSUB: Length too big: 300 STRSUB: Length too big: 300
warning: -(16) -> xstrsub(1): warning: -(16) -> -::xstrsub(4):
STRSUB: Position 4 is past the end of the string STRSUB: Position 4 is past the end of the string
warning: -(17) -> xstrsub(1): warning: -(17) -> -::xstrsub(4):
STRSUB: Position 4 is past the end of the string STRSUB: Position 4 is past the end of the string
warning: -(17) -> xstrsub(1): warning: -(17) -> -::xstrsub(4):
STRSUB: Length too big: 1 STRSUB: Length too big: 1
warning: -(20) -> xstrsub(1): warning: -(20) -> -::xstrsub(4):
STRSUB: Length too big: 10 STRSUB: Length too big: 10
A A
B B