diff options
Diffstat (limited to 'mixlib')
-rw-r--r-- | mixlib/mix_vm_command.c | 32 | ||||
-rw-r--r-- | mixlib/mix_vm_command.h | 20 | ||||
-rw-r--r-- | mixlib/xmix_vm_command.c | 33 | ||||
-rw-r--r-- | mixlib/xmix_vm_command.h | 20 | ||||
-rw-r--r-- | mixlib/xmix_vm_handlers.c | 448 | ||||
-rw-r--r-- | mixlib/xmix_vm_handlers.h | 12 |
6 files changed, 377 insertions, 188 deletions
diff --git a/mixlib/mix_vm_command.c b/mixlib/mix_vm_command.c index 07496c0..2b2819e 100644 --- a/mixlib/mix_vm_command.c +++ b/mixlib/mix_vm_command.c @@ -121,6 +121,7 @@ mix_vm_cmd_dispatcher_new (FILE *out_fd, /* output messages file */ result->result = TRUE; result->out = out_fd; result->err = err_fd; + result->log_msg = TRUE; result->uptime = result->laptime = result->progtime = 0; result->printtime = TRUE; result->trace = FALSE; @@ -157,22 +158,24 @@ mix_vm_cmd_dispatcher_new_with_config (FILE *out, FILE *err, { gint hsize = 0; const gchar *val = mix_config_get (result->config, TRACING_KEY_); - if (val) cmd_tracing_ (result, val); + if (val) cmd_strace_ (result, val); val = mix_config_get (result->config, EDITOR_KEY_); if (val) mix_vm_cmd_dispatcher_set_editor (result, val); val = mix_config_get (result->config, ASM_KEY_); if (val) mix_vm_cmd_dispatcher_set_assembler (result, val); val = mix_config_get (result->config, TIMING_KEY_); - if (val) cmd_timing_ (result, val); + if (val) cmd_stime_ (result, val); val = mix_config_get_devices_dir (result->config); if (!val || !mix_stat_dir (val, "devices")) { gchar *dirname = g_dirname (mix_config_get_filename (config)); - cmd_devdir_ (result, dirname); + cmd_sddir_ (result, dirname); g_free (dirname); } else mix_device_set_dir (val); + val = mix_config_get (result->config, LOGGING_KEY_); + if (val) cmd_slog_ (result, val); #ifdef HAVE_LIBHISTORY val = mix_config_get_history_file (result->config); hsize = mix_config_get_history_size (result->config); @@ -603,3 +606,26 @@ mix_vm_cmd_dispatcher_get_vm (const mix_vm_cmd_dispatcher_t *dis) return dis->vm; } +/* src file info */ +gulong +mix_vm_cmd_dispatcher_get_src_file_lineno (const mix_vm_cmd_dispatcher_t *dis) +{ + g_return_val_if_fail (dis != NULL, 0); + return mix_vm_get_break_lineno (dis->vm); +} + +const gchar * +mix_vm_cmd_dispatcher_get_src_file_line (const mix_vm_cmd_dispatcher_t *dis, + gulong line) +{ + const mix_src_file_t *file; + g_return_val_if_fail (dis != NULL, NULL); + + file = mix_vm_get_src_file (dis->vm); + + if (line == 0 || file == NULL) return ""; + + return mix_src_file_get_line (file, line); +} + + diff --git a/mixlib/mix_vm_command.h b/mixlib/mix_vm_command.h index b6672a0..8d9e86e 100644 --- a/mixlib/mix_vm_command.h +++ b/mixlib/mix_vm_command.h @@ -74,10 +74,16 @@ typedef enum { MIX_CMD_CABP, /* clear all breakpoints */ MIX_CMD_WEVAL, /* evaluate a w-expression */ MIX_CMD_W2D, /* print word in decimal notation */ - MIX_CMD_TRACING, /* enable/disable instruction traces */ + MIX_CMD_STRACE, /* enable/disable instruction traces */ MIX_CMD_PBT, /* print backtrace */ - MIX_CMD_TIMING, /* enable/disable timing statistics */ - MIX_CMD_DEVDIR, /* print/set device directory */ + MIX_CMD_STIME, /* enable/disable timing statistics */ + MIX_CMD_PTIME, /* print current time statistics */ + MIX_CMD_SDDIR, /* set device directory */ + MIX_CMD_PDDIR, /* print current device directory */ + MIX_CMD_SLOG, /* set on/off message logging */ + MIX_CMD_PPROG, /* print the current program path */ + MIX_CMD_PSRC, /* print the current program source path */ + MIx_CMD_PLINE, /* print the current line no */ MIX_CMD_INVALID, /* invalid command identifier */ MIX_CMD_LOCAL /* locally defined command */ } mix_vm_command_t; @@ -206,6 +212,14 @@ mix_vm_cmd_dispatcher_get_progtime (const mix_vm_cmd_dispatcher_t *dis); extern mix_time_t mix_vm_cmd_dispatcher_get_laptime (const mix_vm_cmd_dispatcher_t *dis); +/* src file info */ +extern gulong +mix_vm_cmd_dispatcher_get_src_file_lineno (const mix_vm_cmd_dispatcher_t *dis); + +extern const gchar * +mix_vm_cmd_dispatcher_get_src_file_line (const mix_vm_cmd_dispatcher_t *dis, + gulong line); + /* toggle time printing */ extern void mix_vm_cmd_dispatcher_print_time (mix_vm_cmd_dispatcher_t * dis, diff --git a/mixlib/xmix_vm_command.c b/mixlib/xmix_vm_command.c index 0c0ec8a..32acc92 100644 --- a/mixlib/xmix_vm_command.c +++ b/mixlib/xmix_vm_command.c @@ -21,6 +21,8 @@ * */ +#include <stdarg.h> +#include <stdio.h> #include "xmix_vm_command.h" @@ -29,3 +31,34 @@ const gchar *TRACING_KEY_ = "Tracing"; const gchar *TIMING_KEY_ = "Timing"; const gchar *EDITOR_KEY_ = "Editor"; const gchar *ASM_KEY_ = "Assembler"; +const gchar *LOGGING_KEY_ = "Logs"; + +void +log_message_ (mix_vm_cmd_dispatcher_t *dis, const gchar *fmt, ...) +{ + if (dis && fmt && dis->log_msg && dis->out) + { + va_list args; + va_start (args, fmt); + vfprintf (dis->out, fmt, args); + fprintf (dis->out, "\n"); + va_end (args); + } +} + + +extern void +log_error_ (mix_vm_cmd_dispatcher_t *dis, const gchar *fmt, ...) +{ + enum {BUFF_SIZE = 256}; + static gchar BUFFER[256]; + + if (dis && fmt && dis->err) + { + va_list args; + va_start (args, fmt); + snprintf (BUFFER, BUFF_SIZE, "ERROR: %s\n", fmt); + vfprintf (dis->err, BUFFER, args); + va_end (args); + } +} diff --git a/mixlib/xmix_vm_command.h b/mixlib/xmix_vm_command.h index f83bf72..6a691ee 100644 --- a/mixlib/xmix_vm_command.h +++ b/mixlib/xmix_vm_command.h @@ -44,6 +44,7 @@ extern const gchar *TRACING_KEY_; extern const gchar *TIMING_KEY_; extern const gchar *EDITOR_KEY_; extern const gchar *ASM_KEY_; +extern const gchar *LOGGING_KEY_; /* hooks */ typedef struct @@ -59,7 +60,7 @@ typedef struct } global_hook_; -#define PRNO_ MIX_PRED_MEM +enum {PRNO_ = MIX_PRED_MEM, HOOKNO_ = MIX_CMD_INVALID}; struct mix_vm_cmd_dispatcher_t { @@ -79,14 +80,23 @@ struct mix_vm_cmd_dispatcher_t mix_time_t progtime; /* current program running time */ GHashTable *commands; /* local commands */ GCompletion *completions; /* command completion list */ - GSList *pre_hooks[MIX_CMD_INVALID]; /* Pre-command hooks */ - GSList *post_hooks[MIX_CMD_INVALID]; /* Post-command hooks */ - GSList *global_pre; /* global pre-command hook */ - GSList *global_post; /* global post-command hook */ + GSList *pre_hooks[HOOKNO_]; /* Pre-command hooks */ + GSList *post_hooks[HOOKNO_]; /* Post-command hooks */ + GSList *global_pre; /* global pre-command hook */ + GSList *global_post; /* global post-command hook */ mix_config_t *config; /* externally provided configuration */ mix_predicate_t *preds[PRNO_]; /* predicates for conditional breakpoints */ GHashTable *mem_preds; /* predicates for memory conditional bps */ + gboolean log_msg; /* message logging activation flag*/ }; +extern void +log_message_ (mix_vm_cmd_dispatcher_t *dis, const gchar *fmt, ...); + +extern void +log_error_ (mix_vm_cmd_dispatcher_t *dis, const gchar *fmt, ...); + +#define wants_logs_(dis) (dis)->log_msg + #endif /* XMIX_VM_COMMAND_H */ diff --git a/mixlib/xmix_vm_handlers.c b/mixlib/xmix_vm_handlers.c index 8bbbad4..ed240fb 100644 --- a/mixlib/xmix_vm_handlers.c +++ b/mixlib/xmix_vm_handlers.c @@ -83,14 +83,20 @@ mix_vm_command_info_t commands_[] = { { "weval", cmd_weval_, N_("Evaluate a given W-expression"), "weval WEXPR"}, { "w2d", cmd_w2d_, N_("Convert a MIX word to its decimal value"), "w2d WORD"}, - { "tracing", cmd_tracing_, N_("Turn on/off instruction tracing"), - "tracing [on|off]"}, + { "strace", cmd_strace_, N_("Turn on/off instruction tracing"), + "strace on|off"}, { "pbt", cmd_pbt_, N_("Print backtrace of executed instructions"), "pbt [INS_NO] (e.g pbt 5)"}, - { "timing", cmd_timing_, N_("Turn on/off timing statistics"), - "timing [on|off]"}, - { "devdir", cmd_devdir_, N_("Print/set devices directory"), - "devdir [NEWDIR]"}, + { "stime", cmd_stime_, N_("Turn on/off timing statistics"), + "stime on|off"}, + { "ptime", cmd_ptime_, N_("Print current time statistics"), "ptime"}, + { "sddir", cmd_sddir_, N_("Set devices directory"),"sddir NEWDIR"}, + { "pddir", cmd_pddir_, N_("Print current devices directory"),"pddir"}, + { "slog", cmd_slog_, N_("Turn on/off message logging"), "slog on|off"}, + { "pprog", cmd_pprog_, N_("Print the current program path"), "pprog"}, + { "psrc", cmd_psrc_, N_("Print the current program source path"), "psrc"}, + { "pline", cmd_pline_, + N_("Print the current (or a given) program source line"), "pline [LINENO]"}, { NULL, NULL, NULL, NULL}, }; @@ -101,21 +107,24 @@ trace_ (mix_vm_cmd_dispatcher_t *dis) enum {BUFFER_LEN = 128}; static gchar STRINS[BUFFER_LEN]; - const mix_src_file_t *file = mix_vm_get_src_file (dis->vm); - const gchar *line = "\n"; - mix_address_t loc = mix_vm_get_prog_count (dis->vm); - mix_word_t ins = mix_vm_get_addr_contents (dis->vm, loc); - mix_ins_t fins; - mix_word_to_ins_uncheck (ins, fins); - mix_ins_to_string_in_buffer (&fins, STRINS, BUFFER_LEN); - - if (file != NULL) - { - gulong b = mix_vm_get_break_lineno (dis->vm); - if (b > 0) line = mix_src_file_get_line (file, b); + if (wants_logs_ (dis)) + { + const mix_src_file_t *file = mix_vm_get_src_file (dis->vm); + const gchar *line = "\n"; + mix_address_t loc = mix_vm_get_prog_count (dis->vm); + mix_word_t ins = mix_vm_get_addr_contents (dis->vm, loc); + mix_ins_t fins; + mix_word_to_ins_uncheck (ins, fins); + mix_ins_to_string_in_buffer (&fins, STRINS, BUFFER_LEN); + + if (file != NULL) + { + gulong b = mix_vm_get_break_lineno (dis->vm); + if (b > 0) line = mix_src_file_get_line (file, b); + } + + log_message_ (dis, "%d: [%-15s]\t%s", (gint)loc, STRINS, line); } - - fprintf (dis->out, "%d: [%-15s]\t%s", (gint)loc, STRINS, line); } /* run a program tracing executed instructions */ @@ -137,7 +146,7 @@ run_and_trace_ (mix_vm_cmd_dispatcher_t *dis) static void print_time_ (mix_vm_cmd_dispatcher_t *dis) { - dis->laptime = mix_vm_get_uptime(dis->vm) - dis->uptime; + dis->laptime = mix_vm_get_uptime (dis->vm) - dis->uptime; dis->uptime += dis->laptime; dis->progtime += dis->laptime; if (dis->printtime) @@ -194,32 +203,32 @@ cmd_load_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) errno = 0; if (arg == NULL || *arg == '\0') { - fputs (_("Missing file name\n"), dis->err); + log_error_ (dis, _("Missing file name")); return FALSE; } mix_eval_remove_symbols_from_table (dis->eval, mix_vm_get_symbol_table (dis->vm)); if (!mix_vm_load_file (dis->vm, arg) ) { - fprintf (dis->err, _("Cannot load %s: "), arg); + log_error_ (dis, _("Cannot load %s: ")); if ( errno == 0 ) - fputs (_("Wrong file format\n"), dis->err); + log_error_ (dis, _("Wrong file format")); else - fprintf (dis->err, "%s\n", strerror (errno)); + log_error_ (dis, "%s", strerror (errno)); return FALSE; } if (dis->program != arg) { if (dis->program) g_free (dis->program); - dis->program = g_strdup (arg); + dis->program = mix_file_complete_name (arg, MIX_CODE_DEFEXT); } mix_eval_set_symbols_from_table (dis->eval, mix_vm_get_symbol_table (dis->vm)); - - fprintf (dis->out, _("Program loaded. Start address: %d\n"), - mix_vm_get_prog_count (dis->vm)); + if (wants_logs_ (dis)) + log_message_ (dis, _("Program loaded. Start address: %d"), + mix_vm_get_prog_count (dis->vm)); dis->laptime = dis->progtime = 0; return TRUE; @@ -230,21 +239,21 @@ 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); + log_error_ (dis, _("Editor not specified (use sedit)")); return FALSE; } if (!arg || *arg == '\0') arg = mix_vm_cmd_dispatcher_get_src_file_path (dis); if (!arg) { - fputs (_("MIXAL source file path not found\n"), dis->err); + log_error_ (dis, _("MIXAL source file path not found")); return FALSE; } else { gchar *cmd = g_strdup_printf (dis->editor, arg); - fputs (cmd, dis->out); + if (wants_logs_ (dis)) log_message_ (dis, cmd); system (cmd); - fputs (_(" ...done\n"), dis->out); + if (wants_logs_ (dis)) log_message_ (dis, _(" ...done")); g_free (cmd); return TRUE; } @@ -255,22 +264,21 @@ cmd_compile_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) { if (dis->assembler == NULL) { - fputs (_("MIX assembler not specified\n"), dis->err); + log_error_ (dis, _("MIX assembler not specified (use sasm)")); return FALSE; } if (!arg || *arg == '\0') arg = mix_vm_cmd_dispatcher_get_src_file_path (dis); if (!arg) { - fputs (_("MIXAL source file path not found\n"), dis->err); + log_error_ (dis, _("MIXAL source file path not found")); return FALSE; } else { gchar *cmd = g_strdup_printf (dis->assembler, arg); - fputs (cmd, dis->out); - fputs ("\n", dis->out); - if (system (cmd) == EXIT_SUCCESS) - fputs (_("Successful compilation\n"), dis->out); + if (wants_logs_ (dis)) log_message_ (dis, cmd); + if (system (cmd) == EXIT_SUCCESS && wants_logs_ (dis)) + log_message_ (dis, _("Successful compilation")); g_free (cmd); return TRUE; } @@ -284,46 +292,48 @@ cmd_run_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) if (mix_vm_is_halted (dis->vm)) cmd_load_ (dis, dis->program); - fputs (_("Running ...\n"), dis->out); + if (wants_logs_ (dis)) log_message_ (dis, _("Running ...")); switch (run_and_trace_ (dis)) { case MIX_VM_HALT: - fputs (_("... done\n"), dis->out); + if (wants_logs_ (dis)) log_message_ (dis, _("... done")); break; case MIX_VM_BREAK: - { - gulong line = mix_vm_get_break_lineno (dis->vm); - if (line != 0) - fprintf (dis->out, - _("... stopped: breakpoint at line %ld (address %d)\n"), - line, mix_vm_get_prog_count (dis->vm)); - else - fprintf (dis->out, _("... stopped: breakpoint at address %d\n"), - mix_vm_get_prog_count (dis->vm)); + if (wants_logs_ (dis)) + { + gulong line = mix_vm_get_break_lineno (dis->vm); + if (line != 0) + log_message_ + (dis, _("... stopped: breakpoint at line %ld (address %d)"), + line, mix_vm_get_prog_count (dis->vm)); + else + log_message_ (dis, _("... stopped: breakpoint at address %d"), + mix_vm_get_prog_count (dis->vm)); } break; case MIX_VM_COND_BREAK: - { - gulong line = mix_vm_get_break_lineno (dis->vm); - if (line != 0) - fprintf (dis->out, _("... stopped: %s (line %ld, address %d)\n"), - mix_vm_get_last_breakpoint_message (dis->vm), - line, mix_vm_get_prog_count (dis->vm)); - else - fprintf (dis->out, _("... stopped: %s (address %d)\n"), - mix_vm_get_last_breakpoint_message (dis->vm), - mix_vm_get_prog_count (dis->vm)); + if (wants_logs_ (dis)) + { + gulong line = mix_vm_get_break_lineno (dis->vm); + if (line != 0) + log_message_ (dis, _("... stopped: %s (line %ld, address %d)"), + mix_vm_get_last_breakpoint_message (dis->vm), + line, mix_vm_get_prog_count (dis->vm)); + else + log_message_ (dis, _("... stopped: %s (address %d)"), + mix_vm_get_last_breakpoint_message (dis->vm), + mix_vm_get_prog_count (dis->vm)); } break; case MIX_VM_ERROR: - fputs (_("... error executing loaded file"), dis->err); + log_error_ (dis, _("... error executing loaded file")); break; default: g_assert_not_reached (); break; } - print_time_ (dis); + if (wants_logs_ (dis)) print_time_ (dis); return TRUE; } @@ -341,8 +351,7 @@ cmd_next_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) k++; if (arg[k] != '\0') { - fprintf (dis->err, _("Invalid argument: %s\n"), arg); - cmd_help_ (dis, "next"); + log_error_ (dis, _("Invalid argument: %s"), arg); return FALSE; } ins_no = atoi (arg); @@ -356,18 +365,19 @@ cmd_next_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) k = mix_vm_exec_next (dis->vm); if (k == MIX_VM_HALT) { - fprintf (dis->err, _("End of program reached at address %d\n"), - mix_vm_get_prog_count (dis->vm)); + if (wants_logs_ (dis)) + log_message_(dis, _("End of program reached at address %d"), + mix_vm_get_prog_count (dis->vm)); break; } else if (k == MIX_VM_ERROR) { - fprintf (dis->err, _("Error at address %d\n"), - mix_vm_get_prog_count (dis->vm)); + log_error_ (dis, _("Error at address %d"), + mix_vm_get_prog_count (dis->vm)); break; } } - print_time_ (dis); + if (wants_logs_ (dis)) print_time_ (dis); return TRUE; } @@ -385,7 +395,7 @@ cmd_psym_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) gboolean result = FALSE; const mix_symbol_table_t *table = mix_eval_symbol_table (dis->eval); if ( table == NULL ) - fputs (_("Symbol table not available\n"), dis->err); + log_error_ (dis, _("Symbol table not available")); else if (arg != NULL && *arg != '\0') { if ( mix_symbol_table_is_defined (table, arg) ) @@ -437,7 +447,7 @@ cmd_preg_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) int i = arg[1] - '1'; if ( i < 0 || i > 5 ) { - fprintf (dis->err, _("Invalid I index: %d\n"), i); + log_error_ (dis, _("Invalid I index: %d"), i); return FALSE; } mix_dump_context_add_opt (dis->dump, opt[i]); @@ -445,7 +455,7 @@ cmd_preg_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) } break; default: - fprintf (dis->err, _("Invalid argument: %s\n"), arg); + log_error_ (dis, _("Invalid argument: %s"), arg); return FALSE; } mix_vm_dump (dis->vm, dis->dump); @@ -478,7 +488,7 @@ cmd_pmem_ (mix_vm_cmd_dispatcher_t *dis, const gchar *carg) if ( strlen (carg) == 0 ) { - fputs (_("Missing memory address\n"), dis->err); + log_error_ (dis, _("Missing memory address")); return FALSE; } arg = g_strdup (carg); @@ -509,12 +519,11 @@ cmd_pmem_ (mix_vm_cmd_dispatcher_t *dis, const gchar *carg) if (error) { - fprintf (dis->err, _("Invalid argument: %s\n"), arg); - cmd_help_ (dis, "pmem"); + log_error_ (dis, _("Invalid argument: %s"), arg); } else if ( end < begin || end > MIX_VM_CELL_NO - 1 ) { - fprintf (dis->err, _("Invalid range: %ld-%ld\n"), begin, end); + log_error_ (dis, _("Invalid range: %ld-%ld"), begin, end); error = TRUE; } else @@ -579,8 +588,7 @@ cmd_sreg_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) } if (!ok) { - fprintf (dis->err, _("Invalid argument: %s\n"), arg); - cmd_help_ (dis, "sreg"); + log_error_ (dis, _("Invalid argument: %s"), arg); } return ok; @@ -606,8 +614,7 @@ cmd_scmp_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) } if (!ok) { - fprintf (dis->err, _("Invalid argument: %s\n"), arg); - cmd_help_ (dis, "scmp"); + log_error_ (dis, _("Invalid argument: %s"), arg); } return ok; @@ -630,8 +637,7 @@ cmd_sover_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) } if (!ok) { - fprintf (dis->err, _("Invalid argument: %s\n"), arg); - cmd_help_ (dis, "sover"); + log_error_ (dis, _("Invalid argument: %s"), arg); } return ok; @@ -672,8 +678,7 @@ cmd_smem_ (mix_vm_cmd_dispatcher_t *dis, const gchar *carg) mix_word_new (value)); else { - fprintf (dis->err, _("Invalid argument: %s\n"), arg); - cmd_help_ (dis, "smem"); + log_error_ (dis, _("Invalid argument: %s"), arg); } if (arg) g_free (arg); @@ -686,8 +691,7 @@ cmd_ssym_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) gboolean result = FALSE; if (arg == NULL || strlen(arg) == 0) { - fprintf (dis->err, _("Missing arguments\n")); - cmd_help_ (dis, "ssym"); + log_error_ (dis, _("Missing arguments")); } else { @@ -704,8 +708,7 @@ cmd_ssym_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) } else { - fprintf (dis->err, _("Wrong argument number\n")); - cmd_help_ (dis, "ssym"); + log_error_ (dis, _("Wrong argument number")); } g_free (a); } @@ -720,25 +723,25 @@ cmd_sbp_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) while (isdigit (arg[k])) k++; if (arg[k] != '\0') { - fprintf (dis->err, _("Invalid argument: %s\n"), arg); - cmd_help_ (dis, "sbp"); + log_error_ (dis, _("Invalid argument: %s"), arg); return FALSE; } lineno = atol (arg); switch (k = mix_vm_set_breakpoint (dis->vm, lineno)) { case MIX_VM_BP_INV_LINE: - fprintf (dis->err, _("Line number %ld too high\n"), lineno); + log_error_ (dis, _("Line number %ld too high"), lineno); break; case MIX_VM_BP_ERROR: - fputs (_("Could not set breakpoint. Internal error\n"), dis->err); + log_error_ (dis, _("Could not set breakpoint: internal error")); break; case MIX_VM_BP_NDEBUG: - fputs (_("Could not set breakpoint. No debug info available\n"), - dis->err); + log_error_ (dis, _("Could not set breakpoint: no debug info available"), + dis->err); break; default: - fprintf (dis->err, _("Breakpoint set at line %ld\n"), k); + if (wants_logs_ (dis)) + log_message_ (dis, _("Breakpoint set at line %ld"), k); return TRUE; } return FALSE; @@ -752,21 +755,21 @@ cmd_sbpa_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) while (isdigit (arg[k])) k++; if (arg[k] != '\0') { - fprintf (dis->err, _("Invalid argument: %s\n"), arg); - cmd_help_ (dis, "sbpa"); + log_error_ (dis, _("Invalid argument: %s"), arg); return FALSE; } address = atol (arg); switch (mix_vm_set_breakpoint_address (dis->vm, address)) { case MIX_VM_BP_INV_ADDRESS: - fprintf (dis->err, _("Invalid address %ld\n"), address); + log_error_ (dis, _("Invalid address %ld"), address); break; case MIX_VM_BP_ERROR: - fputs (_("Could not set breakpoint. Internal error\n"), dis->err); + log_error_ (dis, _("Could not set breakpoint: internal error")); break; default: - fprintf (dis->err, _("Breakpoint set at address %ld\n"), address); + if (wants_logs_ (dis)) + log_message_ (dis, _("Breakpoint set at address %ld"), address); return TRUE; } return FALSE; @@ -780,24 +783,24 @@ cmd_cbp_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) while (isdigit (arg[k])) k++; if (arg[k] != '\0') { - fprintf (dis->err, _("Invalid argument: %s\n"), arg); - cmd_help_ (dis, "cbp"); + log_error_ (dis, _("Invalid argument: %s"), arg); return FALSE; } lineno = atol (arg); switch (mix_vm_clear_breakpoint (dis->vm, lineno)) { case MIX_VM_BP_INV_LINE: - fprintf (dis->err, _("No breakpoint set at line %ld\n"), lineno); + log_error_ (dis, _("No breakpoint set at line %ld"), lineno); break; case MIX_VM_BP_ERROR: - fputs (_("Could not set breakpoint. Internal error\n"), dis->err); + log_error_ (dis, _("Could not set breakpoint: internal error")); break; case MIX_VM_BP_NDEBUG: - fputs (_("No debug info available\n"), dis->err); + log_error_ (dis, _("No debug info available")); break; case MIX_VM_BP_OK: - fprintf (dis->err, _("Breakpoint cleared at line %ld\n"), lineno); + if (wants_logs_ (dis)) + log_message_ (dis, _("Breakpoint cleared at line %ld"), lineno); return TRUE; default: g_assert_not_reached (); @@ -814,21 +817,21 @@ cmd_cbpa_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) while (isdigit (arg[k])) k++; if (arg[k] != '\0') { - fprintf (dis->err, _("Invalid argument: %s\n"), arg); - cmd_help_ (dis, "cbpa"); + log_error_ (dis, _("Invalid argument: %s"), arg); return FALSE; } address = atol (arg); switch (mix_vm_clear_breakpoint_address (dis->vm, address)) { case MIX_VM_BP_INV_ADDRESS: - fprintf (dis->err, _("Invalid address %ld\n"), address); + log_error_ (dis, _("Invalid address %ld"), address); break; case MIX_VM_BP_ERROR: - fputs (_("Could not clear breakpoint. Internal error\n"), dis->err); + log_error_ (dis, _("Could not clear breakpoint: internal error")); break; default: - fprintf (dis->err, _("Breakpoint cleared at address %ld\n"), address); + if (wants_logs_ (dis)) + log_message_ (dis, _("Breakpoint cleared at address %ld"), address); return TRUE; } return FALSE; @@ -840,8 +843,7 @@ cmd_cabp_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) { if (strlen (arg) != 0) { - fprintf (dis->err, _("Invalid argument: %s\n"), arg); - cmd_help_ (dis, "cabp"); + log_error_ (dis, _("Unexpected argument: %s"), arg); return FALSE; } mix_vm_clear_all_breakpoints (dis->vm); @@ -853,7 +855,7 @@ cmd_weval_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) { if ( strlen (arg) == 0 ) { - cmd_help_ (dis, "weval"); + log_error_ (dis, _("Missing expression")); return FALSE; } @@ -885,7 +887,7 @@ cmd_w2d_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) { if ( strlen (arg) == 0 ) { - cmd_help_ (dis, "w2d"); + log_error_ (dis, _("Missing expression")); return FALSE; } else @@ -901,7 +903,7 @@ cmd_w2d_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) { if (strlen (b) != 2 || !isdigit(b[0]) || !isdigit(b[1])) { - fprintf (dis->err, _("Incorrect byte specification: %s\n"), b); + log_error_ (dis, _("Incorrect byte specification: %s"), b); success = FALSE; b = NULL; } @@ -915,8 +917,8 @@ cmd_w2d_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) { if (strtok (NULL, "\t") != NULL) { - fprintf (dis->err, - _("The expression %s does not fit in a word\n"), arg); + log_error_ (dis, + _("The expression %s does not fit in a word"), arg); success = FALSE; } else @@ -933,70 +935,79 @@ cmd_w2d_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) } gboolean -cmd_tracing_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) +cmd_strace_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) { static const gchar *ON = "on"; static const gchar *OFF = "off"; - if (arg && !strcmp (arg, ON)) + if (!arg || !strlen (arg)) + { + log_error_ (dis, _("Missing argument")); + } + else if (!strcmp (arg, ON)) { dis->trace = TRUE; if (dis->config) mix_config_update (dis->config, TRACING_KEY_, ON); } - else if (arg && !strcmp (arg, OFF)) + else if (!strcmp (arg, OFF)) { dis->trace = FALSE; if (dis->config) mix_config_update (dis->config, TRACING_KEY_, OFF); } - else if (arg && !strlen (arg)) - { - fprintf (dis->out, "Instruction tracing is currently set %s\n", - dis->trace ? "ON" : "OFF"); - } else - cmd_help_ (dis, "tracing"); + log_error_ (dis, _("Wrong argument: "), arg); return TRUE; } gboolean -cmd_timing_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) +cmd_stime_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) { static const gchar *ON = "on"; static const gchar *OFF = "off"; - if (arg && !strcmp (arg, ON)) + if (!arg || !strlen (arg)) + { + log_error_ (dis, _("Missing argument")); + } + else if (!strcmp (arg, ON)) { dis->printtime = TRUE; if (dis->config) mix_config_update (dis->config, TIMING_KEY_, ON); } - else if (arg && !strcmp (arg, OFF)) + else if (!strcmp (arg, OFF)) { dis->printtime = FALSE; if (dis->config) mix_config_update (dis->config, TIMING_KEY_, OFF); } - else if (arg && !strlen (arg)) - { - print_time_ (dis); - } else - cmd_help_ (dis, "timing"); + log_error_ (dis, _("Wrong argument: "), arg); return TRUE; } +gboolean +cmd_ptime_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) +{ + print_time_ (dis); + return TRUE; +} gboolean cmd_pedit_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) { const gchar *ed = mix_vm_cmd_dispatcher_get_editor (dis); if (dis) - fprintf (dis->out, "Edit command: %s\n", ed); + fprintf (dis->out, _("Edit command: %s\n"), ed); else - fprintf (dis->out, "Edit command not set (use sedit)\n"); + fprintf (dis->out, _("Edit command not set (use sedit)\n")); return TRUE; } gboolean cmd_sedit_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) { - if (!arg || !strlen (arg)) return cmd_help_ (dis, "sedit"); + if (!arg || !strlen (arg)) + { + log_error_ (dis, _("Missing argument")); + return FALSE; + } mix_vm_cmd_dispatcher_set_editor (dis, arg); return TRUE; } @@ -1006,30 +1017,39 @@ cmd_pasm_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) { const gchar *ed = mix_vm_cmd_dispatcher_get_assembler (dis); if (dis) - fprintf (dis->out, "Compile command: %s\n", ed); + fprintf (dis->out, _("Compile command: %s\n"), ed); else - fprintf (dis->out, "Compile command not set (use sasm)\n"); + fprintf (dis->out, _("Compile command not set (use sasm)\n")); return TRUE; } gboolean cmd_sasm_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) { - if (!arg || !strlen (arg)) return cmd_help_ (dis, "sasm"); + if (!arg || !strlen (arg)) + { + log_error_ (dis, _("Missing argument")); + return FALSE; + } mix_vm_cmd_dispatcher_set_assembler (dis, arg); return TRUE; } gboolean -cmd_devdir_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) +cmd_sddir_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) { - if (!arg || !strlen (arg)) - fprintf (dis->out, "Device directory: %s\n", mix_device_get_dir ()); + if (!arg || !strlen (arg)) log_error_ (dis, _("Missing argument")); else if (mix_device_set_dir (arg) && dis->config) mix_config_set_devices_dir (dis->config, arg); return TRUE; } +gboolean +cmd_pddir_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) +{ + fprintf (dis->out, _("Device directory: %s\n"), mix_device_get_dir ()); + return TRUE; +} static const gint INVALID_REG_ = -2; @@ -1072,12 +1092,14 @@ cmd_sbpr_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) if (pred != INVALID_REG_) { mix_vm_set_conditional_breakpoint (dis->vm, dis->preds[pred]); - fprintf (dis->out, _("Conditional breakpoint on r%s change set\n"), arg); + if (wants_logs_ (dis)) + log_message_ (dis, + _("Conditional breakpoint on r%s change set"), arg); return TRUE; } else { - fprintf (dis->err, "Invalid argument %s\n", arg); + log_error_ (dis, _("Invalid argument %s"), arg); return FALSE; } } @@ -1089,16 +1111,19 @@ cmd_cbpr_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) if (pred != INVALID_REG_) { if (mix_vm_clear_conditional_breakpoint (dis->vm, dis->preds[pred])) - fprintf (dis->out, - _("Conditional breakpoint on r%s change removed\n"), - arg); + { + if (wants_logs_(dis)) + log_message_ (dis, + _("Conditional breakpoint on r%s change removed"), + arg); + } else - fprintf (dis->err, _("No breakpoint set on r%s change\n"), arg); + log_error_ (dis, _("No breakpoint set on r%s change"), arg); return TRUE; } else { - fprintf (dis->err, _("Invalid argument %s\n"), arg); + log_error_ (dis, _("Invalid argument %s"), arg); return FALSE; } } @@ -1110,7 +1135,7 @@ cmd_sbpm_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) gpointer key, value; if (add < 0 || add > MIX_VM_CELL_NO) { - fprintf (dis->out, _("Invalid memory address: %s\n"), arg); + log_error_ (dis, _("Invalid memory address: %s"), arg); return FALSE; } if (!g_hash_table_lookup_extended (dis->mem_preds, GINT_TO_POINTER (add), @@ -1122,7 +1147,9 @@ cmd_sbpm_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) GINT_TO_POINTER (add), (gpointer)new_pred); mix_vm_set_conditional_breakpoint (dis->vm, new_pred); } - fprintf (dis->out, _("Conditional breakpoint on mem cell no. %d set\n"), add); + if (wants_logs_ (dis)) + log_message_ (dis, _("Conditional breakpoint on mem cell no. %d set"), + add); return TRUE; } @@ -1133,7 +1160,7 @@ cmd_cbpm_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) gpointer key, value; if (add < 0 || add > MIX_VM_CELL_NO) { - fprintf (dis->out, _("Invalid memory address: %s\n"), arg); + log_error_ (dis, _("Invalid memory address: %s"), arg); return FALSE; } if (g_hash_table_lookup_extended (dis->mem_preds, GINT_TO_POINTER (add), @@ -1142,13 +1169,15 @@ cmd_cbpm_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) g_hash_table_remove (dis->mem_preds, key); mix_vm_clear_conditional_breakpoint (dis->vm, (mix_predicate_t *)value); mix_predicate_delete ((mix_predicate_t *)value); - fprintf (dis->out, - _("Conditional breakpoint on mem cell no. %d removed\n"), add); + if (wants_logs_ (dis)) + log_message_ (dis, + _("Conditional breakpoint on mem cell no. %d removed"), + add); } else { - fprintf (dis->out, _("No conditional breakpoint set at address %d\n"), - add); + log_error_ (dis, _("No conditional breakpoint set at address %d"), + add); } return TRUE; } @@ -1157,12 +1186,13 @@ gboolean cmd_sbpo_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) { if (arg && strlen (arg)) - fprintf (dis->err, _("Unexpected argument: %s\n"), arg); + log_error_ (dis, _("Unexpected argument: %s"), arg); else { mix_vm_set_conditional_breakpoint (dis->vm, dis->preds[MIX_PRED_OVER]); - fprintf (dis->out, - _("Conditional breakpoint on overflow toggled set\n")); + if (wants_logs_ (dis)) + log_message_ (dis, + _("Conditional breakpoint on overflow toggled set")); } return TRUE; } @@ -1171,15 +1201,18 @@ gboolean cmd_cbpo_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) { if (arg && strlen (arg)) - fprintf (dis->err, _("Unexpected argument: %s\n"), arg); + log_error_ (dis, _("Unexpected argument: %s"), arg); else { if (mix_vm_clear_conditional_breakpoint (dis->vm, dis->preds[MIX_PRED_OVER])) - fprintf (dis->out, - _("Conditional breakpoint on overflow toggled removed.\n")); + { + if (wants_logs_ (dis)) + log_message_ + (dis, _("Conditional breakpoint on overflow toggled removed.")); + } else - fprintf (dis->err, _("No breakpoint set on overflow toggle\n")); + log_error_ (dis, _("No breakpoint set on overflow toggle")); } return TRUE; } @@ -1188,12 +1221,13 @@ gboolean cmd_sbpc_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) { if (arg && strlen (arg)) - fprintf (dis->err, _("Unexpected argument: %s\n"), arg); + log_error_ (dis, _("Unexpected argument: %s"), arg); else { mix_vm_set_conditional_breakpoint (dis->vm, dis->preds[MIX_PRED_CMP]); - fprintf (dis->out, - _("Conditional breakpoint on comparison flag changed set.\n")); + if (wants_logs_ (dis)) + log_message_ + (dis, _("Conditional breakpoint on comparison flag changed set")); } return TRUE; } @@ -1202,16 +1236,19 @@ gboolean cmd_cbpc_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) { if (arg && strlen (arg)) - fprintf (dis->err, _("Unexpected argument: %s\n"), arg); + log_error_ (dis, _("Unexpected argument: %s"), arg); else { if (mix_vm_clear_conditional_breakpoint (dis->vm, dis->preds[MIX_PRED_CMP])) - fprintf - (dis->out, - _("Conditional breakpoint on comparison flag changed removed.\n")); + { + if (wants_logs_ (dis)) + log_message_ + (dis, + _("Conditional breakpoint on comparison flag changed removed.")); + } else - fprintf (dis->err, _("No breakpoint set on comparison flag change\n")); + log_error_ (dis, _("No breakpoint set on comparison flag change")); } return TRUE; } @@ -1246,7 +1283,70 @@ cmd_pbt_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) ++k; add = add->next; } - /* if (name) g_free (name); */ return TRUE; } +gboolean +cmd_slog_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) +{ + static const gchar *ON = "on"; + static const gchar *OFF = "off"; + if (arg && !strcmp (arg, ON)) + { + dis->log_msg = TRUE; + if (dis->config) mix_config_update (dis->config, LOGGING_KEY_, ON); + } + else if (arg && !strcmp (arg, OFF)) + { + dis->log_msg = FALSE; + if (dis->config) mix_config_update (dis->config, LOGGING_KEY_, OFF); + } + else + log_error_ (dis, _("Wrong argument: "), arg); + return TRUE; +} + +gboolean +cmd_pprog_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) +{ + const gchar *path = mix_vm_cmd_dispatcher_get_program_path (dis); + fprintf (dis->out, path? path : _("No program currently loaded\n")); + return (path != NULL); +} + +gboolean +cmd_psrc_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) +{ + const gchar *path = mix_vm_cmd_dispatcher_get_src_file_path (dis); + fprintf (dis->out, path? path : _("No program currently loaded\n")); + return (path != NULL); +} + +gboolean +cmd_pline_ (mix_vm_cmd_dispatcher_t *dis, const gchar *arg) +{ + gulong line = 0; + const gchar *txt; + + if (arg && strlen (arg)) line = atoi (arg); + + if (line < 0) + { + log_error_ (dis, _("Invalid argument")); + return FALSE; + } + + if (line == 0) + line = mix_vm_cmd_dispatcher_get_src_file_lineno (dis); + + if (line == 0) + txt = "No such line (debug info not available)\n"; + else + txt = mix_vm_cmd_dispatcher_get_src_file_line (dis, line); + + if (txt == NULL || strlen (txt) == 0) txt = "No such line\n"; + + fprintf (dis->out, "Line %ld: %s", line, txt); + + return TRUE; +} diff --git a/mixlib/xmix_vm_handlers.h b/mixlib/xmix_vm_handlers.h index 3b80898..df5a50f 100644 --- a/mixlib/xmix_vm_handlers.h +++ b/mixlib/xmix_vm_handlers.h @@ -53,15 +53,17 @@ DEC_FUN (cbpa_); DEC_FUN (cabp_); DEC_FUN (weval_); DEC_FUN (w2d_); -DEC_FUN (tracing_); -DEC_FUN (timing_); +DEC_FUN (strace_); +DEC_FUN (stime_); +DEC_FUN (ptime_); DEC_FUN (edit_); DEC_FUN (compile_); DEC_FUN (pedit_); DEC_FUN (sedit_); DEC_FUN (pasm_); DEC_FUN (sasm_); -DEC_FUN (devdir_); +DEC_FUN (pddir_); +DEC_FUN (sddir_); DEC_FUN (sbpr_); DEC_FUN (sbpm_); DEC_FUN (sbpc_); @@ -71,6 +73,10 @@ DEC_FUN (cbpm_); DEC_FUN (cbpc_); DEC_FUN (cbpo_); DEC_FUN (pbt_); +DEC_FUN (slog_); +DEC_FUN (pprog_); +DEC_FUN (psrc_); +DEC_FUN (pline_); /* default command structure */ extern mix_vm_command_info_t commands_[]; |