Use UTF-8 for diagnostic output if it is available. Added a command line

switch --no-utf8 to disable the use of UTF-8 characters.
This commit is contained in:
Kugel Fuhr
2025-07-07 21:49:45 +02:00
parent b1eb1bf6ab
commit c466faf484
28 changed files with 435 additions and 214 deletions

View File

@@ -120,6 +120,7 @@ Long options:
--listing name Create a listing file if assembly was ok --listing name Create a listing file if assembly was ok
--list-bytes n Maximum number of bytes per listing line --list-bytes n Maximum number of bytes per listing line
--memory-model model Set the memory model --memory-model model Set the memory model
--no-utf8 Disable use of UTF-8 in diagnostics
--pagelength n Set the page length for the listing --pagelength n Set the page length for the listing
--relax-checks Relax some checks (see docs) --relax-checks Relax some checks (see docs)
--smart Enable smart mode --smart Enable smart mode
@@ -147,7 +148,7 @@ Here is a description of all the command line options:
name="search paths">. name="search paths">.
<label id="option-color"> <label id="option--color">
<tag><tt>--color</tt></tag> <tag><tt>--color</tt></tag>
This option controls if the assembler will use colors when printing This option controls if the assembler will use colors when printing
@@ -262,6 +263,14 @@ Here is a description of all the command line options:
huge. huge.
<label id="option--no-utf8">
<tag><tt>--no-utf8</tt></tag>
Disable the use of UTF-8 characters in diagnostics. This might be necessary
if auto detection fails or if the output is captured for processing with a
tool that is not UTF-8 capable.
<label id="option-o"> <label id="option-o">
<tag><tt>-o name</tt></tag> <tag><tt>-o name</tt></tag>

View File

@@ -35,6 +35,7 @@
/* ca65 */ /* ca65 */
#include "error.h" #include "error.h"
#include "expect.h"
#include "expr.h" #include "expr.h"
#include "instr.h" #include "instr.h"
#include "lineinfo.h" #include "lineinfo.h"

View File

@@ -46,6 +46,7 @@
/* ca65 */ /* ca65 */
#include "dbginfo.h" #include "dbginfo.h"
#include "error.h" #include "error.h"
#include "expect.h"
#include "expr.h" #include "expr.h"
#include "filetab.h" #include "filetab.h"
#include "global.h" #include "global.h"
@@ -462,7 +463,7 @@ void DbgInfoCheck (void)
/* Search for the symbol name */ /* Search for the symbol name */
S->Sym = SymFindAny (S->Scope, GetStrBuf (S->AsmName)); S->Sym = SymFindAny (S->Scope, GetStrBuf (S->AsmName));
if (S->Sym == 0) { if (S->Sym == 0) {
PError (&S->Pos, "Assembler symbol '%s' not found", PError (&S->Pos, "Assembler symbol `%s' not found",
GetString (S->AsmName)); GetString (S->AsmName));
} else { } else {
/* Set the backlink */ /* Set the backlink */

View File

@@ -37,6 +37,7 @@
#include "ea.h" #include "ea.h"
#include "ea65.h" #include "ea65.h"
#include "error.h" #include "error.h"
#include "expect.h"
#include "expr.h" #include "expr.h"
#include "instr.h" #include "instr.h"
#include "nexttok.h" #include "nexttok.h"
@@ -62,11 +63,11 @@ void GetEA (EffAddr* A)
if (BracketAsIndirect) { if (BracketAsIndirect) {
IndirectEnter = TOK_LBRACK; IndirectEnter = TOK_LBRACK;
IndirectLeave = TOK_RBRACK; IndirectLeave = TOK_RBRACK;
IndirectExpect = "Expected ']'"; IndirectExpect = "Expected `]'";
} else { } else {
IndirectEnter = TOK_LPAREN; IndirectEnter = TOK_LPAREN;
IndirectLeave = TOK_RPAREN; IndirectLeave = TOK_RPAREN;
IndirectExpect = "Expected ')'"; IndirectExpect = "Expected `)'";
} }
/* Clear the output struct */ /* Clear the output struct */
@@ -145,12 +146,12 @@ void GetEA (EffAddr* A)
A->AddrModeSet = AM65_STACK_REL_IND_Y; A->AddrModeSet = AM65_STACK_REL_IND_Y;
if (!Consume (IndirectLeave, IndirectExpect) || if (!Consume (IndirectLeave, IndirectExpect) ||
!ConsumeComma () || !ConsumeComma () ||
!Consume (TOK_Y, "Expected 'Y'")) { !Consume (TOK_Y, "Expected `Y'")) {
/* In case of errors skip anything else on the line */ /* In case of errors skip anything else on the line */
SkipUntilSep (); SkipUntilSep ();
} }
} else { } else {
ErrorExpect ("Expected 'X' or 'S'"); ErrorExpect ("Expected `X' or `S'");
SkipUntilSep (); SkipUntilSep ();
} }
@@ -168,7 +169,7 @@ void GetEA (EffAddr* A)
A->AddrModeSet = AM65_DIR_IND; A->AddrModeSet = AM65_DIR_IND;
break; break;
default: default:
if (!Consume (TOK_Y, "Expected 'Y'")) { if (!Consume (TOK_Y, "Expected `Y'")) {
SkipUntilSep (); SkipUntilSep ();
} }
A->AddrModeSet = AM65_DIR_IND_Y; A->AddrModeSet = AM65_DIR_IND_Y;
@@ -198,20 +199,20 @@ void GetEA (EffAddr* A)
/* [dir] or [dir],y */ /* [dir] or [dir],y */
NextTok (); NextTok ();
A->Expr = Expression (); A->Expr = Expression ();
if (!Consume (TOK_RBRACK, "Expected ']'")) { if (!Consume (TOK_RBRACK, "Expected `]'")) {
SkipUntilSep (); SkipUntilSep ();
} }
if (CurTok.Tok == TOK_COMMA) { if (CurTok.Tok == TOK_COMMA) {
/* [dir],y */ /* [dir],y */
NextTok (); NextTok ();
if (GetCPU () == CPU_45GS02) { if (GetCPU () == CPU_45GS02) {
if (!Consume (TOK_Z, "Expected 'Z'")) { if (!Consume (TOK_Z, "Expected `Z'")) {
SkipUntilSep (); SkipUntilSep ();
} }
A->AddrModeSet = AM65_32BIT_BASE_IND_Z; A->AddrModeSet = AM65_32BIT_BASE_IND_Z;
} }
else { else {
if (!Consume (TOK_Y, "Expected 'Y'")) { if (!Consume (TOK_Y, "Expected `Y'")) {
SkipUntilSep (); SkipUntilSep ();
} }
A->AddrModeSet = AM65_DIR_IND_LONG_Y; A->AddrModeSet = AM65_DIR_IND_LONG_Y;

View File

@@ -37,6 +37,7 @@
#include "ea.h" #include "ea.h"
#include "ea65.h" #include "ea65.h"
#include "error.h" #include "error.h"
#include "expect.h"
#include "expr.h" #include "expr.h"
#include "instr.h" #include "instr.h"
#include "nexttok.h" #include "nexttok.h"

View File

@@ -41,6 +41,7 @@
#include "condasm.h" #include "condasm.h"
#include "enum.h" #include "enum.h"
#include "error.h" #include "error.h"
#include "expect.h"
#include "expr.h" #include "expr.h"
#include "macro.h" #include "macro.h"
#include "nexttok.h" #include "nexttok.h"
@@ -147,7 +148,7 @@ void DoEnum (void)
} }
/* End of enum definition */ /* End of enum definition */
Consume (TOK_ENDENUM, "'.ENDENUM' expected"); Consume (TOK_ENDENUM, "`.ENDENUM' expected");
/* Free the base expression */ /* Free the base expression */
FreeExpr (BaseExpr); FreeExpr (BaseExpr);

View File

@@ -83,6 +83,82 @@ const char* DiagCatDesc[DC_COUNT] = {
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";
/* 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 && IsUTF8) {
SB_AppendStr (&T, QuoteStart);
InQuote = 1;
} else {
/* ca65 uses \' for opening and closing quotes */
SB_AppendChar (&T, '\'');
}
break;
case '\'':
if (InQuote && IsUTF8) {
SB_AppendStr (&T, QuoteEnd);
InQuote = 0;
} 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 VPrintMsg (const FilePos* Pos, DiagCat Cat, const char* Format, static void VPrintMsg (const FilePos* Pos, DiagCat Cat, const char* Format,
va_list ap) va_list ap)
/* Format and output an error/warning message. */ /* Format and output an error/warning message. */
@@ -102,9 +178,9 @@ static void VPrintMsg (const FilePos* Pos, DiagCat Cat, const char* Format,
default: FAIL ("Unexpected Cat value"); break; default: FAIL ("Unexpected Cat value"); break;
} }
/* Format the actual message */ /* Format the actual message, then replace quotes */
SB_VPrintf (&Msg, Format, ap); SB_VPrintf (&Msg, Format, ap);
SB_Terminate (&Msg); ReplaceQuotes (&Msg);
/* Format the location. If the file position is valid, we use the file /* Format the location. If the file position is valid, we use the file
** position, otherwise the program name. This allows to print fatal ** position, otherwise the program name. This allows to print fatal
@@ -214,6 +290,18 @@ static void AddNotifications (const Collection* LineInfos)
void Notification (const char* Format, ...)
/* Print a notification message. */
{
/* Output the message */
va_list ap;
va_start (ap, Format);
VPrintMsg (&CurTok.Pos, DC_NOTE, Format, ap);
va_end (ap);
}
void PNotification (const FilePos* Pos, const char* Format, ...) void PNotification (const FilePos* Pos, const char* Format, ...)
/* Print a notification message. */ /* Print a notification message. */
{ {

View File

@@ -72,6 +72,9 @@ extern unsigned WarningCount;
void Notification (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Print a notification message. */
void PNotification (const FilePos* Pos, const char* Format, ...) attribute ((format (printf, 2, 3))); void PNotification (const FilePos* Pos, const char* Format, ...) attribute ((format (printf, 2, 3)));
/* Print a notification message. */ /* Print a notification message. */

116
src/ca65/expect.c Normal file
View File

@@ -0,0 +1,116 @@
/*****************************************************************************/
/* */
/* expect.c */
/* */
/* Print errors about expected tokens */
/* */
/* */
/* */
/* (C) 2025, Kugelfuhr */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
/* ca65 */
#include "error.h"
#include "expect.h"
#include "nexttok.h"
#include "scanner.h"
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void ErrorExpect (const char* Msg)
/* Output an error message about some expected token using Msg and the
* description of the following token. This means that Msg should contain
* something like "xyz expected". The actual error message would then be
* "xyz expected but found zyx".
*/
{
StrBuf S = AUTO_STRBUF_INITIALIZER;
TokenDesc (&CurTok, &S);
Error ("%s but found `%s'", Msg, SB_GetConstBuf (&S));
SB_Done (&S);
}
int Expect (token_t Expected, const char* Msg)
/* Check if the next token is the expected one. If not, print Msg plus some
* information about the token that was actually found. This means that Msg
* should contain something like "xyz expected". The actual error message would
* then be "xyz expected but found zyx".
* Returns true if the token was found, otherwise false.
*/
{
if (CurTok.Tok == Expected) {
return 1;
}
ErrorExpect (Msg);
return 0;
}
int ExpectSkip (token_t Expected, const char* Msg)
/* Check if the next token is the expected one. If not, print Msg plus some
* information about the token that was actually found and skip the remainder
* of the line. This means that Msg should contain something like "xyz
* expected". The actual error message would then be "xyz expected but found
* zyx".
* Returns true if the token was found, otherwise false.
*/
{
if (CurTok.Tok == Expected) {
return 1;
}
ErrorExpect (Msg);
SkipUntilSep ();
return 0;
}
int ExpectSep (void)
/* Check if we've reached a line separator. If so, return true. If not, output
** an error and skip all tokens until the line separator is reached. Then
** return false.
*/
{
if (!TokIsSep (CurTok.Tok)) {
/* Try to be helpful by giving information about the token that was
* unexpected.
*/
ErrorExpect ("Expected `end-of-line'");
SkipUntilSep ();
return 0;
} else {
return 1;
}
}

83
src/ca65/expect.h Normal file
View File

@@ -0,0 +1,83 @@
/*****************************************************************************/
/* */
/* expect.h */
/* */
/* Print errors about expected tokens */
/* */
/* */
/* */
/* (C) 2025, Kugelfuhr */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#ifndef EXPECT_H
#define EXPECT_H
/* ca65 */
#include "token.h"
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void ErrorExpect (const char* Msg);
/* Output an error message about some expected token using Msg and the
* description of the following token. This means that Msg should contain
* something like "xyz expected". The actual error message would then be
* "xyz expected but found zyx".
*/
int Expect (token_t Expected, const char* Msg);
/* Check if the next token is the expected one. If not, print Msg plus some
* information about the token that was actually found. This means that Msg
* should contain something like "xyz expected". The actual error message would
* then be "xyz expected but found zyx".
* Returns true if the token was found, otherwise false.
*/
int ExpectSkip (token_t Expected, const char* Msg);
/* Check if the next token is the expected one. If not, print Msg plus some
* information about the token that was actually found and skip the remainder
* of the line. This means that Msg should contain something like "xyz
* expected". The actual error message would then be "xyz expected but found
* zyx".
* Returns true if the token was found, otherwise false.
*/
int ExpectSep (void);
/* Check if we've reached a line separator. If so, return true. If not, output
** an error and skip all tokens until the line separator is reached. Then
** return false.
*/
/* End of expect.h */
#endif

View File

@@ -51,6 +51,7 @@
/* ca65 */ /* ca65 */
#include "error.h" #include "error.h"
#include "expect.h"
#include "expr.h" #include "expr.h"
#include "global.h" #include "global.h"
#include "instr.h" #include "instr.h"
@@ -778,7 +779,7 @@ static ExprNode* FuncAddrSize (void)
/* Cheap local symbol */ /* Cheap local symbol */
Sym = SymFindLocal (SymLast, &CurTok.SVal, SYM_FIND_EXISTING); Sym = SymFindLocal (SymLast, &CurTok.SVal, SYM_FIND_EXISTING);
if (Sym == 0) { if (Sym == 0) {
Error ("Unknown symbol or scope: '%m%p'", &CurTok.SVal); Error ("Unknown symbol or scope: `%m%p'", &CurTok.SVal);
} else { } else {
AddrSize = Sym->AddrSize; AddrSize = Sym->AddrSize;
} }
@@ -818,13 +819,13 @@ static ExprNode* FuncAddrSize (void)
if (Sym) { if (Sym) {
AddrSize = Sym->AddrSize; AddrSize = Sym->AddrSize;
} else { } else {
Error ("Unknown symbol or scope: '%m%p%m%p'", &ScopeName, &Name); Error ("Unknown symbol or scope: `%m%p%m%p'", &ScopeName, &Name);
} }
} }
if (AddrSize == 0) { if (AddrSize == 0) {
Warning (1, "Unknown address size: '%m%p%m%p'", &ScopeName, &Name); Warning (1, "Unknown address size: `%m%p%m%p'", &ScopeName, &Name);
} }
/* Free the string buffers */ /* Free the string buffers */
@@ -859,7 +860,7 @@ static ExprNode* FuncSizeOf (void)
/* Cheap local symbol */ /* Cheap local symbol */
Sym = SymFindLocal (SymLast, &CurTok.SVal, SYM_FIND_EXISTING); Sym = SymFindLocal (SymLast, &CurTok.SVal, SYM_FIND_EXISTING);
if (Sym == 0) { if (Sym == 0) {
Error ("Unknown symbol or scope: '%m%p'", &CurTok.SVal); Error ("Unknown symbol or scope: `%m%p'", &CurTok.SVal);
} else { } else {
SizeSym = GetSizeOfSymbol (Sym); SizeSym = GetSizeOfSymbol (Sym);
} }
@@ -911,7 +912,7 @@ static ExprNode* FuncSizeOf (void)
if (Sym) { if (Sym) {
SizeSym = GetSizeOfSymbol (Sym); SizeSym = GetSizeOfSymbol (Sym);
} else { } else {
Error ("Unknown symbol or scope: '%m%p%m%p'", Error ("Unknown symbol or scope: `%m%p%m%p'",
&ScopeName, &Name); &ScopeName, &Name);
} }
} }
@@ -919,7 +920,7 @@ static ExprNode* FuncSizeOf (void)
/* Check if we have a size */ /* Check if we have a size */
if (SizeSym == 0 || !SymIsConst (SizeSym, &Size)) { if (SizeSym == 0 || !SymIsConst (SizeSym, &Size)) {
Error ("Size of '%m%p%m%p' is unknown", &ScopeName, &Name); Error ("Size of `%m%p%m%p' is unknown", &ScopeName, &Name);
Size = 0; Size = 0;
} }
@@ -1059,7 +1060,7 @@ static ExprNode* Function (ExprNode* (*F) (void))
NextTok (); NextTok ();
/* Expression must be enclosed in braces */ /* Expression must be enclosed in braces */
if (!ExpectSkip (TOK_LPAREN, "Expected '('")) { if (!ExpectSkip (TOK_LPAREN, "Expected `('")) {
return GenLiteral0 (); return GenLiteral0 ();
} }
NextTok (); NextTok ();

