From a56dedb386dbdb8098650f425149df9c32df4271 Mon Sep 17 00:00:00 2001 From: Bryce Denney Date: Mon, 11 Jun 2001 14:03:35 +0000 Subject: [PATCH] - added a new log action "ask" which sends the log message to the control panel. It gives the user the option of continue this time, continue and never ask again for this type of log message, or die. - the communication between control.cc and siminterface.cc is still somewhat crude. I'm trying to implement it so that a network protocol based on this interface will be simple. I'll get this cleaned up soon. --- bochs/bochs.h | 12 ++++--- bochs/gui/control.cc | 50 +++++++++++++++++++++++++++- bochs/gui/siminterface.cc | 70 ++++++++++++++++++++++++++++++++++++++- bochs/gui/siminterface.h | 11 +++++- bochs/main.cc | 52 ++++++++++++++++++++++++++--- 5 files changed, 182 insertions(+), 13 deletions(-) diff --git a/bochs/bochs.h b/bochs/bochs.h index 7c393eaf2..c7893a05c 100644 --- a/bochs/bochs.h +++ b/bochs/bochs.h @@ -245,8 +245,9 @@ typedef class logfunctions { // values of onoff: 0=ignore, 1=report, 2=fatal #define ACT_IGNORE 0 #define ACT_REPORT 1 -#define ACT_FATAL 2 -#define N_ACT 3 +#define ACT_ASK 2 +#define ACT_FATAL 3 +#define N_ACT 4 int onoff[N_LOGLEV]; class iofunctions *logio; public: @@ -259,6 +260,7 @@ public: void panic(char *fmt, ...); void ldebug(char *fmt, ...); void fatal (char *prefix, char *fmt, va_list ap); + void ask (int level, char *prefix, char *fmt, va_list ap); void setprefix(char *); void settype(int); void setio(class iofunctions *); @@ -398,8 +400,8 @@ public: return loglevel[i]; } char *getaction(int i) { - static char *name[] = { "ignore", "report", "fatal" }; - assert (i>=ACT_IGNORE && i<=ACT_FATAL); + static char *name[] = { "ignore", "report", "ask", "fatal" }; + assert (i>=ACT_IGNORE && ilog_msg_2 (prefix, &level, msg, sizeof(msg)) >= 0); + fprintf (stderr, "========================================================================\n"); + fprintf (stderr, "Event type: %s\n", SIM->get_log_level_name (level)); + fprintf (stderr, "Device: %s\n", prefix); + fprintf (stderr, "Message: %s\n\n", msg); + fprintf (stderr, "A panic has occurred. Do you want to:\n"); + fprintf (stderr, " cont - continue execution\n"); + fprintf (stderr, " alwayscont - continue execution, and don't ask again.\n"); + fprintf (stderr, " This affects only %s events from device %s\n", SIM->get_log_level_name (level), prefix); + fprintf (stderr, " die - stop execution now\n"); + int choice; + if (ask_menu ("Choose cont, alwayscont, or die. [%s] ", 3, + log_action_ask_choices, 2, &choice) < 0) + return SIM->notify_return(-1); + // return 0 for continue, 1 for alwayscontinue, 2 for die. + SIM->notify_return(choice); + } + break; + default: + fprintf (stderr, "Control panel: notify callback called with unknown code %04x\n", code); + } +} + +void bx_control_panel_init () { + //fprintf (stderr, "bx_control_panel_init()\n"); + SIM->set_notify_callback (control_panel_notify_callback); +} + #endif diff --git a/bochs/gui/siminterface.cc b/bochs/gui/siminterface.cc index 21ef41f3f..7b923609e 100644 --- a/bochs/gui/siminterface.cc +++ b/bochs/gui/siminterface.cc @@ -1,6 +1,6 @@ /* * gui/siminterface.cc - * $Id: siminterface.cc,v 1.9 2001-06-11 06:48:37 bdenney Exp $ + * $Id: siminterface.cc,v 1.10 2001-06-11 14:03:35 bdenney Exp $ * * Defines the actual link between bx_simulator_interface_c methods * and the simulator. This file includes bochs.h because it needs @@ -17,6 +17,14 @@ logfunctions *siminterface_log = NULL; #define LOG_THIS siminterface_log-> class bx_real_sim_c : public bx_simulator_interface_c { + sim_interface_callback_t callback; + int notify_return_val; + int notify_int_args[10]; + char *notify_string_args[10]; +#define NOTIFY_TYPE_INT +#define NOTIFY_TYPE_STRING +public: + bx_real_sim_c (); virtual int getips (); virtual void setips (int ips); virtual int get_vga_update_interval (); @@ -57,6 +65,11 @@ class bx_real_sim_c : public bx_simulator_interface_c { virtual int set_rom_address (int addr); virtual int get_private_colormap (); virtual void set_private_colormap (int en); + virtual void set_notify_callback (sim_interface_callback_t func); + virtual int notify_return (int retcode); + virtual int LOCAL_notify (int code); + virtual int LOCAL_log_msg (char *prefix, int level, char *msg); + virtual int log_msg_2 (char *prefix, int *level, char *msg, int len); }; void init_siminterface () @@ -73,6 +86,11 @@ bx_simulator_interface_c::bx_simulator_interface_c () init_done = 0; } +bx_real_sim_c::bx_real_sim_c () +{ + callback = NULL; +} + int bx_real_sim_c::getips () { @@ -364,4 +382,54 @@ bx_real_sim_c::set_private_colormap (int en) bx_options.private_colormap = en; } +void +bx_real_sim_c::set_notify_callback (sim_interface_callback_t func) +{ + callback = func; +} + +int +bx_real_sim_c::notify_return (int retcode) +{ + notify_return_val = retcode; + return 0; +} + +int +bx_real_sim_c::LOCAL_notify (int code) +{ + if (callback == NULL) + BX_ERROR (("notify called, but no callback function is registered")); + else { + notify_return_val = -999; + (*callback)(code); + if (notify_return_val == -999) + BX_ERROR (("notify callback returned without setting the return value")); + return notify_return_val; + } +} + +// returns 0 for continue, 1 for alwayscontinue, 2 for die. +int +bx_real_sim_c::LOCAL_log_msg (char *prefix, int level, char *msg) +{ + //fprintf (stderr, "calling notify.\n"); + notify_string_args[0] = prefix; + notify_int_args[1] = level; + notify_string_args[2] = msg; + int val = LOCAL_notify (NOTIFY_CODE_LOGMSG); + //fprintf (stderr, "notify returned %d\n", val); + return val; +} + +// called by control.cc +int +bx_real_sim_c::log_msg_2 (char *prefix, int *level, char *msg, int len) +{ + strncpy (prefix, notify_string_args[0], len); + *level= notify_int_args[1]; + strncpy (msg, notify_string_args[2], len); + return 0; +} + #endif // if BX_USE_CONTROL_PANEL==1 diff --git a/bochs/gui/siminterface.h b/bochs/gui/siminterface.h index 758c2c985..9fc7a6def 100644 --- a/bochs/gui/siminterface.h +++ b/bochs/gui/siminterface.h @@ -1,6 +1,6 @@ /* * gui/siminterface.h - * $Id: siminterface.h,v 1.5 2001-06-11 06:35:18 bdenney Exp $ + * $Id: siminterface.h,v 1.6 2001-06-11 14:03:35 bdenney Exp $ * * Interface to the simulator, currently only used by control.cc. * The base class bx_simulator_interface_c, contains only virtual functions @@ -98,6 +98,15 @@ public: virtual int set_rom_address (int addr) {return -1;} virtual int get_private_colormap () { return -1; } virtual void set_private_colormap (int en) {} + typedef int (*sim_interface_callback_t)(int code); + virtual void set_notify_callback (sim_interface_callback_t func) {} + virtual int notify_return (int retcode) {return -1;} + // methods marked LOCAL should only be called by the simulator, not + // from the control panel. +#define NOTIFY_CODE_LOGMSG 0x101 + virtual int LOCAL_notify (int code) {} + virtual int LOCAL_log_msg (char *prefix, int level, char *msg) {return -1;} + virtual int log_msg_2 (char *prefix, int *level, char *msg, int len) {return -1;} }; extern bx_simulator_interface_c *SIM; diff --git a/bochs/main.cc b/bochs/main.cc index ab997908b..96735f81c 100644 --- a/bochs/main.cc +++ b/bochs/main.cc @@ -84,7 +84,7 @@ bx_options_t bx_options = { 1, // newHardDriveSupport { 0, NULL, NULL, NULL }, // load32bitOSImage hack stuff // log options: ignore debug, report info and error, crash on panic. - { "-", { ACT_IGNORE, ACT_REPORT, ACT_REPORT, ACT_FATAL } }, + { "-", { ACT_IGNORE, ACT_REPORT, ACT_REPORT, ACT_ASK } }, }; static void parse_line_unformatted(char *context, char *line); @@ -309,7 +309,10 @@ logfunctions::info(char *fmt, ...) va_start(ap, fmt); this->logio->out(this->type,LOGLEV_INFO,this->prefix, fmt, ap); - if (onoff[LOGLEV_INFO] == ACT_FATAL) fatal (this->prefix, fmt, ap); + if (onoff[LOGLEV_INFO] == ACT_ASK) + ask (LOGLEV_INFO, this->prefix, fmt, ap); + if (onoff[LOGLEV_INFO] == ACT_FATAL) + fatal (this->prefix, fmt, ap); va_end(ap); } @@ -327,7 +330,10 @@ logfunctions::error(char *fmt, ...) va_start(ap, fmt); this->logio->out(this->type,LOGLEV_ERROR,this->prefix, fmt, ap); - if (onoff[LOGLEV_ERROR] == ACT_FATAL) fatal (this->prefix, fmt, ap); + if (onoff[LOGLEV_ERROR] == ACT_ASK) + ask (LOGLEV_ERROR, this->prefix, fmt, ap); + if (onoff[LOGLEV_ERROR] == ACT_FATAL) + fatal (this->prefix, fmt, ap); va_end(ap); } @@ -344,7 +350,10 @@ logfunctions::panic(char *fmt, ...) va_start(ap, fmt); this->logio->out(this->type,LOGLEV_PANIC,this->prefix, fmt, ap); - if (onoff[LOGLEV_PANIC] == ACT_FATAL) fatal (this->prefix, fmt, ap); + if (onoff[LOGLEV_PANIC] == ACT_ASK) + ask (LOGLEV_PANIC, this->prefix, fmt, ap); + if (onoff[LOGLEV_PANIC] == ACT_FATAL) + fatal (this->prefix, fmt, ap); va_end(ap); } @@ -361,10 +370,35 @@ logfunctions::ldebug(char *fmt, ...) va_start(ap, fmt); this->logio->out(this->type,LOGLEV_DEBUG,this->prefix, fmt, ap); - if (onoff[LOGLEV_DEBUG] == ACT_FATAL) fatal (this->prefix, fmt, ap); + if (onoff[LOGLEV_DEBUG] == ACT_ASK) + ask (LOGLEV_DEBUG, this->prefix, fmt, ap); + if (onoff[LOGLEV_DEBUG] == ACT_FATAL) + fatal (this->prefix, fmt, ap); va_end(ap); } +void +logfunctions::ask (int level, char *prefix, char *fmt, va_list ap) +{ +#if BX_USE_CONTROL_PANEL + char buf1[1024], buf2[1024]; + vsprintf (buf1, fmt, ap); + sprintf (buf2, "%s %s", prefix, buf1); + // FIXME: facility set to 0 because it's unknown. + int val = SIM->LOCAL_log_msg (prefix, level, buf2); + switch (val) + { + case 0: // user chose continue + break; + case 1: // user said continue, and don't ask for this facility again. + setonoff (level, ACT_REPORT); + break; + case 2: // user chose die + fatal (prefix, fmt, ap); + } +#endif +} + void logfunctions::fatal (char *prefix, char *fmt, va_list ap) { @@ -922,6 +956,8 @@ parse_line_formatted(char *context, int num_params, char *params[]) bx_options.log.actions[LOGLEV_PANIC] = ACT_REPORT; else if (!strcmp (action, "ignore")) bx_options.log.actions[LOGLEV_PANIC] = ACT_IGNORE; + else if (!strcmp (action, "ask")) + bx_options.log.actions[LOGLEV_PANIC] = ACT_ASK; else { BX_PANIC(("%s: panic directive malformed.", context)); } @@ -940,6 +976,8 @@ parse_line_formatted(char *context, int num_params, char *params[]) bx_options.log.actions[LOGLEV_ERROR] = ACT_REPORT; else if (!strcmp (action, "ignore")) bx_options.log.actions[LOGLEV_ERROR] = ACT_IGNORE; + else if (!strcmp (action, "ask")) + bx_options.log.actions[LOGLEV_PANIC] = ACT_ASK; else { BX_PANIC(("%s: error directive malformed.", context)); } @@ -958,6 +996,8 @@ parse_line_formatted(char *context, int num_params, char *params[]) bx_options.log.actions[LOGLEV_INFO] = ACT_REPORT; else if (!strcmp (action, "ignore")) bx_options.log.actions[LOGLEV_INFO] = ACT_IGNORE; + else if (!strcmp (action, "ask")) + bx_options.log.actions[LOGLEV_PANIC] = ACT_ASK; else { BX_PANIC(("%s: info directive malformed.", context)); } @@ -976,6 +1016,8 @@ parse_line_formatted(char *context, int num_params, char *params[]) bx_options.log.actions[LOGLEV_DEBUG] = ACT_REPORT; else if (!strcmp (action, "ignore")) bx_options.log.actions[LOGLEV_DEBUG] = ACT_IGNORE; + else if (!strcmp (action, "ask")) + bx_options.log.actions[LOGLEV_PANIC] = ACT_ASK; else { BX_PANIC(("%s: debug directive malformed.", context)); }