/* Top level stuff for GDB, the GNU debugger.
- Copyright 1999 Free Software Foundation, Inc.
+
+ Copyright 1999, 2000, 2001, 2002, 2004, 2005 Free Software
+ Foundation, Inc.
+
Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.
This file is part of GDB.
#include "defs.h"
#include "top.h"
#include "inferior.h"
+#include "target.h"
#include "terminal.h" /* for job_control */
-#include <signal.h>
#include "event-loop.h"
+#include "event-top.h"
+#include "interps.h"
+#include <signal.h>
+#include "exceptions.h"
/* For dont_repeat() */
#include "gdbcmd.h"
/* readline include files */
-#include <readline/readline.h>
-#include <readline/history.h>
+#include "readline/readline.h"
+#include "readline/history.h"
/* readline defines this. */
#undef savestring
-extern void _initialize_event_loop PARAMS ((void));
-
-static void command_line_handler PARAMS ((char *));
-static void command_line_handler_continuation PARAMS ((struct continuation_arg *));
-void gdb_readline2 PARAMS ((void));
-void pop_prompt PARAMS ((void));
-void push_prompt PARAMS ((char *, char *, char *));
-static void change_line_handler PARAMS ((void));
-static void change_annotation_level PARAMS ((void));
-static void command_handler PARAMS ((char *));
+static void rl_callback_read_char_wrapper (gdb_client_data client_data);
+static void command_line_handler (char *rl);
+static void command_line_handler_continuation (struct continuation_arg *arg);
+static void change_line_handler (void);
+static void change_annotation_level (void);
+static void command_handler (char *command);
+static void async_do_nothing (gdb_client_data arg);
+static void async_disconnect (gdb_client_data arg);
+static void async_stop_sig (gdb_client_data arg);
+static void async_float_handler (gdb_client_data arg);
/* Signal handlers. */
-void handle_sigint PARAMS ((int));
-static void handle_sigquit PARAMS ((int));
-static void handle_sighup PARAMS ((int));
-static void handle_sigfpe PARAMS ((int));
-#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
-static void handle_sigwinch PARAMS ((int));
-#endif
-/* Signal to catch ^Z typed while reading a command: SIGTSTP or SIGCONT. */
-#ifndef STOP_SIGNAL
-#ifdef SIGTSTP
-#define STOP_SIGNAL SIGTSTP
-void handle_stop_sig PARAMS ((int));
+#ifdef SIGQUIT
+static void handle_sigquit (int sig);
#endif
+static void handle_sighup (int sig);
+static void handle_sigfpe (int sig);
+#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
+static void handle_sigwinch (int sig);
#endif
/* Functions to be invoked by the event loop in response to
signals. */
-static void async_do_nothing PARAMS ((gdb_client_data));
-static void async_disconnect PARAMS ((gdb_client_data));
-static void async_float_handler PARAMS ((gdb_client_data));
-static void async_stop_sig PARAMS ((gdb_client_data));
+static void async_do_nothing (gdb_client_data);
+static void async_disconnect (gdb_client_data);
+static void async_float_handler (gdb_client_data);
+static void async_stop_sig (gdb_client_data);
/* Readline offers an alternate interface, via callback
functions. These are all included in the file callback.c in the
line of input is ready. CALL_READLINE is to be set to the function
that readline offers as callback to the event_loop. */
-void (*input_handler) PARAMS ((char *));
-void (*call_readline) PARAMS ((void));
+void (*input_handler) (char *);
+void (*call_readline) (gdb_client_data);
/* Important variables for the event loop. */
handlers mark these functions as ready to be executed and the event
loop, in a later iteration, calls them. See the function
invoke_async_signal_handler. */
-PTR sigint_token;
+void *sigint_token;
#ifdef SIGHUP
-PTR sighup_token;
+void *sighup_token;
+#endif
+#ifdef SIGQUIT
+void *sigquit_token;
#endif
-PTR sigquit_token;
-PTR sigfpe_token;
+void *sigfpe_token;
#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
-PTR sigwinch_token;
+void *sigwinch_token;
#endif
#ifdef STOP_SIGNAL
-PTR sigtstp_token;
+void *sigtstp_token;
#endif
/* Structure to save a partially entered command. This is used when
char *linebuffer_ptr;
}
readline_input_state;
+
+/* This hook is called by rl_callback_read_char_wrapper after each
+ character is processed. */
+void (*after_char_processing_hook) ();
\f
+/* Wrapper function for calling into the readline library. The event
+ loop expects the callback function to have a paramter, while readline
+ expects none. */
+static void
+rl_callback_read_char_wrapper (gdb_client_data client_data)
+{
+ rl_callback_read_char ();
+ if (after_char_processing_hook)
+ (*after_char_processing_hook) ();
+}
+
/* Initialize all the necessary variables, start the event loop,
register readline, and stdin, start the loop. */
void
-cli_command_loop ()
+cli_command_loop (void)
{
int length;
char *a_prompt;
which the user sets editing on again, by restoring readline
handling of the input. */
static void
-change_line_handler ()
+change_line_handler (void)
{
+ /* NOTE: this operates on input_fd, not instream. If we are reading
+ commands from a file, instream will point to the file. However in
+ async mode, we always read commands from a file with editing
+ off. This means that the 'set editing on/off' will have effect
+ only on the interactive session. */
+
if (async_command_editing_p)
{
/* Turn on editing by using readline. */
- call_readline = rl_callback_read_char;
+ call_readline = rl_callback_read_char_wrapper;
input_handler = command_line_handler;
}
else
first thing from .gdbinit. */
input_handler = command_line_handler;
}
-
- /* To tell the event loop to change the handler associated with the
- input file descriptor, we need to create a new event source,
- corresponding to the same fd, but with a new event handler
- function. */
- /* NOTE: this operates on input_fd, not instream. If we are reading
- commands from a file, instream will point to the file. However in
- async mode, we always read commands from a file with editing
- off. This means that the 'set editing on/off' will have effect
- only on the interactive session. */
- delete_file_handler (input_fd);
- add_file_handler (input_fd, call_readline, 0);
}
/* Displays the prompt. The prompt that is displayed is the current
3. Other????
FIXME: 2. & 3. not implemented yet for async. */
void
-display_gdb_prompt (new_prompt)
- char *new_prompt;
+display_gdb_prompt (char *new_prompt)
{
int prompt_length = 0;
char *gdb_prompt = get_prompt ();
+ /* Each interpreter has its own rules on displaying the command
+ prompt. */
+ if (!current_interp_display_prompt_p ())
+ return;
- if (target_executing && sync_execution)
+ if (target_executing && sync_execution)
{
/* This is to trick readline into not trying to display the
- prompt. Even though we display the prompt using this
- function, readline still tries to do its own display if we
- don't call rl_callback_handler_install and
- rl_callback_handler_remove (which readline detects because a
- global variable is not set). If readline did that, it could
- mess up gdb signal handlers for SIGINT. Readline assumes
- that between calls to rl_set_signals and rl_clear_signals gdb
- doesn't do anything with the signal handlers. Well, that's
- not the case, because when the target executes we change the
- SIGINT signal handler. If we allowed readline to display the
- prompt, the signal handler change would happen exactly
- between the calls to the above two functions.
- Calling rl_callback_handler_remove(), does the job. */
+ prompt. Even though we display the prompt using this
+ function, readline still tries to do its own display if we
+ don't call rl_callback_handler_install and
+ rl_callback_handler_remove (which readline detects because a
+ global variable is not set). If readline did that, it could
+ mess up gdb signal handlers for SIGINT. Readline assumes
+ that between calls to rl_set_signals and rl_clear_signals gdb
+ doesn't do anything with the signal handlers. Well, that's
+ not the case, because when the target executes we change the
+ SIGINT signal handler. If we allowed readline to display the
+ prompt, the signal handler change would happen exactly
+ between the calls to the above two functions.
+ Calling rl_callback_handler_remove(), does the job. */
rl_callback_handler_remove ();
return;
character position to be off, since the newline we read from
the user is not accounted for. */
fputs_unfiltered (new_prompt, gdb_stdout);
-
-#ifdef MPW
- /* Move to a new line so the entered line doesn't have a prompt
- on the front of it. */
- fputs_unfiltered ("\n", gdb_stdout);
-#endif /* MPW */
gdb_flush (gdb_stdout);
}
}
it pops the top of the prompt stack when we want the annotation level
to be the normal ones (1 or 0). */
static void
-change_annotation_level ()
+change_annotation_level (void)
{
char *prefix, *suffix;
{
/* The prompt stack has not been initialized to "", we are
using gdb w/o the --async switch */
- warning ("Command has same effect as set annotate");
+ warning (_("Command has same effect as set annotate"));
return;
}
strings, except when the annotation level is 2. Memory is allocated
within savestring for the new prompt. */
void
-push_prompt (prefix, prompt, suffix)
- char *prefix;
- char *prompt;
- char *suffix;
+push_prompt (char *prefix, char *prompt, char *suffix)
{
the_prompts.top++;
PREFIX (0) = savestring (prefix, strlen (prefix));
/* Pops the top of the prompt stack, and frees the memory allocated for it. */
void
-pop_prompt ()
+pop_prompt (void)
{
/* If we are not during a 'synchronous' execution command, in which
case, the top prompt would be empty. */
in effect, until the user does another 'set prompt'. */
if (strcmp (PROMPT (0), PROMPT (-1)))
{
- free (PROMPT (-1));
+ xfree (PROMPT (-1));
PROMPT (-1) = savestring (PROMPT (0), strlen (PROMPT (0)));
}
- free (PREFIX (0));
- free (PROMPT (0));
- free (SUFFIX (0));
+ xfree (PREFIX (0));
+ xfree (PROMPT (0));
+ xfree (SUFFIX (0));
the_prompts.top--;
}
+
+/* When there is an event ready on the stdin file desriptor, instead
+ of calling readline directly throught the callback function, or
+ instead of calling gdb_readline2, give gdb a chance to detect
+ errors and do something. */
+void
+stdin_event_handler (int error, gdb_client_data client_data)
+{
+ if (error)
+ {
+ printf_unfiltered (_("error detected on stdin\n"));
+ delete_file_handler (input_fd);
+ discard_all_continuations ();
+ /* If stdin died, we may as well kill gdb. */
+ quit_command ((char *) 0, stdin == instream);
+ }
+ else
+ (*call_readline) (client_data);
+}
+
+/* Re-enable stdin after the end of an execution command in
+ synchronous mode, or after an error from the target, and we aborted
+ the exec operation. */
+
+void
+async_enable_stdin (void *dummy)
+{
+ /* See NOTE in async_disable_stdin() */
+ /* FIXME: cagney/1999-09-27: Call this before clearing
+ sync_execution. Current target_terminal_ours() implementations
+ check for sync_execution before switching the terminal. */
+ target_terminal_ours ();
+ pop_prompt ();
+ sync_execution = 0;
+}
+
+/* Disable reads from stdin (the console) marking the command as
+ synchronous. */
+
+void
+async_disable_stdin (void)
+{
+ sync_execution = 1;
+ push_prompt ("", "", "");
+ /* FIXME: cagney/1999-09-27: At present this call is technically
+ redundant since infcmd.c and infrun.c both already call
+ target_terminal_inferior(). As the terminal handling (in
+ sync/async mode) is refined, the duplicate calls can be
+ eliminated (Here or in infcmd.c/infrun.c). */
+ target_terminal_inferior ();
+ /* Add the reinstate of stdin to the list of cleanups to be done
+ in case the target errors out and dies. These cleanups are also
+ done in case of normal successful termination of the execution
+ command, by complete_execution(). */
+ make_exec_error_cleanup (async_enable_stdin, NULL);
+}
\f
+
/* Handles a gdb command. This function is called by
command_line_handler, which has processed one or more input lines
into COMMAND. */
function. The command_loop function will be obsolete when we
switch to use the event loop at every execution of gdb. */
static void
-command_handler (command)
- char *command;
+command_handler (char *command)
{
struct cleanup *old_chain;
int stdin_is_tty = ISATTY (stdin);
extern int display_time;
extern int display_space;
-#if defined(TUI)
- extern int insert_mode;
-#endif
-
quit_flag = 0;
if (instream == stdin && stdin_is_tty)
reinitialize_more_filter ();
- old_chain = make_cleanup ((make_cleanup_func) command_loop_marker, 0);
+ old_chain = make_cleanup (null_cleanup, 0);
-#if defined(TUI)
- insert_mode = 0;
-#endif
/* If readline returned a NULL command, it means that the
connection with the terminal is gone. This happens at the
end of a testsuite run, after Expect has hung up
if (display_space)
{
#ifdef HAVE_SBRK
- extern char **environ;
char *lim = (char *) sbrk (0);
-
- space_at_cmd_start = (long) (lim - (char *) &environ);
+ space_at_cmd_start = lim - lim_at_start;
#endif
}
execute_command (command, instream == stdin);
/* Set things up for this function to be compete later, once the
- executin has completed, if we are doing an execution command,
+ execution has completed, if we are doing an execution command,
otherwise, just go ahead and finish. */
- if (target_has_async && target_executing)
+ if (target_can_async_p () && target_executing)
{
arg1 =
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
arg1->next = arg2;
arg2->next = NULL;
- arg1->data = (PTR) time_at_cmd_start;
- arg2->data = (PTR) space_at_cmd_start;
+ arg1->data.longint = time_at_cmd_start;
+#ifdef HAVE_SBRK
+ arg2->data.longint = space_at_cmd_start;
+#endif
add_continuation (command_line_handler_continuation, arg1);
}
/* Do any commands attached to breakpoint we stopped at. Only if we
are always running synchronously. Or if we have just executed a
command that doesn't start the target. */
- if (!target_has_async || !target_executing)
+ if (!target_can_async_p () || !target_executing)
{
bpstat_do_actions (&stop_bpstat);
do_cleanups (old_chain);
{
long cmd_time = get_run_time () - time_at_cmd_start;
- printf_unfiltered ("Command execution time: %ld.%06ld\n",
+ printf_unfiltered (_("Command execution time: %ld.%06ld\n"),
cmd_time / 1000000, cmd_time % 1000000);
}
if (display_space)
{
#ifdef HAVE_SBRK
- extern char **environ;
char *lim = (char *) sbrk (0);
- long space_now = lim - (char *) &environ;
+ long space_now = lim - lim_at_start;
long space_diff = space_now - space_at_cmd_start;
- printf_unfiltered ("Space used: %ld (%c%ld for this command)\n",
+ printf_unfiltered (_("Space used: %ld (%c%ld for this command)\n"),
space_now,
(space_diff >= 0 ? '+' : '-'),
space_diff);
are always running synchronously. Or if we have just executed a
command that doesn't start the target. */
void
-command_line_handler_continuation (arg)
- struct continuation_arg *arg;
+command_line_handler_continuation (struct continuation_arg *arg)
{
extern int display_time;
extern int display_space;
- long time_at_cmd_start = (long) arg->data;
- long space_at_cmd_start = (long) arg->next->data;
+ long time_at_cmd_start = arg->data.longint;
+ long space_at_cmd_start = arg->next->data.longint;
bpstat_do_actions (&stop_bpstat);
/*do_cleanups (old_chain); *//*?????FIXME????? */
{
long cmd_time = get_run_time () - time_at_cmd_start;
- printf_unfiltered ("Command execution time: %ld.%06ld\n",
+ printf_unfiltered (_("Command execution time: %ld.%06ld\n"),
cmd_time / 1000000, cmd_time % 1000000);
}
if (display_space)
{
#ifdef HAVE_SBRK
- extern char **environ;
char *lim = (char *) sbrk (0);
- long space_now = lim - (char *) &environ;
+ long space_now = lim - lim_at_start;
long space_diff = space_now - space_at_cmd_start;
- printf_unfiltered ("Space used: %ld (%c%ld for this command)\n",
+ printf_unfiltered (_("Space used: %ld (%c%ld for this command)\n"),
space_now,
(space_diff >= 0 ? '+' : '-'),
space_diff);
obsolete once we use the event loop as the default mechanism in
GDB. */
static void
-command_line_handler (rl)
- char *rl;
+command_line_handler (char *rl)
{
static char *linebuffer = 0;
static unsigned linelength = 0;
- register char *p;
+ char *p;
char *p1;
extern char *line;
extern int linesize;
if (annotation_level > 1 && instream == stdin)
{
- printf_unfiltered ("\n\032\032post-");
- printf_unfiltered (async_annotation_suffix);
- printf_unfiltered ("\n");
+ printf_unfiltered (("\n\032\032post-"));
+ puts_unfiltered (async_annotation_suffix);
+ printf_unfiltered (("\n"));
}
if (linebuffer == 0)
{
strcpy (linebuffer, readline_input_state.linebuffer);
p = readline_input_state.linebuffer_ptr;
- free (readline_input_state.linebuffer);
+ xfree (readline_input_state.linebuffer);
more_to_come = 0;
pop_prompt ();
}
gdb_flush (gdb_stderr);
if (source_file_name != NULL)
- {
- ++source_line_number;
- sprintf (source_error,
- "%s%s:%d: Error in sourced command file:\n",
- source_pre_error,
- source_file_name,
- source_line_number);
- error_pre_print = source_error;
- }
+ ++source_line_number;
/* If we are in this case, then command_handler will call quit
and exit from gdb. */
while (*p1)
*p++ = *p1++;
- free (rl); /* Allocated in readline. */
+ xfree (rl); /* Allocated in readline. */
- if (*(p - 1) == '\\')
+ if (p > linebuffer && *(p - 1) == '\\')
{
p--; /* Put on top of '\'. */
- if (*p == '\\')
- {
- readline_input_state.linebuffer = savestring (linebuffer,
- strlen (linebuffer));
- readline_input_state.linebuffer_ptr = p;
-
- /* We will not invoke a execute_command if there is more
- input expected to complete the command. So, we need to
- print an empty prompt here. */
- more_to_come = 1;
- push_prompt ("", "", "");
- display_gdb_prompt (0);
- return;
- }
+ readline_input_state.linebuffer = savestring (linebuffer,
+ strlen (linebuffer));
+ readline_input_state.linebuffer_ptr = p;
+
+ /* We will not invoke a execute_command if there is more
+ input expected to complete the command. So, we need to
+ print an empty prompt here. */
+ more_to_come = 1;
+ push_prompt ("", "", "");
+ display_gdb_prompt (0);
+ return;
}
#ifdef STOP_SIGNAL
#define SERVER_COMMAND_LENGTH 7
server_command =
(p - linebuffer > SERVER_COMMAND_LENGTH)
- && STREQN (linebuffer, "server ", SERVER_COMMAND_LENGTH);
+ && strncmp (linebuffer, "server ", SERVER_COMMAND_LENGTH) == 0;
if (server_command)
{
/* Note that we don't set `line'. Between this and the check in
/* If there was an error, call this function again. */
if (expanded < 0)
{
- free (history_value);
+ xfree (history_value);
return;
}
if (strlen (history_value) > linelength)
}
strcpy (linebuffer, history_value);
p = linebuffer + strlen (linebuffer);
- free (history_value);
+ xfree (history_value);
}
}
will become obsolete when the event loop is made the default
execution for gdb. */
void
-gdb_readline2 ()
+gdb_readline2 (gdb_client_data client_data)
{
int c;
char *result;
if we are called again fgetc will still return EOF and
we'll return NULL then. */
break;
- free (result);
+ xfree (result);
(*input_handler) (0);
}
if (c == '\n')
-#ifndef CRLF_SOURCE_FILES
- break;
-#else
{
if (input_index > 0 && result[input_index - 1] == '\r')
input_index--;
break;
}
-#endif
result[input_index++] = c;
while (input_index >= result_size)
init_signals will become obsolete as we move to have to event loop
as the default for gdb. */
void
-async_init_signals ()
+async_init_signals (void)
{
signal (SIGINT, handle_sigint);
sigint_token =
signal (SIGTRAP, SIG_DFL);
#endif
+#ifdef SIGQUIT
/* If we initialize SIGQUIT to SIG_IGN, then the SIG_IGN will get
passed to the inferior, which we don't want. It would be
possible to do a "signal (SIGQUIT, SIG_DFL)" after we fork, but
signal (SIGQUIT, handle_sigquit);
sigquit_token =
create_async_signal_handler (async_do_nothing, NULL);
+#endif
#ifdef SIGHUP
if (signal (SIGHUP, handle_sighup) != SIG_IGN)
sighup_token =
}
void
-mark_async_signal_handler_wrapper (token)
- void *token;
+mark_async_signal_handler_wrapper (void *token)
{
- mark_async_signal_handler ((async_signal_handler *) token);
+ mark_async_signal_handler ((struct async_signal_handler *) token);
}
/* Tell the event loop what to do if SIGINT is received.
See event-signal.c. */
void
-handle_sigint (sig)
- int sig;
+handle_sigint (int sig)
{
signal (sig, handle_sigint);
/* Do the quit. All the checks have been done by the caller. */
void
-async_request_quit (arg)
- gdb_client_data arg;
+async_request_quit (gdb_client_data arg)
{
quit_flag = 1;
-#ifdef REQUEST_QUIT
- REQUEST_QUIT;
-#else
quit ();
-#endif
}
+#ifdef SIGQUIT
/* Tell the event loop what to do if SIGQUIT is received.
See event-signal.c. */
static void
-handle_sigquit (sig)
- int sig;
+handle_sigquit (int sig)
{
mark_async_signal_handler_wrapper (sigquit_token);
signal (sig, handle_sigquit);
}
+#endif
/* Called by the event loop in response to a SIGQUIT. */
static void
-async_do_nothing (arg)
- gdb_client_data arg;
+async_do_nothing (gdb_client_data arg)
{
/* Empty function body. */
}
/* Tell the event loop what to do if SIGHUP is received.
See event-signal.c. */
static void
-handle_sighup (sig)
- int sig;
+handle_sighup (int sig)
{
mark_async_signal_handler_wrapper (sighup_token);
signal (sig, handle_sighup);
/* Called by the event loop to process a SIGHUP */
static void
-async_disconnect (arg)
- gdb_client_data arg;
+async_disconnect (gdb_client_data arg)
{
catch_errors (quit_cover, NULL,
"Could not kill the program being debugged",
#ifdef STOP_SIGNAL
void
-handle_stop_sig (sig)
- int sig;
+handle_stop_sig (int sig)
{
mark_async_signal_handler_wrapper (sigtstp_token);
signal (sig, handle_stop_sig);
}
static void
-async_stop_sig (arg)
- gdb_client_data arg;
+async_stop_sig (gdb_client_data arg)
{
char *prompt = get_prompt ();
#if STOP_SIGNAL == SIGTSTP
signal (SIGTSTP, SIG_DFL);
+#if HAVE_SIGPROCMASK
+ {
+ sigset_t zero;
+
+ sigemptyset (&zero);
+ sigprocmask (SIG_SETMASK, &zero, 0);
+ }
+#elif HAVE_SIGSETMASK
sigsetmask (0);
+#endif
kill (getpid (), SIGTSTP);
signal (SIGTSTP, handle_stop_sig);
#else
/* Tell the event loop what to do if SIGFPE is received.
See event-signal.c. */
static void
-handle_sigfpe (sig)
- int sig;
+handle_sigfpe (int sig)
{
mark_async_signal_handler_wrapper (sigfpe_token);
signal (sig, handle_sigfpe);
/* Event loop will call this functin to process a SIGFPE. */
static void
-async_float_handler (arg)
- gdb_client_data arg;
+async_float_handler (gdb_client_data arg)
{
/* This message is based on ANSI C, section 4.7. Note that integer
divide by zero causes this, so "float" is a misnomer. */
- error ("Erroneous arithmetic operation.");
+ error (_("Erroneous arithmetic operation."));
}
/* Tell the event loop what to do if SIGWINCH is received.
See event-signal.c. */
#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
static void
-handle_sigwinch (sig)
- int sig;
+handle_sigwinch (int sig)
{
mark_async_signal_handler_wrapper (sigwinch_token);
signal (sig, handle_sigwinch);
\f
/* Called by do_setshow_command. */
-/* ARGSUSED */
void
-set_async_editing_command (args, from_tty, c)
- char *args;
- int from_tty;
- struct cmd_list_element *c;
+set_async_editing_command (char *args, int from_tty, struct cmd_list_element *c)
{
change_line_handler ();
}
/* Called by do_setshow_command. */
-/* ARGSUSED */
void
-set_async_annotation_level (args, from_tty, c)
- char *args;
- int from_tty;
- struct cmd_list_element *c;
+set_async_annotation_level (char *args, int from_tty, struct cmd_list_element *c)
{
change_annotation_level ();
}
/* Called by do_setshow_command. */
-/* ARGSUSED */
void
-set_async_prompt (args, from_tty, c)
- char *args;
- int from_tty;
- struct cmd_list_element *c;
+set_async_prompt (char *args, int from_tty, struct cmd_list_element *c)
{
PROMPT (0) = savestring (new_async_prompt, strlen (new_async_prompt));
}
interface, i.e. via a callback function (rl_callback_read_char),
and hook up instream to the event loop. */
void
-_initialize_event_loop ()
+gdb_setup_readline (void)
{
- if (async_p)
+ /* This function is a noop for the sync case. The assumption is
+ that the sync setup is ALL done in gdb_init, and we would only
+ mess it up here. The sync stuff should really go away over
+ time. */
+
+ gdb_stdout = stdio_fileopen (stdout);
+ gdb_stderr = stdio_fileopen (stderr);
+ gdb_stdlog = gdb_stderr; /* for moment */
+ gdb_stdtarg = gdb_stderr; /* for moment */
+
+ /* If the input stream is connected to a terminal, turn on
+ editing. */
+ if (ISATTY (instream))
{
- /* When a character is detected on instream by select or poll,
- readline will be invoked via this callback function. */
- call_readline = rl_callback_read_char;
-
- /* When readline has read an end-of-line character, it passes
- the complete line to gdb for processing. command_line_handler
- is the function that does this. */
- input_handler = command_line_handler;
-
- /* Tell readline to use the same input stream that gdb uses. */
- rl_instream = instream;
-
- /* Get a file descriptor for the input stream, so that we can
- register it with the event loop. */
- input_fd = fileno (instream);
-
- /* Tell gdb to use the cli_command_loop as the main loop. */
- command_loop_hook = cli_command_loop;
-
- /* Now we need to create the event sources for the input file
- descriptor. */
- /* At this point in time, this is the only event source that we
- register with the even loop. Another source is going to be
- the target program (inferior), but that must be registered
- only when it actually exists (I.e. after we say 'run' or
- after we connect to a remote target. */
- add_file_handler (input_fd, call_readline, 0);
-
/* Tell gdb that we will be using the readline library. This
- could be overwritten by a command in .gdbinit like 'set
- editing on' or 'off'. */
+ could be overwritten by a command in .gdbinit like 'set
+ editing on' or 'off'. */
async_command_editing_p = 1;
+
+ /* When a character is detected on instream by select or poll,
+ readline will be invoked via this callback function. */
+ call_readline = rl_callback_read_char_wrapper;
}
+ else
+ {
+ async_command_editing_p = 0;
+ call_readline = gdb_readline2;
+ }
+
+ /* When readline has read an end-of-line character, it passes the
+ complete line to gdb for processing. command_line_handler is the
+ function that does this. */
+ input_handler = command_line_handler;
+
+ /* Tell readline to use the same input stream that gdb uses. */
+ rl_instream = instream;
+
+ /* Get a file descriptor for the input stream, so that we can
+ register it with the event loop. */
+ input_fd = fileno (instream);
+
+ /* Now we need to create the event sources for the input file
+ descriptor. */
+ /* At this point in time, this is the only event source that we
+ register with the even loop. Another source is going to be the
+ target program (inferior), but that must be registered only when
+ it actually exists (I.e. after we say 'run' or after we connect
+ to a remote target. */
+ add_file_handler (input_fd, stdin_event_handler, 0);
+}
+
+/* Disable command input through the standard CLI channels. Used in
+ the suspend proc for interpreters that use the standard gdb readline
+ interface, like the cli & the mi. */
+void
+gdb_disable_readline (void)
+{
+ /* FIXME - It is too heavyweight to delete and remake these every
+ time you run an interpreter that needs readline. It is probably
+ better to have the interpreters cache these, which in turn means
+ that this needs to be moved into interpreter specific code. */
+
+#if 0
+ ui_file_delete (gdb_stdout);
+ ui_file_delete (gdb_stderr);
+ gdb_stdlog = NULL;
+ gdb_stdtarg = NULL;
+#endif
+
+ rl_callback_handler_remove ();
+ delete_file_handler (input_fd);
}