- 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.
This commit is contained in:
Bryce Denney 2001-06-11 14:03:35 +00:00
parent a97df5a8fa
commit a56dedb386
5 changed files with 182 additions and 13 deletions

View File

@ -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 && i<N_ACT);
return name[i];
}
@ -637,7 +639,7 @@ typedef struct {
typedef struct {
char filename[BX_PATHNAME_LEN];
// one array item for each log level, indexed by LOGLEV_*.
// values: ACT_IGNORE, ACT_REPORT, ACT_FATAL
// values: ACT_IGNORE, ACT_REPORT, ACT_ASK, ACT_FATAL
unsigned char actions[N_LOGLEV];
} bx_log_options;

View File

@ -1,6 +1,6 @@
/*
* gui/control.cc
* $Id: control.cc,v 1.10 2001-06-11 06:48:37 bdenney Exp $
* $Id: control.cc,v 1.11 2001-06-11 14:03:35 bdenney Exp $
*
* This is code for a text-mode control panel. Note that this file
* does NOT include bochs.h. Instead, it does all of its contact with
@ -75,6 +75,7 @@ extern "C" {
#define CPANEL_PATH_LEN 512
/* functions for changing particular options */
void bx_control_panel_init ();
void bx_edit_mem ();
void bx_edit_rom_addr ();
void bx_edit_floppy (int drive);
@ -406,6 +407,7 @@ int bx_control_panel (int menu)
switch (menu)
{
case BX_CPANEL_START_MAIN:
bx_control_panel_init ();
{
if (ask_yn (ask_about_control_panel, 1, &choice) < 0) return -1;
if (choice == 0) return BX_DISABLE_CONTROL_PANEL;
@ -813,5 +815,51 @@ void bx_edit_rom_addr ()
}
}
/*
A panic has occurred. Do you want to:
cont - continue execution
alwayscont - continue execution, and do not ask again
die - stop execution now
*/
char *log_action_ask_choices[] = { "cont", "alwayscont", "die" };
int log_action_n_choices = 3;
int control_panel_notify_callback (int code)
{
switch (code)
{
case NOTIFY_CODE_LOGMSG:
{
int level;
char prefix[512], msg[512];
assert (SIM->log_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

View File

@ -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

View File

@ -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;

View File

@ -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));
}