View File

@@ -211,7 +211,7 @@ unsigned GetFileIndex (const StrBuf* Name)
/* If we don't have this index, print a diagnostic and use the main file */ /* If we don't have this index, print a diagnostic and use the main file */
if (F == 0) { if (F == 0) {
Error ("File name '%m%p' not found in file table", Name); Error ("File name `%m%p' not found in file table", Name);
return 0; return 0;
} else { } else {
return F->Index; return F->Index;
@@ -316,7 +316,7 @@ static void CreateDepFile (const char* Name, FileType Types)
/* Open the file */ /* Open the file */
FILE* F = fopen (Name, "w"); FILE* F = fopen (Name, "w");
if (F == 0) { if (F == 0) {
Fatal ("Cannot open dependency file '%s': %s", Name, strerror (errno)); Fatal ("Cannot open dependency file `%s': %s", Name, strerror (errno));
} }
/* Print the output file followed by a tab char */ /* Print the output file followed by a tab char */

View File

@@ -1961,7 +1961,7 @@ static void PutLDM_m740 (const InsDesc* Ins)
} }
Emit0 (Ins->BaseCode); Emit0 (Ins->BaseCode);
EmitByte (A.Expr); EmitByte (A.Expr);
Consume (TOK_HASH, "'#' expected"); Consume (TOK_HASH, "`#' expected");
EmitByte (Expression ()); EmitByte (Expression ());
} }

View File

@@ -304,7 +304,7 @@ void CreateListing (void)
/* Open the real listing file */ /* Open the real listing file */
F = fopen (SB_GetConstBuf (&ListingName), "w"); F = fopen (SB_GetConstBuf (&ListingName), "w");
if (F == 0) { if (F == 0) {
Fatal ("Cannot open listing file '%s': %s", Fatal ("Cannot open listing file `%s': %s",
SB_GetConstBuf (&ListingName), SB_GetConstBuf (&ListingName),
strerror (errno)); strerror (errno));
} }

View File

