diff options
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | mixgtk/mixgtk.glade | 10 | ||||
-rw-r--r-- | mixgtk/mixgtk_cmd_dispatcher.c | 228 | ||||
-rw-r--r-- | mixgtk/mixgtk_mixvm.h | 1 | ||||
-rw-r--r-- | mixgtk/mixgtk_widgets.c | 3 | ||||
-rw-r--r-- | mixgtk/mixgtk_widgets.h | 3 | ||||
-rw-r--r-- | mixlib/mix_file.c | 10 | ||||
-rw-r--r-- | mixlib/mix_file.h | 4 | ||||
-rw-r--r-- | samples/primes.mixal | 1 |
9 files changed, 238 insertions, 26 deletions
@@ -13,6 +13,10 @@ Please send mdk bug reports to bug-mdk@gnu.org. ** The main gmixvm window is not shown until it is completely drawn. +** The commands 'edit' and 'compile' are now understood by gmixvm. The + external programs used can be configured using the menu entry + Settings->External programs. + ** Bug in CON fixed : 'CON wexpr' didn't compile correctly unless wexpr represented a valid instruction; now, wexpr can evaluate to an arbitrary value (Vasilij Ozmetelenko). diff --git a/mixgtk/mixgtk.glade b/mixgtk/mixgtk.glade index 6676fbd..a0dcfcf 100644 --- a/mixgtk/mixgtk.glade +++ b/mixgtk/mixgtk.glade @@ -2586,6 +2586,11 @@ <name>extern_cancel_button</name> <can_default>True</can_default> <can_focus>True</can_focus> + <signal> + <name>clicked</name> + <handler>on_extern_cancel_button_clicked</handler> + <last_modification_time>Mon, 04 Jun 2001 21:31:50 GMT</last_modification_time> + </signal> <label>_Cancel</label> <relief>GTK_RELIEF_NORMAL</relief> </widget> @@ -2595,6 +2600,11 @@ <name>extern_ok_button</name> <can_default>True</can_default> <can_focus>True</can_focus> + <signal> + <name>clicked</name> + <handler>on_extern_ok_button_clicked</handler> + <last_modification_time>Mon, 04 Jun 2001 21:32:21 GMT</last_modification_time> + </signal> <label>_OK</label> <relief>GTK_RELIEF_NORMAL</relief> </widget> diff --git a/mixgtk/mixgtk_cmd_dispatcher.c b/mixgtk/mixgtk_cmd_dispatcher.c index d53e991..bb1d4db 100644 --- a/mixgtk/mixgtk_cmd_dispatcher.c +++ b/mixgtk/mixgtk_cmd_dispatcher.c @@ -24,18 +24,20 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> +#include <ctype.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <mixlib/mix_vm_command.h> -#include "mixgtk_cmd_dispatcher.h" #include "mixgtk_mixvm.h" #include "mixgtk_mixal.h" +#include "mixgtk_config.h" +#include "mixgtk_cmd_dispatcher.h" /* a mix vm command dispatcher */ -struct mixgtk_dispatch_ +typedef struct mixgtk_dispatch_ { mix_vm_cmd_dispatcher_t *dispatcher; /* the underlying cmd dispatcher */ FILE *out; /* the dispatcher's output file */ @@ -45,10 +47,128 @@ struct mixgtk_dispatch_ GtkWidget *status; /* the status bar widget */ guint context; /* context of the status bar messages */ GCompletion *completions; /* mixvm command completions */ -}; +} mixgtk_dispatch_data_t; static struct mixgtk_dispatch_ dis_data_ = {NULL}; +/* local commands stuff */ +static const gchar *EDITOR_ = NULL; +static const gchar *MIXASM_ = NULL; +static const gchar *EDITOR_KEY_ = "Editor"; +static const gchar *MIXASM_KEY_ = "Mixasm"; + +typedef gboolean (*local_handler_t) (mixgtk_dispatch_data_t *, + const gchar *); + +static void +log_command_ (mixgtk_dispatch_data_t *dis, const gchar *cmd) +{ + gtk_text_insert (GTK_TEXT (dis->log), NULL, NULL, NULL,"MIX> ", -1); + gtk_text_insert (GTK_TEXT (dis->log), NULL, NULL, NULL, cmd, -1); + gtk_text_insert (GTK_TEXT (dis->log), NULL, NULL, NULL, "\n", -1); +} + +static void +flush_log_ (mixgtk_dispatch_data_t *dis) +{ + enum {BLKSIZE = 100}; + static gchar BUFFER[BLKSIZE]; + + ssize_t k; + fflush (dis->out); + while ((k = read (dis->fildes[0], BUFFER, BLKSIZE)) != 0) + { + if (k == -1 && errno != EINTR) break; + if (k != -1) + gtk_text_insert (GTK_TEXT (dis->log), NULL, NULL, NULL, + BUFFER, k); + } +} + +static gboolean +exec_ (mixgtk_dispatch_data_t *dis, const gchar *cmd, const gchar *arg) +{ + gchar *fullcmd = NULL; + gboolean r = FALSE; + fullcmd = g_strdup_printf (cmd, arg); + r = !system (fullcmd); + flush_log_ (dis); + g_free (fullcmd); + return r; +} + +static const gchar * +get_src_file_path_ (mixgtk_dispatch_data_t *dis) +{ + static gchar *PATH = NULL; + + const mix_vm_t *vm = mix_vm_cmd_dispatcher_get_vm (dis->dispatcher); + const mix_src_file_t *f = mix_vm_get_src_file (vm); + + if (PATH) + { + g_free (PATH); + PATH = NULL; + } + + if (f) + PATH = mix_file_complete_name (mix_src_file_get_path (f), MIX_SRC_DEFEXT); + + return PATH; +} + +static gboolean +edit_handler_ (mixgtk_dispatch_data_t *dis, const gchar *arg) +{ + if (!arg) arg = get_src_file_path_ (dis); + if (!arg) return FALSE; + return exec_ (dis, EDITOR_, arg); +} + +static gboolean +compile_handler_ (mixgtk_dispatch_data_t *dis, const gchar *arg) +{ + if (!arg) arg = get_src_file_path_ (dis); + if (!arg) return FALSE; + return exec_ (dis, MIXASM_, arg); +} + +static const gchar* local_cmds_[] = { + "edit", "compile" +}; + +static const local_handler_t handlers_[] = { + edit_handler_, compile_handler_ +}; + +#define LOCAL_NO_ (sizeof (local_cmds_) / sizeof (local_cmds_[0])) + +static gboolean +dispatch_local_command_ (mixgtk_dispatch_data_t *dis, const gchar *cmd) +{ + int k = 0; + + g_return_val_if_fail (dis != NULL, FALSE); + g_return_val_if_fail (cmd != NULL, FALSE); + + for (k = 0; k < LOCAL_NO_; ++k) + { + if (!strncmp (local_cmds_[k], cmd, strlen (local_cmds_[k]))) + { + int j = 0; + const gchar *arg = NULL; + while (cmd[j] && !isspace (cmd[j])) ++j; + if (cmd[j]) arg = cmd + j; + log_command_ (dis, cmd); + handlers_[k](dis, arg); + return TRUE; + } + } + + return FALSE; +} + + /* completions */ static void init_completions_ (void) @@ -59,10 +179,12 @@ init_completions_ (void) dis_data_.completions = g_completion_new (NULL); for (k = 0; k < MIX_CMD_INVALID; ++k) cmds = g_list_append (cmds, (gpointer) mix_vm_command_to_string (k)); + for (k = 0; k < sizeof (local_cmds_) / sizeof (local_cmds_[0]); ++k) + cmds = g_list_append (cmds, (gpointer)local_cmds_[k]); g_completion_add_items (dis_data_.completions, cmds); } -/* global hooks for the command dispatcher */ +/* global hooks for the command dispatcher static void global_pre_hook_ (mix_vm_cmd_dispatcher_t *dis, mix_vm_command_t cmd, const gchar *arg, gpointer data) @@ -86,24 +208,13 @@ global_pre_hook_ (mix_vm_cmd_dispatcher_t *dis, _("\n*** Invalid command ***\n"), -1); } } +*/ static void global_post_hook_ (mix_vm_cmd_dispatcher_t *dis, mix_vm_command_t cmd, const gchar *arg, gpointer data) { - enum {BLKSIZE = 100}; - static gchar BUFFER[BLKSIZE]; - - ssize_t k; - fflush (dis_data_.out); - while ((k = read (dis_data_.fildes[0], BUFFER, BLKSIZE)) != 0) - { - if (k == -1 && errno != EINTR) break; - if (cmd < MIX_CMD_INVALID) - gtk_text_insert (GTK_TEXT (dis_data_.log), NULL, NULL, NULL, - BUFFER, k); - } - + flush_log_ ((mixgtk_dispatch_data_t *)data); mixgtk_mixvm_update_vm_widgets (); } @@ -168,10 +279,9 @@ allbp_post_hook_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg, static void install_hooks_ (void) { - mix_vm_cmd_dispatcher_global_pre_hook (dis_data_.dispatcher, - global_pre_hook_, NULL); mix_vm_cmd_dispatcher_global_post_hook (dis_data_.dispatcher, - global_post_hook_, NULL); + global_post_hook_, + (gpointer)(&dis_data_)); mix_vm_cmd_dispatcher_post_hook (dis_data_.dispatcher, MIX_CMD_LOAD, load_post_hook_, NULL); @@ -198,6 +308,63 @@ install_hooks_ (void) NULL); } +/* configuration stuff */ +static void +read_config_ (void) +{ + EDITOR_ = mixgtk_config_get (EDITOR_KEY_); + if (!EDITOR_) + { + static const gchar *ENV[] = {"MDK_EDITOR", "X_EDITOR", NULL}; + int k = 0; + while (!EDITOR_ && ENV[k]) EDITOR_ = getenv (ENV[k++]); + if (EDITOR_) EDITOR_ = g_strconcat (EDITOR_, " %s", NULL); + } + MIXASM_ = mixgtk_config_get (MIXASM_KEY_); + if (!MIXASM_) MIXASM_ = "mixasm -g %s"; +} + +static GtkWidget *ext_dlg_ = NULL; +static GtkWidget *ed_entry_ = NULL; +static GtkWidget *asm_entry_ = NULL; + +static const gchar *ED_NAME_ = "editor_entry"; +static const gchar *ASM_NAME_ = "mixasm_entry"; + +void +on_external_programs_activate () +{ + if (!ext_dlg_) + { + ext_dlg_ = mixgtk_widget_factory_get_dialog (MIXGTK_EXTERNPROG_DIALOG); + g_return_if_fail (ext_dlg_ != NULL); + ed_entry_ = mixgtk_widget_factory_get_child_by_name + (MIXGTK_EXTERNPROG_DIALOG, ED_NAME_); + g_assert (ed_entry_); + asm_entry_ = mixgtk_widget_factory_get_child_by_name + (MIXGTK_EXTERNPROG_DIALOG, ASM_NAME_); + g_assert (asm_entry_); + } + gtk_entry_set_text (GTK_ENTRY (ed_entry_), EDITOR_); + gtk_entry_set_text (GTK_ENTRY (asm_entry_), MIXASM_); + gtk_widget_show (ext_dlg_); +} + +void +on_extern_cancel_button_clicked () +{ + gtk_widget_hide (ext_dlg_); +} + +void +on_extern_ok_button_clicked () +{ + EDITOR_ = gtk_entry_get_text (GTK_ENTRY (ed_entry_)); + MIXASM_ = gtk_entry_get_text (GTK_ENTRY (asm_entry_)); + mixgtk_config_update (EDITOR_KEY_, EDITOR_); + mixgtk_config_update (MIXASM_KEY_, MIXASM_); + gtk_widget_hide (ext_dlg_); +} /* initialise the command dispatcher */ gboolean @@ -215,6 +382,10 @@ mixgtk_cmd_dispatcher_init (void) { int r = pipe (dis_data_.fildes); g_return_val_if_fail (r == 0, FALSE); + /* connect stdout/stderr to the pipe's write end */ + if (dup2 (dis_data_.fildes[1], STDOUT_FILENO) == -1 + || dup2 (dis_data_.fildes[1], STDERR_FILENO) == -1) + return FALSE; dis_data_.out = fdopen (dis_data_.fildes[1], "w"); g_return_val_if_fail (dis_data_.out != NULL, FALSE); r = fcntl (dis_data_.fildes[0], F_GETFL, 0); @@ -225,6 +396,7 @@ mixgtk_cmd_dispatcher_init (void) dis_data_.dispatcher = mix_vm_cmd_dispatcher_new (dis_data_.out, dis_data_.out); mix_vm_cmd_dispatcher_print_time (dis_data_.dispatcher, FALSE); + install_hooks_ (); } @@ -238,6 +410,7 @@ mixgtk_cmd_dispatcher_init (void) } if (!dis_data_.completions) init_completions_ (); + read_config_ (); return TRUE; } @@ -266,7 +439,7 @@ mixgtk_cmd_dispatcher_get_times (gint *uptime, gint *progtime, gint *laptime) } /* get the underlying vm */ -extern mix_vm_t * +mix_vm_t * mixgtk_cmd_dispatcher_get_vm (void) { return (mix_vm_t *) mix_vm_cmd_dispatcher_get_vm (dis_data_.dispatcher); @@ -280,14 +453,20 @@ on_mixvm_cmd_entry_activate (GtkWidget *w, gpointer e) GList *cmds = NULL; gchar *prefix = NULL; - text = gtk_entry_get_text (GTK_ENTRY (w)); + text = g_strchomp (gtk_entry_get_text (GTK_ENTRY (w))); - if (mix_vm_command_from_string (g_strchomp (text)) != MIX_CMD_INVALID) + if (mix_vm_command_from_string (text) != MIX_CMD_INVALID) { mix_vm_cmd_dispatcher_dispatch_text (dis_data_.dispatcher, text); gtk_entry_set_text (GTK_ENTRY (w), ""); return; } + + if (dispatch_local_command_ (&dis_data_, text)) + { + gtk_entry_set_text (GTK_ENTRY (w), ""); + return; + } cmds = g_completion_complete (dis_data_.completions, text, &prefix); @@ -323,7 +502,10 @@ on_mixvm_cmd_entry_activate (GtkWidget *w, gpointer e) } else { + log_command_ (&dis_data_, text); mix_vm_cmd_dispatcher_dispatch_text (dis_data_.dispatcher, text); gtk_entry_set_text (GTK_ENTRY (w), ""); } } + + diff --git a/mixgtk/mixgtk_mixvm.h b/mixgtk/mixgtk_mixvm.h index 8207d91..04d210a 100644 --- a/mixgtk/mixgtk_mixvm.h +++ b/mixgtk/mixgtk_mixvm.h @@ -26,6 +26,7 @@ #define MIXGTK_MIXVM_H #include <mixlib/mix_vm.h> +#include "mixgtk.h" /* initialise the mixvm widgets */ extern gboolean diff --git a/mixgtk/mixgtk_widgets.c b/mixgtk/mixgtk_widgets.c index b032898..d5ac7b1 100644 --- a/mixgtk/mixgtk_widgets.c +++ b/mixgtk/mixgtk_widgets.c @@ -37,7 +37,8 @@ static const gchar * dnames_[] = { "color_dialog", "colorsel_dialog", "fontsel_dialog", - "devform_dialog" + "devform_dialog", + "external_dialog" }; #define DLG_NO_ (sizeof (dnames_) / sizeof(dnames_[0])) diff --git a/mixgtk/mixgtk_widgets.h b/mixgtk/mixgtk_widgets.h index 261ad12..ed7cf7e 100644 --- a/mixgtk/mixgtk_widgets.h +++ b/mixgtk/mixgtk_widgets.h @@ -37,7 +37,8 @@ typedef enum { MIXGTK_COLOR_DIALOG, /* color customization dialog */ MIXGTK_COLORSEL_DIALOG, /* color selection dialog */ MIXGTK_FONTSEL_DIALOG, /* font selection dialog */ - MIXGTK_DEVFORM_DIALOG /* device format config dialog */ + MIXGTK_DEVFORM_DIALOG, /* device format config dialog */ + MIXGTK_EXTERNPROG_DIALOG /* external programs dialog */ } mixgtk_dialog_id_t; /* enumeration of mixvm widget ids */ diff --git a/mixlib/mix_file.c b/mixlib/mix_file.c index ac623f6..816a380 100644 --- a/mixlib/mix_file.c +++ b/mixlib/mix_file.c @@ -133,6 +133,16 @@ mix_file_to_FILE(const mix_file_t *file) return io_get_FILE_(file); } +/* complete a name with an extension, if needed */ +gchar * +mix_file_complete_name (const gchar *name, const gchar *extension) +{ + if (!name) return NULL; + if (!extension || !needs_completion_ (name, extension)) + return g_strdup (name); + return add_completion_ (name, extension); +} + /* Get the base name and extension of file */ const gchar * mix_file_base_name(const mix_file_t *file) diff --git a/mixlib/mix_file.h b/mixlib/mix_file.h index a4bac12..bb9e7e3 100644 --- a/mixlib/mix_file.h +++ b/mixlib/mix_file.h @@ -49,6 +49,10 @@ mix_file_to_FILE(const mix_file_t *file); /* standard default extensions */ extern const gchar *MIX_SRC_DEFEXT, *MIX_LIST_DEFEXT, *MIX_CODE_DEFEXT; +/* complete a name with an extension, if needed */ +extern gchar * +mix_file_complete_name (const gchar *name, const gchar *extension); + /* Get the base name and extension of file */ extern const gchar * mix_file_base_name(const mix_file_t *file); diff --git a/samples/primes.mixal b/samples/primes.mixal index d8e6eef..d2de8c0 100644 --- a/samples/primes.mixal +++ b/samples/primes.mixal @@ -51,4 +51,3 @@ TITLE ALF "FIRST" CON BUF0+10 END START -
\ No newline at end of file |