Support colors in diagnostic output.

This commit is contained in:
Kugel Fuhr
2025-07-09 14:21:14 +02:00
parent 96f8ce4cee
commit 79967ff01b
21 changed files with 377 additions and 148 deletions

View File

@@ -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"
};

View File

@@ -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) {

View File

@@ -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 */

View File

@@ -105,7 +105,7 @@ static ExprNode* Factor (void)
/* Left parenthesis */
CfgNextTok ();
N = CfgExpr ();
CfgConsume (CFGTOK_RPAR, "')' expected");
CfgConsume (CFGTOK_RPAR, "`)' expected");
break;
default:

View File

@@ -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");
}

View File

@@ -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));
}
}

View File

@@ -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);
}

View File

@@ -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 */

View 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));

View File

@@ -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));
}

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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));
}
}

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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);
}

View File

@@ -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));
}
}

View File

@@ -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);