aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog12
-rw-r--r--gdb/interps.c20
-rw-r--r--gdb/interps.h11
-rw-r--r--gdb/main.c12
-rw-r--r--gdb/top.c85
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"
diff --git a/gdb/main.c b/gdb/main.c
index 947ed55..5477379 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -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
diff --git a/gdb/top.c b/gdb/top.c
index 7506c45..3174f3c 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -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