diff options
| -rw-r--r-- | mixlib/mix_vm_command.c | 100 | ||||
| -rw-r--r-- | mixlib/mix_vm_command.h | 12 | 
2 files changed, 111 insertions, 1 deletions
| diff --git a/mixlib/mix_vm_command.c b/mixlib/mix_vm_command.c index 677b5f8..19c4695 100644 --- a/mixlib/mix_vm_command.c +++ b/mixlib/mix_vm_command.c @@ -50,6 +50,8 @@ struct mix_vm_cmd_dispatcher_t    mix_vm_t *vm;			/* the virtual machine */    gboolean result;		/* last command's outcome */    gchar *program;		/* the name of the last loaded program */ +  gchar *editor;		/* edit command line template */ +  gchar *assembler;		/* compile command line template */    FILE *out;			/* message output file */    FILE *err;			/* error output file */    mix_dump_context_t *dump;	/* dump context for output */ @@ -94,6 +96,8 @@ DEC_FUN (weval_);  DEC_FUN (w2d_);  DEC_FUN (tron_);  DEC_FUN (troff_); +DEC_FUN (edit_); +DEC_FUN (compile_);  /* internal command info struct */  typedef struct { @@ -108,6 +112,9 @@ typedef struct {  command_ commands_[] = {    { "help", cmd_help_, N_("Display this text"), "help [COMMAND]"},    { "load", cmd_load_, N_("Load a MIX code file"), "load FILENAME"}, +  { "edit", cmd_edit_, N_("Edit a MIXAL source file"), "edit [FILENAME]"}, +  { "compile", cmd_compile_, N_("Compile a MIXAL source file"), +    "compile [FILENAME]"},    { "run", cmd_run_, N_("Run loaded or given MIX code file"),       "run [FILENAME]"},    { "next", cmd_next_, N_("Execute next instruction(s)"),  @@ -197,6 +204,8 @@ mix_vm_cmd_dispatcher_new (FILE *out_fd, /* output messages file */    result->printtime = TRUE;    result->trace = FALSE;    result->program = NULL; +  result->editor = NULL; +  result->assembler = NULL;    result->eval = mix_eval_new ();    result->dump = mix_dump_context_new (out_fd,   				       MIX_SHORT_ZERO, MIX_SHORT_ZERO, @@ -214,16 +223,37 @@ mix_vm_cmd_dispatcher_new (FILE *out_fd, /* output messages file */  }  /* delete (does not close the fds in the constructor) */ -extern void +void  mix_vm_cmd_dispatcher_delete (mix_vm_cmd_dispatcher_t *dis)  {    g_return_if_fail (dis != NULL);    mix_eval_delete (dis->eval);    mix_dump_context_delete (dis->dump);    mix_vm_delete (dis->vm); +  if (dis->editor) g_free (dis->editor); +  if (dis->editor) g_free (dis->assembler);    g_free (dis);  } +/* set editor and compiler templates */ +void +mix_vm_cmd_dispatcher_set_editor (mix_vm_cmd_dispatcher_t *dis, +				  const gchar *edit_tplt) +{ +  g_return_if_fail (dis != NULL); +  if (dis->editor) g_free (dis->editor); +  dis->editor = (edit_tplt) ? g_strdup (edit_tplt) : NULL; +} + +void +mix_vm_cmd_dispatcher_set_assembler (mix_vm_cmd_dispatcher_t *dis, +				     const gchar *asm_tplt) +{ +  g_return_if_fail (dis != NULL); +  if (dis->assembler) g_free (dis->assembler); +  dis->assembler = (asm_tplt) ? g_strdup (asm_tplt) : NULL; +} +  /* install hooks */  void  mix_vm_cmd_dispatcher_pre_hook (mix_vm_cmd_dispatcher_t *dis, @@ -508,6 +538,74 @@ cmd_load_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg)    return TRUE;  } +static const gchar * +get_src_file_path_ (mix_vm_cmd_dispatcher_t *dis) +{ +  static gchar *PATH = NULL; +   +  const mix_vm_t *vm = mix_vm_cmd_dispatcher_get_vm (dis); +  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 +cmd_edit_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) +{ +  if (dis->editor == NULL) +    { +      fputs (_("Editor not specified (set MDK_EDITOR)\n"), dis->err); +      return FALSE; +    } +  if (!arg || *arg == '\0') arg = get_src_file_path_ (dis); +  if (!arg) +    { +      fputs (_("MIXAL source file path not found\n"), dis->err); +      return FALSE; +    } +  else +    { +      gchar *cmd = g_strdup_printf (dis->editor, arg); +      system (cmd); +      g_free (cmd); +      return TRUE; +    } +} + +static gboolean +cmd_compile_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) +{ +  if (dis->assembler == NULL) +    { +      fputs (_("MIX assembler not specified\n"), dis->err); +      return FALSE; +    } +  if (!arg || *arg == '\0') arg = get_src_file_path_ (dis); +  if (!arg) +    { +      fputs (_("MIXAL source file path not found\n"), dis->err); +      return FALSE; +    } +  else +    { +      gchar *cmd = g_strdup_printf (dis->assembler, arg); +      system (cmd); +      g_free (cmd); +      return TRUE; +    } +} + +  static gboolean  cmd_run_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) diff --git a/mixlib/mix_vm_command.h b/mixlib/mix_vm_command.h index 856c2d5..ad73064 100644 --- a/mixlib/mix_vm_command.h +++ b/mixlib/mix_vm_command.h @@ -39,6 +39,8 @@ typedef struct mix_vm_cmd_dispatcher_t mix_vm_cmd_dispatcher_t;  typedef enum {    MIX_CMD_HELP = 0,		/* echo help message */    MIX_CMD_LOAD,			/* load a mix program */ +  MIX_CMD_EDIT,			/* edit mixal source */ +  MIX_CMD_COMPILE,		/* compile mixal source */    MIX_CMD_RUN,			/* run a loaded program */    MIX_CMD_NEXT,			/* run next instruction */    MIX_CMD_LOC,			/* print location pointer */ @@ -97,6 +99,16 @@ mix_vm_cmd_dispatcher_new (FILE *out_fd, /* output messages file */  extern void  mix_vm_cmd_dispatcher_delete (mix_vm_cmd_dispatcher_t *dis); + +/* set editor and compiler templates */ +extern void +mix_vm_cmd_dispatcher_set_editor (mix_vm_cmd_dispatcher_t *dis, +				  const gchar *edit_tplt); + +extern void +mix_vm_cmd_dispatcher_set_assembler (mix_vm_cmd_dispatcher_t *dis, +				     const gchar *asm_tplt); +  /* dispatch a command */  extern gboolean /* TRUE if success, FALSE otherwise */  mix_vm_cmd_dispatcher_dispatch (mix_vm_cmd_dispatcher_t *dis, | 