@@ -45,6 +45,7 @@
/* ca65 */ /* ca65 */
#include "condasm.h" #include "condasm.h"
#include "error.h" #include "error.h"
#include "expect.h"
#include "global.h" #include "global.h"
#include "instr.h" #include "instr.h"
#include "istack.h" #include "istack.h"
@@ -380,7 +381,7 @@ static void MacSkipDef (unsigned Style, const FilePos* StartPos)
int LastWasSep = 0; int LastWasSep = 0;
while (1) { while (1) {
if (CurTok.Tok == TOK_EOF) { if (CurTok.Tok == TOK_EOF) {
ErrorExpect ("Expected '.ENDMACRO'"); ErrorExpect ("Expected `.ENDMACRO'");
PNotification (StartPos, "Macro definition started here"); PNotification (StartPos, "Macro definition started here");
break; break;
} }
@@ -434,9 +435,9 @@ void MacDef (unsigned Style)
Existing = HT_Find (&MacroTab, &CurTok.SVal); Existing = HT_Find (&MacroTab, &CurTok.SVal);
if (Existing != 0) { if (Existing != 0) {
/* Macro is already defined */ /* Macro is already defined */
Error ("A macro named '%m%p' is already defined", &CurTok.SVal); Error ("A macro named `%m%p' is already defined", &CurTok.SVal);
PNotification (&Existing->DefPos, PNotification (&Existing->DefPos,
"Previous definition of macro '%s' was here", "Previous definition of macro `%s' was here",
SB_GetConstBuf (&Existing->Name)); SB_GetConstBuf (&Existing->Name));
/* Skip tokens until we reach the final .endmacro */ /* Skip tokens until we reach the final .endmacro */
MacSkipDef (Style, &StartPos); MacSkipDef (Style, &StartPos);
@@ -478,7 +479,7 @@ void MacDef (unsigned Style)
while (1) { while (1) {
if (SB_Compare (&List->Id, &CurTok.SVal) == 0) { if (SB_Compare (&List->Id, &CurTok.SVal) == 0) {
Error ("Duplicate macro parameter '%m%p'", &CurTok.SVal); Error ("Duplicate macro parameter `%m%p'", &CurTok.SVal);
M->HasError = 1; M->HasError = 1;
} }
if (List->Next == 0) { if (List->Next == 0) {
@@ -529,7 +530,7 @@ void MacDef (unsigned Style)
} }
/* May not have end of file in a macro definition */ /* May not have end of file in a macro definition */
if (CurTok.Tok == TOK_EOF) { if (CurTok.Tok == TOK_EOF) {
Error ("Missing '.ENDMACRO' for definition of macro '%s'", Error ("Missing `.ENDMACRO' for definition of macro `%s'",
SB_GetConstBuf (&M->Name)); SB_GetConstBuf (&M->Name));
PNotification (&StartPos, "Macro definition started here"); PNotification (&StartPos, "Macro definition started here");
M->HasError = 1; M->HasError = 1;
@@ -645,11 +646,11 @@ void MacUndef (const StrBuf* Name, unsigned char Style)
/* Don't let the user kid with us */ /* Don't let the user kid with us */
if (M == 0 || M->Style != Style) { if (M == 0 || M->Style != Style) {
Error ("No such macro: %m%p", Name); Error ("No such macro: `%m%p'", Name);
return; return;
} }
if (M->Expansions > 0) { if (M->Expansions > 0) {
Error ("Cannot delete macro '%s' which is currently expanded", Error ("Cannot delete macro `%s' which is currently expanded",
SB_GetConstBuf (&M->Name)); SB_GetConstBuf (&M->Name));
return; return;
} }
@@ -837,10 +838,10 @@ static void StartExpClassic (MacExp* E)
/* Check for maximum parameter count */ /* Check for maximum parameter count */
if (E->ParamCount >= E->M->ParamCount) { if (E->ParamCount >= E->M->ParamCount) {
ErrorSkip ("Too many parameters for macro '%s'", ErrorSkip ("Too many parameters for macro `%s'",
SB_GetConstBuf (&E->M->Name)); SB_GetConstBuf (&E->M->Name));
PNotification (&E->M->DefPos, PNotification (&E->M->DefPos,
"See definition of macro '%s' which was here", "See definition of macro `%s' which was here",
SB_GetConstBuf (&E->M->Name)); SB_GetConstBuf (&E->M->Name));
break; break;
} }
@@ -966,7 +967,7 @@ static void StartExpDefine (MacExp* E)
/* Check for a comma */ /* Check for a comma */
if (Count > 0) { if (Count > 0) {
if (Expect (TOK_COMMA, "Expected ','")) { if (Expect (TOK_COMMA, "Expected `,'")) {
NextTok (); NextTok ();
} }
} }
@@ -1000,18 +1001,18 @@ void MacExpandStart (Macro* M)
/* We cannot expand a macro with errors */ /* We cannot expand a macro with errors */
if (M->HasError) { if (M->HasError) {
PError (&Pos, "Macro '%s' contains errors and cannot be expanded", PError (&Pos, "Macro `%s' contains errors and cannot be expanded",
SB_GetConstBuf (&M->Name)); SB_GetConstBuf (&M->Name));
PNotification (&M->DefPos, "Definition of macro '%s' was here", PNotification (&M->DefPos, "Definition of macro `%s' was here",
SB_GetConstBuf (&M->Name)); SB_GetConstBuf (&M->Name));
return; return;
} }
/* We cannot expand an incomplete macro */ /* We cannot expand an incomplete macro */
if (M->Incomplete) { if (M->Incomplete) {
PError (&Pos, "Macro '%s' is incomplete and cannot be expanded", PError (&Pos, "Macro `%s' is incomplete and cannot be expanded",
SB_GetConstBuf (&M->Name)); SB_GetConstBuf (&M->Name));
PNotification (&M->DefPos, "Definition of macro '%s' was here", PNotification (&M->DefPos, "Definition of macro `%s' was here",
SB_GetConstBuf (&M->Name)); SB_GetConstBuf (&M->Name));
return; return;
} }
@@ -1020,7 +1021,7 @@ void MacExpandStart (Macro* M)
** to force an endless loop and assembler crash. ** to force an endless loop and assembler crash.
*/ */
if (MacExpansions >= MAX_MACEXPANSIONS) { if (MacExpansions >= MAX_MACEXPANSIONS) {
PError (&Pos, "Too many nested macro expansions for macro '%s'", PError (&Pos, "Too many nested macro expansions for macro `%s'",
SB_GetConstBuf (&M->Name)); SB_GetConstBuf (&M->Name));
return; return;
} }

View File

@@ -57,6 +57,7 @@
#include "asserts.h" #include "asserts.h"
#include "dbginfo.h" #include "dbginfo.h"
#include "error.h" #include "error.h"
#include "expect.h"
#include "expr.h" #include "expr.h"
#include "feature.h" #include "feature.h"
#include "filetab.h" #include "filetab.h"
@@ -126,6 +127,7 @@ static void Usage (void)
" --listing name\t\tCreate a listing file if assembly was ok\n" " --listing name\t\tCreate a listing file if assembly was ok\n"
" --list-bytes n\t\tMaximum number of bytes per listing line\n" " --list-bytes n\t\tMaximum number of bytes per listing line\n"
" --memory-model model\t\tSet the memory model\n" " --memory-model model\t\tSet the memory model\n"
" --no-utf8\t\t\tDisable use of UTF-8 in diagnostics\n"
" --pagelength n\t\tSet the page length for the listing\n" " --pagelength n\t\tSet the page length for the listing\n"
" --relax-checks\t\tRelax some checks (see docs)\n" " --relax-checks\t\tRelax some checks (see docs)\n"
" --smart\t\t\tEnable smart mode\n" " --smart\t\t\tEnable smart mode\n"
@@ -641,7 +643,7 @@ static void OptListing (const char* Opt, const char* Arg)
** the filename is empty or begins with the option char. ** the filename is empty or begins with the option char.
*/ */
if (Arg == 0 || *Arg == '\0' || *Arg == '-') { if (Arg == 0 || *Arg == '\0' || *Arg == '-') {
Fatal ("The meaning of '%s' has changed. It does now " Fatal ("The meaning of `%s' has changed. It does now "
"expect a file name as argument.", Opt); "expect a file name as argument.", Opt);
} }
@@ -675,6 +677,15 @@ static void OptMemoryModel (const char* Opt, const char* Arg)
static void OptNoUtf8 (const char* Opt attribute ((unused)),
const char* Arg attribute ((unused)))
/* Handle the --no-utf8 option */
{
CP_DisableUTF8 ();
}
static void OptPageLength (const char* Opt attribute ((unused)), const char* Arg) static void OptPageLength (const char* Opt attribute ((unused)), const char* Arg)
/* Handle the --pagelength option */ /* Handle the --pagelength option */
{ {
@@ -790,7 +801,7 @@ static void OneLine (void)
if (CurTok.Tok == TOK_COLON) { if (CurTok.Tok == TOK_COLON) {
NextTok (); NextTok ();
} else if (CurTok.WS || !NoColonLabels) { } else if (CurTok.WS || !NoColonLabels) {
Error ("':' expected"); Error ("`:' expected");
} }
} }
@@ -876,7 +887,7 @@ static void OneLine (void)
*/ */
if (CurTok.Tok != TOK_COLON) { if (CurTok.Tok != TOK_COLON) {
if (HadWS || !NoColonLabels) { if (HadWS || !NoColonLabels) {
ErrorExpect ("Expected ':' after identifier to form a label"); ErrorExpect ("Expected `:' after identifier to form a label");
SkipUntilSep (); SkipUntilSep ();
goto Done; goto Done;
} }
@@ -921,7 +932,7 @@ static void OneLine (void)
HandleInstruction (Instr); HandleInstruction (Instr);
} else if (PCAssignment && (CurTok.Tok == TOK_STAR || CurTok.Tok == TOK_PC)) { } else if (PCAssignment && (CurTok.Tok == TOK_STAR || CurTok.Tok == TOK_PC)) {
NextTok (); NextTok ();
if (!ExpectSkip (TOK_EQ, "Expected '='")) { if (!ExpectSkip (TOK_EQ, "Expected `='")) {
goto Done; goto Done;
} }
/* Skip the equal sign */ /* Skip the equal sign */
@@ -1046,6 +1057,7 @@ int main (int argc, char* argv [])
{ "--list-bytes", 1, OptListBytes }, { "--list-bytes", 1, OptListBytes },
{ "--listing", 1, OptListing }, { "--listing", 1, OptListing },
{ "--memory-model", 1, OptMemoryModel }, { "--memory-model", 1, OptMemoryModel },
{ "--no-utf8", 0, OptNoUtf8 },
{ "--pagelength", 1, OptPageLength }, { "--pagelength", 1, OptPageLength },
{ "--relax-checks", 0, OptRelaxChecks }, { "--relax-checks", 0, OptRelaxChecks },
{ "--smart", 0, OptSmart }, { "--smart", 0, OptSmart },

View File

@@ -44,6 +44,7 @@
/* ca65 */ /* ca65 */
#include "condasm.h" #include "condasm.h"
#include "error.h" #include "error.h"
#include "expect.h"
#include "expr.h" #include "expr.h"
#include "global.h" #include "global.h"
#include "scanner.h" #include "scanner.h"
@@ -179,7 +180,7 @@ static void FuncConcat (void)
** by the string token just created. ** by the string token just created.
*/ */
if (CurTok.Tok != TOK_RPAREN) { if (CurTok.Tok != TOK_RPAREN) {
Error ("')' expected"); Error ("`)' expected");
} else { } else {
CurTok.Tok = TOK_STRCON; CurTok.Tok = TOK_STRCON;
SB_Copy (&CurTok.SVal, &Buf); SB_Copy (&CurTok.SVal, &Buf);
@@ -253,7 +254,7 @@ static void FuncIdent (void)
SB_Copy (&Buf, &CurTok.SVal); SB_Copy (&Buf, &CurTok.SVal);
NextTok (); NextTok ();
if (CurTok.Tok != TOK_RPAREN) { if (CurTok.Tok != TOK_RPAREN) {
Error ("')' expected"); Error ("`)' expected");
} else { } else {
CurTok.Tok = Id; CurTok.Tok = Id;
SB_Copy (&CurTok.SVal, &Buf); SB_Copy (&CurTok.SVal, &Buf);
@@ -600,7 +601,7 @@ static void FuncSPrintF (void)
** by the string token just created. ** by the string token just created.
*/ */
if (CurTok.Tok != TOK_RPAREN) { if (CurTok.Tok != TOK_RPAREN) {
Error ("')' expected"); Error ("`)' expected");
} else { } else {
CurTok.Tok = TOK_STRCON; CurTok.Tok = TOK_STRCON;
SB_Copy (&CurTok.SVal, &R); SB_Copy (&CurTok.SVal, &R);
@@ -660,7 +661,7 @@ static void FuncString (void)
** by the string token just created. ** by the string token just created.
*/ */
if (CurTok.Tok != TOK_RPAREN) { if (CurTok.Tok != TOK_RPAREN) {
Error ("')' expected"); Error ("`)' expected");
} else { } else {
CurTok.Tok = TOK_STRCON; CurTok.Tok = TOK_STRCON;
SB_Copy (&CurTok.SVal, &Buf); SB_Copy (&CurTok.SVal, &Buf);
@@ -725,59 +726,6 @@ void NextTok (void)
void ErrorExpect (const char* Msg)
/* Output an error message about some expected token using Msg and the
* description of the following token. This means that Msg should contain
* something like "xyz expected". The actual error message would then be
* "xyz expected but found zyx".
*/
{
StrBuf S = AUTO_STRBUF_INITIALIZER;
TokenDesc (&CurTok, &S);
Error ("%s but found '%s'", Msg, SB_GetConstBuf (&S));
SB_Done (&S);
}
int Expect (token_t Expected, const char* Msg)
/* Check if the next token is the expected one. If not, print Msg plus some
* information about the token that was actually found. This means that Msg
* should contain something like "xyz expected". The actual error message would
* then be "xyz expected but found zyx".
* Returns true if the token was found, otherwise false.
*/
{
if (CurTok.Tok == Expected) {
return 1;
}
ErrorExpect (Msg);
return 0;
}
int ExpectSkip (token_t Expected, const char* Msg)
/* Check if the next token is the expected one. If not, print Msg plus some
* information about the token that was actually found and skip the remainder
* of the line. This means that Msg should contain something like "xyz
* expected". The actual error message would then be "xyz expected but found
* zyx".
* Returns true if the token was found, otherwise false.
*/
{
if (CurTok.Tok == Expected) {
return 1;
}
ErrorExpect (Msg);
SkipUntilSep ();
return 0;
}
int Consume (token_t Expected, const char* ErrMsg) int Consume (token_t Expected, const char* ErrMsg)
/* Consume Token, print an error if we don't find it. Return true if the token /* Consume Token, print an error if we don't find it. Return true if the token
** was found and false otherwise. ** was found and false otherwise.
@@ -816,7 +764,7 @@ int ConsumeLParen (void)
** otherwise. ** otherwise.
*/ */
{ {
return Consume (TOK_LPAREN, "Expected '('"); return Consume (TOK_LPAREN, "Expected `('");
} }
@@ -826,7 +774,7 @@ int ConsumeRParen (void)
** otherwise. ** otherwise.
*/ */
{ {
return Consume (TOK_RPAREN, "Expected ')'"); return Consume (TOK_RPAREN, "Expected `)'");
} }
@@ -836,7 +784,7 @@ int ConsumeComma (void)
** otherwise. ** otherwise.
*/ */
{ {
return Consume (TOK_COMMA, "Expected ','"); return Consume (TOK_COMMA, "Expected `,'");
} }
@@ -851,26 +799,6 @@ void SkipUntilSep (void)
int ExpectSep (void)
/* Check if we've reached a line separator. If so, return true. If not, output
** an error and skip all tokens until the line separator is reached. Then
** return false.
*/
{
if (!TokIsSep (CurTok.Tok)) {
/* Try to be helpful by giving information about the token that was
* unexpected.
*/
ErrorExpect ("Expected 'end-of-line'");
SkipUntilSep ();
return 0;
} else {
return 1;
}
}
void EnterRawTokenMode (void) void EnterRawTokenMode (void)
/* Enter raw token mode. In raw mode, token handling functions are not /* Enter raw token mode. In raw mode, token handling functions are not
** executed, but the function tokens are passed untouched to the upper ** executed, but the function tokens are passed untouched to the upper

View File

@@ -51,30 +51,6 @@
void NextTok (void); void NextTok (void);
/* Get next token and handle token level functions */ /* Get next token and handle token level functions */
void ErrorExpect (const char* Msg);
/* Output an error message about some expected token using Msg and the
* description of the following token. This means that Msg should contain
* something like "xyz expected". The actual error message would then be
* "xyz expected but found zyx".
*/
int Expect (token_t Expected, const char* Msg);
/* Check if the next token is the expected one. If not, print Msg plus some
* information about the token that was actually found. This means that Msg
* should contain something like "xyz expected". The actual error message would
* then be "xyz expected but found zyx".
* Returns true if the token was found, otherwise false.
*/
int ExpectSkip (token_t Expected, const char* Msg);
/* Check if the next token is the expected one. If not, print Msg plus some
* information about the token that was actually found and skip the remainder
* of the line. This means that Msg should contain something like "xyz
* expected". The actual error message would then be "xyz expected but found
* zyx".
* Returns true if the token was found, otherwise false.
*/
int Consume (token_t Expected, const char* ErrMsg); int Consume (token_t Expected, const char* ErrMsg);
/* Consume Token, print an error if we don't find it. Return true if the token /* Consume Token, print an error if we don't find it. Return true if the token
** was found and false otherwise. ** was found and false otherwise.
@@ -103,12 +79,6 @@ int ConsumeComma (void);
void SkipUntilSep (void); void SkipUntilSep (void);
/* Skip tokens until we reach a line separator or end of file */ /* Skip tokens until we reach a line separator or end of file */
int ExpectSep (void);
/* Check if we've reached a line separator. If so, return true. If not, output
** an error and skip all tokens until the line separator is reached. Then
** return false.
*/
void EnterRawTokenMode (void); void EnterRawTokenMode (void);
/* Enter raw token mode. In raw mode, token handling functions are not /* Enter raw token mode. In raw mode, token handling functions are not
** executed, but the function tokens are passed untouched to the upper ** executed, but the function tokens are passed untouched to the upper

View File

@@ -113,7 +113,7 @@ static void ObjWriteError (void)
remove (OutFile); remove (OutFile);
/* Now abort with a fatal error */ /* Now abort with a fatal error */
Fatal ("Cannot write to output file '%s': %s", OutFile, strerror (Error)); Fatal ("Cannot write to output file `%s': %s", OutFile, strerror (Error));
} }
@@ -170,7 +170,7 @@ void ObjOpen (void)
/* Create the output file */ /* Create the output file */
F = fopen (OutFile, "w+b"); F = fopen (OutFile, "w+b");
if (F == 0) { if (F == 0) {
Fatal ("Cannot open output file '%s': %s", OutFile, strerror (errno)); Fatal ("Cannot open output file `%s': %s", OutFile, strerror (errno));
} }
/* Write a dummy header */ /* Write a dummy header */

View File

@@ -60,6 +60,7 @@
#include "dbginfo.h" #include "dbginfo.h"
#include "enum.h" #include "enum.h"
#include "error.h" #include "error.h"
#include "expect.h"
#include "expr.h" #include "expr.h"
#include "feature.h" #include "feature.h"
#include "filetab.h" #include "filetab.h"
@@ -1038,13 +1039,13 @@ static void DoFeature (void)
Feature = FindFeature (&CurTok.SVal); Feature = FindFeature (&CurTok.SVal);
if (Feature == FEAT_UNKNOWN) { if (Feature == FEAT_UNKNOWN) {
/* Not found */ /* Not found */
ErrorSkip ("Invalid feature: '%m%p'", &CurTok.SVal); ErrorSkip ("Invalid feature: `%m%p'", &CurTok.SVal);
return; return;
} }
if (Feature == FEAT_ADDRSIZE) { if (Feature == FEAT_ADDRSIZE) {
Warning (1, "Deprecated feature: '.feature addrsize'. " Warning (1, "Deprecated feature `addrsize'");
"Pseudo function .addrsize is always available."); Notification ("Pseudo function `.addrsize' is always available");
} }
NextTok (); NextTok ();
@@ -1270,7 +1271,7 @@ static void DoIncBin (void)
char* PathName = SearchFile (BinSearchPath, SB_GetConstBuf (&Name)); char* PathName = SearchFile (BinSearchPath, SB_GetConstBuf (&Name));
if (PathName == 0 || (F = fopen (PathName, "rb")) == 0) { if (PathName == 0 || (F = fopen (PathName, "rb")) == 0) {
/* Not found or cannot open, print an error and bail out */ /* Not found or cannot open, print an error and bail out */
ErrorSkip ("Cannot open include file '%m%p': %s", &Name, strerror (errno)); ErrorSkip ("Cannot open include file `%m%p': %s", &Name, strerror (errno));
xfree (PathName); xfree (PathName);
goto ExitPoint; goto ExitPoint;
} }
@@ -1296,7 +1297,7 @@ static void DoIncBin (void)
*/ */
SB_Terminate (&Name); SB_Terminate (&Name);
if (FileStat (SB_GetConstBuf (&Name), &StatBuf) != 0) { if (FileStat (SB_GetConstBuf (&Name), &StatBuf) != 0) {
Fatal ("Cannot stat input file '%m%p': %s", &Name, strerror (errno)); Fatal ("Cannot stat input file `%m%p': %s", &Name, strerror (errno));
} }
/* Add the file to the input file table */ /* Add the file to the input file table */
@@ -1336,7 +1337,7 @@ static void DoIncBin (void)
size_t BytesRead = fread (Buf, 1, BytesToRead, F); size_t BytesRead = fread (Buf, 1, BytesToRead, F);
if (BytesToRead != BytesRead) { if (BytesToRead != BytesRead) {
/* Some sort of error */ /* Some sort of error */
ErrorSkip ("Cannot read from include file '%m%p': %s", ErrorSkip ("Cannot read from include file `%m%p': %s",
&Name, strerror (errno)); &Name, strerror (errno));
break; break;
} }
@@ -2019,7 +2020,7 @@ static void DoUnDef (void)
static void DoUnexpected (void) static void DoUnexpected (void)
/* Got an unexpected keyword */ /* Got an unexpected keyword */
{ {
Error ("Unexpected '%m%p'", &Keyword); Error ("Unexpected `%m%p'", &Keyword);
SkipUntilSep (); SkipUntilSep ();
} }

View File

@@ -40,6 +40,7 @@
/* ca65 */ /* ca65 */
#include "error.h" #include "error.h"
#include "expect.h"
#include "expr.h" #include "expr.h"
#include "nexttok.h" #include "nexttok.h"
#include "toklist.h" #include "toklist.h"
@@ -67,8 +68,8 @@ static TokList* CollectRepeatTokens (const FilePos* StartPos)
/* Check for end of input */ /* Check for end of input */
if (CurTok.Tok == TOK_EOF) { if (CurTok.Tok == TOK_EOF) {
ErrorExpect ("Expected '.ENDREPEAT'"); ErrorExpect ("Expected `.ENDREPEAT'");
PNotification (StartPos, "For this '.REPEAT' command"); PNotification (StartPos, "For this `.REPEAT' command");
FreeTokList (List); FreeTokList (List);
return 0; return 0;
} }

View File

@@ -52,6 +52,7 @@
/* ca65 */ /* ca65 */
#include "condasm.h" #include "condasm.h"
#include "error.h" #include "error.h"
#include "expect.h"
#include "filetab.h" #include "filetab.h"
#include "global.h" #include "global.h"
#include "incpath.h" #include "incpath.h"
@@ -545,7 +546,7 @@ int NewInputFile (const char* Name)
/* Main file */ /* Main file */
F = fopen (Name, "r"); F = fopen (Name, "r");
if (F == 0) { if (F == 0) {
Fatal ("Cannot open input file '%s': %s", Name, strerror (errno)); Fatal ("Cannot open input file `%s': %s", Name, strerror (errno));
} }
} else { } else {
/* We are on include level. Search for the file in the include /* We are on include level. Search for the file in the include
@@ -554,7 +555,7 @@ int NewInputFile (const char* Name)
PathName = SearchFile (IncSearchPath, Name); PathName = SearchFile (IncSearchPath, Name);
if (PathName == 0 || (F = fopen (PathName, "r")) == 0) { if (PathName == 0 || (F = fopen (PathName, "r")) == 0) {
/* Not found or cannot open, print an error and bail out */ /* Not found or cannot open, print an error and bail out */
Error ("Cannot open include file '%s': %s", Name, strerror (errno)); Error ("Cannot open include file `%s': %s", Name, strerror (errno));
goto ExitPoint; goto ExitPoint;
} }
@@ -571,7 +572,7 @@ int NewInputFile (const char* Name)
** here. ** here.
*/ */
if (FileStat (Name, &Buf) != 0) { if (FileStat (Name, &Buf) != 0) {
Fatal ("Cannot stat input file '%s': %s", Name, strerror (errno)); Fatal ("Cannot stat input file `%s': %s", Name, strerror (errno));
} }
/* Add the file to the input file table and remember the index */ /* Add the file to the input file table and remember the index */
@@ -1196,7 +1197,7 @@ Again:
/* Not found */ /* Not found */
if (!LeadingDotInIdents) { if (!LeadingDotInIdents) {
/* Invalid pseudo instruction */ /* Invalid pseudo instruction */
Error ("'%m%p' is not a recognized control command", &CurTok.SVal); Error ("`%m%p' is not a recognized control command", &CurTok.SVal);
goto Again; goto Again;
} }
@@ -1686,14 +1687,14 @@ unsigned char ParseAddrSize (void)
/* Check for an identifier */ /* Check for an identifier */
if (CurTok.Tok != TOK_IDENT) { if (CurTok.Tok != TOK_IDENT) {
Error ("Address size specifier expected"); ErrorExpect ("Expected an address size specifier");
return ADDR_SIZE_DEFAULT; return ADDR_SIZE_DEFAULT;
} }
/* Convert the attribute */ /* Convert the attribute */
AddrSize = AddrSizeFromStr (SB_GetConstBuf (&CurTok.SVal)); AddrSize = AddrSizeFromStr (SB_GetConstBuf (&CurTok.SVal));
if (AddrSize == ADDR_SIZE_INVALID) { if (AddrSize == ADDR_SIZE_INVALID) {
Error ("Address size specifier expected"); ErrorExpect ("Expected an address size specifier");
AddrSize = ADDR_SIZE_DEFAULT; AddrSize = ADDR_SIZE_DEFAULT;
} }

View File

@@ -134,7 +134,7 @@ static Segment* NewSegment (const char* Name, unsigned char AddrSize)
/* Check the segment name for invalid names */ /* Check the segment name for invalid names */
if (!ValidSegName (Name)) { if (!ValidSegName (Name)) {
Error ("Illegal segment name: '%s'", Name); Error ("Illegal segment name: `%s'", Name);
} }
/* Create a new segment and return it */ /* Create a new segment and return it */

View File

@@ -39,6 +39,7 @@
/* ca65 */ /* ca65 */
#include "condasm.h" #include "condasm.h"
#include "error.h" #include "error.h"
#include "expect.h"
#include "expr.h" #include "expr.h"
#include "macro.h" #include "macro.h"
#include "nexttok.h" #include "nexttok.h"
@@ -287,9 +288,9 @@ static long DoStructInternal (long Offs, unsigned Type)
/* End of struct/union definition */ /* End of struct/union definition */
if (Type == STRUCT) { if (Type == STRUCT) {
Consume (TOK_ENDSTRUCT, "Expected '.ENDSTRUCT'"); Consume (TOK_ENDSTRUCT, "Expected `.ENDSTRUCT'");
} else { } else {
Consume (TOK_ENDUNION, "Expected '.ENDUNION'"); Consume (TOK_ENDUNION, "Expected `.ENDUNION'");
} }
/* Return the size of the struct */ /* Return the size of the struct */

View File

@@ -593,7 +593,7 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D)
if (SymHasUserMark (Sym)) { if (SymHasUserMark (Sym)) {
LIError (&Sym->DefLines, LIError (&Sym->DefLines,
"Circular reference in definition of symbol '%m%p'", "Circular reference in definition of symbol `%m%p'",
GetSymName (Sym)); GetSymName (Sym));
ED_SetError (D); ED_SetError (D);
} else { } else {

View File

@@ -40,6 +40,7 @@
/* ca65 */ /* ca65 */
#include "error.h" #include "error.h"
#include "expect.h"
#include "nexttok.h" #include "nexttok.h"
#include "scanner.h" #include "scanner.h"
#include "symbol.h" #include "symbol.h"
@@ -95,7 +96,7 @@ SymTable* ParseScopedIdent (StrBuf* Name, StrBuf* FullName)
if (Scope == 0) { if (Scope == 0) {
/* Scope not found */ /* Scope not found */
SB_Terminate (FullName); SB_Terminate (FullName);
Error ("No such scope: '%m%p'", FullName); Error ("No such scope: `%m%p'", FullName);
return 0; return 0;
} }
@@ -138,7 +139,7 @@ SymTable* ParseScopedIdent (StrBuf* Name, StrBuf* FullName)
Scope = SymFindScope (Scope, Name, SYM_FIND_EXISTING); Scope = SymFindScope (Scope, Name, SYM_FIND_EXISTING);
if (Scope == 0) { if (Scope == 0) {
/* Scope not found */ /* Scope not found */
Error ("No such scope: '%m%p'", FullName); Error ("No such scope: `%m%p'", FullName);
return 0; return 0;
} }

View File

@@ -215,7 +215,7 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
if (S->Flags & SF_IMPORT) { if (S->Flags & SF_IMPORT) {
/* Defined symbol is marked as imported external symbol */ /* Defined symbol is marked as imported external symbol */
Error ("Symbol '%m%p' is already an import", GetSymName (S)); Error ("Symbol `%m%p' is already an import", GetSymName (S));
if (CollCount (&S->DefLines) > 0) { if (CollCount (&S->DefLines) > 0) {
PNotification (GetSourcePos (CollAt(&S->DefLines, 0)), PNotification (GetSourcePos (CollAt(&S->DefLines, 0)),
"The symbol was previously imported here"); "The symbol was previously imported here");
@@ -224,13 +224,13 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
} }
if ((Flags & SF_VAR) != 0 && (S->Flags & (SF_EXPORT | SF_GLOBAL))) { if ((Flags & SF_VAR) != 0 && (S->Flags & (SF_EXPORT | SF_GLOBAL))) {
/* Variable symbols cannot be exports or globals */ /* Variable symbols cannot be exports or globals */
Error ("Var symbol '%m%p' cannot be an export or global symbol", GetSymName (S)); Error ("Var symbol `%m%p' cannot be an export or global symbol", GetSymName (S));
return; return;
} }
if (S->Flags & SF_DEFINED) { if (S->Flags & SF_DEFINED) {
/* Multiple definition. In case of a variable, this is legal. */ /* Multiple definition. In case of a variable, this is legal. */
if ((S->Flags & SF_VAR) == 0) { if ((S->Flags & SF_VAR) == 0) {
Error ("Symbol '%m%p' is already defined", GetSymName (S)); Error ("Symbol `%m%p' is already defined", GetSymName (S));
if (CollCount (&S->DefLines) > 0) { if (CollCount (&S->DefLines) > 0) {
PNotification (GetSourcePos (CollAt(&S->DefLines, 0)), PNotification (GetSourcePos (CollAt(&S->DefLines, 0)),
"The symbol was previously defined here"); "The symbol was previously defined here");
@@ -240,7 +240,7 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
} else { } else {
/* Redefinition must also be a variable symbol */ /* Redefinition must also be a variable symbol */
if ((Flags & SF_VAR) == 0) { if ((Flags & SF_VAR) == 0) {
Error ("Symbol '%m%p' is already different kind", GetSymName (S)); Error ("Symbol `%m%p' is already different kind", GetSymName (S));
return; return;
} }
/* Delete the current symbol expression, since it will get /* Delete the current symbol expression, since it will get
@@ -296,7 +296,7 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags
S->ExportSize = S->AddrSize; S->ExportSize = S->AddrSize;
} else if (S->AddrSize > S->ExportSize) { } else if (S->AddrSize > S->ExportSize) {
/* We're exporting a symbol smaller than it actually is */ /* We're exporting a symbol smaller than it actually is */
Warning (1, "Symbol '%m%p' is %s but exported %s", Warning (1, "Symbol `%m%p' is %s but exported %s",
GetSymName (S), AddrSizeToStr (S->AddrSize), GetSymName (S), AddrSizeToStr (S->AddrSize),
AddrSizeToStr (S->ExportSize)); AddrSizeToStr (S->ExportSize));
} }
@@ -328,13 +328,13 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
/* Mark the given symbol as an imported symbol */ /* Mark the given symbol as an imported symbol */
{ {
if (S->Flags & SF_DEFINED) { if (S->Flags & SF_DEFINED) {
Error ("Symbol '%m%p' is already defined", GetSymName (S)); Error ("Symbol `%m%p' is already defined", GetSymName (S));
S->Flags |= SF_MULTDEF; S->Flags |= SF_MULTDEF;
return; return;
} }
if (S->Flags & SF_EXPORT) { if (S->Flags & SF_EXPORT) {
/* The symbol is already marked as exported symbol */ /* The symbol is already marked as exported symbol */
Error ("Cannot import exported symbol '%m%p'", GetSymName (S)); Error ("Cannot import exported symbol `%m%p'", GetSymName (S));
return; return;
} }
@@ -350,16 +350,16 @@ void SymImport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
*/ */
if (S->Flags & SF_IMPORT) { if (S->Flags & SF_IMPORT) {
if ((Flags & SF_FORCED) != (S->Flags & SF_FORCED)) { if ((Flags & SF_FORCED) != (S->Flags & SF_FORCED)) {
Error ("Redeclaration mismatch for symbol '%m%p'", GetSymName (S)); Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
} }
if (AddrSize != S->AddrSize) { if (AddrSize != S->AddrSize) {
Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
} }
if (S->Flags & SF_GLOBAL) { if (S->Flags & SF_GLOBAL) {
S->Flags &= ~SF_GLOBAL; S->Flags &= ~SF_GLOBAL;
if (AddrSize != S->AddrSize) { if (AddrSize != S->AddrSize) {
Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
} }
@@ -382,12 +382,12 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
/* Check if it's ok to export the symbol */ /* Check if it's ok to export the symbol */
if (S->Flags & SF_IMPORT) { if (S->Flags & SF_IMPORT) {
/* The symbol is already marked as imported external symbol */ /* The symbol is already marked as imported external symbol */
Error ("Symbol '%m%p' is already an import", GetSymName (S)); Error ("Symbol `%m%p' is already an import", GetSymName (S));
return; return;
} }
if (S->Flags & SF_VAR) { if (S->Flags & SF_VAR) {
/* Variable symbols cannot be exported */ /* Variable symbols cannot be exported */
Error ("Var symbol '%m%p' cannot be exported", GetSymName (S)); Error ("Var symbol `%m%p' cannot be exported", GetSymName (S));
return; return;
} }
@@ -396,7 +396,7 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
*/ */
if (S->Flags & SF_GLOBAL) { if (S->Flags & SF_GLOBAL) {
if (AddrSize != S->ExportSize) { if (AddrSize != S->ExportSize) {
Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
S->Flags &= ~SF_GLOBAL; S->Flags &= ~SF_GLOBAL;
@@ -411,7 +411,7 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
*/ */
if ((S->Flags & (SF_EXPORT|SF_DEFINED)) == SF_EXPORT) { if ((S->Flags & (SF_EXPORT|SF_DEFINED)) == SF_EXPORT) {
if (S->ExportSize != AddrSize) { if (S->ExportSize != AddrSize) {
Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
} }
S->ExportSize = AddrSize; S->ExportSize = AddrSize;
@@ -425,7 +425,7 @@ void SymExport (SymEntry* S, unsigned char AddrSize, unsigned Flags)
S->ExportSize = S->AddrSize; S->ExportSize = S->AddrSize;
} else if (S->AddrSize > S->ExportSize) { } else if (S->AddrSize > S->ExportSize) {
/* We're exporting a symbol smaller than it actually is */ /* We're exporting a symbol smaller than it actually is */
Warning (1, "Symbol '%m%p' is %s but exported %s", Warning (1, "Symbol `%m%p' is %s but exported %s",
GetSymName (S), AddrSizeToStr (S->AddrSize), GetSymName (S), AddrSizeToStr (S->AddrSize),
AddrSizeToStr (S->ExportSize)); AddrSizeToStr (S->ExportSize));
} }
@@ -447,7 +447,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
{ {
if (S->Flags & SF_VAR) { if (S->Flags & SF_VAR) {
/* Variable symbols cannot be exported or imported */ /* Variable symbols cannot be exported or imported */
Error ("Var symbol '%m%p' cannot be made global", GetSymName (S)); Error ("Var symbol `%m%p' cannot be made global", GetSymName (S));
return; return;
} }
@@ -460,7 +460,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
AddrSize = GetCurrentSegAddrSize (); AddrSize = GetCurrentSegAddrSize ();
} }
if (AddrSize != S->AddrSize) { if (AddrSize != S->AddrSize) {
Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
return; return;
} }
@@ -472,12 +472,12 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
if ((S->Flags & SF_DEFINED) == 0) { if ((S->Flags & SF_DEFINED) == 0) {
/* Symbol is undefined */ /* Symbol is undefined */
if (AddrSize != S->ExportSize) { if (AddrSize != S->ExportSize) {
Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
} else if (AddrSize != ADDR_SIZE_DEFAULT) { } else if (AddrSize != ADDR_SIZE_DEFAULT) {
/* Symbol is defined and address size given */ /* Symbol is defined and address size given */
if (AddrSize != S->ExportSize) { if (AddrSize != S->ExportSize) {
Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
} }
return; return;
@@ -489,7 +489,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
*/ */
if (S->Flags & SF_GLOBAL) { if (S->Flags & SF_GLOBAL) {
if (AddrSize != S->ExportSize) { if (AddrSize != S->ExportSize) {
Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
return; return;
} }
@@ -507,7 +507,7 @@ void SymGlobal (SymEntry* S, unsigned char AddrSize, unsigned Flags)
S->ExportSize = S->AddrSize; S->ExportSize = S->AddrSize;
} else if (S->AddrSize > S->ExportSize) { } else if (S->AddrSize > S->ExportSize) {
/* We're exporting a symbol smaller than it actually is */ /* We're exporting a symbol smaller than it actually is */
Warning (1, "Symbol '%m%p' is %s but exported %s", Warning (1, "Symbol `%m%p' is %s but exported %s",
GetSymName (S), AddrSizeToStr (S->AddrSize), GetSymName (S), AddrSizeToStr (S->AddrSize),
AddrSizeToStr (S->ExportSize)); AddrSizeToStr (S->ExportSize));
} }
@@ -550,12 +550,12 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
/* Check for errors */ /* Check for errors */
if (S->Flags & SF_IMPORT) { if (S->Flags & SF_IMPORT) {
/* The symbol is already marked as imported external symbol */ /* The symbol is already marked as imported external symbol */
Error ("Symbol '%m%p' is already an import", GetSymName (S)); Error ("Symbol `%m%p' is already an import", GetSymName (S));
return; return;
} }
if (S->Flags & SF_VAR) { if (S->Flags & SF_VAR) {
/* Variable symbols cannot be exported or imported */ /* Variable symbols cannot be exported or imported */
Error ("Var symbol '%m%p' cannot be exported", GetSymName (S)); Error ("Var symbol `%m%p' cannot be exported", GetSymName (S));
return; return;
} }
@@ -567,7 +567,7 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
/* Use the real size of the symbol */ /* Use the real size of the symbol */
AddrSize = S->AddrSize; AddrSize = S->AddrSize;
} else if (S->AddrSize != AddrSize) { } else if (S->AddrSize != AddrSize) {
Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
} }
@@ -577,7 +577,7 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
*/ */
if (S->Flags & (SF_EXPORT | SF_GLOBAL)) { if (S->Flags & (SF_EXPORT | SF_GLOBAL)) {
if (S->ExportSize != AddrSize) { if (S->ExportSize != AddrSize) {
Error ("Address size mismatch for symbol '%m%p'", GetSymName (S)); Error ("Address size mismatch for symbol `%m%p'", GetSymName (S));
} }
S->Flags &= ~SF_GLOBAL; S->Flags &= ~SF_GLOBAL;
} }
@@ -588,7 +588,7 @@ void SymConDes (SymEntry* S, unsigned char AddrSize, unsigned Type, unsigned Pri
*/ */
if (S->ConDesPrio[Type] != CD_PRIO_NONE) { if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
if (S->ConDesPrio[Type] != Prio) { if (S->ConDesPrio[Type] != Prio) {
Error ("Redeclaration mismatch for symbol '%m%p'", GetSymName (S)); Error ("Redeclaration mismatch for symbol `%m%p'", GetSymName (S));
} }
} }
S->ConDesPrio[Type] = Prio; S->ConDesPrio[Type] = Prio;

View File

@@ -178,7 +178,7 @@ static SymTable* NewSymTable (SymTable* Parent, const StrBuf* Name)
} }
} else { } else {
/* Duplicate scope name */ /* Duplicate scope name */
Internal ("Duplicate scope name: '%m%p'", Name); Internal ("Duplicate scope name: `%m%p'", Name);
} }
} }
} }
@@ -216,7 +216,7 @@ void SymEnterLevel (const StrBuf* ScopeName, unsigned char Type,
/* Check if the scope has been defined before */ /* Check if the scope has been defined before */
if (CurrentScope->Flags & ST_DEFINED) { if (CurrentScope->Flags & ST_DEFINED) {
Error ("Duplicate scope '%m%p'", ScopeName); Error ("Duplicate scope `%m%p'", ScopeName);
} }
} else { } else {
@@ -502,7 +502,7 @@ static void SymCheckUndefined (SymEntry* S)
if (Sym->Flags & SF_IMPORT) { if (Sym->Flags & SF_IMPORT) {
/* The symbol is already marked as import */ /* The symbol is already marked as import */
LIError (&S->RefLines, LIError (&S->RefLines,
"Symbol '%s' is already an import", "Symbol `%s' is already an import",
GetString (Sym->Name)); GetString (Sym->Name));
} }
if ((Sym->Flags & SF_EXPORT) == 0) { if ((Sym->Flags & SF_EXPORT) == 0) {
@@ -516,7 +516,7 @@ static void SymCheckUndefined (SymEntry* S)
if (Sym->AddrSize > Sym->ExportSize) { if (Sym->AddrSize > Sym->ExportSize) {
/* We're exporting a symbol smaller than it actually is */ /* We're exporting a symbol smaller than it actually is */
LIWarning (&Sym->DefLines, 1, LIWarning (&Sym->DefLines, 1,
"Symbol '%m%p' is %s but exported %s", "Symbol `%m%p' is %s but exported %s",
GetSymName (Sym), GetSymName (Sym),
AddrSizeToStr (Sym->AddrSize), AddrSizeToStr (Sym->AddrSize),
AddrSizeToStr (Sym->ExportSize)); AddrSizeToStr (Sym->ExportSize));
@@ -541,7 +541,7 @@ static void SymCheckUndefined (SymEntry* S)
if (S->Flags & SF_EXPORT) { if (S->Flags & SF_EXPORT) {
/* We will not auto-import an export */ /* We will not auto-import an export */
LIError (&S->RefLines, LIError (&S->RefLines,
"Exported symbol '%m%p' was never defined", "Exported symbol `%m%p' was never defined",
GetSymName (S)); GetSymName (S));
} else { } else {
if (AutoImport) { if (AutoImport) {
@@ -554,7 +554,7 @@ static void SymCheckUndefined (SymEntry* S)
} else { } else {
/* Error */ /* Error */
LIError (&S->RefLines, LIError (&S->RefLines,
"Symbol '%m%p' is undefined", "Symbol `%m%p' is undefined",
GetSymName (S)); GetSymName (S));
} }
} }
@@ -573,13 +573,13 @@ void SymCheck (void)
if (CurrentScope->Label) { if (CurrentScope->Label) {
/* proc has a label indicating the line it was opened. */ /* proc has a label indicating the line it was opened. */
LIError (&CurrentScope->Label->DefLines, LIError (&CurrentScope->Label->DefLines,
"Local proc '%s' was not closed", "Local proc `%s' was not closed",
GetString (CurrentScope->Name)); GetString (CurrentScope->Name));
} else { } else {
/* scope has no label to track a line number, uses end-of-document line instead. /* scope has no label to track a line number, uses end-of-document line instead.
** Anonymous scopes will reveal their internal automatic name. ** Anonymous scopes will reveal their internal automatic name.
*/ */
Error ("Local scope '%s' was not closed", Error ("Local scope `%s' was not closed",
GetString (CurrentScope->Name)); GetString (CurrentScope->Name));
} }
} }
@@ -627,7 +627,7 @@ void SymCheck (void)
ReleaseFullLineInfo (&S->RefLines); ReleaseFullLineInfo (&S->RefLines);
} else if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) { } else if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) {
LIWarning (&S->DefLines, 2, LIWarning (&S->DefLines, 2,
"Symbol '%m%p' is defined but never used", "Symbol `%m%p' is defined but never used",
GetSymName (S)); GetSymName (S));
} }
@@ -636,7 +636,7 @@ void SymCheck (void)
if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) { if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) {
/* Imported symbol is not referenced */ /* Imported symbol is not referenced */
LIWarning (&S->DefLines, 2, LIWarning (&S->DefLines, 2,
"Symbol '%m%p' is imported but never used", "Symbol `%m%p' is imported but never used",
GetSymName (S)); GetSymName (S));
} else { } else {
/* Give the import an id, count imports */ /* Give the import an id, count imports */
@@ -664,7 +664,7 @@ void SymCheck (void)
} else if (S->AddrSize > S->ExportSize) { } else if (S->AddrSize > S->ExportSize) {
/* We're exporting a symbol smaller than it actually is */ /* We're exporting a symbol smaller than it actually is */
LIWarning (&S->DefLines, 1, LIWarning (&S->DefLines, 1,
"Symbol '%m%p' is %s but exported %s", "Symbol `%m%p' is %s but exported %s",
GetSymName (S), GetSymName (S),
AddrSizeToStr (S->AddrSize), AddrSizeToStr (S->AddrSize),
AddrSizeToStr (S->ExportSize)); AddrSizeToStr (S->ExportSize));
@@ -684,7 +684,7 @@ void SymCheck (void)
const FilePos* P = S->GuessedUse[S->AddrSize - 1]; const FilePos* P = S->GuessedUse[S->AddrSize - 1];
if (P) { if (P) {
PWarning (P, 0, PWarning (P, 0,
"Didn't use %s addressing for '%m%p'", "Didn't use %s addressing for `%m%p'",
AddrSizeToStr (S->AddrSize), AddrSizeToStr (S->AddrSize),
GetSymName (S)); GetSymName (S));
} }