X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Ftop.c;h=b7fdd4eec4e37d06c59c1f93e4fe91eef4deb06b;hb=994337c3642476693a4de423b639b32ccd5292f7;hp=3b11642e41fc04d2ad0a1f6b484e81be4892c0bc;hpb=b6ba6518e9254bc25f88088228e93ac966ebccd1;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/top.c b/gdb/top.c index 3b11642e41..b7fdd4eec4 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 (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, + 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. This file is part of GDB. @@ -16,14 +18,19 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #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 "exceptions.h" #include #include "target.h" #include "breakpoint.h" @@ -36,85 +43,27 @@ #include "completer.h" #include "top.h" #include "version.h" +#include "serial.h" +#include "doublest.h" +#include "gdb_assert.h" +#include "main.h" +#include "event-loop.h" /* readline include files */ -#include -#include +#include "readline/readline.h" +#include "readline/history.h" /* readline defines this. */ #undef savestring #include -#include - #include "event-top.h" #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. */ @@ -124,23 +73,39 @@ static void disconnect (int); /* Initialization file name for gdb. This is overridden in some configs. */ +#ifndef PATH_MAX +# ifdef FILENAME_MAX +# define PATH_MAX FILENAME_MAX +# else +# define PATH_MAX 512 +# endif +#endif + #ifndef GDBINIT_FILENAME #define GDBINIT_FILENAME ".gdbinit" #endif -char gdbinit[] = GDBINIT_FILENAME; +char gdbinit[PATH_MAX + 1] = GDBINIT_FILENAME; int inhibit_gdbinit = 0; /* If nonzero, and GDB has been configured to be able to use windows, attempt to open them upon startup. */ -int use_windows = 1; +int use_windows = 0; extern char lang_frame_mismatch_warn[]; /* language.c */ /* Flag for whether we want all the "from_tty" gubbish printed. */ int caution = 1; /* Default is yes, sigh. */ +static void +show_caution (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("\ +Whether to confirm potentially dangerous operations is %s.\n"), + value); +} /* stdio stream that command input is being read from. Set to stdin normally. Set by source_command to the file we are sourcing. Set to NULL if we are @@ -148,6 +113,10 @@ int caution = 1; /* Default is yes, sigh. */ FILE *instream; +/* Flag to indicate whether a user defined command is currently running. */ + +int in_user_command; + /* Current working directory. */ char *current_directory; @@ -166,7 +135,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. */ @@ -200,7 +168,7 @@ int baud_rate = -1; In mid-1996, remote_timeout was moved from remote.c to top.c and it began being used in other remote-* targets. It appears that the default was changed to 20 seconds at that time, perhaps because the - Hitachi E7000 ICE didn't always respond in a timely manner. + Renesas E7000 ICE didn't always respond in a timely manner. But if 5 seconds is a long time to sit and wait for retransmissions, 20 seconds is far worse. This demonstrates the difficulty of using @@ -221,23 +189,10 @@ int remote_debug = 0; target is off and running, which gdb is doing something else. */ 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; +/* Sbrk location on entry to main. Used for statistics only. */ +#ifdef HAVE_SBRK +char *lim_at_start; +#endif /* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT. */ @@ -248,350 +203,121 @@ 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. -void (*init_ui_hook) (char *argv0); + 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 (*deprecated_init_ui_hook) (char *argv0); /* This hook is called from within gdb's many mini-event loops which could steal control from a real user interface's event loop. It returns non-zero if the user is requesting a detach, zero otherwise. */ -int (*ui_loop_hook) (int); +int (*deprecated_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); +void (*deprecated_command_loop_hook) (void); /* Called from print_frame_info to list the line we stopped in. */ -void (*print_frame_info_listing_hook) (struct symtab * s, int line, - int stopline, int noerror); +void (*deprecated_print_frame_info_listing_hook) (struct symtab * s, int line, + int stopline, int noerror); /* Replaces most of query. */ -int (*query_hook) (const char *, va_list); +int (*deprecated_query_hook) (const char *, va_list); /* Replaces most of warning. */ -void (*warning_hook) (const char *, va_list); +void (*deprecated_warning_hook) (const char *, va_list); -/* These three functions support getting lines of text from the user. They - are used in sequence. First readline_begin_hook is called with a text - string that might be (for example) a message for the user to type in a - sequence of commands to be executed at a breakpoint. If this function - calls back to a GUI, it might take this opportunity to pop up a text - interaction window with this message. Next, readline_hook is called - with a prompt that is emitted prior to collecting the user input. - It can be called multiple times. Finally, readline_end_hook is called - to notify the GUI that we are done with the interaction window and it - can close it. */ +/* These three functions support getting lines of text from the user. + They are used in sequence. First deprecated_readline_begin_hook is + called with a text string that might be (for example) a message for + the user to type in a sequence of commands to be executed at a + breakpoint. If this function calls back to a GUI, it might take + this opportunity to pop up a text interaction window with this + message. Next, deprecated_readline_hook is called with a prompt + that is emitted prior to collecting the user input. It can be + called multiple times. Finally, deprecated_readline_end_hook is + called to notify the GUI that we are done with the interaction + window and it can close it. */ -void (*readline_begin_hook) (char *, ...); -char *(*readline_hook) (char *); -void (*readline_end_hook) (void); +void (*deprecated_readline_begin_hook) (char *, ...); +char *(*deprecated_readline_hook) (char *); +void (*deprecated_readline_end_hook) (void); /* Called as appropriate to notify the interface of the specified breakpoint conditions. */ -void (*create_breakpoint_hook) (struct breakpoint * bpt); -void (*delete_breakpoint_hook) (struct breakpoint * bpt); -void (*modify_breakpoint_hook) (struct breakpoint * bpt); +void (*deprecated_create_breakpoint_hook) (struct breakpoint * bpt); +void (*deprecated_delete_breakpoint_hook) (struct breakpoint * bpt); +void (*deprecated_modify_breakpoint_hook) (struct breakpoint * bpt); /* Called as appropriate to notify the interface that we have attached to or detached from an already running process. */ -void (*attach_hook) (void); -void (*detach_hook) (void); +void (*deprecated_attach_hook) (void); +void (*deprecated_detach_hook) (void); /* Called during long calculations to allow GUI to repair window damage, and to check for stop buttons, etc... */ -void (*interactive_hook) (void); +void (*deprecated_interactive_hook) (void); /* Called when the registers have changed, as a hint to a GUI to minimize window update. */ -void (*registers_changed_hook) (void); +void (*deprecated_registers_changed_hook) (void); /* Tell the GUI someone changed the register REGNO. -1 means that the caller does not know which register changed or that several registers have changed (see value_assign). */ -void (*register_changed_hook) (int regno); +void (*deprecated_register_changed_hook) (int regno); /* Tell the GUI someone changed LEN bytes of memory at ADDR */ -void (*memory_changed_hook) (CORE_ADDR addr, int len); +void (*deprecated_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 (*deprecated_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... */ -void (*call_command_hook) (struct cmd_list_element * c, char *cmd, - int from_tty); +void (*deprecated_call_command_hook) (struct cmd_list_element * c, char *cmd, + int from_tty); /* Called after a `set' command has finished. Is only run if the `set' command succeeded. */ -void (*set_hook) (struct cmd_list_element * c); +void (*deprecated_set_hook) (struct cmd_list_element * c); /* Called when the current thread changes. Argument is thread id. */ -void (*context_hook) (int id); +void (*deprecated_context_hook) (int id); /* Takes control from error (). Typically used to prevent longjmps out of the middle of the GUI. Usually used in conjunction with a catch routine. */ -NORETURN void (*error_hook) (void) ATTR_NORETURN; - - -/* One should use catch_errors rather than manipulating these - directly. */ -#if defined(HAVE_SIGSETJMP) -#define SIGJMP_BUF sigjmp_buf -#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) -#endif - -/* Where to go for return_to_top_level. */ -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) -{ - quit_flag = 0; - immediate_quit = 0; - - /* Perhaps it would be cleaner to do this via the cleanup chain (not sure - I can think of a reason why that is vital, though). */ - bpstat_clear_actions (stop_bpstat); /* Clear queued breakpoint commands */ - - disable_current_display (); - do_cleanups (ALL_CLEANUPS); - if (event_loop_p && target_can_async_p () && !target_executing) - do_exec_cleanups (ALL_CLEANUPS); - if (event_loop_p && sync_execution) - do_exec_error_cleanups (ALL_CLEANUPS); - - if (annotation_level > 1) - switch (reason) - { - case RETURN_QUIT: - annotate_quit (); - break; - case RETURN_ERROR: - annotate_error (); - break; - } - - /* Jump to the containing catch_errors() call, communicating REASON - to that call via setjmp's return value. Note that REASON can't - be zero, by definition in defs.h. */ - - (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. - - 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). - This is an OK restriction; with very few exceptions immediate_quit can - be replaced by judicious use of QUIT. - - MASK specifies what to catch; it is normally set to - RETURN_MASK_ALL, if for no other reason than that the code which - calls catch_errors might not be set up to deal with a quit which - isn't caught. But if the code can deal with it, it generally - should be RETURN_MASK_ERROR, unless for some reason it is more - useful to abort only the portion of the operation inside the - catch_errors. Note that quit should return to the command line - fairly quickly, even if some further processing is being done. */ - -/* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with - error() et.al. could maintain a set of flags that indicate the the - current state of each of the longjmp buffers. This would give the - longjmp code the chance to detect a longjmp botch (before it gets - to longjmperror()). Prior to 1999-11-05 this wasn't possible as - code also randomly used a SET_TOP_LEVEL macro that directly - initialize the longjmp buffers. */ - -/* MAYBE: cagney/1999-11-05: Should the catch_errors and cleanups code - 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) -{ - SIGJMP_BUF *saved_catch; - SIGJMP_BUF catch; - int val; - struct cleanup *saved_cleanup_chain; - char *saved_error_pre_print; - char *saved_quit_pre_print; - - /* Return value from SIGSETJMP(): enum return_reason if error or - quit caught, 0 otherwise. */ - int caught; - - /* Override error/quit messages during FUNC. */ - - saved_error_pre_print = error_pre_print; - saved_quit_pre_print = quit_pre_print; - - if (mask & RETURN_MASK_ERROR) - error_pre_print = errstring; - if (mask & RETURN_MASK_QUIT) - quit_pre_print = errstring; - - /* Prevent error/quit during FUNC from calling cleanups established - prior to here. */ - - saved_cleanup_chain = save_cleanups (); - - /* Call FUNC, catching error/quit events. */ - - saved_catch = catch_return; - catch_return = &catch; - caught = SIGSETJMP (catch); - if (!caught) - val = (*func) (args); - else - val = 0; - catch_return = saved_catch; - - /* FIXME: cagney/1999-11-05: A correct FUNC implementation will - clean things up (restoring the cleanup chain) to the state they - were just prior to the call. Unfortunately, many FUNC's are not - that well behaved. This could be fixed by adding either a - 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_cleanups (saved_cleanup_chain); - - 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. */ - - if (!caught) - return val; - - /* If 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. - - A possible fix is to add a new interface, catch_event(), that - returns enum return_reason after catching an error or a quit. - - 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. - - 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. */ - - return 0; -} - -struct captured_command_args - { - catch_command_errors_ftype *command; - char *arg; - int from_tty; - }; - -static int -do_captured_command (void *data) -{ - struct captured_command_args *context = data; - context->command (context->arg, context->from_tty); - /* FIXME: cagney/1999-11-07: Technically this do_cleanups() call - isn't needed. Instead an assertion check could be made that - simply confirmed that the called function correctly cleaned up - after itself. Unfortunately, old code (prior to 1999-11-04) in - main.c was calling SET_TOP_LEVEL(), calling the command function, - and then *always* calling do_cleanups(). For the moment we - remain ``bug compatible'' with that old code.. */ - do_cleanups (ALL_CLEANUPS); - return 1; -} - -int -catch_command_errors (catch_command_errors_ftype * command, - char *arg, int from_tty, return_mask mask) -{ - struct captured_command_args args; - args.command = command; - args.arg = arg; - args.from_tty = from_tty; - return catch_errors (do_captured_command, &args, "", mask); -} - +void (*deprecated_error_hook) (void); /* 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. */ @@ -612,21 +338,6 @@ quit_cover (PTR s) event-top.c into this file, top.c */ /* static */ char *source_file_name; -/* Buffer containing the error_pre_print used by the source stuff. - Malloc'd. */ -/* NOTE 1999-04-29: This variable 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 */ char *source_error; -static int source_error_allocated; - -/* Something to glom on to the start of error_pre_print if source_file_name - is set. */ -/* NOTE 1999-04-29: This variable 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 */ char *source_pre_error; - /* Clean up on error during a "source" command (or execution of a user-defined command). */ @@ -649,8 +360,6 @@ read_command_file (FILE *stream) do_cleanups (cleanups); } -extern void init_proc (void); - void (*pre_init_ui_hook) (void); #ifdef __MSDOS__ @@ -662,79 +371,17 @@ 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. */ void execute_command (char *p, int from_tty) { - register struct cmd_list_element *c; - register enum language flang; + struct cmd_list_element *c; + 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 @@ -754,24 +401,36 @@ extern void serial_log_command (const char *); char *arg; line = p; + /* If trace-commands is set then this will print this command. */ + print_command_trace (p); + c = lookup_cmd (&p, cmdlist, "", 0, 1); /* If the target is running, we allow only a limited set of commands. */ - if (event_loop_p && target_can_async_p () && target_executing) - if (!strcmp (c->name, "help") - && !strcmp (c->name, "pwd") - && !strcmp (c->name, "show") - && !strcmp (c->name, "stop")) - error ("Cannot execute this command while the target is running."); + if (target_can_async_p () && target_executing) + if (strcmp (c->name, "help") != 0 + && strcmp (c->name, "pwd") != 0 + && strcmp (c->name, "show") != 0 + && strcmp (c->name, "stop") != 0) + error (_("Cannot execute this command while the target is running.")); /* 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 +439,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 +448,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) - error ("That is not a command, just a help topic."); - else if (call_command_hook) - call_command_hook (c, arg, from_tty & caution); + else if (!cmd_func_p (c)) + error (_("That is not a command, just a help topic.")); + else if (deprecated_call_command_hook) + deprecated_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 +507,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 +515,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; @@ -893,10 +527,8 @@ command_loop (void) if (display_space) { #ifdef HAVE_SBRK - extern char **environ; char *lim = (char *) sbrk (0); - - space_at_cmd_start = (long) (lim - (char *) &environ); + space_at_cmd_start = lim - lim_at_start; #endif } @@ -909,19 +541,18 @@ command_loop (void) { long cmd_time = get_run_time () - time_at_cmd_start; - printf_unfiltered ("Command execution time: %ld.%06ld\n", + printf_unfiltered (_("Command execution time: %ld.%06ld\n"), cmd_time / 1000000, cmd_time % 1000000); } if (display_space) { #ifdef HAVE_SBRK - extern char **environ; char *lim = (char *) sbrk (0); - long space_now = lim - (char *) &environ; + long space_now = lim - lim_at_start; long space_diff = space_now - space_at_cmd_start; - printf_unfiltered ("Space used: %ld (%c%ld for this command)\n", + printf_unfiltered (_("Space used: %ld (%c%ld for this command)\n"), space_now, (space_diff >= 0 ? '+' : '-'), space_diff); @@ -1001,11 +632,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); } @@ -1029,15 +655,11 @@ gdb_readline (char *prompt_arg) } if (c == '\n') -#ifndef CRLF_SOURCE_FILES - break; -#else { if (input_index > 0 && result[input_index - 1] == '\r') input_index--; break; } -#endif result[input_index++] = c; while (input_index >= result_size) @@ -1055,32 +677,149 @@ gdb_readline (char *prompt_arg) substitution. These variables are given default values at the end of this file. */ static int command_editing_p; + /* NOTE 1999-04-29: This variable 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 history_expansion_p; + static int write_history_p; +static void +show_write_history_p (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("Saving of the history record on exit is %s.\n"), + value); +} + static int history_size; +static void +show_history_size (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("The size of the command history is %s.\n"), + value); +} + static char *history_filename; +static void +show_history_filename (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("\ +The filename in which to record the command history is \"%s\".\n"), + value); +} -/* Functions that are used as part of the fancy command line editing. */ +/* This is like readline(), but it has some gdb-specific behavior. + gdb may want 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 wants a synchronous response. + + We used to call readline() directly, running it in synchronous + mode. But mixing modes this way is not supported, and as of + readline 5.x it no longer works; the arrow keys come unbound during + the synchronous call. So we make a nested call into the event + loop. That's what gdb_readline_wrapper is for. */ + +/* A flag set as soon as gdb_readline_wrapper_line is called; we can't + rely on gdb_readline_wrapper_result, which might still be NULL if + the user types Control-D for EOF. */ +static int gdb_readline_wrapper_done; + +/* The result of the current call to gdb_readline_wrapper, once a newline + is seen. */ +static char *gdb_readline_wrapper_result; + +/* Any intercepted hook. Operate-and-get-next sets this, expecting it + to be called after the newline is processed (which will redisplay + the prompt). But in gdb_readline_wrapper we will not get a new + prompt until the next call, or until we return to the event loop. + So we disable this hook around the newline and restore it before we + return. */ +static void (*saved_after_char_processing_hook) (void); + +/* This function is called when readline has seen a complete line of + text. */ -/* 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) +static void +gdb_readline_wrapper_line (char *line) { - return NULL; + gdb_assert (!gdb_readline_wrapper_done); + gdb_readline_wrapper_result = line; + gdb_readline_wrapper_done = 1; + + /* Prevent operate-and-get-next from acting too early. */ + saved_after_char_processing_hook = after_char_processing_hook; + after_char_processing_hook = NULL; } -/* Line completion interface function for readline. */ +struct gdb_readline_wrapper_cleanup + { + void (*handler_orig) (char *); + char *prompt_orig; + int already_prompted_orig; + }; + +static void +gdb_readline_wrapper_cleanup (void *arg) +{ + struct gdb_readline_wrapper_cleanup *cleanup = arg; + + gdb_assert (rl_already_prompted == 1); + rl_already_prompted = cleanup->already_prompted_orig; + PROMPT (0) = cleanup->prompt_orig; + + gdb_assert (input_handler == gdb_readline_wrapper_line); + input_handler = cleanup->handler_orig; + gdb_readline_wrapper_result = NULL; + gdb_readline_wrapper_done = 0; -static char * -readline_line_completion_function (char *text, int matches) + after_char_processing_hook = saved_after_char_processing_hook; + saved_after_char_processing_hook = NULL; + + xfree (cleanup); +} + +char * +gdb_readline_wrapper (char *prompt) { - return line_completion_function (text, matches, rl_line_buffer, rl_point); + struct cleanup *back_to; + struct gdb_readline_wrapper_cleanup *cleanup; + char *retval; + + cleanup = xmalloc (sizeof (*cleanup)); + cleanup->handler_orig = input_handler; + input_handler = gdb_readline_wrapper_line; + + cleanup->prompt_orig = get_prompt (); + PROMPT (0) = prompt; + cleanup->already_prompted_orig = rl_already_prompted; + + back_to = make_cleanup (gdb_readline_wrapper_cleanup, cleanup); + + /* Display our prompt and prevent double prompt display. */ + display_gdb_prompt (NULL); + rl_already_prompted = 1; + + if (after_char_processing_hook) + (*after_char_processing_hook) (); + gdb_assert (after_char_processing_hook == NULL); + + /* gdb_do_one_event argument is unused. */ + while (gdb_do_one_event (NULL) >= 0) + if (gdb_readline_wrapper_done) + break; + + retval = gdb_readline_wrapper_result; + do_cleanups (back_to); + return retval; } + #ifdef STOP_SIGNAL static void @@ -1088,7 +827,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 +851,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) { @@ -1115,35 +872,55 @@ do_nothing (int signo) signal (signo, do_nothing); } +/* 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. */ static void -init_signals (void) +gdb_rl_operate_and_get_next_completion (void) { - signal (SIGINT, request_quit); + 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; - /* If SIGTRAP was set to SIG_IGN, then the SIG_IGN will get passed - to the inferior and breakpoints will be ignored. */ -#ifdef SIGTRAP - signal (SIGTRAP, SIG_DFL); -#endif + /* readline doesn't automatically update the display for us. */ + rl_redisplay (); - /* If we initialize SIGQUIT to SIG_IGN, then the SIG_IGN will get - passed to the inferior, which we don't want. It would be - possible to do a "signal (SIGQUIT, SIG_DFL)" after we fork, but - on BSD4.3 systems using vfork, that can affect the - GDB process as well as the inferior (the signal handling tables - might be in memory, shared between the two). Since we establish - a handler for SIGQUIT, when we call exec it will set the signal - to SIG_DFL for us. */ - signal (SIGQUIT, do_nothing); -#ifdef SIGHUP - if (signal (SIGHUP, do_nothing) != SIG_IGN) - signal (SIGHUP, disconnect); -#endif - signal (SIGFPE, float_handler); + after_char_processing_hook = NULL; + rl_pre_input_hook = NULL; +} -#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER) - signal (SIGWINCH, SIGWINCH_HANDLER); -#endif +/* 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; + + /* Use the async hook. */ + after_char_processing_hook = 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' @@ -1166,7 +943,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix) { static char *linebuffer = 0; static unsigned linelength = 0; - register char *p; + char *p; char *p1; char *rl; char *local_prompt = prompt_arg; @@ -1203,12 +980,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix) immediate_quit++; #ifdef STOP_SIGNAL if (job_control) - { - if (event_loop_p) - signal (STOP_SIGNAL, handle_stop_sig); - else - signal (STOP_SIGNAL, stop_sig); - } + signal (STOP_SIGNAL, handle_stop_sig); #endif while (1) @@ -1220,31 +992,23 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix) gdb_flush (gdb_stderr); if (source_file_name != NULL) - { - ++source_line_number; - sprintf (source_error, - "%s%s:%d: Error in sourced command file:\n", - source_pre_error, - source_file_name, - source_line_number); - error_pre_print = source_error; - } + ++source_line_number; if (annotation_level > 1 && instream == stdin) { - printf_unfiltered ("\n\032\032pre-"); - printf_unfiltered (annotation_suffix); - printf_unfiltered ("\n"); + puts_unfiltered ("\n\032\032pre-"); + puts_unfiltered (annotation_suffix); + puts_unfiltered ("\n"); } /* Don't use fancy stuff if not talking to stdin. */ - if (readline_hook && instream == NULL) + if (deprecated_readline_hook && input_from_terminal_p ()) { - rl = (*readline_hook) (local_prompt); + rl = (*deprecated_readline_hook) (local_prompt); } - else if (command_editing_p && instream == stdin && ISATTY (instream)) + else if (command_editing_p && input_from_terminal_p ()) { - rl = readline (local_prompt); + rl = gdb_readline_wrapper (local_prompt); } else { @@ -1253,9 +1017,9 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix) if (annotation_level > 1 && instream == stdin) { - printf_unfiltered ("\n\032\032post-"); - printf_unfiltered (annotation_suffix); - printf_unfiltered ("\n"); + puts_unfiltered ("\n\032\032post-"); + puts_unfiltered (annotation_suffix); + puts_unfiltered ("\n"); } if (!rl || rl == (char *) EOF) @@ -1297,7 +1061,7 @@ command_line_input (char *prompt_arg, int repeat, char *annotation_suffix) #define SERVER_COMMAND_LENGTH 7 server_command = (p - linebuffer > SERVER_COMMAND_LENGTH) - && STREQN (linebuffer, "server ", SERVER_COMMAND_LENGTH); + && strncmp (linebuffer, "server ", SERVER_COMMAND_LENGTH) == 0; if (server_command) { /* Note that we don't set `line'. Between this and the check in @@ -1386,16 +1150,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 (C) 2007 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 @@ -1411,7 +1170,7 @@ There is absolutely no warranty for GDB. Type \"show warranty\" for details.\n" /* After the required info we print the configuration information. */ fprintf_filtered (stream, "This GDB was configured as \""); - if (!STREQ (host_name, target_name)) + if (strcmp (host_name, target_name) != 0) { fprintf_filtered (stream, "--host=%s --target=%s", host_name, target_name); } @@ -1424,267 +1183,10 @@ There is absolutely no warranty for GDB. Type \"show warranty\" for details.\n" /* get_prompt: access method for the GDB prompt string. */ -#define MAX_PROMPT_SIZE 256 - -/* - * int get_prompt_1 (char * buf); - * - * Work-horse for get_prompt (called via catch_errors). - * Argument is buffer to hold the formatted prompt. - * - * Returns: 1 for success (use formatted prompt) - * 0 for failure (use gdb_prompt_string). - */ - -static int gdb_prompt_escape; - -static int -get_prompt_1 (void *data) -{ - char *formatted_prompt = data; - char *local_prompt; - - if (event_loop_p) - local_prompt = PROMPT (0); - else - local_prompt = gdb_prompt_string; - - - if (gdb_prompt_escape == 0) - { - return 0; /* do no formatting */ - } - else - /* formatted prompt */ - { - char fmt[40], *promptp, *outp, *tmp; - value_ptr arg_val; - DOUBLEST doubleval; - LONGEST longval; - CORE_ADDR addrval; - - int i, len; - struct type *arg_type, *elt_type; - - promptp = local_prompt; - outp = formatted_prompt; - - while (*promptp != '\0') - { - int available = MAX_PROMPT_SIZE - (outp - formatted_prompt) - 1; - - if (*promptp != gdb_prompt_escape) - { - if (available >= 1) /* overflow protect */ - *outp++ = *promptp++; - } - else - { - /* GDB prompt string contains escape char. Parse for arg. - Two consecutive escape chars followed by arg followed by - a comma means to insert the arg using a default format. - Otherwise a printf format string may be included between - the two escape chars. eg: - %%foo, insert foo using default format - %2.2f%foo, insert foo using "%2.2f" format - A mismatch between the format string and the data type - of "foo" is an error (which we don't know how to protect - against). */ - - fmt[0] = '\0'; /* assume null format string */ - if (promptp[1] == gdb_prompt_escape) /* double esc char */ - { - promptp += 2; /* skip past two escape chars. */ - } - else - { - /* extract format string from between two esc chars */ - i = 0; - do - { - fmt[i++] = *promptp++; /* copy format string */ - } - while (i < sizeof (fmt) - 1 && - *promptp != gdb_prompt_escape && - *promptp != '\0'); - - if (*promptp != gdb_prompt_escape) - error ("Syntax error at prompt position %d", - promptp - local_prompt); - else - { - promptp++; /* skip second escape char */ - fmt[i++] = '\0'; /* terminate the format string */ - } - } - - arg_val = parse_to_comma_and_eval (&promptp); - if (*promptp == ',') - promptp++; /* skip past the comma */ - arg_type = check_typedef (VALUE_TYPE (arg_val)); - switch (TYPE_CODE (arg_type)) - { - case TYPE_CODE_ARRAY: - elt_type = check_typedef (TYPE_TARGET_TYPE (arg_type)); - if (TYPE_LENGTH (arg_type) > 0 && - TYPE_LENGTH (elt_type) == 1 && - TYPE_CODE (elt_type) == TYPE_CODE_INT) - { - int len = TYPE_LENGTH (arg_type); - - if (VALUE_LAZY (arg_val)) - value_fetch_lazy (arg_val); - tmp = VALUE_CONTENTS (arg_val); - - if (len > available) - len = available; /* overflow protect */ - - /* FIXME: how to protect GDB from crashing - from bad user-supplied format string? */ - if (fmt[0] != 0) - sprintf (outp, fmt, tmp); - else - strncpy (outp, tmp, len); - outp[len] = '\0'; - } - break; - case TYPE_CODE_PTR: - elt_type = check_typedef (TYPE_TARGET_TYPE (arg_type)); - addrval = value_as_pointer (arg_val); - - if (TYPE_LENGTH (elt_type) == 1 && - TYPE_CODE (elt_type) == TYPE_CODE_INT && - addrval != 0) - { - /* display it as a string */ - char *default_fmt = "%s"; - char *tmp; - int err = 0; - - /* Limiting the number of bytes that the following call - will read protects us from sprintf overflow later. */ - i = target_read_string (addrval, /* src */ - &tmp, /* dest */ - available, /* len */ - &err); - if (err) /* read failed */ - error ("%s on target_read", safe_strerror (err)); - - tmp[i] = '\0'; /* force-terminate string */ - /* FIXME: how to protect GDB from crashing - from bad user-supplied format string? */ - sprintf (outp, fmt[0] == 0 ? default_fmt : fmt, - tmp); - xfree (tmp); - } - else - { - /* display it as a pointer */ - char *default_fmt = "0x%x"; - - /* FIXME: how to protect GDB from crashing - from bad user-supplied format string? */ - if (available >= 16 /*? */ ) /* overflow protect */ - sprintf (outp, fmt[0] == 0 ? default_fmt : fmt, - (long) addrval); - } - break; - case TYPE_CODE_FLT: - { - char *default_fmt = "%g"; - - doubleval = value_as_double (arg_val); - /* FIXME: how to protect GDB from crashing - from bad user-supplied format string? */ - if (available >= 16 /*? */ ) /* overflow protect */ - sprintf (outp, fmt[0] == 0 ? default_fmt : fmt, - (double) doubleval); - break; - } - case TYPE_CODE_INT: - { - char *default_fmt = "%d"; - - longval = value_as_long (arg_val); - /* FIXME: how to protect GDB from crashing - from bad user-supplied format string? */ - if (available >= 16 /*? */ ) /* overflow protect */ - sprintf (outp, fmt[0] == 0 ? default_fmt : fmt, - (long) longval); - break; - } - case TYPE_CODE_BOOL: - { - /* no default format for bool */ - longval = value_as_long (arg_val); - if (available >= 8 /*? */ ) /* overflow protect */ - { - if (longval) - strcpy (outp, ""); - else - strcpy (outp, ""); - } - break; - } - case TYPE_CODE_ENUM: - { - /* no default format for enum */ - longval = value_as_long (arg_val); - len = TYPE_NFIELDS (arg_type); - /* find enum name if possible */ - for (i = 0; i < len; i++) - if (TYPE_FIELD_BITPOS (arg_type, i) == longval) - break; /* match -- end loop */ - - if (i < len) /* enum name found */ - { - char *name = TYPE_FIELD_NAME (arg_type, i); - - strncpy (outp, name, available); - /* in casel available < strlen (name), */ - outp[available] = '\0'; - } - else - { - if (available >= 16 /*? */ ) /* overflow protect */ - sprintf (outp, "%ld", (long) longval); - } - break; - } - case TYPE_CODE_VOID: - *outp = '\0'; - break; /* void type -- no output */ - default: - error ("bad data type at prompt position %d", - promptp - local_prompt); - break; - } - outp += strlen (outp); - } - } - *outp++ = '\0'; /* terminate prompt string */ - return 1; - } -} - char * get_prompt (void) { - static char buf[MAX_PROMPT_SIZE]; - - if (catch_errors (get_prompt_1, buf, "bad formatted prompt: ", - RETURN_MASK_ALL)) - { - return &buf[0]; /* successful formatted prompt */ - } - else - { - /* Prompt could not be formatted. */ - if (event_loop_p) - return PROMPT (0); - else - return gdb_prompt_string; - } + return PROMPT (0); } void @@ -1695,10 +1197,7 @@ set_prompt (char *s) if (prompt != NULL) xfree (prompt); */ - if (event_loop_p) - PROMPT (0) = savestring (s, strlen (s)); - else - gdb_prompt_string = savestring (s, strlen (s)); + PROMPT (0) = savestring (s, strlen (s)); } @@ -1708,53 +1207,50 @@ 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; /* This is something of a hack. But there's no reliable way to see if a GUI is running. The `use_windows' variable doesn't cut it. */ - if (init_ui_hook) + if (deprecated_init_ui_hook) s = "A debugging session is active.\nDo you still want to close the debugger?"; else if (attach_flag) s = "The program is running. Quit anyway (and detach it)? "; else s = "The program is running. Exit anyway? "; - if (!query (s)) + if (!query ("%s", s)) return 0; } return 1; } -/* Quit without asking for confirmation. */ +/* Helper routine for quit_force that requires error handling. */ -void -quit_force (char *args, int from_tty) +struct qt_args { - int exit_code = 0; + char *args; + int from_tty; +}; - /* An optional expression may be used to cause gdb to terminate with the - value of that expression. */ - if (args) - { - value_ptr val = parse_and_eval (args); - - exit_code = (int) value_as_long (val); - } +static int +quit_target (void *arg) +{ + struct qt_args *qt = (struct qt_args *)arg; - 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); + target_detach (qt->args, qt->from_tty); else - target_kill (); + target_kill (); } /* UDI wants this, to kill the TIP. */ - target_close (1); + target_close (¤t_target, 1); /* Save the history information if it is appropriate to do so. */ if (write_history_p && history_filename) @@ -1762,29 +1258,56 @@ 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 + return 0; +} + +/* Quit without asking for confirmation. */ + +void +quit_force (char *args, int from_tty) +{ + int exit_code = 0; + struct qt_args qt; + + /* An optional expression may be used to cause gdb to terminate with the + value of that expression. */ + if (args) + { + struct value *val = parse_and_eval (args); + + exit_code = (int) value_as_long (val); + } + else if (return_child_result) + exit_code = return_child_result_value; + + qt.args = args; + qt.from_tty = from_tty; + + /* We want to handle any quit errors and exit regardless. */ + catch_errors (quit_target, &qt, + "Quitting: ", RETURN_MASK_ALL); exit (exit_code); } -/* Returns whether GDB is running on a terminal and whether the user - desires that questions be asked of them on that terminal. */ +/* Returns whether GDB is running on a terminal and input is + currently coming from that terminal. */ int input_from_terminal_p (void) { - return gdb_has_a_terminal () && (instream == stdin) & caution; + if (gdb_has_a_terminal () && instream == stdin) + return 1; + + /* If INSTREAM is unset, and we are not in a user command, we + must be in Insight. That's like having a terminal, for our + purposes. */ + if (instream == NULL && !in_user_command) + return 1; + + return 0; } -/* ARGSUSED */ static void dont_repeat_command (char *ignored, int from_tty) { @@ -1810,8 +1333,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; @@ -1872,7 +1393,6 @@ extern HIST_ENTRY *history_get (int); } /* Called by do_setshow_command. */ -/* ARGSUSED */ static void set_history_size_command (char *args, int from_tty, struct cmd_list_element *c) { @@ -1883,19 +1403,17 @@ set_history_size_command (char *args, int from_tty, struct cmd_list_element *c) else { history_size = INT_MAX; - error ("History size must be non-negative"); + error (_("History size must be non-negative")); } } -/* ARGSUSED */ void set_history (char *args, int from_tty) { - printf_unfiltered ("\"set history\" must be followed by the name of a history subcommand.\n"); + printf_unfiltered (_("\"set history\" must be followed by the name of a history subcommand.\n")); help_list (sethistlist, "set history ", -1, gdb_stdout); } -/* ARGSUSED */ void show_history (char *args, int from_tty) { @@ -1905,7 +1423,6 @@ show_history (char *args, int from_tty) int info_verbose = 0; /* Default verbose msgs off */ /* Called by do_setshow_command. An elaborate joke. */ -/* ARGSUSED */ void set_verbose (char *args, int from_tty, struct cmd_list_element *c) { @@ -1926,15 +1443,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 @@ -1964,40 +1472,69 @@ init_history (void) that was read. */ #ifdef __MSDOS__ /* No leading dots in file names are allowed on MSDOS. */ - history_filename = concat (current_directory, "/_gdb_history", NULL); + history_filename = concat (current_directory, "/_gdb_history", + (char *)NULL); #else - history_filename = concat (current_directory, "/.gdb_history", NULL); + history_filename = concat (current_directory, "/.gdb_history", + (char *)NULL); #endif } read_history (history_filename); } +static void +show_new_async_prompt (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("Gdb's prompt is \"%s\".\n"), value); +} + +static void +show_async_command_editing_p (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("\ +Editing of command lines as they are typed is %s.\n"), + value); +} + +static void +show_annotation_level (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("Annotation_level is %s.\n"), value); +} + +static void +show_exec_done_display_p (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("\ +Notification of completion for asynchronous execution commands is %s.\n"), + value); +} static void init_main (void) { struct cmd_list_element *c; - /* If we are running the asynchronous version, - we initialize the prompts differently. */ - if (!event_loop_p) - { - gdb_prompt_string = savestring (DEFAULT_PROMPT, strlen (DEFAULT_PROMPT)); - } - else - { - /* initialize the prompt stack to a simple "(gdb) " prompt or to - whatever the DEFAULT_PROMPT is. */ - the_prompts.top = 0; - PREFIX (0) = ""; - PROMPT (0) = savestring (DEFAULT_PROMPT, strlen (DEFAULT_PROMPT)); - SUFFIX (0) = ""; - /* Set things up for annotation_level > 1, if the user ever decides - to use it. */ - async_annotation_suffix = "prompt"; - /* Set the variable associated with the setshow prompt command. */ - new_async_prompt = savestring (PROMPT (0), strlen (PROMPT (0))); - } - gdb_prompt_escape = 0; /* default to none. */ + /* initialize the prompt stack to a simple "(gdb) " prompt or to + whatever the DEFAULT_PROMPT is. */ + the_prompts.top = 0; + PREFIX (0) = ""; + PROMPT (0) = savestring (DEFAULT_PROMPT, strlen (DEFAULT_PROMPT)); + SUFFIX (0) = ""; + /* Set things up for annotation_level > 1, if the user ever decides + to use it. */ + 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); /* Set the important stuff up for command editing. */ command_editing_p = 1; @@ -2005,124 +1542,129 @@ init_main (void) write_history_p = 0; /* Setup important stuff for command line editing. */ - rl_completion_entry_function = (int (*)()) readline_line_completion_function; - rl_completer_word_break_characters = - get_gdb_completer_word_break_characters (); + rl_completion_entry_function = readline_line_completion_function; + rl_completer_word_break_characters = default_word_break_characters (); rl_completer_quote_characters = get_gdb_completer_quote_characters (); rl_readline_name = "gdb"; - - /* 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 - gdb. */ - if (!event_loop_p) - { - add_show_from_set - (add_set_cmd ("prompt", class_support, var_string, - (char *) &gdb_prompt_string, "Set gdb's prompt", - &setlist), - &showlist); - } - else - { - c = add_set_cmd ("prompt", class_support, var_string, - (char *) &new_async_prompt, "Set gdb's prompt", - &setlist); - add_show_from_set (c, &showlist); - c->function.sfunc = set_async_prompt; - } - - add_show_from_set - (add_set_cmd ("prompt-escape-char", class_support, var_zinteger, - (char *) &gdb_prompt_escape, - "Set escape character for formatting of gdb's prompt", - &setlist), - &showlist); - - add_com ("dont-repeat", class_support, dont_repeat_command, "Don't repeat this command.\n\ + rl_terminal_name = getenv ("TERM"); + + /* 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); + + add_setshow_string_cmd ("prompt", class_support, + &new_async_prompt, _("\ +Set gdb's prompt"), _("\ +Show gdb's prompt"), NULL, + set_async_prompt, + show_new_async_prompt, + &setlist, &showlist); + + add_com ("dont-repeat", class_support, dont_repeat_command, _("\ +Don't repeat this command.\n\ Primarily used inside of user-defined commands that should not be repeated when\n\ -hitting return."); +hitting return.")); - /* The set editing 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 gdb. */ - if (!event_loop_p) - { - add_show_from_set - (add_set_cmd ("editing", class_support, var_boolean, (char *) &command_editing_p, - "Set editing of command lines as they are typed.\n\ + add_setshow_boolean_cmd ("editing", class_support, + &async_command_editing_p, _("\ +Set editing of command lines as they are typed."), _("\ +Show editing of command lines as they are typed."), _("\ Use \"on\" to enable the editing, and \"off\" to disable it.\n\ Without an argument, command line editing is enabled. To edit, use\n\ -EMACS-like or VI-like commands like control-P or ESC.", &setlist), - &showlist); - } - else - { - c = add_set_cmd ("editing", class_support, var_boolean, (char *) &async_command_editing_p, - "Set editing of command lines as they are typed.\n\ -Use \"on\" to enable the editing, and \"off\" to disable it.\n\ -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; - } - - add_show_from_set - (add_set_cmd ("save", no_class, var_boolean, (char *) &write_history_p, - "Set saving of the history record on exit.\n\ +EMACS-like or VI-like commands like control-P or ESC."), + set_async_editing_command, + show_async_command_editing_p, + &setlist, &showlist); + + add_setshow_boolean_cmd ("save", no_class, &write_history_p, _("\ +Set saving of the history record on exit."), _("\ +Show saving of the history record on exit."), _("\ Use \"on\" to enable the saving, and \"off\" to disable it.\n\ -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\ -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; - - 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); - - add_show_from_set - (add_set_cmd ("confirm", class_support, var_boolean, - (char *) &caution, - "Set whether to confirm potentially dangerous operations.", - &setlist), - &showlist); - - /* The set annotate 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 - gdb. */ - if (!event_loop_p) - { - c = add_set_cmd ("annotate", class_obscure, var_zinteger, - (char *) &annotation_level, "Set annotation_level.\n\ -0 == normal; 1 == fullname (for use when running under emacs)\n\ -2 == output annotated suitably for use by programs that control GDB.", - &setlist); - c = add_show_from_set (c, &showlist); - } - else - { - c = add_set_cmd ("annotate", class_obscure, var_zinteger, - (char *) &annotation_level, "Set annotation_level.\n\ +Without an argument, saving is enabled."), + NULL, + show_write_history_p, + &sethistlist, &showhistlist); + + add_setshow_integer_cmd ("size", no_class, &history_size, _("\ +Set the size of the command history,"), _("\ +Show the size of the command history,"), _("\ +ie. the number of previous commands to keep a record of."), + set_history_size_command, + show_history_size, + &sethistlist, &showhistlist); + + add_setshow_filename_cmd ("filename", no_class, &history_filename, _("\ +Set the filename in which to record the command history"), _("\ +Show the filename in which to record the command history"), _("\ +(the list of previous commands of which a record is kept)."), + NULL, + show_history_filename, + &sethistlist, &showhistlist); + + add_setshow_boolean_cmd ("confirm", class_support, &caution, _("\ +Set whether to confirm potentially dangerous operations."), _("\ +Show whether to confirm potentially dangerous operations."), NULL, + NULL, + show_caution, + &setlist, &showlist); + + add_setshow_zinteger_cmd ("annotate", class_obscure, &annotation_level, _("\ +Set annotation_level."), _("\ +Show annotation_level."), _("\ 0 == normal; 1 == fullname (for use when running under emacs)\n\ -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; - } - if (event_loop_p) - { - add_show_from_set - (add_set_cmd ("exec-done-display", class_support, var_boolean, (char *) &exec_done_display_p, - "Set notification of completion for asynchronous execution commands.\n\ -Use \"on\" to enable the notification, and \"off\" to disable it.", &setlist), - &showlist); - } +2 == output annotated suitably for use by programs that control GDB."), + set_async_annotation_level, + show_annotation_level, + &setlist, &showlist); + + add_setshow_boolean_cmd ("exec-done-display", class_support, + &exec_done_display_p, _("\ +Set notification of completion for asynchronous execution commands."), _("\ +Show notification of completion for asynchronous execution commands."), _("\ +Use \"on\" to enable the notification, and \"off\" to disable it."), + NULL, + show_exec_done_display_p, + &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 */ + + initialize_stdin_serial (); + + async_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 + deprecated_init_ui_hook. */ + if (deprecated_init_ui_hook) + deprecated_init_ui_hook (argv0); }