1
0
mirror of https://github.com/cc65/cc65.git synced 2025-03-11 02:33:17 +00:00

Change option processing and options to be more compatible with the other

tools. Support long options. Remove unnecessary newlines from error messages.


git-svn-id: svn://svn.cc65.org/cc65/trunk@5346 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2011-12-28 18:12:47 +00:00
parent 3364c1d779
commit 049ff2ce3e

View File

@ -22,10 +22,12 @@
#include <time.h> #include <time.h>
/* common stuff */ /* common stuff */
#include "fname.h"
#include "abend.h" #include "abend.h"
#include "cmdline.h"
#include "fname.h"
#include "chartype.h" #include "chartype.h"
#include "target.h" #include "target.h"
#include "version.h"
#include "xmalloc.h" #include "xmalloc.h"
/* I hope that no one will be able to create a .grc bigger than this... */ /* I hope that no one will be able to create a .grc bigger than this... */
@ -94,9 +96,8 @@ const unsigned char icon1[] = {255, 255, 255, 128, 0, 1, 128, 0, 1,
128, 0, 1, 128, 0, 1, 128, 0, 1, 128, 0, 1, 128, 0, 1, 128, 0, 1,
128, 0, 1, 128, 0, 1, 255, 255, 255}; 128, 0, 1, 128, 0, 1, 255, 255, 255};
char *ProgName; /* for AbEnd, later remove and use common/cmdline.h */ const char *outputCName = NULL;
const char *outputSName = NULL;
char *outputCName = NULL, *outputSName = NULL;
FILE *outputCFile, *outputSFile; FILE *outputCFile, *outputSFile;
int CFnum = 0, SFnum = 0; int CFnum = 0, SFnum = 0;
int apple = 0; int apple = 0;
@ -104,18 +105,72 @@ char outputCMode[2] = "w";
char outputSMode[2] = "w"; char outputSMode[2] = "w";
void printUsage(void) { static void Usage (void) {
printf("Usage: %s [options] file\n" printf ("Usage: %s [options] file\n"
"Options:\n" "Short options:\n"
"\t-h, -?\t\tthis help\n" " -V\t\t\tPrint the version number\n"
"\t-o name\t\tname C output file\n" " -h\t\t\tHelp (this text)\n"
"\t-s name\t\tname asm output file\n" " -o name\t\tName the C output file\n"
"\t-t sys\t\tset target system\n", " -s name\t\tName the asm output file\n"
ProgName); " -t sys\t\tSet the target system\n"
"\n"
"Long options:\n"
" --help\t\tHelp (this text)\n"
" --target sys\t\tSet the target system\n"
" --version\t\tPrint the version number\n",
ProgName);
} }
static void OptHelp (const char* Opt attribute ((unused)),
const char* Arg attribute ((unused)))
/* Print usage information and exit */
{
Usage ();
exit (EXIT_SUCCESS);
}
static void OptTarget (const char* Opt attribute ((unused)), const char* Arg)
/* Set the target system */
{
switch (FindTarget(Arg)) {
case TGT_GEOS_CBM:
apple = 0;
break;
case TGT_GEOS_APPLE:
apple = 1;
break;
case TGT_UNKNOWN:
AbEnd ("Unknown target system `%s'", Arg);
break;
default:
/* Target is known but unsupported */
AbEnd ("Unsupported target system `%s'", Arg);
break;
}
}
static void OptVersion (const char* Opt attribute ((unused)),
const char* Arg attribute ((unused)))
/* Print the assembler version */
{
fprintf (stderr,
"grc65 V%s - (C) Copyright, Maciej 'YTM/Elysium' Witkowiak\n",
GetVersionAsString ());
}
void printCHeader(void) { void printCHeader(void) {
fprintf(outputCFile, fprintf(outputCFile,
@ -145,7 +200,7 @@ void printSHeader(void) {
void openCFile(void) { void openCFile(void) {
if ((outputCFile = fopen(outputCName,outputCMode)) == 0) { if ((outputCFile = fopen(outputCName,outputCMode)) == 0) {
AbEnd("can't open file %s for writing: %s\n", outputCName, strerror(errno)); AbEnd ("Can't open file %s for writing: %s", outputCName, strerror(errno));
} }
if (CFnum == 0) { if (CFnum == 0) {
@ -159,7 +214,7 @@ void openCFile(void) {
void openSFile(void) { void openSFile(void) {
if ((outputSFile = fopen(outputSName, outputSMode)) == 0) { if ((outputSFile = fopen(outputSName, outputSMode)) == 0) {
AbEnd("can't open file %s for writing: %s\n", outputSName, strerror(errno)); AbEnd ("Can't open file %s for writing: %s", outputSName, strerror(errno));
} }
if (SFnum == 0) { if (SFnum == 0) {
@ -259,7 +314,7 @@ void DoMenu(void) {
myMenu.type = nextWord(); myMenu.type = nextWord();
if (strcmp(nextWord(), "{") != 0) { if (strcmp(nextWord(), "{") != 0) {
AbEnd("menu '%s' description has no opening bracket!\n", myMenu.name); AbEnd ("Menu '%s' description has no opening bracket!", myMenu.name);
} }
curItem = xmalloc(sizeof(struct menuitem)); curItem = xmalloc(sizeof(struct menuitem));
myMenu.item = curItem; myMenu.item = curItem;
@ -284,8 +339,8 @@ void DoMenu(void) {
curItem = newItem; curItem = newItem;
item++; item++;
} while (strcmp(token, "}") != 0); } while (strcmp(token, "}") != 0);
if (item == 0) AbEnd("menu '%s' has 0 items!\n", myMenu.name); if (item == 0) AbEnd ("Menu '%s' has 0 items!", myMenu.name);
if (item > 31) AbEnd("menu '%s' has too many items!\n", myMenu.name); if (item > 31) AbEnd ("Menu '%s' has too many items!", myMenu.name);
curItem->next = NULL; curItem->next = NULL;
@ -347,7 +402,7 @@ void DoMenu(void) {
"};\n\n"); "};\n\n");
if (fclose(outputCFile) != 0) if (fclose(outputCFile) != 0)
AbEnd("error closing %s: %s\n", outputCName, strerror(errno)); AbEnd ("Error closing %s: %s", outputCName, strerror(errno));
} }
@ -373,7 +428,7 @@ void DoHeader(void) {
myHead.geostype = 0x82; myHead.geostype = 0x82;
break; break;
default: default:
AbEnd("filetype '%s' is not supported yet\n", token); AbEnd ("Filetype '%s' is not supported yet", token);
} }
} else { } else {
switch (a) { switch (a) {
@ -384,7 +439,7 @@ void DoHeader(void) {
myHead.geostype = 14; myHead.geostype = 14;
break; break;
default: default:
AbEnd("filetype '%s' is not supported yet\n", token); AbEnd ("Filetype '%s' is not supported yet", token);
} }
} }
@ -413,7 +468,7 @@ void DoHeader(void) {
myHead.min = my_tm->tm_min; myHead.min = my_tm->tm_min;
if (strcmp(nextWord(), "{") != 0) { if (strcmp(nextWord(), "{") != 0) {
AbEnd("header '%s' has no opening bracket!\n", myHead.dosname); AbEnd ("Header '%s' has no opening bracket!", myHead.dosname);
} }
do { do {
@ -421,7 +476,7 @@ void DoHeader(void) {
if (strcmp(token, "}") == 0) break; if (strcmp(token, "}") == 0) break;
switch (a = findToken(hdrFields, token)) { switch (a = findToken(hdrFields, token)) {
case -1: case -1:
AbEnd("unknown field '%s' in header '%s'\n", token, myHead.dosname); AbEnd ("Unknown field '%s' in header '%s'", token, myHead.dosname);
break; break;
case 0: /* author */ case 0: /* author */
myHead.author = nextPhrase(); myHead.author = nextPhrase();
@ -439,7 +494,7 @@ void DoHeader(void) {
case 3: /* dostype */ case 3: /* dostype */
switch (b = findToken(hdrDOSTp, nextWord())) { switch (b = findToken(hdrDOSTp, nextWord())) {
case -1: case -1:
AbEnd("unknown dostype in header '%s'\n", myHead.dosname); AbEnd ("Unknown dostype in header '%s'", myHead.dosname);
break; break;
default: default:
if (apple == 0) myHead.dostype = b / 2 + 128 + 1; if (apple == 0) myHead.dostype = b / 2 + 128 + 1;
@ -449,7 +504,7 @@ void DoHeader(void) {
case 4: /* mode */ case 4: /* mode */
switch (b = findToken(hdrModes, nextWord())) { switch (b = findToken(hdrModes, nextWord())) {
case -1: case -1:
AbEnd("unknown mode in header '%s'\n", myHead.dosname); AbEnd ("Unknown mode in header '%s'", myHead.dosname);
case 0: case 0:
if (apple == 0) myHead.mode = 0x40; if (apple == 0) myHead.mode = 0x40;
break; break;
@ -467,7 +522,7 @@ void DoHeader(void) {
case 5: /* structure */ case 5: /* structure */
switch (b = findToken(hdrStructTp, nextWord())) { switch (b = findToken(hdrStructTp, nextWord())) {
case -1: case -1:
AbEnd("unknown structure type in header '%s'\n", myHead.dosname); AbEnd ("unknown structure type in header '%s'", myHead.dosname);
case 0: case 0:
case 1: case 1:
myHead.structure = 0; myHead.structure = 0;
@ -581,7 +636,7 @@ void DoHeader(void) {
myHead.info); myHead.info);
if (fclose (outputSFile) != 0) if (fclose (outputSFile) != 0)
AbEnd("error closing %s: %s\n", outputSName, strerror(errno)); AbEnd ("Error closing %s: %s", outputSName, strerror(errno));
} }
@ -596,7 +651,7 @@ void DoVLIR(void) {
vlirsize = strtol(nextWord(), NULL, 0); vlirsize = strtol(nextWord(), NULL, 0);
if (strcmp(nextWord(), "{") != 0) { if (strcmp(nextWord(), "{") != 0) {
AbEnd ("VLIR description has no opening bracket!\n"); AbEnd ("VLIR description has no opening bracket!");
} }
lastrecord = -1; lastrecord = -1;
@ -608,10 +663,10 @@ void DoVLIR(void) {
record = atoi(token); record = atoi(token);
if (record < 0 || record > 126) { if (record < 0 || record > 126) {
AbEnd("VLIR record %i is out of range 0-126.\n", record); AbEnd ("VLIR record %i is out of range 0-126.", record);
} }
if (vlirtable[record] == 1) { if (vlirtable[record] == 1) {
AbEnd("VLIR record %i is defined twice.\n", record); AbEnd ("VLIR record %i is defined twice.", record);
} }
vlirtable[record] = 1; vlirtable[record] = 1;
@ -619,7 +674,7 @@ void DoVLIR(void) {
} while (strcmp(token, "}") != 0); } while (strcmp(token, "}") != 0);
if (lastrecord == -1) { if (lastrecord == -1) {
AbEnd("There must be at least one VLIR record.\n"); AbEnd ("There must be at least one VLIR record.");
} }
/* always include record 0 */ /* always include record 0 */
@ -659,7 +714,7 @@ void DoVLIR(void) {
"\n"); "\n");
if (fclose(outputSFile) != 0) if (fclose(outputSFile) != 0)
AbEnd("error closing %s: %s\n", outputSName, strerror(errno)); AbEnd ("Error closing %s: %s", outputSName, strerror(errno));
openCFile(); openCFile();
@ -670,7 +725,7 @@ void DoVLIR(void) {
"#define OVERLAY_SIZE (unsigned)&_OVERLAYSIZE__\n\n"); "#define OVERLAY_SIZE (unsigned)&_OVERLAYSIZE__\n\n");
if (fclose(outputCFile) != 0) if (fclose(outputCFile) != 0)
AbEnd("error closing %s: %s\n", outputCName, strerror(errno)); AbEnd ("Error closing %s: %s", outputCName, strerror(errno));
} }
@ -711,7 +766,7 @@ char *filterInput(FILE *F, char *tbl) {
} }
} }
if (bracket != 0) AbEnd("there are unclosed brackets!\n"); if (bracket != 0) AbEnd ("There are unclosed brackets!");
return tbl; return tbl;
} }
@ -728,7 +783,7 @@ void processFile(const char *filename) {
int vlir = 0; /* number of processed VLIR sections */ int vlir = 0; /* number of processed VLIR sections */
if ((F = fopen(filename, "r")) == 0) { if ((F = fopen(filename, "r")) == 0) {
AbEnd("can't open file %s for reading: %s\n", filename, strerror(errno)); AbEnd ("Can't open file %s for reading: %s", filename, strerror(errno));
} }
str = filterInput(F, xmalloc(BLOODY_BIG_BUFFER)); str = filterInput(F, xmalloc(BLOODY_BIG_BUFFER));
@ -743,7 +798,7 @@ void processFile(const char *filename) {
break; break;
case 1: case 1:
if (++head != 1) { if (++head != 1) {
AbEnd("more than one HEADER section, aborting.\n"); AbEnd ("More than one HEADER section, aborting.");
} else { } else {
DoHeader(); DoHeader();
} }
@ -752,13 +807,13 @@ void processFile(const char *filename) {
case 3: break; /* dialog not implemented yet */ case 3: break; /* dialog not implemented yet */
case 4: case 4:
if (++vlir != 1) { if (++vlir != 1) {
AbEnd("more than one VLIR section, aborting.\n"); AbEnd ("More than one VLIR section, aborting.");
} else { } else {
DoVLIR(); DoVLIR();
} }
break; break;
default: default:
AbEnd("unknown section %s.\n",token); AbEnd ("Unknown section %s.",token);
break; break;
} }
} }
@ -769,54 +824,74 @@ void processFile(const char *filename) {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int ffile = 0, i = 1; /* Program long options */
static const LongOpt OptTab[] = {
{ "--help", 0, OptHelp },
{ "--target", 1, OptTarget },
{ "--version", 0, OptVersion },
};
ProgName = argv[0]; unsigned ffile = 0;
unsigned I;
while (i < argc) {
const char *arg = argv[i];
if (arg[0] == '-') { /* Initialize the cmdline module */
switch (arg[1]) { InitCmdLine (&argc, &argv, "grc65");
/* Check the parameters */
I = 1;
while (I < ArgCount) {
/* Get the argument */
const char* Arg = ArgVec [I];
/* Check for an option */
if (Arg[0] == '-') {
switch (Arg[1]) {
case '-':
LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
break;
case 'o': case 'o':
outputCName = argv[++i]; outputCName = GetArg (&I, 2);
break; break;
case 's': case 's':
outputSName = argv[++i]; outputSName = GetArg (&I, 2);
break; break;
case 't': case 't':
switch (FindTarget(argv[++i])) { OptTarget (Arg, GetArg (&I, 2));
case TGT_GEOS_CBM:
apple = 0;
break;
case TGT_GEOS_APPLE:
apple = 1;
break;
default:
AbEnd("unknown target system type %s\n", argv[i]);
}
break; break;
case 'h': case 'h':
case '?': case '?':
printUsage(); OptHelp (Arg, 0);
exit(EXIT_SUCCESS);
break; break;
case 'V':
OptVersion (Arg, 0);
break;
default: default:
AbEnd("unknown option %s\n", arg); UnknownOption (Arg);
} }
} else { } else {
ffile++; ffile++;
if (outputCName == NULL) outputCName = MakeFilename(arg, ".h"); if (outputCName == NULL) outputCName = MakeFilename (Arg, ".h");
if (outputSName == NULL) outputSName = MakeFilename(arg, ".s"); if (outputSName == NULL) outputSName = MakeFilename (Arg, ".s");
processFile(arg); processFile(Arg);
} }
i++; /* Next argument */
++I;
} }
if (ffile == 0) AbEnd("no input file\n"); if (ffile == 0) AbEnd ("No input file");
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }