- clean up the command line argument parsing. Before, we had two slightly

different versions of the code for wxWindows and non-wxWindows and the GDB
  stub did not accept any command line options at all.
- IMPORTANT CHANGE: the quick start option used to cause two things:
  1) read the bochsrc immediately, 2) start simulation immediately without
  going into the config interface.  This has changed in a subtle way.
  Now, we always try to read the bochsrc immediately.  Then if the quick
  start option is on, we start the simulation immediately.
- add "Restore Factory Default Configuration" in text config menu.  It was
  already there in wx.  Now the default choice is always "5. Begin simulation"
  and because the bochsrc is always read now, this works.
- When the user chooses "Read configuration file" from either text mode
  or wx interfaces, reset all bochs parameters first, then read in the
  new file.  This means that every time you read a configuration file
  you are starting from a consistent "blank slate".
- move much of the code from bx_do_text_config_interface into bx_init_main
  so that wxWindows and non-wxWindows code uses the same logic.  There was
  only a tiny bit left in bx_do_text_config_interface so I eliminated it.
- move the "help" message into a separate function print_usage()
- detect all flags (cmdline args that start with -) in a loop, instead of
  a big if/else.  This makes it easy to add others.
- fix problem with Carbon gui, so that -psn arg gets ignored
- print usage if you type -h, --help, or if flags are not recognized
- code that called io->set_log_action (that sets the log action for all
  devices) was only called if the configuration interface was on; I'm not
  sure why.  Now it is called all the time.
- the wxWindows equivalent of main() is called MyApp::OnInit.  Now OnInit
  and main() are very similar.  They both call bx_init_siminterface, then
  bx_init_main (and quit if it fails), then show the config interface if
  quickstart is off, and then simulate.
