#include <time.h>
/* common stuff */
-#include "fname.h"
#include "abend.h"
+#include "cmdline.h"
+#include "fname.h"
#include "chartype.h"
#include "target.h"
+#include "version.h"
#include "xmalloc.h"
/* I hope that no one will be able to create a .grc bigger than this... */
128, 0, 1, 128, 0, 1, 128, 0, 1,
128, 0, 1, 128, 0, 1, 255, 255, 255};
-char *ProgName; /* for AbEnd, later remove and use common/cmdline.h */
-
-char *outputCName = NULL, *outputSName = NULL;
+const char *outputCName = NULL;
+const char *outputSName = NULL;
FILE *outputCFile, *outputSFile;
int CFnum = 0, SFnum = 0;
int apple = 0;
char outputSMode[2] = "w";
-void printUsage(void) {
+static void Usage (void) {
+
+ printf ("Usage: %s [options] file\n"
+ "Short options:\n"
+ " -V\t\t\tPrint the version number\n"
+ " -h\t\t\tHelp (this text)\n"
+ " -o name\t\tName the C output file\n"
+ " -s name\t\tName the asm output file\n"
+ " -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;
+
+ }
+}
+
- printf("Usage: %s [options] file\n"
- "Options:\n"
- "\t-h, -?\t\tthis help\n"
- "\t-o name\t\tname C output file\n"
- "\t-s name\t\tname asm output file\n"
- "\t-t sys\t\tset target system\n",
- ProgName);
+
+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) {
fprintf(outputCFile,
void openCFile(void) {
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) {
void openSFile(void) {
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) {
myMenu.type = nextWord();
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));
myMenu.item = curItem;
curItem = newItem;
item++;
} while (strcmp(token, "}") != 0);
- if (item == 0) AbEnd("menu '%s' has 0 items!\n", myMenu.name);
- if (item > 31) AbEnd("menu '%s' has too many 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!", myMenu.name);
curItem->next = NULL;
"};\n\n");
if (fclose(outputCFile) != 0)
- AbEnd("error closing %s: %s\n", outputCName, strerror(errno));
+ AbEnd ("Error closing %s: %s", outputCName, strerror(errno));
}
myHead.geostype = 0x82;
break;
default:
- AbEnd("filetype '%s' is not supported yet\n", token);
+ AbEnd ("Filetype '%s' is not supported yet", token);
}
} else {
switch (a) {
myHead.geostype = 14;
break;
default:
- AbEnd("filetype '%s' is not supported yet\n", token);
+ AbEnd ("Filetype '%s' is not supported yet", token);
}
}
myHead.min = my_tm->tm_min;
if (strcmp(nextWord(), "{") != 0) {
- AbEnd("header '%s' has no opening bracket!\n", myHead.dosname);
+ AbEnd ("Header '%s' has no opening bracket!", myHead.dosname);
}
do {
if (strcmp(token, "}") == 0) break;
switch (a = findToken(hdrFields, token)) {
case -1:
- AbEnd("unknown field '%s' in header '%s'\n", token, myHead.dosname);
+ AbEnd ("Unknown field '%s' in header '%s'", token, myHead.dosname);
break;
case 0: /* author */
myHead.author = nextPhrase();
case 3: /* dostype */
switch (b = findToken(hdrDOSTp, nextWord())) {
case -1:
- AbEnd("unknown dostype in header '%s'\n", myHead.dosname);
+ AbEnd ("Unknown dostype in header '%s'", myHead.dosname);
break;
default:
if (apple == 0) myHead.dostype = b / 2 + 128 + 1;
case 4: /* mode */
switch (b = findToken(hdrModes, nextWord())) {
case -1:
- AbEnd("unknown mode in header '%s'\n", myHead.dosname);
+ AbEnd ("Unknown mode in header '%s'", myHead.dosname);
case 0:
if (apple == 0) myHead.mode = 0x40;
break;
case 5: /* structure */
switch (b = findToken(hdrStructTp, nextWord())) {
case -1:
- AbEnd("unknown structure type in header '%s'\n", myHead.dosname);
+ AbEnd ("unknown structure type in header '%s'", myHead.dosname);
case 0:
case 1:
myHead.structure = 0;
myHead.info);
if (fclose (outputSFile) != 0)
- AbEnd("error closing %s: %s\n", outputSName, strerror(errno));
+ AbEnd ("Error closing %s: %s", outputSName, strerror(errno));
}
vlirsize = strtol(nextWord(), NULL, 0);
if (strcmp(nextWord(), "{") != 0) {
- AbEnd ("VLIR description has no opening bracket!\n");
+ AbEnd ("VLIR description has no opening bracket!");
}
lastrecord = -1;
record = atoi(token);
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) {
- AbEnd("VLIR record %i is defined twice.\n", record);
+ AbEnd ("VLIR record %i is defined twice.", record);
}
vlirtable[record] = 1;
} while (strcmp(token, "}") != 0);
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 */
"\n");
if (fclose(outputSFile) != 0)
- AbEnd("error closing %s: %s\n", outputSName, strerror(errno));
+ AbEnd ("Error closing %s: %s", outputSName, strerror(errno));
openCFile();
"#define OVERLAY_SIZE (unsigned)&_OVERLAYSIZE__\n\n");
if (fclose(outputCFile) != 0)
- AbEnd("error closing %s: %s\n", outputCName, strerror(errno));
+ AbEnd ("Error closing %s: %s", outputCName, strerror(errno));
}
}
}
- if (bracket != 0) AbEnd("there are unclosed brackets!\n");
+ if (bracket != 0) AbEnd ("There are unclosed brackets!");
return tbl;
}
int vlir = 0; /* number of processed VLIR sections */
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));
break;
case 1:
if (++head != 1) {
- AbEnd("more than one HEADER section, aborting.\n");
+ AbEnd ("More than one HEADER section, aborting.");
} else {
DoHeader();
}
case 3: break; /* dialog not implemented yet */
case 4:
if (++vlir != 1) {
- AbEnd("more than one VLIR section, aborting.\n");
+ AbEnd ("More than one VLIR section, aborting.");
} else {
DoVLIR();
}
break;
default:
- AbEnd("unknown section %s.\n",token);
+ AbEnd ("Unknown section %s.",token);
break;
}
}
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 },
+ };
+
+ unsigned ffile = 0;
+ unsigned I;
+
+
+ /* Initialize the cmdline module */
+ InitCmdLine (&argc, &argv, "grc65");
+
+ /* Check the parameters */
+ I = 1;
+ while (I < ArgCount) {
+
+ /* Get the argument */
+ const char* Arg = ArgVec [I];
- ProgName = argv[0];
+ /* Check for an option */
+ if (Arg[0] == '-') {
+ switch (Arg[1]) {
- while (i < argc) {
- const char *arg = argv[i];
+ case '-':
+ LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0]));
+ break;
- if (arg[0] == '-') {
- switch (arg[1]) {
case 'o':
- outputCName = argv[++i];
+ outputCName = GetArg (&I, 2);
break;
+
case 's':
- outputSName = argv[++i];
+ outputSName = GetArg (&I, 2);
break;
+
case 't':
- switch (FindTarget(argv[++i])) {
- case TGT_GEOS_CBM:
- apple = 0;
- break;
- case TGT_GEOS_APPLE:
- apple = 1;
- break;
- default:
- AbEnd("unknown target system type %s\n", argv[i]);
- }
+ OptTarget (Arg, GetArg (&I, 2));
break;
+
case 'h':
case '?':
- printUsage();
- exit(EXIT_SUCCESS);
+ OptHelp (Arg, 0);
break;
+
+ case 'V':
+ OptVersion (Arg, 0);
+ break;
+
default:
- AbEnd("unknown option %s\n", arg);
+ UnknownOption (Arg);
}
+
} else {
ffile++;
- if (outputCName == NULL) outputCName = MakeFilename(arg, ".h");
- if (outputSName == NULL) outputSName = MakeFilename(arg, ".s");
+ if (outputCName == NULL) outputCName = MakeFilename (Arg, ".h");
+ 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;
}