summaryrefslogtreecommitdiffhomepage
path: root/mixutils/mixvm_command.c
diff options
context:
space:
mode:
Diffstat (limited to 'mixutils/mixvm_command.c')
-rw-r--r--mixutils/mixvm_command.c176
1 files changed, 52 insertions, 124 deletions
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;
}
-
-