aboutsummaryrefslogtreecommitdiff
path: root/src/casm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/casm.c')
-rw-r--r--src/casm.c117
1 files changed, 78 insertions, 39 deletions
diff --git a/src/casm.c b/src/casm.c
index 2643a02..fb50532 100644
--- a/src/casm.c
+++ b/src/casm.c
@@ -86,6 +86,16 @@ typedef struct
} CPU;
+/* Defines a static value table handler
+*/
+typedef struct
+{
+ const ValueTable *table;
+ CommandStatus (*handler)(int o, int ac, char *av[],
+ int q[], char *e, size_t es);
+} ValTableHandler;
+
+
/* ---------------------------------------- GLOBALS
*/
static const CPU cpu_table[]=
@@ -123,6 +133,10 @@ static const CPU cpu_table[]=
static const CPU *cpu = cpu_table;
+static ValTableHandler *valtable_handler;
+static int valtable_count;
+
+
/* ---------------------------------------- PROTOS
*/
static void CheckLimits(void);
@@ -133,6 +147,45 @@ static void RunPass(const char *name, FILE *, int depth);
static void ProduceOutput(void);
+/* ---------------------------------------- STATIC VALUE TABLE HANDLING
+*/
+static void PushValTableHandler(const ValueTable *t,
+ CommandStatus (*h)(int o, int ac, char *av[],
+ int q[], char *e, size_t es))
+{
+ if (t)
+ {
+ valtable_handler = Realloc(valtable_handler,
+ (sizeof *valtable_handler) *
+ (++valtable_count));
+
+ valtable_handler[valtable_count - 1].table = t;
+ valtable_handler[valtable_count - 1].handler = h;
+ }
+}
+
+
+static CommandStatus CheckValTableHandlers(const char *opt, int ac,
+ char *args[], int q[],
+ char *err, size_t errsize)
+{
+ const ValueTable *entry;
+ int f;
+
+ for(f = 0; f < valtable_count; f++)
+ {
+ if ((entry = ParseTable(opt, valtable_handler[f].table)))
+ {
+ return valtable_handler[f].handler
+ (entry->value, ac, args, q, err, errsize);
+ }
+ }
+
+ return CMD_NOT_KNOWN;
+}
+
+
+
/* ---------------------------------------- INTERNAL COMMAND HANDLING
*/
@@ -384,6 +437,7 @@ static CommandStatus OPTION(const char *label, int argc, char *argv[],
char **args;
int ac;
char *opt;
+ CommandStatus status = CMD_NOT_KNOWN;
if (*argv[1] == '+' || *argv[1] == '-')
{
@@ -412,51 +466,25 @@ static CommandStatus OPTION(const char *label, int argc, char *argv[],
opt = argv[1];
}
- /* TODO: There should be someway to make this better
- */
- if ((entry = ParseTable(opt, ListOptions())))
- {
- return ListSetOption(entry->value, ac, args, q, err, errsize);
- }
- else if ((entry = ParseTable(opt, MacroOptions())))
- {
- return MacroSetOption(entry->value, ac, args, q, err, errsize);
- }
- else if ((entry = ParseTable(opt, CodepageOptions())))
- {
- return CodepageSetOption(entry->value, ac, args, q, err, errsize);
- }
- else if ((entry = ParseTable(opt, OutputOptions())))
- {
- return OutputSetOption(entry->value, ac, args, q, err, errsize);
- }
- else if ((entry = ParseTable(opt, RawOutputOptions())))
- {
- return RawOutputSetOption(entry->value, ac, args, q, err, errsize);
- }
- else if ((entry = ParseTable(opt, SpecTAPOutputOptions())))
- {
- return SpecTAPOutputSetOption(entry->value, ac, args, q, err, errsize);
- }
- else if ((entry = ParseTable(opt, T64OutputOptions())))
- {
- return T64OutputSetOption(entry->value, ac, args, q, err, errsize);
- }
- else if ((entry = ParseTable(opt, ZX81OutputOptions())))
+ status = CheckValTableHandlers(opt, ac, args, q, err, errsize);
+
+ if (status == CMD_NOT_KNOWN)
{
- return ZX81OutputSetOption(entry->value, ac, args, q, err, errsize);
+ if ((entry = ParseTable(opt, cpu->options())))
+ {
+ status = cpu->set_option(entry->value, ac, args, q, err, errsize);
+ }
}
- else if ((entry = ParseTable(opt, GBOutputOptions())))
+
+ if (status == CMD_NOT_KNOWN)
{
- return GBOutputSetOption(entry->value, ac, args, q, err, errsize);
+ snprintf(err, errsize, "%s: unknown option %s", argv[0], opt);
+ return CMD_FAILED;
}
- else if ((entry = ParseTable(opt, cpu->options())))
+ else
{
- return cpu->set_option(entry->value, ac, args, q, err, errsize);
+ return status;
}
-
- snprintf(err, errsize, "%s: unknown option %s", argv[0], opt);
- return CMD_FAILED;
}
@@ -576,6 +604,17 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
+ PushValTableHandler(ListOptions(), ListSetOption);
+ PushValTableHandler(MacroOptions(), MacroSetOption);
+ PushValTableHandler(CodepageOptions(), CodepageSetOption);
+ PushValTableHandler(OutputOptions(), OutputSetOption);
+ PushValTableHandler(RawOutputOptions(), RawOutputSetOption);
+ PushValTableHandler(SpecTAPOutputOptions(), SpecTAPOutputSetOption);
+ PushValTableHandler(T64OutputOptions(), T64OutputSetOption);
+ PushValTableHandler(ZX81OutputOptions(), ZX81OutputSetOption);
+ PushValTableHandler(GBOutputOptions(), GBOutputSetOption);
+ PushValTableHandler(SNESOutputOptions(), SNESOutputSetOption);
+
ClearState();
SetPC(0);