mirror of
https://github.com/cc65/cc65.git
synced 2025-01-12 17:30:50 +00:00
Make ld65 -L command line option position independent again.
Handle long versions of command line arguments correctly.
This commit is contained in:
parent
18c2289784
commit
5114a3b861
178
src/ld65/main.c
178
src/ld65/main.c
@ -80,6 +80,24 @@
|
|||||||
static unsigned ObjFiles = 0; /* Count of object files linked */
|
static unsigned ObjFiles = 0; /* Count of object files linked */
|
||||||
static unsigned LibFiles = 0; /* Count of library files linked */
|
static unsigned LibFiles = 0; /* Count of library files linked */
|
||||||
|
|
||||||
|
/* struct InputFile.Type definitions */
|
||||||
|
#define INPUT_FILES_FILE 0 /* Entry is a file (unknown type) */
|
||||||
|
#define INPUT_FILES_FILE_OBJ 1 /* Entry is a object file */
|
||||||
|
#define INPUT_FILES_FILE_LIB 2 /* Entry is a library file */
|
||||||
|
#define INPUT_FILES_SGROUP 3 /* Entry is 'StartGroup' */
|
||||||
|
#define INPUT_FILES_EGROUP 4 /* Entry is 'EndGroup' */
|
||||||
|
|
||||||
|
#define MAX_INPUTFILES 256
|
||||||
|
|
||||||
|
/* Array of inputs (libraries and object files) */
|
||||||
|
static struct InputFile {
|
||||||
|
const char *FileName;
|
||||||
|
unsigned Type;
|
||||||
|
} *InputFiles;
|
||||||
|
static unsigned InputFilesCount = 0;
|
||||||
|
static const char *CmdlineCfgFile = NULL,
|
||||||
|
*CmdlineTarget = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -390,7 +408,10 @@ static void OptHelp (const char* Opt attribute ((unused)),
|
|||||||
static void OptLib (const char* Opt attribute ((unused)), const char* Arg)
|
static void OptLib (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Link a library */
|
/* Link a library */
|
||||||
{
|
{
|
||||||
LinkFile (Arg, FILETYPE_LIB);
|
InputFiles[InputFilesCount].Type = INPUT_FILES_FILE_LIB;
|
||||||
|
InputFiles[InputFilesCount].FileName = Arg;
|
||||||
|
if (++InputFilesCount >= MAX_INPUTFILES)
|
||||||
|
Error ("Too many input files");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -406,6 +427,9 @@ static void OptLibPath (const char* Opt attribute ((unused)), const char* Arg)
|
|||||||
static void OptMapFile (const char* Opt attribute ((unused)), const char* Arg)
|
static void OptMapFile (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Give the name of the map file */
|
/* Give the name of the map file */
|
||||||
{
|
{
|
||||||
|
if (MapFileName) {
|
||||||
|
Error ("Cannot use -m twice");
|
||||||
|
}
|
||||||
MapFileName = Arg;
|
MapFileName = Arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,7 +450,10 @@ static void OptModuleId (const char* Opt, const char* Arg)
|
|||||||
static void OptObj (const char* Opt attribute ((unused)), const char* Arg)
|
static void OptObj (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Link an object file */
|
/* Link an object file */
|
||||||
{
|
{
|
||||||
LinkFile (Arg, FILETYPE_OBJ);
|
InputFiles[InputFilesCount].Type = INPUT_FILES_FILE_OBJ;
|
||||||
|
InputFiles[InputFilesCount].FileName = Arg;
|
||||||
|
if (++InputFilesCount >= MAX_INPUTFILES)
|
||||||
|
Error ("Too many input files");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -439,16 +466,14 @@ static void OptObjPath (const char* Opt attribute ((unused)), const char* Arg)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptOutputName (const char* Opt, const char* Arg)
|
static void OptOutputName (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Give the name of the output file */
|
/* Give the name of the output file */
|
||||||
{
|
{
|
||||||
/* If the name of the output file has been used in the config before
|
static int OutputNameSeen = 0;
|
||||||
* (by using %O) we're actually changing it later, which - in most cases -
|
if (OutputNameSeen) {
|
||||||
* gives unexpected results, so emit a warning in this case.
|
Error ("Cannot use -o twice");
|
||||||
*/
|
|
||||||
if (OutputNameUsed) {
|
|
||||||
Warning ("Option `%s' should precede options `-t' or `-C'", Opt);
|
|
||||||
}
|
}
|
||||||
|
OutputNameSeen = 1;
|
||||||
OutputName = Arg;
|
OutputName = Arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,6 +482,9 @@ static void OptOutputName (const char* Opt, const char* Arg)
|
|||||||
static void OptStartAddr (const char* Opt, const char* Arg)
|
static void OptStartAddr (const char* Opt, const char* Arg)
|
||||||
/* Set the default start address */
|
/* Set the default start address */
|
||||||
{
|
{
|
||||||
|
if (HaveStartAddr) {
|
||||||
|
Error ("Cannot use -S twice");
|
||||||
|
}
|
||||||
StartAddr = CvtNumber (Opt, Arg);
|
StartAddr = CvtNumber (Opt, Arg);
|
||||||
HaveStartAddr = 1;
|
HaveStartAddr = 1;
|
||||||
}
|
}
|
||||||
@ -520,29 +548,61 @@ static void OptVersion (const char* Opt attribute ((unused)),
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void CmdlOptStartGroup (const char* Opt attribute ((unused)),
|
||||||
|
const char* Arg attribute ((unused)))
|
||||||
|
/* Remember 'start group' occurrence in input files array */
|
||||||
|
{
|
||||||
|
InputFiles[InputFilesCount].Type = INPUT_FILES_SGROUP;
|
||||||
|
InputFiles[InputFilesCount].FileName = Arg; /* Unused */
|
||||||
|
if (++InputFilesCount >= MAX_INPUTFILES)
|
||||||
|
Error ("Too many input files");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void CmdlOptEndGroup (const char* Opt attribute ((unused)),
|
||||||
|
const char* Arg attribute ((unused)))
|
||||||
|
/* Remember 'end group' occurrence in input files array */
|
||||||
|
{
|
||||||
|
InputFiles[InputFilesCount].Type = INPUT_FILES_EGROUP;
|
||||||
|
InputFiles[InputFilesCount].FileName = Arg; /* Unused */
|
||||||
|
if (++InputFilesCount >= MAX_INPUTFILES)
|
||||||
|
Error ("Too many input files");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void CmdlOptConfig (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
|
/* Set 'config file' command line parameter */
|
||||||
|
{
|
||||||
|
if (CmdlineCfgFile || CmdlineTarget) {
|
||||||
|
Error ("Cannot use -C/-t twice");
|
||||||
|
}
|
||||||
|
CmdlineCfgFile = Arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void CmdlOptTarget (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
|
/* Set 'target' command line parameter */
|
||||||
|
{
|
||||||
|
if (CmdlineCfgFile || CmdlineTarget) {
|
||||||
|
Error ("Cannot use -C/-t twice");
|
||||||
|
}
|
||||||
|
CmdlineTarget = Arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void ParseCommandLine(void)
|
static void ParseCommandLine(void)
|
||||||
{
|
{
|
||||||
/* struct InputFile.Type definitions */
|
|
||||||
#define INPUT_FILES_FILE 0 /* Entry is a file */
|
|
||||||
#define INPUT_FILES_SGROUP 1 /* Entry is 'StartGroup' */
|
|
||||||
#define INPUT_FILES_EGROUP 2 /* Entry is 'EndGroup' */
|
|
||||||
#define INPUT_FILES_LIBPATH 3 /* Entry is a library search path */
|
|
||||||
|
|
||||||
#define MAX_INPUTFILES 256
|
|
||||||
|
|
||||||
struct InputFile {
|
|
||||||
const char *FileName;
|
|
||||||
unsigned Type;
|
|
||||||
} *InputFiles;
|
|
||||||
unsigned InputFilesCount = 0;
|
|
||||||
|
|
||||||
/* Program long options */
|
/* Program long options */
|
||||||
static const LongOpt OptTab[] = {
|
static const LongOpt OptTab[] = {
|
||||||
{ "--cfg-path", 1, OptCfgPath },
|
{ "--cfg-path", 1, OptCfgPath },
|
||||||
{ "--config", 1, OptConfig },
|
{ "--config", 1, CmdlOptConfig },
|
||||||
{ "--dbgfile", 1, OptDbgFile },
|
{ "--dbgfile", 1, OptDbgFile },
|
||||||
{ "--define", 1, OptDefine },
|
{ "--define", 1, OptDefine },
|
||||||
{ "--end-group", 0, OptEndGroup },
|
{ "--end-group", 0, CmdlOptEndGroup },
|
||||||
{ "--force-import", 1, OptForceImport },
|
{ "--force-import", 1, OptForceImport },
|
||||||
{ "--help", 0, OptHelp },
|
{ "--help", 0, OptHelp },
|
||||||
{ "--lib", 1, OptLib },
|
{ "--lib", 1, OptLib },
|
||||||
@ -552,15 +612,13 @@ static void ParseCommandLine(void)
|
|||||||
{ "--obj", 1, OptObj },
|
{ "--obj", 1, OptObj },
|
||||||
{ "--obj-path", 1, OptObjPath },
|
{ "--obj-path", 1, OptObjPath },
|
||||||
{ "--start-addr", 1, OptStartAddr },
|
{ "--start-addr", 1, OptStartAddr },
|
||||||
{ "--start-group", 0, OptStartGroup },
|
{ "--start-group", 0, CmdlOptStartGroup },
|
||||||
{ "--target", 1, OptTarget },
|
{ "--target", 1, CmdlOptTarget },
|
||||||
{ "--version", 0, OptVersion },
|
{ "--version", 0, OptVersion },
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned I;
|
unsigned I;
|
||||||
unsigned OutNameGiven = 0, CfgFileGiven = 0, TargetGiven = 0, StartAddressGiven = 0,
|
unsigned LabelFileGiven = 0;
|
||||||
MapFileGiven = 0, LabelFileGiven = 0;
|
|
||||||
const char *CfgFile = NULL, *Target = NULL;
|
|
||||||
|
|
||||||
/* Allocate memory for input file array */
|
/* Allocate memory for input file array */
|
||||||
InputFiles = xmalloc (MAX_INPUTFILES * sizeof (struct InputFile));
|
InputFiles = xmalloc (MAX_INPUTFILES * sizeof (struct InputFile));
|
||||||
@ -583,17 +641,11 @@ static void ParseCommandLine(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case '(':
|
case '(':
|
||||||
InputFiles[InputFilesCount].Type = INPUT_FILES_SGROUP;
|
CmdlOptStartGroup (Arg, 0);
|
||||||
InputFiles[InputFilesCount].FileName = Arg; /* Unused */
|
|
||||||
if (++InputFilesCount >= MAX_INPUTFILES)
|
|
||||||
Error ("Too many input files");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ')':
|
case ')':
|
||||||
InputFiles[InputFilesCount].Type = INPUT_FILES_EGROUP;
|
CmdlOptEndGroup (Arg, 0);
|
||||||
InputFiles[InputFilesCount].FileName = Arg; /* Unused */
|
|
||||||
if (++InputFilesCount >= MAX_INPUTFILES)
|
|
||||||
Error ("Too many input files");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
@ -602,27 +654,15 @@ static void ParseCommandLine(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'm':
|
case 'm':
|
||||||
if (MapFileGiven) {
|
|
||||||
Error ("Cannot use -m twice");
|
|
||||||
}
|
|
||||||
MapFileGiven = 1;
|
|
||||||
OptMapFile (Arg, GetArg (&I, 2));
|
OptMapFile (Arg, GetArg (&I, 2));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'o':
|
case 'o':
|
||||||
if (OutNameGiven) {
|
|
||||||
Error ("Cannot use -o twice");
|
|
||||||
}
|
|
||||||
OutNameGiven = 1;
|
|
||||||
OptOutputName (NULL, GetArg (&I, 2));
|
OptOutputName (NULL, GetArg (&I, 2));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
if (TargetGiven || CfgFileGiven) {
|
CmdlOptTarget (Arg, GetArg (&I, 2));
|
||||||
Error ("Cannot use -C/-t twice");
|
|
||||||
}
|
|
||||||
TargetGiven = 1;
|
|
||||||
Target = GetArg (&I, 2);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'u':
|
case 'u':
|
||||||
@ -638,11 +678,7 @@ static void ParseCommandLine(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'C':
|
case 'C':
|
||||||
if (TargetGiven || CfgFileGiven) {
|
CmdlOptConfig (Arg, GetArg (&I, 2));
|
||||||
Error ("Cannot use -C/-t twice");
|
|
||||||
}
|
|
||||||
CfgFileGiven = 1;
|
|
||||||
CfgFile = GetArg (&I, 2);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'D':
|
case 'D':
|
||||||
@ -660,19 +696,12 @@ static void ParseCommandLine(void)
|
|||||||
LabelFileName = GetArg (&I, 3);
|
LabelFileName = GetArg (&I, 3);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
InputFiles[InputFilesCount].Type = INPUT_FILES_LIBPATH;
|
OptLibPath (Arg, InputFiles[I].FileName);
|
||||||
InputFiles[InputFilesCount].FileName = GetArg (&I, 2);
|
|
||||||
if (++InputFilesCount >= MAX_INPUTFILES)
|
|
||||||
Error ("Too many input files");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'S':
|
case 'S':
|
||||||
if (StartAddressGiven) {
|
|
||||||
Error ("Cannot use -S twice");
|
|
||||||
}
|
|
||||||
StartAddressGiven = 1;
|
|
||||||
OptStartAddr (Arg, GetArg (&I, 2));
|
OptStartAddr (Arg, GetArg (&I, 2));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -699,14 +728,10 @@ static void ParseCommandLine(void)
|
|||||||
++I;
|
++I;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OutNameGiven == 0) {
|
if (CmdlineTarget) {
|
||||||
Error ("No output file specified");
|
OptTarget (NULL, CmdlineTarget);
|
||||||
}
|
} else if (CmdlineCfgFile) {
|
||||||
|
OptConfig (NULL, CmdlineCfgFile);
|
||||||
if (TargetGiven) {
|
|
||||||
OptTarget (NULL, Target);
|
|
||||||
} else if (CfgFileGiven) {
|
|
||||||
OptConfig (NULL, CfgFile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process input files */
|
/* Process input files */
|
||||||
@ -715,15 +740,18 @@ static void ParseCommandLine(void)
|
|||||||
case INPUT_FILES_FILE:
|
case INPUT_FILES_FILE:
|
||||||
LinkFile (InputFiles[I].FileName, FILETYPE_UNKNOWN);
|
LinkFile (InputFiles[I].FileName, FILETYPE_UNKNOWN);
|
||||||
break;
|
break;
|
||||||
|
case INPUT_FILES_FILE_LIB:
|
||||||
|
LinkFile (InputFiles[I].FileName, FILETYPE_LIB);
|
||||||
|
break;
|
||||||
|
case INPUT_FILES_FILE_OBJ:
|
||||||
|
LinkFile (InputFiles[I].FileName, FILETYPE_OBJ);
|
||||||
|
break;
|
||||||
case INPUT_FILES_SGROUP:
|
case INPUT_FILES_SGROUP:
|
||||||
OptStartGroup (NULL, 0);
|
OptStartGroup (NULL, 0);
|
||||||
break;
|
break;
|
||||||
case INPUT_FILES_EGROUP:
|
case INPUT_FILES_EGROUP:
|
||||||
OptEndGroup (NULL, 0);
|
OptEndGroup (NULL, 0);
|
||||||
break;
|
break;
|
||||||
case INPUT_FILES_LIBPATH:
|
|
||||||
OptLibPath (NULL, InputFiles[I].FileName);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user