- modified: main.cc gui/control.cc gui/wxmain.cc
This commit is contained in:
Bryce Denney 2002-10-14 13:37:20 +00:00
parent bb9fd8ae22
commit d1196d1996
3 changed files with 150 additions and 177 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: control.cc,v 1.64 2002-10-06 02:37:27 bdenney Exp $
// $Id: control.cc,v 1.65 2002-10-14 13:37:18 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// This is code for a text-mode configuration interfac. Note that this file
@ -229,25 +229,19 @@ static char *startup_menu_prompt =
"------------------------------\n"
"\n"
"This is the Bochs Configuration Interface, where you can describe the\n"
"machine that you want to simulate. The first choice, \"Read options\n"
"from...\", lets you read in a saved machine configuration from a file.\n"
"The second choice lets you edit the present configuration. The\n"
"third choice saves the current configuration to a file so that you\n"
"can use it again next time. When you are satisfied with the config-\n"
"uration, go ahead and start the simulation.\n"
"\n"
"Most people will want to read options from a file called .bochsrc,\n"
"then immediately start the simulation. A quick way to do this is to\n"
"press return three times to accept the default choices (shown in\n"
"square brackets).\n"
"machine that you want to simulate. Bochs has already searched for a\n"
"configuration file (typically called bochsrc.txt) and loaded it if it\n"
"could be found. When you are satisfied with the configuration, go\n"
"ahead and start the simulation.\n"
"\n"
"You can also start bochs with the -q option to skip these menus.\n"
"\n"
"1. Read options from...\n"
"2. Edit options\n"
"3. Save options to...\n"
"4. Begin simulation\n"
"5. Quit now\n"
"1. Restore factory default configuration\n"
"2. Read options from...\n"
"3. Edit options\n"
"4. Save options to...\n"
"5. Begin simulation\n"
"6. Quit now\n"
"\n"
"Please choose one: [%d] ";
@ -412,15 +406,23 @@ int bx_config_interface (int menu)
case BX_CI_START_MENU:
{
static int read_rc = 0;
Bit32u default_choice = 1;
default_choice = read_rc ? 4 : 1;
if (ask_uint (startup_menu_prompt, 1, 5, default_choice, &choice, 10) < 0) return -1;
Bit32u default_choice = 5;
if (ask_uint (startup_menu_prompt, 1, 6, default_choice, &choice, 10) < 0) return -1;
switch (choice) {
case 1: if (bx_read_rc (NULL) >= 0) read_rc=1; break;
case 2: bx_config_interface (BX_CI_START_OPTS); break;
case 3: bx_write_rc (NULL); break;
case 4: return 0; // return from menu
case 5: SIM->quit_sim (1); return -1;
case 1:
SIM->reset_all_param ();
break;
case 2:
// Before reading a new configuration, reset every option to its
// original state.
SIM->reset_all_param ();
if (bx_read_rc (NULL) >= 0)
read_rc=1;
break;
case 3: bx_config_interface (BX_CI_START_OPTS); break;
case 4: bx_write_rc (NULL); break;
case 5: return 0; // return from menu
case 6: SIM->quit_sim (1); return -1;
default: BAD_OPTION(menu, choice);
}
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////
// $Id: wxmain.cc,v 1.68 2002-10-10 15:44:34 bdenney Exp $
// $Id: wxmain.cc,v 1.69 2002-10-14 13:37:20 bdenney Exp $
/////////////////////////////////////////////////////////////////
//
// wxmain.cc implements the wxWindows frame, toolbar, menus, and dialogs.
@ -155,13 +155,22 @@ bool MyApp::OnInit()
//wxLog::AddTraceMask (_T("mime"));
wxLog::SetActiveTarget (new wxLogStderr ());
bx_init_siminterface ();
// install callback function to handle anything that occurs before the
// simulation begins.
// Install callback function to handle anything that occurs before the
// simulation begins. This is responsible for displaying any error
// dialogs during bochsrc and command line processing.
SIM->set_notify_callback (&MyApp::DefaultCallback, this);
if (bx_init_main (argc, argv) < 0) {
// init failed. Don't even start the interface.
static jmp_buf context;
if (setjmp (context) == 0) {
SIM->set_quit_context (&context);
if (bx_init_main (argc, argv) < 0) {
// init failed. Don't even start the interface.
return FALSE;
}
} else {
// quit unexpectedly via longjmp
return FALSE;
}
SIM->set_quit_context (NULL);
MyFrame *frame = new MyFrame( "Bochs x86 Emulator", wxPoint(50,50), wxSize(450,340), wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION );
theFrame = frame; // hack alert
frame->Show( TRUE );

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: main.cc,v 1.158 2002-10-06 19:21:05 bdenney Exp $
// $Id: main.cc,v 1.159 2002-10-14 13:37:17 bdenney Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -43,7 +43,6 @@
#endif
#endif
int enable_config_interface = 1;
int bochsrc_include_count = 0;
extern "C" {
@ -83,12 +82,13 @@ class state_file state_stuff("state_file.out", "options");
bx_debug_t bx_dbg;
bx_options_t bx_options; // initialized in bx_init_options()
char *bochsrc_filename = NULL;
static Bit32s parse_line_unformatted(char *context, char *line);
static Bit32s parse_line_formatted(char *context, int num_params, char *params[]);
static int parse_bochsrc(char *rcfile);
#if !BX_WITH_WX
static void bx_do_text_config_interface (int argc, char *argv[]);
static void bx_do_text_config_interface (int first_arg, int argc, char *argv[]);
#endif
static Bit32s
@ -1340,8 +1340,11 @@ int main (int argc, char *argv[])
if (setjmp (context) == 0) {
SIM->set_quit_context (&context);
if (bx_init_main (argc, argv) < 0) return 0;
bx_do_text_config_interface (argc, argv);
bx_config_interface (BX_CI_INIT);
if (! SIM->get_param_bool(BXP_QUICK_START)->get ()) {
// Display the pre-simulation configuration interface.
bx_config_interface (BX_CI_START_MENU);
}
bx_continue_after_config_interface (argc, argv);
// function returned normally
} else {
@ -1352,15 +1355,26 @@ int main (int argc, char *argv[])
}
#endif
void
print_usage ()
{
fprintf(stderr,
"Usage: bochs [flags] [bochsrc options]\n\n"
" -q quickstart with default configuration file\n"
" -f configfile specify configuration file\n"
" -qf configfile quickstart with specified configuration file\n"
" --help display this help and exit\n\n"
"For information on Bochs configuration file arguments, see the\n"
#if (!defined(WIN32)) && !BX_WITH_MACOS
"bochsrc section in the user documentation or the man page of bochsrc.\n");
#else
"bochsrc section in the user documentation.\n");
#endif
}
int
bx_init_main (int argc, char *argv[])
{
int help = 0;
#if BX_WITH_WX
int arg = 1;
char *bochsrc = NULL;
#endif
// To deal with initialization order problems inherent in C++, use the macros
// SAFE_GET_IOFUNC and SAFE_GET_GENLOG to retrieve "io" and "genlog" in all
// constructors or functions called by constructors. The macros test for
@ -1372,144 +1386,89 @@ bx_init_main (int argc, char *argv[])
SAFE_GET_IOFUNC(); // never freed
SAFE_GET_GENLOG(); // never freed
if ((argc > 1) && (!strcmp ("--help", argv[1]))) {
fprintf(stderr, "Usage: bochs [options] [bochsrc options]\n\n"
" -q quickstart with default configuration file\n"
" -qf configfile quickstart with specified configuration file\n"
" --help display this help and exit\n\n"
"For information on Bochs configuration file arguments, see the\n"
#if (!defined(WIN32)) && !BX_WITH_MACOS
"bochsrc section in the user documentation or the man page of bochsrc.\n");
#else
"bochsrc section in the user documentation.\n");
#endif
help = 1;
} else {
#if !BX_WITH_WX
bx_print_header ();
#endif
}
// initalization must be done early because some destructors expect
// the bx_options to exist by the time they are called.
bx_init_bx_dbg ();
bx_init_options ();
if (help) exit(0);
if (!BX_WITH_WX) bx_print_header ();
#if !BX_USE_CONFIG_INTERFACE
// this allows people to get quick start behavior by default
SIM->get_param_bool(BXP_QUICK_START)->set (1);
#endif
// interpret the args that start with -, like -q, -f, etc.
int arg = 1;
while (arg < argc) {
// parse next arg
if (!strcmp ("--help", argv[arg]) || !strncmp ("-h", argv[arg], 2)) {
print_usage();
SIM->quit_sim (0);
}
else if (!strcmp ("-q", argv[arg])) {
SIM->get_param_bool(BXP_QUICK_START)->set (1);
}
else if (!strcmp ("-f", argv[arg])) {
if (++arg >= argc) BX_PANIC(("-f must be followed by a filename"));
else bochsrc_filename = argv[arg];
}
else if (!strcmp ("-qf", argv[arg])) {
SIM->get_param_bool(BXP_QUICK_START)->set (1);
if (++arg >= argc) BX_PANIC(("-qf must be followed by a filename"));
else bochsrc_filename = argv[arg];
}
#if BX_WITH_CARBON
/* "-psn" is passed if we are launched by double-clicking */
if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
// ugly hack. I don't know how to open a window to print messages in,
// so put them in /tmp/early-bochs-out.txt. Sorry. -bbd
io->init_log("/tmp/early-bochs-out.txt");
BX_INFO (("I was launched by double clicking. Fixing home directory."));
argc = 1; // ignore all other args.
setupWorkingDirectory (argv[0]);
// there is no stdin/stdout so disable the text-based config interface.
enable_config_interface = 0;
}
// if it was started from command line, there could be some args still.
for (int a=0; a<argc; a++) {
BX_INFO (("argument %d is %s", a, argv[a]));
}
char cwd[MAXPATHLEN];
getwd (cwd);
BX_INFO (("Now my working directory is %s", cwd));
else if (!strncmp ("-psn", argv[arg], 4)) {
// "-psn" is passed if we are launched by double-clicking
// ugly hack. I don't know how to open a window to print messages in,
// so put them in /tmp/early-bochs-out.txt. Sorry. -bbd
io->init_log("/tmp/early-bochs-out.txt");
BX_INFO (("I was launched by double clicking. Fixing home directory."));
arg = argc; // ignore all other args.
setupWorkingDirectory (argv[0]);
// there is no stdin/stdout so disable the text-based config interface.
SIM->get_param_bool(BXP_QUICK_START)->set (1);
char cwd[MAXPATHLEN];
getwd (cwd);
BX_INFO (("Now my working directory is %s", cwd));
// if it was started from command line, there could be some args still.
for (int a=0; a<argc; a++) {
BX_INFO (("argument %d is %s", a, argv[a]));
}
}
#endif
#if BX_WITH_WX
// detect -q or -qf
if ((argc > 1) && (!strncmp ("-q", argv[1], 2))) {
SIM->get_param_bool(BXP_QUICK_START)->set (1); // used in wxmain.cc
else if (argv[arg][0] == '-') {
print_usage();
BX_PANIC (("command line arg '%s' was not understood", argv[arg]));
}
else {
// the arg did not start with -, so stop interpreting flags
break;
}
arg++;
if ((argc > 2) && (!strcmp(argv[1], "-qf"))) {
bochsrc = argv[arg];
arg++;
}
else if ((argc > 3) && (!strcmp ("-f", argv[arg]))) {
bochsrc = argv[arg+1];
arg += 2;
}
if (bochsrc == NULL) bochsrc = bx_find_bochsrc ();
if (bochsrc) {
if (bx_read_configuration (bochsrc) < 0)
return -1; // read config failed
}
}
// parse cmdline after bochsrc so that it can override things
bx_parse_cmdline (arg, argc, argv);
#endif
int norcfile = 1;
/* always parse configuration file and command line arguments */
if (bochsrc_filename == NULL) bochsrc_filename = bx_find_bochsrc ();
if (bochsrc_filename)
norcfile = bx_read_configuration (bochsrc_filename);
if (norcfile) {
// No configuration was loaded, so the current settings are unusable.
// Switch off quick start so that we will drop into the configuration
// interface.
SIM->get_param_bool(BXP_QUICK_START)->set (0);
}
// parse the rest of the command line. This is done after reading the
// configuration file so that the command line arguments can override
// the settings from the file.
if (bx_parse_cmdline (arg, argc, argv)) {
BX_PANIC(("There were errors while parsing the command line"));
return -1;
}
return 0;
}
#if !BX_WITH_WX
static void
bx_do_text_config_interface (int argc, char *argv[])
{
char *bochsrc = NULL;
int norcfile = 1;
// detect -q, -qf argument before anything else
int arg = 1;
if ((argc > 1) && !strncmp ("-q", argv[1], 2)) {
// skip the configuration interface
arg++;
enable_config_interface = 0;
if ((argc > 2) && (!strcmp(argv[1], "-qf"))) {
bochsrc = argv[arg];
arg++;
}
else if ((argc > 3) && (!strcmp ("-f", argv[arg]))) {
bochsrc = argv[arg+1];
arg += 2;
}
}
#if !BX_USE_CONFIG_INTERFACE
enable_config_interface = 0;
#endif
if (!enable_config_interface || BX_WITH_WX) {
/* parse configuration file and command line arguments */
if (bochsrc == NULL) bochsrc = bx_find_bochsrc ();
if (bochsrc)
norcfile = bx_read_configuration (bochsrc);
if (norcfile && arg>=argc) {
// no bochsrc used. This is legal since they may have everything on the
// command line. However if they have no arguments then give them some
// friendly advice.
fprintf (stderr, "%s\n", divider);
fprintf (stderr, "Before running Bochs, you should cd to a directory which contains\n");
fprintf (stderr, "a .bochsrc file and a disk image. If you downloaded a binary package,\n");
fprintf (stderr, "all the necessary files are already on your disk.\n");
#if defined(WIN32)
fprintf (stderr, "\nFor Windows installations, go to the dlxlinux direectory and\n");
fprintf (stderr, "double-click on the start.bat script.\n");
#elif !defined(macintosh)
fprintf (stderr, "\nFor UNIX installations, try running \"bochs-dlx\" for a demo. This script\n");
fprintf (stderr, "is basically equivalent to typing:\n");
fprintf (stderr, " cd /usr/share/bochs/dlxlinux\n");
fprintf (stderr, " bochs\n");
#endif
BX_EXIT(1);
}
}
// parse the rest of the command line.
if (bx_parse_cmdline (arg, argc, argv)) {
fprintf (stderr, "There were errors while parsing the command line.\n");
fprintf (stderr, "Bochs is exiting.\n");
exit (1);
}
if (enable_config_interface) {
// update log actions before starting configuration interface
for (int level=0; level<N_LOGLEV; level++) {
int action = SIM->get_default_log_action (level);
io->set_log_action (level, action);
}
// Display the pre-simulation configuration interface.
bx_config_interface (BX_CI_START_MENU);
}
}
#endif
int
bx_continue_after_config_interface (int argc, char *argv[])
{
@ -1571,15 +1530,13 @@ bx_read_configuration (char *rcfile)
// parse rcfile first, then parse arguments in order.
BX_INFO (("reading configuration from %s", rcfile));
if (parse_bochsrc(rcfile) < 0) {
BX_ERROR (("reading from %s failed", rcfile));
BX_PANIC (("reading from %s failed", rcfile));
return -1;
}
// update log actions if configuration interface is enabled
if (enable_config_interface) {
for (int level=0; level<N_LOGLEV; level++) {
int action = SIM->get_default_log_action (level);
io->set_log_action (level, action);
}
// update log actions
for (int level=0; level<N_LOGLEV; level++) {
int action = SIM->get_default_log_action (level);
io->set_log_action (level, action);
}
return 0;
}
@ -1593,6 +1550,11 @@ int bx_parse_cmdline (int arg, int argc, char *argv[])
parse_line_unformatted("cmdline args", argv[arg]);
arg++;
}
// update log actions
for (int level=0; level<N_LOGLEV; level++) {
int action = SIM->get_default_log_action (level);
io->set_log_action (level, action);
}
return 0;
}
@ -1601,7 +1563,7 @@ bx_init_hardware()
{
// all configuration has been read, now initialize everything.
if (!enable_config_interface) {
if (SIM->get_param_bool(BXP_QUICK_START)->get ()) {
for (int level=0; level<N_LOGLEV; level++) {
int action = SIM->get_default_log_action (level);
#if !BX_USE_CONFIG_INTERFACE