1
0
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:
Christian Groessler 2014-03-27 23:47:59 +01:00
parent 18c2289784
commit 5114a3b861

View File

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