summaryrefslogtreecommitdiffhomepage
path: root/mixutils
diff options
context:
space:
mode:
Diffstat (limited to 'mixutils')
-rw-r--r--mixutils/Makefile.am7
-rw-r--r--mixutils/mixvm.c4
-rw-r--r--mixutils/mixvm_command.c176
-rw-r--r--mixutils/mixvm_command.h3
-rw-r--r--mixutils/mixvm_loop.c27
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)