Merge pull request #2802 from kugelfuhr/kugelfuhr/modernize-ld65-diags
Modernize ld65 diagnostics
This commit is contained in:
@@ -110,6 +110,7 @@ Long options:
|
||||
--target sys Set the target system
|
||||
--verbose Increase verbosity
|
||||
--version Print the compiler version number
|
||||
--warnings-as-errors Treat warnings as errors
|
||||
--writable-strings Make string literals writable
|
||||
---------------------------------------------------------------------------
|
||||
</verb></tscreen>
|
||||
@@ -656,6 +657,15 @@ Here is a description of all the command line options:
|
||||
or warnings are encountered.
|
||||
|
||||
|
||||
<label id="option--warnings-as-errors">
|
||||
<tag><tt>--warnings-as-errors</tt></tag>
|
||||
|
||||
Treat all warnings as error. This makes the compiler exit with an appropriate
|
||||
error code in case of warnings. The effect of this switch is identical to
|
||||
the command line option <tt/<ref id="option-W" name="-W error">/. It is
|
||||
available for compatibility with the other tools.
|
||||
|
||||
|
||||
<label id="option-writable-strings">
|
||||
<tag><tt>--writable-strings</tt></tag>
|
||||
|
||||
@@ -766,7 +776,9 @@ Here is a description of all the command line options:
|
||||
<tag><tt/const-comparison/</tag>
|
||||
Warn if the result of a comparison is constant.
|
||||
<tag><tt/error/</tag>
|
||||
Treat all warnings as errors.
|
||||
Treat all warnings as errors. This has the same effect as using the
|
||||
<tt/<ref id="option--warnings-as-errors" name="--warnings-as-errors">/
|
||||
option.
|
||||
<tag><tt/no-effect/</tag>
|
||||
Warn about statements that don't have an effect.
|
||||
<tag><tt/pointer-sign/</tag>
|
||||
|
||||
@@ -34,7 +34,7 @@ and other things.
|
||||
---------------------------------------------------------------------------
|
||||
Usage: cl65 [options] file [...]
|
||||
Short options:
|
||||
-c Compile and assemble but don't link
|
||||
-c Compile and assemble, but don't link
|
||||
-d Debug mode
|
||||
-g Add debug info
|
||||
-h Help (this text)
|
||||
@@ -55,10 +55,10 @@ Short options:
|
||||
-L path Specify a library search path
|
||||
-Ln name Create a VICE label file
|
||||
-O Optimize code
|
||||
-Oi Optimize code, inline more code
|
||||
-Oi Optimize code, inline runtime functions
|
||||
-Or Optimize code, honour the register keyword
|
||||
-Os Optimize code, inline standard functions
|
||||
-S Compile but don't assemble and link
|
||||
-Os Optimize code, inline known C functions
|
||||
-S Compile, but don't assemble and link
|
||||
-T Include source as comment
|
||||
-V Print the version number
|
||||
-W name[,...] Suppress compiler warnings
|
||||
@@ -81,8 +81,9 @@ Long options:
|
||||
--code-label name Define and export a CODE segment label
|
||||
--code-name seg Set the name of the CODE segment
|
||||
--codesize x Accept larger code by factor x
|
||||
--color [on|auto|off] Color diagnostics (default: auto)
|
||||
--config name Use linker config file
|
||||
--cpu type Set cpu type
|
||||
--cpu type Set CPU type
|
||||
--create-dep name Create a make dependency file
|
||||
--create-full-dep name Create a full make dependency file
|
||||
--data-label name Define and export a DATA segment label
|
||||
@@ -101,8 +102,9 @@ Long options:
|
||||
--mapfile name Create a map file
|
||||
--memory-model model Set the memory model
|
||||
--module Link as a module
|
||||
--module-id id Specify a module id for the linker
|
||||
--module-id id Specify a module ID for the linker
|
||||
--no-target-lib Don't link the target library
|
||||
--no-utf8 Disable use of UTF-8 in diagnostics
|
||||
--o65-model model Override the o65 model
|
||||
--obj file Link this object file
|
||||
--obj-path path Specify an object file search path
|
||||
|
||||
@@ -73,6 +73,7 @@ Short options:
|
||||
Long options:
|
||||
--allow-multiple-definition Allow multiple definitions
|
||||
--cfg-path path Specify a config file search path
|
||||
--color [on|auto|off] Color diagnostics (default: auto)
|
||||
--config name Use linker config file
|
||||
--dbgfile name Generate debug information
|
||||
--define sym=val Define a symbol
|
||||
@@ -84,13 +85,13 @@ Long options:
|
||||
--lib-path path Specify a library search path
|
||||
--mapfile name Create a map file
|
||||
--module-id id Specify a module id
|
||||
--no-utf8 Disable use of UTF-8 in diagnostics
|
||||
--obj file Link this object file
|
||||
--obj-path path Specify an object file search path
|
||||
--start-addr addr Set the default start address
|
||||
--start-group Start a library group
|
||||
--target sys Set the target system
|
||||
--version Print the linker version
|
||||
--warnings-as-errors Treat warnings as errors
|
||||
---------------------------------------------------------------------------
|
||||
</verb></tscreen>
|
||||
|
||||
@@ -292,6 +293,14 @@ Here is a description of all of the command-line options:
|
||||
and in a built-in default directory.
|
||||
|
||||
|
||||
<label id="option--color">
|
||||
<tag><tt>--color</tt></tag>
|
||||
|
||||
This option controls if the linker will use colors when printing
|
||||
diagnostics. The default is "auto" which will enable colors if the output
|
||||
goes to a terminal (not to a file).
|
||||
|
||||
|
||||
<label id="option--dbgfile">
|
||||
<tag><tt>--dbgfile name</tt></tag>
|
||||
|
||||
@@ -315,6 +324,14 @@ Here is a description of all of the command-line options:
|
||||
type because of an unusual extension.
|
||||
|
||||
|
||||
<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.
|
||||
|
||||
|
||||
<tag><tt>--obj file</tt></tag>
|
||||
|
||||
Links an object file to the output. Use this command-line option instead
|
||||
|
||||
@@ -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"
|
||||
};
|
||||
|
||||
|
||||
@@ -504,14 +504,11 @@ static void OptBinIncludeDir (const char* Opt attribute ((unused)), const char*
|
||||
static void OptColor(const char* Opt, const char* Arg)
|
||||
/* Handle the --color option */
|
||||
{
|
||||
if (strcmp (Arg, "off") == 0 || strcmp (Arg, "false") == 0) {
|
||||
CP_SetColorMode (CM_OFF);
|
||||
} else if (strcmp (Arg, "auto") == 0) {
|
||||
CP_SetColorMode (CM_AUTO);
|
||||
} else if (strcmp (Arg, "on") == 0 || strcmp (Arg, "true") == 0) {
|
||||
CP_SetColorMode (CM_ON);
|
||||
} else {
|
||||
ColorMode Mode = CP_Parse (Arg);
|
||||
if (Mode == CM_INVALID) {
|
||||
AbEnd ("Invalid argument to %s: %s", Opt, Arg);
|
||||
} else {
|
||||
CP_SetColorMode (Mode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -745,6 +742,8 @@ static void OptVersion (const char* Opt attribute ((unused)),
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptSeglist (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Enable segment listing */
|
||||
@@ -752,6 +751,8 @@ static void OptSeglist (const char* Opt attribute ((unused)),
|
||||
SegList = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptWarningsAsErrors (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Generate an error if any warnings occur */
|
||||
@@ -759,6 +760,8 @@ static void OptWarningsAsErrors (const char* Opt attribute ((unused)),
|
||||
WarningsAsErrors = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptExpandMacros (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Expand macros in listing
|
||||
@@ -770,6 +773,8 @@ static void OptExpandMacros (const char* Opt attribute ((unused)),
|
||||
ExpandMacros++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void DoPCAssign (void)
|
||||
/* Start absolute code */
|
||||
{
|
||||
|
||||
@@ -140,6 +140,7 @@ static void Usage (void)
|
||||
" --target sys\t\t\tSet the target system\n"
|
||||
" --verbose\t\t\tIncrease verbosity\n"
|
||||
" --version\t\t\tPrint the compiler version number\n"
|
||||
" --warnings-as-errors\t\tTreat warnings as errors\n"
|
||||
" --writable-strings\t\tMake string literals writable\n",
|
||||
ProgName);
|
||||
}
|
||||
@@ -968,6 +969,15 @@ static void OptWarning (const char* Opt attribute ((unused)), const char* Arg)
|
||||
|
||||
|
||||
|
||||
static void OptWarningsAsErrors (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Generate an error if any warnings occur */
|
||||
{
|
||||
IS_Set (&WarningsAreErrors, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptWritableStrings (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Make string literals writable */
|
||||
@@ -1016,6 +1026,7 @@ int main (int argc, char* argv[])
|
||||
{ "--target", 1, OptTarget },
|
||||
{ "--verbose", 0, OptVerbose },
|
||||
{ "--version", 0, OptVersion },
|
||||
{ "--warnings-as-errors", 0, OptWarningsAsErrors },
|
||||
{ "--writable-strings", 0, OptWritableStrings },
|
||||
};
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
/* common */
|
||||
#include "attrib.h"
|
||||
#include "cmdline.h"
|
||||
#include "consprop.h"
|
||||
#include "filetype.h"
|
||||
#include "fname.h"
|
||||
#include "mmodel.h"
|
||||
@@ -858,6 +859,7 @@ static void Usage (void)
|
||||
" --code-label name\t\tDefine and export a CODE segment label\n"
|
||||
" --code-name seg\t\tSet the name of the CODE segment\n"
|
||||
" --codesize x\t\t\tAccept larger code by factor x\n"
|
||||
" --color [on|auto|off]\t\tColor diagnostics (default: auto)\n"
|
||||
" --config name\t\t\tUse linker config file\n"
|
||||
" --cpu type\t\t\tSet CPU type\n"
|
||||
" --create-dep name\t\tCreate a make dependency file\n"
|
||||
@@ -880,6 +882,7 @@ static void Usage (void)
|
||||
" --module\t\t\tLink as a module\n"
|
||||
" --module-id id\t\tSpecify a module ID for the linker\n"
|
||||
" --no-target-lib\t\tDon't link the target library\n"
|
||||
" --no-utf8\t\t\tDisable use of UTF-8 in diagnostics\n"
|
||||
" --o65-model model\t\tOverride the o65 model\n"
|
||||
" --obj file\t\t\tLink this object file\n"
|
||||
" --obj-path path\t\tSpecify an object file search path\n"
|
||||
@@ -895,7 +898,8 @@ static void Usage (void)
|
||||
" --version\t\t\tPrint the version number\n"
|
||||
" --verbose\t\t\tVerbose mode\n"
|
||||
" --zeropage-label name\t\tDefine and export a ZEROPAGE segment label\n"
|
||||
" --zeropage-name seg\t\tSet the name of the ZEROPAGE segment\n",
|
||||
" --zeropage-name seg\t\tSet the name of the ZEROPAGE segment\n"
|
||||
" --warnings-as-errors\t\tTreat warnings as errors\n",
|
||||
ProgName);
|
||||
}
|
||||
|
||||
@@ -1028,6 +1032,19 @@ static void OptConfig (const char* Opt attribute ((unused)), const char* Arg)
|
||||
|
||||
|
||||
|
||||
static void OptColor(const char* Opt, const char* Arg)
|
||||
/* Handle the --color option */
|
||||
{
|
||||
if (CP_Parse (Arg) == CM_INVALID) {
|
||||
Error ("Invalid argument to %s: %s", Opt, Arg);
|
||||
} else {
|
||||
CmdAddArg2 (&CA65, "--color", Arg);
|
||||
CmdAddArg2 (&LD65, "--color", Arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptCPU (const char* Opt attribute ((unused)), const char* Arg)
|
||||
/* Handle the --cpu option */
|
||||
{
|
||||
@@ -1236,6 +1253,16 @@ static void OptNoTargetLib (const char* Opt attribute ((unused)),
|
||||
|
||||
|
||||
|
||||
static void OptNoUtf8 (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Handle the --no-utf8 option */
|
||||
{
|
||||
CmdAddArg (&CA65, "--no-utf8");
|
||||
CmdAddArg (&LD65, "--no-utf8");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptO65Model (const char* Opt attribute ((unused)), const char* Arg)
|
||||
/* Handle the --o65-model option */
|
||||
{
|
||||
@@ -1409,6 +1436,17 @@ static void OptZeropageName (const char* Opt attribute ((unused)), const char* A
|
||||
|
||||
|
||||
|
||||
static void OptWarningsAsErrors (const char* Opt attribute ((unused)),
|
||||
const char* Arg attribute ((unused)))
|
||||
/* Handle the --warnings-as-errors option */
|
||||
{
|
||||
CmdAddArg (&CA65, "--warnings-as-errors");
|
||||
CmdAddArg (&CC65, "--warnings-as-errors");
|
||||
CmdAddArg (&LD65, "--warnings-as-errors");
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main (int argc, char* argv [])
|
||||
/* Utility main program */
|
||||
{
|
||||
@@ -1428,6 +1466,7 @@ int main (int argc, char* argv [])
|
||||
{ "--code-label", 1, OptCodeLabel },
|
||||
{ "--code-name", 1, OptCodeName },
|
||||
{ "--codesize", 1, OptCodeSize },
|
||||
{ "--color", 1, OptColor },
|
||||
{ "--config", 1, OptConfig },
|
||||
{ "--cpu", 1, OptCPU },
|
||||
{ "--create-dep", 1, OptCreateDep },
|
||||
@@ -1450,10 +1489,11 @@ int main (int argc, char* argv [])
|
||||
{ "--module", 0, OptModule },
|
||||
{ "--module-id", 1, OptModuleId },
|
||||
{ "--no-target-lib", 0, OptNoTargetLib },
|
||||
{ "--no-utf8", 0, OptNoUtf8 },
|
||||
{ "--o65-model", 1, OptO65Model },
|
||||
{ "--obj", 1, OptObj },
|
||||
{ "--obj-path", 1, OptObjPath },
|
||||
{ "--print-target-path", 0, OptPrintTargetPath},
|
||||
{ "--print-target-path", 0, OptPrintTargetPath },
|
||||
{ "--register-space", 1, OptRegisterSpace },
|
||||
{ "--register-vars", 0, OptRegisterVars },
|
||||
{ "--rodata-name", 1, OptRodataName },
|
||||
@@ -1466,6 +1506,7 @@ int main (int argc, char* argv [])
|
||||
{ "--version", 0, OptVersion },
|
||||
{ "--zeropage-label", 1, OptZeropageLabel },
|
||||
{ "--zeropage-name", 1, OptZeropageName },
|
||||
{ "--warnings-as-errors", 0, OptWarningsAsErrors },
|
||||
};
|
||||
|
||||
char* CmdPath;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if !defined(_WIN32)
|
||||
# include <unistd.h>
|
||||
#else
|
||||
@@ -153,6 +154,23 @@ void CP_Init (void)
|
||||
|
||||
|
||||
|
||||
ColorMode CP_Parse (const char* Mode)
|
||||
/* Parse the given string which is assumed to be one of the color modes.
|
||||
* Return the matching enum or CM_INVALID if there was no match.
|
||||
*/
|
||||
{
|
||||
if (strcmp (Mode, "off") == 0 || strcmp (Mode, "false") == 0) {
|
||||
return CM_OFF;
|
||||
} else if (strcmp (Mode, "auto") == 0) {
|
||||
return CM_AUTO;
|
||||
} else if (strcmp (Mode, "on") == 0 || strcmp (Mode, "true") == 0) {
|
||||
return CM_ON;
|
||||
} else {
|
||||
return CM_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int CP_IsTTY (void)
|
||||
/* Return true if console output goes to a tty */
|
||||
{
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
|
||||
/* Color mode for the program */
|
||||
enum ColorMode { CM_OFF, CM_AUTO, CM_ON };
|
||||
enum ColorMode { CM_INVALID = -1, CM_OFF, CM_AUTO, CM_ON };
|
||||
typedef enum ColorMode ColorMode;
|
||||
|
||||
/* Colors */
|
||||
@@ -96,6 +96,11 @@ void CP_Init (void);
|
||||
** data from this module.
|
||||
**/
|
||||
|
||||
ColorMode CP_Parse (const char* Mode);
|
||||
/* Parse the given string which is assumed to be one of the color modes.
|
||||
** Return the matching enum or CM_INVALID if there was no match.
|
||||
*/
|
||||
|
||||
int CP_IsTTY (void);
|
||||
/* Return true if console output goes to a tty */
|
||||
|
||||
|
||||
@@ -109,8 +109,8 @@ void CheckAssertions (void)
|
||||
for (I = 0; I < CollCount (&Assertions); ++I) {
|
||||
|
||||
const LineInfo* LI;
|
||||
const char* Module;
|
||||
unsigned Line;
|
||||
const FilePos* Pos;
|
||||
const char* Message;
|
||||
|
||||
/* Get the assertion */
|
||||
Assertion* A = CollAtUnchecked (&Assertions, I);
|
||||
@@ -120,38 +120,33 @@ void CheckAssertions (void)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Retrieve the relevant line info for this assertion */
|
||||
/* Get some assertion data */
|
||||
Message = GetString (A->Msg);
|
||||
LI = CollConstAt (&A->LineInfos, 0);
|
||||
|
||||
/* Get file name and line number from the source */
|
||||
Module = GetSourceName (LI);
|
||||
Line = GetSourceLine (LI);
|
||||
Pos = GetSourcePos (LI);
|
||||
|
||||
/* 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",
|
||||
Module, Line);
|
||||
AddPNote (Pos, "The assert message is: \"%s\"", Message);
|
||||
PWarning (Pos, "Cannot evaluate this source code assertion");
|
||||
} else if (GetExprVal (A->Expr) == 0) {
|
||||
|
||||
/* Assertion failed */
|
||||
const char* Message = GetString (A->Msg);
|
||||
|
||||
switch (A->Action) {
|
||||
|
||||
case ASSERT_ACT_WARN:
|
||||
case ASSERT_ACT_LDWARN:
|
||||
Warning ("%s:%u: %s", Module, Line, Message);
|
||||
PWarning (Pos, "Assertion failed: %s", Message);
|
||||
break;
|
||||
|
||||
case ASSERT_ACT_ERROR:
|
||||
case ASSERT_ACT_LDERROR:
|
||||
Error ("%s:%u: %s", Module, Line, Message);
|
||||
PError (Pos, "Assertion failed: %s", Message);
|
||||
break;
|
||||
|
||||
default:
|
||||
Internal ("Invalid assertion action (%u) in module '%s', "
|
||||
"line %u (file corrupt?)",
|
||||
A->Action, Module, Line);
|
||||
AddPNote (Pos, "The file might be corrupt or wrong version");
|
||||
PError (Pos, "Invalid assertion action %u", A->Action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,11 +301,11 @@ void BinWriteTarget (BinDesc* D, struct File* F)
|
||||
/* Open the file */
|
||||
D->F = fopen (D->Filename, "wb");
|
||||
if (D->F == 0) {
|
||||
Error ("Cannot open '%s': %s", D->Filename, strerror (errno));
|
||||
Error ("Cannot open `%s': %s", D->Filename, strerror (errno));
|
||||
}
|
||||
|
||||
/* Keep the user happy */
|
||||
Print (stdout, 1, "Opened '%s'...\n", D->Filename);
|
||||
Print (stdout, 1, "Opened `%s'...\n", D->Filename);
|
||||
|
||||
/* Dump all memory areas */
|
||||
for (I = 0; I < CollCount (&F->MemoryAreas); ++I) {
|
||||
@@ -317,7 +317,7 @@ void BinWriteTarget (BinDesc* D, struct File* F)
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (D->F) != 0) {
|
||||
Error ("Cannot write to '%s': %s", D->Filename, strerror (errno));
|
||||
Error ("Cannot write to `%s': %s", D->Filename, strerror (errno));
|
||||
}
|
||||
|
||||
/* Reset the file and filename */
|
||||
|
||||
@@ -105,11 +105,11 @@ static ExprNode* Factor (void)
|
||||
/* Left parenthesis */
|
||||
CfgNextTok ();
|
||||
N = CfgExpr ();
|
||||
CfgConsume (CFGTOK_RPAR, "')' expected");
|
||||
CfgConsume (CFGTOK_RPAR, "`)' expected");
|
||||
break;
|
||||
|
||||
default:
|
||||
CfgError (&CfgErrorPos, "Invalid expression: %d", CfgTok);
|
||||
PError (&CfgErrorPos, "Invalid expression: %d", CfgTok);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ long CfgConstExpr (void)
|
||||
|
||||
/* Check that it's const */
|
||||
if (!IsConstExpr (Expr)) {
|
||||
CfgError (&CfgErrorPos, "Constant expression expected");
|
||||
PError (&CfgErrorPos, "Constant expression expected");
|
||||
}
|
||||
|
||||
/* Get the value */
|
||||
@@ -238,7 +238,7 @@ long CfgCheckedConstExpr (long Min, long Max)
|
||||
|
||||
/* Check the range */
|
||||
if (Val < Min || Val > Max) {
|
||||
CfgError (&CfgErrorPos, "Range error");
|
||||
PError (&CfgErrorPos, "Range error");
|
||||
}
|
||||
|
||||
/* Return the value */
|
||||
|
||||
@@ -228,7 +228,7 @@ static MemoryArea* CfgGetMemory (unsigned Name)
|
||||
{
|
||||
MemoryArea* M = CfgFindMemory (Name);
|
||||
if (M == 0) {
|
||||
CfgError (&CfgErrorPos, "Invalid memory area '%s'", GetString (Name));
|
||||
PError (&CfgErrorPos, "Invalid memory area `%s'", GetString (Name));
|
||||
}
|
||||
return M;
|
||||
}
|
||||
@@ -321,8 +321,7 @@ static MemoryArea* CreateMemoryArea (const FilePos* Pos, unsigned Name)
|
||||
/* Check for duplicate names */
|
||||
MemoryArea* M = CfgFindMemory (Name);
|
||||
if (M) {
|
||||
CfgError (&CfgErrorPos,
|
||||
"Memory area '%s' defined twice",
|
||||
PError (&CfgErrorPos, "Memory area `%s' defined twice",
|
||||
GetString (Name));
|
||||
}
|
||||
|
||||
@@ -345,7 +344,7 @@ static SegDesc* NewSegDesc (unsigned Name)
|
||||
/* Check for duplicate names */
|
||||
SegDesc* S = CfgFindSegDesc (Name);
|
||||
if (S) {
|
||||
CfgError (&CfgErrorPos, "Segment '%s' defined twice", GetString (Name));
|
||||
PError (&CfgErrorPos, "Segment `%s' defined twice", GetString (Name));
|
||||
}
|
||||
|
||||
/* Allocate memory */
|
||||
@@ -391,7 +390,7 @@ static void FlagAttr (unsigned* Flags, unsigned Mask, const char* Name)
|
||||
*/
|
||||
{
|
||||
if (*Flags & Mask) {
|
||||
CfgError (&CfgErrorPos, "%s is already defined", Name);
|
||||
PError (&CfgErrorPos, "Attribute `%s' is already defined", Name);
|
||||
}
|
||||
*Flags |= Mask;
|
||||
}
|
||||
@@ -402,7 +401,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);
|
||||
PError (&CfgErrorPos, "Mandatory attribute `%s' is missing", Name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,7 +439,8 @@ static void ParseMemory (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t AttrTok;
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes),
|
||||
"Memory attribute");
|
||||
AttrTok = CfgTok;
|
||||
|
||||
/* An optional assignment follows */
|
||||
@@ -500,7 +500,7 @@ static void ParseMemory (void)
|
||||
|
||||
case CFGTOK_TYPE:
|
||||
FlagAttr (&M->Attr, MA_TYPE, "TYPE");
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "TYPE");
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Memory type");
|
||||
if (CfgTok == CFGTOK_RO) {
|
||||
M->Flags |= MF_RO;
|
||||
}
|
||||
@@ -554,7 +554,7 @@ static void ParseFiles (void)
|
||||
|
||||
/* The MEMORY section must preceed the FILES section */
|
||||
if ((SectionsEncountered & SE_MEMORY) == 0) {
|
||||
CfgError (&CfgErrorPos, "MEMORY must precede FILES");
|
||||
PError (&CfgErrorPos, "`MEMORY' must precede `FILES'");
|
||||
}
|
||||
|
||||
/* Parse all files */
|
||||
@@ -568,8 +568,7 @@ static void ParseFiles (void)
|
||||
/* Search for the file, it must exist */
|
||||
F = FindFile (GetStrBufId (&CfgSVal));
|
||||
if (F == 0) {
|
||||
CfgError (&CfgErrorPos,
|
||||
"File '%s' not found in MEMORY section",
|
||||
PError (&CfgErrorPos, "File `%s' not found in `MEMORY' section",
|
||||
SB_GetConstBuf (&CfgSVal));
|
||||
}
|
||||
|
||||
@@ -582,7 +581,8 @@ static void ParseFiles (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t AttrTok;
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes),
|
||||
"File attribute");
|
||||
AttrTok = CfgTok;
|
||||
|
||||
/* An optional assignment follows */
|
||||
@@ -595,11 +595,10 @@ static void ParseFiles (void)
|
||||
case CFGTOK_FORMAT:
|
||||
if (F->Format != BINFMT_DEFAULT) {
|
||||
/* We've set the format already! */
|
||||
CfgError (&CfgErrorPos,
|
||||
"Cannot set a file format twice");
|
||||
PError (&CfgErrorPos, "Cannot set a file format twice");
|
||||
}
|
||||
/* Read the format token */
|
||||
CfgSpecialToken (Formats, ENTRY_COUNT (Formats), "Format");
|
||||
CfgSpecialToken (Formats, ENTRY_COUNT (Formats), "File format");
|
||||
switch (CfgTok) {
|
||||
|
||||
case CFGTOK_BIN:
|
||||
@@ -667,7 +666,7 @@ static void ParseSegments (void)
|
||||
|
||||
/* The MEMORY section must preceed the SEGMENTS section */
|
||||
if ((SectionsEncountered & SE_MEMORY) == 0) {
|
||||
CfgError (&CfgErrorPos, "MEMORY must precede SEGMENTS");
|
||||
PError (&CfgErrorPos, "`MEMORY' must precede `SEGMENTS'");
|
||||
}
|
||||
|
||||
while (CfgTok == CFGTOK_IDENT) {
|
||||
@@ -686,7 +685,7 @@ static void ParseSegments (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t AttrTok;
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Segment attribute");
|
||||
AttrTok = CfgTok;
|
||||
|
||||
/* An optional assignment follows */
|
||||
@@ -759,7 +758,7 @@ static void ParseSegments (void)
|
||||
|
||||
case CFGTOK_TYPE:
|
||||
FlagAttr (&S->Attr, SA_TYPE, "TYPE");
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Segment type");
|
||||
switch (CfgTok) {
|
||||
case CFGTOK_RO: S->Flags |= SF_RO; break;
|
||||
case CFGTOK_RW: /* Default */ break;
|
||||
@@ -793,9 +792,9 @@ static void ParseSegments (void)
|
||||
** separate run and load memory areas.
|
||||
*/
|
||||
if ((S->Flags & SF_ALIGN_LOAD) != 0 && (S->Load == S->Run)) {
|
||||
CfgWarning (&CfgErrorPos,
|
||||
"ALIGN_LOAD attribute specified, but no separate "
|
||||
"LOAD and RUN memory areas assigned");
|
||||
PWarning (&CfgErrorPos,
|
||||
"`ALIGN_LOAD' attribute specified, but no separate "
|
||||
"`LOAD' and `RUN' memory areas assigned");
|
||||
/* Remove the flag */
|
||||
S->Flags &= ~SF_ALIGN_LOAD;
|
||||
}
|
||||
@@ -804,16 +803,16 @@ static void ParseSegments (void)
|
||||
** load and run memory areas, because it's is never written to disk.
|
||||
*/
|
||||
if ((S->Flags & SF_BSS) != 0 && (S->Load != S->Run)) {
|
||||
CfgWarning (&CfgErrorPos,
|
||||
"Segment with type 'bss' has both LOAD and RUN "
|
||||
PWarning (&CfgErrorPos,
|
||||
"Segment with type `bss' has both `LOAD' and `RUN' "
|
||||
"memory areas assigned");
|
||||
}
|
||||
|
||||
/* Don't allow read/write data to be put into a readonly area */
|
||||
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'",
|
||||
PError (&CfgErrorPos,
|
||||
"Cannot place r/w segment `%s' in r/o memory area `%s'",
|
||||
GetString (S->Name), GetString (S->Run->Name));
|
||||
}
|
||||
}
|
||||
@@ -823,8 +822,8 @@ static void ParseSegments (void)
|
||||
((S->Flags & SF_OFFSET) != 0) +
|
||||
((S->Flags & SF_START) != 0);
|
||||
if (Count > 1) {
|
||||
CfgError (&CfgErrorPos,
|
||||
"Only one of ALIGN, START, OFFSET may be used");
|
||||
PError (&CfgErrorPos,
|
||||
"Only one of `ALIGN', `START' or `OFFSET' may be used");
|
||||
}
|
||||
|
||||
/* Skip the semicolon */
|
||||
@@ -881,7 +880,7 @@ static void ParseO65 (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t AttrTok;
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "O65 attribute");
|
||||
AttrTok = CfgTok;
|
||||
|
||||
/* An optional assignment follows */
|
||||
@@ -924,7 +923,7 @@ static void ParseO65 (void)
|
||||
/* Cannot have this attribute twice */
|
||||
FlagAttr (&AttrFlags, atType, "TYPE");
|
||||
/* Get the type of the executable */
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "O65 type");
|
||||
switch (CfgTok) {
|
||||
|
||||
case CFGTOK_SMALL:
|
||||
@@ -936,7 +935,7 @@ static void ParseO65 (void)
|
||||
break;
|
||||
|
||||
default:
|
||||
CfgError (&CfgErrorPos, "Unexpected type token");
|
||||
PError (&CfgErrorPos, "Unexpected type token");
|
||||
}
|
||||
/* Eat the attribute token */
|
||||
CfgNextTok ();
|
||||
@@ -952,13 +951,15 @@ static void ParseO65 (void)
|
||||
CfgRangeCheck (O65OS_MIN, O65OS_MAX);
|
||||
OS = (unsigned) CfgIVal;
|
||||
} else {
|
||||
CfgSpecialToken (OperatingSystems, ENTRY_COUNT (OperatingSystems), "OS type");
|
||||
CfgSpecialToken (OperatingSystems,
|
||||
ENTRY_COUNT (OperatingSystems),
|
||||
"O65 OS specification");
|
||||
switch (CfgTok) {
|
||||
case CFGTOK_LUNIX: OS = O65OS_LUNIX; break;
|
||||
case CFGTOK_OSA65: OS = O65OS_OSA65; break;
|
||||
case CFGTOK_CC65: OS = O65OS_CC65; break;
|
||||
case CFGTOK_OPENCBM: OS = O65OS_OPENCBM; break;
|
||||
default: CfgError (&CfgErrorPos, "Unexpected OS token");
|
||||
default: PError (&CfgErrorPos, "Unexpected OS token");
|
||||
}
|
||||
}
|
||||
CfgNextTok ();
|
||||
@@ -993,12 +994,12 @@ static void ParseO65 (void)
|
||||
/* Check for attributes that may not be combined */
|
||||
if (OS == O65OS_CC65) {
|
||||
if ((AttrFlags & (atImport | atExport)) != 0 && ModuleId < 0x8000) {
|
||||
CfgError (&CfgErrorPos,
|
||||
PError (&CfgErrorPos,
|
||||
"OS type CC65 may not have imports or exports for ids < $8000");
|
||||
}
|
||||
} else {
|
||||
if (AttrFlags & atID) {
|
||||
CfgError (&CfgErrorPos,
|
||||
PError (&CfgErrorPos,
|
||||
"Operating system does not support the ID attribute");
|
||||
}
|
||||
}
|
||||
@@ -1033,7 +1034,7 @@ static void ParseXex (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t AttrTok;
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Xex attribute");
|
||||
AttrTok = CfgTok;
|
||||
|
||||
/* An optional assignment follows */
|
||||
@@ -1071,7 +1072,7 @@ static void ParseXex (void)
|
||||
CfgNextTok ();
|
||||
/* Add to XEX */
|
||||
if (XexAddInitAd (XexFmtDesc, InitMem, InitAd))
|
||||
CfgError (&CfgErrorPos, "INITAD already given for memory area");
|
||||
PError (&CfgErrorPos, "`INITAD' already given for memory area");
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1104,7 +1105,7 @@ static void ParseFormats (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t FormatTok;
|
||||
CfgSpecialToken (Formats, ENTRY_COUNT (Formats), "Format");
|
||||
CfgSpecialToken (Formats, ENTRY_COUNT (Formats), "Format attribute");
|
||||
FormatTok = CfgTok;
|
||||
|
||||
/* Skip the name and the following colon */
|
||||
@@ -1190,7 +1191,8 @@ static void ParseConDes (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t AttrTok;
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes),
|
||||
"CONDES attribute");
|
||||
AttrTok = CfgTok;
|
||||
|
||||
/* An optional assignment follows */
|
||||
@@ -1232,7 +1234,7 @@ static void ParseConDes (void)
|
||||
case CFGTOK_ORDER:
|
||||
/* Don't allow this twice */
|
||||
FlagAttr (&AttrFlags, atOrder, "ORDER");
|
||||
CfgSpecialToken (Orders, ENTRY_COUNT (Orders), "Order");
|
||||
CfgSpecialToken (Orders, ENTRY_COUNT (Orders), "CONDES order");
|
||||
switch (CfgTok) {
|
||||
case CFGTOK_DECREASING: Order = cdDecreasing; break;
|
||||
case CFGTOK_INCREASING: Order = cdIncreasing; break;
|
||||
@@ -1257,7 +1259,7 @@ static void ParseConDes (void)
|
||||
CfgRangeCheck (CD_TYPE_MIN, CD_TYPE_MAX);
|
||||
Type = (int) CfgIVal;
|
||||
} else {
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "CONDES type");
|
||||
switch (CfgTok) {
|
||||
case CFGTOK_CONSTRUCTOR: Type = CD_TYPE_CON; break;
|
||||
case CFGTOK_DESTRUCTOR: Type = CD_TYPE_DES; break;
|
||||
@@ -1289,9 +1291,9 @@ static void ParseConDes (void)
|
||||
AttrCheck (AttrFlags, atType, "TYPE");
|
||||
|
||||
/* Check if the condes has already attributes defined */
|
||||
if (ConDesHasSegName(Type) || ConDesHasLabel(Type)) {
|
||||
CfgError (&CfgErrorPos,
|
||||
"CONDES attributes for type %d are already defined",
|
||||
if (ConDesHasSegName (Type) || ConDesHasLabel (Type)) {
|
||||
PError (&CfgErrorPos,
|
||||
"`CONDES' attributes for type %d are already defined",
|
||||
Type);
|
||||
}
|
||||
|
||||
@@ -1334,7 +1336,8 @@ static void ParseStartAddress (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t AttrTok;
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes),
|
||||
"Start address attribute");
|
||||
AttrTok = CfgTok;
|
||||
|
||||
/* An optional assignment follows */
|
||||
@@ -1389,7 +1392,7 @@ static void ParseFeatures (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t FeatureTok;
|
||||
CfgSpecialToken (Features, ENTRY_COUNT (Features), "Feature");
|
||||
CfgSpecialToken (Features, ENTRY_COUNT (Features), "Feature attribute");
|
||||
FeatureTok = CfgTok;
|
||||
|
||||
/* Skip the name and the following colon */
|
||||
@@ -1479,7 +1482,8 @@ static void ParseSymbols (void)
|
||||
|
||||
/* Map the identifier to a token */
|
||||
cfgtok_t AttrTok;
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
|
||||
CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes),
|
||||
"Symbol attribute");
|
||||
AttrTok = CfgTok;
|
||||
|
||||
/* Skip the attribute name */
|
||||
@@ -1495,7 +1499,8 @@ static void ParseSymbols (void)
|
||||
/* Don't allow this twice */
|
||||
FlagAttr (&AttrFlags, atAddrSize, "ADDRSIZE");
|
||||
/* Map the type to a token */
|
||||
CfgSpecialToken (AddrSizes, ENTRY_COUNT (AddrSizes), "AddrSize");
|
||||
CfgSpecialToken (AddrSizes, ENTRY_COUNT (AddrSizes),
|
||||
"Address size specification");
|
||||
switch (CfgTok) {
|
||||
case CFGTOK_ABS: AddrSize = ADDR_SIZE_ABS; break;
|
||||
case CFGTOK_FAR: AddrSize = ADDR_SIZE_FAR; break;
|
||||
@@ -1511,7 +1516,8 @@ static void ParseSymbols (void)
|
||||
/* Don't allow this twice */
|
||||
FlagAttr (&AttrFlags, atType, "TYPE");
|
||||
/* Map the type to a token */
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
|
||||
CfgSpecialToken (Types, ENTRY_COUNT (Types),
|
||||
"Address size type");
|
||||
switch (CfgTok) {
|
||||
case CFGTOK_EXPORT: Type = CfgSymExport; break;
|
||||
case CFGTOK_IMPORT: Type = CfgSymImport; break;
|
||||
@@ -1559,7 +1565,7 @@ static void ParseSymbols (void)
|
||||
case CfgSymImport:
|
||||
/* An import must not have a value */
|
||||
if (AttrFlags & atValue) {
|
||||
CfgError (&CfgErrorPos, "Imports must not have a value");
|
||||
PError (&CfgErrorPos, "Imports must not have a value");
|
||||
}
|
||||
/* Generate the import */
|
||||
Imp = InsertImport (GenImport (Name, AddrSize));
|
||||
@@ -1606,12 +1612,13 @@ static void ParseConfig (void)
|
||||
do {
|
||||
|
||||
/* Read the block ident */
|
||||
CfgSpecialToken (BlockNames, ENTRY_COUNT (BlockNames), "Block identifier");
|
||||
CfgSpecialToken (BlockNames, ENTRY_COUNT (BlockNames),
|
||||
"Configuration block identifier");
|
||||
BlockTok = CfgTok;
|
||||
CfgNextTok ();
|
||||
|
||||
/* Expected a curly brace */
|
||||
CfgConsume (CFGTOK_LCURLY, "'{' expected");
|
||||
CfgConsume (CFGTOK_LCURLY, "`{' expected");
|
||||
|
||||
/* Read the block */
|
||||
switch (BlockTok) {
|
||||
@@ -1646,7 +1653,7 @@ static void ParseConfig (void)
|
||||
}
|
||||
|
||||
/* Skip closing brace */
|
||||
CfgConsume (CFGTOK_RCURLY, "'}' expected");
|
||||
CfgConsume (CFGTOK_RCURLY, "`}' expected");
|
||||
|
||||
} while (CfgTok != CFGTOK_EOF);
|
||||
}
|
||||
@@ -1702,10 +1709,20 @@ static void ProcessSegments (void)
|
||||
** in any of the object file, check that there's no initialized data
|
||||
** in the segment.
|
||||
*/
|
||||
if ((S->Flags & SF_BSS) != 0 && S->Seg != 0 && !IsBSSType (S->Seg)) {
|
||||
CfgWarning (GetSourcePos (S->LI),
|
||||
"Segment '%s' with type 'bss' contains initialized data",
|
||||
GetString (S->Name));
|
||||
if ((S->Flags & SF_BSS) != 0 && S->Seg != 0) {
|
||||
Section* Sec = GetNonBSSSection (S->Seg);
|
||||
if (Sec) {
|
||||
const FilePos* Pos = GetSourcePos (S->LI);
|
||||
if (Sec->Obj) {
|
||||
AddPNote (Pos, "Initialized data comes at least partially "
|
||||
"from `%s'", GetString (Sec->Obj->Name));
|
||||
} else {
|
||||
AddPNote (Pos, "Initialized data is at least partially "
|
||||
"linker generated");
|
||||
}
|
||||
PWarning (Pos, "Segment `%s' with type `bss' contains "
|
||||
"initialized data", GetString (S->Name));
|
||||
}
|
||||
}
|
||||
|
||||
/* If this segment does exist in any of the object files, insert the
|
||||
@@ -1732,8 +1749,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",
|
||||
PWarning (&CfgErrorPos, "Segment `%s' does not exist",
|
||||
GetString (S->Name));
|
||||
}
|
||||
|
||||
@@ -1764,9 +1780,9 @@ static void ProcessSymbols (void)
|
||||
case CfgSymO65Export:
|
||||
/* Check if the export symbol is also defined as an import. */
|
||||
if (O65GetImport (O65FmtDesc, Sym->Name) != 0) {
|
||||
CfgError (
|
||||
PError (
|
||||
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)
|
||||
);
|
||||
}
|
||||
@@ -1776,9 +1792,9 @@ static void ProcessSymbols (void)
|
||||
** error message when checking it here.
|
||||
*/
|
||||
if (O65GetExport (O65FmtDesc, Sym->Name) != 0) {
|
||||
CfgError (
|
||||
PError (
|
||||
GetSourcePos (Sym->LI),
|
||||
"Duplicate exported o65 symbol: '%s'",
|
||||
"Duplicate exported o65 symbol: `%s'",
|
||||
GetString (Sym->Name)
|
||||
);
|
||||
}
|
||||
@@ -1790,9 +1806,9 @@ static void ProcessSymbols (void)
|
||||
case CfgSymO65Import:
|
||||
/* Check if the import symbol is also defined as an export. */
|
||||
if (O65GetExport (O65FmtDesc, Sym->Name) != 0) {
|
||||
CfgError (
|
||||
PError (
|
||||
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)
|
||||
);
|
||||
}
|
||||
@@ -1802,9 +1818,9 @@ static void ProcessSymbols (void)
|
||||
** error message when checking it here.
|
||||
*/
|
||||
if (O65GetImport (O65FmtDesc, Sym->Name) != 0) {
|
||||
CfgError (
|
||||
PError (
|
||||
GetSourcePos (Sym->LI),
|
||||
"Duplicate imported o65 symbol: '%s'",
|
||||
"Duplicate imported o65 symbol: `%s'",
|
||||
GetString (Sym->Name)
|
||||
);
|
||||
}
|
||||
@@ -1913,8 +1929,8 @@ unsigned CfgProcess (void)
|
||||
** and mark the memory area as placed.
|
||||
*/
|
||||
if (!IsConstExpr (M->StartExpr)) {
|
||||
CfgError (GetSourcePos (M->LI),
|
||||
"Start address of memory area '%s' is not constant",
|
||||
PError (GetSourcePos (M->LI),
|
||||
"Start address of memory area `%s' is not constant",
|
||||
GetString (M->Name));
|
||||
}
|
||||
Addr = M->Start = GetExprVal (M->StartExpr);
|
||||
@@ -1938,14 +1954,14 @@ unsigned CfgProcess (void)
|
||||
|
||||
/* Resolve the size expression */
|
||||
if (!IsConstExpr (M->SizeExpr)) {
|
||||
CfgError (GetSourcePos (M->LI),
|
||||
"Size of memory area '%s' is not constant",
|
||||
PError (GetSourcePos (M->LI),
|
||||
"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",
|
||||
PError (GetSourcePos (M->LI),
|
||||
"Size of memory area `%s' is negative: %ld",
|
||||
GetString (M->Name), (long)M->Size);
|
||||
}
|
||||
|
||||
@@ -1968,16 +1984,16 @@ unsigned CfgProcess (void)
|
||||
if (S->Flags & (SF_OFFSET | SF_START)) {
|
||||
++Overwrites;
|
||||
} else {
|
||||
CfgError (GetSourcePos (M->LI),
|
||||
"Segment '%s' of type 'overwrite' requires either"
|
||||
" 'Start' or 'Offset' attribute to be specified",
|
||||
PError (GetSourcePos (M->LI),
|
||||
"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'",
|
||||
PError (GetSourcePos (M->LI),
|
||||
"Segment `%s' is preceded by at least one segment"
|
||||
" of type `overwrite'",
|
||||
GetString (S->Name));
|
||||
}
|
||||
}
|
||||
@@ -2002,8 +2018,8 @@ unsigned CfgProcess (void)
|
||||
/* Segment requires another alignment than configured
|
||||
** in the linker.
|
||||
*/
|
||||
CfgWarning (GetSourcePos (S->LI),
|
||||
"Segment '%s' isn't aligned properly; the"
|
||||
PWarning (GetSourcePos (S->LI),
|
||||
"Segment `%s' isn't aligned properly; the"
|
||||
" resulting executable might not be functional.",
|
||||
GetString (S->Name));
|
||||
}
|
||||
@@ -2017,8 +2033,8 @@ unsigned CfgProcess (void)
|
||||
** that is somewhat suspicious.
|
||||
*/
|
||||
if (M->FillLevel == 0 && NewAddr > Addr) {
|
||||
CfgWarning (GetSourcePos (S->LI),
|
||||
"The first segment in memory area '%s' "
|
||||
PWarning (GetSourcePos (S->LI),
|
||||
"The first segment in memory area `%s' "
|
||||
"needs fill bytes for alignment.",
|
||||
GetString (M->Name));
|
||||
}
|
||||
@@ -2038,8 +2054,8 @@ unsigned CfgProcess (void)
|
||||
|
||||
if (S->Flags & SF_OVERWRITE) {
|
||||
if (NewAddr < M->Start) {
|
||||
CfgError (GetSourcePos (S->LI),
|
||||
"Segment '%s' begins before memory area '%s'",
|
||||
PError (GetSourcePos (S->LI),
|
||||
"Segment `%s' begins before memory area `%s'",
|
||||
GetString (S->Name), GetString (M->Name));
|
||||
} else {
|
||||
Addr = NewAddr;
|
||||
@@ -2049,15 +2065,23 @@ unsigned CfgProcess (void)
|
||||
/* Offset already too large */
|
||||
++Overflows;
|
||||
if (S->Flags & SF_OFFSET) {
|
||||
CfgWarning (GetSourcePos (S->LI),
|
||||
"Segment '%s' offset is too small in '%s' by %lu byte%s",
|
||||
GetString (S->Name), GetString (M->Name),
|
||||
Addr - NewAddr, (Addr - NewAddr == 1) ? "" : "s");
|
||||
PWarning (
|
||||
GetSourcePos (S->LI),
|
||||
"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",
|
||||
GetString (S->Name), GetString (M->Name),
|
||||
Addr - NewAddr, (Addr - NewAddr == 1) ? "" : "s");
|
||||
PWarning (
|
||||
GetSourcePos (S->LI),
|
||||
"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"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
Addr = NewAddr;
|
||||
@@ -2101,10 +2125,14 @@ unsigned CfgProcess (void)
|
||||
if (FillLevel > M->Size && (M->Flags & MF_OVERFLOW) == 0) {
|
||||
++Overflows;
|
||||
M->Flags |= MF_OVERFLOW;
|
||||
CfgWarning (GetSourcePos (M->LI),
|
||||
"Segment '%s' overflows memory area '%s' by %lu byte%s",
|
||||
GetString (S->Name), GetString (M->Name),
|
||||
FillLevel - M->Size, (FillLevel - M->Size == 1) ? "" : "s");
|
||||
PWarning (
|
||||
GetSourcePos (M->LI),
|
||||
"Segment `%s' overflows memory area `%s' by %lu byte%s",
|
||||
GetString (S->Name),
|
||||
GetString (M->Name),
|
||||
FillLevel - M->Size,
|
||||
(FillLevel - M->Size == 1) ? "" : "s"
|
||||
);
|
||||
}
|
||||
if (FillLevel > M->FillLevel) {
|
||||
/* Regular segments increase FillLevel. Overwrite segments may
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
304
src/ld65/error.c
304
src/ld65/error.c
@@ -39,10 +39,13 @@
|
||||
|
||||
/* common */
|
||||
#include "cmdline.h"
|
||||
#include "coll.h"
|
||||
#include "consprop.h"
|
||||
#include "strbuf.h"
|
||||
|
||||
/* ld65 */
|
||||
#include "error.h"
|
||||
#include "spool.h"
|
||||
|
||||
|
||||
|
||||
@@ -55,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;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -63,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;
|
||||
@@ -87,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);
|
||||
}
|
||||
|
||||
@@ -107,17 +317,67 @@ 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);
|
||||
SB_VPrintf (&S, Format, ap);
|
||||
VPrintMsg (&NoFile, DC_INT, Format, ap);
|
||||
va_end (ap);
|
||||
SB_Terminate (&S);
|
||||
|
||||
fprintf (stderr, "%s: Internal Error: %s\n", ProgName, SB_GetConstBuf (&S));
|
||||
|
||||
SB_Done (&S);
|
||||
|
||||
/* Terminate after errors */
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AddPNote (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);
|
||||
VPrepMsg (S, Pos, DC_NOTE, Format, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PWarning (const FilePos* Pos, const char* Format, ...)
|
||||
/* Print a warning message adding file name and line number of a given file */
|
||||
{
|
||||
/* Output the message */
|
||||
va_list ap;
|
||||
va_start (ap, Format);
|
||||
VPrintMsg (Pos, DC_WARN, Format, ap);
|
||||
va_end (ap);
|
||||
|
||||
/* Output all stored notes */
|
||||
OutputNotes ();
|
||||
|
||||
/* Count warnings */
|
||||
++WarningCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PError (const FilePos* Pos, const char* Format, ...)
|
||||
/* Print an error message adding file name and line number of a given file */
|
||||
{
|
||||
/* Output the message */
|
||||
va_list ap;
|
||||
va_start (ap, Format);
|
||||
VPrintMsg (Pos, DC_ERR, Format, ap);
|
||||
va_end (ap);
|
||||
|
||||
/* Output all stored notes */
|
||||
OutputNotes ();
|
||||
|
||||
/* Terminate after errors */
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
/* common */
|
||||
#include "attrib.h"
|
||||
#include "filepos.h"
|
||||
|
||||
|
||||
|
||||
@@ -60,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 */
|
||||
|
||||
@@ -69,6 +76,17 @@ 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 AddPNote (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 PWarning (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 */
|
||||
|
||||
void PError (const FilePos* Pos, const char* Format, ...) attribute((format(printf,2,3)));
|
||||
/* Print an error message adding file name and line number of a given file */
|
||||
|
||||
|
||||
|
||||
/* End of error.h */
|
||||
|
||||
@@ -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);
|
||||
PWarning (GetSourcePos (LI),
|
||||
"Unresolved external `%s'",
|
||||
Name);
|
||||
}
|
||||
}
|
||||
Imp = Imp->Next;
|
||||
@@ -1080,7 +1079,7 @@ void CircularRefError (const Export* E)
|
||||
/* Print an error about a circular reference using to define the given export */
|
||||
{
|
||||
const LineInfo* LI = GetExportPos (E);
|
||||
Error ("Circular reference for symbol '%s', %s:%u",
|
||||
Error ("Circular reference for symbol `%s', %s:%u",
|
||||
GetString (E->Name),
|
||||
GetSourceName (LI),
|
||||
GetSourceLine (LI));
|
||||
|
||||
@@ -408,12 +408,12 @@ long GetExprVal (ExprNode* Expr)
|
||||
Error ("Argument of .BANK() isn't a label attached to a segment");
|
||||
}
|
||||
if (D.Seg->MemArea == 0) {
|
||||
Error ("Segment '%s' is referenced by .BANK(),"
|
||||
Error ("Segment `%s' is referenced by .BANK(),"
|
||||
" but not assigned to a memory area",
|
||||
GetString (D.Seg->Name));
|
||||
}
|
||||
if (D.Seg->MemArea->BankExpr == 0) {
|
||||
Error ("Memory area '%s' is referenced by .BANK(),"
|
||||
Error ("Memory area `%s' is referenced by .BANK(),"
|
||||
" but has no BANK attribute",
|
||||
GetString (D.Seg->MemArea->Name));
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ ExtSym* NewExtSym (ExtSymTab* Tab, unsigned Name)
|
||||
ExtSym* E = GetExtSym (Tab, Name);
|
||||
if (E != 0) {
|
||||
/* We do already have a symbol with this name */
|
||||
Error ("Duplicate external symbol '%s'", GetString (Name));
|
||||
Error ("Duplicate external symbol `%s'", GetString (Name));
|
||||
}
|
||||
|
||||
/* Allocate memory for the structure */
|
||||
|
||||
@@ -112,7 +112,7 @@ static void CloseLibrary (Library* L)
|
||||
{
|
||||
/* Close the library file */
|
||||
if (fclose (L->F) != 0) {
|
||||
Error ("Error closing '%s': %s", GetString (L->Name), strerror (errno));
|
||||
Error ("Error closing `%s': %s", GetString (L->Name), strerror (errno));
|
||||
}
|
||||
L->F = 0;
|
||||
}
|
||||
@@ -144,7 +144,7 @@ static void LibSeek (Library* L, unsigned long Offs)
|
||||
/* Do a seek in the library checking for errors */
|
||||
{
|
||||
if (fseek (L->F, Offs, SEEK_SET) != 0) {
|
||||
Error ("Seek error in '%s' (%lu): %s",
|
||||
Error ("Seek error in `%s' (%lu): %s",
|
||||
GetString (L->Name), Offs, strerror (errno));
|
||||
}
|
||||
}
|
||||
@@ -158,7 +158,7 @@ static void LibReadHeader (Library* L)
|
||||
L->Header.Magic = LIB_MAGIC;
|
||||
L->Header.Version = Read16 (L->F);
|
||||
if (L->Header.Version != LIB_VERSION) {
|
||||
Error ("Wrong data version in '%s'", GetString (L->Name));
|
||||
Error ("Wrong data version in `%s'", GetString (L->Name));
|
||||
}
|
||||
L->Header.Flags = Read16 (L->F);
|
||||
L->Header.IndexOffs = Read32 (L->F);
|
||||
@@ -171,12 +171,12 @@ static void LibReadObjHeader (Library* L, ObjData* O)
|
||||
{
|
||||
O->Header.Magic = Read32 (L->F);
|
||||
if (O->Header.Magic != OBJ_MAGIC) {
|
||||
Error ("Object file '%s' in library '%s' is invalid",
|
||||
Error ("Object file `%s' in library `%s' is invalid",
|
||||
GetObjFileName (O), GetString (L->Name));
|
||||
}
|
||||
O->Header.Version = Read16 (L->F);
|
||||
if (O->Header.Version != OBJ_VERSION) {
|
||||
Error ("Object file '%s' in library '%s' has wrong version",
|
||||
Error ("Object file `%s' in library `%s' has wrong version",
|
||||
GetObjFileName (O), GetString (L->Name));
|
||||
}
|
||||
O->Header.Flags = Read16 (L->F);
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "asserts.h"
|
||||
#include "binfmt.h"
|
||||
#include "condes.h"
|
||||
#include "consprop.h"
|
||||
#include "config.h"
|
||||
#include "dbgfile.h"
|
||||
#include "error.h"
|
||||
@@ -130,6 +131,7 @@ static void Usage (void)
|
||||
"Long options:\n"
|
||||
" --allow-multiple-definition\tAllow multiple definitions\n"
|
||||
" --cfg-path path\t\tSpecify a config file search path\n"
|
||||
" --color [on|auto|off]\t\tColor diagnostics (default: auto)\n"
|
||||
" --config name\t\t\tUse linker config file\n"
|
||||
" --dbgfile name\t\tGenerate debug information\n"
|
||||
" --define sym=val\t\tDefine a symbol\n"
|
||||
@@ -141,6 +143,7 @@ static void Usage (void)
|
||||
" --lib-path path\t\tSpecify a library search path\n"
|
||||
" --mapfile name\t\tCreate a map file\n"
|
||||
" --module-id id\t\tSpecify a module id\n"
|
||||
" --no-utf8\t\t\tDisable use of UTF-8 in diagnostics\n"
|
||||
" --obj file\t\t\tLink this object file\n"
|
||||
" --obj-path path\t\tSpecify an object file search path\n"
|
||||
" --start-addr addr\t\tSet the default start address\n"
|
||||
@@ -216,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 */
|
||||
@@ -248,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);
|
||||
|
||||
}
|
||||
|
||||
@@ -310,6 +313,19 @@ static void OptCfgPath (const char* Opt attribute ((unused)), const char* Arg)
|
||||
|
||||
|
||||
|
||||
static void OptColor (const char* Opt, const char* Arg)
|
||||
/* Handle the --color option */
|
||||
{
|
||||
ColorMode Mode = CP_Parse (Arg);
|
||||
if (Mode == CM_INVALID) {
|
||||
Error ("Invalid argument to %s: %s", Opt, Arg);
|
||||
} else {
|
||||
CP_SetColorMode (Mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void OptConfig (const char* Opt attribute ((unused)), const char* Arg)
|
||||
/* Define the config file */
|
||||
{
|
||||
@@ -324,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 */
|
||||
@@ -378,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 */
|
||||
@@ -457,6 +473,15 @@ static void OptModuleId (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 OptObj (const char* Opt attribute ((unused)), const char* Arg)
|
||||
/* Link an object file */
|
||||
{
|
||||
@@ -519,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 */
|
||||
@@ -536,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 */
|
||||
@@ -623,12 +648,13 @@ static void CmdlOptTarget (const char* Opt attribute ((unused)), const char* Arg
|
||||
|
||||
|
||||
|
||||
static void ParseCommandLine(void)
|
||||
static void ParseCommandLine (void)
|
||||
{
|
||||
/* Program long options */
|
||||
static const LongOpt OptTab[] = {
|
||||
{ "--allow-multiple-definition", 0, OptMultDef },
|
||||
{ "--cfg-path", 1, OptCfgPath },
|
||||
{ "--color", 1, OptColor },
|
||||
{ "--config", 1, CmdlOptConfig },
|
||||
{ "--dbgfile", 1, OptDbgFile },
|
||||
{ "--define", 1, OptDefine },
|
||||
@@ -640,6 +666,7 @@ static void ParseCommandLine(void)
|
||||
{ "--lib-path", 1, OptLibPath },
|
||||
{ "--mapfile", 1, OptMapFile },
|
||||
{ "--module-id", 1, OptModuleId },
|
||||
{ "--no-utf8", 0, OptNoUtf8 },
|
||||
{ "--obj", 1, OptObj },
|
||||
{ "--obj-path", 1, OptObjPath },
|
||||
{ "--start-addr", 1, OptStartAddr },
|
||||
@@ -800,6 +827,9 @@ int main (int argc, char* argv [])
|
||||
{
|
||||
unsigned MemoryAreaOverflows;
|
||||
|
||||
/* Initialize console output */
|
||||
CP_Init ();
|
||||
|
||||
/* Initialize the cmdline module */
|
||||
InitCmdLine (&argc, &argv, "ld65");
|
||||
|
||||
@@ -856,7 +886,7 @@ int main (int argc, char* argv [])
|
||||
}
|
||||
|
||||
if (WarningCount > 0 && WarningsAsErrors) {
|
||||
Error("Warnings as errors");
|
||||
Error ("Warnings as errors");
|
||||
}
|
||||
|
||||
/* Create the output 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -807,7 +807,7 @@ static void O65WriteSeg (O65Desc* D, SegDesc** Seg, unsigned Count, int DoWrite)
|
||||
|
||||
/* Check the size of the segment for overflow */
|
||||
if ((D->Header.Mode & MF_SIZE_MASK) == MF_SIZE_16BIT && D->SegSize > 0xFFFF) {
|
||||
Error ("Segment overflow in file '%s'", D->Filename);
|
||||
Error ("Segment overflow in file `%s'", D->Filename);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -960,7 +960,7 @@ static void O65WriteExports (O65Desc* D)
|
||||
|
||||
/* Bail out if we cannot handle the expression */
|
||||
if (ED.TooComplex) {
|
||||
Error ("Expression for symbol '%s' is too complex", Name);
|
||||
Error ("Expression for symbol `%s' is too complex", Name);
|
||||
}
|
||||
|
||||
/* Determine the segment id for the expression */
|
||||
@@ -979,7 +979,7 @@ static void O65WriteExports (O65Desc* D)
|
||||
/* For some reason, we didn't find this segment in the list of
|
||||
** segments written to the o65 file.
|
||||
*/
|
||||
Error ("Segment for symbol '%s' is undefined", Name);
|
||||
Error ("Segment for symbol `%s' is undefined", Name);
|
||||
}
|
||||
SegmentID = O65SegType (Seg);
|
||||
|
||||
@@ -1209,7 +1209,7 @@ void O65SetExport (O65Desc* D, unsigned Ident)
|
||||
*/
|
||||
Export* E = FindExport (Ident);
|
||||
if (E == 0 || IsUnresolvedExport (E)) {
|
||||
Error ("Unresolved export: '%s'", GetString (Ident));
|
||||
Error ("Unresolved export: `%s'", GetString (Ident));
|
||||
}
|
||||
|
||||
/* Insert the entry into the table */
|
||||
@@ -1372,7 +1372,7 @@ void O65WriteTarget (O65Desc* D, File* F)
|
||||
/* Open the file */
|
||||
D->F = fopen (D->Filename, "wb");
|
||||
if (D->F == 0) {
|
||||
Error ("Cannot open '%s': %s", D->Filename, strerror (errno));
|
||||
Error ("Cannot open `%s': %s", D->Filename, strerror (errno));
|
||||
}
|
||||
|
||||
/* Keep the user happy */
|
||||
@@ -1430,7 +1430,7 @@ void O65WriteTarget (O65Desc* D, File* F)
|
||||
|
||||
/* Close the file */
|
||||
if (fclose (D->F) != 0) {
|
||||
Error ("Cannot write to '%s': %s", D->Filename, strerror (errno));
|
||||
Error ("Cannot write to `%s': %s", D->Filename, strerror (errno));
|
||||
}
|
||||
|
||||
/* Reset the file and filename */
|
||||
|
||||
@@ -184,7 +184,7 @@ unsigned MakeGlobalStringId (const ObjData* O, unsigned Index)
|
||||
/* Convert a local string id into a global one and return it. */
|
||||
{
|
||||
if (Index >= O->StringCount) {
|
||||
Error ("Invalid string index (%u) in module '%s'",
|
||||
Error ("Invalid string index (%u) in module `%s'",
|
||||
Index, GetObjFileName (O));
|
||||
}
|
||||
return O->Strings[Index];
|
||||
@@ -214,7 +214,7 @@ struct Section* GetObjSection (const ObjData* O, unsigned Id)
|
||||
/* Get a section from an object file checking for a valid index */
|
||||
{
|
||||
if (Id >= CollCount (&O->Sections)) {
|
||||
Error ("Invalid section index (%u) in module '%s'",
|
||||
Error ("Invalid section index (%u) in module `%s'",
|
||||
Id, GetObjFileName (O));
|
||||
}
|
||||
return CollAtUnchecked (&O->Sections, Id);
|
||||
@@ -226,7 +226,7 @@ struct Import* GetObjImport (const ObjData* O, unsigned Id)
|
||||
/* Get an import from an object file checking for a valid index */
|
||||
{
|
||||
if (Id >= CollCount (&O->Imports)) {
|
||||
Error ("Invalid import index (%u) in module '%s'",
|
||||
Error ("Invalid import index (%u) in module `%s'",
|
||||
Id, GetObjFileName (O));
|
||||
}
|
||||
return CollAtUnchecked (&O->Imports, Id);
|
||||
@@ -238,7 +238,7 @@ struct Export* GetObjExport (const ObjData* O, unsigned Id)
|
||||
/* Get an export from an object file checking for a valid index */
|
||||
{
|
||||
if (Id >= CollCount (&O->Exports)) {
|
||||
Error ("Invalid export index (%u) in module '%s'",
|
||||
Error ("Invalid export index (%u) in module `%s'",
|
||||
Id, GetObjFileName (O));
|
||||
}
|
||||
return CollAtUnchecked (&O->Exports, Id);
|
||||
@@ -250,7 +250,7 @@ struct DbgSym* GetObjDbgSym (const ObjData* O, unsigned Id)
|
||||
/* Get a debug symbol from an object file checking for a valid index */
|
||||
{
|
||||
if (Id >= CollCount (&O->DbgSyms)) {
|
||||
Error ("Invalid debug symbol index (%u) in module '%s'",
|
||||
Error ("Invalid debug symbol index (%u) in module `%s'",
|
||||
Id, GetObjFileName (O));
|
||||
}
|
||||
return CollAtUnchecked (&O->DbgSyms, Id);
|
||||
@@ -262,7 +262,7 @@ struct Scope* GetObjScope (const ObjData* O, unsigned Id)
|
||||
/* Get a scope from an object file checking for a valid index */
|
||||
{
|
||||
if (Id >= CollCount (&O->Scopes)) {
|
||||
Error ("Invalid scope index (%u) in module '%s'",
|
||||
Error ("Invalid scope index (%u) in module `%s'",
|
||||
Id, GetObjFileName (O));
|
||||
}
|
||||
return CollAtUnchecked (&O->Scopes, Id);
|
||||
|
||||
@@ -67,7 +67,7 @@ static unsigned GetModule (const char* Name)
|
||||
/* Make a module name from the file name */
|
||||
const char* Module = FindName (Name);
|
||||
if (*Module == 0) {
|
||||
Error ("Cannot make module name from '%s'", Name);
|
||||
Error ("Cannot make module name from `%s'", Name);
|
||||
}
|
||||
return GetStringId (Module);
|
||||
}
|
||||
@@ -79,7 +79,7 @@ static void ObjReadHeader (FILE* Obj, ObjHeader* H, const char* Name)
|
||||
{
|
||||
H->Version = Read16 (Obj);
|
||||
if (H->Version != OBJ_VERSION) {
|
||||
Error ("Object file '%s' has wrong version, expected %08X, got %08X",
|
||||
Error ("Object file `%s' has wrong version, expected %08X, got %08X",
|
||||
Name, OBJ_VERSION, H->Version);
|
||||
}
|
||||
H->Flags = Read16 (Obj);
|
||||
|
||||
@@ -76,49 +76,6 @@ static FILE* InputFile = 0;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Error handling */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
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;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, Format);
|
||||
SB_VPrintf (&Buf, Format, ap);
|
||||
va_end (ap);
|
||||
|
||||
Warning ("%s:%u: %s",
|
||||
GetString (Pos->Name), Pos->Line, SB_GetConstBuf (&Buf));
|
||||
SB_Done (&Buf);
|
||||
|
||||
/* Count warnings */
|
||||
++WarningCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, Format);
|
||||
SB_VPrintf (&Buf, Format, ap);
|
||||
va_end (ap);
|
||||
|
||||
Error ("%s:%u: %s",
|
||||
GetString (Pos->Name), Pos->Line, SB_GetConstBuf (&Buf));
|
||||
SB_Done (&Buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
@@ -170,7 +127,7 @@ static void StrVal (void)
|
||||
|
||||
case EOF:
|
||||
case '\n':
|
||||
CfgError (&CfgErrorPos, "Unterminated string");
|
||||
PError (&CfgErrorPos, "Unterminated string");
|
||||
break;
|
||||
|
||||
case '%':
|
||||
@@ -180,7 +137,7 @@ static void StrVal (void)
|
||||
case EOF:
|
||||
case '\n':
|
||||
case '\"':
|
||||
CfgError (&CfgErrorPos, "Unterminated '%%' escape sequence");
|
||||
PError (&CfgErrorPos, "Unterminated `%%' escape sequence");
|
||||
break;
|
||||
|
||||
case '%':
|
||||
@@ -198,8 +155,8 @@ static void StrVal (void)
|
||||
break;
|
||||
|
||||
default:
|
||||
CfgWarning (&CfgErrorPos,
|
||||
"Unknown escape sequence '%%%c'", C);
|
||||
PWarning (&CfgErrorPos,
|
||||
"Unknown escape sequence `%%%c'", C);
|
||||
SB_AppendChar (&CfgSVal, '%');
|
||||
SB_AppendChar (&CfgSVal, C);
|
||||
NextChar ();
|
||||
@@ -255,7 +212,7 @@ Again:
|
||||
if (C == '$') {
|
||||
NextChar ();
|
||||
if (!isxdigit (C)) {
|
||||
CfgError (&CfgErrorPos, "Hex digit expected");
|
||||
PError (&CfgErrorPos, "Hex digit expected");
|
||||
}
|
||||
CfgIVal = 0;
|
||||
while (isxdigit (C)) {
|
||||
@@ -383,7 +340,7 @@ Again:
|
||||
break;
|
||||
|
||||
default:
|
||||
CfgError (&CfgErrorPos, "Invalid format specification");
|
||||
PError (&CfgErrorPos, "Invalid format specification");
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -392,7 +349,7 @@ Again:
|
||||
break;
|
||||
|
||||
default:
|
||||
CfgError (&CfgErrorPos, "Invalid character '%c'", C);
|
||||
PError (&CfgErrorPos, "Invalid character `%c'", C);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -403,7 +360,7 @@ void CfgConsume (cfgtok_t T, const char* Msg)
|
||||
/* Skip a token, print an error message if not found */
|
||||
{
|
||||
if (CfgTok != T) {
|
||||
CfgError (&CfgErrorPos, "%s", Msg);
|
||||
PError (&CfgErrorPos, "%s", Msg);
|
||||
}
|
||||
CfgNextTok ();
|
||||
}
|
||||
@@ -413,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");
|
||||
}
|
||||
|
||||
|
||||
@@ -421,7 +378,7 @@ void CfgConsumeSemi (void)
|
||||
void CfgConsumeColon (void)
|
||||
/* Consume a colon */
|
||||
{
|
||||
CfgConsume (CFGTOK_COLON, "':' expected");
|
||||
CfgConsume (CFGTOK_COLON, "`:' expected");
|
||||
}
|
||||
|
||||
|
||||
@@ -450,7 +407,7 @@ void CfgAssureInt (void)
|
||||
/* Make sure the next token is an integer */
|
||||
{
|
||||
if (CfgTok != CFGTOK_INTCON) {
|
||||
CfgError (&CfgErrorPos, "Integer constant expected");
|
||||
PError (&CfgErrorPos, "Integer constant expected");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,7 +417,7 @@ void CfgAssureStr (void)
|
||||
/* Make sure the next token is a string constant */
|
||||
{
|
||||
if (CfgTok != CFGTOK_STRCON) {
|
||||
CfgError (&CfgErrorPos, "String constant expected");
|
||||
PError (&CfgErrorPos, "String constant expected");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,7 +427,7 @@ void CfgAssureIdent (void)
|
||||
/* Make sure the next token is an identifier */
|
||||
{
|
||||
if (CfgTok != CFGTOK_IDENT) {
|
||||
CfgError (&CfgErrorPos, "Identifier expected");
|
||||
PError (&CfgErrorPos, "Identifier expected");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,12 +437,34 @@ void CfgRangeCheck (unsigned long Lo, unsigned long Hi)
|
||||
/* Check the range of CfgIVal */
|
||||
{
|
||||
if (CfgIVal < Lo || CfgIVal > Hi) {
|
||||
CfgError (&CfgErrorPos, "Range error");
|
||||
PError (&CfgErrorPos, "Range error");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void SpecialTokenHelp (const IdentTok* Table, unsigned Size, StrBuf* Msg)
|
||||
/* Create a help message for errors in CfgSpecialToken. StrBuf must be
|
||||
** initialized and is overwritten.
|
||||
*/
|
||||
{
|
||||
unsigned I;
|
||||
|
||||
SB_AppendStr (Msg, "You may use one of `");
|
||||
for (I = 0; I < Size; ++I) {
|
||||
if (I == Size - 1) {
|
||||
SB_AppendStr (Msg, " or `");
|
||||
} else if (I > 0) {
|
||||
SB_AppendStr (Msg, ", `");
|
||||
}
|
||||
SB_AppendStr (Msg, Table[I].Ident);
|
||||
SB_AppendChar (Msg, '\'');
|
||||
}
|
||||
SB_Terminate (Msg); /* So we may use %s */
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name)
|
||||
/* Map an identifier to one of the special tokens in the table */
|
||||
{
|
||||
@@ -504,13 +483,22 @@ void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name)
|
||||
}
|
||||
}
|
||||
|
||||
/* Not found */
|
||||
CfgError (&CfgErrorPos, "%s expected, got '%s'", Name, SB_GetConstBuf(&CfgSVal));
|
||||
/* Not found. Add a helpful note about the possible names only if
|
||||
** there is a not too large number of them.
|
||||
*/
|
||||
if (Size > 0 && Size <= 5) {
|
||||
StrBuf Note = AUTO_STRBUF_INITIALIZER;
|
||||
SpecialTokenHelp (Table, Size, &Note);
|
||||
AddPNote (&CfgErrorPos, "%s", SB_GetConstBuf (&Note));
|
||||
SB_Done (&Note);
|
||||
}
|
||||
PError (&CfgErrorPos, "%s expected but got `%s'", Name,
|
||||
SB_GetConstBuf (&CfgSVal));
|
||||
return;
|
||||
}
|
||||
|
||||
/* No identifier */
|
||||
CfgError (&CfgErrorPos, "%s expected", Name);
|
||||
PError (&CfgErrorPos, "%s expected", Name);
|
||||
}
|
||||
|
||||
|
||||
@@ -531,7 +519,7 @@ void CfgBoolToken (void)
|
||||
} else {
|
||||
/* We expected an integer here */
|
||||
if (CfgTok != CFGTOK_INTCON) {
|
||||
CfgError (&CfgErrorPos, "Boolean value expected");
|
||||
PError (&CfgErrorPos, "Boolean value expected");
|
||||
}
|
||||
CfgTok = (CfgIVal == 0)? CFGTOK_FALSE : CFGTOK_TRUE;
|
||||
}
|
||||
@@ -561,7 +549,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 */
|
||||
|
||||
@@ -186,12 +186,6 @@ extern FilePos CfgErrorPos;
|
||||
|
||||
|
||||
|
||||
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 */
|
||||
|
||||
void CfgError (const FilePos* Pos, const char* Format, ...) attribute((format(printf,2,3)));
|
||||
/* Print an error message adding file name and line number of a given file */
|
||||
|
||||
void CfgNextTok (void);
|
||||
/* Read the next token from the input stream */
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ void PrintDbgScopes (FILE* F)
|
||||
case SCOPE_ENUM: fputs (",type=enum", F); break;
|
||||
|
||||
default:
|
||||
Error ("Module '%s': Unknown scope type %u",
|
||||
Error ("Module `%s': Unknown scope type %u",
|
||||
GetObjFileName (O), S->Type);
|
||||
}
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ Segment* GetSegment (unsigned Name, unsigned char AddrSize, const char* ObjName)
|
||||
if (ObjName == 0) {
|
||||
ObjName = "[linker generated]";
|
||||
}
|
||||
Error ("Module '%s': Type mismatch for segment '%s'", ObjName,
|
||||
Error ("Module `%s': Type mismatch for segment `%s'", ObjName,
|
||||
GetString (Name));
|
||||
}
|
||||
}
|
||||
@@ -226,13 +226,13 @@ Section* ReadSection (FILE* F, ObjData* O)
|
||||
if (Sec->Alignment > 1) {
|
||||
Alignment = LeastCommonMultiple (S->Alignment, Sec->Alignment);
|
||||
if (Alignment > MAX_ALIGNMENT) {
|
||||
Error ("Combined alignment for segment '%s' is %lu which exceeds "
|
||||
"%lu. Last module requiring alignment was '%s'.",
|
||||
Error ("Combined alignment for segment `%s' is %lu which exceeds "
|
||||
"%lu. Last module requiring alignment was `%s'.",
|
||||
GetString (Name), Alignment, MAX_ALIGNMENT,
|
||||
GetObjFileName (O));
|
||||
} else if (Alignment >= LARGE_ALIGNMENT && Alignment > S->Alignment && Alignment > Sec->Alignment && !LargeAlignment) {
|
||||
Warning ("Combined alignment for segment '%s' is suspiciously "
|
||||
"large (%lu). Last module requiring alignment was '%s'.",
|
||||
Warning ("Combined alignment for segment `%s' is suspiciously "
|
||||
"large (%lu). Last module requiring alignment was `%s'.",
|
||||
GetString (Name), Alignment, GetObjFileName (O));
|
||||
}
|
||||
S->Alignment = Alignment;
|
||||
@@ -270,7 +270,7 @@ Section* ReadSection (FILE* F, ObjData* O)
|
||||
break;
|
||||
|
||||
default:
|
||||
Error ("Unknown fragment type in module '%s', segment '%s': %02X",
|
||||
Error ("Unknown fragment type in module `%s', segment `%s': %02X",
|
||||
GetObjFileName (O), GetString (S->Name), Type);
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
@@ -306,9 +306,11 @@ Segment* SegFind (unsigned Name)
|
||||
|
||||
|
||||
|
||||
int IsBSSType (Segment* S)
|
||||
/* Check if the given segment is a BSS style segment, that is, it does not
|
||||
** contain non-zero data.
|
||||
Section* GetNonBSSSection (Segment* S)
|
||||
/* Used when checking a BSS style segment for initialized data. Will walk over
|
||||
** all sections in S and check if any of them contains initialized data. If so,
|
||||
** the first section containing initialized data is returned. Otherwise the
|
||||
** function returns NULL.
|
||||
*/
|
||||
{
|
||||
/* Loop over all sections */
|
||||
@@ -326,18 +328,20 @@ int IsBSSType (Segment* S)
|
||||
unsigned long Count = F->Size;
|
||||
while (Count--) {
|
||||
if (*Data++ != 0) {
|
||||
return 0;
|
||||
return Sec;
|
||||
}
|
||||
}
|
||||
} else if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
|
||||
if (GetExprVal (F->Expr) != 0) {
|
||||
return 0;
|
||||
return Sec;
|
||||
}
|
||||
}
|
||||
F = F->Next;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
/* No uninitialized data found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -502,19 +506,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;
|
||||
@@ -638,11 +642,9 @@ void PrintDbgSegments (FILE* F)
|
||||
fprintf (F, ",oname=\"%s\",ooffs=%lu",
|
||||
S->OutputName, S->OutputOffs);
|
||||
}
|
||||
if (S->MemArea) {
|
||||
if (S->MemArea->BankExpr) {
|
||||
if (S->MemArea && S->MemArea->BankExpr) {
|
||||
if (IsConstExpr (S->MemArea->BankExpr)) {
|
||||
fprintf (F, ",bank=%lu", GetExprVal(S->MemArea->BankExpr));
|
||||
}
|
||||
fprintf (F, ",bank=%lu", GetExprVal (S->MemArea->BankExpr));
|
||||
}
|
||||
}
|
||||
fputc ('\n', F);
|
||||
@@ -664,7 +666,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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,9 +131,11 @@ Section* ReadSection (FILE* F, struct ObjData* O);
|
||||
Segment* SegFind (unsigned Name);
|
||||
/* Return the given segment or NULL if not found. */
|
||||
|
||||
int IsBSSType (Segment* S);
|
||||
/* Check if the given segment is a BSS style segment, that is, it does not
|
||||
** contain non-zero data.
|
||||
Section* GetNonBSSSection (Segment* S);
|
||||
/* Used when checking a BSS style segment for initialized data. Will walk over
|
||||
** all sections in S and check if any of them contains initialized data. If so,
|
||||
** the first section containing initialized data is returned. Otherwise the
|
||||
** function returns NULL.
|
||||
*/
|
||||
|
||||
void SegDump (void);
|
||||
|
||||
@@ -120,7 +120,9 @@ void XexSetRunAd (XexDesc* D, Import *RunAd)
|
||||
D->RunAd = RunAd;
|
||||
}
|
||||
|
||||
XexInitAd* XexSearchInitMem(XexDesc* D, MemoryArea *InitMem)
|
||||
|
||||
|
||||
XexInitAd* XexSearchInitMem (XexDesc* D, MemoryArea *InitMem)
|
||||
{
|
||||
XexInitAd* I;
|
||||
for (I=D->InitAds; I != 0; I=I->next)
|
||||
@@ -132,6 +134,7 @@ XexInitAd* XexSearchInitMem(XexDesc* D, MemoryArea *InitMem)
|
||||
}
|
||||
|
||||
|
||||
|
||||
int XexAddInitAd (XexDesc* D, MemoryArea *InitMem, Import *InitAd)
|
||||
/* Sets and INITAD for the given memory area */
|
||||
{
|
||||
@@ -149,6 +152,8 @@ int XexAddInitAd (XexDesc* D, MemoryArea *InitMem, Import *InitAd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static unsigned XexWriteExpr (ExprNode* E, int Signed, unsigned Size,
|
||||
unsigned long Offs attribute ((unused)),
|
||||
void* Data)
|
||||
@@ -287,7 +292,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);
|
||||
|
||||
@@ -61,8 +61,8 @@ define CPUDETECT_template
|
||||
|
||||
$(WORKDIR)/$1-cpudetect.bin: cpudetect.s $1-cpudetect.ref $(ISEQUAL)
|
||||
$(if $(QUIET),echo asm/$1-cpudetect.bin)
|
||||
$(CA65) -t none --cpu $1 -l $$(@:.bin=.lst) -o $$(@:.bin=.o) $$< $(CATERR)
|
||||
$(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib $(CATERR)
|
||||
$(CA65) --no-utf8 -t none --cpu $1 -l $$(@:.bin=.lst) -o $$(@:.bin=.o) $$< $(CATERR)
|
||||
$(LD65) --no-utf8 -t none -o $$@ $$(@:.bin=.o) none.lib $(CATERR)
|
||||
$(ISEQUAL) $1-cpudetect.ref $$@
|
||||
|
||||
endef # CPUDETECT_template
|
||||
@@ -70,7 +70,7 @@ endef # CPUDETECT_template
|
||||
$(foreach cpu,$(CPUDETECT_CPUS),$(eval $(call CPUDETECT_template,$(cpu))))
|
||||
|
||||
$(WORKDIR)/%.o: %.s | $(WORKDIR)
|
||||
$(CA65) -l $(@:.o=.lst) -o $@ $< $(NULLOUT) $(CATERR)
|
||||
$(CA65) --no-utf8 -l $(@:.o=.lst) -o $@ $< $(NULLOUT) $(CATERR)
|
||||
|
||||
clean:
|
||||
@$(call RMDIR,$(WORKDIR))
|
||||
|
||||
11
test/asm/listing/170-ld-errormsg.cfg
Normal file
11
test/asm/listing/170-ld-errormsg.cfg
Normal file
@@ -0,0 +1,11 @@
|
||||
MEMORY {
|
||||
ZP: file = "", start = $80, size = $001F;
|
||||
MAIN: file = %O, start = %S, size = $1000;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
CODE: load = MAIN, type = rw;
|
||||
RODATA: load = MAIN, type = rw;
|
||||
DATA: load = MAIN, type = rw;
|
||||
BSS: load = MAIN, type = bss;
|
||||
}
|
||||
6
test/asm/listing/170-ld-errormsg.s
Normal file
6
test/asm/listing/170-ld-errormsg.s
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
.code
|
||||
.byte 5
|
||||
.bss
|
||||
.byte 3
|
||||
|
||||
11
test/asm/listing/171-ld-errormsg.cfg
Normal file
11
test/asm/listing/171-ld-errormsg.cfg
Normal file
@@ -0,0 +1,11 @@
|
||||
MEMORY {
|
||||
ZP: file = "", start = $80, size = $001F;
|
||||
MAIN: file = %O, start = %S, size = $100;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
CODE: load = MAIN, type = rw;
|
||||
RODATA: load = MAIN, type = rw;
|
||||
DATA: load = MAIN, type = rw;
|
||||
BSS: load = MAIN, type = bss;
|
||||
}
|
||||
4
test/asm/listing/171-ld-errormsg.s
Normal file
4
test/asm/listing/171-ld-errormsg.s
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
.code
|
||||
.res 256, 3
|
||||
.byte $FF
|
||||
6
test/asm/listing/172-ld-errormsg.cfg
Normal file
6
test/asm/listing/172-ld-errormsg.cfg
Normal file
@@ -0,0 +1,6 @@
|
||||
MEMORY {
|
||||
MAIN: file = %O, start = %S, size = $1000;
|
||||
}
|
||||
SEGMENTS {
|
||||
CODE: load = MAIN, type = rwx;
|
||||
}
|
||||
4
test/asm/listing/172-ld-errormsg.s
Normal file
4
test/asm/listing/172-ld-errormsg.s
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
.bss
|
||||
.byte 3
|
||||
|
||||
@@ -73,21 +73,21 @@ $(WORKDIR)/$1.bin: $1.s $(ISEQUAL)
|
||||
|
||||
# compile without generating listing
|
||||
ifeq ($(wildcard control/$1.err),)
|
||||
$(CA65) -t none --no-utf8 -o $$(@:.bin=.o) $$< > $$(@:.bin=.err) 2> $$(@:.bin=.err2)
|
||||
$(CA65) --no-utf8 -t none --no-utf8 -o $$(@:.bin=.o) $$< > $$(@:.bin=.err) 2> $$(@:.bin=.err2)
|
||||
ifeq ($(wildcard control/$1.no-ld65),)
|
||||
ifeq ($(wildcard $1.cfg),)
|
||||
$(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2)
|
||||
$(LD65) --no-utf8 -t none -o $$@ $$(@:.bin=.o) none.lib > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2)
|
||||
else
|
||||
$(LD65) -C $$(<:.s=.cfg) -o $$@ $$(@:.bin=.o) > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2)
|
||||
$(LD65) --no-utf8 -C $$(<:.s=.cfg) -o $$@ $$(@:.bin=.o) > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2)
|
||||
endif
|
||||
endif
|
||||
else
|
||||
$(CA65) -t none --no-utf8 -o $$(@:.bin=.o) $$< > $$(@:.bin=.err) 2> $$(@:.bin=.err2) || $(TRUE)
|
||||
$(CA65) --no-utf8 -t none --no-utf8 -o $$(@:.bin=.o) $$< > $$(@:.bin=.err) 2> $$(@:.bin=.err2) || $(TRUE)
|
||||
ifeq ($(wildcard control/$1.no-ld65),)
|
||||
ifeq ($(wildcard $1.cfg),)
|
||||
$(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2) || $(TRUE)
|
||||
$(LD65) --no-utf8 -t none -o $$@ $$(@:.bin=.o) none.lib > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2) || $(TRUE)
|
||||
else
|
||||
$(LD65) -C $$(<:.s=.cfg) -o $$@ $$(@:.bin=.o) > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2) || $(TRUE)
|
||||
$(LD65) --no-utf8 -C $$(<:.s=.cfg) -o $$@ $$(@:.bin=.o) > $$(@:.bin=.ld65-err) 2> $$(@:.bin=.ld65-err2) || $(TRUE)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@@ -144,21 +144,21 @@ endif
|
||||
|
||||
# compile with listing file
|
||||
ifeq ($(wildcard control/$1.err),)
|
||||
$(CA65) -t none --no-utf8 -l $$(@:.bin=.list-lst) -o $$(@:.bin=.list-o) $$< > $$(@:.bin=.list-err) 2> $$(@:.bin=.list-err2)
|
||||
$(CA65) --no-utf8 -t none --no-utf8 -l $$(@:.bin=.list-lst) -o $$(@:.bin=.list-o) $$< > $$(@:.bin=.list-err) 2> $$(@:.bin=.list-err2)
|
||||
ifeq ($(wildcard control/$1.no-ld65),)
|
||||
ifeq ($(wildcard $1.cfg),)
|
||||
$(LD65) -t none -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) none.lib > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2)
|
||||
$(LD65) --no-utf8 -t none -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) none.lib > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2)
|
||||
else
|
||||
$(LD65) -C $$(<:.s=.cfg) -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2)
|
||||
$(LD65) --no-utf8 -C $$(<:.s=.cfg) -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2)
|
||||
endif
|
||||
endif
|
||||
else
|
||||
$(CA65) -t none --no-utf8 -l $$(@:.bin=.list-lst) -o $$(@:.bin=.list-o) $$< > $$(@:.bin=.list-err) 2> $$(@:.bin=.list-err2) || $(TRUE)
|
||||
$(CA65) --no-utf8 -t none --no-utf8 -l $$(@:.bin=.list-lst) -o $$(@:.bin=.list-o) $$< > $$(@:.bin=.list-err) 2> $$(@:.bin=.list-err2) || $(TRUE)
|
||||
ifeq ($(wildcard control/$1.no-ld65),)
|
||||
ifeq ($(wildcard $1.cfg),)
|
||||
$(LD65) -t none -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) none.lib > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2) || $(TRUE)
|
||||
$(LD65) --no-utf8 -t none -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) none.lib > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2) || $(TRUE)
|
||||
else
|
||||
$(LD65) -C $$(<:.s=.cfg) -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2) || $(TRUE)
|
||||
$(LD65) --no-utf8 -C $$(<:.s=.cfg) -o $$(@:.bin=.list-bin) $$(@:.bin=.list-o) > $$(@:.bin=.list-ld65-err) 2> $$(@:.bin=.list-ld65-err2) || $(TRUE)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@@ -212,7 +212,7 @@ $(foreach listing,$(LISTING_TESTS),$(eval $(call LISTING_template,$(listing))))
|
||||
|
||||
|
||||
$(WORKDIR)/%.o: %.s | $(WORKDIR)
|
||||
$(CA65) -l $(@:.o=.lst) -o $@ $<
|
||||
$(CA65) --no-utf8 -l $(@:.o=.lst) -o $@ $<
|
||||
|
||||
clean:
|
||||
@$(call RMDIR,$(WORKDIR))
|
||||
|
||||
0
test/asm/listing/control/171-ld-errormsg.err
Normal file
0
test/asm/listing/control/171-ld-errormsg.err
Normal file
0
test/asm/listing/control/172-ld-errormsg.err
Normal file
0
test/asm/listing/control/172-ld-errormsg.err
Normal file
@@ -1,40 +1,40 @@
|
||||
ld65: Warning: 030-assert-success.s:3: Code not at $0000
|
||||
ld65: Warning: 030-assert-success.s:4: Code not at $0000
|
||||
ld65: Warning: 030-assert-success.s:6: Code not at $0001
|
||||
ld65: Warning: 030-assert-success.s:7: Code not at $0001
|
||||
ld65: Warning: 030-assert-success.s:12: Code not at $1001
|
||||
ld65: Warning: 030-assert-success.s:13: Code not at $1001
|
||||
ld65: Warning: 030-assert-success.s:15: Code not at $8000
|
||||
ld65: Warning: 030-assert-success.s:16: Code not at $8000
|
||||
ld65: Warning: 030-assert-success.s:18: Code not at $8001
|
||||
ld65: Warning: 030-assert-success.s:19: Code not at $8001
|
||||
ld65: Warning: 030-assert-success.s:23: Code not at $0000
|
||||
ld65: Warning: 030-assert-success.s:24: Code not at $0000
|
||||
ld65: Warning: 030-assert-success.s:26: Code not at $0001
|
||||
ld65: Warning: 030-assert-success.s:27: Code not at $0001
|
||||
ld65: Warning: 030-assert-success.s:29: Code not at $1000
|
||||
ld65: Warning: 030-assert-success.s:30: Code not at $1000
|
||||
ld65: Warning: 030-assert-success.s:35: Code not at $8000
|
||||
ld65: Warning: 030-assert-success.s:36: Code not at $8000
|
||||
ld65: Warning: 030-assert-success.s:38: Code not at $8001
|
||||
ld65: Warning: 030-assert-success.s:39: Code not at $8001
|
||||
ld65: Warning: 030-assert-success.s:45: Code not at $0000
|
||||
ld65: Warning: 030-assert-success.s:46: Code not at $0000
|
||||
ld65: Warning: 030-assert-success.s:48: Code not at $0001
|
||||
ld65: Warning: 030-assert-success.s:49: Code not at $0001
|
||||
ld65: Warning: 030-assert-success.s:51: Code not at $1000
|
||||
ld65: Warning: 030-assert-success.s:52: Code not at $1000
|
||||
ld65: Warning: 030-assert-success.s:54: Code not at $1001
|
||||
ld65: Warning: 030-assert-success.s:55: Code not at $1001
|
||||
ld65: Warning: 030-assert-success.s:60: Code not at $8001
|
||||
ld65: Warning: 030-assert-success.s:61: Code not at $8001
|
||||
ld65: Warning: 030-assert-success.s:65: Code not at $0000
|
||||
ld65: Warning: 030-assert-success.s:66: Code not at $0000
|
||||
ld65: Warning: 030-assert-success.s:68: Code not at $0001
|
||||
ld65: Warning: 030-assert-success.s:69: Code not at $0001
|
||||
ld65: Warning: 030-assert-success.s:71: Code not at $1000
|
||||
ld65: Warning: 030-assert-success.s:72: Code not at $1000
|
||||
ld65: Warning: 030-assert-success.s:74: Code not at $1001
|
||||
ld65: Warning: 030-assert-success.s:75: Code not at $1001
|
||||
ld65: Warning: 030-assert-success.s:77: Code not at $8000
|
||||
ld65: Warning: 030-assert-success.s:78: Code not at $8000
|
||||
030-assert-success.s:3: Warning: Assertion failed: Code not at $0000
|
||||
030-assert-success.s:4: Warning: Assertion failed: Code not at $0000
|
||||
030-assert-success.s:6: Warning: Assertion failed: Code not at $0001
|
||||
030-assert-success.s:7: Warning: Assertion failed: Code not at $0001
|
||||
030-assert-success.s:12: Warning: Assertion failed: Code not at $1001
|
||||
030-assert-success.s:13: Warning: Assertion failed: Code not at $1001
|
||||
030-assert-success.s:15: Warning: Assertion failed: Code not at $8000
|
||||
030-assert-success.s:16: Warning: Assertion failed: Code not at $8000
|
||||
030-assert-success.s:18: Warning: Assertion failed: Code not at $8001
|
||||
030-assert-success.s:19: Warning: Assertion failed: Code not at $8001
|
||||
030-assert-success.s:23: Warning: Assertion failed: Code not at $0000
|
||||
030-assert-success.s:24: Warning: Assertion failed: Code not at $0000
|
||||
030-assert-success.s:26: Warning: Assertion failed: Code not at $0001
|
||||
030-assert-success.s:27: Warning: Assertion failed: Code not at $0001
|
||||
030-assert-success.s:29: Warning: Assertion failed: Code not at $1000
|
||||
030-assert-success.s:30: Warning: Assertion failed: Code not at $1000
|
||||
030-assert-success.s:35: Warning: Assertion failed: Code not at $8000
|
||||
030-assert-success.s:36: Warning: Assertion failed: Code not at $8000
|
||||
030-assert-success.s:38: Warning: Assertion failed: Code not at $8001
|
||||
030-assert-success.s:39: Warning: Assertion failed: Code not at $8001
|
||||
030-assert-success.s:45: Warning: Assertion failed: Code not at $0000
|
||||
030-assert-success.s:46: Warning: Assertion failed: Code not at $0000
|
||||
030-assert-success.s:48: Warning: Assertion failed: Code not at $0001
|
||||
030-assert-success.s:49: Warning: Assertion failed: Code not at $0001
|
||||
030-assert-success.s:51: Warning: Assertion failed: Code not at $1000
|
||||
030-assert-success.s:52: Warning: Assertion failed: Code not at $1000
|
||||
030-assert-success.s:54: Warning: Assertion failed: Code not at $1001
|
||||
030-assert-success.s:55: Warning: Assertion failed: Code not at $1001
|
||||
030-assert-success.s:60: Warning: Assertion failed: Code not at $8001
|
||||
030-assert-success.s:61: Warning: Assertion failed: Code not at $8001
|
||||
030-assert-success.s:65: Warning: Assertion failed: Code not at $0000
|
||||
030-assert-success.s:66: Warning: Assertion failed: Code not at $0000
|
||||
030-assert-success.s:68: Warning: Assertion failed: Code not at $0001
|
||||
030-assert-success.s:69: Warning: Assertion failed: Code not at $0001
|
||||
030-assert-success.s:71: Warning: Assertion failed: Code not at $1000
|
||||
030-assert-success.s:72: Warning: Assertion failed: Code not at $1000
|
||||
030-assert-success.s:74: Warning: Assertion failed: Code not at $1001
|
||||
030-assert-success.s:75: Warning: Assertion failed: Code not at $1001
|
||||
030-assert-success.s:77: Warning: Assertion failed: Code not at $8000
|
||||
030-assert-success.s:78: Warning: Assertion failed: Code not at $8000
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 032-assert-error2.s:3: Code not at $0000
|
||||
032-assert-error2.s:3: Error: Assertion failed: Code not at $0000
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 032-assert-error3.s:3: Code not at $0000
|
||||
032-assert-error3.s:3: Error: Assertion failed: Code not at $0000
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 032-assert-error4.s:3: Code not at $0001
|
||||
032-assert-error4.s:3: Error: Assertion failed: Code not at $0001
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 032-assert-error6.s:3: Code not at $1001
|
||||
032-assert-error6.s:3: Error: Assertion failed: Code not at $1001
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 032-assert-error7.s:3: Code not at $8000
|
||||
032-assert-error7.s:3: Error: Assertion failed: Code not at $8000
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 032-assert-error8.s:3: Code not at $8001
|
||||
032-assert-error8.s:3: Error: Assertion failed: Code not at $8001
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:3: Code not at $0000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:4: Code not at $0000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:6: Code not at $0001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:7: Code not at $0001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:12: Code not at $1001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:13: Code not at $1001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:15: Code not at $8000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:16: Code not at $8000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:18: Code not at $8001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:19: Code not at $8001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:23: Code not at $0000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:24: Code not at $0000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:26: Code not at $0001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:27: Code not at $0001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:29: Code not at $1000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:30: Code not at $1000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:35: Code not at $8000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:36: Code not at $8000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:38: Code not at $8001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:39: Code not at $8001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:45: Code not at $0000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:46: Code not at $0000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:48: Code not at $0001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:49: Code not at $0001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:51: Code not at $1000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:52: Code not at $1000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:54: Code not at $1001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:55: Code not at $1001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:60: Code not at $8001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:61: Code not at $8001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:65: Code not at $0000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:66: Code not at $0000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:68: Code not at $0001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:69: Code not at $0001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:71: Code not at $1000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:72: Code not at $1000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:74: Code not at $1001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:75: Code not at $1001
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:77: Code not at $8000
|
||||
ld65: Warning: 033-assert-ldwarning-success.s:78: Code not at $8000
|
||||
033-assert-ldwarning-success.s:3: Warning: Assertion failed: Code not at $0000
|
||||
033-assert-ldwarning-success.s:4: Warning: Assertion failed: Code not at $0000
|
||||
033-assert-ldwarning-success.s:6: Warning: Assertion failed: Code not at $0001
|
||||
033-assert-ldwarning-success.s:7: Warning: Assertion failed: Code not at $0001
|
||||
033-assert-ldwarning-success.s:12: Warning: Assertion failed: Code not at $1001
|
||||
033-assert-ldwarning-success.s:13: Warning: Assertion failed: Code not at $1001
|
||||
033-assert-ldwarning-success.s:15: Warning: Assertion failed: Code not at $8000
|
||||
033-assert-ldwarning-success.s:16: Warning: Assertion failed: Code not at $8000
|
||||
033-assert-ldwarning-success.s:18: Warning: Assertion failed: Code not at $8001
|
||||
033-assert-ldwarning-success.s:19: Warning: Assertion failed: Code not at $8001
|
||||
033-assert-ldwarning-success.s:23: Warning: Assertion failed: Code not at $0000
|
||||
033-assert-ldwarning-success.s:24: Warning: Assertion failed: Code not at $0000
|
||||
033-assert-ldwarning-success.s:26: Warning: Assertion failed: Code not at $0001
|
||||
033-assert-ldwarning-success.s:27: Warning: Assertion failed: Code not at $0001
|
||||
033-assert-ldwarning-success.s:29: Warning: Assertion failed: Code not at $1000
|
||||
033-assert-ldwarning-success.s:30: Warning: Assertion failed: Code not at $1000
|
||||
033-assert-ldwarning-success.s:35: Warning: Assertion failed: Code not at $8000
|
||||
033-assert-ldwarning-success.s:36: Warning: Assertion failed: Code not at $8000
|
||||
033-assert-ldwarning-success.s:38: Warning: Assertion failed: Code not at $8001
|
||||
033-assert-ldwarning-success.s:39: Warning: Assertion failed: Code not at $8001
|
||||
033-assert-ldwarning-success.s:45: Warning: Assertion failed: Code not at $0000
|
||||
033-assert-ldwarning-success.s:46: Warning: Assertion failed: Code not at $0000
|
||||
033-assert-ldwarning-success.s:48: Warning: Assertion failed: Code not at $0001
|
||||
033-assert-ldwarning-success.s:49: Warning: Assertion failed: Code not at $0001
|
||||
033-assert-ldwarning-success.s:51: Warning: Assertion failed: Code not at $1000
|
||||
033-assert-ldwarning-success.s:52: Warning: Assertion failed: Code not at $1000
|
||||
033-assert-ldwarning-success.s:54: Warning: Assertion failed: Code not at $1001
|
||||
033-assert-ldwarning-success.s:55: Warning: Assertion failed: Code not at $1001
|
||||
033-assert-ldwarning-success.s:60: Warning: Assertion failed: Code not at $8001
|
||||
033-assert-ldwarning-success.s:61: Warning: Assertion failed: Code not at $8001
|
||||
033-assert-ldwarning-success.s:65: Warning: Assertion failed: Code not at $0000
|
||||
033-assert-ldwarning-success.s:66: Warning: Assertion failed: Code not at $0000
|
||||
033-assert-ldwarning-success.s:68: Warning: Assertion failed: Code not at $0001
|
||||
033-assert-ldwarning-success.s:69: Warning: Assertion failed: Code not at $0001
|
||||
033-assert-ldwarning-success.s:71: Warning: Assertion failed: Code not at $1000
|
||||
033-assert-ldwarning-success.s:72: Warning: Assertion failed: Code not at $1000
|
||||
033-assert-ldwarning-success.s:74: Warning: Assertion failed: Code not at $1001
|
||||
033-assert-ldwarning-success.s:75: Warning: Assertion failed: Code not at $1001
|
||||
033-assert-ldwarning-success.s:77: Warning: Assertion failed: Code not at $8000
|
||||
033-assert-ldwarning-success.s:78: Warning: Assertion failed: Code not at $8000
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 034-assert-lderror2.s:3: Code not at $0000
|
||||
034-assert-lderror2.s:3: Error: Assertion failed: Code not at $0000
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 034-assert-lderror3.s:3: Code not at $0000
|
||||
034-assert-lderror3.s:3: Error: Assertion failed: Code not at $0000
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 034-assert-lderror4.s:3: Code not at $0001
|
||||
034-assert-lderror4.s:3: Error: Assertion failed: Code not at $0001
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 034-assert-lderror6.s:3: Code not at $1001
|
||||
034-assert-lderror6.s:3: Error: Assertion failed: Code not at $1001
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 034-assert-lderror7.s:3: Code not at $8000
|
||||
034-assert-lderror7.s:3: Error: Assertion failed: Code not at $8000
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Error: 034-assert-lderror8.s:3: Code not at $8001
|
||||
034-assert-lderror8.s:3: Error: Assertion failed: Code not at $8001
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Warning: <<<#PATH#>>>:<<<#INTEGER#>>>: Segment 'CODE' isn't aligned properly; the resulting executable might not be functional.
|
||||
<<<#PATH#>>>:<<<#INTEGER#>>>: Warning: Segment 'CODE' isn't aligned properly; the resulting executable might not be functional.
|
||||
|
||||
@@ -1 +1 @@
|
||||
ld65: Warning: runtime/sp-compat.s:16: Symbol 'sp' is deprecated - please use 'c_sp' instead
|
||||
runtime/sp-compat.s:16: Warning: Assertion failed: Symbol 'sp' is deprecated - please use 'c_sp' instead
|
||||
|
||||
1
test/asm/listing/ref/170-ld-errormsg.bin-ref
Normal file
1
test/asm/listing/ref/170-ld-errormsg.bin-ref
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
2
test/asm/listing/ref/170-ld-errormsg.ld65err2-ref
Normal file
2
test/asm/listing/ref/170-ld-errormsg.ld65err2-ref
Normal file
@@ -0,0 +1,2 @@
|
||||
170-ld-errormsg.cfg:10: Warning: Segment 'BSS' with type 'bss' contains initialized data
|
||||
170-ld-errormsg.cfg:10: Note: Initialized data comes at least partially from '<<<#PATH#>>>'
|
||||
2
test/asm/listing/ref/171-ld-errormsg.ld65err2-ref
Normal file
2
test/asm/listing/ref/171-ld-errormsg.ld65err2-ref
Normal file
@@ -0,0 +1,2 @@
|
||||
171-ld-errormsg.cfg:3: Warning: Segment 'CODE' overflows memory area 'MAIN' by 1 byte
|
||||
ld65: Error: Cannot generate most of the files due to memory area overflow
|
||||
2
test/asm/listing/ref/172-ld-errormsg.ld65err2-ref
Normal file
2
test/asm/listing/ref/172-ld-errormsg.ld65err2-ref
Normal file
@@ -0,0 +1,2 @@
|
||||
172-ld-errormsg.cfg:5: Error: Segment type expected but got 'RWX'
|
||||
172-ld-errormsg.cfg:5: Note: You may use one of 'RO', 'RW', 'BSS', 'ZP' or 'OVERWRITE'
|
||||
@@ -1,3 +1,3 @@
|
||||
ld65: Warning: 201-overwrite-overflow.cfg:3: Segment 'AO' overflows memory area 'A' by 1 byte
|
||||
ld65: Warning: 201-overwrite-overflow.cfg:4: Segment 'BO' overflows memory area 'B' by 1 byte
|
||||
201-overwrite-overflow.cfg:3: Warning: Segment 'AO' overflows memory area 'A' by 1 byte
|
||||
201-overwrite-overflow.cfg:4: Warning: Segment 'BO' overflows memory area 'B' by 1 byte
|
||||
ld65: Error: Cannot generate most of the files due to memory area overflows
|
||||
|
||||
@@ -63,15 +63,15 @@ define PRG_template
|
||||
# sim65 ensure 64-bit wait time does not timeout
|
||||
$(WORKDIR)/sim65-timein.$1.prg: sim65-timein.s | $(WORKDIR)
|
||||
$(if $(QUIET),echo misc/sim65-timein.$1.prg)
|
||||
$(CA65) -t sim$1 -o $$(@:.prg=.o) $$< $(NULLERR)
|
||||
$(LD65) -t sim$1 -o $$@ $$(@:.prg=.o) sim$1.lib $(NULLERR)
|
||||
$(CA65) --no-utf8 -t sim$1 -o $$(@:.prg=.o) $$< $(NULLERR)
|
||||
$(LD65) --no-utf8 -t sim$1 -o $$@ $$(@:.prg=.o) sim$1.lib $(NULLERR)
|
||||
$(SIM65) -x 4400000000 -c $$@ $(NULLOUT) $(NULLERR)
|
||||
|
||||
# sim65 ensure 64-bit wait time does timeout
|
||||
$(WORKDIR)/sim65-timeout.$1.prg: sim65-timeout.s | $(WORKDIR)
|
||||
$(if $(QUIET),echo misc/sim65-timeout.$1.prg)
|
||||
$(CA65) -t sim$1 -o $$(@:.prg=.o) $$< $(NULLERR)
|
||||
$(LD65) -t sim$1 -o $$@ $$(@:.prg=.o) sim$1.lib $(NULLERR)
|
||||
$(CA65) --no-utf8 -t sim$1 -o $$(@:.prg=.o) $$< $(NULLERR)
|
||||
$(LD65) --no-utf8 -t sim$1 -o $$@ $$(@:.prg=.o) sim$1.lib $(NULLERR)
|
||||
$(NOT) $(SIM65) -x 4400000000 -c $$@ $(NULLOUT) $(NULLERR)
|
||||
|
||||
endef # PRG_template
|
||||
|
||||
@@ -61,8 +61,8 @@ define OPCODE_template
|
||||
|
||||
$(WORKDIR)/$1-opcodes.bin: $1-opcodes.s $(ISEQUAL)
|
||||
$(if $(QUIET),echo asm/$1-opcodes.bin)
|
||||
$(CA65) -t none --cpu $1 -l $$(@:.bin=.lst) -o $$(@:.bin=.o) $$<
|
||||
$(LD65) -t none -o $$@ $$(@:.bin=.o) none.lib
|
||||
$(CA65) --no-utf8 -t none --cpu $1 -l $$(@:.bin=.lst) -o $$(@:.bin=.o) $$<
|
||||
$(LD65) --no-utf8 -t none -o $$@ $$(@:.bin=.o) none.lib
|
||||
$(ISEQUAL) $1-opcodes.ref $$@
|
||||
|
||||
endef # OPCODE_template
|
||||
@@ -70,7 +70,7 @@ endef # OPCODE_template
|
||||
$(foreach cpu,$(OPCODE_CPUS),$(eval $(call OPCODE_template,$(cpu))))
|
||||
|
||||
$(WORKDIR)/%.o: %.s | $(WORKDIR)
|
||||
$(CA65) -l $(@:.o=.lst) -o $@ $<
|
||||
$(CA65) --no-utf8 -l $(@:.o=.lst) -o $@ $<
|
||||
|
||||
clean:
|
||||
@$(call RMDIR,$(WORKDIR))
|
||||
|
||||
@@ -55,8 +55,8 @@ define PRG_template
|
||||
|
||||
$(WORKDIR)/%.$1.prg: %.s | $(WORKDIR)
|
||||
$(if $(QUIET),echo asm/val/$$*.$1.prg)
|
||||
$(CA65) -t sim$1 -o $$(@:.prg=.o) $$< $(NULLOUT) $(NULLERR)
|
||||
$(LD65) -C sim6502-asmtest.cfg -o $$@ $$(@:.prg=.o) sim$1.lib $(NULLOUT) $(NULLERR)
|
||||
$(CA65) --no-utf8 -t sim$1 -o $$(@:.prg=.o) $$< $(NULLOUT) $(NULLERR)
|
||||
$(LD65) --no-utf8 -C sim6502-asmtest.cfg -o $$@ $$(@:.prg=.o) sim$1.lib $(NULLOUT) $(NULLERR)
|
||||
$(SIM65) $(SIM65FLAGS) $$@ $(NULLOUT)
|
||||
|
||||
endef # PRG_template
|
||||
|
||||
Reference in New Issue
Block a user