X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fmain.c;h=f7aa5188f39eae71af441108199ab6b1d99f1400;hb=9733f989bbfcefd612a9712683eeebff74329bf4;hp=96df49c9815bcabe4068e32f356fa56555310425;hpb=2df3850c7bfea139c5baf6c2911c11456a1b32e9;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/main.c b/gdb/main.c index 96df49c981..f7aa5188f3 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -1,6 +1,6 @@ /* 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, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This file is part of GDB. @@ -23,7 +23,8 @@ #include "top.h" #include "target.h" #include "inferior.h" -#include "call-cmds.h" +#include "symfile.h" +#include "gdbcore.h" #include "getopt.h" @@ -33,6 +34,13 @@ #include "gdb_string.h" #include "event-loop.h" +#include "ui-out.h" + +#if defined (TUI) +/* 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. */ @@ -48,6 +56,11 @@ int display_space; processes UI events asynchronously. */ int event_loop_p = 1; +#ifdef UI_OUT +/* Has an interpreter been specified and if so, which. */ +char *interpreter_p; +#endif + /* Whether this is the command line version or not */ int tui_version = 0; @@ -57,10 +70,10 @@ 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 */ @@ -69,7 +82,7 @@ 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. */ @@ -77,16 +90,44 @@ static void print_gdb_help PARAMS ((GDB_FILE *)); extern int enable_external_editor; extern char *external_editor_command; -#ifdef __CYGWIN__ -#include /* for MAX_PATH */ -#include /* for cygwin32_conv_to_posix_path */ -#endif +/* Call command_loop. If it happens to return, pass that through as a + non-zero return status. */ -int -main (argc, argv) - int argc; - char **argv; +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. Unfortunately, many FUNCs + 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; @@ -139,12 +180,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; @@ -160,17 +195,16 @@ 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) 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() */ @@ -221,7 +255,18 @@ 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 +#ifdef UI_OUT + {"ui", required_argument, 0, 'i'}, + {"interpreter", required_argument, 0, 'i'}, + {"i", required_argument, 0, 'i'}, +#endif {"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'}, @@ -296,6 +341,45 @@ main (argc, argv) cmdsize * sizeof (*cmdarg)); } break; +#ifdef GDBTK + case 'z': + { +extern int gdbtk_test (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 */ +#ifdef UI_OUT + case 'i': + interpreter_p = optarg; + break; +#endif case 'd': dirarg[ndir++] = optarg; if (ndir >= dirsize) @@ -385,6 +469,7 @@ main (argc, argv) execarg = argv[optind]; break; case 2: + /* FIXME: The documentation says this can be a "ProcID". as well. */ corearg = argv[optind]; break; case 3: @@ -445,21 +530,7 @@ main (argc, argv) *before* all the command line arguments are processed; it sets global parameters, which are independent of what file you are debugging or what directory you are in. */ -#ifdef __CYGWIN32__ - { - char *tmp = getenv ("HOME"); - - if (tmp != NULL) - { - homedir = (char *) alloca (MAX_PATH + 1); - cygwin32_conv_to_posix_path (tmp, homedir); - } - else - homedir = NULL; - } -#else homedir = getenv ("HOME"); -#endif if (homedir) { homeinit = (char *) alloca (strlen (homedir) + @@ -470,10 +541,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 @@ -491,41 +560,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); - free ((PTR) dirarg); - do_cleanups (ALL_CLEANUPS); + catch_command_errors (directory_command, dirarg[i], 0, RETURN_MASK_ALL); + xfree (dirarg); 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_attach, execarg, !batch, RETURN_MASK_ALL)) + catch_command_errors (symbol_file_add_main, symarg, 0, RETURN_MASK_ALL); } else { if (execarg != NULL) - if (!SET_TOP_LEVEL ()) - exec_file_command (execarg, !batch); + catch_command_errors (exec_file_attach, execarg, !batch, RETURN_MASK_ALL); if (symarg != NULL) - if (!SET_TOP_LEVEL ()) - symbol_file_command (symarg, 0); + catch_command_errors (symbol_file_add_main, 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 @@ -538,17 +596,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; @@ -566,14 +623,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 @@ -586,8 +644,10 @@ 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); + xfree (cmdarg); /* Read in the old history after all the command files have been read. */ init_history (); @@ -628,10 +688,8 @@ main (argc, argv) #endif } - /* The default command loop. - The WIN32 Gui calls this main to set up gdb's state, and - has its own command loop. */ -#if !defined _WIN32 || defined __GNUC__ +#if 0 + /* FIXME: cagney/1999-11-06: The original main loop was like: */ while (1) { if (!SET_TOP_LEVEL ()) @@ -647,18 +705,44 @@ 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); + } + /* 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\ @@ -682,6 +766,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\