diff options
-rw-r--r-- | gdb/ChangeLog | 12 | ||||
-rw-r--r-- | gdb/interps.c | 20 | ||||
-rw-r--r-- | gdb/interps.h | 11 | ||||
-rw-r--r-- | gdb/main.c | 12 | ||||
-rw-r--r-- | gdb/top.c | 85 |
5 files changed, 127 insertions, 13 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ed1f53a..45e41f1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,17 @@ 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 Pedro Alves <palves@redhat.com> + * cli/cli-script.c (read_next_line): Adjust to per-UI stdin. (read_command_lines): Use input_interactive_p instead of input_from_terminal_p. diff --git a/gdb/interps.c b/gdb/interps.c index fdf1479..163c837 100644 --- a/gdb/interps.c +++ b/gdb/interps.c @@ -319,6 +319,21 @@ interp_lookup (struct ui *ui, const char *name) return NULL; } +/* See interps.h. */ + +void +set_top_level_interpreter (const char *name) +{ + /* Find it. */ + struct interp *interp = interp_lookup (current_ui, name); + + if (interp == NULL) + error (_("Interpreter `%s' unrecognized"), name); + /* Install it. */ + if (!interp_set (interp, 1)) + error (_("Interpreter `%s' failed to initialize."), name); +} + /* Returns the current interpreter. */ struct ui_out * @@ -550,8 +565,9 @@ interpreter_exec_cmd (char *args, int from_tty) do_cleanups (cleanup); } -/* List the possible interpreters which could complete the given text. */ -static VEC (char_ptr) * +/* See interps.h. */ + +VEC (char_ptr) * interpreter_completer (struct cmd_list_element *ignore, const char *text, const char *word) { diff --git a/gdb/interps.h b/gdb/interps.h index 4ac0845..97d510f 100644 --- a/gdb/interps.h +++ b/gdb/interps.h @@ -95,6 +95,11 @@ extern int interp_set (struct interp *interp, int top_level); the interpreter. */ extern struct interp *interp_lookup (struct ui *ui, const char *name); +/* 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); + 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); @@ -131,6 +136,12 @@ extern int interp_supports_command_editing (struct interp *interp); chance to e.g., print a prompt. */ extern void interp_pre_command_loop (struct interp *interp); +/* 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); + /* well-known interpreters */ #define INTERP_CONSOLE "console" #define INTERP_MI1 "mi1" @@ -963,17 +963,7 @@ captured_main (void *data) /* Install the default UI. All the interpreters should have had a look at things by now. Initialize the default interpreter. */ - - { - /* Find it. */ - struct interp *interp = interp_lookup (current_ui, interpreter_p); - - if (interp == NULL) - error (_("Interpreter `%s' unrecognized"), interpreter_p); - /* Install it. */ - if (!interp_set (interp, 1)) - error (_("Interpreter `%s' failed to initialize."), interpreter_p); - } + set_top_level_interpreter (interpreter_p); /* FIXME: cagney/2003-02-03: The big hack (part 2 of 2) that lets GDB retain the old MI1 interpreter startup behavior. Output the @@ -74,6 +74,10 @@ # include "tui/tui.h" #endif +#ifndef O_NOCTTY +# define O_NOCTTY 0 +#endif + extern void initialize_all_files (void); #define PROMPT(X) the_prompts.prompt_stack[the_prompts.top + X].prompt @@ -320,6 +324,79 @@ delete_ui (struct ui *todel) free_ui (ui); } +/* Open file named NAME for read/write, making sure not to make it the + controlling terminal. */ + +static FILE * +open_terminal_stream (const char *name) +{ + int fd; + + fd = open (name, O_RDWR | O_NOCTTY); + if (fd < 0) + perror_with_name (_("opening terminal failed")); + + return fdopen (fd, "w+"); +} + +/* Implementation of the "new-ui" command. */ + +static void +new_ui_command (char *args, int from_tty) +{ + struct ui *ui; + struct interp *interp; + FILE *stream[3] = { NULL, NULL, NULL }; + int i; + int res; + int argc; + char **argv; + const char *interpreter_name; + const char *tty_name; + struct cleanup *back_to; + struct cleanup *streams_chain; + + dont_repeat (); + + argv = gdb_buildargv (args); + back_to = make_cleanup_freeargv (argv); + argc = countargv (argv); + + if (argc < 2) + error (_("usage: new-ui <interpreter> <tty>")); + + interpreter_name = argv[0]; + tty_name = argv[1]; + + streams_chain = make_cleanup (null_cleanup, NULL); + + /* Open specified terminal, once for each of + stdin/stdout/stderr. */ + for (i = 0; i < 3; i++) + { + stream[i] = open_terminal_stream (tty_name); + make_cleanup_fclose (stream[i]); + } + + ui = new_ui (stream[0], stream[1], stream[2]); + + discard_cleanups (streams_chain); + + ui->async = 1; + + make_cleanup (restore_ui_cleanup, current_ui); + current_ui = ui; + + set_top_level_interpreter (interpreter_name); + + interp_pre_command_loop (top_level_interpreter ()); + + /* This restores the previous UI. */ + do_cleanups (back_to); + + printf_unfiltered ("New UI allocated\n"); +} + /* Handler for SIGHUP. */ #ifdef SIGHUP @@ -1923,6 +2000,8 @@ set_history_filename (char *args, int from_tty, struct cmd_list_element *c) static void init_main (void) { + struct cmd_list_element *c; + /* Initialize the prompt to a simple "(gdb) " prompt or to whatever the DEFAULT_PROMPT is. */ set_prompt (DEFAULT_PROMPT); @@ -2060,6 +2139,12 @@ input settings."), NULL, show_interactive_mode, &setlist, &showlist); + + c = add_cmd ("new-ui", class_support, new_ui_command, _("\ +Create a new UI. It takes two arguments:\n\ +The first argument is the name of the interpreter to run.\n\ +The second argument is the terminal the UI runs on.\n"), &cmdlist); + set_cmd_completer (c, interpreter_completer); } void |