X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fmain.c;h=eb058bb1a27183d0839521e58c5e2d4fe7a97358;hb=abd8680d6efd97e7ba848a6392ee3ad72be18cd0;hp=7ca3ecc7387ca60432384a1300ce9ab79b0fad9e;hpb=d4f3574e777abfa65c9ba134e582228f3f32a8d6;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/main.c b/gdb/main.c index 7ca3ecc738..eb058bb1a2 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -1,6 +1,5 @@ /* Top level stuff for GDB, the GNU debugger. - Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 1999 - Free Software Foundation, Inc. + Copyright 1986-1995, 1999-2000 Free Software Foundation, Inc. This file is part of GDB. @@ -33,6 +32,12 @@ #include "gdb_string.h" #include "event-loop.h" +#include "ui-out.h" +#if defined (TUI) || defined (GDBTK) +/* FIXME: cagney/2000-01-31: This #include is to allow older code such + as that found in the TUI to continue to build. */ +#include "tui/tui-file.h" +#endif /* If nonzero, display time usage both at startup and for each command. */ @@ -46,7 +51,7 @@ int display_space; invoked on the command line with the -nw --async options. In this version, the usual command_loop is substituted by and event loop which processes UI events asynchronously. */ -int async_p = 1; +int event_loop_p = 1; /* Whether this is the command line version or not */ int tui_version = 0; @@ -57,15 +62,19 @@ int xdb_commands = 0; /* Whether dbx commands will be handled */ int dbx_commands = 0; -GDB_FILE *gdb_stdout; -GDB_FILE *gdb_stderr; -GDB_FILE *gdb_stdlog; -GDB_FILE *gdb_stdtarg; +struct ui_file *gdb_stdout; +struct ui_file *gdb_stderr; +struct ui_file *gdb_stdlog; +struct ui_file *gdb_stdtarg; + +/* Used to initialize error() - defined in utils.c */ + +extern void error_init (void); /* Whether to enable writing into executable and core files */ extern int write_files; -static void print_gdb_help PARAMS ((GDB_FILE *)); +static void print_gdb_help (struct ui_file *); /* These two are used to set the external editor commands when gdb is farming out files to be edited by another program. */ @@ -78,11 +87,44 @@ extern char *external_editor_command; #include /* for cygwin32_conv_to_posix_path */ #endif -int -main (argc, argv) - int argc; - char **argv; +/* Call command_loop. If it happens to return, pass that through as a + non-zero return status. */ + +static int +captured_command_loop (void *data) { + if (command_loop_hook == NULL) + command_loop (); + else + command_loop_hook (); + /* FIXME: cagney/1999-11-05: A correct command_loop() implementaton + would clean things up (restoring the cleanup chain) to the state + they were just prior to the call. Technically, this means that + the do_cleanups() below is redundant. Unfortunatly, many FUNC's + are not that well behaved. do_cleanups should either be replaced + with a do_cleanups call (to cover the problem) or an assertion + check to detect bad FUNCs code. */ + do_cleanups (ALL_CLEANUPS); + /* If the command_loop returned, normally (rather than threw an + error) we try to quit. If the quit is aborted, catch_errors() + which called this catch the signal and restart the command + loop. */ + quit_command (NULL, instream == stdin); + return 1; +} + +struct captured_main_args + { + int argc; + char **argv; + }; + +static int +captured_main (void *data) +{ + struct captured_main_args *context = data; + int argc = context->argc; + char **argv = context->argv; int count; static int quiet = 0; static int batch = 0; @@ -135,12 +177,6 @@ main (argc, argv) alloca (4 - i); #endif - /* If error() is called from initialization code, just exit */ - if (SET_TOP_LEVEL ()) - { - exit (1); - } - cmdsize = 1; cmdarg = (char **) xmalloc (cmdsize * sizeof (*cmdarg)); ncmd = 0; @@ -156,19 +192,24 @@ main (argc, argv) getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)); current_directory = gdb_dirbuf; -#if 0 - /* not yet */ - gdb_stdout = stdio_fileopen (stdout); - gdb_stderr = stdio_fileopen (stderr); - gdb_stdlog = gdb_stderr; /* for moment */ - gdb_stdtarg = gdb_stderr; /* for moment */ -#else +#if defined (TUI) || defined (GDBTK) + /* Older code uses the tui_file and fputs_unfiltered_hook(). It + should be using a customized UI_FILE object and re-initializing + within its own _initialize function. */ gdb_stdout = tui_fileopen (stdout); gdb_stderr = tui_fileopen (stderr); gdb_stdlog = gdb_stdout; /* for moment */ gdb_stdtarg = gdb_stderr; /* for moment */ +#else + gdb_stdout = stdio_fileopen (stdout); + gdb_stderr = stdio_fileopen (stderr); + gdb_stdlog = gdb_stderr; /* for moment */ + gdb_stdtarg = gdb_stderr; /* for moment */ #endif + /* initialize error() */ + error_init (); + /* Parse arguments and options. */ { int c; @@ -177,8 +218,8 @@ main (argc, argv) with no equivalent). */ static struct option long_options[] = { - {"async", no_argument, &async_p, 1}, - {"noasync", no_argument, &async_p, 0}, + {"async", no_argument, &event_loop_p, 1}, + {"noasync", no_argument, &event_loop_p, 0}, #if defined(TUI) {"tui", no_argument, &tui_version, 1}, #endif @@ -214,7 +255,16 @@ main (argc, argv) {"command", required_argument, 0, 'x'}, {"version", no_argument, &print_version, 1}, {"x", required_argument, 0, 'x'}, +#ifdef GDBTK + {"tclcommand", required_argument, 0, 'z'}, + {"enable-external-editor", no_argument, 0, 'y'}, + {"editor-command", required_argument, 0, 'w'}, +#endif + {"ui", required_argument, 0, 'i'}, + {"interpreter", required_argument, 0, 'i'}, + {"i", required_argument, 0, 'i'}, {"directory", required_argument, 0, 'd'}, + {"d", required_argument, 0, 'd'}, {"cd", required_argument, 0, 11}, {"tty", required_argument, 0, 't'}, {"baud", required_argument, 0, 'b'}, @@ -289,6 +339,40 @@ main (argc, argv) cmdsize * sizeof (*cmdarg)); } break; +#ifdef GDBTK + case 'z': + { + extern int gdbtk_test PARAMS ((char *)); + if (!gdbtk_test (optarg)) + { + fprintf_unfiltered (gdb_stderr, "%s: unable to load tclcommand file \"%s\"", + argv[0], optarg); + exit (1); + } + break; + } + case 'y': + { + /* + * This enables the edit/button in the main window, even + * when IDE_ENABLED is set to false. In this case you must + * use --tclcommand to specify a tcl/script to be called, + * Tcl/Variable to store the edit/command is: + * external_editor + */ + enable_external_editor = 1; + break; + } + case 'w': + { + /* + * if editor command is enabled, both flags are set + */ + enable_external_editor = 1; + external_editor_command = xstrdup (optarg); + break; + } +#endif /* GDBTK */ case 'd': dirarg[ndir++] = optarg; if (ndir >= dirsize) @@ -463,10 +547,8 @@ main (argc, argv) if (!inhibit_gdbinit) { - if (!SET_TOP_LEVEL ()) - source_command (homeinit, 0); + catch_command_errors (source_command, homeinit, 0, RETURN_MASK_ALL); } - do_cleanups (ALL_CLEANUPS); /* Do stats; no need to do them elsewhere since we'll only need them if homedir is set. Make sure that they are @@ -484,41 +566,30 @@ main (argc, argv) /* Now perform all the actions indicated by the arguments. */ if (cdarg != NULL) { - if (!SET_TOP_LEVEL ()) - { - cd_command (cdarg, 0); - } + catch_command_errors (cd_command, cdarg, 0, RETURN_MASK_ALL); } - do_cleanups (ALL_CLEANUPS); for (i = 0; i < ndir; i++) - if (!SET_TOP_LEVEL ()) - directory_command (dirarg[i], 0); + catch_command_errors (directory_command, dirarg[i], 0, RETURN_MASK_ALL); free ((PTR) dirarg); - do_cleanups (ALL_CLEANUPS); if (execarg != NULL && symarg != NULL && STREQ (execarg, symarg)) { - /* The exec file and the symbol-file are the same. If we can't open - it, better only print one error message. */ - if (!SET_TOP_LEVEL ()) - { - exec_file_command (execarg, !batch); - symbol_file_command (symarg, 0); - } + /* The exec file and the symbol-file are the same. If we can't + open it, better only print one error message. + catch_command_errors returns non-zero on success! */ + if (catch_command_errors (exec_file_command, execarg, !batch, RETURN_MASK_ALL)) + catch_command_errors (symbol_file_command, symarg, 0, RETURN_MASK_ALL); } else { if (execarg != NULL) - if (!SET_TOP_LEVEL ()) - exec_file_command (execarg, !batch); + catch_command_errors (exec_file_command, execarg, !batch, RETURN_MASK_ALL); if (symarg != NULL) - if (!SET_TOP_LEVEL ()) - symbol_file_command (symarg, 0); + catch_command_errors (symbol_file_command, symarg, 0, RETURN_MASK_ALL); } - do_cleanups (ALL_CLEANUPS); /* After the symbol file has been read, print a newline to get us beyond the copyright line... But errors should still set off @@ -531,17 +602,16 @@ main (argc, argv) if (corearg != NULL) { - if (!SET_TOP_LEVEL ()) - core_file_command (corearg, !batch); - else if (isdigit (corearg[0]) && !SET_TOP_LEVEL ()) - attach_command (corearg, !batch); + if (catch_command_errors (core_file_command, corearg, !batch, RETURN_MASK_ALL) == 0) + { + /* See if the core file is really a PID. */ + if (isdigit (corearg[0])) + catch_command_errors (attach_command, corearg, !batch, RETURN_MASK_ALL); + } } - do_cleanups (ALL_CLEANUPS); if (ttyarg != NULL) - if (!SET_TOP_LEVEL ()) - tty_command (ttyarg, !batch); - do_cleanups (ALL_CLEANUPS); + catch_command_errors (tty_command, ttyarg, !batch, RETURN_MASK_ALL); #ifdef ADDITIONAL_OPTION_HANDLER ADDITIONAL_OPTION_HANDLER; @@ -559,14 +629,15 @@ main (argc, argv) || memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat))) if (!inhibit_gdbinit) { - if (!SET_TOP_LEVEL ()) - source_command (gdbinit, 0); + catch_command_errors (source_command, gdbinit, 0, RETURN_MASK_ALL); } - do_cleanups (ALL_CLEANUPS); for (i = 0; i < ncmd; i++) { - if (!SET_TOP_LEVEL ()) +#if 0 + /* NOTE: cagney/1999-11-03: SET_TOP_LEVEL() was a macro that + expanded into a call to setjmp(). */ + if (!SET_TOP_LEVEL ()) /* NB: This is #if 0'd out */ { /* NOTE: I am commenting this out, because it is not clear where this feature is used. It is very old and @@ -579,6 +650,8 @@ main (argc, argv) source_command (cmdarg[i], !batch); do_cleanups (ALL_CLEANUPS); } +#endif + catch_command_errors (source_command, cmdarg[i], !batch, RETURN_MASK_ALL); } free ((PTR) cmdarg); @@ -625,6 +698,11 @@ main (argc, argv) The WIN32 Gui calls this main to set up gdb's state, and has its own command loop. */ #if !defined _WIN32 || defined __GNUC__ + /* GUIs generally have their own command loop, mainloop, or + whatever. This is a good place to gain control because many + error conditions will end up here via longjmp(). */ +#if 0 + /* FIXME: cagney/1999-11-06: The original main loop was like: */ while (1) { if (!SET_TOP_LEVEL ()) @@ -640,18 +718,45 @@ main (argc, argv) quit_command ((char *) 0, instream == stdin); } } - /* No exit -- exit is through quit_command. */ + /* NOTE: If the command_loop() returned normally, the loop would + attempt to exit by calling the function quit_command(). That + function would either call exit() or throw an error returning + control to SET_TOP_LEVEL. */ + /* NOTE: The function do_cleanups() was called once each time round + the loop. The usefulness of the call isn't clear. If an error + was thrown, everything would have already been cleaned up. If + command_loop() returned normally and quit_command() was called, + either exit() or error() (again cleaning up) would be called. */ +#endif + /* NOTE: cagney/1999-11-07: There is probably no reason for not + moving this loop and the code found in captured_command_loop() + into the command_loop() proper. The main thing holding back that + change - SET_TOP_LEVEL() - has been eliminated. */ + while (1) + { + catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL); + } #endif + /* No exit -- exit is through quit_command. */ +} +int +main (int argc, char **argv) +{ + struct captured_main_args args; + args.argc = argc; + args.argv = argv; + catch_errors (captured_main, &args, "", RETURN_MASK_ALL); + return 0; } + /* Don't use *_filtered for printing help. We don't want to prompt for continue no matter how small the screen or how much we're going to print. */ static void -print_gdb_help (stream) - GDB_FILE *stream; +print_gdb_help (struct ui_file *stream) { fputs_unfiltered ("\ This is the GNU debugger. Usage:\n\n\ @@ -675,6 +780,10 @@ Options:\n\n\ --exec=EXECFILE Use EXECFILE as the executable.\n\ --fullname Output information used by emacs-GDB interface.\n\ --help Print this message.\n\ +", stream); + fputs_unfiltered ("\ + --interpreter=INTERP\n\ + Select a specific interpreter / user interface\n\ ", stream); fputs_unfiltered ("\ --mapped Use mapped symbol files if supported on this system.\n\ @@ -707,6 +816,6 @@ Options:\n\n\ fputs_unfiltered ("\n\ For more information, type \"help\" from within GDB, or consult the\n\ GDB manual (available as on-line info or a printed manual).\n\ -Report bugs to \"bug-gdb@prep.ai.mit.edu\".\ +Report bugs to \"bug-gdb@gnu.org\".\ ", stream); }