diff options
author | Pedro Alves <palves@redhat.com> | 2011-09-06 14:49:00 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2011-09-06 14:49:00 +0000 |
commit | ab821bc6473fe7fa3982d77a837cd5913a35d6f2 (patch) | |
tree | e0a4fe3cd8df39b8a352564cdb750b179a3426bc /gdb/event-top.c | |
parent | b140b0101b2641e96c39ce022cd79fe7db3b7322 (diff) | |
download | gdb-ab821bc6473fe7fa3982d77a837cd5913a35d6f2.zip gdb-ab821bc6473fe7fa3982d77a837cd5913a35d6f2.tar.gz gdb-ab821bc6473fe7fa3982d77a837cd5913a35d6f2.tar.bz2 |
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.
Diffstat (limited to 'gdb/event-top.c')
-rw-r--r-- | gdb/event-top.c | 277 |
1 files changed, 92 insertions, 185 deletions
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. */ |