Support colors in diagnostic output.
This commit is contained in:
@@ -71,7 +71,7 @@ unsigned WarningCount = 0;
|
||||
typedef enum { DC_NOTE, DC_WARN, DC_ERR, DC_FATAL, DC_COUNT } DiagCat;
|
||||
|
||||
/* Descriptions for diagnostic categories */
|
||||
const char* DiagCatDesc[DC_COUNT] = {
|
||||
static const char* DiagCatDesc[DC_COUNT] = {
|
||||
"Note", "Warning", "Error", "Fatal error"
|
||||
};
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ void CheckAssertions (void)
|
||||
|
||||
/* If the expression is not constant, we're not able to handle it */
|
||||
if (!IsConstExpr (A->Expr)) {
|
||||
Warning ("Cannot evaluate assertion in module '%s', line %u",
|
||||
Warning ("Cannot evaluate assertion in module `%s', line %u",
|
||||
Module, Line);
|
||||
} else if (GetExprVal (A->Expr) == 0) {
|
||||
|
||||
|
||||
@@ -301,11 +301,11 @@ void BinWriteTarget (BinDesc* D, struct File* F)
|
||||
/* Open the file */
|
||||
D->F = fopen (D->Filename, "wb");
|
||||
if (D->F == 0) {
|
||||
Error ("Cannot open '%s': %s", D->Filename, strerror (errno));
|
||||
Error ("Cannot open `%s': %s", D->Filename, strerror (errno));
|
||||
}
|
||||
|
||||
/* Keep the user happy */
|
||||
Print (stdout, 1, "Opened '%s'...\n", D->Filename);
|
||||
Print (stdout, 1, "Opened `%s'...\n", D->Filename);
|
||||
|
||||
/* Dump all memory areas */
|
||||
for (I = 0; I < CollCount (&F->MemoryAreas); ++I) {
|
||||
@@ -317,7 +317,7 @@ void BinWriteTarget (BinDesc* D, struct File* F)
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (D->F) != 0) {
|
||||
Error ("Cannot write to '%s': %s", D->Filename, strerror (errno));
|
||||
Error ("Cannot write to `%s': %s", D->Filename, strerror (errno));
|
||||
}
|
||||
|
||||
/* Reset the file and filename */
|
||||
|
||||
@@ -105,7 +105,7 @@ static ExprNode* Factor (void)
|
||||
/* Left parenthesis */
|
||||
CfgNextTok ();
|
||||
N = CfgExpr ();
|
||||
CfgConsume (CFGTOK_RPAR, "')' expected");
|
||||
CfgConsume (CFGTOK_RPAR, "`)' expected");
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -228,7 +228,7 @@ static MemoryArea* CfgGetMemory (unsigned Name)
|
||||
{
|
||||
MemoryArea* M = CfgFindMemory (Name);
|
||||
if (M == 0) {
|
||||
CfgError (&CfgErrorPos, "Invalid memory area '%s'", GetString (Name));
|
||||
CfgError (&CfgErrorPos, "Invalid memory area `%s'", GetString (Name));
|
||||
}
|
||||
return M;
|
||||
}
|
||||
@@ -322,7 +322,7 @@ static MemoryArea* CreateMemoryArea (const FilePos* Pos, unsigned Name)
|
||||
MemoryArea* M = CfgFindMemory (Name);
|
||||
if (M) {
|
||||
CfgError (&CfgErrorPos,
|
||||
"Memory area '%s' defined twice",
|
||||
"Memory area `%s' defined twice",
|
||||
GetString (Name));
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ static SegDesc* NewSegDesc (unsigned Name)
|
||||
/* Check for duplicate names */
|
||||
SegDesc* S = CfgFindSegDesc (Name);
|
||||
if (S) {
|
||||
CfgError (&CfgErrorPos, "Segment '%s' defined twice", GetString (Name));
|
||||
CfgError (&CfgErrorPos, "Segment `%s' defined twice", GetString (Name));
|
||||
}
|
||||
|
||||
/* Allocate memory */
|
||||
@@ -391,7 +391,7 @@ static void FlagAttr (unsigned* Flags, unsigned Mask, const char* Name)
|
||||
*/
|
||||
{
|
||||
if (*Flags & Mask) {
|
||||
CfgError (&CfgErrorPos, "%s is already defined", Name);
|
||||
CfgError (&CfgErrorPos, "Attribute `%s' is already defined", Name);
|
||||
}
|
||||
*Flags |= Mask;
|
||||
}
|
||||
@@ -402,7 +402,7 @@ static void AttrCheck (unsigned Attr, unsigned Mask, const char* Name)
|
||||
/* Check that a mandatory attribute was given */
|
||||
{
|
||||
if ((Attr & Mask) == 0) {
|
||||
CfgError (&CfgErrorPos, "%s attribute is missing", Name);
|
||||
CfgError (&CfgErrorPos, "Mandatory attribute `%s' is missing", Name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -569,7 +569,7 @@ static void ParseFiles (void)
|
||||
F = FindFile (GetStrBufId (&CfgSVal));
|
||||
if (F == 0) {
|
||||
CfgError (&CfgErrorPos,
|
||||
"File '%s' not found in MEMORY section",
|
||||
"File `%s' not found in MEMORY section",
|
||||
SB_GetConstBuf (&CfgSVal));
|
||||
}
|
||||
|
||||
@@ -805,7 +805,7 @@ static void ParseSegments (void)
|
||||
*/
|
||||
if ((S->Flags & SF_BSS) != 0 && (S->Load != S->Run)) {
|
||||
CfgWarning (&CfgErrorPos,
|
||||
"Segment with type 'bss' has both LOAD and RUN "
|
||||
"Segment with type `bss' has both LOAD and RUN "
|
||||
"memory areas assigned");
|
||||
}
|
||||
|
||||
@@ -813,7 +813,7 @@ static void ParseSegments (void)
|
||||
if ((S->Flags & SF_RO) == 0) {
|
||||
if (S->Run->Flags & MF_RO) {
|
||||
CfgError (&CfgErrorPos,
|
||||
"Cannot put r/w segment '%s' in r/o memory area '%s'",
|
||||
"Cannot put r/w segment `%s' in r/o memory area `%s'",
|
||||
GetString (S->Name), GetString (S->Run->Name));
|
||||
}
|
||||
}
|
||||
@@ -1611,7 +1611,7 @@ static void ParseConfig (void)
|
||||
CfgNextTok ();
|
||||
|
||||
/* Expected a curly brace */
|
||||
CfgConsume (CFGTOK_LCURLY, "'{' expected");
|
||||
CfgConsume (CFGTOK_LCURLY, "`{' expected");
|
||||
|
||||
/* Read the block */
|
||||
switch (BlockTok) {
|
||||
@@ -1646,7 +1646,7 @@ static void ParseConfig (void)
|
||||
}
|
||||
|
||||
/* Skip closing brace */
|
||||
CfgConsume (CFGTOK_RCURLY, "'}' expected");
|
||||
CfgConsume (CFGTOK_RCURLY, "`}' expected");
|
||||
|
||||
} while (CfgTok != CFGTOK_EOF);
|
||||
}
|
||||
@@ -1704,7 +1704,7 @@ static void ProcessSegments (void)
|
||||
*/
|
||||
if ((S->Flags & SF_BSS) != 0 && S->Seg != 0 && !IsBSSType (S->Seg)) {
|
||||
CfgWarning (GetSourcePos (S->LI),
|
||||
"Segment '%s' with type 'bss' contains initialized data",
|
||||
"Segment `%s' with type `bss' contains initialized data",
|
||||
GetString (S->Name));
|
||||
}
|
||||
|
||||
@@ -1733,7 +1733,7 @@ static void ProcessSegments (void)
|
||||
/* Print a warning if the segment is not optional */
|
||||
if ((S->Flags & SF_OPTIONAL) == 0) {
|
||||
CfgWarning (&CfgErrorPos,
|
||||
"Segment '%s' does not exist",
|
||||
"Segment `%s' does not exist",
|
||||
GetString (S->Name));
|
||||
}
|
||||
|
||||
@@ -1766,7 +1766,7 @@ static void ProcessSymbols (void)
|
||||
if (O65GetImport (O65FmtDesc, Sym->Name) != 0) {
|
||||
CfgError (
|
||||
GetSourcePos (Sym->LI),
|
||||
"Exported o65 symbol '%s' cannot also be an o65 import",
|
||||
"Exported o65 symbol `%s' cannot also be an o65 import",
|
||||
GetString (Sym->Name)
|
||||
);
|
||||
}
|
||||
@@ -1778,7 +1778,7 @@ static void ProcessSymbols (void)
|
||||
if (O65GetExport (O65FmtDesc, Sym->Name) != 0) {
|
||||
CfgError (
|
||||
GetSourcePos (Sym->LI),
|
||||
"Duplicate exported o65 symbol: '%s'",
|
||||
"Duplicate exported o65 symbol: `%s'",
|
||||
GetString (Sym->Name)
|
||||
);
|
||||
}
|
||||
@@ -1792,7 +1792,7 @@ static void ProcessSymbols (void)
|
||||
if (O65GetExport (O65FmtDesc, Sym->Name) != 0) {
|
||||
CfgError (
|
||||
GetSourcePos (Sym->LI),
|
||||
"Imported o65 symbol '%s' cannot also be an o65 export",
|
||||
"Imported o65 symbol `%s' cannot also be an o65 export",
|
||||
GetString (Sym->Name)
|
||||
);
|
||||
}
|
||||
@@ -1804,7 +1804,7 @@ static void ProcessSymbols (void)
|
||||
if (O65GetImport (O65FmtDesc, Sym->Name) != 0) {
|
||||
CfgError (
|
||||
GetSourcePos (Sym->LI),
|
||||
"Duplicate imported o65 symbol: '%s'",
|
||||
"Duplicate imported o65 symbol: `%s'",
|
||||
GetString (Sym->Name)
|
||||
);
|
||||
}
|
||||
@@ -1914,7 +1914,7 @@ unsigned CfgProcess (void)
|
||||
*/
|
||||
if (!IsConstExpr (M->StartExpr)) {
|
||||
CfgError (GetSourcePos (M->LI),
|
||||
"Start address of memory area '%s' is not constant",
|
||||
"Start address of memory area `%s' is not constant",
|
||||
GetString (M->Name));
|
||||
}
|
||||
Addr = M->Start = GetExprVal (M->StartExpr);
|
||||
@@ -1939,13 +1939,13 @@ unsigned CfgProcess (void)
|
||||
/* Resolve the size expression */
|
||||
if (!IsConstExpr (M->SizeExpr)) {
|
||||
CfgError (GetSourcePos (M->LI),
|
||||
"Size of memory area '%s' is not constant",
|
||||
"Size of memory area `%s' is not constant",
|
||||
GetString (M->Name));
|
||||
}
|
||||
M->Size = GetExprVal (M->SizeExpr);
|
||||
if (M->Size >= 0x80000000) {
|
||||
CfgError (GetSourcePos (M->LI),
|
||||
"Size of memory area '%s' is negative: %ld",
|
||||
"Size of memory area `%s' is negative: %ld",
|
||||
GetString (M->Name), (long)M->Size);
|
||||
}
|
||||
|
||||
@@ -1969,15 +1969,15 @@ unsigned CfgProcess (void)
|
||||
++Overwrites;
|
||||
} else {
|
||||
CfgError (GetSourcePos (M->LI),
|
||||
"Segment '%s' of type 'overwrite' requires either"
|
||||
" 'Start' or 'Offset' attribute to be specified",
|
||||
"Segment `%s' of type `overwrite' requires either"
|
||||
" `START' or `OFFSET' attribute to be specified",
|
||||
GetString (S->Name));
|
||||
}
|
||||
} else {
|
||||
if (Overwrites > 0) {
|
||||
CfgError (GetSourcePos (M->LI),
|
||||
"Segment '%s' is preceded by at least one segment"
|
||||
" of type 'overwrite'",
|
||||
"Segment `%s' is preceded by at least one segment"
|
||||
" of type `overwrite'",
|
||||
GetString (S->Name));
|
||||
}
|
||||
}
|
||||
@@ -2003,7 +2003,7 @@ unsigned CfgProcess (void)
|
||||
** in the linker.
|
||||
*/
|
||||
CfgWarning (GetSourcePos (S->LI),
|
||||
"Segment '%s' isn't aligned properly; the"
|
||||
"Segment `%s' isn't aligned properly; the"
|
||||
" resulting executable might not be functional.",
|
||||
GetString (S->Name));
|
||||
}
|
||||
@@ -2018,7 +2018,7 @@ unsigned CfgProcess (void)
|
||||
*/
|
||||
if (M->FillLevel == 0 && NewAddr > Addr) {
|
||||
CfgWarning (GetSourcePos (S->LI),
|
||||
"The first segment in memory area '%s' "
|
||||
"The first segment in memory area `%s' "
|
||||
"needs fill bytes for alignment.",
|
||||
GetString (M->Name));
|
||||
}
|
||||
@@ -2039,7 +2039,7 @@ unsigned CfgProcess (void)
|
||||
if (S->Flags & SF_OVERWRITE) {
|
||||
if (NewAddr < M->Start) {
|
||||
CfgError (GetSourcePos (S->LI),
|
||||
"Segment '%s' begins before memory area '%s'",
|
||||
"Segment `%s' begins before memory area `%s'",
|
||||
GetString (S->Name), GetString (M->Name));
|
||||
} else {
|
||||
Addr = NewAddr;
|
||||
@@ -2050,12 +2050,12 @@ unsigned CfgProcess (void)
|
||||
++Overflows;
|
||||
if (S->Flags & SF_OFFSET) {
|
||||
CfgWarning (GetSourcePos (S->LI),
|
||||
"Segment '%s' offset is too small in '%s' by %lu byte%s",
|
||||
"Segment `%s' offset is too small in `%s' by %lu byte%s",
|
||||
GetString (S->Name), GetString (M->Name),
|
||||
Addr - NewAddr, (Addr - NewAddr == 1) ? "" : "s");
|
||||
} else {
|
||||
CfgWarning (GetSourcePos (S->LI),
|
||||
"Segment '%s' start address is too low in '%s' by %lu byte%s",
|
||||
"Segment `%s' start address is too low in `%s' by %lu byte%s",
|
||||
GetString (S->Name), GetString (M->Name),
|
||||
Addr - NewAddr, (Addr - NewAddr == 1) ? "" : "s");
|
||||
}
|
||||
@@ -2102,7 +2102,7 @@ unsigned CfgProcess (void)
|
||||
++Overflows;
|
||||
M->Flags |= MF_OVERFLOW;
|
||||
CfgWarning (GetSourcePos (M->LI),
|
||||
"Segment '%s' overflows memory area '%s' by %lu byte%s",
|
||||
"Segment `%s' overflows memory area `%s' by %lu byte%s",
|
||||
GetString (S->Name), GetString (M->Name),
|
||||
FillLevel - M->Size, (FillLevel - M->Size == 1) ? "" : "s");
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ void CreateDbgFile (void)
|
||||
/* Open the debug info file */
|
||||
FILE* F = fopen (DbgFileName, "w");
|
||||
if (F == 0) {
|
||||
Error ("Cannot create debug file '%s': %s", DbgFileName, strerror (errno));
|
||||
Error ("Cannot create debug file `%s': %s", DbgFileName, strerror (errno));
|
||||
}
|
||||
|
||||
/* Output version information */
|
||||
@@ -166,6 +166,6 @@ void CreateDbgFile (void)
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (F) != 0) {
|
||||
Error ("Error closing debug file '%s': %s", DbgFileName, strerror (errno));
|
||||
Error ("Error closing debug file `%s': %s", DbgFileName, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
295
src/ld65/error.c
295
src/ld65/error.c
@@ -39,6 +39,8 @@
|
||||
|
||||
/* common */
|
||||
#include "cmdline.h"
|
||||
#include "coll.h"
|
||||
#include "consprop.h"
|
||||
#include "strbuf.h"
|
||||
|
||||
/* ld65 */
|
||||
@@ -56,6 +58,22 @@
|
||||
/* Statistics */
|
||||
unsigned WarningCount = 0;
|
||||
|
||||
/* Diagnostic category. */
|
||||
typedef enum { DC_NOTE, DC_WARN, DC_ERR, DC_INT, DC_COUNT } DiagCat;
|
||||
|
||||
/* Descriptions for diagnostic categories */
|
||||
const char* DiagCatDesc[DC_COUNT] = {
|
||||
"Note", "Warning", "Error", "Internal error"
|
||||
};
|
||||
|
||||
/* An empty file position used when diagnostics aren't related to a file */
|
||||
static FilePos NoFile = STATIC_FILEPOS_INITIALIZER;
|
||||
|
||||
/* Notifications. They are remembered here and output with the next call to
|
||||
** Error() or Warning().
|
||||
*/
|
||||
static Collection Notes = STATIC_COLLECTION_INITIALIZER;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -64,20 +82,213 @@ unsigned WarningCount = 0;
|
||||
|
||||
|
||||
|
||||
static void ReplaceQuotes (StrBuf* Msg)
|
||||
/* Replace opening and closing single quotes in Msg by their typographically
|
||||
** correct UTF-8 counterparts for better readbility. A closing quote will
|
||||
** only get replaced if an opening quote has been seen before.
|
||||
** To handle some special cases, the function will also treat \xF0 as
|
||||
** opening and \xF1 as closing quote. These are replaced without the need for
|
||||
** correct ordering (open/close).
|
||||
** The function will change the quotes in place, so after the call Msg will
|
||||
** contain the changed string. If UTF-8 is not available, the function will
|
||||
** replace '`' by '\'' since that was the default behavior before. It will
|
||||
** also replace \xF0 and \xF1 by '\''.
|
||||
*/
|
||||
{
|
||||
/* UTF-8 characters for single quotes */
|
||||
static const char QuoteStart[] = "\xE2\x80\x98";
|
||||
static const char QuoteEnd[] = "\xE2\x80\x99";
|
||||
|
||||
/* ANSI color sequences */
|
||||
const char* ColorStart = CP_BrightGreen ();
|
||||
const char* ColorEnd = CP_White ();
|
||||
|
||||
/* Remember a few things */
|
||||
int IsUTF8 = CP_IsUTF8 ();
|
||||
|
||||
/* We create a new string in T and will later copy it back to Msg */
|
||||
StrBuf T = AUTO_STRBUF_INITIALIZER;
|
||||
|
||||
/* Parse the string and create a modified copy */
|
||||
SB_Reset (Msg);
|
||||
int InQuote = 0;
|
||||
while (1) {
|
||||
char C = SB_Get (Msg);
|
||||
switch (C) {
|
||||
case '`':
|
||||
if (!InQuote) {
|
||||
InQuote = 1;
|
||||
if (IsUTF8) {
|
||||
SB_AppendStr (&T, QuoteStart);
|
||||
} else {
|
||||
/* ca65 uses \' for opening and closing quotes */
|
||||
SB_AppendChar (&T, '\'');
|
||||
}
|
||||
SB_AppendStr (&T, ColorStart);
|
||||
} else {
|
||||
/* Found two ` without closing quote - don't replace */
|
||||
SB_AppendChar (&T, '`');
|
||||
}
|
||||
break;
|
||||
case '\'':
|
||||
if (InQuote) {
|
||||
InQuote = 0;
|
||||
SB_AppendStr (&T, ColorEnd);
|
||||
if (IsUTF8) {
|
||||
SB_AppendStr (&T, QuoteEnd);
|
||||
} else {
|
||||
SB_AppendChar (&T, C);
|
||||
}
|
||||
} else {
|
||||
SB_AppendChar (&T, C);
|
||||
}
|
||||
break;
|
||||
case '\xF0':
|
||||
if (IsUTF8) {
|
||||
SB_AppendStr (&T, QuoteStart);
|
||||
} else {
|
||||
SB_AppendChar (&T, '\'');
|
||||
}
|
||||
break;
|
||||
case '\xF1':
|
||||
if (IsUTF8) {
|
||||
SB_AppendStr (&T, QuoteEnd);
|
||||
} else {
|
||||
SB_AppendChar (&T, '\'');
|
||||
}
|
||||
break;
|
||||
case '\0':
|
||||
goto Done;
|
||||
default:
|
||||
SB_AppendChar (&T, C);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Done:
|
||||
/* Copy the string back, then terminate it */
|
||||
SB_Move (Msg, &T);
|
||||
SB_Terminate (Msg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void VPrepMsg (StrBuf* S, const FilePos* Pos, DiagCat Cat,
|
||||
const char* Format, va_list ap)
|
||||
/* Prepare an error/warning/notification message in S. */
|
||||
{
|
||||
StrBuf Msg = AUTO_STRBUF_INITIALIZER;
|
||||
StrBuf Loc = AUTO_STRBUF_INITIALIZER;
|
||||
|
||||
/* Determine the description for the category and its color */
|
||||
const char* Desc = DiagCatDesc[Cat];
|
||||
const char* Color;
|
||||
switch (Cat) {
|
||||
case DC_NOTE: Color = CP_Cyan (); break;
|
||||
case DC_WARN: Color = CP_Yellow (); break;
|
||||
case DC_ERR: Color = CP_BrightRed (); break;
|
||||
case DC_INT: Color = CP_BrightRed (); break;
|
||||
default: FAIL ("Unexpected Cat value"); break;
|
||||
}
|
||||
|
||||
/* Format the actual message, then replace quotes */
|
||||
SB_VPrintf (&Msg, Format, ap);
|
||||
ReplaceQuotes (&Msg);
|
||||
|
||||
/* Format the location. If the file position is valid, we use the file
|
||||
** position, otherwise the program name. This allows to print fatal
|
||||
** errors in the startup phase.
|
||||
*/
|
||||
if (Pos->Name == INVALID_STRING_ID) {
|
||||
SB_CopyStr (&Loc, ProgName);
|
||||
} else {
|
||||
SB_Printf (&Loc, "%s:%u", GetString (Pos->Name), Pos->Line);
|
||||
}
|
||||
SB_Terminate (&Loc);
|
||||
|
||||
/* Format the full message */
|
||||
SB_Printf (S, "%s%s: %s%s:%s %s%s",
|
||||
CP_White (),
|
||||
SB_GetConstBuf (&Loc),
|
||||
Color,
|
||||
Desc,
|
||||
CP_White (),
|
||||
SB_GetConstBuf (&Msg),
|
||||
CP_Reset ());
|
||||
|
||||
/* Delete the formatted message and the location string */
|
||||
SB_Done (&Loc);
|
||||
SB_Done (&Msg);
|
||||
|
||||
/* Add a new line and terminate the generated full message */
|
||||
SB_AppendChar (S, '\n');
|
||||
SB_Terminate (S);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void VPrintMsg (const FilePos* Pos, DiagCat Cat, const char* Format,
|
||||
va_list ap)
|
||||
/* Format and output an error/warning message. */
|
||||
{
|
||||
/* Format the message */
|
||||
StrBuf S = AUTO_STRBUF_INITIALIZER;
|
||||
VPrepMsg (&S, Pos, Cat, Format, ap);
|
||||
|
||||
/* Output the full message */
|
||||
fputs (SB_GetConstBuf (&S), stderr);
|
||||
|
||||
/* Delete the buffer for the full message */
|
||||
SB_Done (&S);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OutputNotes (void)
|
||||
/* Output all stored notification messages, then delete them */
|
||||
{
|
||||
unsigned I;
|
||||
for (I = 0; I < CollCount (&Notes); ++I) {
|
||||
StrBuf* S = CollAtUnchecked (&Notes, I);
|
||||
fputs (SB_GetConstBuf (S), stderr);
|
||||
FreeStrBuf (S);
|
||||
}
|
||||
CollDeleteAll (&Notes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddNote (const char* Format, ...)
|
||||
/* Add a notification message that will be output after the next error or
|
||||
** warning. There cannot be a Notification() function since Error() will
|
||||
** always terminate.
|
||||
*/
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
/* Create a new string buffer and add it to the notes */
|
||||
StrBuf* S = NewStrBuf ();
|
||||
CollAppend (&Notes, S);
|
||||
|
||||
/* Create the message in the string buffer */
|
||||
va_start (ap, Format);
|
||||
VPrepMsg (S, &NoFile, DC_NOTE, Format, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Warning (const char* Format, ...)
|
||||
/* Print a warning message */
|
||||
{
|
||||
StrBuf S = STATIC_STRBUF_INITIALIZER;
|
||||
/* Output the message */
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, Format);
|
||||
SB_VPrintf (&S, Format, ap);
|
||||
VPrintMsg (&NoFile, DC_WARN, Format, ap);
|
||||
va_end (ap);
|
||||
SB_Terminate (&S);
|
||||
|
||||
fprintf (stderr, "%s: Warning: %s\n", ProgName, SB_GetConstBuf (&S));
|
||||
|
||||
SB_Done (&S);
|
||||
/* Output all stored notes */
|
||||
OutputNotes ();
|
||||
|
||||
/* Count warnings */
|
||||
++WarningCount;
|
||||
@@ -88,18 +299,16 @@ void Warning (const char* Format, ...)
|
||||
void Error (const char* Format, ...)
|
||||
/* Print an error message and die */
|
||||
{
|
||||
StrBuf S = STATIC_STRBUF_INITIALIZER;
|
||||
/* Output the message */
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, Format);
|
||||
SB_VPrintf (&S, Format, ap);
|
||||
VPrintMsg (&NoFile, DC_ERR, Format, ap);
|
||||
va_end (ap);
|
||||
SB_Terminate (&S);
|
||||
|
||||
fprintf (stderr, "%s: Error: %s\n", ProgName, SB_GetConstBuf (&S));
|
||||
|
||||
SB_Done (&S);
|
||||
/* Output all stored notes */
|
||||
OutputNotes ();
|
||||
|
||||
/* Terminate after errors */
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -108,19 +317,33 @@ void Error (const char* Format, ...)
|
||||
void Internal (const char* Format, ...)
|
||||
/* Print an internal error message and die */
|
||||
{
|
||||
StrBuf S = STATIC_STRBUF_INITIALIZER;
|
||||
/* Output the message */
|
||||
va_list ap;
|
||||
va_start (ap, Format);
|
||||
VPrintMsg (&NoFile, DC_INT, Format, ap);
|
||||
va_end (ap);
|
||||
|
||||
/* Terminate after errors */
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddCfgNote (const FilePos* Pos, const char* Format, ...)
|
||||
/* Add a notifcation message using file name and line number of the config file.
|
||||
** See comment for AddNote() above.
|
||||
*/
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
/* Create a new string buffer and add it to the notes */
|
||||
StrBuf* S = NewStrBuf ();
|
||||
CollAppend (&Notes, S);
|
||||
|
||||
/* Create the message in the string buffer */
|
||||
va_start (ap, Format);
|
||||
SB_VPrintf (&S, Format, ap);
|
||||
VPrepMsg (S, Pos, DC_NOTE, Format, ap);
|
||||
va_end (ap);
|
||||
SB_Terminate (&S);
|
||||
|
||||
fprintf (stderr, "%s: Internal Error: %s\n", ProgName, SB_GetConstBuf (&S));
|
||||
|
||||
SB_Done (&S);
|
||||
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
@@ -128,16 +351,14 @@ void Internal (const char* Format, ...)
|
||||
void CfgWarning (const FilePos* Pos, const char* Format, ...)
|
||||
/* Print a warning message adding file name and line number of a given file */
|
||||
{
|
||||
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
|
||||
/* Output the message */
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, Format);
|
||||
SB_VPrintf (&Buf, Format, ap);
|
||||
VPrintMsg (Pos, DC_WARN, Format, ap);
|
||||
va_end (ap);
|
||||
|
||||
Warning ("%s:%u: %s",
|
||||
GetString (Pos->Name), Pos->Line, SB_GetConstBuf (&Buf));
|
||||
SB_Done (&Buf);
|
||||
/* Output all stored notes */
|
||||
OutputNotes ();
|
||||
|
||||
/* Count warnings */
|
||||
++WarningCount;
|
||||
@@ -148,17 +369,15 @@ void CfgWarning (const FilePos* Pos, const char* Format, ...)
|
||||
void CfgError (const FilePos* Pos, const char* Format, ...)
|
||||
/* Print an error message adding file name and line number of a given file */
|
||||
{
|
||||
StrBuf Buf = STATIC_STRBUF_INITIALIZER;
|
||||
/* Output the message */
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, Format);
|
||||
SB_VPrintf (&Buf, Format, ap);
|
||||
VPrintMsg (Pos, DC_ERR, Format, ap);
|
||||
va_end (ap);
|
||||
|
||||
Error ("%s:%u: %s",
|
||||
GetString (Pos->Name), Pos->Line, SB_GetConstBuf (&Buf));
|
||||
SB_Done (&Buf);
|
||||
/* Output all stored notes */
|
||||
OutputNotes ();
|
||||
|
||||
/* Terminate after errors */
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -61,6 +61,12 @@ extern unsigned WarningCount;
|
||||
|
||||
|
||||
|
||||
void AddNote (const char* Format, ...) attribute((format(printf,1,2)));
|
||||
/* Add a notification message that will be output after the next error or
|
||||
** warning. There cannot be a Notification() function since Error() will
|
||||
** always terminate.
|
||||
*/
|
||||
|
||||
void Warning (const char* Format, ...) attribute((format(printf,1,2)));
|
||||
/* Print a warning message */
|
||||
|
||||
@@ -70,6 +76,11 @@ void Error (const char* Format, ...) attribute((noreturn, format(printf,1,2)));
|
||||
void Internal (const char* Format, ...) attribute((noreturn, format(printf,1,2)));
|
||||
/* Print an internal error message and die */
|
||||
|
||||
void AddCfgNote (const FilePos* Pos, const char* Format, ...) attribute((format(printf,2,3)));
|
||||
/* Add a notifcation message using file name and line number of the config file.
|
||||
** See comment for AddNote() above.
|
||||
*/
|
||||
|
||||
void CfgWarning (const FilePos* Pos, const char* Format, ...) attribute((format(printf,2,3)));
|
||||
/* Print a warning message adding file name and line number of the config file */
|
||||
|
||||
|
||||
@@ -167,13 +167,13 @@ Import* ReadImport (FILE* F, ObjData* Obj)
|
||||
*/
|
||||
if (ObjHasFiles (I->Obj)) {
|
||||
const LineInfo* LI = GetImportPos (I);
|
||||
Error ("Invalid import size in for '%s', imported from %s:%u: 0x%02X",
|
||||
Error ("Invalid import size in for `%s', imported from %s:%u: 0x%02X",
|
||||
GetString (I->Name),
|
||||
GetSourceName (LI),
|
||||
GetSourceLine (LI),
|
||||
I->AddrSize);
|
||||
} else {
|
||||
Error ("Invalid import size in for '%s', imported from %s: 0x%02X",
|
||||
Error ("Invalid import size in for `%s', imported from %s: 0x%02X",
|
||||
GetString (I->Name),
|
||||
GetObjFileName (I->Obj),
|
||||
I->AddrSize);
|
||||
@@ -200,7 +200,7 @@ Import* GenImport (unsigned Name, unsigned char AddrSize)
|
||||
/* We have no object file information and no line info for a new
|
||||
** import
|
||||
*/
|
||||
Error ("Invalid import size 0x%02X for symbol '%s'",
|
||||
Error ("Invalid import size 0x%02X for symbol `%s'",
|
||||
I->AddrSize,
|
||||
GetString (I->Name));
|
||||
}
|
||||
@@ -484,7 +484,7 @@ void InsertExport (Export* E)
|
||||
}
|
||||
} else if (AllowMultDef == 0) {
|
||||
/* Duplicate entry, this is fatal unless allowed by the user */
|
||||
Error ("Duplicate external identifier: '%s'",
|
||||
Error ("Duplicate external identifier: `%s'",
|
||||
GetString (L->Name));
|
||||
}
|
||||
return;
|
||||
@@ -663,7 +663,7 @@ long GetExportVal (const Export* E)
|
||||
{
|
||||
if (E->Expr == 0) {
|
||||
/* OOPS */
|
||||
Internal ("'%s' is an undefined external", GetString (E->Name));
|
||||
Internal ("`%s' is an undefined external", GetString (E->Name));
|
||||
}
|
||||
return GetExprVal (E->Expr);
|
||||
}
|
||||
@@ -726,9 +726,9 @@ static void CheckSymType (const Export* E)
|
||||
}
|
||||
|
||||
/* Output the diagnostic */
|
||||
Warning ("Address size mismatch for '%s': "
|
||||
"Exported from %s as '%s', "
|
||||
"import in %s as '%s'",
|
||||
Warning ("Address size mismatch for `%s': "
|
||||
"Exported from %s as `%s', "
|
||||
"import in %s as `%s'",
|
||||
GetString (E->Name),
|
||||
SB_GetConstBuf (&ExportLoc),
|
||||
ExpAddrSize,
|
||||
@@ -775,21 +775,20 @@ static void PrintUnresolved (ExpCheckFunc F, void* Data)
|
||||
if (E->Expr == 0 && E->ImpCount > 0 && F (E->Name, Data) == 0) {
|
||||
/* Unresolved external */
|
||||
Import* Imp = E->ImpList;
|
||||
const char* name = GetString (E->Name);
|
||||
const char* Name = GetString (E->Name);
|
||||
while (Imp) {
|
||||
unsigned J, count = CollCount (&Imp->RefLines);
|
||||
/* The count is 0 when the import was not added by an input file,
|
||||
but by the compiler itself. */
|
||||
if (count == 0) {
|
||||
fprintf (stderr, "Error: Unresolved external '%s'\n", name);
|
||||
unsigned J, Count = CollCount (&Imp->RefLines);
|
||||
/* The count is 0 when the import was not added by an input
|
||||
** file, but by the compiler itself.
|
||||
*/
|
||||
if (Count == 0) {
|
||||
Warning ("Unresolved external `%s'", Name);
|
||||
} else {
|
||||
for (J = 0; J < count; ++J) {
|
||||
for (J = 0; J < Count; ++J) {
|
||||
const LineInfo* LI = CollConstAt (&Imp->RefLines, J);
|
||||
fprintf (stderr,
|
||||
"%s:%u: Error: Unresolved external '%s'\n",
|
||||
GetSourceName (LI),
|
||||
GetSourceLine (LI),
|
||||
name);
|
||||
CfgWarning (GetSourcePos (LI),
|
||||
"Unresolved external `%s'",
|
||||
Name);
|
||||
}
|
||||
}
|
||||
Imp = Imp->Next;
|
||||
@@ -1080,7 +1079,7 @@ void CircularRefError (const Export* E)
|
||||
/* Print an error about a circular reference using to define the given export */
|
||||
{
|
||||
const LineInfo* LI = GetExportPos (E);
|
||||
Error ("Circular reference for symbol '%s', %s:%u",
|
||||
Error ("Circular reference for symbol `%s', %s:%u",
|
||||
GetString (E->Name),
|
||||
GetSourceName (LI),
|
||||
GetSourceLine (LI));
|
||||
|
||||
@@ -408,12 +408,12 @@ long GetExprVal (ExprNode* Expr)
|
||||
Error ("Argument of .BANK() isn't a label attached to a segment");
|
||||
}
|
||||
if (D.Seg->MemArea == 0) {
|
||||
Error ("Segment '%s' is referenced by .BANK(),"
|
||||
Error ("Segment `%s' is referenced by .BANK(),"
|
||||
" but not assigned to a memory area",
|
||||
GetString (D.Seg->Name));
|
||||
}
|
||||
if (D.Seg->MemArea->BankExpr == 0) {
|
||||
Error ("Memory area '%s' is referenced by .BANK(),"
|
||||
Error ("Memory area `%s' is referenced by .BANK(),"
|
||||
" but has no BANK attribute",
|
||||
GetString (D.Seg->MemArea->Name));
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ ExtSym* NewExtSym (ExtSymTab* Tab, unsigned Name)
|
||||
ExtSym* E = GetExtSym (Tab, Name);
|
||||
if (E != 0) {
|
||||
/* We do already have a symbol with this name */
|
||||
Error ("Duplicate external symbol '%s'", GetString (Name));
|
||||
Error ("Duplicate external symbol `%s'", GetString (Name));
|
||||
}
|
||||
|
||||
/* Allocate memory for the structure */
|
||||
|
||||
@@ -112,7 +112,7 @@ static void CloseLibrary (Library* L)
|
||||
{
|
||||
/* Close the library file */
|
||||
if (fclose (L->F) != 0) {
|
||||
Error ("Error closing '%s': %s", GetString (L->Name), strerror (errno));
|
||||
Error ("Error closing `%s': %s", GetString (L->Name), strerror (errno));
|
||||
}
|
||||
L->F = 0;
|
||||
}
|
||||
@@ -144,7 +144,7 @@ static void LibSeek (Library* L, unsigned long Offs)
|
||||
/* Do a seek in the library checking for errors */
|
||||
{
|
||||
if (fseek (L->F, Offs, SEEK_SET) != 0) {
|
||||
Error ("Seek error in '%s' (%lu): %s",
|
||||
Error ("Seek error in `%s' (%lu): %s",
|
||||
GetString (L->Name), Offs, strerror (errno));
|
||||
}
|
||||
}
|
||||
@@ -158,7 +158,7 @@ static void LibReadHeader (Library* L)
|
||||
L->Header.Magic = LIB_MAGIC;
|
||||
L->Header.Version = Read16 (L->F);
|
||||
if (L->Header.Version != LIB_VERSION) {
|
||||
Error ("Wrong data version in '%s'", GetString (L->Name));
|
||||
Error ("Wrong data version in `%s'", GetString (L->Name));
|
||||
}
|
||||
L->Header.Flags = Read16 (L->F);
|
||||
L->Header.IndexOffs = Read32 (L->F);
|
||||
@@ -171,12 +171,12 @@ static void LibReadObjHeader (Library* L, ObjData* O)
|
||||
{
|
||||
O->Header.Magic = Read32 (L->F);
|
||||
if (O->Header.Magic != OBJ_MAGIC) {
|
||||
Error ("Object file '%s' in library '%s' is invalid",
|
||||
Error ("Object file `%s' in library `%s' is invalid",
|
||||
GetObjFileName (O), GetString (L->Name));
|
||||
}
|
||||
O->Header.Version = Read16 (L->F);
|
||||
if (O->Header.Version != OBJ_VERSION) {
|
||||
Error ("Object file '%s' in library '%s' has wrong version",
|
||||
Error ("Object file `%s' in library `%s' has wrong version",
|
||||
GetObjFileName (O), GetString (L->Name));
|
||||
}
|
||||
O->Header.Flags = Read16 (L->F);
|
||||
|
||||
@@ -219,13 +219,13 @@ static void LinkFile (const char* Name, FILETYPE Type)
|
||||
|
||||
/* We must have a valid name now */
|
||||
if (PathName == 0) {
|
||||
Error ("Input file '%s' not found", Name);
|
||||
Error ("Input file `%s' not found", Name);
|
||||
}
|
||||
|
||||
/* Try to open the file */
|
||||
F = fopen (PathName, "rb");
|
||||
if (F == 0) {
|
||||
Error ("Cannot open '%s': %s", PathName, strerror (errno));
|
||||
Error ("Cannot open `%s': %s", PathName, strerror (errno));
|
||||
}
|
||||
|
||||
/* Read the magic word */
|
||||
@@ -251,7 +251,7 @@ static void LinkFile (const char* Name, FILETYPE Type)
|
||||
|
||||
default:
|
||||
fclose (F);
|
||||
Error ("File '%s' has unknown type", PathName);
|
||||
Error ("File `%s' has unknown type", PathName);
|
||||
|
||||
}
|
||||
|
||||
@@ -340,7 +340,7 @@ static void OptConfig (const char* Opt attribute ((unused)), const char* Arg)
|
||||
PathName = SearchFile (CfgDefaultPath, Arg);
|
||||
}
|
||||
if (PathName == 0) {
|
||||
Error ("Cannot find config file '%s'", Arg);
|
||||
Error ("Cannot find config file `%s'", Arg);
|
||||
}
|
||||
|
||||
/* Read the config */
|
||||
@@ -394,7 +394,7 @@ static void OptForceImport (const char* Opt attribute ((unused)), const char* Ar
|
||||
/* Get the address size and check it */
|
||||
unsigned char AddrSize = AddrSizeFromStr (ColPos+1);
|
||||
if (AddrSize == ADDR_SIZE_INVALID) {
|
||||
Error ("Invalid address size '%s'", ColPos+1);
|
||||
Error ("Invalid address size `%s'", ColPos+1);
|
||||
}
|
||||
|
||||
/* Create a copy of the argument */
|
||||
@@ -544,7 +544,7 @@ static void OptTarget (const char* Opt attribute ((unused)), const char* Arg)
|
||||
/* Map the target name to a target id */
|
||||
Target = FindTarget (Arg);
|
||||
if (Target == TGT_UNKNOWN) {
|
||||
Error ("Invalid target name: '%s'", Arg);
|
||||
Error ("Invalid target name: `%s'", Arg);
|
||||
}
|
||||
|
||||
/* Set the target binary format */
|
||||
@@ -561,7 +561,7 @@ static void OptTarget (const char* Opt attribute ((unused)), const char* Arg)
|
||||
PathName = SearchFile (CfgDefaultPath, SB_GetBuf (&FileName));
|
||||
}
|
||||
if (PathName == 0) {
|
||||
Error ("Cannot find config file '%s'", SB_GetBuf (&FileName));
|
||||
Error ("Cannot find config file `%s'", SB_GetBuf (&FileName));
|
||||
}
|
||||
|
||||
/* Free file name memory */
|
||||
|
||||
@@ -67,7 +67,7 @@ void CreateMapFile (int ShortMap)
|
||||
/* Open the map file */
|
||||
FILE* F = fopen (MapFileName, "w");
|
||||
if (F == 0) {
|
||||
Error ("Cannot create map file '%s': %s", MapFileName, strerror (errno));
|
||||
Error ("Cannot create map file `%s': %s", MapFileName, strerror (errno));
|
||||
}
|
||||
|
||||
/* Write a modules list */
|
||||
@@ -132,7 +132,7 @@ void CreateMapFile (int ShortMap)
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (F) != 0) {
|
||||
Error ("Error closing map file '%s': %s", MapFileName, strerror (errno));
|
||||
Error ("Error closing map file `%s': %s", MapFileName, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ void CreateLabelFile (void)
|
||||
/* Open the label file */
|
||||
FILE* F = fopen (LabelFileName, "w");
|
||||
if (F == 0) {
|
||||
Error ("Cannot create label file '%s': %s", LabelFileName, strerror (errno));
|
||||
Error ("Cannot create label file `%s': %s", LabelFileName, strerror (errno));
|
||||
}
|
||||
|
||||
/* Print the labels for the export symbols */
|
||||
@@ -155,6 +155,6 @@ void CreateLabelFile (void)
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (F) != 0) {
|
||||
Error ("Error closing label file '%s': %s", LabelFileName, strerror (errno));
|
||||
Error ("Error closing label file `%s': %s", LabelFileName, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -807,7 +807,7 @@ static void O65WriteSeg (O65Desc* D, SegDesc** Seg, unsigned Count, int DoWrite)
|
||||
|
||||
/* Check the size of the segment for overflow */
|
||||
if ((D->Header.Mode & MF_SIZE_MASK) == MF_SIZE_16BIT && D->SegSize > 0xFFFF) {
|
||||
Error ("Segment overflow in file '%s'", D->Filename);
|
||||
Error ("Segment overflow in file `%s'", D->Filename);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -960,7 +960,7 @@ static void O65WriteExports (O65Desc* D)
|
||||
|
||||
/* Bail out if we cannot handle the expression */
|
||||
if (ED.TooComplex) {
|
||||
Error ("Expression for symbol '%s' is too complex", Name);
|
||||
Error ("Expression for symbol `%s' is too complex", Name);
|
||||
}
|
||||
|
||||
/* Determine the segment id for the expression */
|
||||
@@ -979,7 +979,7 @@ static void O65WriteExports (O65Desc* D)
|
||||
/* For some reason, we didn't find this segment in the list of
|
||||
** segments written to the o65 file.
|
||||
*/
|
||||
Error ("Segment for symbol '%s' is undefined", Name);
|
||||
Error ("Segment for symbol `%s' is undefined", Name);
|
||||
}
|
||||
SegmentID = O65SegType (Seg);
|
||||
|
||||
@@ -1209,7 +1209,7 @@ void O65SetExport (O65Desc* D, unsigned Ident)
|
||||
*/
|
||||
Export* E = FindExport (Ident);
|
||||
if (E == 0 || IsUnresolvedExport (E)) {
|
||||
Error ("Unresolved export: '%s'", GetString (Ident));
|
||||
Error ("Unresolved export: `%s'", GetString (Ident));
|
||||
}
|
||||
|
||||
/* Insert the entry into the table */
|
||||
@@ -1372,7 +1372,7 @@ void O65WriteTarget (O65Desc* D, File* F)
|
||||
/* Open the file */
|
||||
D->F = fopen (D->Filename, "wb");
|
||||
if (D->F == 0) {
|
||||
Error ("Cannot open '%s': %s", D->Filename, strerror (errno));
|
||||
Error ("Cannot open `%s': %s", D->Filename, strerror (errno));
|
||||
}
|
||||
|
||||
/* Keep the user happy */
|
||||
@@ -1430,7 +1430,7 @@ void O65WriteTarget (O65Desc* D, File* F)
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (D->F) != 0) {
|
||||
Error ("Cannot write to '%s': %s", D->Filename, strerror (errno));
|
||||
Error ("Cannot write to `%s': %s", D->Filename, strerror (errno));
|
||||
}
|
||||
|
||||
/* Reset the file and filename */
|
||||
|
||||
@@ -184,7 +184,7 @@ unsigned MakeGlobalStringId (const ObjData* O, unsigned Index)
|
||||
/* Convert a local string id into a global one and return it. */
|
||||
{
|
||||
if (Index >= O->StringCount) {
|
||||
Error ("Invalid string index (%u) in module '%s'",
|
||||
Error ("Invalid string index (%u) in module `%s'",
|
||||
Index, GetObjFileName (O));
|
||||
}
|
||||
return O->Strings[Index];
|
||||
@@ -214,7 +214,7 @@ struct Section* GetObjSection (const ObjData* O, unsigned Id)
|
||||
/* Get a section from an object file checking for a valid index */
|
||||
{
|
||||
if (Id >= CollCount (&O->Sections)) {
|
||||
Error ("Invalid section index (%u) in module '%s'",
|
||||
Error ("Invalid section index (%u) in module `%s'",
|
||||
Id, GetObjFileName (O));
|
||||
}
|
||||
return CollAtUnchecked (&O->Sections, Id);
|
||||
@@ -226,7 +226,7 @@ struct Import* GetObjImport (const ObjData* O, unsigned Id)
|
||||
/* Get an import from an object file checking for a valid index */
|
||||
{
|
||||
if (Id >= CollCount (&O->Imports)) {
|
||||
Error ("Invalid import index (%u) in module '%s'",
|
||||
Error ("Invalid import index (%u) in module `%s'",
|
||||
Id, GetObjFileName (O));
|
||||
}
|
||||
return CollAtUnchecked (&O->Imports, Id);
|
||||
@@ -238,7 +238,7 @@ struct Export* GetObjExport (const ObjData* O, unsigned Id)
|
||||
/* Get an export from an object file checking for a valid index */
|
||||
{
|
||||
if (Id >= CollCount (&O->Exports)) {
|
||||
Error ("Invalid export index (%u) in module '%s'",
|
||||
Error ("Invalid export index (%u) in module `%s'",
|
||||
Id, GetObjFileName (O));
|
||||
}
|
||||
return CollAtUnchecked (&O->Exports, Id);
|
||||
@@ -250,7 +250,7 @@ struct DbgSym* GetObjDbgSym (const ObjData* O, unsigned Id)
|
||||
/* Get a debug symbol from an object file checking for a valid index */
|
||||
{
|
||||
if (Id >= CollCount (&O->DbgSyms)) {
|
||||
Error ("Invalid debug symbol index (%u) in module '%s'",
|
||||
Error ("Invalid debug symbol index (%u) in module `%s'",
|
||||
Id, GetObjFileName (O));
|
||||
}
|
||||
return CollAtUnchecked (&O->DbgSyms, Id);
|
||||
@@ -262,7 +262,7 @@ struct Scope* GetObjScope (const ObjData* O, unsigned Id)
|
||||
/* Get a scope from an object file checking for a valid index */
|
||||
{
|
||||
if (Id >= CollCount (&O->Scopes)) {
|
||||
Error ("Invalid scope index (%u) in module '%s'",
|
||||
Error ("Invalid scope index (%u) in module `%s'",
|
||||
Id, GetObjFileName (O));
|
||||
}
|
||||
return CollAtUnchecked (&O->Scopes, Id);
|
||||
|
||||
@@ -67,7 +67,7 @@ static unsigned GetModule (const char* Name)
|
||||
/* Make a module name from the file name */
|
||||
const char* Module = FindName (Name);
|
||||
if (*Module == 0) {
|
||||
Error ("Cannot make module name from '%s'", Name);
|
||||
Error ("Cannot make module name from `%s'", Name);
|
||||
}
|
||||
return GetStringId (Module);
|
||||
}
|
||||
@@ -79,7 +79,7 @@ static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
|
||||
{
|
||||
H->Version = Read16 (Obj);
|
||||
if (H->Version != OBJ_VERSION) {
|
||||
Error ("Object file '%s' has wrong version, expected %08X, got %08X",
|
||||
Error ("Object file `%s' has wrong version, expected %08X, got %08X",
|
||||
Name, OBJ_VERSION, H->Version);
|
||||
}
|
||||
H->Flags = Read16 (Obj);
|
||||
|
||||
@@ -137,7 +137,7 @@ static void StrVal (void)
|
||||
case EOF:
|
||||
case '\n':
|
||||
case '\"':
|
||||
CfgError (&CfgErrorPos, "Unterminated '%%' escape sequence");
|
||||
CfgError (&CfgErrorPos, "Unterminated `%%' escape sequence");
|
||||
break;
|
||||
|
||||
case '%':
|
||||
@@ -156,7 +156,7 @@ static void StrVal (void)
|
||||
|
||||
default:
|
||||
CfgWarning (&CfgErrorPos,
|
||||
"Unknown escape sequence '%%%c'", C);
|
||||
"Unknown escape sequence `%%%c'", C);
|
||||
SB_AppendChar (&CfgSVal, '%');
|
||||
SB_AppendChar (&CfgSVal, C);
|
||||
NextChar ();
|
||||
@@ -349,7 +349,7 @@ Again:
|
||||
break;
|
||||
|
||||
default:
|
||||
CfgError (&CfgErrorPos, "Invalid character '%c'", C);
|
||||
CfgError (&CfgErrorPos, "Invalid character `%c'", C);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -370,7 +370,7 @@ void CfgConsume (cfgtok_t T, const char* Msg)
|
||||
void CfgConsumeSemi (void)
|
||||
/* Consume a semicolon */
|
||||
{
|
||||
CfgConsume (CFGTOK_SEMI, "';' expected");
|
||||
CfgConsume (CFGTOK_SEMI, "`;' expected");
|
||||
}
|
||||
|
||||
|
||||
@@ -378,7 +378,7 @@ void CfgConsumeSemi (void)
|
||||
void CfgConsumeColon (void)
|
||||
/* Consume a colon */
|
||||
{
|
||||
CfgConsume (CFGTOK_COLON, "':' expected");
|
||||
CfgConsume (CFGTOK_COLON, "`:' expected");
|
||||
}
|
||||
|
||||
|
||||
@@ -462,7 +462,7 @@ void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name)
|
||||
}
|
||||
|
||||
/* Not found */
|
||||
CfgError (&CfgErrorPos, "%s expected, got '%s'", Name, SB_GetConstBuf(&CfgSVal));
|
||||
CfgError (&CfgErrorPos, "%s expected, got `%s'", Name, SB_GetConstBuf(&CfgSVal));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -518,7 +518,7 @@ void CfgOpenInput (void)
|
||||
/* Open the file */
|
||||
InputFile = fopen (CfgName, "r");
|
||||
if (InputFile == 0) {
|
||||
Error ("Cannot open '%s': %s", CfgName, strerror (errno));
|
||||
Error ("Cannot open `%s': %s", CfgName, strerror (errno));
|
||||
}
|
||||
|
||||
/* Initialize variables */
|
||||
|
||||
@@ -147,7 +147,7 @@ void PrintDbgScopes (FILE* F)
|
||||
case SCOPE_ENUM: fputs (",type=enum", F); break;
|
||||
|
||||
default:
|
||||
Error ("Module '%s': Unknown scope type %u",
|
||||
Error ("Module `%s': Unknown scope type %u",
|
||||
GetObjFileName (O), S->Type);
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ Segment* GetSegment (unsigned Name, unsigned char AddrSize, const char* ObjName)
|
||||
if (ObjName == 0) {
|
||||
ObjName = "[linker generated]";
|
||||
}
|
||||
Error ("Module '%s': Type mismatch for segment '%s'", ObjName,
|
||||
Error ("Module `%s': Type mismatch for segment `%s'", ObjName,
|
||||
GetString (Name));
|
||||
}
|
||||
}
|
||||
@@ -226,13 +226,13 @@ Section* ReadSection (FILE* F, ObjData* O)
|
||||
if (Sec->Alignment > 1) {
|
||||
Alignment = LeastCommonMultiple (S->Alignment, Sec->Alignment);
|
||||
if (Alignment > MAX_ALIGNMENT) {
|
||||
Error ("Combined alignment for segment '%s' is %lu which exceeds "
|
||||
"%lu. Last module requiring alignment was '%s'.",
|
||||
Error ("Combined alignment for segment `%s' is %lu which exceeds "
|
||||
"%lu. Last module requiring alignment was `%s'.",
|
||||
GetString (Name), Alignment, MAX_ALIGNMENT,
|
||||
GetObjFileName (O));
|
||||
} else if (Alignment >= LARGE_ALIGNMENT && Alignment > S->Alignment && Alignment > Sec->Alignment && !LargeAlignment) {
|
||||
Warning ("Combined alignment for segment '%s' is suspiciously "
|
||||
"large (%lu). Last module requiring alignment was '%s'.",
|
||||
Warning ("Combined alignment for segment `%s' is suspiciously "
|
||||
"large (%lu). Last module requiring alignment was `%s'.",
|
||||
GetString (Name), Alignment, GetObjFileName (O));
|
||||
}
|
||||
S->Alignment = Alignment;
|
||||
@@ -270,7 +270,7 @@ Section* ReadSection (FILE* F, ObjData* O)
|
||||
break;
|
||||
|
||||
default:
|
||||
Error ("Unknown fragment type in module '%s', segment '%s': %02X",
|
||||
Error ("Unknown fragment type in module `%s', segment `%s': %02X",
|
||||
GetObjFileName (O), GetString (S->Name), Type);
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
@@ -502,19 +502,19 @@ void SegWrite (const char* TgtName, FILE* Tgt, Segment* S, SegWriteFunc F, void*
|
||||
break;
|
||||
|
||||
case SEG_EXPR_RANGE_ERROR:
|
||||
Error ("Range error in module '%s', line %u",
|
||||
Error ("Range error in module `%s', line %u",
|
||||
GetFragmentSourceName (Frag),
|
||||
GetFragmentSourceLine (Frag));
|
||||
break;
|
||||
|
||||
case SEG_EXPR_TOO_COMPLEX:
|
||||
Error ("Expression too complex in module '%s', line %u",
|
||||
Error ("Expression too complex in module `%s', line %u",
|
||||
GetFragmentSourceName (Frag),
|
||||
GetFragmentSourceLine (Frag));
|
||||
break;
|
||||
|
||||
case SEG_EXPR_INVALID:
|
||||
Error ("Invalid expression in module '%s', line %u",
|
||||
Error ("Invalid expression in module `%s', line %u",
|
||||
GetFragmentSourceName (Frag),
|
||||
GetFragmentSourceLine (Frag));
|
||||
break;
|
||||
@@ -664,7 +664,7 @@ void CheckSegments (void)
|
||||
|
||||
/* Check it */
|
||||
if (S->Size > 0 && S->Dumped == 0) {
|
||||
Error ("Missing memory area assignment for segment '%s'",
|
||||
Error ("Missing memory area assignment for segment `%s'",
|
||||
GetString (S->Name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,7 +287,7 @@ static unsigned long XexWriteMem (XexDesc* D, MemoryArea* M)
|
||||
if (DoWrite || (M->Flags & MF_FILL) != 0) {
|
||||
/* "overwrite" segments are not supported */
|
||||
if (S->Flags & SF_OVERWRITE) {
|
||||
Error ("ATARI file format does not support overwrite for segment '%s'.",
|
||||
Error ("ATARI file format does not support overwrite for segment `%s'.",
|
||||
GetString (S->Name));
|
||||
} else {
|
||||
XexStartSegment (D, Addr, NewAddr - Addr);
|
||||
|
||||
Reference in New Issue
Block a user