ref: 4877e6dbba2bcf2ba6a523e1d9048de0d4cc8e2f
parent: 3dec5698dbfc2ccab17df905c603bfc889e72c40
parent: ec171c5f00cf6577e421e28ece288221e4bae62c
author: Antonio Niño Díaz <[email protected]>
date: Tue Aug 1 15:46:58 EDT 2017
Merge pull request #196 from error-msgs Print more useful error messages when redefining symbols Signed-off-by: Antonio Niño Díaz <[email protected]>
--- a/include/asm/fstack.h
+++ b/include/asm/fstack.h
@@ -41,6 +41,8 @@
FILE *
fstk_FindFile(char *);
+int fstk_GetLine(void);
+
extern int yywrap(void);
#endif
--- a/include/asm/symbol.h
+++ b/include/asm/symbol.h
@@ -15,7 +15,9 @@
struct Section *pSection;
ULONG ulMacroSize;
char *pMacro;
- SLONG(*Callback) (struct sSymbol *);
+ SLONG(*Callback) (struct sSymbol *);
+ char tzFileName[_MAX_PATH + 1]; /* File where the symbol was defined. */
+ ULONG nFileLine; /* Line where the symbol was defined. */
};
#define SYMF_RELOC 0x001 /* symbol will be reloc'ed during
* linking, it's absolute value is
--- /dev/null
+++ b/include/common.h
@@ -1,0 +1,6 @@
+#ifndef RGBDS_COMMON_H
+#define RGBDS_COMMON_H
+
+#define RGBDS_OBJECT_VERSION_STRING "RGB5"
+
+#endif /* RGBDS_COMMON_H */
--- a/include/link/mylink.h
+++ b/include/link/mylink.h
@@ -89,6 +89,9 @@
SLONG nSectionID; /* internal to object.c */
struct sSection *pSection;
SLONG nOffset;
+ char *pzObjFileName; /* Object file where the symbol is located. */
+ char *pzFileName; /* Source file where the symbol was defined. */
+ ULONG nFileLine; /* Line where the symbol was defined. */
};
enum ePatchType {
--- a/include/link/symbol.h
+++ b/include/link/symbol.h
@@ -4,7 +4,8 @@
#include "types.h"
void sym_Init(void);
-void sym_CreateSymbol(char *tzName, SLONG nValue, SLONG nBank);
+void sym_CreateSymbol(char *tzName, SLONG nValue, SLONG nBank,
+ char *tzObjFileName, char *tzFileName, ULONG nFileLine);
SLONG sym_GetValue(char *tzName);
SLONG sym_GetBank(char *tzName);
--- a/src/asm/fstack.c
+++ b/src/asm/fstack.c
@@ -42,8 +42,8 @@
/*
* defines for nCurrentStatus
*/
-#define STAT_isInclude 0
-#define STAT_isMacro 1
+#define STAT_isInclude 0 /* 'Normal' state as well */
+#define STAT_isMacro 1
#define STAT_isMacroArg 2
#define STAT_isREPTBlock 3
@@ -149,6 +149,37 @@
return (0);
} else
return (1);
+}
+
+int
+fstk_GetLine(void)
+{
+ struct sContext *pLastFile, **ppLastFile;
+
+ switch (nCurrentStatus) {
+ case STAT_isInclude:
+ /* This is the normal mode, also used when including a file. */
+ return nLineNo;
+ case STAT_isMacro:
+ break; /* Peek top file of the stack */
+ case STAT_isMacroArg:
+ return nLineNo; /* ??? */
+ case STAT_isREPTBlock:
+ break; /* Peek top file of the stack */
+ }
+
+ if ((pLastFile = pFileStack) != NULL) {
+ ppLastFile = &pFileStack;
+ while (pLastFile->pNext) {
+ ppLastFile = &(pLastFile->pNext);
+ pLastFile = *ppLastFile;
+ }
+ return pLastFile->nLine;
+ }
+
+ /* This is only reached if the lexer is in REPT or MACRO mode but there
+ * are no saved contexts with the origin of said REPT or MACRO. */
+ fatalerror("fstk_GetLine: Internal error.");
}
int
--- a/src/asm/output.c
+++ b/src/asm/output.c
@@ -15,6 +15,7 @@
#include "asm/main.h"
#include "asm/rpn.h"
#include "asm/fstack.h"
+#include "common.h"
#include "extern/err.h"
void out_SetCurrentSection(struct Section * pSect);
@@ -282,6 +283,9 @@
fputc(type, f);
if (type != SYM_IMPORT) {
+ fputstring(pSym->tzFileName, f);
+ fputlong(pSym->nFileLine, f);
+
fputlong(sectid, f);
fputlong(offset, f);
}
@@ -501,7 +505,9 @@
struct PatchSymbol *pSym;
struct Section *pSect;
- fwrite("RGB4", 1, 4, f);
+ fwrite(RGBDS_OBJECT_VERSION_STRING, 1,
+ strlen(RGBDS_OBJECT_VERSION_STRING), f);
+
fputlong(countsymbols(), f);
fputlong(countsections(), f);
--- a/src/asm/rgbasm.5
+++ b/src/asm/rgbasm.5
@@ -12,7 +12,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd April 17, 2017
+.Dd July 22, 2017
.Dt RGBASM 5
.Os RGBDS Manual
.Sh NAME
--- a/src/asm/symbol.c
+++ b/src/asm/symbol.c
@@ -8,6 +8,7 @@
#include <time.h>
#include "asm/asm.h"
+#include "asm/fstack.h"
#include "asm/symbol.h"
#include "asm/main.h"
#include "asm/mymath.h"
@@ -109,6 +110,8 @@
(*ppsym)->pMacro = NULL;
(*ppsym)->pSection = NULL;
(*ppsym)->Callback = NULL;
+ strcpy((*ppsym)->tzFileName, tzCurrentFileName);
+ (*ppsym)->nFileLine = fstk_GetLine();
return (*ppsym);
} else {
fatalerror("No memory for symbol");
@@ -518,7 +521,8 @@
if ((nsym = findsymbol(tzSym, NULL)) != NULL) {
if (nsym->nType & SYMF_DEFINED) {
- yyerror("'%s' already defined", tzSym);
+ yyerror("'%s' already defined in %s(%d)",
+ tzSym, nsym->tzFileName, nsym->nFileLine);
}
} else
nsym = createsymbol(tzSym);
@@ -550,7 +554,8 @@
if ((nsym = findsymbol(tzSym, NULL)) != NULL) {
if (nsym->nType & SYMF_DEFINED) {
- yyerror("'%s' already defined", tzSym);
+ yyerror("'%s' already defined in %s(%d)",
+ tzSym, nsym->tzFileName, nsym->nFileLine);
}
} else
nsym = createsymbol(tzSym);
@@ -653,7 +658,8 @@
if ((nsym = findsymbol(tzSym, scope)) != NULL) {
if (nsym->nType & SYMF_DEFINED) {
- yyerror("'%s' already defined", tzSym);
+ yyerror("'%s' already defined in %s(%d)",
+ tzSym, nsym->tzFileName, nsym->nFileLine);
}
} else
nsym = createsymbol(tzSym);
@@ -782,7 +788,8 @@
if ((nsym = findsymbol(tzSym, NULL)) != NULL) {
if (nsym->nType & SYMF_DEFINED) {
- yyerror("'%s' already defined", tzSym);
+ yyerror("'%s' already defined in %s(%d)",
+ tzSym, nsym->tzFileName, nsym->nFileLine);
}
} else
nsym = createsymbol(tzSym);
--- a/src/link/assign.c
+++ b/src/link/assign.c
@@ -566,16 +566,21 @@
((pSect->tSymbols[i]->pSection == pSect) ||
(pSect->tSymbols[i]->pSection == NULL))) {
if (pSect->tSymbols[i]->pSection == NULL)
- sym_CreateSymbol(pSect->tSymbols[i]->
- pzName,
- pSect->tSymbols[i]->
- nOffset, -1);
+ sym_CreateSymbol(
+ pSect->tSymbols[i]->pzName,
+ pSect->tSymbols[i]->nOffset,
+ -1,
+ pSect->tSymbols[i]->pzObjFileName,
+ pSect->tSymbols[i]->pzFileName,
+ pSect->tSymbols[i]->nFileLine);
else
- sym_CreateSymbol(pSect->tSymbols[i]->
- pzName,
- pSect->nOrg +
- pSect->tSymbols[i]->
- nOffset, pSect->nBank);
+ sym_CreateSymbol(
+ pSect->tSymbols[i]->pzName,
+ pSect->nOrg + pSect->tSymbols[i]->nOffset,
+ pSect->nBank,
+ pSect->tSymbols[i]->pzObjFileName,
+ pSect->tSymbols[i]->pzFileName,
+ pSect->tSymbols[i]->nFileLine);
}
}
pSect = pSect->pNext;
--- a/src/link/object.c
+++ b/src/link/object.c
@@ -3,11 +3,13 @@
*
*/
+#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "common.h"
#include "extern/err.h"
#include "link/assign.h"
#include "link/mylink.h"
@@ -116,7 +118,7 @@
*/
struct sSymbol *
-obj_ReadSymbol(FILE * f)
+obj_ReadSymbol(FILE * f, char *tzObjectfile)
{
struct sSymbol *pSym;
@@ -126,7 +128,14 @@
}
readasciiz(&pSym->pzName, f);
- if ((pSym->Type = (enum eSymbolType) fgetc(f)) != SYM_IMPORT) {
+ pSym->Type = (enum eSymbolType)fgetc(f);
+
+ pSym->pzObjFileName = tzObjectfile;
+
+ if (pSym->Type != SYM_IMPORT) {
+ readasciiz(&pSym->pzFileName, f);
+ pSym->nFileLine = readlong(f);
+
pSym->nSectionID = readlong(f);
pSym->nOffset = readlong(f);
}
@@ -263,7 +272,7 @@
}
void
-obj_ReadRGB(FILE * pObjfile)
+obj_ReadRGB(FILE * pObjfile, char *tzObjectfile)
{
struct sSection *pFirstSection;
SLONG nNumberOfSymbols, nNumberOfSections, i;
@@ -280,7 +289,7 @@
}
for (i = 0; i < nNumberOfSymbols; i += 1)
- tSymbols[i] = obj_ReadSymbol(pObjfile);
+ tSymbols[i] = obj_ReadSymbol(pObjfile, tzObjectfile);
} else
tSymbols = (struct sSymbol **) & dummymem;
@@ -325,21 +334,22 @@
void
obj_ReadOpenFile(FILE * pObjfile, char *tzObjectfile)
{
- char tzHeader[8];
+ char tzHeader[strlen(RGBDS_OBJECT_VERSION_STRING) + 1];
- fread(tzHeader, sizeof(char), 4, pObjfile);
- tzHeader[4] = 0;
- if (strncmp(tzHeader, "RGB", 3) == 0) {
- switch (tzHeader[3]) {
- case '3':
- case '4': // V4 supports OAM sections, but is otherwise identical
- obj_ReadRGB(pObjfile);
- break;
- default:
- errx(1, "'%s' uses an unsupported object file version (%s). Please reassemble it.", tzObjectfile, tzHeader);
- }
+ fread(tzHeader, sizeof(char), strlen(RGBDS_OBJECT_VERSION_STRING),
+ pObjfile);
+
+ tzHeader[strlen(RGBDS_OBJECT_VERSION_STRING)] = 0;
+
+ if (strncmp(tzHeader, RGBDS_OBJECT_VERSION_STRING,
+ strlen(RGBDS_OBJECT_VERSION_STRING)) == 0) {
+ obj_ReadRGB(pObjfile, tzObjectfile);
} else {
- errx(1, "'%s' is not a valid object", tzObjectfile);
+ for (int i = 0; i < strlen(RGBDS_OBJECT_VERSION_STRING); i++)
+ if (!isprint(tzHeader[i]))
+ tzHeader[i] = '?';
+ errx(1, "%s: Invalid file or object file version [%s]",
+ tzObjectfile, tzHeader);
}
}
--- a/src/link/symbol.c
+++ b/src/link/symbol.c
@@ -12,8 +12,10 @@
struct ISymbol {
char *pzName;
SLONG nValue;
- SLONG nBank;
- //-1 = const
+ SLONG nBank; /* -1 = constant */
+ char tzObjFileName[_MAX_PATH + 1]; /* Object file where the symbol was defined. */
+ char tzFileName[_MAX_PATH + 1]; /* Source file where the symbol was defined. */
+ ULONG nFileLine; /* Line where the symbol was defined. */
struct ISymbol *pNext;
};
@@ -76,7 +78,8 @@
}
void
-sym_CreateSymbol(char *tzName, SLONG nValue, SLONG nBank)
+sym_CreateSymbol(char *tzName, SLONG nValue, SLONG nBank, char *tzObjFileName,
+ char *tzFileName, ULONG nFileLine)
{
if (strcmp(tzName, "@") == 0)
return;
@@ -92,7 +95,10 @@
if (nBank == -1)
return;
- errx(1, "Symbol '%s' defined more than once", tzName);
+ errx(1, "'%s' in both %s : %s(%d) and %s : %s(%d)",
+ tzName, tzObjFileName, tzFileName, nFileLine,
+ (*ppSym)->tzObjFileName,
+ (*ppSym)->tzFileName, (*ppSym)->nFileLine);
}
}
@@ -102,6 +108,11 @@
(*ppSym)->nValue = nValue;
(*ppSym)->nBank = nBank;
(*ppSym)->pNext = NULL;
+ strncpy((*ppSym)->tzObjFileName, tzObjFileName,
+ sizeof((*ppSym)->tzObjFileName));
+ strncpy((*ppSym)->tzFileName, tzFileName,
+ sizeof((*ppSym)->tzFileName));
+ (*ppSym)->nFileLine = nFileLine;
}
}
}
--- a/src/rgbds.5
+++ b/src/rgbds.5
@@ -12,7 +12,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd April 17, 2017
+.Dd July 22, 2017
.Dt RGBDS 5
.Os RGBDS Manual
.Sh NAME
@@ -42,7 +42,7 @@
.Bd -literal
; Header
-BYTE ID[4] ; "RGB4"
+BYTE ID[4] ; "RGB5"
LONG NumberOfSymbols ; The number of symbols used in this file
LONG NumberOfSections ; The number of sections used in this file
@@ -58,6 +58,10 @@
; 2 = EXPORT this symbol to other objects.
IF Type != 1 ; If symbol is defined in this object file.
+
+ STRING FileName ; File where the symbol is defined.
+
+ LONG LineNum ; Line number in the file where the symbol is defined.
LONG SectionID ; The section number (of this object file) in which
; this symbol is defined.