shithub: rgbds

Download patch

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.