diff --git a/Makefile b/Makefile index 1118f461..ba197193 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,7 @@ rgbasm_obj = \ src/asm/symbol.o \ src/asm/locallex.o \ src/extern/err.o \ + src/extern/reallocarray.o \ src/extern/strlcpy.o \ src/extern/strlcat.o diff --git a/src/asm/main.c b/src/asm/main.c index fd121aab..5b19b5ee 100644 --- a/src/asm/main.c +++ b/src/asm/main.c @@ -11,10 +11,14 @@ #include "asm/output.h" #include "asm/main.h" #include "extern/err.h" +#include "extern/reallocarray.h" int yyparse(void); void setuplex(void); +int cldefines_index; +int cldefines_size; +char **cldefines; clock_t nStartClock, nEndClock; SLONG nLineNo; ULONG nTotalLines, nPass, nPC, nIFDepth, nErrors; @@ -174,6 +178,45 @@ opt_Pop(void) fatalerror("No entries in the option stack"); } +void +opt_AddDefine(char *s) +{ + char *value, *equals; + if(cldefines_index >= cldefines_size) + { + cldefines_size *= 2; + cldefines = reallocarray(cldefines, cldefines_size, + 2 * sizeof(void *)); + if(!cldefines) + { + fatalerror("No memory for command line defines"); + } + } + equals = strchr(s, '='); + if(equals) + { + *equals = '\0'; + value = equals + 1; + } + else + { + value = "1"; + } + cldefines[cldefines_index++] = s; + cldefines[cldefines_index++] = value; +} + +void +opt_ParseDefines() +{ + int i; + + for(i = 0; i < cldefines_index; i += 2) + { + sym_AddString(cldefines[i], cldefines[i + 1]); + } +} + /* * Error handling */ @@ -211,8 +254,8 @@ static void usage(void) { printf( -"Usage: rgbasm [-hv] [-b chars] [-g chars] [-i path] [-o outfile]\n" -" [-p pad_value] file.asm\n"); +"Usage: rgbasm [-hv] [-b chars] [-Dname[=value]] [-g chars] [-i path]\n" +" [-o outfile] [-p pad_value] file.asm\n"); exit(1); } @@ -226,7 +269,13 @@ main(int argc, char *argv[]) char *tzMainfile; - + cldefines_size = 32; + cldefines = reallocarray(cldefines, cldefines_size, + 2 * sizeof(void *)); + if(!cldefines) + { + fatalerror("No memory for command line defines"); + } if (argc == 1) usage(); @@ -247,7 +296,7 @@ main(int argc, char *argv[]) newopt = CurrentOptions; - while ((ch = getopt(argc, argv, "b:g:hi:o:p:v")) != -1) { + while ((ch = getopt(argc, argv, "b:D:g:hi:o:p:v")) != -1) { switch (ch) { case 'b': if (strlen(optarg) == 2) { @@ -258,6 +307,9 @@ main(int argc, char *argv[]) "option 'b'"); } break; + case 'D': + opt_AddDefine(optarg); + break; case 'g': if (strlen(optarg) == 4) { newopt.gbgfx[0] = optarg[1]; @@ -323,6 +375,7 @@ main(int argc, char *argv[]) nErrors = 0; sym_PrepPass1(); fstk_Init(tzMainfile); + opt_ParseDefines(); if (CurrentOptions.verbose) { printf("Pass 1...\n"); @@ -350,6 +403,7 @@ main(int argc, char *argv[]) fstk_Init(tzMainfile); yy_set_state(LEX_STATE_NORMAL); opt_SetCurrentOptions(&DefaultOptions); + opt_ParseDefines(); if (CurrentOptions.verbose) { printf("Pass 2...\n"); diff --git a/src/asm/rgbasm.1 b/src/asm/rgbasm.1 index 7041f3f9..a676a945 100644 --- a/src/asm/rgbasm.1 +++ b/src/asm/rgbasm.1 @@ -8,6 +8,7 @@ .Nm rgbasm .Op Fl hv .Op Fl b Ar chars +.Op Fl D Ar name Ns Op = Ns Ar value .Op Fl g Ar chars .Op Fl i Ar path .Op Fl o Ar outfile @@ -22,6 +23,12 @@ Its arguments are as follows: .It Fl b Ar chars Change the two characters used for binary constants. The defaults are 01. +.It Fl D Ar name Ns Op = Ns Ar value +Add string symbol to the compiled source code. This is equivalent to +.Ar name +.Cm EQUS +.Qq Ar "value" +in code. If a value is not specified, a value of 1 is given. .It Fl g Ar chars Change the four characters used for binary constants. The defaults are 0123.