gdb/
2011-09-12 Pedro Alves <pedro@codesourcery.com> Matt Rice <ratmice@gmail.com> PR gdb/13175 * interps.c (struct interp) <interpreter_out>: Delete field. (interp_new): Remove the data and uiout parameters and adjust. (interp_set): Only set the current_uiout from the interpreter's uiout after initializing the interpreter. Adjust call to init_proc. (interp_ui_out): Adjust to call procs->ui_out_proc. (interp_data, interp_name): New. * interps.h (interp_init_ftype): Add `self' parameter. (interp_ui_out_ftype): New typedef. (struct interp_procs) <ui_out_proc>: New method pointer. (interp_new): Remove the data and uiout parameters. (interp_data, interp_name): Declare. * tui/tui-interp.c (tui_init): Adjust prototype. (tui_ui_out): New. (_initialize_tui_interp): Install tui_ui_out. Don't instanciate tui_out here. Adjust call to interp_new. * tui/tui-io.c (tui_initialize_io): Don't set current_uiout here. * cli/cli-interp.c (cli_interpreter_init): Adjust prototype. (cli_ui_out): New. (_initialize_cli_interp): Install it. Adjust call to interp_new. * mi/mi-common.h (struct mi_interp) <uiout>: New field. * mi/mi-interp.c (mi_interpreter_init): Adjust prototype. Initialize mi->uiout depending on the mi_version as extracted from the interpreter's name. (mi_ui_out): New. (_initialize_mi_interp): Install mi_ui_out. Adjust calls to interp_new. Don't allocate the ui_out's of the interpreters here. gdb/testsuite/ 2011-09-12 Matt Rice <ratmice@gmail.com> Pedro Alves <pedro@codesourcery.com> PR gdb/13175 * gdb.base/interp.exp: New tests. * gdb.base/interp.c: New file.
This commit is contained in:
parent
d0afda0369
commit
4801a9a356
11 changed files with 212 additions and 35 deletions
|
@ -1,3 +1,36 @@
|
|||
2011-09-12 Pedro Alves <pedro@codesourcery.com>
|
||||
Matt Rice <ratmice@gmail.com>
|
||||
|
||||
PR gdb/13175
|
||||
|
||||
* interps.c (struct interp) <interpreter_out>: Delete field.
|
||||
(interp_new): Remove the data and uiout parameters and adjust.
|
||||
(interp_set): Only set the current_uiout from the interpreter's
|
||||
uiout after initializing the interpreter. Adjust call to
|
||||
init_proc.
|
||||
(interp_ui_out): Adjust to call procs->ui_out_proc.
|
||||
(interp_data, interp_name): New.
|
||||
* interps.h (interp_init_ftype): Add `self' parameter.
|
||||
(interp_ui_out_ftype): New typedef.
|
||||
(struct interp_procs) <ui_out_proc>: New method pointer.
|
||||
(interp_new): Remove the data and uiout parameters.
|
||||
(interp_data, interp_name): Declare.
|
||||
* tui/tui-interp.c (tui_init): Adjust prototype.
|
||||
(tui_ui_out): New.
|
||||
(_initialize_tui_interp): Install tui_ui_out. Don't instanciate
|
||||
tui_out here. Adjust call to interp_new.
|
||||
* tui/tui-io.c (tui_initialize_io): Don't set current_uiout here.
|
||||
* cli/cli-interp.c (cli_interpreter_init): Adjust prototype.
|
||||
(cli_ui_out): New.
|
||||
(_initialize_cli_interp): Install it. Adjust call to interp_new.
|
||||
* mi/mi-common.h (struct mi_interp) <uiout>: New field.
|
||||
* mi/mi-interp.c (mi_interpreter_init): Adjust prototype.
|
||||
Initialize mi->uiout depending on the mi_version as extracted from
|
||||
the interpreter's name.
|
||||
(mi_ui_out): New.
|
||||
(_initialize_mi_interp): Install mi_ui_out. Adjust calls to
|
||||
interp_new. Don't allocate the ui_out's of the interpreters here.
|
||||
|
||||
2011-09-12 Aleksandar Ristovski <aristovski@qnx.com>
|
||||
|
||||
* solib.c (solib_used): New function.
|
||||
|
|
|
@ -40,7 +40,7 @@ static struct gdb_exception safe_execute_command (struct ui_out *uiout,
|
|||
/* These implement the cli out interpreter: */
|
||||
|
||||
static void *
|
||||
cli_interpreter_init (int top_level)
|
||||
cli_interpreter_init (struct interp *self, int top_level)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -135,6 +135,11 @@ safe_execute_command (struct ui_out *command_uiout, char *command, int from_tty)
|
|||
return e;
|
||||
}
|
||||
|
||||
static struct ui_out *
|
||||
cli_ui_out (struct interp *self)
|
||||
{
|
||||
return cli_uiout;
|
||||
}
|
||||
|
||||
/* Standard gdb initialization hook. */
|
||||
extern initialize_file_ftype _initialize_cli_interp; /* -Wmissing-prototypes */
|
||||
|
@ -147,13 +152,14 @@ _initialize_cli_interp (void)
|
|||
cli_interpreter_resume, /* resume_proc */
|
||||
cli_interpreter_suspend, /* suspend_proc */
|
||||
cli_interpreter_exec, /* exec_proc */
|
||||
cli_interpreter_display_prompt_p /* prompt_proc_p */
|
||||
cli_interpreter_display_prompt_p, /* prompt_proc_p */
|
||||
cli_ui_out /* ui_out_proc */
|
||||
};
|
||||
struct interp *cli_interp;
|
||||
|
||||
/* Create a default uiout builder for the CLI. */
|
||||
cli_uiout = cli_out_new (gdb_stdout);
|
||||
cli_interp = interp_new (INTERP_CONSOLE, NULL, cli_uiout, &procs);
|
||||
cli_interp = interp_new (INTERP_CONSOLE, &procs);
|
||||
|
||||
interp_add (cli_interp);
|
||||
}
|
||||
|
|
|
@ -67,11 +67,6 @@ struct interp
|
|||
/* Has the init_proc been run? */
|
||||
int inited;
|
||||
|
||||
/* This is the ui_out used to collect results for this interpreter.
|
||||
It can be a formatter for stdout, as is the case for the console
|
||||
& mi outputs, or it might be a result formatter. */
|
||||
struct ui_out *interpreter_out;
|
||||
|
||||
const struct interp_procs *procs;
|
||||
int quiet_p;
|
||||
};
|
||||
|
@ -97,16 +92,14 @@ static int interpreter_initialized = 0;
|
|||
fills the fields from the inputs, and returns a pointer to the
|
||||
interpreter. */
|
||||
struct interp *
|
||||
interp_new (const char *name, void *data, struct ui_out *uiout,
|
||||
const struct interp_procs *procs)
|
||||
interp_new (const char *name, const struct interp_procs *procs)
|
||||
{
|
||||
struct interp *new_interp;
|
||||
|
||||
new_interp = XMALLOC (struct interp);
|
||||
|
||||
new_interp->name = xstrdup (name);
|
||||
new_interp->data = data;
|
||||
new_interp->interpreter_out = uiout;
|
||||
new_interp->data = NULL;
|
||||
new_interp->quiet_p = 0;
|
||||
new_interp->procs = procs;
|
||||
new_interp->inited = 0;
|
||||
|
@ -184,19 +177,20 @@ interp_set (struct interp *interp, int top_level)
|
|||
interpreter_p = xstrdup (current_interpreter->name);
|
||||
}
|
||||
|
||||
current_uiout = interp->interpreter_out;
|
||||
|
||||
/* Run the init proc. If it fails, try to restore the old interp. */
|
||||
|
||||
if (!interp->inited)
|
||||
{
|
||||
if (interp->procs->init_proc != NULL)
|
||||
{
|
||||
interp->data = interp->procs->init_proc (top_level);
|
||||
interp->data = interp->procs->init_proc (interp, top_level);
|
||||
}
|
||||
interp->inited = 1;
|
||||
}
|
||||
|
||||
/* Do this only after the interpreter is initialized. */
|
||||
current_uiout = interp->procs->ui_out_proc (interp);
|
||||
|
||||
/* Clear out any installed interpreter hooks/event handlers. */
|
||||
clear_interpreter_hooks ();
|
||||
|
||||
|
@ -254,9 +248,25 @@ struct ui_out *
|
|||
interp_ui_out (struct interp *interp)
|
||||
{
|
||||
if (interp != NULL)
|
||||
return interp->interpreter_out;
|
||||
return interp->procs->ui_out_proc (interp);
|
||||
|
||||
return current_interpreter->interpreter_out;
|
||||
return current_interpreter->procs->ui_out_proc (current_interpreter);
|
||||
}
|
||||
|
||||
/* Returns the interpreter's cookie. */
|
||||
|
||||
void *
|
||||
interp_data (struct interp *interp)
|
||||
{
|
||||
return interp->data;
|
||||
}
|
||||
|
||||
/* Returns the interpreter's name. */
|
||||
|
||||
const char *
|
||||
interp_name (struct interp *interp)
|
||||
{
|
||||
return interp->name;
|
||||
}
|
||||
|
||||
/* Returns true if the current interp is the passed in name. */
|
||||
|
|
|
@ -36,13 +36,14 @@ extern struct gdb_exception interp_exec (struct interp *interp,
|
|||
const char *command);
|
||||
extern int interp_quiet_p (struct interp *interp);
|
||||
|
||||
typedef void *(interp_init_ftype) (int top_level);
|
||||
typedef void *(interp_init_ftype) (struct interp *self, int top_level);
|
||||
typedef int (interp_resume_ftype) (void *data);
|
||||
typedef int (interp_suspend_ftype) (void *data);
|
||||
typedef int (interp_prompt_p_ftype) (void *data);
|
||||
typedef struct gdb_exception (interp_exec_ftype) (void *data,
|
||||
const char *command);
|
||||
typedef void (interp_command_loop_ftype) (void *data);
|
||||
typedef struct ui_out *(interp_ui_out_ftype) (struct interp *self);
|
||||
|
||||
struct interp_procs
|
||||
{
|
||||
|
@ -51,16 +52,23 @@ struct interp_procs
|
|||
interp_suspend_ftype *suspend_proc;
|
||||
interp_exec_ftype *exec_proc;
|
||||
interp_prompt_p_ftype *prompt_proc_p;
|
||||
|
||||
/* Returns the ui_out currently used to collect results for this
|
||||
interpreter. It can be a formatter for stdout, as is the case
|
||||
for the console & mi outputs, or it might be a result
|
||||
formatter. */
|
||||
interp_ui_out_ftype *ui_out_proc;
|
||||
|
||||
interp_command_loop_ftype *command_loop_proc;
|
||||
};
|
||||
|
||||
extern struct interp *interp_new (const char *name, void *data,
|
||||
struct ui_out *uiout,
|
||||
const struct interp_procs *procs);
|
||||
extern struct interp *interp_new (const char *name, const struct interp_procs *procs);
|
||||
extern void interp_add (struct interp *interp);
|
||||
extern int interp_set (struct interp *interp, int top_level);
|
||||
extern struct interp *interp_lookup (const char *name);
|
||||
extern struct ui_out *interp_ui_out (struct interp *interp);
|
||||
extern void *interp_data (struct interp *interp);
|
||||
extern const char *interp_name (struct interp *interp);
|
||||
|
||||
extern int current_interp_named_p (const char *name);
|
||||
extern int current_interp_display_prompt_p (void);
|
||||
|
|
|
@ -52,6 +52,9 @@ struct mi_interp
|
|||
struct ui_file *targ;
|
||||
struct ui_file *event_channel;
|
||||
|
||||
/* MI's builder. */
|
||||
struct ui_out *uiout;
|
||||
|
||||
/* This is the interpreter for the mi... */
|
||||
struct interp *mi2_interp;
|
||||
struct interp *mi1_interp;
|
||||
|
|
|
@ -72,9 +72,11 @@ static void mi_breakpoint_modified (struct breakpoint *b);
|
|||
static int report_initial_inferior (struct inferior *inf, void *closure);
|
||||
|
||||
static void *
|
||||
mi_interpreter_init (int top_level)
|
||||
mi_interpreter_init (struct interp *interp, int top_level)
|
||||
{
|
||||
struct mi_interp *mi = XMALLOC (struct mi_interp);
|
||||
const char *name;
|
||||
int mi_version;
|
||||
|
||||
/* HACK: We need to force stdout/stderr to point at the console. This avoids
|
||||
any potential side effects caused by legacy code that is still
|
||||
|
@ -90,6 +92,22 @@ mi_interpreter_init (int top_level)
|
|||
mi->targ = mi_console_file_new (raw_stdout, "@", '"');
|
||||
mi->event_channel = mi_console_file_new (raw_stdout, "=", 0);
|
||||
|
||||
name = interp_name (interp);
|
||||
/* INTERP_MI selects the most recent released version. "mi2" was
|
||||
released as part of GDB 6.0. */
|
||||
if (strcmp (name, INTERP_MI) == 0)
|
||||
mi_version = 2;
|
||||
else if (strcmp (name, INTERP_MI1) == 0)
|
||||
mi_version = 1;
|
||||
else if (strcmp (name, INTERP_MI2) == 0)
|
||||
mi_version = 2;
|
||||
else if (strcmp (name, INTERP_MI3) == 0)
|
||||
mi_version = 3;
|
||||
else
|
||||
gdb_assert_not_reached ("unhandled MI version");
|
||||
|
||||
mi->uiout = mi_out_new (mi_version);
|
||||
|
||||
if (top_level)
|
||||
{
|
||||
observer_attach_new_thread (mi_new_thread);
|
||||
|
@ -701,6 +719,14 @@ report_initial_inferior (struct inferior *inf, void *closure)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct ui_out *
|
||||
mi_ui_out (struct interp *interp)
|
||||
{
|
||||
struct mi_interp *mi = interp_data (interp);
|
||||
|
||||
return mi->uiout;
|
||||
}
|
||||
|
||||
extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */
|
||||
|
||||
void
|
||||
|
@ -712,15 +738,13 @@ _initialize_mi_interp (void)
|
|||
mi_interpreter_resume, /* resume_proc */
|
||||
mi_interpreter_suspend, /* suspend_proc */
|
||||
mi_interpreter_exec, /* exec_proc */
|
||||
mi_interpreter_prompt_p /* prompt_proc_p */
|
||||
mi_interpreter_prompt_p, /* prompt_proc_p */
|
||||
mi_ui_out /* ui_out_proc */
|
||||
};
|
||||
|
||||
/* The various interpreter levels. */
|
||||
interp_add (interp_new (INTERP_MI1, NULL, mi_out_new (1), &procs));
|
||||
interp_add (interp_new (INTERP_MI2, NULL, mi_out_new (2), &procs));
|
||||
interp_add (interp_new (INTERP_MI3, NULL, mi_out_new (3), &procs));
|
||||
|
||||
/* "mi" selects the most recent released version. "mi2" was
|
||||
released as part of GDB 6.0. */
|
||||
interp_add (interp_new (INTERP_MI, NULL, mi_out_new (2), &procs));
|
||||
interp_add (interp_new (INTERP_MI1, &procs));
|
||||
interp_add (interp_new (INTERP_MI2, &procs));
|
||||
interp_add (interp_new (INTERP_MI3, &procs));
|
||||
interp_add (interp_new (INTERP_MI, &procs));
|
||||
}
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2011-09-12 Matt Rice <ratmice@gmail.com>
|
||||
Pedro Alves <pedro@codesourcery.com>
|
||||
|
||||
PR gdb/13175
|
||||
|
||||
* gdb.base/interp.exp: New tests.
|
||||
* gdb.base/interp.c: New file.
|
||||
|
||||
2011-09-12 Doug Evans <dje@google.com>
|
||||
|
||||
* gdb.dwarf2/clztest.exp: Fix initialization of tests array.
|
||||
|
|
24
gdb/testsuite/gdb.base/interp.c
Normal file
24
gdb/testsuite/gdb.base/interp.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* This test program is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2011
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
int
|
||||
main (int argc, const char **argv)
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -20,7 +20,11 @@ if $tracelevel then {
|
|||
strace $tracelevel
|
||||
}
|
||||
|
||||
gdb_start
|
||||
set testfile "interp"
|
||||
|
||||
if { [prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.c {debug}] } {
|
||||
return -1
|
||||
}
|
||||
|
||||
# Do not use gdb_test for this test, since it has two prompts.
|
||||
set cmd "interpreter-exec mi \"-var-update *\""
|
||||
|
@ -45,4 +49,50 @@ gdb_test_multiple "interpreter-exec mi \"-break-insert --thread a\"" \
|
|||
}
|
||||
}
|
||||
|
||||
set cmd "interpreter-exec mi \"-stack-info-frame\""
|
||||
gdb_test_multiple $cmd $cmd {
|
||||
-re ".error,msg=.No registers\..\r\n$gdb_prompt " {
|
||||
pass "$cmd"
|
||||
gdb_expect 1 {
|
||||
-re "\r\n$gdb_prompt $" { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set cmd "interpreter-exec mi1 \"-break-insert main\""
|
||||
gdb_test_multiple $cmd $cmd {
|
||||
-re ".done.bkpt=.number=.\[0-9\]\[^\n\]+\r\n$gdb_prompt " {
|
||||
pass "$cmd"
|
||||
gdb_expect 1 {
|
||||
-re "\r\n$gdb_prompt $" { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set cmd "interpreter-exec mi2 \"-break-insert main\""
|
||||
gdb_test_multiple $cmd $cmd {
|
||||
-re ".done.bkpt=.number=.\[0-9\]\[^\n\]+\r\n$gdb_prompt " {
|
||||
pass "$cmd"
|
||||
gdb_expect 1 {
|
||||
-re "\r\n$gdb_prompt $" { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set cmd "interpreter-exec mi3 \"-break-insert main\""
|
||||
gdb_test_multiple $cmd $cmd {
|
||||
-re ".done.bkpt=.number=.\[0-9\]\[^\n\]+\r\n$gdb_prompt " {
|
||||
pass "$cmd"
|
||||
gdb_expect 1 {
|
||||
-re "\r\n$gdb_prompt $" { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ![runto_main] then {
|
||||
fail "run to main"
|
||||
return -1;
|
||||
}
|
||||
|
||||
gdb_test "list" ".*\[0-9\].*main \\(int argc.*" "can list sources"
|
||||
gdb_exit
|
||||
|
|
|
@ -52,7 +52,7 @@ static int tui_is_toplevel = 0;
|
|||
/* These implement the TUI interpreter. */
|
||||
|
||||
static void *
|
||||
tui_init (int top_level)
|
||||
tui_init (struct interp *self, int top_level)
|
||||
{
|
||||
tui_is_toplevel = top_level;
|
||||
|
||||
|
@ -126,6 +126,15 @@ tui_display_prompt_p (void *data)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static struct ui_out *
|
||||
tui_ui_out (struct interp *self)
|
||||
{
|
||||
if (tui_active)
|
||||
return tui_out;
|
||||
else
|
||||
return tui_old_uiout;
|
||||
}
|
||||
|
||||
static struct gdb_exception
|
||||
tui_exec (void *data, const char *command_str)
|
||||
{
|
||||
|
@ -144,11 +153,13 @@ _initialize_tui_interp (void)
|
|||
tui_suspend,
|
||||
tui_exec,
|
||||
tui_display_prompt_p,
|
||||
tui_ui_out,
|
||||
};
|
||||
struct interp *tui_interp;
|
||||
|
||||
/* Create a default uiout builder for the TUI. */
|
||||
tui_out = tui_out_new (gdb_stdout);
|
||||
interp_add (interp_new (INTERP_TUI, NULL, tui_out, &procs));
|
||||
tui_interp = interp_new (INTERP_TUI, &procs);
|
||||
interp_add (tui_interp);
|
||||
if (interpreter_p && strcmp (interpreter_p, INTERP_TUI) == 0)
|
||||
tui_start_enabled = 1;
|
||||
|
||||
|
|
|
@ -607,7 +607,7 @@ tui_initialize_io (void)
|
|||
|
||||
/* Create the default UI. It is not created because we installed a
|
||||
deprecated_init_ui_hook. */
|
||||
tui_old_uiout = current_uiout = cli_out_new (gdb_stdout);
|
||||
tui_old_uiout = cli_out_new (gdb_stdout);
|
||||
|
||||
#ifdef TUI_USE_PIPE_FOR_READLINE
|
||||
/* Temporary solution for readline writing to stdout: redirect
|
||||
|
|
Loading…
Reference in a new issue