This is the mail archive of the
gdb@sourceware.org
mailing list for the GDB project.
Re: More descriptive prompt [was Re: Process exit in multi-process, and gdb's selected thread.]
- From: Pedro Alves <pedro at codesourcery dot com>
- To: Doug Evans <dje at google dot com>
- Cc: Marc Khouzam <marc dot khouzam at ericsson dot com>, gdb at sourceware dot org
- Date: Tue, 24 Feb 2009 18:41:11 +0000
- Subject: Re: More descriptive prompt [was Re: Process exit in multi-process, and gdb's selected thread.]
- References: <e394668d0902241012n458775c5s9e7ba9187209764@mail.gmail.com>
On Tuesday 24 February 2009 18:12:03, Doug Evans wrote:
> If there's general favorability of this I'll work on a patch.
This was something that had occured to be before as well when
I got tired of doing "info threads" while working on non-stop.
This is what I was using at one point. It added a PS1 style
formatting to the gdb command, so I could do
(gdb) set prompt (\\p \\T: \\S)
And have the prompt show up as:
(1 Thread 0x7ffff7fd36e0 (LWP 12690): stopped)
or, ...
(1 Thread 0x7ffff7fd36e0 (LWP 12690): running)
etc.
--
Pedro Alves
---
gdb/event-top.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 86 insertions(+), 3 deletions(-)
Index: src/gdb/event-top.c
===================================================================
--- src.orig/gdb/event-top.c 2009-01-14 13:37:57.000000000 +0000
+++ src/gdb/event-top.c 2009-02-24 18:33:39.000000000 +0000
@@ -33,6 +33,7 @@
#include "cli/cli-script.h" /* for reset_command_nest_depth */
#include "main.h"
#include "gdbthread.h"
+#include "gdb_obstack.h"
/* For dont_repeat() */
#include "gdbcmd.h"
@@ -244,6 +245,83 @@ change_line_handler (void)
}
}
+static char *
+expand_gdb_prompt (char *prompt)
+{
+ char *p;
+ int escape = 0;
+ struct obstack obstack;
+ obstack_init (&obstack);
+
+ for (p = prompt; *p ; p++)
+ {
+ if (escape)
+ {
+ escape = 0;
+ switch (*p)
+ {
+ case 'p':
+ {
+ char *t = xstrprintf ("%d",
+ pid_to_thread_id (inferior_ptid));
+ obstack_grow_str (&obstack, t);
+ xfree (t);
+ break;
+ }
+ case 'T':
+ {
+ if (!ptid_equal (inferior_ptid, null_ptid))
+ {
+ char *t = target_pid_to_str (inferior_ptid);
+ if (t)
+ obstack_grow_str (&obstack, t);
+ }
+ break;
+ }
+ case 'x':
+ {
+ if (!ptid_equal (inferior_ptid, null_ptid))
+ {
+ char *t = target_extra_thread_info (inferior_thread ());
+ if (t)
+ obstack_grow_str (&obstack, t);
+ }
+ break;
+ }
+ case 'S':
+ {
+ if (!ptid_equal (inferior_ptid, null_ptid))
+ {
+ if (is_running (inferior_ptid))
+ obstack_grow_str (&obstack, "running");
+ else if (is_stopped (inferior_ptid))
+ obstack_grow_str (&obstack, "stopped");
+ else if (is_exited (inferior_ptid))
+ obstack_grow_str (&obstack, "exited");
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ switch (*p)
+ {
+ case '\\':
+ escape = 1;
+ break;
+ default:
+ obstack_1grow (&obstack, *p);
+ break;
+ }
+ }
+ }
+
+ obstack_1grow (&obstack, '\0');
+
+ return xstrdup (obstack_finish (&obstack));
+}
+
/* 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
@@ -260,6 +338,7 @@ display_gdb_prompt (char *new_prompt)
{
int prompt_length = 0;
char *gdb_prompt = get_prompt ();
+ char *expanded_prompt;
/* Reset the nesting depth used when trace-commands is set. */
reset_command_nest_depth ();
@@ -307,20 +386,24 @@ display_gdb_prompt (char *new_prompt)
strcat (new_prompt, SUFFIX (0));
}
+ expanded_prompt = expand_gdb_prompt (new_prompt);
+
if (async_command_editing_p)
{
rl_callback_handler_remove ();
- rl_callback_handler_install (new_prompt, input_handler);
+ rl_callback_handler_install (expanded_prompt, input_handler);
}
/* new_prompt at this point can be the top of the stack or the one passed in */
- else if (new_prompt)
+ else
{
/* Don't use a _filtered function here. It causes the assumed
character position to be off, since the newline we read from
the user is not accounted for. */
- fputs_unfiltered (new_prompt, gdb_stdout);
+ fputs_unfiltered (expanded_prompt, gdb_stdout);
gdb_flush (gdb_stdout);
}
+
+ xfree (expanded_prompt);
}
/* Used when the user requests a different annotation level, with