- 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:
parent
a97df5a8fa
commit
a56dedb386
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user