mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 12:03:41 +08:00
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.
This commit is contained in:
parent
b140b0101b
commit
ab821bc647
@ -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>
|
2011-09-05 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
PR cli/13110
|
PR cli/13110
|
||||||
|
275
gdb/event-top.c
275
gdb/event-top.c
@ -47,8 +47,8 @@
|
|||||||
static void rl_callback_read_char_wrapper (gdb_client_data client_data);
|
static void rl_callback_read_char_wrapper (gdb_client_data client_data);
|
||||||
static void command_line_handler (char *rl);
|
static void command_line_handler (char *rl);
|
||||||
static void change_line_handler (void);
|
static void change_line_handler (void);
|
||||||
static void change_annotation_level (void);
|
|
||||||
static void command_handler (char *command);
|
static void command_handler (char *command);
|
||||||
|
static char *top_level_prompt (void);
|
||||||
|
|
||||||
/* Signal handlers. */
|
/* Signal handlers. */
|
||||||
#ifdef SIGQUIT
|
#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. */
|
loop as default engine, and event-top.c is merged into top.c. */
|
||||||
int async_command_editing_p;
|
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
|
/* This is the annotation suffix that will be used when the
|
||||||
annotation_level is 2. */
|
annotation_level is 2. */
|
||||||
char *async_annotation_suffix;
|
char *async_annotation_suffix;
|
||||||
@ -124,11 +120,6 @@ int exec_done_display_p = 0;
|
|||||||
read commands from. */
|
read commands from. */
|
||||||
int input_fd;
|
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. */
|
/* Signal handling variables. */
|
||||||
/* Each of these is a pointer to a function that the event loop will
|
/* Each of these is a pointer to a function that the event loop will
|
||||||
invoke if the corresponding signal has received. The real signal
|
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
|
because each line of input is handled by a different call to
|
||||||
command_line_handler, and normally there is no state retained
|
command_line_handler, and normally there is no state retained
|
||||||
between different calls. */
|
between different calls. */
|
||||||
int more_to_come = 0;
|
static int more_to_come = 0;
|
||||||
|
|
||||||
struct readline_input_state
|
struct readline_input_state
|
||||||
{
|
{
|
||||||
@ -224,22 +215,28 @@ change_line_handler (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Displays the prompt. The prompt that is displayed is the current
|
/* Displays the prompt. If the argument NEW_PROMPT is NULL, the
|
||||||
top of the prompt stack, if the argument NEW_PROMPT is
|
prompt that is displayed is the current top level prompt.
|
||||||
0. Otherwise, it displays whatever NEW_PROMPT is. This is used
|
Otherwise, it displays whatever NEW_PROMPT is as a local/secondary
|
||||||
after each gdb command has completed, and in the following cases:
|
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 '\'
|
1. When the user enters a command line which is ended by '\'
|
||||||
indicating that the command will continue on the next line.
|
indicating that the command will continue on the next line. In
|
||||||
In that case the prompt that is displayed is the empty string.
|
that case the prompt that is displayed is the empty string.
|
||||||
|
|
||||||
2. When the user is entering 'commands' for a breakpoint, or
|
2. When the user is entering 'commands' for a breakpoint, or
|
||||||
actions for a tracepoint. In this case the prompt will be '>'
|
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
|
void
|
||||||
display_gdb_prompt (char *new_prompt)
|
display_gdb_prompt (char *new_prompt)
|
||||||
{
|
{
|
||||||
int prompt_length = 0;
|
|
||||||
char *actual_gdb_prompt = NULL;
|
char *actual_gdb_prompt = NULL;
|
||||||
|
struct cleanup *old_chain;
|
||||||
|
|
||||||
/* Reset the nesting depth used when trace-commands is set. */
|
/* Reset the nesting depth used when trace-commands is set. */
|
||||||
reset_command_nest_depth ();
|
reset_command_nest_depth ();
|
||||||
@ -249,77 +246,42 @@ display_gdb_prompt (char *new_prompt)
|
|||||||
if (!current_interp_display_prompt_p ())
|
if (!current_interp_display_prompt_p ())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Get the prompt before the observers are called as observer hook
|
old_chain = make_cleanup (free_current_contents, &actual_gdb_prompt);
|
||||||
functions may change the prompt. Do not call observers on an
|
|
||||||
explicit prompt change as passed to this function, as this forms
|
/* Do not call the python hook on an explicit prompt change as
|
||||||
a temporary prompt, IE, displayed but not set. Do not call
|
passed to this function, as this forms a secondary/local prompt,
|
||||||
observers for a prompt change if sync_execution is set, it will
|
IE, displayed but not set. */
|
||||||
call us again with sync_execution not set when it wants to
|
if (! new_prompt)
|
||||||
display an actual prompt. */
|
|
||||||
if (! sync_execution && ! new_prompt)
|
|
||||||
{
|
{
|
||||||
char *post_gdb_prompt = NULL;
|
if (sync_execution)
|
||||||
char *pre_gdb_prompt = xstrdup (get_prompt (0));
|
|
||||||
|
|
||||||
observer_notify_before_prompt (pre_gdb_prompt);
|
|
||||||
post_gdb_prompt = get_prompt (0);
|
|
||||||
|
|
||||||
/* 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))
|
|
||||||
{
|
|
||||||
/* 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)
|
|
||||||
{
|
{
|
||||||
/* Just use the top of the prompt stack. */
|
/* This is to trick readline into not trying to display the
|
||||||
prompt_length = strlen (get_prefix (0)) +
|
prompt. Even though we display the prompt using this
|
||||||
strlen (get_suffix (0)) +
|
function, readline still tries to do its own display if
|
||||||
strlen (get_prompt (0)) + 1;
|
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. */
|
||||||
|
|
||||||
actual_gdb_prompt = (char *) alloca (prompt_length);
|
rl_callback_handler_remove ();
|
||||||
|
return;
|
||||||
/* 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));
|
|
||||||
}
|
}
|
||||||
else
|
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)
|
if (async_command_editing_p)
|
||||||
{
|
{
|
||||||
@ -336,94 +298,61 @@ display_gdb_prompt (char *new_prompt)
|
|||||||
fputs_unfiltered (actual_gdb_prompt, gdb_stdout);
|
fputs_unfiltered (actual_gdb_prompt, gdb_stdout);
|
||||||
gdb_flush (gdb_stdout);
|
gdb_flush (gdb_stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
do_cleanups (old_chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Used when the user requests a different annotation level, with
|
/* Return the top level prompt, as specified by "set prompt", possibly
|
||||||
'set annotate'. It pushes a new prompt (with prefix and suffix) on top
|
overriden by the python gdb.prompt_hook hook, and then composed
|
||||||
of the prompt stack, if the annotation level desired is 2, otherwise
|
with the prompt prefix and suffix (annotations). The caller is
|
||||||
it pops the top of the prompt stack when we want the annotation level
|
responsible for freeing the returned string. */
|
||||||
to be the normal ones (1 or 0). */
|
|
||||||
static void
|
static char *
|
||||||
change_annotation_level (void)
|
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))
|
/* 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 >= 2)
|
||||||
{
|
{
|
||||||
/* The prompt stack has not been initialized to "", we are
|
/* Prefix needs to have new line at end. */
|
||||||
using gdb w/o the --async switch. */
|
prefix = (char *) alloca (strlen (async_annotation_suffix) + 10);
|
||||||
warning (_("Command has same effect as set annotate"));
|
strcpy (prefix, "\n\032\032pre-");
|
||||||
return;
|
strcat (prefix, async_annotation_suffix);
|
||||||
}
|
strcat (prefix, "\n");
|
||||||
|
|
||||||
if (annotation_level > 1)
|
/* Suffix needs to have a new line at end and \032 \032 at
|
||||||
{
|
beginning. */
|
||||||
if (!strcmp (get_prefix (0), "") && !strcmp (get_suffix (0), ""))
|
suffix = (char *) alloca (strlen (async_annotation_suffix) + 6);
|
||||||
{
|
strcpy (suffix, "\n\032\032");
|
||||||
/* Push a new prompt if the previous annotation_level was not >1. */
|
strcat (suffix, async_annotation_suffix);
|
||||||
prefix = (char *) alloca (strlen (async_annotation_suffix) + 10);
|
strcat (suffix, "\n");
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (strcmp (get_prefix (0), "") && strcmp (get_suffix (0), ""))
|
prefix = "";
|
||||||
{
|
suffix = "";
|
||||||
/* Pop the top of the stack, we are going back to annotation < 1. */
|
|
||||||
pop_prompt ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Pushes a new prompt on the prompt stack. Each prompt has three
|
prompt_length = strlen (prefix) + strlen (prompt) + strlen (suffix);
|
||||||
parts: prefix, prompt, suffix. Usually prefix and suffix are empty
|
composed_prompt = xmalloc (prompt_length + 1);
|
||||||
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
|
strcpy (composed_prompt, prefix);
|
||||||
command. This is why we take care of saving the old prompt
|
strcat (composed_prompt, prompt);
|
||||||
in case a new one is not specified. */
|
strcat (composed_prompt, suffix);
|
||||||
if (prompt)
|
|
||||||
set_prompt (prompt, 0);
|
|
||||||
else
|
|
||||||
set_prompt (get_prompt (-1), 0);
|
|
||||||
|
|
||||||
set_suffix (suffix, 0);
|
xfree (prompt);
|
||||||
}
|
|
||||||
|
|
||||||
/* Pops the top of the prompt stack, and frees the memory allocated
|
return composed_prompt;
|
||||||
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--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* When there is an event ready on the stdin file desriptor, instead
|
/* 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
|
sync_execution. Current target_terminal_ours() implementations
|
||||||
check for sync_execution before switching the terminal. */
|
check for sync_execution before switching the terminal. */
|
||||||
target_terminal_ours ();
|
target_terminal_ours ();
|
||||||
pop_prompt ();
|
|
||||||
sync_execution = 0;
|
sync_execution = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -471,11 +399,7 @@ async_enable_stdin (void)
|
|||||||
void
|
void
|
||||||
async_disable_stdin (void)
|
async_disable_stdin (void)
|
||||||
{
|
{
|
||||||
if (!sync_execution)
|
sync_execution = 1;
|
||||||
{
|
|
||||||
sync_execution = 1;
|
|
||||||
push_prompt ("", "", "");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -558,7 +482,6 @@ command_line_handler (char *rl)
|
|||||||
p = readline_input_state.linebuffer_ptr;
|
p = readline_input_state.linebuffer_ptr;
|
||||||
xfree (readline_input_state.linebuffer);
|
xfree (readline_input_state.linebuffer);
|
||||||
more_to_come = 0;
|
more_to_come = 0;
|
||||||
pop_prompt ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef STOP_SIGNAL
|
#ifdef STOP_SIGNAL
|
||||||
@ -611,8 +534,7 @@ command_line_handler (char *rl)
|
|||||||
input expected to complete the command. So, we need to
|
input expected to complete the command. So, we need to
|
||||||
print an empty prompt here. */
|
print an empty prompt here. */
|
||||||
more_to_come = 1;
|
more_to_come = 1;
|
||||||
push_prompt ("", "", "");
|
display_gdb_prompt ("");
|
||||||
display_gdb_prompt (0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -967,7 +889,7 @@ handle_stop_sig (int sig)
|
|||||||
static void
|
static void
|
||||||
async_stop_sig (gdb_client_data arg)
|
async_stop_sig (gdb_client_data arg)
|
||||||
{
|
{
|
||||||
char *prompt = get_prompt (0);
|
char *prompt = get_prompt ();
|
||||||
|
|
||||||
#if STOP_SIGNAL == SIGTSTP
|
#if STOP_SIGNAL == SIGTSTP
|
||||||
signal (SIGTSTP, SIG_DFL);
|
signal (SIGTSTP, SIG_DFL);
|
||||||
@ -1033,21 +955,6 @@ set_async_editing_command (char *args, int from_tty,
|
|||||||
change_line_handler ();
|
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
|
/* Set things up for readline to be invoked via the alternate
|
||||||
interface, i.e. via a callback function (rl_callback_read_char),
|
interface, i.e. via a callback function (rl_callback_read_char),
|
||||||
and hook up instream to the event loop. */
|
and hook up instream to the event loop. */
|
||||||
|
@ -25,51 +25,6 @@
|
|||||||
|
|
||||||
struct cmd_list_element;
|
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.
|
/* Exported functions from event-top.c.
|
||||||
FIXME: these should really go into top.h. */
|
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 async_init_signals (void);
|
||||||
extern void set_async_editing_command (char *args, int from_tty,
|
extern void set_async_editing_command (char *args, int from_tty,
|
||||||
struct cmd_list_element *c);
|
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. */
|
/* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT. */
|
||||||
#ifndef STOP_SIGNAL
|
#ifndef STOP_SIGNAL
|
||||||
@ -94,8 +45,6 @@ extern void handle_stop_sig (int sig);
|
|||||||
#endif
|
#endif
|
||||||
extern void handle_sigint (int sig);
|
extern void handle_sigint (int sig);
|
||||||
extern void handle_sigterm (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 gdb_readline2 (void *client_data);
|
||||||
extern void mark_async_signal_handler_wrapper (void *token);
|
extern void mark_async_signal_handler_wrapper (void *token);
|
||||||
extern void async_request_quit (void *arg);
|
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 async_command_editing_p;
|
||||||
extern int exec_done_display_p;
|
extern int exec_done_display_p;
|
||||||
extern char *async_annotation_suffix;
|
extern char *async_annotation_suffix;
|
||||||
extern char *new_async_prompt;
|
|
||||||
extern struct prompts the_prompts;
|
extern struct prompts the_prompts;
|
||||||
extern void (*call_readline) (void *);
|
extern void (*call_readline) (void *);
|
||||||
extern void (*input_handler) (char *);
|
extern void (*input_handler) (char *);
|
||||||
|
@ -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
|
/* If a prompt has been set, PROMPT will not be NULL. If it is
|
||||||
NULL, do not set the prompt. */
|
NULL, do not set the prompt. */
|
||||||
if (prompt != NULL)
|
if (prompt != NULL)
|
||||||
set_prompt (prompt, 0);
|
set_prompt (prompt);
|
||||||
|
|
||||||
do_cleanups (cleanup);
|
do_cleanups (cleanup);
|
||||||
return;
|
return;
|
||||||
|
126
gdb/top.c
126
gdb/top.c
@ -554,7 +554,7 @@ command_loop (void)
|
|||||||
while (instream && !feof (instream))
|
while (instream && !feof (instream))
|
||||||
{
|
{
|
||||||
if (window_hook && instream == stdin)
|
if (window_hook && instream == stdin)
|
||||||
(*window_hook) (instream, get_prompt (0));
|
(*window_hook) (instream, get_prompt ());
|
||||||
|
|
||||||
quit_flag = 0;
|
quit_flag = 0;
|
||||||
if (instream == stdin && stdin_is_tty)
|
if (instream == stdin && stdin_is_tty)
|
||||||
@ -563,7 +563,7 @@ command_loop (void)
|
|||||||
|
|
||||||
/* Get a command-line. This calls the readline package. */
|
/* Get a command-line. This calls the readline package. */
|
||||||
command = command_line_input (instream == stdin ?
|
command = command_line_input (instream == stdin ?
|
||||||
get_prompt (0) : (char *) NULL,
|
get_prompt () : (char *) NULL,
|
||||||
instream == stdin, "prompt");
|
instream == stdin, "prompt");
|
||||||
if (command == 0)
|
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;
|
||||||
|
|
||||||
|
/* Access method for the GDB prompt string. */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
get_prefix (int level)
|
get_prompt (void)
|
||||||
{
|
{
|
||||||
return PREFIX (level);
|
return top_prompt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set_prefix: set method for the GDB prefix string. */
|
/* Set method for the GDB prompt string. */
|
||||||
|
|
||||||
void
|
void
|
||||||
set_prefix (const char *s, int level)
|
set_prompt (const char *s)
|
||||||
{
|
{
|
||||||
/* If S is NULL, just free the PREFIX at level LEVEL and set to
|
char *p = xstrdup (s);
|
||||||
NULL. */
|
|
||||||
if (s == NULL)
|
|
||||||
{
|
|
||||||
xfree (PREFIX (level));
|
|
||||||
PREFIX (level) = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char *p = xstrdup (s);
|
|
||||||
|
|
||||||
xfree (PREFIX (level));
|
xfree (top_prompt);
|
||||||
PREFIX (level) = p;
|
top_prompt = p;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get_suffix: access method for the GDB suffix 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)
|
|
||||||
{
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get_prompt: access method for the GDB prompt string. */
|
|
||||||
|
|
||||||
char *
|
|
||||||
get_prompt (int level)
|
|
||||||
{
|
|
||||||
return PROMPT (level);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
set_prompt (const char *s, int level)
|
|
||||||
{
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1589,8 +1519,8 @@ init_history (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
show_new_async_prompt (struct ui_file *file, int from_tty,
|
show_prompt (struct ui_file *file, int from_tty,
|
||||||
struct cmd_list_element *c, const char *value)
|
struct cmd_list_element *c, const char *value)
|
||||||
{
|
{
|
||||||
fprintf_filtered (file, _("Gdb's prompt is \"%s\".\n"), 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
|
static void
|
||||||
init_main (void)
|
init_main (void)
|
||||||
{
|
{
|
||||||
/* initialize the prompt stack to a simple "(gdb) " prompt or to
|
/* Initialize the prompt to a simple "(gdb) " prompt or to whatever
|
||||||
whatever the DEFAULT_PROMPT is. */
|
the DEFAULT_PROMPT is. */
|
||||||
the_prompts.top = 0;
|
set_prompt (DEFAULT_PROMPT);
|
||||||
PREFIX (0) = "";
|
|
||||||
set_prompt (DEFAULT_PROMPT, 0);
|
|
||||||
SUFFIX (0) = "";
|
|
||||||
/* Set things up for annotation_level > 1, if the user ever decides
|
/* Set things up for annotation_level > 1, if the user ever decides
|
||||||
to use it. */
|
to use it. */
|
||||||
async_annotation_suffix = "prompt";
|
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. */
|
/* Set the important stuff up for command editing. */
|
||||||
command_editing_p = 1;
|
command_editing_p = 1;
|
||||||
history_expansion_p = 0;
|
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);
|
rl_add_defun ("operate-and-get-next", gdb_rl_operate_and_get_next, 15);
|
||||||
|
|
||||||
add_setshow_string_cmd ("prompt", class_support,
|
add_setshow_string_cmd ("prompt", class_support,
|
||||||
&new_async_prompt,
|
&top_prompt,
|
||||||
_("Set gdb's prompt"),
|
_("Set gdb's prompt"),
|
||||||
_("Show gdb's prompt"),
|
_("Show gdb's prompt"),
|
||||||
NULL, set_async_prompt,
|
NULL, NULL,
|
||||||
show_new_async_prompt,
|
show_prompt,
|
||||||
&setlist, &showlist);
|
&setlist, &showlist);
|
||||||
|
|
||||||
add_com ("dont-repeat", class_support, dont_repeat_command, _("\
|
add_com ("dont-repeat", class_support, dont_repeat_command, _("\
|
||||||
@ -1716,7 +1638,7 @@ Set annotation_level."), _("\
|
|||||||
Show annotation_level."), _("\
|
Show annotation_level."), _("\
|
||||||
0 == normal; 1 == fullname (for use when running under emacs)\n\
|
0 == normal; 1 == fullname (for use when running under emacs)\n\
|
||||||
2 == output annotated suitably for use by programs that control GDB."),
|
2 == output annotated suitably for use by programs that control GDB."),
|
||||||
set_async_annotation_level,
|
NULL,
|
||||||
show_annotation_level,
|
show_annotation_level,
|
||||||
&setlist, &showlist);
|
&setlist, &showlist);
|
||||||
|
|
||||||
|
22
gdb/top.h
22
gdb/top.h
@ -51,27 +51,11 @@ extern struct cleanup *prepare_execute_command (void);
|
|||||||
|
|
||||||
/* This function returns a pointer to the string that is used
|
/* This function returns a pointer to the string that is used
|
||||||
by gdb for its command prompt. */
|
by gdb for its command prompt. */
|
||||||
extern char *get_prompt (int);
|
extern char *get_prompt (void);
|
||||||
|
|
||||||
/* 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
|
/* This function returns a pointer to the string that is used
|
||||||
by gdb for its command prompt prefix. */
|
by gdb for its command prompt. */
|
||||||
extern char *get_prefix (int);
|
extern void set_prompt (const char *s);
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
/* From random places. */
|
/* From random places. */
|
||||||
extern int readnow_symbol_files;
|
extern int readnow_symbol_files;
|
||||||
|
Loading…
Reference in New Issue
Block a user