/* Top level stuff for GDB, the GNU debugger.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995
+ Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
#include "top.h"
/* readline include files */
-#include "readline.h"
-#include "history.h"
+#include <readline/readline.h>
+#include <readline/history.h>
/* readline defines this. */
#undef savestring
#endif
#include "gdb_string.h"
-#ifndef NO_SYS_FILE
-#include <sys/file.h>
-#endif
-#include <sys/param.h>
#include "gdb_stat.h"
#include <ctype.h>
-extern void initialize_targets PARAMS ((void));
-
extern void initialize_utils PARAMS ((void));
/* Prototypes for local functions */
+static void dont_repeat_command PARAMS ((char *, int));
+
+static void source_cleanup_lines PARAMS ((PTR));
+
+static void user_defined_command PARAMS ((char *, int));
+
+static void init_signals PARAMS ((void));
+
+#ifdef STOP_SIGNAL
+static void stop_sig PARAMS ((int));
+#endif
+
static char * line_completion_function PARAMS ((char *, int, char *, int));
static char * readline_line_completion_function PARAMS ((char *, int));
static void set_verbose PARAMS ((char *, int, struct cmd_list_element *));
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
-
-static void set_endian PARAMS ((char *, int));
-
-static void set_endian_big PARAMS ((char *, int));
-
-static void set_endian_little PARAMS ((char *, int));
-
-static void set_endian_auto PARAMS ((char *, int));
-
-static void show_endian PARAMS ((char *, int));
-
-#endif
-
static void show_history PARAMS ((char *, int));
static void set_history PARAMS ((char *, int));
static void do_nothing PARAMS ((int));
-static int quit_cover PARAMS ((char *));
+#ifdef SIGHUP
+static int quit_cover PARAMS ((PTR));
static void disconnect PARAMS ((int));
+#endif
static void source_cleanup PARAMS ((FILE *));
struct cmd_list_element *disablelist;
+/* Chain containing all defined toggle subcommands. */
+
+struct cmd_list_element *togglelist;
+
+/* Chain containing all defined stop subcommands. */
+
+struct cmd_list_element *stoplist;
+
/* Chain containing all defined delete subcommands. */
struct cmd_list_element *deletelist;
struct cmd_list_element *showlist;
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
-/* Chain containing the \"set endian\" commands. */
-
-struct cmd_list_element *endianlist;
-#endif
-
/* Chain containing all defined \"set history\". */
struct cmd_list_element *sethistlist;
/* stdio stream that command input is being read from. Set to stdin normally.
Set by source_command to the file we are sourcing. Set to NULL if we are
- executing a user-defined command. */
+ executing a user-defined command or interacting via a GUI. */
FILE *instream;
int baud_rate = -1;
+/* Timeout limit for response from target. */
+
+int remote_timeout = 20; /* Set default to 20 */
+
/* Non-zero tells remote* modules to output debugging info. */
int remote_debug = 0;
/* Called after most modules have been initialized, but before taking users
command file. */
-void (*init_ui_hook) PARAMS ((void));
+void (*init_ui_hook) PARAMS ((char *argv0));
+#ifdef __CYGWIN__
+void (*ui_loop_hook) PARAMS ((int));
+#endif
/* Called instead of command_loop at top level. Can be invoked via
return_to_top_level. */
/* Called instead of fputs for all output. */
-void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer, FILE *stream));
+void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer, GDB_FILE *stream));
/* Called when the target says something to the host, which may
want to appear in a different window. */
int stopline, int noerror));
/* Replaces most of query. */
-int (*query_hook) PARAMS (());
+int (*query_hook) PARAMS ((const char *, va_list));
+
+/* Replaces most of warning. */
+
+void (*warning_hook) PARAMS ((const char *, va_list));
/* Called from gdb_flush to flush output. */
-void (*flush_hook) PARAMS ((FILE *stream));
+void (*flush_hook) PARAMS ((GDB_FILE *stream));
+
+/* These three functions support getting lines of text from the user. They
+ are used in sequence. First readline_begin_hook is called with a text
+ string that might be (for example) a message for the user to type in a
+ sequence of commands to be executed at a breakpoint. If this function
+ calls back to a GUI, it might take this opportunity to pop up a text
+ interaction window with this message. Next, readline_hook is called
+ with a prompt that is emitted prior to collecting the user input.
+ It can be called multiple times. Finally, readline_end_hook is called
+ to notify the GUI that we are done with the interaction window and it
+ can close it. */
+
+void (*readline_begin_hook) PARAMS ((char *, ...));
+char * (*readline_hook) PARAMS ((char *));
+void (*readline_end_hook) PARAMS ((void));
/* Called as appropriate to notify the interface of the specified breakpoint
conditions. */
void (*registers_changed_hook) PARAMS ((void));
+/* tell the GUI someone changed the PC */
+void (*pc_changed_hook) PARAMS ((void));
+
/* Called when going to wait for the target. Usually allows the GUI to run
while waiting for target events. */
void (*call_command_hook) PARAMS ((struct cmd_list_element *c, char *cmd,
int from_tty));
+/* Called when the current thread changes. Argument is thread id. */
+
+void (*context_hook) PARAMS ((int id));
/* Takes control from error (). Typically used to prevent longjmps out of the
middle of the GUI. Usually used in conjunction with a catch routine. */
-NORETURN void (*error_hook) PARAMS (()) ATTR_NORETURN;
+NORETURN void (*error_hook) PARAMS ((void)) ATTR_NORETURN;
\f
/* Where to go for return_to_top_level (RETURN_ERROR). */
-jmp_buf error_return;
+SIGJMP_BUF error_return;
/* Where to go for return_to_top_level (RETURN_QUIT). */
-jmp_buf quit_return;
+SIGJMP_BUF quit_return;
/* Return for reason REASON. This generally gets back to the command
loop, but can be caught via catch_errors. */
break;
}
- (NORETURN void) longjmp
+ (NORETURN void) SIGLONGJMP
(reason == RETURN_ERROR ? error_return : quit_return, 1);
}
int
catch_errors (func, args, errstring, mask)
- int (*func) PARAMS ((char *));
+ catch_errors_ftype *func;
PTR args;
char *errstring;
return_mask mask;
{
- jmp_buf saved_error;
- jmp_buf saved_quit;
- jmp_buf tmp_jmp;
+ SIGJMP_BUF saved_error;
+ SIGJMP_BUF saved_quit;
+ SIGJMP_BUF tmp_jmp;
int val;
struct cleanup *saved_cleanup_chain;
char *saved_error_pre_print;
if (mask & RETURN_MASK_ERROR)
{
- memcpy ((char *)saved_error, (char *)error_return, sizeof (jmp_buf));
+ memcpy ((char *)saved_error, (char *)error_return, sizeof (SIGJMP_BUF));
error_pre_print = errstring;
}
if (mask & RETURN_MASK_QUIT)
{
- memcpy (saved_quit, quit_return, sizeof (jmp_buf));
+ memcpy (saved_quit, quit_return, sizeof (SIGJMP_BUF));
quit_pre_print = errstring;
}
- if (setjmp (tmp_jmp) == 0)
+ if (SIGSETJMP (tmp_jmp) == 0)
{
if (mask & RETURN_MASK_ERROR)
- memcpy (error_return, tmp_jmp, sizeof (jmp_buf));
+ memcpy (error_return, tmp_jmp, sizeof (SIGJMP_BUF));
if (mask & RETURN_MASK_QUIT)
- memcpy (quit_return, tmp_jmp, sizeof (jmp_buf));
+ memcpy (quit_return, tmp_jmp, sizeof (SIGJMP_BUF));
val = (*func) (args);
}
else
if (mask & RETURN_MASK_ERROR)
{
- memcpy (error_return, saved_error, sizeof (jmp_buf));
+ memcpy (error_return, saved_error, sizeof (SIGJMP_BUF));
error_pre_print = saved_error_pre_print;
}
if (mask & RETURN_MASK_QUIT)
{
- memcpy (quit_return, saved_quit, sizeof (jmp_buf));
+ memcpy (quit_return, saved_quit, sizeof (SIGJMP_BUF));
quit_pre_print = saved_quit_pre_print;
}
return val;
/* Handler for SIGHUP. */
+#ifdef SIGHUP
static void
disconnect (signo)
int signo;
static int
quit_cover (s)
-char *s;
+ PTR s;
{
caution = 0; /* Throw caution to the wind -- we're exiting.
This prevents asking the user dumb questions. */
quit_command((char *)0, 0);
return 0;
}
+#endif /* defined SIGHUP */
\f
/* Line number we are currently in in a file which is being sourced. */
static int source_line_number;
{
struct cleanup *cleanups;
- cleanups = make_cleanup (source_cleanup, instream);
+ cleanups = make_cleanup ((make_cleanup_func) source_cleanup, instream);
instream = stream;
command_loop ();
do_cleanups (cleanups);
}
\f
-extern void init_proc ();
+extern void init_proc PARAMS ((void));
void (*pre_init_ui_hook) PARAMS ((void));
void
-gdb_init ()
+gdb_init (argv0)
+ char *argv0;
{
if (pre_init_ui_hook)
pre_init_ui_hook ();
expected_language = current_language; /* don't warn about the change. */
if (init_ui_hook)
- init_ui_hook ();
+ init_ui_hook (argv0);
}
/* Allocate, initialize a new command line structure for one of the
/* Allocate and build a new command line structure. */
cmd = build_command_line (type, arg);
- old_chain = make_cleanup (free_command_lines, &cmd);
+ old_chain = make_cleanup ((make_cleanup_func) free_command_lines, &cmd);
/* Read in the body of this command. */
if (recurse_read_control_structure (cmd) == invalid_control)
struct command_line *current;
struct cleanup *old_chain = 0;
value_ptr val;
+ value_ptr val_mark;
int loop;
enum command_control_type ret;
char *new_line;
new_line = insert_args (cmd->line);
if (!new_line)
return invalid_control;
- old_chain = make_cleanup (free_current_contents, &new_line);
+ old_chain = make_cleanup ((make_cleanup_func) free_current_contents,
+ &new_line);
execute_command (new_line, 0);
ret = cmd->control_type;
break;
new_line = insert_args (cmd->line);
if (!new_line)
return invalid_control;
- old_chain = make_cleanup (free_current_contents, &new_line);
+ old_chain = make_cleanup ((make_cleanup_func) free_current_contents,
+ &new_line);
expr = parse_expression (new_line);
- make_cleanup (free_current_contents, &expr);
+ make_cleanup ((make_cleanup_func) free_current_contents, &expr);
ret = simple_control;
loop = 1;
/* Keep iterating so long as the expression is true. */
while (loop == 1)
{
+ int cond_result;
+
+ QUIT;
+
/* Evaluate the expression. */
+ val_mark = value_mark ();
val = evaluate_expression (expr);
+ cond_result = value_true (val);
+ value_free_to_mark (val_mark);
/* If the value is false, then break out of the loop. */
- if (!value_true (val))
+ if (!cond_result)
break;
/* Execute the body of the while statement. */
new_line = insert_args (cmd->line);
if (!new_line)
return invalid_control;
- old_chain = make_cleanup (free_current_contents, &new_line);
+ old_chain = make_cleanup ((make_cleanup_func) free_current_contents,
+ &new_line);
/* Parse the conditional for the if statement. */
expr = parse_expression (new_line);
- make_cleanup (free_current_contents, &expr);
+ make_cleanup ((make_cleanup_func) free_current_contents, &expr);
current = NULL;
ret = simple_control;
/* Evaluate the conditional. */
+ val_mark = value_mark ();
val = evaluate_expression (expr);
/* Choose which arm to take commands from based on the value of the
current = *cmd->body_list;
else if (cmd->body_count == 2)
current = *(cmd->body_list + 1);
+ value_free_to_mark (val_mark);
/* Execute commands in the given arm. */
while (current)
args->next = user_args;
user_args = args;
- old_chain = make_cleanup (arg_cleanup, 0);
+ old_chain = make_cleanup ((make_cleanup_func) arg_cleanup, 0);
if (p == NULL)
return old_chain;
while (*p)
{
char *start_arg;
+ int squote = 0;
+ int dquote = 0;
+ int bsquote = 0;
if (arg_count >= MAXUSERARGS)
{
user_args->a[arg_count].arg = p;
/* Get to the end of this argument. */
- while (*p && *p != ' ' && *p != '\t')
- p++;
+ while (*p)
+ {
+ if (((*p == ' ' || *p == '\t')) && !squote && !dquote && !bsquote)
+ break;
+ else
+ {
+ if (bsquote)
+ bsquote = 0;
+ else if (*p == '\\')
+ bsquote = 1;
+ else if (squote)
+ {
+ if (*p == '\'')
+ squote = 0;
+ }
+ else if (dquote)
+ {
+ if (*p == '"')
+ dquote = 0;
+ }
+ else
+ {
+ if (*p == '\'')
+ squote = 1;
+ else if (*p == '"')
+ dquote = 1;
+ }
+ p++;
+ }
+ }
user_args->a[arg_count].len = p - start_arg;
arg_count++;
/* Set the instream to 0, indicating execution of a
user-defined function. */
- old_chain = make_cleanup (source_cleanup, instream);
+ old_chain = make_cleanup ((make_cleanup_func) source_cleanup, instream);
instream = (FILE *) 0;
while (cmdlines)
{
register struct cmd_list_element *c;
register enum language flang;
static int warned = 0;
+ /* FIXME: These should really be in an appropriate header file */
+ extern void serial_log_command PARAMS ((const char *));
free_all_values ();
+ /* Force cleanup of any alloca areas if using C alloca instead of
+ a builtin alloca. */
+ alloca (0);
+
/* This can happen when command_line_input hits end of file. */
if (p == NULL)
return;
+ serial_log_command (p);
+
while (*p == ' ' || *p == '\t') p++;
if (*p)
{
char *command;
int stdin_is_tty = ISATTY (stdin);
long time_at_cmd_start;
- long space_at_cmd_start;
+#ifdef HAVE_SBRK
+ long space_at_cmd_start = 0;
+#endif
extern int display_time;
extern int display_space;
- while (!feof (instream))
+ while (instream && !feof (instream))
{
+#if defined(TUI)
+ extern int insert_mode;
+#endif
if (window_hook && instream == stdin)
(*window_hook) (instream, prompt);
quit_flag = 0;
if (instream == stdin && stdin_is_tty)
reinitialize_more_filter ();
- old_chain = make_cleanup (command_loop_marker, 0);
+ old_chain = make_cleanup ((make_cleanup_func) command_loop_marker, 0);
+
+#if defined(TUI)
+ /* A bit of paranoia: I want to make sure the "insert_mode" global
+ * is clear except when it is being used for command-line editing
+ * (see tuiIO.c, utils.c); otherwise normal output will
+ * get messed up in the TUI. So clear it before/after
+ * the command-line-input call. - RT
+ */
+ insert_mode = 0;
+#endif
+ /* Get a command-line. This calls the readline package. */
command = command_line_input (instream == stdin ? prompt : (char *) NULL,
instream == stdin, "prompt");
+#if defined(TUI)
+ insert_mode = 0;
+#endif
if (command == 0)
return;
if (display_space)
{
+#ifdef HAVE_SBRK
extern char **environ;
char *lim = (char *) sbrk (0);
space_at_cmd_start = (long) (lim - (char *) &environ);
+#endif
}
execute_command (command, instream == stdin);
if (display_space)
{
+#ifdef HAVE_SBRK
extern char **environ;
char *lim = (char *) sbrk (0);
long space_now = lim - (char *) &environ;
space_now,
(space_diff >= 0 ? '+' : '-'),
space_diff);
+#endif
}
}
}
}
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)
char *word;
{
/* From readline. */
- extern char *filename_completion_function ();
+ extern char *filename_completion_function PARAMS ((char *, int));
int subsequent_name;
char **return_val;
int return_val_used;
do_nothing (signo)
int signo;
{
+ /* Under System V the default disposition of a signal is reinstated after
+ the signal is caught and delivered to an application process. On such
+ systems one must restore the replacement signal handler if one wishes
+ to continue handling the signal in one's program. On BSD systems this
+ is not needed but it is harmless, and it simplifies the code to just do
+ it unconditionally. */
+ signal (signo, do_nothing);
}
static void
{
signal (SIGINT, request_quit);
+ /* If SIGTRAP was set to SIG_IGN, then the SIG_IGN will get passed
+ to the inferior and breakpoints will be ignored. */
+#ifdef SIGTRAP
+ signal (SIGTRAP, SIG_DFL);
+#endif
+
/* 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
a handler for SIGQUIT, when we call exec it will set the signal
to SIG_DFL for us. */
signal (SIGQUIT, do_nothing);
+#ifdef SIGHUP
if (signal (SIGHUP, do_nothing) != SIG_IGN)
signal (SIGHUP, disconnect);
+#endif
signal (SIGFPE, float_handler);
#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
char *p1;
char *rl;
char *local_prompt = prrompt;
- register int c;
char *nline;
char got_eof = 0;
}
/* Don't use fancy stuff if not talking to stdin. */
- if (command_editing_p && instream == stdin
- && ISATTY (instream))
- rl = readline (local_prompt);
+ if (readline_hook && instream == NULL)
+ {
+ rl = (*readline_hook) (local_prompt);
+ }
+ else if (command_editing_p && instream == stdin && ISATTY (instream))
+ {
+ rl = readline (local_prompt);
+ }
else
- rl = gdb_readline (local_prompt);
+ {
+ rl = gdb_readline (local_prompt);
+ }
if (annotation_level > 1 && instream == stdin)
{
/* If we just got an empty line, and that is supposed
to repeat the previous command, return the value in the
global buffer. */
- if (repeat)
- {
- if (p == linebuffer)
- return line;
- p1 = linebuffer;
- while (*p1 == ' ' || *p1 == '\t')
- p1++;
- if (!*p1)
- return line;
- }
+ if (repeat && p == linebuffer)
+ return line;
+ for (p1 = linebuffer; *p1 == ' ' || *p1 == '\t'; p1++) ;
+ if (repeat && !*p1)
+ return line;
*p = 0;
out the command and then later fetch it from the value history
and remove the '#'. The kill ring is probably better, but some
people are in the habit of commenting things out. */
- p1 = linebuffer;
- while ((c = *p1++) != '\0')
- {
- if (c == '"')
- while ((c = *p1++) != '"')
- {
- /* Make sure an escaped '"' doesn't make us think the string
- is ended. */
- if (c == '\\')
- parse_escape (&p1);
- if (c == '\0')
- break;
- }
- else if (c == '\'')
- while ((c = *p1++) != '\'')
- {
- /* Make sure an escaped '\'' doesn't make us think the string
- is ended. */
- if (c == '\\')
- parse_escape (&p1);
- if (c == '\0')
- break;
- }
- else if (c == '#')
- {
- /* Found a comment. */
- p1[-1] = '\0';
- break;
- }
- }
+ if (*p1 == '#')
+ *p1 = '\0'; /* Found a comment. */
/* Save into global buffer if appropriate. */
if (repeat)
error ("Control nesting too deep!\n");
/* Set a prompt based on the nesting of the control commands. */
- if (instream == stdin)
+ if (instream == stdin || (instream == 0 && readline_hook != NULL))
{
for (i = 0; i < control_level; i++)
control_prompt[i] = ' ';
*command = build_command_line (while_control, p + 6);
else if (p1 - p > 2 && !strncmp (p, "if", 2))
*command = build_command_line (if_control, p + 3);
- else if (p1 - p == 5 && !strncmp (p, "loop_break", 5))
+ else if (p1 - p == 10 && !strncmp (p, "loop_break", 10))
{
*command = (struct command_line *)
xmalloc (sizeof (struct command_line));
(*command)->body_count = 0;
(*command)->body_list = NULL;
}
- else if (p1 - p == 8 && !strncmp (p, "loop_continue", 8))
+ else if (p1 - p == 13 && !strncmp (p, "loop_continue", 13))
{
*command = (struct command_line *)
xmalloc (sizeof (struct command_line));
}
/* Recursively read in the control structures and create a command_line
- tructure from them.
+ structure from them.
The parent_control parameter is the control structure in which the
following commands are nested. */
return ret;
}
+/* Read lines from the input stream and accumulate them in a chain of
+ struct command_line's, which is then returned. For input from a
+ terminal, the special command "end" is used to mark the end of the
+ input, and is not included in the returned chain of commands. */
-/* Read lines from the input stream
- and accumulate them in a chain of struct command_line's
- which is then returned. */
+#define END_MESSAGE "End with a line saying just \"end\"."
struct command_line *
-read_command_lines ()
+read_command_lines (prompt, from_tty)
+char *prompt;
+int from_tty;
{
struct command_line *head, *tail, *next;
struct cleanup *old_chain;
enum command_control_type ret;
enum misc_command_type val;
+ if (readline_begin_hook)
+ {
+ /* Note - intentional to merge messages with no newline */
+ (*readline_begin_hook) ("%s %s\n", prompt, END_MESSAGE);
+ }
+ else if (from_tty && input_from_terminal_p ())
+ {
+ printf_unfiltered ("%s\n%s\n", prompt, END_MESSAGE);
+ gdb_flush (gdb_stdout);
+ }
+
head = tail = NULL;
old_chain = NULL;
else
{
head = next;
- old_chain = make_cleanup (free_command_lines, &head);
+ old_chain = make_cleanup ((make_cleanup_func) free_command_lines,
+ &head);
}
tail = next;
}
if (ret != invalid_control)
{
discard_cleanups (old_chain);
- return head;
}
else
do_cleanups (old_chain);
}
- return NULL;
+ if (readline_end_hook)
+ {
+ (*readline_end_hook) ();
+ }
+ return (head);
}
/* Free a chain of struct command_line's. */
register struct command_line *cmds;
register struct cmd_list_element *c, *newc, *hookc = 0;
char *tem = comname;
+ char tmpbuf[128];
#define HOOK_STRING "hook-"
#define HOOK_LEN 5
for (tem = comname; *tem; tem++)
if (isupper(*tem)) *tem = tolower(*tem);
- if (from_tty)
- {
- printf_unfiltered ("Type commands for definition of \"%s\".\n\
-End with a line saying just \"end\".\n", comname);
- gdb_flush (gdb_stdout);
- }
-
control_level = 0;
- cmds = read_command_lines ();
+ sprintf (tmpbuf, "Type commands for definition of \"%s\".", comname);
+ cmds = read_command_lines (tmpbuf, from_tty);
if (c && c->class == class_user)
free_command_lines (&c->user_commands);
struct command_line *doclines;
register struct cmd_list_element *c;
char *tem = comname;
+ char tmpbuf[128];
validate_comname (comname);
if (c->class != class_user)
error ("Command \"%s\" is built-in.", comname);
- if (from_tty)
- printf_unfiltered ("Type documentation for \"%s\".\n\
-End with a line saying just \"end\".\n", comname);
-
- doclines = read_command_lines ();
+ sprintf (tmpbuf, "Type documentation for \"%s\".", comname);
+ doclines = read_command_lines (tmpbuf, from_tty);
if (c->doc) free (c->doc);
free_command_lines (&doclines);
}
\f
-void
-print_gnu_advertisement ()
-{
- printf_unfiltered ("\
-GDB is free software and you are welcome to distribute copies of it\n\
- under certain conditions; type \"show copying\" to see the conditions.\n\
-There is absolutely no warranty for GDB; type \"show warranty\" for details.\n\
-");
-}
-
+/* Print the GDB banner. */
void
print_gdb_version (stream)
GDB_FILE *stream;
{
+ /* From GNU coding standards, first line is meant to be easy for a
+ program to parse, and is just canonical program name and version
+ number, which starts after last space. */
+
+ fprintf_filtered (stream, "GNU gdb %s\n", version);
+
+ /* Second line is a copyright notice. */
+
+ fprintf_filtered (stream, "Copyright 1998 Free Software Foundation, Inc.\n");
+
+ /* Following the copyright is a brief statement that the program is
+ free software, that users are free to copy and change it on
+ certain conditions, that it is covered by the GNU GPL, and that
+ there is no warranty. */
+
fprintf_filtered (stream, "\
-GDB %s (%s", version, host_name);
+GDB is free software, covered by the GNU General Public License, and you are\n\
+welcome to change it and/or distribute copies of it under certain conditions.\n\
+Type \"show copying\" to see the conditions.\n\
+There is absolutely no warranty for GDB. Type \"show warranty\" for details.\n");
- if (!STREQ (host_name, target_name))
- fprintf_filtered (stream, " --target %s", target_name);
+ /* After the required info we print the configuration information. */
- fprintf_filtered (stream, "), ");
- wrap_here("");
- fprintf_filtered (stream, "Copyright 1995 Free Software Foundation, Inc.");
+ fprintf_filtered (stream, "This GDB was configured as \"");
+ if (!STREQ (host_name, target_name))
+ {
+ fprintf_filtered (stream, "--host=%s --target=%s", host_name, target_name);
+ }
+ else
+ {
+ fprintf_filtered (stream, "%s", host_name);
+ }
+ fprintf_filtered (stream, "\".");
}
/* ARGSUSED */
int from_tty;
{
immediate_quit++;
- print_gnu_advertisement ();
print_gdb_version (gdb_stdout);
printf_filtered ("\n");
immediate_quit--;
printf_unfiltered ("%s", prompt);
gdb_flush (gdb_stdout);
}
+
+/* This replaces the above for the frontends: it returns a pointer
+ to the prompt. */
+char *
+get_prompt ()
+{
+ return prompt;
+}
+
+void
+set_prompt (s)
+ char *s;
+{
+/* ??rehrauer: I don't know why this fails, since it looks as though
+ assignments to prompt are wrapped in calls to savestring...
+ if (prompt != NULL)
+ free (prompt);
+*/
+ prompt = savestring (s, strlen (s));
+}
+
\f
+/* If necessary, make the user confirm that we should quit. Return
+ non-zero if we should quit, zero if we shouldn't. */
+
+int
+quit_confirm ()
+{
+ if (inferior_pid != 0 && target_has_execution)
+ {
+ char *s;
+
+ /* This is something of a hack. But there's no reliable way to
+ see if a GUI is running. The `use_windows' variable doesn't
+ cut it. */
+ if (init_ui_hook)
+ s = "A debugging session is active.\nDo you still want to close the debugger?";
+ else if (attach_flag)
+ s = "The program is running. Quit anyway (and detach it)? ";
+ else
+ s = "The program is running. Exit anyway? ";
+
+ if (! query (s))
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Quit without asking for confirmation. */
+
void
-quit_command (args, from_tty)
+quit_force (args, from_tty)
char *args;
int from_tty;
{
if (inferior_pid != 0 && target_has_execution)
{
if (attach_flag)
- {
- if (query ("The program is running. Quit anyway (and detach it)? "))
- target_detach (args, from_tty);
- else
- error ("Not confirmed.");
- }
+ target_detach (args, from_tty);
else
- {
- if (query ("The program is running. Quit anyway (and kill it)? "))
- target_kill ();
- else
- error ("Not confirmed.");
- }
+ target_kill ();
}
+
/* UDI wants this, to kill the TIP. */
target_close (1);
if (write_history_p && history_filename)
write_history (history_filename);
+ do_final_cleanups(ALL_CLEANUPS); /* Do any final cleanups before exiting */
+
+#if defined(TUI)
+ /* tuiDo((TuiOpaqueFuncPtr)tuiCleanUp); */
+ /* The above does not need to be inside a tuiDo(), since
+ * it is not manipulating the curses screen, but rather,
+ * it is tearing it down.
+ */
+ if (tui_version)
+ tuiCleanUp();
+#endif
+
exit (exit_code);
}
+/* Handle the quit command. */
+
+void
+quit_command (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ if (! quit_confirm ())
+ error ("Not confirmed.");
+ quit_force (args, from_tty);
+}
+
/* Returns whether GDB is running on a terminal and whether the user
desires that questions be asked of them on that terminal. */
old_cleanups = make_cleanup (free, file);
stream = fopen (file, FOPEN_RT);
- if (stream == 0)
- perror_with_name (file);
+ if (!stream)
+ if (from_tty)
+ perror_with_name (file);
+ else
+ return;
- make_cleanup (fclose, stream);
+ make_cleanup ((make_cleanup_func) fclose, stream);
old_lines.old_line = source_line_number;
old_lines.old_file = source_file_name;
necessarily reading from stdin. */
}
\f
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
-
-/* Functions to manipulate the endianness of the target. */
-
-#ifndef TARGET_BYTE_ORDER_DEFAULT
-#define TARGET_BYTE_ORDER_DEFAULT BIG_ENDIAN
-#endif
-
-int target_byte_order = TARGET_BYTE_ORDER_DEFAULT;
-
-static int target_byte_order_auto = 1;
-
-/* Called if the user enters ``set endian'' without an argument. */
-static void
-set_endian (args, from_tty)
- char *args;
- int from_tty;
-{
- printf_unfiltered ("\"set endian\" must be followed by \"auto\", \"big\" or \"little\".\n");
- show_endian (args, from_tty);
-}
-
-/* Called by ``set endian big''. */
-static void
-set_endian_big (args, from_tty)
- char *args;
- int from_tty;
-{
- target_byte_order = BIG_ENDIAN;
- target_byte_order_auto = 0;
-}
-
-/* Called by ``set endian little''. */
-static void
-set_endian_little (args, from_tty)
- char *args;
- int from_tty;
-{
- target_byte_order = LITTLE_ENDIAN;
- target_byte_order_auto = 0;
-}
-
-/* Called by ``set endian auto''. */
-static void
-set_endian_auto (args, from_tty)
- char *args;
- int from_tty;
-{
- target_byte_order_auto = 1;
-}
-
-/* Called by ``show endian''. */
-static void
-show_endian (args, from_tty)
- char *args;
- int from_tty;
-{
- const char *msg =
- (target_byte_order_auto
- ? "The target endianness is set automatically (currently %s endian)\n"
- : "The target is assumed to be %s endian\n");
- printf_unfiltered ((char *) msg, TARGET_BYTE_ORDER == BIG_ENDIAN ? "big" : "little");
-}
-
-#endif /* defined (TARGET_BYTE_ORDER_SELECTABLE) */
-
-/* Set the endianness from a BFD. */
-void
-set_endian_from_file (abfd)
- bfd *abfd;
-{
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
- int want;
-
- if (abfd->xvec->byteorder_big_p)
- want = BIG_ENDIAN;
- else
- want = LITTLE_ENDIAN;
- if (target_byte_order_auto)
- target_byte_order = want;
- else if (target_byte_order != want)
- warning ("%s endian file does not match %s endian target.",
- want == BIG_ENDIAN ? "big" : "little",
- TARGET_BYTE_ORDER == BIG_ENDIAN ? "big" : "little");
-
-#else /* ! defined (TARGET_BYTE_ORDER_SELECTABLE) */
-
- if (abfd->xvec->byteorder_big_p
- ? TARGET_BYTE_ORDER != BIG_ENDIAN
- : TARGET_BYTE_ORDER == BIG_ENDIAN)
- warning ("%s endian file does not match %s endian target.",
- abfd->xvec->byteorder_big_p ? "big" : "little",
- TARGET_BYTE_ORDER == BIG_ENDIAN ? "big" : "little");
-
-#endif /* ! defined (TARGET_BYTE_ORDER_SELECTABLE) */
-}
-\f
/* Functions to manipulate command line editing control variables. */
/* Number of commands to print in each call to show_commands. */
infolist = NULL;
enablelist = NULL;
disablelist = NULL;
+ togglelist = NULL;
+ stoplist = NULL;
deletelist = NULL;
enablebreaklist = NULL;
setlist = NULL;
unsetlist = NULL;
showlist = NULL;
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
- endianlist = NULL;
-#endif
sethistlist = NULL;
showhistlist = NULL;
unsethistlist = NULL;
{
struct cmd_list_element *c;
-#ifdef TARGET_BYTE_ORDER_SELECTABLE
-
- add_prefix_cmd ("endian", class_support, set_endian,
- "Set endianness of target.",
- &endianlist, "set endian ", 0, &setlist);
- add_cmd ("big", class_support, set_endian_big,
- "Set target as being big endian.", &endianlist);
- add_cmd ("little", class_support, set_endian_little,
- "Set target as being little endian.", &endianlist);
- add_cmd ("auto", class_support, set_endian_auto,
- "Select target endianness automatically.", &endianlist);
- add_cmd ("endian", class_support, show_endian,
- "Show endianness of target.", &showlist);
-
-#endif /* defined (TARGET_BYTE_ORDER_SELECTABLE) */
-
#ifdef DEFAULT_PROMPT
prompt = savestring (DEFAULT_PROMPT, strlen(DEFAULT_PROMPT));
#else
The commands in this class are those defined by the user.\n\
Use the \"define\" command to define a command.", &cmdlist);
add_cmd ("support", class_support, NO_FUNCTION, "Support facilities.", &cmdlist);
- add_cmd ("status", class_info, NO_FUNCTION, "Status inquiries.", &cmdlist);
+ if (!dbx_commands)
+ add_cmd ("status", class_info, NO_FUNCTION, "Status inquiries.", &cmdlist);
add_cmd ("files", class_files, NO_FUNCTION, "Specifying and examining files.", &cmdlist);
add_cmd ("breakpoints", class_breakpoint, NO_FUNCTION, "Making program stop at certain points.", &cmdlist);
add_cmd ("data", class_vars, NO_FUNCTION, "Examining data.", &cmdlist);
add_show_from_set
(add_set_cmd ("editing", class_support, var_boolean, (char *)&command_editing_p,
"Set editing of command lines as they are typed.\n\
-Use \"on\" to enable to enable the editing, and \"off\" to disable it.\n\
+Use \"on\" to enable the editing, and \"off\" to disable it.\n\
Without an argument, command line editing is enabled. To edit, use\n\
EMACS-like or VI-like commands like control-P or ESC.", &setlist),
&showlist);
add_show_from_set
(add_set_cmd ("save", no_class, var_boolean, (char *)&write_history_p,
"Set saving of the history record on exit.\n\
-Use \"on\" to enable to enable the saving, and \"off\" to disable it.\n\
+Use \"on\" to enable the saving, and \"off\" to disable it.\n\
Without an argument, saving is enabled.", &sethistlist),
&showhistlist);
When enabled, each packet sent or received with the remote target\n\
is displayed.", &setlist),
&showlist);
+
+ add_show_from_set (
+ add_set_cmd ("remotetimeout", no_class, var_integer, (char *)&remote_timeout,
+ "Set timeout limit to wait for target to respond.\n\
+This value is used to set the time limit for gdb to wait for a response\n\
+from he target.", &setlist),
+ &showlist);
+
+ c = add_set_cmd ("annotate", class_obscure, var_zinteger,
+ (char *)&annotation_level, "Set annotation_level.\n\
+0 == normal; 1 == fullname (for use when running under emacs)\n\
+2 == output annotated suitably for use by programs that control GDB.",
+ &setlist);
+ c = add_show_from_set (c, &showlist);
}