X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Ftop.c;h=a2cee530c20be5e84f2318d6159d33b738f5ef83;hb=fcaffe4c2a56cdb0c0bb542a3d00dcf8bb5c19b3;hp=3b11642e41fc04d2ad0a1f6b484e81be4892c0bc;hpb=b6ba6518e9254bc25f88088228e93ac966ebccd1;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/top.c b/gdb/top.c index 3b11642e41..a2cee530c2 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -1,6 +1,8 @@ /* Top level stuff for GDB, the GNU debugger. - Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + + Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 + Free Software Foundation, Inc. This file is part of GDB. @@ -22,6 +24,10 @@ #include "defs.h" #include "gdbcmd.h" #include "call-cmds.h" +#include "cli/cli-cmds.h" +#include "cli/cli-script.h" +#include "cli/cli-setshow.h" +#include "cli/cli-decode.h" #include "symtab.h" #include "inferior.h" #include @@ -36,6 +42,9 @@ #include "completer.h" #include "top.h" #include "version.h" +#include "serial.h" +#include "doublest.h" +#include "gdb_assert.h" /* readline include files */ #include @@ -52,69 +61,8 @@ #include "gdb_string.h" #include "gdb_stat.h" #include -#ifdef UI_OUT #include "ui-out.h" #include "cli-out.h" -#endif - -/* From completer.c */ - -extern int is_complete_command (void (*func) (char *args, int from_tty)); - -/* From cli/cli-cmds.c */ - -extern void init_cmd_lists (void); - -extern void init_cli_cmds (void); - -extern void execute_user_command (struct cmd_list_element *c, char *args); - -/* From cli/cli-setshow.c */ - -extern void do_setshow_command (char *, int, struct cmd_list_element *); - -/* Exported to CLI cli/cli-cmds.c. */ - -void set_verbose (char *, int, struct cmd_list_element *); - -void show_history (char *, int); - -void set_history (char *, int); - -void show_commands (char *, int); - -void do_restore_instream_cleanup (void *stream); - -/* Prototypes for local functions */ - -static void dont_repeat_command (char *, int); - -static void init_signals (void); - -#ifdef STOP_SIGNAL -static void stop_sig (int); -#endif - -static char *readline_line_completion_function (char *, int); - -static void init_main (void); - -static void float_handler (int); - -static void init_signals (void); - -static void set_history_size_command (char *, int, struct cmd_list_element *); - -static void do_nothing (int); - -#ifdef SIGHUP -/* NOTE 1999-04-29: This function will be static again, once we modify - gdb to use the event loop as the default command loop and we merge - event-top.c into this file, top.c */ -/* static */ int quit_cover (PTR); - -static void disconnect (int); -#endif /* Default command line prompt. This is overriden in some configs. */ @@ -166,7 +114,6 @@ int xgdb_verbose; /* gdb prints this when reading a command interactively */ static char *gdb_prompt_string; /* the global prompt string */ -extern char *get_prompt (void); /* access function for prompt string */ /* Buffer used for reading command lines, and the size allocated for it so far. */ @@ -224,21 +171,6 @@ int target_executing = 0; /* Level of control structure. */ static int control_level; -/* Structure for arguments to user defined functions. */ -#define MAXUSERARGS 10 -struct user_args - { - struct user_args *next; - struct - { - char *arg; - int len; - } - a[MAXUSERARGS]; - int count; - } - *user_args; - /* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT. */ #ifndef STOP_SIGNAL @@ -248,23 +180,13 @@ static void stop_sig (int); #endif #endif -/* Some System V have job control but not sigsetmask(). */ -#if !defined (HAVE_SIGSETMASK) -#if !defined (USG) -#define HAVE_SIGSETMASK 1 -#else -#define HAVE_SIGSETMASK 0 -#endif -#endif - -#if 0 == (HAVE_SIGSETMASK) -#define sigsetmask(n) -#endif - /* Hooks for alternate command interfaces. */ /* Called after most modules have been initialized, but before taking users - command file. */ + command file. + + If the UI fails to initialize and it wants GDB to continue + using the default UI, then it should clear this hook before returning. */ void (*init_ui_hook) (char *argv0); @@ -275,7 +197,7 @@ void (*init_ui_hook) (char *argv0); int (*ui_loop_hook) (int); /* Called instead of command_loop at top level. Can be invoked via - return_to_top_level. */ + throw_exception(). */ void (*command_loop_hook) (void); @@ -341,7 +263,8 @@ void (*memory_changed_hook) (CORE_ADDR addr, int len); /* Called when going to wait for the target. Usually allows the GUI to run while waiting for target events. */ -int (*target_wait_hook) (int pid, struct target_waitstatus * status); +ptid_t (*target_wait_hook) (ptid_t ptid, + struct target_waitstatus * status); /* Used by UI as a wrapper around command execution. May do various things like enabling/disabling buttons, etc... */ @@ -368,21 +291,21 @@ NORETURN void (*error_hook) (void) ATTR_NORETURN; directly. */ #if defined(HAVE_SIGSETJMP) #define SIGJMP_BUF sigjmp_buf -#define SIGSETJMP(buf) sigsetjmp(buf, 1) -#define SIGLONGJMP(buf,val) siglongjmp(buf,val) +#define SIGSETJMP(buf) sigsetjmp((buf), 1) +#define SIGLONGJMP(buf,val) siglongjmp((buf), (val)) #else #define SIGJMP_BUF jmp_buf #define SIGSETJMP(buf) setjmp(buf) -#define SIGLONGJMP(buf,val) longjmp(buf,val) +#define SIGLONGJMP(buf,val) longjmp((buf), (val)) #endif -/* Where to go for return_to_top_level. */ +/* Where to go for throw_exception(). */ static SIGJMP_BUF *catch_return; /* Return for reason REASON to the nearest containing catch_errors(). */ NORETURN void -return_to_top_level (enum return_reason reason) +throw_exception (enum return_reason reason) { quit_flag = 0; immediate_quit = 0; @@ -416,10 +339,11 @@ return_to_top_level (enum return_reason reason) (NORETURN void) SIGLONGJMP (*catch_return, (int) reason); } -/* Call FUNC with arg ARGS, catching any errors. If there is no - error, return the value returned by FUNC. If there is an error, - print ERRSTRING, print the specific error message, then return - zero. +/* Call FUNC() with args FUNC_UIOUT and FUNC_ARGS, catching any + errors. Set FUNC_CAUGHT to an ``enum return_reason'' if the + function is aborted (using throw_exception() or zero if the + function returns normally. Set FUNC_VAL to the value returned by + the function or 0 if the function was aborted. Must not be called with immediate_quit in effect (bad things might happen, say we got a signal in the middle of a memcpy to quit_return). @@ -447,21 +371,30 @@ return_to_top_level (enum return_reason reason) be consolidated into a single file instead of being distributed between utils.c and top.c? */ -int -catch_errors (catch_errors_ftype *func, PTR args, char *errstring, - return_mask mask) +static void +catcher (catch_exceptions_ftype *func, + struct ui_out *func_uiout, + void *func_args, + int *func_val, + enum return_reason *func_caught, + char *errstring, + return_mask mask) { SIGJMP_BUF *saved_catch; SIGJMP_BUF catch; - int val; struct cleanup *saved_cleanup_chain; char *saved_error_pre_print; char *saved_quit_pre_print; + struct ui_out *saved_uiout; /* Return value from SIGSETJMP(): enum return_reason if error or quit caught, 0 otherwise. */ int caught; + /* Return value from FUNC(): Hopefully non-zero. Explicitly set to + zero if an error quit was caught. */ + int val; + /* Override error/quit messages during FUNC. */ saved_error_pre_print = error_pre_print; @@ -472,6 +405,11 @@ catch_errors (catch_errors_ftype *func, PTR args, char *errstring, if (mask & RETURN_MASK_QUIT) quit_pre_print = errstring; + /* Override the global ``struct ui_out'' builder. */ + + saved_uiout = uiout; + uiout = func_uiout; + /* Prevent error/quit during FUNC from calling cleanups established prior to here. */ @@ -483,7 +421,7 @@ catch_errors (catch_errors_ftype *func, PTR args, char *errstring, catch_return = &catch; caught = SIGSETJMP (catch); if (!caught) - val = (*func) (args); + val = (*func) (func_uiout, func_args); else val = 0; catch_return = saved_catch; @@ -495,47 +433,78 @@ catch_errors (catch_errors_ftype *func, PTR args, char *errstring, do_cleanups call (to cover the problem) or an assertion check to detect bad FUNCs code. */ - /* Restore the cleanup chain and error/quit messages to their - original states. */ + /* Restore the cleanup chain, the error/quit messages, and the uiout + builder, to their original states. */ restore_cleanups (saved_cleanup_chain); + uiout = saved_uiout; + if (mask & RETURN_MASK_QUIT) quit_pre_print = saved_quit_pre_print; if (mask & RETURN_MASK_ERROR) error_pre_print = saved_error_pre_print; - /* Return normally if no error/quit event occurred. */ + /* Return normally if no error/quit event occurred or this catcher + can handle this exception. The caller analyses the func return + values. */ - if (!caught) - return val; + if (!caught || (mask & RETURN_MASK (caught))) + { + *func_val = val; + *func_caught = caught; + return; + } - /* If the caller didn't request that the event be caught, relay the + /* The caller didn't request that the event be caught, relay the event to the next containing catch_errors(). */ - if (!(mask & RETURN_MASK (caught))) - return_to_top_level (caught); - - /* Tell the caller that an event was caught. - - FIXME: nsd/2000-02-22: When MASK is RETURN_MASK_ALL, the caller - can't tell what type of event occurred. + throw_exception (caught); +} - A possible fix is to add a new interface, catch_event(), that - returns enum return_reason after catching an error or a quit. +int +catch_exceptions (struct ui_out *uiout, + catch_exceptions_ftype *func, + void *func_args, + char *errstring, + return_mask mask) +{ + int val; + enum return_reason caught; + catcher (func, uiout, func_args, &val, &caught, errstring, mask); + gdb_assert (val >= 0); + gdb_assert (caught <= 0); + if (caught < 0) + return caught; + return val; +} - When returning normally, i.e. without catching an error or a - quit, catch_event() could return RETURN_NORMAL, which would be - added to enum return_reason. FUNC would return information - exclusively via ARGS. +struct catch_errors_args +{ + catch_errors_ftype *func; + void *func_args; +}; - Alternatively, normal catch_event() could return FUNC's return - value. The caller would need to be aware of potential overlap - with enum return_reason, which could be publicly restricted to - negative values to simplify return value processing in FUNC and - in the caller. */ +int +do_catch_errors (struct ui_out *uiout, void *data) +{ + struct catch_errors_args *args = data; + return args->func (args->func_args); +} - return 0; +int +catch_errors (catch_errors_ftype *func, void *func_args, char *errstring, + return_mask mask) +{ + int val; + enum return_reason caught; + struct catch_errors_args args; + args.func = func; + args.func_args = func_args; + catcher (do_catch_errors, uiout, &args, &val, &caught, errstring, mask); + if (caught != 0) + return 0; + return val; } struct captured_command_args @@ -576,28 +545,28 @@ catch_command_errors (catch_command_errors_ftype * command, /* Handler for SIGHUP. */ #ifdef SIGHUP -static void -disconnect (int signo) -{ - catch_errors (quit_cover, NULL, - "Could not kill the program being debugged", RETURN_MASK_ALL); - signal (SIGHUP, SIG_DFL); - kill (getpid (), SIGHUP); -} - /* Just a little helper function for disconnect(). */ /* NOTE 1999-04-29: This function will be static again, once we modify gdb to use the event loop as the default command loop and we merge event-top.c into this file, top.c */ /* static */ int -quit_cover (PTR s) +quit_cover (void *s) { caution = 0; /* Throw caution to the wind -- we're exiting. This prevents asking the user dumb questions. */ quit_command ((char *) 0, 0); return 0; } + +static void +disconnect (int signo) +{ + catch_errors (quit_cover, NULL, + "Could not kill the program being debugged", RETURN_MASK_ALL); + signal (SIGHUP, SIG_DFL); + kill (getpid (), SIGHUP); +} #endif /* defined SIGHUP */ /* Line number we are currently in in a file which is being sourced. */ @@ -649,8 +618,6 @@ read_command_file (FILE *stream) do_cleanups (cleanups); } -extern void init_proc (void); - void (*pre_init_ui_hook) (void); #ifdef __MSDOS__ @@ -662,66 +629,6 @@ do_chdir_cleanup (void *old_dir) } #endif -void -gdb_init (char *argv0) -{ - if (pre_init_ui_hook) - pre_init_ui_hook (); - - /* Run the init function of each source file */ - - getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)); - current_directory = gdb_dirbuf; - -#ifdef __MSDOS__ - /* Make sure we return to the original directory upon exit, come - what may, since the OS doesn't do that for us. */ - make_final_cleanup (do_chdir_cleanup, xstrdup (current_directory)); -#endif - - init_cmd_lists (); /* This needs to be done first */ - initialize_targets (); /* Setup target_terminal macros for utils.c */ - initialize_utils (); /* Make errors and warnings possible */ - initialize_all_files (); - initialize_current_architecture (); - init_cli_cmds(); - init_main (); /* But that omits this file! Do it now */ - - /* The signal handling mechanism is different depending whether or - not the async version is run. NOTE: in the future we plan to make - the event loop be the default engine of gdb, and this difference - will disappear. */ - if (event_loop_p) - async_init_signals (); - else - init_signals (); - - /* We need a default language for parsing expressions, so simple things like - "set width 0" won't fail if no language is explicitly set in a config file - or implicitly set by reading an executable during startup. */ - set_language (language_c); - expected_language = current_language; /* don't warn about the change. */ - -#ifdef UI_OUT - /* Install the default UI */ - uiout = cli_out_new (gdb_stdout); -#endif - -#ifdef UI_OUT - /* All the interpreters should have had a look at things by now. - Initialize the selected interpreter. */ - if (interpreter_p && !init_ui_hook) - { - fprintf_unfiltered (gdb_stderr, "Interpreter `%s' unrecognized.\n", - interpreter_p); - exit (1); - } -#endif - - if (init_ui_hook) - init_ui_hook (argv0); -} - /* Execute the line P as a command. Pass FROM_TTY as second argument to the defining function. */ @@ -732,9 +639,7 @@ execute_command (char *p, int from_tty) register enum language flang; static int warned = 0; char *line; - /* FIXME: These should really be in an appropriate header file */ -extern void serial_log_command (const char *); - + free_all_values (); /* Force cleanup of any alloca areas if using C alloca instead of @@ -768,10 +673,19 @@ extern void serial_log_command (const char *); /* Pass null arg rather than an empty one. */ arg = *p ? p : 0; - /* Clear off trailing whitespace, except for set and complete command. */ + /* FIXME: cagney/2002-02-02: The c->type test is pretty dodgy + while the is_complete_command(cfunc) test is just plain + bogus. They should both be replaced by a test of the form + c->strip_trailing_white_space_p. */ + /* NOTE: cagney/2002-02-02: The function.cfunc in the below + can't be replaced with func. This is because it is the + cfunc, and not the func, that has the value that the + is_complete_command hack is testing for. */ + /* Clear off trailing whitespace, except for set and complete + command. */ if (arg && c->type != set_cmd - && !is_complete_command (c->function.cfunc)) + && !is_complete_command (c)) { p = arg + strlen (arg) - 1; while (p >= arg && (*p == ' ' || *p == '\t')) @@ -780,12 +694,7 @@ extern void serial_log_command (const char *); } /* If this command has been pre-hooked, run the hook first. */ - if ((c->hook_pre) && (!c->hook_in)) - { - c->hook_in = 1; /* Prevent recursive hooking */ - execute_user_command (c->hook_pre, (char *) 0); - c->hook_in = 0; /* Allow hook to work again once it is complete */ - } + execute_cmd_pre_hook (c); if (c->flags & DEPRECATED_WARN_USER) deprecated_cmd_warning (&line); @@ -794,20 +703,15 @@ extern void serial_log_command (const char *); execute_user_command (c, arg); else if (c->type == set_cmd || c->type == show_cmd) do_setshow_command (arg, from_tty & caution, c); - else if (c->function.cfunc == NO_FUNCTION) + else if (!cmd_func_p (c)) error ("That is not a command, just a help topic."); else if (call_command_hook) call_command_hook (c, arg, from_tty & caution); else - (*c->function.cfunc) (arg, from_tty & caution); + cmd_func (c, arg, from_tty & caution); /* If this command has been post-hooked, run the hook last. */ - if ((c->hook_post) && (!c->hook_in)) - { - c->hook_in = 1; /* Prevent recursive hooking */ - execute_user_command (c->hook_post, (char *) 0); - c->hook_in = 0; /* allow hook to work again once it is complete */ - } + execute_cmd_post_hook (c); } @@ -858,9 +762,6 @@ command_loop (void) while (instream && !feof (instream)) { -#if defined(TUI) - extern int insert_mode; -#endif if (window_hook && instream == stdin) (*window_hook) (instream, get_prompt ()); @@ -869,22 +770,10 @@ command_loop (void) reinitialize_more_filter (); old_chain = make_cleanup (null_cleanup, 0); -#if defined(TUI) - /* A bit of paranoia: I want to make sure the "insert_mode" global - * is clear except when it is being used for command-line editing - * (see tuiIO.c, utils.c); otherwise normal output will - * get messed up in the TUI. So clear it before/after - * the command-line-input call. - RT - */ - insert_mode = 0; -#endif /* Get a command-line. This calls the readline package. */ command = command_line_input (instream == stdin ? get_prompt () : (char *) NULL, instream == stdin, "prompt"); -#if defined(TUI) - insert_mode = 0; -#endif if (command == 0) return; @@ -1001,11 +890,6 @@ gdb_readline (char *prompt_arg) character position to be off, since the newline we read from the user is not accounted for. */ fputs_unfiltered (prompt_arg, gdb_stdout); -#ifdef MPW - /* Move to a new line so the entered line doesn't have a prompt - on the front of it. */ - fputs_unfiltered ("\n", gdb_stdout); -#endif /* MPW */ gdb_flush (gdb_stdout); } @@ -1063,24 +947,29 @@ static int write_history_p; static int history_size; static char *history_filename; -/* Functions that are used as part of the fancy command line editing. */ - -/* This can be used for functions which don't want to complete on symbols - but don't want to complete on anything else either. */ -/* ARGSUSED */ -char ** -noop_completer (char *text, char *prefix) +/* This is like readline(), but it has some gdb-specific behavior. + gdb can use readline in both the synchronous and async modes during + a single gdb invocation. At the ordinary top-level prompt we might + be using the async readline. That means we can't use + rl_pre_input_hook, since it doesn't work properly in async mode. + However, for a secondary prompt (" >", such as occurs during a + `define'), gdb just calls readline() directly, running it in + synchronous mode. So for operate-and-get-next to work in this + situation, we have to switch the hooks around. That is what + gdb_readline_wrapper is for. */ +char * +gdb_readline_wrapper (char *prompt) { - return NULL; -} - -/* Line completion interface function for readline. */ + /* Set the hook that works in this case. */ + if (event_loop_p && after_char_processing_hook) + { + rl_pre_input_hook = (Function *) after_char_processing_hook; + after_char_processing_hook = NULL; + } -static char * -readline_line_completion_function (char *text, int matches) -{ - return line_completion_function (text, matches, rl_line_buffer, rl_point); + return readline (prompt); } + #ifdef STOP_SIGNAL static void @@ -1088,7 +977,16 @@ stop_sig (int signo) { #if STOP_SIGNAL == SIGTSTP signal (SIGTSTP, SIG_DFL); +#if HAVE_SIGPROCMASK + { + sigset_t zero; + + sigemptyset (&zero); + sigprocmask (SIG_SETMASK, &zero, 0); + } +#elif HAVE_SIGSETMASK sigsetmask (0); +#endif kill (getpid (), SIGTSTP); signal (SIGTSTP, stop_sig); #else @@ -1103,6 +1001,15 @@ stop_sig (int signo) #endif /* STOP_SIGNAL */ /* Initialize signal handlers. */ +static void +float_handler (int signo) +{ + /* This message is based on ANSI C, section 4.7. Note that integer + divide by zero causes this, so "float" is a misnomer. */ + signal (SIGFPE, float_handler); + error ("Erroneous arithmetic operation."); +} + static void do_nothing (int signo) { @@ -1146,6 +1053,66 @@ init_signals (void) #endif } +/* The current saved history number from operate-and-get-next. + This is -1 if not valid. */ +static int operate_saved_history = -1; + +/* This is put on the appropriate hook and helps operate-and-get-next + do its work. */ +void +gdb_rl_operate_and_get_next_completion (void) +{ + int delta = where_history () - operate_saved_history; + /* The `key' argument to rl_get_previous_history is ignored. */ + rl_get_previous_history (delta, 0); + operate_saved_history = -1; + + /* readline doesn't automatically update the display for us. */ + rl_redisplay (); + + after_char_processing_hook = NULL; + rl_pre_input_hook = NULL; +} + +/* This is a gdb-local readline command handler. It accepts the + current command line (like RET does) and, if this command was taken + from the history, arranges for the next command in the history to + appear on the command line when the prompt returns. + We ignore the arguments. */ +static int +gdb_rl_operate_and_get_next (int count, int key) +{ + int where; + + if (event_loop_p) + { + /* Use the async hook. */ + after_char_processing_hook = gdb_rl_operate_and_get_next_completion; + } + else + { + /* This hook only works correctly when we are using the + synchronous readline. */ + rl_pre_input_hook = (Function *) gdb_rl_operate_and_get_next_completion; + } + + /* Find the current line, and find the next line to use. */ + where = where_history(); + + /* FIXME: kettenis/20020817: max_input_history is renamed into + history_max_entries in readline-4.2. When we do a new readline + import, we should probably change it here too, even though + readline maintains backwards compatibility for now by still + defining max_input_history. */ + if ((history_is_stifled () && (history_length >= max_input_history)) || + (where >= history_length - 1)) + operate_saved_history = where; + else + operate_saved_history = where + 1; + + return rl_newline (1, key); +} + /* Read one line from the command input stream `instream' into the local static buffer `linebuffer' (whose current length is `linelength'). @@ -1244,7 +1211,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix) } else if (command_editing_p && instream == stdin && ISATTY (instream)) { - rl = readline (local_prompt); + rl = gdb_readline_wrapper (local_prompt); } else { @@ -1386,16 +1353,11 @@ print_gdb_version (struct ui_file *stream) program to parse, and is just canonical program name and version number, which starts after last space. */ -#ifdef MI_OUT - /* Print it console style until a format is defined */ - fprintf_filtered (stream, "GNU gdb %s (MI_OUT)\n", version); -#else fprintf_filtered (stream, "GNU gdb %s\n", version); -#endif /* Second line is a copyright notice. */ - fprintf_filtered (stream, "Copyright 2001 Free Software Foundation, Inc.\n"); + fprintf_filtered (stream, "Copyright 2002 Free Software Foundation, Inc.\n"); /* Following the copyright is a brief statement that the program is free software, that users are free to copy and change it on @@ -1458,7 +1420,7 @@ get_prompt_1 (void *data) /* formatted prompt */ { char fmt[40], *promptp, *outp, *tmp; - value_ptr arg_val; + struct value *arg_val; DOUBLEST doubleval; LONGEST longval; CORE_ADDR addrval; @@ -1510,7 +1472,7 @@ get_prompt_1 (void *data) if (*promptp != gdb_prompt_escape) error ("Syntax error at prompt position %d", - promptp - local_prompt); + (int) (promptp - local_prompt)); else { promptp++; /* skip second escape char */ @@ -1550,7 +1512,7 @@ get_prompt_1 (void *data) break; case TYPE_CODE_PTR: elt_type = check_typedef (TYPE_TARGET_TYPE (arg_type)); - addrval = value_as_pointer (arg_val); + addrval = value_as_address (arg_val); if (TYPE_LENGTH (elt_type) == 1 && TYPE_CODE (elt_type) == TYPE_CODE_INT && @@ -1656,7 +1618,7 @@ get_prompt_1 (void *data) break; /* void type -- no output */ default: error ("bad data type at prompt position %d", - promptp - local_prompt); + (int) (promptp - local_prompt)); break; } outp += strlen (outp); @@ -1708,7 +1670,7 @@ set_prompt (char *s) int quit_confirm (void) { - if (inferior_pid != 0 && target_has_execution) + if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution) { char *s; @@ -1740,12 +1702,12 @@ quit_force (char *args, int from_tty) value of that expression. */ if (args) { - value_ptr val = parse_and_eval (args); + struct value *val = parse_and_eval (args); exit_code = (int) value_as_long (val); } - if (inferior_pid != 0 && target_has_execution) + if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution) { if (attach_flag) target_detach (args, from_tty); @@ -1762,16 +1724,6 @@ quit_force (char *args, int from_tty) do_final_cleanups (ALL_CLEANUPS); /* Do any final cleanups before exiting */ -#if defined(TUI) - /* tuiDo((TuiOpaqueFuncPtr)tuiCleanUp); */ - /* The above does not need to be inside a tuiDo(), since - * it is not manipulating the curses screen, but rather, - * it is tearing it down. - */ - if (tui_version) - tuiCleanUp (); -#endif - exit (exit_code); } @@ -1810,8 +1762,6 @@ show_commands (char *args, int from_tty) than the number of the last command). Relative to history_base. */ int hist_len; -extern HIST_ENTRY *history_get (int); - /* Print out some of the commands from the command history. */ /* First determine the length of the history list. */ hist_len = history_size; @@ -1926,15 +1876,6 @@ set_verbose (char *args, int from_tty, struct cmd_list_element *c) } } -static void -float_handler (int signo) -{ - /* This message is based on ANSI C, section 4.7. Note that integer - divide by zero causes this, so "float" is a misnomer. */ - signal (SIGFPE, float_handler); - error ("Erroneous arithmetic operation."); -} - /* Init the history buffer. Note that we are called after the init file(s) * have been read so that the user can change the history file via his * .gdbinit file (for instance). The GDBHISTFILE environment variable @@ -1996,6 +1937,12 @@ init_main (void) async_annotation_suffix = "prompt"; /* Set the variable associated with the setshow prompt command. */ new_async_prompt = savestring (PROMPT (0), strlen (PROMPT (0))); + + /* If gdb was started with --annotate=2, this is equivalent to + the user entering the command 'set annotate 2' at the gdb + prompt, so we need to do extra processing. */ + if (annotation_level > 1) + set_async_annotation_level (NULL, 0, NULL); } gdb_prompt_escape = 0; /* default to none. */ @@ -2011,6 +1958,10 @@ init_main (void) rl_completer_quote_characters = get_gdb_completer_quote_characters (); rl_readline_name = "gdb"; + /* The name for this defun comes from Bash, where it originated. + 15 is Control-o, the same binding this function has in Bash. */ + rl_add_defun ("operate-and-get-next", gdb_rl_operate_and_get_next, 15); + /* The set prompt command is different depending whether or not the async version is run. NOTE: this difference is going to disappear as we make the event loop be the default engine of @@ -2029,7 +1980,7 @@ init_main (void) (char *) &new_async_prompt, "Set gdb's prompt", &setlist); add_show_from_set (c, &showlist); - c->function.sfunc = set_async_prompt; + set_cmd_sfunc (c, set_async_prompt); } add_show_from_set @@ -2065,7 +2016,7 @@ Without an argument, command line editing is enabled. To edit, use\n\ EMACS-like or VI-like commands like control-P or ESC.", &setlist); add_show_from_set (c, &showlist); - c->function.sfunc = set_async_editing_command; + set_cmd_sfunc (c, set_async_editing_command); } add_show_from_set @@ -2076,16 +2027,17 @@ Without an argument, saving is enabled.", &sethistlist), &showhistlist); c = add_set_cmd ("size", no_class, var_integer, (char *) &history_size, - "Set the size of the command history, \n\ + "Set the size of the command history,\n\ ie. the number of previous commands to keep a record of.", &sethistlist); add_show_from_set (c, &showhistlist); - c->function.sfunc = set_history_size_command; + set_cmd_sfunc (c, set_history_size_command); - add_show_from_set - (add_set_cmd ("filename", no_class, var_filename, (char *) &history_filename, - "Set the filename in which to record the command history\n\ - (the list of previous commands of which a record is kept).", &sethistlist), - &showhistlist); + c = add_set_cmd ("filename", no_class, var_filename, + (char *) &history_filename, + "Set the filename in which to record the command history\n\ +(the list of previous commands of which a record is kept).", &sethistlist); + set_cmd_completer (c, filename_completer); + add_show_from_set (c, &showhistlist); add_show_from_set (add_set_cmd ("confirm", class_support, var_boolean, @@ -2115,7 +2067,7 @@ ie. the number of previous commands to keep a record of.", &sethistlist); 2 == output annotated suitably for use by programs that control GDB.", &setlist); add_show_from_set (c, &showlist); - c->function.sfunc = set_async_annotation_level; + set_cmd_sfunc (c, set_async_annotation_level); } if (event_loop_p) { @@ -2126,3 +2078,64 @@ Use \"on\" to enable the notification, and \"off\" to disable it.", &setlist), &showlist); } } + +void +gdb_init (char *argv0) +{ + if (pre_init_ui_hook) + pre_init_ui_hook (); + + /* Run the init function of each source file */ + + getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)); + current_directory = gdb_dirbuf; + +#ifdef __MSDOS__ + /* Make sure we return to the original directory upon exit, come + what may, since the OS doesn't do that for us. */ + make_final_cleanup (do_chdir_cleanup, xstrdup (current_directory)); +#endif + + init_cmd_lists (); /* This needs to be done first */ + initialize_targets (); /* Setup target_terminal macros for utils.c */ + initialize_utils (); /* Make errors and warnings possible */ + initialize_all_files (); + initialize_current_architecture (); + init_cli_cmds(); + init_main (); /* But that omits this file! Do it now */ + + /* The signal handling mechanism is different depending whether or + not the async version is run. NOTE: in the future we plan to make + the event loop be the default engine of gdb, and this difference + will disappear. */ + if (event_loop_p) + async_init_signals (); + else + init_signals (); + + /* We need a default language for parsing expressions, so simple things like + "set width 0" won't fail if no language is explicitly set in a config file + or implicitly set by reading an executable during startup. */ + set_language (language_c); + expected_language = current_language; /* don't warn about the change. */ + + /* Allow another UI to initialize. If the UI fails to initialize, and + it wants GDB to revert to the CLI, it should clear init_ui_hook. */ + if (init_ui_hook) + init_ui_hook (argv0); + + /* Install the default UI */ + if (!init_ui_hook) + { + uiout = cli_out_new (gdb_stdout); + + /* All the interpreters should have had a look at things by now. + Initialize the selected interpreter. */ + if (interpreter_p) + { + fprintf_unfiltered (gdb_stderr, "Interpreter `%s' unrecognized.\n", + interpreter_p); + exit (1); + } + } +}