diff options
-rw-r--r-- | gdb/ChangeLog | 35 | ||||
-rw-r--r-- | gdb/event-top.c | 277 | ||||
-rw-r--r-- | gdb/event-top.h | 52 | ||||
-rw-r--r-- | gdb/python/python.c | 2 | ||||
-rw-r--r-- | gdb/top.c | 124 | ||||
-rw-r--r-- | gdb/top.h | 22 |
6 files changed, 154 insertions, 358 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 80fc406..af56e35 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,38 @@ +2011-09-06 Pedro Alves <pedro@codesourcery.com> + + * event-top.h (MAXPROMPTS, struct prompts): Delete. + (set_async_annotation_level, set_async_prompt, pop_prompt) + (push_prompt, new_async_prompt): Delete declarations. + * top.h (get_prompt, set_prompt): Change prototype. + (get_prefix, set_prefix, get_suffix, set_suffix): Delete + declarations. + * top.c (command_loop): + (top_prompt): New global. + (get_prefix, set_prefix, get_suffix, ): Delete. + (get_prompt, set_prompt): Rewrite. + (show_new_async_prompt): Rename to ... + (show_prompt): ... this. + (init_main): Adjust. Don't handle --annotate=2 here. + * event-top.c (new_async_prompt): Delete. + (the_prompts): Delete. + (more_to_come): Make static. + (display_gdb_prompt): Use top_level_prompt() to compute the top + level prompt, and don't notify the before_prompt observers + directly here. Always trick readline into not trying to display + the prompt if sync_execution and displaying the primary prompt. + If displaying a local/secondary prompt, always show it, even if + sync_execution is set. + (change_annotation_level): Delete. + (top_level_prompt): New, based on change_annotation_level. + (push_prompt, pop_prompt): Delete. + (async_disable_stdin): No longer pushes prompt. + (command_line_handler): No longer pushes or pops prompt. If more + input is expected, call display_gdb_prompt with an explicit empty + prompt. + (async_stop_sig): Adjust. + (set_async_annotation_level, set_async_prompt): Delete. + * python/python.c (before_prompt_hook): Adjust. + 2011-09-05 Pedro Alves <pedro@codesourcery.com> PR cli/13110 diff --git a/gdb/event-top.c b/gdb/event-top.c index 09bd89f..ff2aefb 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -47,8 +47,8 @@ static void rl_callback_read_char_wrapper (gdb_client_data client_data); static void command_line_handler (char *rl); static void change_line_handler (void); -static void change_annotation_level (void); static void command_handler (char *command); +static char *top_level_prompt (void); /* Signal handlers. */ #ifdef SIGQUIT @@ -108,10 +108,6 @@ void (*call_readline) (gdb_client_data); loop as default engine, and event-top.c is merged into top.c. */ int async_command_editing_p; -/* This variable contains the new prompt that the user sets with the - set prompt command. */ -char *new_async_prompt; - /* This is the annotation suffix that will be used when the annotation_level is 2. */ char *async_annotation_suffix; @@ -124,11 +120,6 @@ int exec_done_display_p = 0; read commands from. */ int input_fd; -/* This is the prompt stack. Prompts will be pushed on the stack as - needed by the different 'kinds' of user inputs GDB is asking - for. See event-loop.h. */ -struct prompts the_prompts; - /* Signal handling variables. */ /* Each of these is a pointer to a function that the event loop will invoke if the corresponding signal has received. The real signal @@ -155,7 +146,7 @@ void *sigtstp_token; because each line of input is handled by a different call to command_line_handler, and normally there is no state retained between different calls. */ -int more_to_come = 0; +static int more_to_come = 0; struct readline_input_state { @@ -224,22 +215,28 @@ change_line_handler (void) } } -/* Displays the prompt. The prompt that is displayed is the current - top of the prompt stack, if the argument NEW_PROMPT is - 0. Otherwise, it displays whatever NEW_PROMPT is. This is used - after each gdb command has completed, and in the following cases: +/* Displays the prompt. If the argument NEW_PROMPT is NULL, the + prompt that is displayed is the current top level prompt. + Otherwise, it displays whatever NEW_PROMPT is as a local/secondary + prompt. + + This is used after each gdb command has completed, and in the + following cases: + 1. When the user enters a command line which is ended by '\' - indicating that the command will continue on the next line. - In that case the prompt that is displayed is the empty string. + indicating that the command will continue on the next line. In + that case the prompt that is displayed is the empty string. + 2. When the user is entering 'commands' for a breakpoint, or actions for a tracepoint. In this case the prompt will be '>' - 3. Other???? - FIXME: 2. & 3. not implemented yet for async. */ + + 3. On prompting for pagination. */ + void display_gdb_prompt (char *new_prompt) { - int prompt_length = 0; char *actual_gdb_prompt = NULL; + struct cleanup *old_chain; /* Reset the nesting depth used when trace-commands is set. */ reset_command_nest_depth (); @@ -249,77 +246,42 @@ display_gdb_prompt (char *new_prompt) if (!current_interp_display_prompt_p ()) return; - /* Get the prompt before the observers are called as observer hook - functions may change the prompt. Do not call observers on an - explicit prompt change as passed to this function, as this forms - a temporary prompt, IE, displayed but not set. Do not call - observers for a prompt change if sync_execution is set, it will - call us again with sync_execution not set when it wants to - display an actual prompt. */ - if (! sync_execution && ! new_prompt) - { - char *post_gdb_prompt = NULL; - char *pre_gdb_prompt = xstrdup (get_prompt (0)); - - observer_notify_before_prompt (pre_gdb_prompt); - post_gdb_prompt = get_prompt (0); + old_chain = make_cleanup (free_current_contents, &actual_gdb_prompt); - /* If the observer changed the prompt, use that prompt. */ - if (strcmp (pre_gdb_prompt, post_gdb_prompt) != 0) - actual_gdb_prompt = post_gdb_prompt; - - xfree (pre_gdb_prompt); - } - - /* In the sync_execution && !is_running case we need to display the prompt - even though it may be "" to avoid a double prompt, while installing the - callback handlers, in the async_editing_p case for pagination, - So fall through. */ - if (sync_execution && is_running (inferior_ptid)) + /* Do not call the python hook on an explicit prompt change as + passed to this function, as this forms a secondary/local prompt, + IE, displayed but not set. */ + if (! new_prompt) { - /* This is to trick readline into not trying to display the - prompt. Even though we display the prompt using this - function, readline still tries to do its own display if we - don't call rl_callback_handler_install and - rl_callback_handler_remove (which readline detects because a - global variable is not set). If readline did that, it could - mess up gdb signal handlers for SIGINT. Readline assumes - that between calls to rl_set_signals and rl_clear_signals gdb - doesn't do anything with the signal handlers. Well, that's - not the case, because when the target executes we change the - SIGINT signal handler. If we allowed readline to display the - prompt, the signal handler change would happen exactly - between the calls to the above two functions. - Calling rl_callback_handler_remove(), does the job. */ - - rl_callback_handler_remove (); - return; - } - - /* If the observer changed the prompt, ACTUAL_GDB_PROMPT will not be - NULL. Otherwise, either copy the existing prompt, or set it to - NEW_PROMPT. */ - if (! actual_gdb_prompt) - { - if (! new_prompt) + if (sync_execution) { - /* Just use the top of the prompt stack. */ - prompt_length = strlen (get_prefix (0)) + - strlen (get_suffix (0)) + - strlen (get_prompt (0)) + 1; - - actual_gdb_prompt = (char *) alloca (prompt_length); - - /* Prefix needs to have new line at end. */ - strcpy (actual_gdb_prompt, get_prefix (0)); - strcat (actual_gdb_prompt, get_prompt (0)); - /* Suffix needs to have a new line at end and \032 \032 at - beginning. */ - strcat (actual_gdb_prompt, get_suffix (0)); + /* This is to trick readline into not trying to display the + prompt. Even though we display the prompt using this + function, readline still tries to do its own display if + we don't call rl_callback_handler_install and + rl_callback_handler_remove (which readline detects + because a global variable is not set). If readline did + that, it could mess up gdb signal handlers for SIGINT. + Readline assumes that between calls to rl_set_signals and + rl_clear_signals gdb doesn't do anything with the signal + handlers. Well, that's not the case, because when the + target executes we change the SIGINT signal handler. If + we allowed readline to display the prompt, the signal + handler change would happen exactly between the calls to + the above two functions. Calling + rl_callback_handler_remove(), does the job. */ + + rl_callback_handler_remove (); + return; } else - actual_gdb_prompt = new_prompt;; + { + /* Display the top level prompt. */ + actual_gdb_prompt = top_level_prompt (); + } } + else + actual_gdb_prompt = xstrdup (new_prompt); if (async_command_editing_p) { @@ -336,94 +298,61 @@ display_gdb_prompt (char *new_prompt) fputs_unfiltered (actual_gdb_prompt, gdb_stdout); gdb_flush (gdb_stdout); } + + do_cleanups (old_chain); } -/* Used when the user requests a different annotation level, with - 'set annotate'. It pushes a new prompt (with prefix and suffix) on top - of the prompt stack, if the annotation level desired is 2, otherwise - it pops the top of the prompt stack when we want the annotation level - to be the normal ones (1 or 0). */ -static void -change_annotation_level (void) +/* Return the top level prompt, as specified by "set prompt", possibly + overriden by the python gdb.prompt_hook hook, and then composed + with the prompt prefix and suffix (annotations). The caller is + responsible for freeing the returned string. */ + +static char * +top_level_prompt (void) { - char *prefix, *suffix; + char *prefix; + char *prompt = NULL; + char *suffix; + char *composed_prompt; + size_t prompt_length; - if (!get_prefix (0) || !get_prompt (0) || !get_suffix (0)) - { - /* The prompt stack has not been initialized to "", we are - using gdb w/o the --async switch. */ - warning (_("Command has same effect as set annotate")); - return; - } + /* Give observers a chance of changing the prompt. E.g., the python + `gdb.prompt_hook' is installed as an observer. */ + observer_notify_before_prompt (get_prompt ()); + + prompt = xstrdup (get_prompt ()); - if (annotation_level > 1) + if (annotation_level >= 2) { - if (!strcmp (get_prefix (0), "") && !strcmp (get_suffix (0), "")) - { - /* Push a new prompt if the previous annotation_level was not >1. */ - prefix = (char *) alloca (strlen (async_annotation_suffix) + 10); - strcpy (prefix, "\n\032\032pre-"); - strcat (prefix, async_annotation_suffix); - strcat (prefix, "\n"); - - suffix = (char *) alloca (strlen (async_annotation_suffix) + 6); - strcpy (suffix, "\n\032\032"); - strcat (suffix, async_annotation_suffix); - strcat (suffix, "\n"); - - push_prompt (prefix, (char *) 0, suffix); - } + /* Prefix needs to have new line at end. */ + prefix = (char *) alloca (strlen (async_annotation_suffix) + 10); + strcpy (prefix, "\n\032\032pre-"); + strcat (prefix, async_annotation_suffix); + strcat (prefix, "\n"); + + /* Suffix needs to have a new line at end and \032 \032 at + beginning. */ + suffix = (char *) alloca (strlen (async_annotation_suffix) + 6); + strcpy (suffix, "\n\032\032"); + strcat (suffix, async_annotation_suffix); + strcat (suffix, "\n"); } else { - if (strcmp (get_prefix (0), "") && strcmp (get_suffix (0), "")) - { - /* Pop the top of the stack, we are going back to annotation < 1. */ - pop_prompt (); - } + prefix = ""; + suffix = ""; } -} -/* Pushes a new prompt on the prompt stack. Each prompt has three - parts: prefix, prompt, suffix. Usually prefix and suffix are empty - strings, except when the annotation level is 2. Memory is allocated - within xstrdup for the new prompt. */ -void -push_prompt (char *prefix, char *prompt, char *suffix) -{ - the_prompts.top++; - set_prefix (prefix, 0); - - /* Note that this function is used by the set annotate 2 - command. This is why we take care of saving the old prompt - in case a new one is not specified. */ - if (prompt) - set_prompt (prompt, 0); - else - set_prompt (get_prompt (-1), 0); + prompt_length = strlen (prefix) + strlen (prompt) + strlen (suffix); + composed_prompt = xmalloc (prompt_length + 1); - set_suffix (suffix, 0); -} + strcpy (composed_prompt, prefix); + strcat (composed_prompt, prompt); + strcat (composed_prompt, suffix); -/* Pops the top of the prompt stack, and frees the memory allocated - for it. */ -void -pop_prompt (void) -{ - /* If we are not during a 'synchronous' execution command, in which - case, the top prompt would be empty. */ - if (strcmp (get_prompt (0), "")) - /* This is for the case in which the prompt is set while the - annotation level is 2. The top prompt will be changed, but when - we return to annotation level < 2, we want that new prompt to be - in effect, until the user does another 'set prompt'. */ - if (strcmp (get_prompt (0), get_prompt (-1))) - set_prompt (get_prompt (0), -1); - - set_prefix (NULL, 0); - set_prompt (NULL, 0); - set_suffix (NULL, 0); - the_prompts.top--; + xfree (prompt); + + return composed_prompt; } /* When there is an event ready on the stdin file desriptor, instead @@ -460,7 +389,6 @@ async_enable_stdin (void) sync_execution. Current target_terminal_ours() implementations check for sync_execution before switching the terminal. */ target_terminal_ours (); - pop_prompt (); sync_execution = 0; } } @@ -471,11 +399,7 @@ async_enable_stdin (void) void async_disable_stdin (void) { - if (!sync_execution) - { - sync_execution = 1; - push_prompt ("", "", ""); - } + sync_execution = 1; } @@ -558,7 +482,6 @@ command_line_handler (char *rl) p = readline_input_state.linebuffer_ptr; xfree (readline_input_state.linebuffer); more_to_come = 0; - pop_prompt (); } #ifdef STOP_SIGNAL @@ -611,8 +534,7 @@ command_line_handler (char *rl) input expected to complete the command. So, we need to print an empty prompt here. */ more_to_come = 1; - push_prompt ("", "", ""); - display_gdb_prompt (0); + display_gdb_prompt (""); return; } @@ -967,7 +889,7 @@ handle_stop_sig (int sig) static void async_stop_sig (gdb_client_data arg) { - char *prompt = get_prompt (0); + char *prompt = get_prompt (); #if STOP_SIGNAL == SIGTSTP signal (SIGTSTP, SIG_DFL); @@ -1033,21 +955,6 @@ set_async_editing_command (char *args, int from_tty, change_line_handler (); } -/* Called by do_setshow_command. */ -void -set_async_annotation_level (char *args, int from_tty, - struct cmd_list_element *c) -{ - change_annotation_level (); -} - -/* Called by do_setshow_command. */ -void -set_async_prompt (char *args, int from_tty, struct cmd_list_element *c) -{ - set_prompt (new_async_prompt, 0); -} - /* Set things up for readline to be invoked via the alternate interface, i.e. via a callback function (rl_callback_read_char), and hook up instream to the event loop. */ diff --git a/gdb/event-top.h b/gdb/event-top.h index 952abdb..1274787 100644 --- a/gdb/event-top.h +++ b/gdb/event-top.h @@ -25,51 +25,6 @@ struct cmd_list_element; -/* Stack for prompts. Each prompt is composed as a prefix, a prompt - and a suffix. The prompt to be displayed at any given time is the - one on top of the stack. A stack is necessary because of cases in - which the execution of a gdb command requires further input from - the user, like for instance 'commands' for breakpoints and - 'actions' for tracepoints. In these cases, the prompt is '>' and - gdb should process input using the asynchronous readline interface - and the event loop. In order to achieve this, we need to save - somewhere the state of GDB, i.e. that it is processing user input - as part of a command and not as part of the top level command loop. - The prompt stack represents part of the saved state. Another part - would be the function that readline would invoke after a whole line - of input has ben entered. This second piece would be something - like, for instance, where to return within the code for the actions - commands after a line has been read. This latter portion has not - beeen implemented yet. The need for a 3-part prompt arises from - the annotation level. When this is set to 2, the prompt is - actually composed of a prefix, the prompt itself and a suffix. */ - -/* At any particular time there will be always at least one prompt on - the stack, the one being currently displayed by gdb. If gdb is - using annotation level equal 2, there will be 2 prompts on the - stack: the usual one, w/o prefix and suffix (at top - 1), and the - 'composite' one with prefix and suffix added (at top). At this - time, this is the only use of the prompt stack. Resetting annotate - to 0 or 1, pops the top of the stack, resetting its size to one - element. The MAXPROMPTS limit is safe, for now. Once other cases - are dealt with (like the different prompts used for 'commands' or - 'actions') this array implementation of the prompt stack may have - to change. */ - -#define MAXPROMPTS 10 -struct prompts - { - struct - { - char *prefix; - char *prompt; - char *suffix; - } - prompt_stack[MAXPROMPTS]; - int top; - }; - - /* Exported functions from event-top.c. FIXME: these should really go into top.h. */ @@ -79,10 +34,6 @@ void gdb_disable_readline (void); extern void async_init_signals (void); extern void set_async_editing_command (char *args, int from_tty, struct cmd_list_element *c); -extern void set_async_annotation_level (char *args, int from_tty, - struct cmd_list_element *c); -extern void set_async_prompt (char *args, int from_tty, - struct cmd_list_element *c); /* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT. */ #ifndef STOP_SIGNAL @@ -94,8 +45,6 @@ extern void handle_stop_sig (int sig); #endif extern void handle_sigint (int sig); extern void handle_sigterm (int sig); -extern void pop_prompt (void); -extern void push_prompt (char *prefix, char *prompt, char *suffix); extern void gdb_readline2 (void *client_data); extern void mark_async_signal_handler_wrapper (void *token); extern void async_request_quit (void *arg); @@ -109,7 +58,6 @@ extern void async_enable_stdin (void); extern int async_command_editing_p; extern int exec_done_display_p; extern char *async_annotation_suffix; -extern char *new_async_prompt; extern struct prompts the_prompts; extern void (*call_readline) (void *); extern void (*input_handler) (char *); diff --git a/gdb/python/python.c b/gdb/python/python.c index 360bed4..0f702a2 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -753,7 +753,7 @@ before_prompt_hook (const char *current_gdb_prompt) /* If a prompt has been set, PROMPT will not be NULL. If it is NULL, do not set the prompt. */ if (prompt != NULL) - set_prompt (prompt, 0); + set_prompt (prompt); do_cleanups (cleanup); return; @@ -554,7 +554,7 @@ command_loop (void) while (instream && !feof (instream)) { if (window_hook && instream == stdin) - (*window_hook) (instream, get_prompt (0)); + (*window_hook) (instream, get_prompt ()); quit_flag = 0; if (instream == stdin && stdin_is_tty) @@ -563,7 +563,7 @@ command_loop (void) /* Get a command-line. This calls the readline package. */ command = command_line_input (instream == stdin ? - get_prompt (0) : (char *) NULL, + get_prompt () : (char *) NULL, instream == stdin, "prompt"); if (command == 0) { @@ -1145,97 +1145,27 @@ and \"show warranty\" for details.\n"); } -/* get_prefix: access method for the GDB prefix string. */ +/* The current top level prompt, settable with "set prompt", and/or + with the python `gdb.prompt_hook' hook. */ +static char *top_prompt; -char * -get_prefix (int level) -{ - return PREFIX (level); -} - -/* set_prefix: set method for the GDB prefix string. */ - -void -set_prefix (const char *s, int level) -{ - /* If S is NULL, just free the PREFIX at level LEVEL and set to - NULL. */ - if (s == NULL) - { - xfree (PREFIX (level)); - PREFIX (level) = NULL; - } - else - { - char *p = xstrdup (s); - - xfree (PREFIX (level)); - PREFIX (level) = p; - } -} - -/* get_suffix: access method for the GDB suffix string. */ +/* Access method for the GDB prompt string. */ char * -get_suffix (int level) -{ - return SUFFIX (level); -} - -/* set_suffix: set method for the GDB suffix string. */ - -void -set_suffix (const char *s, int level) +get_prompt (void) { - /* If S is NULL, just free the SUFFIX at level LEVEL and set to - NULL. */ - if (s == NULL) - { - xfree (SUFFIX (level)); - SUFFIX (level) = NULL; - } - else - { - char *p = xstrdup (s); - - xfree (SUFFIX (level)); - SUFFIX (level) = p; - } + return top_prompt; } - /* get_prompt: access method for the GDB prompt string. */ - -char * -get_prompt (int level) -{ - return PROMPT (level); -} +/* Set method for the GDB prompt string. */ void -set_prompt (const char *s, int level) +set_prompt (const char *s) { - /* If S is NULL, just free the PROMPT at level LEVEL and set to - NULL. */ - if (s == NULL) - { - xfree (PROMPT (level)); - PROMPT (level) = NULL; - } - else - { - char *p = xstrdup (s); - - xfree (PROMPT (0)); - PROMPT (0) = p; + char *p = xstrdup (s); - if (level == 0) - { - /* Also, free and set new_async_prompt so prompt changes sync up - with set/show prompt. */ - xfree (new_async_prompt); - new_async_prompt = xstrdup (PROMPT (0)); - } - } + xfree (top_prompt); + top_prompt = p; } @@ -1589,8 +1519,8 @@ init_history (void) } static void -show_new_async_prompt (struct ui_file *file, int from_tty, - struct cmd_list_element *c, const char *value) +show_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); } @@ -1622,22 +1552,14 @@ show_exec_done_display_p (struct ui_file *file, int from_tty, static void init_main (void) { - /* initialize the prompt stack to a simple "(gdb) " prompt or to - whatever the DEFAULT_PROMPT is. */ - the_prompts.top = 0; - PREFIX (0) = ""; - set_prompt (DEFAULT_PROMPT, 0); - SUFFIX (0) = ""; + /* Initialize the prompt to a simple "(gdb) " prompt or to whatever + the DEFAULT_PROMPT is. */ + set_prompt (DEFAULT_PROMPT); + /* Set things up for annotation_level > 1, if the user ever decides to use it. */ async_annotation_suffix = "prompt"; - /* 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; history_expansion_p = 0; @@ -1656,11 +1578,11 @@ init_main (void) rl_add_defun ("operate-and-get-next", gdb_rl_operate_and_get_next, 15); add_setshow_string_cmd ("prompt", class_support, - &new_async_prompt, + &top_prompt, _("Set gdb's prompt"), _("Show gdb's prompt"), - NULL, set_async_prompt, - show_new_async_prompt, + NULL, NULL, + show_prompt, &setlist, &showlist); add_com ("dont-repeat", class_support, dont_repeat_command, _("\ @@ -1716,7 +1638,7 @@ 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."), - set_async_annotation_level, + NULL, show_annotation_level, &setlist, &showlist); @@ -51,27 +51,11 @@ extern struct cleanup *prepare_execute_command (void); /* This function returns a pointer to the string that is used by gdb for its command prompt. */ -extern char *get_prompt (int); - -/* This function copies the specified string into the string that - is used by gdb for its command prompt. */ -extern void set_prompt (const char *, int level); - -/* This function returns a pointer to the string that is used - by gdb for its command prompt prefix. */ -extern char *get_prefix (int); - -/* This function copies the specified string into the string that - is used by gdb for its command prompt prefix. */ -extern void set_prefix (const char *, int); +extern char *get_prompt (void); /* This function returns a pointer to the string that is used - by gdb for its command prompt suffix. */ -extern char *get_suffix (int); - -/* This function copies the specified string into the string that - is used by gdb for its command prompt suffix. */ -extern void set_suffix (const char *, int); + by gdb for its command prompt. */ +extern void set_prompt (const char *s); /* From random places. */ extern int readnow_symbol_files; |