binutils-gdb/gdb/interps.h

155 lines
5.8 KiB
C
Raw Normal View History

2003-02-06 06:30:17 +01:00
/* Manages interpreters for GDB, the GNU debugger.
Copyright (C) 2000-2016 Free Software Foundation, Inc.
2003-02-06 06:30:17 +01:00
Written by Jim Ingham <jingham@apple.com> of Apple Computer, Inc.
This file is part of GDB.
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
2003-02-06 06:30:17 +01:00
(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/>. */
2003-02-06 06:30:17 +01:00
#ifndef INTERPS_H
#define INTERPS_H
struct ui_out;
struct interp;
Introduce interpreter factories If every UI instance has its own set of interpreters, then the current scheme of creating the interpreters at GDB initialization time no longer works. We need to create them whenever a new UI instance is created. The scheme implemented here has each interpreter register a factory callback that when called creates a new instance of a specific interpreter type. Then, when some code in gdb looks up an interpreter (always by name), if there's none yet, the factory method is called to construct one. gdb/ChangeLog: 2016-06-21 Pedro Alves <palves@redhat.com> * cli/cli-interp.c (cli_uiout): Delete, moved into ... (struct cli_interp): ... this new structure. (cli_on_normal_stop, cli_on_signal_received) (cli_on_end_stepping_range, cli_on_signal_exited, cli_on_exited) (cli_on_no_history): Use interp_ui_out. (cli_interpreter_init): If top level, set the cli_interp global. (cli_interpreter_init): Return the interp's data instead of NULL. (cli_interpreter_resume, cli_interpreter_exec, cli_ui_out): Adjust to cli_uiout being in the interpreter's data. (cli_interp_procs): New, factored out from _initialize_cli_interp. (cli_interp_factory): New function. (_initialize_cli_interp): Call interp_factory_register. * interps.c (get_interp_info): New, factored out from ... (get_current_interp_info): ... this. (interp_new): Add parameter 'data'. Store it. (struct interp_factory): New function. (interp_factory_p): New typedef. Define a VEC_P. (interpreter_factories): New global. (interp_factory_register): New function. (interp_add): Add 'ui' parameter. Use get_interp_info and interp_lookup_existing. (interp_lookup): Rename to ... (interp_lookup_existing): ... this. Add 'ui' parameter. Don't check for NULL or empty name here. (interp_lookup): Add 'ui' parameter and reimplement. (interp_set_temp, interpreter_exec_cmd): Adjust. (interpreter_completer): Complete on registered interpreter factories instead of interpreters. * interps.h (interp_factory_func): New typedef. (interp_factory_register): Declare. (interp_new, interp_add): Adjust. (interp_lookup): Declare. * main.c (captured_main): Adjust. * mi/mi-interp.c (mi_cmd_interpreter_exec): Adjust. (mi_interp_procs): New, factored out from _initialize_mi_interp. (mi_interp_factory): New function. * python/python.c (execute_gdb_command): Adjust. * tui/tui-interp.c (tui_init): If top level, set the tui_interp global. (tui_interp_procs): New. (tui_interp_factory): New function. (_initialize_tui_interp): Call interp_factory_register.
2016-06-21 02:11:45 +02:00
struct ui;
typedef struct interp *(*interp_factory_func) (const char *name);
/* Each interpreter kind (CLI, MI, etc.) registers itself with a call
to this function, passing along its name, and a pointer to a
function that creates a new instance of an interpreter with that
name. */
extern void interp_factory_register (const char *name,
interp_factory_func func);
2003-02-06 06:30:17 +01:00
extern int interp_resume (struct interp *interp);
extern int interp_suspend (struct interp *interp);
extern struct gdb_exception interp_exec (struct interp *interp,
const char *command);
2003-02-06 06:30:17 +01:00
extern int interp_quiet_p (struct interp *interp);
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.
2011-09-12 23:25:22 +02:00
typedef void *(interp_init_ftype) (struct interp *self, int top_level);
2003-02-06 06:30:17 +01:00
typedef int (interp_resume_ftype) (void *data);
typedef int (interp_suspend_ftype) (void *data);
typedef struct gdb_exception (interp_exec_ftype) (void *data,
const char *command);
Simplify starting the command event loop All interpreter types (CLI/TUI/MI) print the prompt, and then call start_event_loop. Because we'll need an interpreter hook to display the interpreter-specific prompt before going back to the event loop, without actually starting an event loop, this patch moves the start_event_loop call to common code, and replaces the command_loop hook with a pre_command_look hook, that now just prints the prompt. Turns out to be a cleanup on its own right anyway. gdb/ChangeLog: 2016-06-21 Pedro Alves <palves@redhat.com> * cli/cli-interp.c (cli_interpreter_pre_command_loop): New function. (cli_interp_procs): Install it instead of cli_command_loop. * cli/cli-interp.h (cli_interpreter_pre_command_loop): Declare. * event-top.c (cli_command_loop): Delete. * interps.c (interp_new): Remove reference to command_loop_proc. (current_interp_command_loop): Delete. (interp_pre_command_loop): New function. (interp_command_loop_ftype): Delete. * interps.h (interp_pre_command_loop_ftype): New typedef. (struct interp_procs) <command_loop_proc>: Delele field. <pre_command_loop_proc>: New field. (current_interp_command_loop): Delete declaration. (interp_pre_command_loop): New declaration. * main.c (captured_command_loop): Call interp_pre_command_loop instead of current_interp_command_loop and start an event loop. * mi/mi-interp.c (mi_command_loop): Delete. (mi_interpreter_pre_command_loop): New. (mi_interp_procs): Update. * tui/tui-interp.c (tui_interp_procs): Install cli_interpreter_pre_command_loop instead of cli_command_loop.
2016-06-21 02:11:51 +02:00
typedef void (interp_pre_command_loop_ftype) (struct interp *self);
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.
2011-09-12 23:25:22 +02:00
typedef struct ui_out *(interp_ui_out_ftype) (struct interp *self);
2003-02-06 06:30:17 +01:00
typedef int (interp_set_logging_ftype) (struct interp *self, int start_log,
struct ui_file *out,
struct ui_file *logfile);
Make command line editing (use of readline) be per UI Due to the way that readline's API works (based on globals), we can only have one instance of readline in a process. So the goal of this patch is to only allow editing in the main UI, and make sure that only one UI calls into readline. Some MI paths touch readline variables currently, which is bad as that is changing variables that matter for the main console UI. This patch fixes those. This actually fixes a nasty bug -- starting gdb in MI mode ("gdb -i=mi"), and then doing "set editing on" crashes GDB, because MI is not prepared to use readline: set editing on &"set editing on\n" =cmd-param-changed,param="editing",value="on" ^done (gdb) p 1 readline: readline_callback_read_char() called with no handler! Aborted (core dumped) The fix for that was to add an interp_proc method to query the interpreter whether it actually supports editing. New test included. gdb/ChangeLog: 2016-06-21 Pedro Alves <palves@redhat.com> PR mi/20034 * cli/cli-interp.c: Include cli-interp.h and event-top.h. (cli_interpreter_resume): Pass 1 to gdb_setup_readline. Set the UI's input_handler here. (cli_interpreter_supports_command_editing): New function. (cli_interp_procs): Install it. * cli/cli-interp.h: New file. * event-top.c (async_command_editing_p): Rename to ... (set_editing_cmd_var): ... this. (change_line_handler): Add parameter 'editing', and use it. Bail early if the interpreter doesn't support editing. Don't touch readline state if editing is off. (gdb_rl_callback_handler_remove, gdb_rl_callback_handler_install) (gdb_rl_callback_handler_reinstall): Assert the current UI is the main UI. (display_gdb_prompt): Don't call gdb_rl_callback_handler_remove if not using readline. Check whether the current UI is using command editing instead of checking the async_command_editing_p global. (set_async_editing_command): Delete. (gdb_setup_readline): Add 'editing' parameter. Only allow editing on the main UI. Don't touch readline state if editing is off. (gdb_disable_readline): Don't touch readline state if editing is off. * event-top.h (gdb_setup_readline): Add 'int' parameter. (set_async_editing_command): Delete declaration. (change_line_handler, command_line_handler): Declare. (async_command_editing_p): Rename to ... (set_editing_cmd_var): ... this. * infrun.c (reinstall_readline_callback_handler_cleanup): Check whether the current UI has editing enabled rather than checking the async_command_editing_p global. * interps.c (interp_supports_command_editing): New function. * interps.h (interp_supports_command_editing_ftype): New typedef. (struct interp_procs) <supports_command_editing_proc>: New field. (interp_supports_command_editing): Declare. * mi/mi-interp.c (mi_interpreter_resume): Pass 0 to gdb_setup_readline. Don't clear the async_command_editing_p global. Update comments. * top.c (gdb_readline_wrapper_line, gdb_readline_wrapper): Check whether the current UI has editing enabled rather than checking the async_command_editing_p global. Don't touch readline state if editing is off. (undo_terminal_modifications_before_exit): Switch to the main UI. Unconditionally call gdb_disable_readline. (set_editing): New function. (show_async_command_editing_p): Rename to ... (show_editing): ... this. Show the state of the current UI. (_initialize_top): Adjust. * top.h (struct ui) <command_editing>: New field. * tui/tui-interp.c: Include cli/cli-interp.h. (tui_resume): Pass 1 to gdb_setup_readline. Set the UI's input_handler. (tui_interp_procs): Install cli_interpreter_supports_command_editing. * tui/tui-io.c (tui_getc): Check whether the current UI has editing enabled rather than checking the async_command_editing_p global. gdb/testsuite/ChangeLog: 2016-06-21 Pedro Alves <palves@redhat.com> PR mi/20034 * gdb.mi/mi-editing.exp: New file.
2016-06-21 02:11:48 +02:00
typedef int (interp_supports_command_editing_ftype) (struct interp *self);
2003-02-06 06:30:17 +01:00
struct interp_procs
{
interp_init_ftype *init_proc;
interp_resume_ftype *resume_proc;
interp_suspend_ftype *suspend_proc;
interp_exec_ftype *exec_proc;
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.
2011-09-12 23:25:22 +02:00
/* 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;
/* Provides a hook for interpreters to do any additional
setup/cleanup that they might need when logging is enabled or
disabled. */
interp_set_logging_ftype *set_logging_proc;
Simplify starting the command event loop All interpreter types (CLI/TUI/MI) print the prompt, and then call start_event_loop. Because we'll need an interpreter hook to display the interpreter-specific prompt before going back to the event loop, without actually starting an event loop, this patch moves the start_event_loop call to common code, and replaces the command_loop hook with a pre_command_look hook, that now just prints the prompt. Turns out to be a cleanup on its own right anyway. gdb/ChangeLog: 2016-06-21 Pedro Alves <palves@redhat.com> * cli/cli-interp.c (cli_interpreter_pre_command_loop): New function. (cli_interp_procs): Install it instead of cli_command_loop. * cli/cli-interp.h (cli_interpreter_pre_command_loop): Declare. * event-top.c (cli_command_loop): Delete. * interps.c (interp_new): Remove reference to command_loop_proc. (current_interp_command_loop): Delete. (interp_pre_command_loop): New function. (interp_command_loop_ftype): Delete. * interps.h (interp_pre_command_loop_ftype): New typedef. (struct interp_procs) <command_loop_proc>: Delele field. <pre_command_loop_proc>: New field. (current_interp_command_loop): Delete declaration. (interp_pre_command_loop): New declaration. * main.c (captured_command_loop): Call interp_pre_command_loop instead of current_interp_command_loop and start an event loop. * mi/mi-interp.c (mi_command_loop): Delete. (mi_interpreter_pre_command_loop): New. (mi_interp_procs): Update. * tui/tui-interp.c (tui_interp_procs): Install cli_interpreter_pre_command_loop instead of cli_command_loop.
2016-06-21 02:11:51 +02:00
/* Called before starting an event loop, to give the interpreter a
chance to e.g., print a prompt. */
interp_pre_command_loop_ftype *pre_command_loop_proc;
Make command line editing (use of readline) be per UI Due to the way that readline's API works (based on globals), we can only have one instance of readline in a process. So the goal of this patch is to only allow editing in the main UI, and make sure that only one UI calls into readline. Some MI paths touch readline variables currently, which is bad as that is changing variables that matter for the main console UI. This patch fixes those. This actually fixes a nasty bug -- starting gdb in MI mode ("gdb -i=mi"), and then doing "set editing on" crashes GDB, because MI is not prepared to use readline: set editing on &"set editing on\n" =cmd-param-changed,param="editing",value="on" ^done (gdb) p 1 readline: readline_callback_read_char() called with no handler! Aborted (core dumped) The fix for that was to add an interp_proc method to query the interpreter whether it actually supports editing. New test included. gdb/ChangeLog: 2016-06-21 Pedro Alves <palves@redhat.com> PR mi/20034 * cli/cli-interp.c: Include cli-interp.h and event-top.h. (cli_interpreter_resume): Pass 1 to gdb_setup_readline. Set the UI's input_handler here. (cli_interpreter_supports_command_editing): New function. (cli_interp_procs): Install it. * cli/cli-interp.h: New file. * event-top.c (async_command_editing_p): Rename to ... (set_editing_cmd_var): ... this. (change_line_handler): Add parameter 'editing', and use it. Bail early if the interpreter doesn't support editing. Don't touch readline state if editing is off. (gdb_rl_callback_handler_remove, gdb_rl_callback_handler_install) (gdb_rl_callback_handler_reinstall): Assert the current UI is the main UI. (display_gdb_prompt): Don't call gdb_rl_callback_handler_remove if not using readline. Check whether the current UI is using command editing instead of checking the async_command_editing_p global. (set_async_editing_command): Delete. (gdb_setup_readline): Add 'editing' parameter. Only allow editing on the main UI. Don't touch readline state if editing is off. (gdb_disable_readline): Don't touch readline state if editing is off. * event-top.h (gdb_setup_readline): Add 'int' parameter. (set_async_editing_command): Delete declaration. (change_line_handler, command_line_handler): Declare. (async_command_editing_p): Rename to ... (set_editing_cmd_var): ... this. * infrun.c (reinstall_readline_callback_handler_cleanup): Check whether the current UI has editing enabled rather than checking the async_command_editing_p global. * interps.c (interp_supports_command_editing): New function. * interps.h (interp_supports_command_editing_ftype): New typedef. (struct interp_procs) <supports_command_editing_proc>: New field. (interp_supports_command_editing): Declare. * mi/mi-interp.c (mi_interpreter_resume): Pass 0 to gdb_setup_readline. Don't clear the async_command_editing_p global. Update comments. * top.c (gdb_readline_wrapper_line, gdb_readline_wrapper): Check whether the current UI has editing enabled rather than checking the async_command_editing_p global. Don't touch readline state if editing is off. (undo_terminal_modifications_before_exit): Switch to the main UI. Unconditionally call gdb_disable_readline. (set_editing): New function. (show_async_command_editing_p): Rename to ... (show_editing): ... this. Show the state of the current UI. (_initialize_top): Adjust. * top.h (struct ui) <command_editing>: New field. * tui/tui-interp.c: Include cli/cli-interp.h. (tui_resume): Pass 1 to gdb_setup_readline. Set the UI's input_handler. (tui_interp_procs): Install cli_interpreter_supports_command_editing. * tui/tui-io.c (tui_getc): Check whether the current UI has editing enabled rather than checking the async_command_editing_p global. gdb/testsuite/ChangeLog: 2016-06-21 Pedro Alves <palves@redhat.com> PR mi/20034 * gdb.mi/mi-editing.exp: New file.
2016-06-21 02:11:48 +02:00
/* Returns true if this interpreter supports using the readline
library; false if it uses GDB's own simplified readline
emulation. */
interp_supports_command_editing_ftype *supports_command_editing_proc;
2003-02-06 06:30:17 +01:00
};
Introduce interpreter factories If every UI instance has its own set of interpreters, then the current scheme of creating the interpreters at GDB initialization time no longer works. We need to create them whenever a new UI instance is created. The scheme implemented here has each interpreter register a factory callback that when called creates a new instance of a specific interpreter type. Then, when some code in gdb looks up an interpreter (always by name), if there's none yet, the factory method is called to construct one. gdb/ChangeLog: 2016-06-21 Pedro Alves <palves@redhat.com> * cli/cli-interp.c (cli_uiout): Delete, moved into ... (struct cli_interp): ... this new structure. (cli_on_normal_stop, cli_on_signal_received) (cli_on_end_stepping_range, cli_on_signal_exited, cli_on_exited) (cli_on_no_history): Use interp_ui_out. (cli_interpreter_init): If top level, set the cli_interp global. (cli_interpreter_init): Return the interp's data instead of NULL. (cli_interpreter_resume, cli_interpreter_exec, cli_ui_out): Adjust to cli_uiout being in the interpreter's data. (cli_interp_procs): New, factored out from _initialize_cli_interp. (cli_interp_factory): New function. (_initialize_cli_interp): Call interp_factory_register. * interps.c (get_interp_info): New, factored out from ... (get_current_interp_info): ... this. (interp_new): Add parameter 'data'. Store it. (struct interp_factory): New function. (interp_factory_p): New typedef. Define a VEC_P. (interpreter_factories): New global. (interp_factory_register): New function. (interp_add): Add 'ui' parameter. Use get_interp_info and interp_lookup_existing. (interp_lookup): Rename to ... (interp_lookup_existing): ... this. Add 'ui' parameter. Don't check for NULL or empty name here. (interp_lookup): Add 'ui' parameter and reimplement. (interp_set_temp, interpreter_exec_cmd): Adjust. (interpreter_completer): Complete on registered interpreter factories instead of interpreters. * interps.h (interp_factory_func): New typedef. (interp_factory_register): Declare. (interp_new, interp_add): Adjust. (interp_lookup): Declare. * main.c (captured_main): Adjust. * mi/mi-interp.c (mi_cmd_interpreter_exec): Adjust. (mi_interp_procs): New, factored out from _initialize_mi_interp. (mi_interp_factory): New function. * python/python.c (execute_gdb_command): Adjust. * tui/tui-interp.c (tui_init): If top level, set the tui_interp global. (tui_interp_procs): New. (tui_interp_factory): New function. (_initialize_tui_interp): Call interp_factory_register.
2016-06-21 02:11:45 +02:00
extern struct interp *interp_new (const char *name,
const struct interp_procs *procs,
void *data);
extern void interp_add (struct ui *ui, struct interp *interp);
extern int interp_set (struct interp *interp, int top_level);
Introduce interpreter factories If every UI instance has its own set of interpreters, then the current scheme of creating the interpreters at GDB initialization time no longer works. We need to create them whenever a new UI instance is created. The scheme implemented here has each interpreter register a factory callback that when called creates a new instance of a specific interpreter type. Then, when some code in gdb looks up an interpreter (always by name), if there's none yet, the factory method is called to construct one. gdb/ChangeLog: 2016-06-21 Pedro Alves <palves@redhat.com> * cli/cli-interp.c (cli_uiout): Delete, moved into ... (struct cli_interp): ... this new structure. (cli_on_normal_stop, cli_on_signal_received) (cli_on_end_stepping_range, cli_on_signal_exited, cli_on_exited) (cli_on_no_history): Use interp_ui_out. (cli_interpreter_init): If top level, set the cli_interp global. (cli_interpreter_init): Return the interp's data instead of NULL. (cli_interpreter_resume, cli_interpreter_exec, cli_ui_out): Adjust to cli_uiout being in the interpreter's data. (cli_interp_procs): New, factored out from _initialize_cli_interp. (cli_interp_factory): New function. (_initialize_cli_interp): Call interp_factory_register. * interps.c (get_interp_info): New, factored out from ... (get_current_interp_info): ... this. (interp_new): Add parameter 'data'. Store it. (struct interp_factory): New function. (interp_factory_p): New typedef. Define a VEC_P. (interpreter_factories): New global. (interp_factory_register): New function. (interp_add): Add 'ui' parameter. Use get_interp_info and interp_lookup_existing. (interp_lookup): Rename to ... (interp_lookup_existing): ... this. Add 'ui' parameter. Don't check for NULL or empty name here. (interp_lookup): Add 'ui' parameter and reimplement. (interp_set_temp, interpreter_exec_cmd): Adjust. (interpreter_completer): Complete on registered interpreter factories instead of interpreters. * interps.h (interp_factory_func): New typedef. (interp_factory_register): Declare. (interp_new, interp_add): Adjust. (interp_lookup): Declare. * main.c (captured_main): Adjust. * mi/mi-interp.c (mi_cmd_interpreter_exec): Adjust. (mi_interp_procs): New, factored out from _initialize_mi_interp. (mi_interp_factory): New function. * python/python.c (execute_gdb_command): Adjust. * tui/tui-interp.c (tui_init): If top level, set the tui_interp global. (tui_interp_procs): New. (tui_interp_factory): New function. (_initialize_tui_interp): Call interp_factory_register.
2016-06-21 02:11:45 +02:00
/* Look up the interpreter for NAME, creating one if none exists yet.
If NAME is not a interpreter type previously registered with
interp_factory_register, return NULL; otherwise return a pointer to
the interpreter. */
extern struct interp *interp_lookup (struct ui *ui, const char *name);
Add new command to create extra console/mi UIs With all the previous plumbing in place, it's now easy to add a command that actually creates a new console/mi UI. The intended use case is to make it possible and easy for MI frontends to provide a fully featured GDB console to users, with readline support, command line editing, history, etc., just like if gdb was started on the command line. Currently MI frontends have to try to implement all of that theirselves and make use of "-interpreter-exec console ...", which is far from perfect. If you ever tried Eclipse's gdb console window, you'll know what I mean... Instead of trying to multiplex console through MI, this command let's just leverage all the built in readline/editing support already inside gdb. The plan is for the MI frontend to start GDB in regular console mode, running inside a terminal emulator widget embedded in Eclipse (which already exists, for supporting the shell widget; other frontends have similar widgets), and then tell GDB to run a full MI interpreter on an specified input/output device, independent of the console. My original prototype planned to do things the other way around -- start GDB in MI mode, and then start an extra CLI console on separate tty. I handed over that prototype to Marc Khouzam @ Eclipse CDT, and after experimentation and discussion, we ended up concluding that starting GDB in CLI mode instead was both easier and actually also supported an interesting use case -- connect an Eclipse frontend to a GDB that is already running outside Eclipse. The current usage is "new-ui <interpreter> <tty>". E.g., on a terminal run this scriplet: $ cat gdb-client #!/bin/bash reset tty tail -f /dev/null $ gdb-client /dev/pts/15 Now run gdb on another terminal, and tell it to start a MI interpreter on the tty of the other terminal: ... (gdb) new-ui mi /dev/pts/15 New UI allocated Now back to the the gdb-client terminal, we'll get an MI prompt, ready for MI input: /dev/pts/15 =thread-group-added,id="i1" (gdb) You can also start a new UI running a CLI, with: (gdb) new-ui console /dev/pts/15 Though note that this console won't support readline command editing. It works as if "set editing off" was entered. gdb/ChangeLog: 2016-06-21 Pedro Alves <palves@redhat.com> * interps.c (set_top_level_interpreter): New function, factored out from captured_main. (interpreter_completer): Make extern. * interps.h (set_top_level_interpreter, interpreter_completer): New declarations. (captured_main): Use set_top_level_interpreter. * top.c [!O_NOCTTY] (O_NOCTTY): Define as 0. (open_terminal_stream, new_ui_command): New functions. (init_main): Install the "new-ui" command.
2016-06-21 02:11:55 +02:00
/* Set the current UI's top level interpreter to the interpreter named
NAME. Throws an error if NAME is not a known interpreter or the
interpreter fails to initialize. */
extern void set_top_level_interpreter (const char *name);
2003-02-06 06:30:17 +01:00
extern struct ui_out *interp_ui_out (struct interp *interp);
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.
2011-09-12 23:25:22 +02:00
extern void *interp_data (struct interp *interp);
extern const char *interp_name (struct interp *interp);
extern struct interp *interp_set_temp (const char *name);
2003-02-06 06:30:17 +01:00
extern int current_interp_named_p (const char *name);
Make display_gdb_prompt CLI-only. Enabling target-async by default will require implementing sync execution on top of an async target, much like foreground command are implemented on the CLI in async mode. In order to do that, we will need better control of when to print the MI prompt. Currently the interp->display_prompt_p hook is all we have, and MI just always returns false, meaning, make display_gdb_prompt a no-op. We'll need to be able to know to print the MI prompt in some of the conditions that display_gdb_prompt is called from the core, but not all. This is all a litte twisted currently. As we can see, display_gdb_prompt is really CLI specific, so make the console interpreters (console/tui) themselves call it. To be able to do that, and add a few different observers that the interpreters can use to distinguish when or why the the prompt is being printed: #1 - one called whenever a command is cancelled due to an error. #2 - another for when a foreground command just finished. In both cases, CLI wants to print the prompt, while MI doesn't. MI will want to print the prompt in the second case when in a special MI mode. The display_gdb_prompt call in interp_set made me pause. The comment there reads: /* Finally, put up the new prompt to show that we are indeed here. Also, display_gdb_prompt for the console does some readline magic which is needed for the console interpreter, at least... */ But, that looks very much like a no-op to me currently: - the MI interpreter always return false in the prompt hook, meaning actually display no prompt. - the interpreter used at that point is still quiet. And the console/tui interpreters return false in the prompt hook if they're quiet, meaning actually display no prompt. The only remaining possible use would then be the readline magic. But whatever that might have been, it's not reacheable today either, because display_gdb_prompt returns early, before touching readline if the interpreter returns false in the display_prompt_p hook. Tested on x86_64 Fedora 20, sync and async modes. gdb/ 2014-05-29 Pedro Alves <palves@redhat.com> * cli/cli-interp.c (cli_interpreter_display_prompt_p): Delete. (_initialize_cli_interp): Adjust. * event-loop.c: Include "observer.h". (start_event_loop): Notify 'command_error' observers instead of calling display_gdb_prompt. Remove FIXME comment. * event-top.c (display_gdb_prompt): Remove call into the interpreters. * inf-loop.c: Include "observer.h". (inferior_event_handler): Notify 'command_error' observers instead of calling display_gdb_prompt. * infrun.c (fetch_inferior_event): Notify 'sync_execution_done' observers instead of calling display_gdb_prompt. * interps.c (interp_set): Don't call display_gdb_prompt. (current_interp_display_prompt_p): Delete. * interps.h (interp_prompt_p): Delete declaration. (interp_prompt_p_ftype): Delete. (struct interp_procs) <prompt_proc_p>: Delete field. (current_interp_display_prompt_p): Delete declaration. * mi-interp.c (mi_interpreter_prompt_p): Delete. (_initialize_mi_interp): Adjust. * tui-interp.c (tui_init): Install 'sync_execution_done' and 'command_error' observers. (tui_on_sync_execution_done, tui_on_command_error): New functions. (tui_display_prompt_p): Delete. (_initialize_tui_interp): Adjust. gdb/doc/ 2014-05-29 Pedro Alves <palves@redhat.com> * observer.texi (sync_execution_done, command_error): New subjects.
2014-05-23 12:37:12 +02:00
/* Call this function to give the current interpreter an opportunity
to do any special handling of streams when logging is enabled or
disabled. START_LOG is 1 when logging is starting, 0 when it ends,
and OUT is the stream for the log file; it will be NULL when
logging is ending. LOGFILE is non-NULL if the output streams
are to be tees, with the log file as one of the outputs. */
extern int current_interp_set_logging (int start_log, struct ui_file *out,
struct ui_file *logfile);
/* Returns opaque data associated with the top-level interpreter. */
extern void *top_level_interpreter_data (void);
2008-04-19 08:09:15 +02:00
extern struct interp *top_level_interpreter (void);
2003-02-06 06:30:17 +01:00
/* Return the current UI's current interpreter. */
extern struct interp *current_interpreter (void);
PR gdb/13860: don't lose '-interpreter-exec console EXECUTION_COMMAND''s output in async mode. The other part of PR gdb/13860 is about console execution commands in MI getting their output half lost. E.g., take the finish command, executed on a frontend's GDB console: sync: finish &"finish\n" ~"Run till exit from #0 usleep (useconds=10) at ../sysdeps/unix/sysv/linux/usleep.c:27\n" ^running *running,thread-id="1" (gdb) ~"0x00000000004004d7 in foo () at stepinf.c:6\n" ~"6\t usleep (10);\n" ~"Value returned is $1 = 0\n" *stopped,reason="function-finished",frame={addr="0x00000000004004d7",func="foo",args=[],file="stepinf.c",fullname="/home/pedro/gdb/tests/stepinf.c",line="6"},thread-id="1",stopped-threads="all",core="1" async: finish &"finish\n" ~"Run till exit from #0 usleep (useconds=10) at ../sysdeps/unix/sysv/linux/usleep.c:27\n" ^running *running,thread-id="1" (gdb) *stopped,reason="function-finished",frame={addr="0x00000000004004d7",func="foo",args=[],file="stepinf.c",fullname="/home/pedro/gdb/tests/stepinf.c",line="6"},gdb-result-var="$1",return-value="0",thread-id="1",stopped-threads="all",core="0" Note how all the "Value returned" etc. output is missing in async mode. The same happens with e.g., catchpoints: =breakpoint-modified,bkpt={number="1",type="catchpoint",disp="keep",enabled="y",what="22016",times="1"} ~"\nCatchpoint " ~"1 (forked process 22016), 0x0000003791cbd8a6 in __libc_fork () at ../nptl/sysdeps/unix/sysv/linux/fork.c:131\n" ~"131\t pid = ARCH_FORK ();\n" *stopped,reason="fork",disp="keep",bkptno="1",newpid="22016",frame={addr="0x0000003791cbd8a6",func="__libc_fork",args=[],file="../nptl/sysdeps/unix/sysv/linux/fork.c",fullname="/usr/src/debug/glibc-2.14-394-g8f3b1ff/nptl/sysdeps/unix/sysv/linux/fork.c",line="131"},thread-id="1",stopped-threads="all",core="0" where all those ~ lines are missing in async mode, or just the "step" current line indication: s &"s\n" ^running *running,thread-id="all" (gdb) ~"13\t foo ();\n" *stopped,frame={addr="0x00000000004004ef",func="main",args=[{name="argc",value="1"},{name="argv",value="0x7fffffffdd78"}],file="stepinf.c",fullname="/home/pedro/gdb/tests/stepinf.c",line="13"},thread-id="1",stopped-threads="all",core="3" (gdb) Or in the case of the PRs example, the "Stopped due to shared library event" note: start &"start\n" ~"Temporary breakpoint 1 at 0x400608: file ../../../src/gdb/testsuite/gdb.mi/solib-main.c, line 21.\n" =breakpoint-created,bkpt={number="1",type="breakpoint",disp="del",enabled="y",addr="0x0000000000400608",func="main",file="../../../src/gdb/testsuite/gdb.mi/solib-main.c",fullname="/home/pedro/gdb/mygit/src/gdb/testsuite/gdb.mi/solib-main.c",line="21",times="0",original-location="main"} ~"Starting program: /home/pedro/gdb/mygit/build/gdb/testsuite/gdb.mi/solib-main \n" =thread-group-started,id="i1",pid="21990" =thread-created,id="1",group-id="i1" ^running *running,thread-id="all" (gdb) =library-loaded,id="/lib64/ld-linux-x86-64.so.2",target-name="/lib64/ld-linux-x86-64.so.2",host-name="/lib64/ld-linux-x86-64.so.2",symbols-loaded="0",thread-group="i1" ~"Stopped due to shared library event (no libraries added or removed)\n" *stopped,reason="solib-event",thread-id="1",stopped-threads="all",core="3" (gdb) IMO, if you're typing execution commands in a frontend's console, you expect to see their output. Indeed it's what you get in sync mode. I think async mode should do the same. Deciding what to mirror to the console wrt to breakpoints and random stops gets messy real fast. E.g., say "s" trips on a breakpoint. We'd clearly want to mirror the event to the console in this case. But what about more complicated cases like "s&; thread n; s&", and one of those steps spawning a new thread, and that thread hitting a breakpoint? It's impossible in general to track whether the thread had any relation to the commands that had been executed. So I think we should just simplify and always mirror breakpoints and random events to the console. Notes: - mi->out is the same as gdb_stdout when MI is the current interpreter. I think that referring to that directly is cleaner. An earlier revision of this patch made the changes that are now done in mi_on_normal_stop directly in infrun.c:normal_stop, and so not having an obvious place to put the new uiout by then, and not wanting to abuse CLI's uiout, I made a temporary uiout when necessary. - Hopefuly the rest of the patch is more or less obvious given the comments added. Tested on x86_64 Fedora 20, no regressions. 2014-05-21 Pedro Alves <palves@redhat.com> PR gdb/13860 * gdbthread.h (struct thread_control_state): New field `command_interp'. * infrun.c (follow_fork): Copy the new thread control field to the child fork thread. (clear_proceed_status_thread): Clear the new thread control field. (proceed): Set the new thread control field. * interps.h (command_interp): Declare. * interps.c (command_interpreter): New global. (command_interp): New function. (interp_exec): Set `command_interpreter' while here. * cli-out.c (cli_uiout_dtor): New function. (cli_ui_out_impl): Install it. * mi/mi-interp.c: Include cli-out.h. (mi_cmd_interpreter_exec): Add comment. (restore_current_uiout_cleanup): New function. (ui_out_free_cleanup): New function. (mi_on_normal_stop): If finishing an execution command started by a CLI command, or any kind of breakpoint-like event triggered, print the stop event to the output (CLI) stream. * mi/mi-out.c (mi_ui_out_impl): Install NULL `dtor' handler. 2014-05-21 Pedro Alves <palves@redhat.com> PR gdb/13860 * gdb.mi/mi-cli.exp (line_callee4_next_step): New global. (top level): Test that output related to execution commands is sent to the console with CLI commands, but not with MI commands. Test that breakpoint events are always mirrored to the console. Also expect the new source line to be output after a "next" in async mode too. Make it a pass/fail test. * gdb.mi/mi-solib.exp: Test that the CLI solib event note is output. * lib/mi-support.exp (mi_gdb_expect_cli_output): New procedure.
2014-03-11 21:31:36 +01:00
extern struct interp *command_interp (void);
2003-06-08 Andrew Cagney <cagney@redhat.com> * acinclude.m4 (gcc_AC_CHECK_DECL, (gcc_AC_CHECK_DECL): Stolen from GCC's acinclude.m4. * configure.in: Check for getopt's delcaration. * aclocal.m4, config.in, configure: Re-generate. * main.c (error_init): Delete declaration. * defs.h (error_init): Declare. * rs6000-tdep.c (rs6000_fetch_pointer_argument): Make static. (rs6000_convert_from_func_ptr_addr): Make static. (_initialize_rs6000_tdep): Add declaration. * cli/cli-cmds.c (dont_repeat): Delete declaration. (show_commands, set_verbose, show_history): Delete declaration. * top.h (set_verbose): Add declaration. (show_history, set_history, show_commands): Add declaration. (do_restore_instream_cleanup): Add declaration. * objc-lang.c (specialcmp): Make static. (print_object_command): Make static. (find_objc_msgsend): Make static. (find_objc_msgcall_submethod_helper): Make static. (find_objc_msgcall_submethod): Make static. (_initialize_objc_language): Add declaration. (find_implementation_from_class): Make static. (find_implementation): Make static. * objc-exp.y (yylex): Delete lookup_struct_typedef declaration. * objc-lang.h (lookup_struct_typedef): Add declaration. * cli/cli-interp.c (_initialize_cli_interp): Add declaration. * cli/cli-script.c (clear_hook_in_cleanup): Make static. (do_restore_user_call_depth): Make static. (do_restore_instream_cleanup): Delete declaration. (dont_repeat): Delete declaration. * cli/cli-decode.c (add_abbrev_cmd): Delete function. * cli/cli-dump.c (_initialize_cli_dump): Add declaration. * reggroups.c (_initialize_reggroup): Add declaration. * cp-support.c (_initialize_cp_support): Add declaration. * cp-abi.c (_initialize_cp_abi): Add declaration. * hpacc-abi.c (_initialize_hpacc_abi): Add declaration. * gnu-v3-abi.c (gnuv3_baseclass_offset): Make static. (_initialize_gnu_v3_abi): Add declaration. * gnu-v2-abi.c (gnuv2_value_rtti_type): Make static. (_initialize_gnu_v2_abi): Add declaration. * frame-base.c (_initialize_frame_base): Add declaration. * doublest.c (floatformat_from_length): Make static. * frame-unwind.c (_initialize_frame_unwind): Add declaration. * frame.c (create_sentinel_frame): Make static. (_initialize_frame): Add declaration. * top.c (do_catch_errors): Make static. (gdb_rl_operate_and_get_next_completion): Make static. * typeprint.c: Include "typeprint.h". * sentinel-frame.c (sentinel_frame_prev_register): Make static. (sentinel_frame_this_id): Make static. * p-valprint.c (_initialize_pascal_valprint): Add declaration. * ui-out.c (make_cleanup_ui_out_begin_end): Delete function. * dwarf2-frame.c (dwarf2_frame_cache): Make static. * p-exp.y (push_current_type, pop_current_type): ISO C declaration. * dwarf2expr.h (dwarf_expr_context): ISO C declaration. * maint.c (maintenance_print_architecture): Make static. * signals/signals.c (_initialize_signals): Add declaration. * std-regs.c (_initialize_frame_reg): Add declaration. * jv-exp.y (push_variable): ISO C definition. (push_qualified_expression_name): Ditto. * memattr.c (_initialize_mem): Add declaration. * remote.c (remote_check_watch_resources): Make static. (remote_stopped_by_watchpoint): Make static. (remote_stopped_data_address): Make static. * d10v-tdep.c (nr_dmap_regs): Make static. (a0_regnum): Make static. (d10v_frame_unwind_cache): Make static. (d10v_frame_p): Make static. * osabi.c (show_osabi): Make static. (_initialize_gdb_osabi): Add extern declaration. * gdbtypes.c (make_qualified_type): Make static. (safe_parse_type): Make static. * macrocmd.c (_initialize_macrocmd): Add extern declaration. * macrotab.c (macro_bcache_free): Make static. * interps.c (interp_set_quiet): Make static. (interpreter_exec_cmd): Make static. * stack.h (select_frame_command): New file. * stack.c: Include "stack.h". (select_frame_command_wrapper): Delete function. (select_frame_command): Make global. * infcall.c: Include "infcall.h". * linespec.c: Include "linespec.h". * symfile.c (sections_overlap): Make static. * cp-support.h (cp_initialize_namespace): ISO C declaration. * charset.c (_initialize_charset): Add missing prototype. * regcache.c (init_legacy_regcache_descr): Make static. (do_regcache_xfree): Make static. (regcache_xfer_part): Make static. (_initialize_regcache): Add missing prototype. * breakpoint.c (parse_breakpoint_sals): Make static. (breakpoint_sals_to_pc): Make static. * interps.h (clear_interpreter_hooks): ISO C declaration. * Makefile.in (stack_h): Define. (stack.o, typeprint.o, mi-main.o): Update dependencies. (mi-cmd-stack.o, infcall.o, linespec.o): Update dependencies. Index: mi/ChangeLog 2003-06-08 Andrew Cagney <cagney@redhat.com> * mi-parse.c (_initialize_mi_parse): Delete function. * mi-main.c: Include "mi-main.h". * mi-interp.c (_initialize_mi_interp): Add declaration. * mi-cmd-stack.c: Include "stack.h". (select_frame_command_wrapper): Delete extern declaration. (mi_cmd_stack_select_frame): Replace select_frame_command_wrapper with select_frame_command.
2003-06-08 20:27:14 +02:00
extern void clear_interpreter_hooks (void);
2003-02-06 06:30:17 +01:00
Make command line editing (use of readline) be per UI Due to the way that readline's API works (based on globals), we can only have one instance of readline in a process. So the goal of this patch is to only allow editing in the main UI, and make sure that only one UI calls into readline. Some MI paths touch readline variables currently, which is bad as that is changing variables that matter for the main console UI. This patch fixes those. This actually fixes a nasty bug -- starting gdb in MI mode ("gdb -i=mi"), and then doing "set editing on" crashes GDB, because MI is not prepared to use readline: set editing on &"set editing on\n" =cmd-param-changed,param="editing",value="on" ^done (gdb) p 1 readline: readline_callback_read_char() called with no handler! Aborted (core dumped) The fix for that was to add an interp_proc method to query the interpreter whether it actually supports editing. New test included. gdb/ChangeLog: 2016-06-21 Pedro Alves <palves@redhat.com> PR mi/20034 * cli/cli-interp.c: Include cli-interp.h and event-top.h. (cli_interpreter_resume): Pass 1 to gdb_setup_readline. Set the UI's input_handler here. (cli_interpreter_supports_command_editing): New function. (cli_interp_procs): Install it. * cli/cli-interp.h: New file. * event-top.c (async_command_editing_p): Rename to ... (set_editing_cmd_var): ... this. (change_line_handler): Add parameter 'editing', and use it. Bail early if the interpreter doesn't support editing. Don't touch readline state if editing is off. (gdb_rl_callback_handler_remove, gdb_rl_callback_handler_install) (gdb_rl_callback_handler_reinstall): Assert the current UI is the main UI. (display_gdb_prompt): Don't call gdb_rl_callback_handler_remove if not using readline. Check whether the current UI is using command editing instead of checking the async_command_editing_p global. (set_async_editing_command): Delete. (gdb_setup_readline): Add 'editing' parameter. Only allow editing on the main UI. Don't touch readline state if editing is off. (gdb_disable_readline): Don't touch readline state if editing is off. * event-top.h (gdb_setup_readline): Add 'int' parameter. (set_async_editing_command): Delete declaration. (change_line_handler, command_line_handler): Declare. (async_command_editing_p): Rename to ... (set_editing_cmd_var): ... this. * infrun.c (reinstall_readline_callback_handler_cleanup): Check whether the current UI has editing enabled rather than checking the async_command_editing_p global. * interps.c (interp_supports_command_editing): New function. * interps.h (interp_supports_command_editing_ftype): New typedef. (struct interp_procs) <supports_command_editing_proc>: New field. (interp_supports_command_editing): Declare. * mi/mi-interp.c (mi_interpreter_resume): Pass 0 to gdb_setup_readline. Don't clear the async_command_editing_p global. Update comments. * top.c (gdb_readline_wrapper_line, gdb_readline_wrapper): Check whether the current UI has editing enabled rather than checking the async_command_editing_p global. Don't touch readline state if editing is off. (undo_terminal_modifications_before_exit): Switch to the main UI. Unconditionally call gdb_disable_readline. (set_editing): New function. (show_async_command_editing_p): Rename to ... (show_editing): ... this. Show the state of the current UI. (_initialize_top): Adjust. * top.h (struct ui) <command_editing>: New field. * tui/tui-interp.c: Include cli/cli-interp.h. (tui_resume): Pass 1 to gdb_setup_readline. Set the UI's input_handler. (tui_interp_procs): Install cli_interpreter_supports_command_editing. * tui/tui-io.c (tui_getc): Check whether the current UI has editing enabled rather than checking the async_command_editing_p global. gdb/testsuite/ChangeLog: 2016-06-21 Pedro Alves <palves@redhat.com> PR mi/20034 * gdb.mi/mi-editing.exp: New file.
2016-06-21 02:11:48 +02:00
/* Returns true if INTERP supports using the readline library; false
if it uses GDB's own simplified form of readline. */
extern int interp_supports_command_editing (struct interp *interp);
Simplify starting the command event loop All interpreter types (CLI/TUI/MI) print the prompt, and then call start_event_loop. Because we'll need an interpreter hook to display the interpreter-specific prompt before going back to the event loop, without actually starting an event loop, this patch moves the start_event_loop call to common code, and replaces the command_loop hook with a pre_command_look hook, that now just prints the prompt. Turns out to be a cleanup on its own right anyway. gdb/ChangeLog: 2016-06-21 Pedro Alves <palves@redhat.com> * cli/cli-interp.c (cli_interpreter_pre_command_loop): New function. (cli_interp_procs): Install it instead of cli_command_loop. * cli/cli-interp.h (cli_interpreter_pre_command_loop): Declare. * event-top.c (cli_command_loop): Delete. * interps.c (interp_new): Remove reference to command_loop_proc. (current_interp_command_loop): Delete. (interp_pre_command_loop): New function. (interp_command_loop_ftype): Delete. * interps.h (interp_pre_command_loop_ftype): New typedef. (struct interp_procs) <command_loop_proc>: Delele field. <pre_command_loop_proc>: New field. (current_interp_command_loop): Delete declaration. (interp_pre_command_loop): New declaration. * main.c (captured_command_loop): Call interp_pre_command_loop instead of current_interp_command_loop and start an event loop. * mi/mi-interp.c (mi_command_loop): Delete. (mi_interpreter_pre_command_loop): New. (mi_interp_procs): Update. * tui/tui-interp.c (tui_interp_procs): Install cli_interpreter_pre_command_loop instead of cli_command_loop.
2016-06-21 02:11:51 +02:00
/* Called before starting an event loop, to give the interpreter a
chance to e.g., print a prompt. */
extern void interp_pre_command_loop (struct interp *interp);
Add new command to create extra console/mi UIs With all the previous plumbing in place, it's now easy to add a command that actually creates a new console/mi UI. The intended use case is to make it possible and easy for MI frontends to provide a fully featured GDB console to users, with readline support, command line editing, history, etc., just like if gdb was started on the command line. Currently MI frontends have to try to implement all of that theirselves and make use of "-interpreter-exec console ...", which is far from perfect. If you ever tried Eclipse's gdb console window, you'll know what I mean... Instead of trying to multiplex console through MI, this command let's just leverage all the built in readline/editing support already inside gdb. The plan is for the MI frontend to start GDB in regular console mode, running inside a terminal emulator widget embedded in Eclipse (which already exists, for supporting the shell widget; other frontends have similar widgets), and then tell GDB to run a full MI interpreter on an specified input/output device, independent of the console. My original prototype planned to do things the other way around -- start GDB in MI mode, and then start an extra CLI console on separate tty. I handed over that prototype to Marc Khouzam @ Eclipse CDT, and after experimentation and discussion, we ended up concluding that starting GDB in CLI mode instead was both easier and actually also supported an interesting use case -- connect an Eclipse frontend to a GDB that is already running outside Eclipse. The current usage is "new-ui <interpreter> <tty>". E.g., on a terminal run this scriplet: $ cat gdb-client #!/bin/bash reset tty tail -f /dev/null $ gdb-client /dev/pts/15 Now run gdb on another terminal, and tell it to start a MI interpreter on the tty of the other terminal: ... (gdb) new-ui mi /dev/pts/15 New UI allocated Now back to the the gdb-client terminal, we'll get an MI prompt, ready for MI input: /dev/pts/15 =thread-group-added,id="i1" (gdb) You can also start a new UI running a CLI, with: (gdb) new-ui console /dev/pts/15 Though note that this console won't support readline command editing. It works as if "set editing off" was entered. gdb/ChangeLog: 2016-06-21 Pedro Alves <palves@redhat.com> * interps.c (set_top_level_interpreter): New function, factored out from captured_main. (interpreter_completer): Make extern. * interps.h (set_top_level_interpreter, interpreter_completer): New declarations. (captured_main): Use set_top_level_interpreter. * top.c [!O_NOCTTY] (O_NOCTTY): Define as 0. (open_terminal_stream, new_ui_command): New functions. (init_main): Install the "new-ui" command.
2016-06-21 02:11:55 +02:00
/* List the possible interpreters which could complete the given
text. */
extern VEC (char_ptr) *interpreter_completer (struct cmd_list_element *ignore,
const char *text,
const char *word);
2003-02-06 06:30:17 +01:00
/* well-known interpreters */
#define INTERP_CONSOLE "console"
#define INTERP_MI1 "mi1"
#define INTERP_MI2 "mi2"
#define INTERP_MI3 "mi3"
2003-02-06 06:30:17 +01:00
#define INTERP_MI "mi"
#define INTERP_TUI "tui"
#define INTERP_INSIGHT "insight"
2003-02-06 06:30:17 +01:00
#endif