diff options
Diffstat (limited to 'mixutils')
-rw-r--r-- | mixutils/Makefile.am | 7 | ||||
-rw-r--r-- | mixutils/mixvm.c | 4 | ||||
-rw-r--r-- | mixutils/mixvm_command.c | 176 | ||||
-rw-r--r-- | mixutils/mixvm_command.h | 3 | ||||
-rw-r--r-- | mixutils/mixvm_loop.c | 27 |
5 files changed, 84 insertions, 133 deletions
diff --git a/mixutils/Makefile.am b/mixutils/Makefile.am index 1c8cdd5..314c3ed 100644 --- a/mixutils/Makefile.am +++ b/mixutils/Makefile.am @@ -10,7 +10,12 @@ # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -INCLUDES = -I$(includedir) +if MAKE_GUILE +INCLUDES = -I$(includedir) -DMAKE_GUILE +else +INCLUDES = -I$(includedir) +endif + LDADD = $(top_builddir)/mixlib/libmix.a $(top_builddir)/lib/libreplace.a \ $(top_builddir)/mixguile/libmixguile.a $(INTLLIBS) diff --git a/mixutils/mixvm.c b/mixutils/mixvm.c index 81b1fa2..aef9493 100644 --- a/mixutils/mixvm.c +++ b/mixutils/mixvm.c @@ -35,7 +35,7 @@ #endif /* HAVE_GETOPT_LONG */ extern void -mix_vmloop (const gchar *code_file, gboolean use_emacs); +mix_vmloop (int argc, char *argv[], const gchar *code_file, gboolean use_emacs); extern void mix_vmrun (const gchar *code_file, gboolean dump); @@ -128,7 +128,7 @@ main (int argc, char **argv) mix_init_lib (); if (run) mix_vmrun(in, dump); - else mix_vmloop (in, emacs); + else mix_vmloop (argc, argv, in, emacs); mix_release_lib (); diff --git a/mixutils/mixvm_command.c b/mixutils/mixvm_command.c index 610f79a..4e9d9f8 100644 --- a/mixutils/mixvm_command.c +++ b/mixutils/mixvm_command.c @@ -42,39 +42,42 @@ #include <mixlib/mix_eval.h> #include <mixlib/mix_src_file.h> #include <mixlib/mix_vm_command.h> + +#ifdef MAKE_GUILE +# include <mixguile/mixguile.h> +static gboolean +try_guile_ (char *line) +{ + if (line[0] == '(') + { + if (line[strlen (line) -1] != ')') return FALSE; + mixguile_interpret_command (line); + return TRUE; + } + return FALSE; +} +#else /* !MAKE_GUILE */ +# define try_guile_(ignored) FALSE +#endif /* MAKE_GUILE */ + #include "mixvm_command.h" +/* mixvm dispatcher */ +static mix_vm_cmd_dispatcher_t *dis_ = NULL; + /* The names of functions that actually do the manipulation. */ #define DEC_FUN(name) \ -static int cmd_##name (char *arg) +static gboolean cmd_##name (mix_vm_cmd_dispatcher_t *dis, const char *arg) -DEC_FUN (help_); DEC_FUN (shell_); DEC_FUN (quit_); -/* A structure which contains information on the commands this program - can understand. */ -typedef struct { - const char *name; /* User printable name of the function. */ - Function *func; /* Function to call to do the job. */ - const char *doc; /* Documentation for this function. */ - const char *usage; /* Usage */ -} COMMAND; - -COMMAND commands[] = { - { "help", cmd_help_, N_("Display this text"), "help [COMMAND]" }, +mix_vm_command_info_t commands[] = { { "shell", cmd_shell_, N_("Execute shell command"), "shell COMMAND" }, { "quit", cmd_quit_, N_("Quit the program"), "quit" }, { (char *)NULL, (Function *)NULL, (char *)NULL } }; -#define LOCAL_COMANDS_NO_ ((sizeof (commands) / sizeof (commands[0])) - 1) -#define MIX_COMMANDS_NO_ MIX_CMD_INVALID+1 -#define ALL_COMMANDS_NO_ LOCAL_COMANDS_NO_+MIX_COMMANDS_NO_ - -static const char *mix_commands_[ALL_COMMANDS_NO_] = {NULL}; - - #ifdef HAVE_LIBREADLINE /* readline functions */ @@ -109,48 +112,29 @@ mixvm_cmd_completion_ (char *text, int start, int end) static char * mixvm_cmd_generator_ (const char *text, int state) { - static int list_index, len; - const char *name; + static const GList *comp = NULL; + char *prefix = NULL; + char *name = NULL; - /* If this is a new word to complete, initialize now. This includes - saving the length of TEXT for efficiency, and initializing the index - variable to 0. */ + /* If this is a new word to complete, initialize now. */ if (!state) { - list_index = 0; - len = strlen (text); + if (prefix) g_free (prefix); + comp = mix_vm_cmd_dispatcher_complete (dis_, text, &prefix); } /* Return the next name which partially matches from the command list. */ - while ((name = mix_commands_[list_index]) != NULL) + if (comp) { - list_index++; - if (strncmp (name, text, len) == 0) - return (g_strdup (name)); + name = g_strdup ((const gchar *)comp->data); + comp = comp->next; } - /* If no names matched, then return NULL. */ - return ((char *)NULL); + return name; } #endif /* HAVE_LIBREADLINE */ -/* command functions */ -static COMMAND * -find_command_ (const char *name) -{ - int i; - - for (i = 0; commands[i].name; i++) - if (strcmp (name, commands[i].name) == 0) - return (&commands[i]); - - return ((COMMAND *)NULL); -} - -/* mixvm dispatcher */ -static mix_vm_cmd_dispatcher_t *dis_ = NULL; - /* emacs interface */ static void emacs_output_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg, gpointer data) @@ -171,48 +155,26 @@ emacs_output_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg, gpointer data) } static int -cmd_help_ (char *arg) -{ - int i; - int printed = 0; - - for (i = 1; commands[i].name; i++) - { - if (!arg || !*arg) - { - printf (_("%s\t\t%s.\n"), commands[i].name, _(commands[i].doc)); - printed++; - } - else if (strcmp (arg, commands[i].name) == 0) - { - printf (_("%s\t\t%s.\nUsage:\t\t%s\n"), commands[i].name, - _(commands[i].doc), commands[i].usage); - printed++; - } - } - if (!printed ||!arg || !*arg) - mix_vm_cmd_dispatcher_dispatch (dis_, MIX_CMD_HELP, arg); - return TRUE; -} - -static int -cmd_quit_ (char *arg) +cmd_quit_ (mix_vm_cmd_dispatcher_t *dis, const char *arg) { puts ("Quitting ..."); if ( dis_ ) mix_vm_cmd_dispatcher_delete (dis_); + exit (0); + /* pek: anything needed here to make the marker disappear??? */ return FALSE; } static int -cmd_shell_ (char *arg) +cmd_shell_ (mix_vm_cmd_dispatcher_t *dis, const char *arg) { system (arg); return TRUE; } + /* external interface */ static void @@ -238,17 +200,10 @@ init_dis_ (mix_vm_cmd_dispatcher_t *dis) mix_vm_cmd_dispatcher_set_assembler (dis, "mixasm -g %s"); } -void +mix_vm_cmd_dispatcher_t * mixvm_cmd_init (mix_config_t *config, char *arg, gboolean use_emacs) { int k; - /* get local command names */ - for (k = 0; k < LOCAL_COMANDS_NO_; ++k) - mix_commands_[k] = commands[k].name; - /* get external command names */ - for (k = 0; k < MIX_CMD_INVALID; ++k) - mix_commands_[k + LOCAL_COMANDS_NO_] = mix_vm_command_to_string (k); - mix_commands_[ALL_COMMANDS_NO_ - 1] = NULL; #ifdef HAVE_LIBREADLINE /* Tell the completer that we want a crack first. */ @@ -263,6 +218,14 @@ mixvm_cmd_init (mix_config_t *config, char *arg, gboolean use_emacs) init_dis_ (dis_); + /* add local commands */ + k = 0; + while (commands[k].name) + { + mix_vm_cmd_dispatcher_register_new (dis_, commands + k); + ++k; + } + /* install post hook for emacs interaction */ if (use_emacs) { @@ -273,56 +236,21 @@ mixvm_cmd_init (mix_config_t *config, char *arg, gboolean use_emacs) if (arg) mix_vm_cmd_dispatcher_dispatch (dis_, MIX_CMD_LOAD, arg); + + return dis_; } gboolean mixvm_cmd_exec (char *line) { - int i; - COMMAND *command; - char *cmd, *arg; - mix_vm_command_t mix_cmd; - - if (!line) return cmd_quit_(NULL); + if (!line) return cmd_quit_(dis_, NULL); /* strip white space */ line = g_strstrip(line); - /* Isolate the command word. */ - i = 0; - while (line[i] && isspace (line[i])) - i++; - cmd = line + i; - - while (line[i] && !isspace (line[i])) - i++; - - if (line[i]) - line[i++] = '\0'; - - if (cmd == NULL || strlen (cmd) == 0) - return TRUE; + if (try_guile_ (line)) return TRUE; - /* Get argument to command, if any. */ - while (isspace (line[i])) - i++; - - arg = line + i; - - /* try to find local command */ - command = find_command_ (cmd); - if (command) - return ((*(command->func)) (arg)); + (void)mix_vm_cmd_dispatcher_dispatch_text (dis_, line); - /* try to find mix command */ - mix_cmd = mix_vm_command_from_string (cmd); - - if (mix_cmd == MIX_CMD_INVALID) - fprintf (stderr, _("%s: No such command. Try \'help\'\n"), cmd); - else - mix_vm_cmd_dispatcher_dispatch (dis_, mix_cmd, arg); - return TRUE; } - - diff --git a/mixutils/mixvm_command.h b/mixutils/mixvm_command.h index f4fdea8..e748710 100644 --- a/mixutils/mixvm_command.h +++ b/mixutils/mixvm_command.h @@ -24,8 +24,9 @@ #define MIXVM_COMMAND_H #include <mixlib/mix_config.h> +#include <mixlib/mix_vm_command.h> -extern void +extern mix_vm_cmd_dispatcher_t * mixvm_cmd_init (mix_config_t *config, char *arg, gboolean use_emacs); extern gboolean diff --git a/mixutils/mixvm_loop.c b/mixutils/mixvm_loop.c index 023d82d..f88acfb 100644 --- a/mixutils/mixvm_loop.c +++ b/mixutils/mixvm_loop.c @@ -27,6 +27,11 @@ #include <mixlib/mix_vm.h> #include <mixlib/mix_device.h> #include <mixlib/mix_vm_dump.h> + +#ifdef MAKE_GUILE +#include <mixguile/mixguile.h> +#endif + #include "mixvm_command.h" #ifdef HAVE_LIBHISTORY @@ -80,7 +85,7 @@ rl_gets () /* The main command loop of the virtual machine */ static mix_config_t *config_ = NULL; -static void +static mix_vm_cmd_dispatcher_t * init_mixvm_ (const gchar *file, gboolean use_emacs) { static const gchar *HISTORY_FILE = "mixvm.history"; @@ -93,18 +98,30 @@ init_mixvm_ (const gchar *file, gboolean use_emacs) if (mix_config_get_history_size (config_) == 0) mix_config_set_history_size (config_, HISTORY_SIZE); - mixvm_cmd_init (config_, (char *)file, use_emacs); + return mixvm_cmd_init (config_, (char *)file, use_emacs); } -void -mix_vmloop (const gchar *file, gboolean use_emacs) + +static void +loop_ (int argc, char *argv[]) { - init_mixvm_ (file, use_emacs); while ( mixvm_cmd_exec (rl_gets ()) ) ; mix_config_delete (config_); } +void +mix_vmloop (int argc, char *argv[], const gchar *file, gboolean use_emacs) +{ +#ifdef MAKE_GUILE + mix_vm_cmd_dispatcher_t *dis = init_mixvm_ (file, use_emacs); + mixguile_init (argc, argv, loop_, dis); +#else + (void) init_mixvm_ (file, use_emacs); + loop_ (argc, argv); +#endif +} + /* run a program and exit */ void mix_vmrun (const gchar *code_file, gboolean dump) |