/* Top level stuff for GDB, the GNU debugger.
- Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999
- Free Software Foundation, Inc.
+ Copyright 1986-2000 Free Software Foundation, Inc.
This file is part of GDB.
#include <sys/types.h>
+#include <setjmp.h>
#include "event-top.h"
#include "gdb_string.h"
#include "gdb_stat.h"
#include <ctype.h>
+#ifdef UI_OUT
+#include "ui-out.h"
+#include "cli-out.h"
+#endif
/* Prototypes for local functions */
-static void dont_repeat_command PARAMS ((char *, int));
+static void dont_repeat_command (char *, int);
-static void source_cleanup_lines PARAMS ((PTR));
+static void source_cleanup_lines (PTR);
-static void user_defined_command PARAMS ((char *, int));
+static void user_defined_command (char *, int);
-static void init_signals PARAMS ((void));
+static void init_signals (void);
#ifdef STOP_SIGNAL
-static void stop_sig PARAMS ((int));
+static void stop_sig (int);
#endif
-static char *line_completion_function PARAMS ((char *, int, char *, int));
-
-static char *readline_line_completion_function PARAMS ((char *, int));
+static char *line_completion_function (char *, int, char *, int);
-/* NOTE 1999-04-29: this function will be static again, after we make the
- event loop be the default command loop for gdb, and we merge
- event-top.c into this file, top.c */
-/* static */ void command_loop_marker PARAMS ((int));
+static char *readline_line_completion_function (char *, int);
-static void while_command PARAMS ((char *, int));
+static void while_command (char *, int);
-static void if_command PARAMS ((char *, int));
+static void if_command (char *, int);
-static struct command_line *
- build_command_line PARAMS ((enum command_control_type, char *));
+static struct command_line *build_command_line (enum command_control_type,
+ char *);
-static struct command_line *
- get_command_line PARAMS ((enum command_control_type, char *));
+static struct command_line *get_command_line (enum command_control_type,
+ char *);
-static void realloc_body_list PARAMS ((struct command_line *, int));
+static void realloc_body_list (struct command_line *, int);
-static enum misc_command_type read_next_line PARAMS ((struct command_line **));
+static enum misc_command_type read_next_line (struct command_line **);
static enum command_control_type
-recurse_read_control_structure PARAMS ((struct command_line *));
+recurse_read_control_structure (struct command_line *);
+
+static struct cleanup *setup_user_args (char *);
-static struct cleanup *setup_user_args PARAMS ((char *));
+static char *locate_arg (char *);
-static char *locate_arg PARAMS ((char *));
+static char *insert_args (char *);
-static char *insert_args PARAMS ((char *));
+static void arg_cleanup (void *);
-static void arg_cleanup PARAMS ((void));
+static void init_main (void);
-static void init_main PARAMS ((void));
+static void init_cmd_lists (void);
-static void init_cmd_lists PARAMS ((void));
+static void float_handler (int);
-static void float_handler PARAMS ((int));
+static void init_signals (void);
-static void init_signals PARAMS ((void));
+static void set_verbose (char *, int, struct cmd_list_element *);
-static void set_verbose PARAMS ((char *, int, struct cmd_list_element *));
+static void show_history (char *, int);
-static void show_history PARAMS ((char *, int));
+static void set_history (char *, int);
-static void set_history PARAMS ((char *, int));
+static void set_history_size_command (char *, int, struct cmd_list_element *);
-static void set_history_size_command PARAMS ((char *, int,
- struct cmd_list_element *));
+static void show_commands (char *, int);
-static void show_commands PARAMS ((char *, int));
+static void echo_command (char *, int);
-static void echo_command PARAMS ((char *, int));
+static void pwd_command (char *, int);
-static void pwd_command PARAMS ((char *, int));
+static void show_version (char *, int);
-static void show_version PARAMS ((char *, int));
+static void document_command (char *, int);
-static void document_command PARAMS ((char *, int));
+static void define_command (char *, int);
-static void define_command PARAMS ((char *, int));
+static void validate_comname (char *);
-static void validate_comname PARAMS ((char *));
+static void help_command (char *, int);
-static void help_command PARAMS ((char *, int));
+static void show_command (char *, int);
-static void show_command PARAMS ((char *, int));
+static void info_command (char *, int);
-static void info_command PARAMS ((char *, int));
+static void complete_command (char *, int);
-static void complete_command PARAMS ((char *, int));
+static void do_nothing (int);
-static void do_nothing PARAMS ((int));
+static void show_debug (char *, int);
+
+static void set_debug (char *, int);
#ifdef SIGHUP
/* NOTE 1999-04-29: This function will be static again, once we modify
gdb to use the event loop as the default command loop and we merge
event-top.c into this file, top.c */
-/* static */ int quit_cover PARAMS ((PTR));
+/* static */ int quit_cover (PTR);
-static void disconnect PARAMS ((int));
+static void disconnect (int);
#endif
-static void source_cleanup PARAMS ((FILE *));
+static void do_restore_instream_cleanup (void *stream);
+
+static struct cleanup *make_cleanup_free_command_lines (struct command_line **);
/* Default command line prompt. This is overriden in some configs. */
struct cmd_list_element *showprintlist;
+struct cmd_list_element *setdebuglist;
+
+struct cmd_list_element *showdebuglist;
+
struct cmd_list_element *setchecklist;
struct cmd_list_element *showchecklist;
The function receives two args: an input stream,
and a prompt string. */
-void (*window_hook) PARAMS ((FILE *, char *));
+void (*window_hook) (FILE *, char *);
int epoch_interface;
int xgdb_verbose;
/* gdb prints this when reading a command interactively */
static char *gdb_prompt_string; /* the global prompt string */
-extern char *get_prompt PARAMS ((void)); /* access function for prompt string */
+extern char *get_prompt (void); /* access function for prompt string */
/* Buffer used for reading command lines, and the size
allocated for it so far. */
int linesize = 100;
/* Nonzero if the current command is modified by "server ". This
- affects things like recording into the command history, comamnds
+ affects things like recording into the command history, commands
repeating on RETURN, etc. This is so a user interface (emacs, GUI,
whatever) can issue its own commands and also send along commands
from the user, and have the user not notice that the user interface
/* Timeout limit for response from target. */
-int remote_timeout = 20; /* Set default to 20 */
+/* The default value has been changed many times over the years. It
+ was originally 5 seconds. But that was thought to be a long time
+ to sit and wait, so it was changed to 2 seconds. That was thought
+ to be plenty unless the connection was going through some terminal
+ server or multiplexer or other form of hairy serial connection.
+
+ In mid-1996, remote_timeout was moved from remote.c to top.c and
+ it began being used in other remote-* targets. It appears that the
+ default was changed to 20 seconds at that time, perhaps because the
+ Hitachi E7000 ICE didn't always respond in a timely manner.
+
+ But if 5 seconds is a long time to sit and wait for retransmissions,
+ 20 seconds is far worse. This demonstrates the difficulty of using
+ a single variable for all protocol timeouts.
+
+ As remote.c is used much more than remote-e7000.c, it was changed
+ back to 2 seconds in 1999. */
+
+int remote_timeout = 2;
/* Non-zero tells remote* modules to output debugging info. */
#ifndef STOP_SIGNAL
#ifdef SIGTSTP
#define STOP_SIGNAL SIGTSTP
-static void stop_sig PARAMS ((int));
+static void stop_sig (int);
#endif
#endif
/* Called after most modules have been initialized, but before taking users
command file. */
-void (*init_ui_hook) PARAMS ((char *argv0));
+void (*init_ui_hook) (char *argv0);
/* This hook is called from within gdb's many mini-event loops which could
steal control from a real user interface's event loop. It returns
non-zero if the user is requesting a detach, zero otherwise. */
-int (*ui_loop_hook) PARAMS ((int));
+int (*ui_loop_hook) (int);
/* Called instead of command_loop at top level. Can be invoked via
return_to_top_level. */
-void (*command_loop_hook) PARAMS ((void));
+void (*command_loop_hook) (void);
-/* Called instead of fputs for all output. */
-
-void (*fputs_unfiltered_hook) PARAMS ((const char *linebuffer, GDB_FILE * stream));
-
/* Called from print_frame_info to list the line we stopped in. */
-void (*print_frame_info_listing_hook) PARAMS ((struct symtab * s, int line,
- int stopline, int noerror));
+void (*print_frame_info_listing_hook) (struct symtab * s, int line,
+ int stopline, int noerror);
/* Replaces most of query. */
-int (*query_hook) PARAMS ((const char *, va_list));
+int (*query_hook) (const char *, va_list);
/* Replaces most of warning. */
-void (*warning_hook) PARAMS ((const char *, va_list));
+void (*warning_hook) (const char *, va_list);
/* 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
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));
+void (*readline_begin_hook) (char *, ...);
+char *(*readline_hook) (char *);
+void (*readline_end_hook) (void);
/* Called as appropriate to notify the interface of the specified breakpoint
conditions. */
-void (*create_breakpoint_hook) PARAMS ((struct breakpoint * bpt));
-void (*delete_breakpoint_hook) PARAMS ((struct breakpoint * bpt));
-void (*modify_breakpoint_hook) PARAMS ((struct breakpoint * bpt));
+void (*create_breakpoint_hook) (struct breakpoint * bpt);
+void (*delete_breakpoint_hook) (struct breakpoint * bpt);
+void (*modify_breakpoint_hook) (struct breakpoint * bpt);
/* Called as appropriate to notify the interface that we have attached
to or detached from an already running process. */
-void (*attach_hook) PARAMS ((void));
-void (*detach_hook) PARAMS ((void));
+void (*attach_hook) (void);
+void (*detach_hook) (void);
/* Called during long calculations to allow GUI to repair window damage, and to
check for stop buttons, etc... */
-void (*interactive_hook) PARAMS ((void));
+void (*interactive_hook) (void);
/* Called when the registers have changed, as a hint to a GUI
to minimize window update. */
-void (*registers_changed_hook) PARAMS ((void));
+void (*registers_changed_hook) (void);
/* Tell the GUI someone changed the register REGNO. -1 means
that the caller does not know which register changed or
that several registers have changed (see value_assign). */
-void (*register_changed_hook) PARAMS ((int regno));
+void (*register_changed_hook) (int regno);
/* Tell the GUI someone changed LEN bytes of memory at ADDR */
-void (*memory_changed_hook) PARAMS ((CORE_ADDR addr, int len));
+void (*memory_changed_hook) (CORE_ADDR addr, int len);
/* Called when going to wait for the target. Usually allows the GUI to run
while waiting for target events. */
-int (*target_wait_hook) PARAMS ((int pid, struct target_waitstatus * status));
+int (*target_wait_hook) (int pid, struct target_waitstatus * status);
/* Used by UI as a wrapper around command execution. May do various things
like enabling/disabling buttons, etc... */
-void (*call_command_hook) PARAMS ((struct cmd_list_element * c, char *cmd,
- int from_tty));
+void (*call_command_hook) (struct cmd_list_element * c, char *cmd,
+ int from_tty);
/* Called after a `set' command has finished. Is only run if the
`set' command succeeded. */
-void (*set_hook) PARAMS ((struct cmd_list_element *c));
+void (*set_hook) (struct cmd_list_element * c);
/* Called when the current thread changes. Argument is thread id. */
-void (*context_hook) PARAMS ((int id));
+void (*context_hook) (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 ((void)) ATTR_NORETURN;
+NORETURN void (*error_hook) (void) ATTR_NORETURN;
\f
-/* Where to go for return_to_top_level (RETURN_ERROR). */
- SIGJMP_BUF error_return;
-/* Where to go for return_to_top_level (RETURN_QUIT). */
- SIGJMP_BUF quit_return;
+/* One should use catch_errors rather than manipulating these
+ directly. */
+#if defined(HAVE_SIGSETJMP)
+#define SIGJMP_BUF sigjmp_buf
+#define SIGSETJMP(buf) sigsetjmp(buf, 1)
+#define SIGLONGJMP(buf,val) siglongjmp(buf,val)
+#else
+#define SIGJMP_BUF jmp_buf
+#define SIGSETJMP(buf) setjmp(buf)
+#define SIGLONGJMP(buf,val) longjmp(buf,val)
+#endif
+
+/* Where to go for return_to_top_level. */
+static SIGJMP_BUF *catch_return;
-/* Return for reason REASON. This generally gets back to the command
- loop, but can be caught via catch_errors. */
+/* Return for reason REASON to the nearest containing catch_errors(). */
- NORETURN void
-return_to_top_level (reason)
- enum return_reason reason;
+NORETURN void
+return_to_top_level (enum return_reason reason)
{
quit_flag = 0;
immediate_quit = 0;
disable_current_display ();
do_cleanups (ALL_CLEANUPS);
- if (event_loop_p && target_can_async_p ())
+ if (event_loop_p && target_can_async_p () && !target_executing)
do_exec_cleanups (ALL_CLEANUPS);
if (event_loop_p && sync_execution)
do_exec_error_cleanups (ALL_CLEANUPS);
break;
}
- (NORETURN void) SIGLONGJMP
- (reason == RETURN_ERROR ? error_return : quit_return, 1);
+ /* Jump to the containing catch_errors() call, communicating REASON
+ to that call via setjmp's return value. Note that REASON can't
+ be zero, by definition in defs.h. */
+
+ (NORETURN void) SIGLONGJMP (*catch_return, (int) reason);
}
/* Call FUNC with arg ARGS, catching any errors. If there is no
code also randomly used a SET_TOP_LEVEL macro that directly
initialize the longjmp buffers. */
-/* MAYBE: cagney/1999-11-05: Since the SET_TOP_LEVEL macro has been
- eliminated it is now possible to use the stack to directly store
- each longjmp buffer. The global code would just need to update a
- pointer (onto the stack - ulgh!?) indicating the current longjmp
- buffers. It would certainly improve the performance of the longjmp
- code since the memcpy's would be eliminated. */
-
/* MAYBE: cagney/1999-11-05: Should the catch_erros and cleanups code
be consolidated into a single file instead of being distributed
between utils.c and top.c? */
int
-catch_errors (func, args, errstring, mask)
- catch_errors_ftype *func;
- PTR args;
- char *errstring;
- return_mask mask;
+catch_errors (catch_errors_ftype *func, PTR args, char *errstring,
+ return_mask mask)
{
- SIGJMP_BUF saved_error;
- SIGJMP_BUF saved_quit;
- SIGJMP_BUF tmp_jmp;
+ SIGJMP_BUF *saved_catch;
+ SIGJMP_BUF catch;
int val;
struct cleanup *saved_cleanup_chain;
char *saved_error_pre_print;
char *saved_quit_pre_print;
- saved_cleanup_chain = save_cleanups ();
+ /* Return value from SIGSETJMP(): enum return_reason if error or
+ quit caught, 0 otherwise. */
+ int caught;
+
+ /* Override error/quit messages during FUNC. */
+
saved_error_pre_print = error_pre_print;
saved_quit_pre_print = quit_pre_print;
if (mask & RETURN_MASK_ERROR)
- {
- memcpy ((char *) saved_error, (char *) error_return, sizeof (SIGJMP_BUF));
- error_pre_print = errstring;
- }
+ error_pre_print = errstring;
if (mask & RETURN_MASK_QUIT)
- {
- memcpy (saved_quit, quit_return, sizeof (SIGJMP_BUF));
- quit_pre_print = errstring;
- }
+ quit_pre_print = errstring;
- if (SIGSETJMP (tmp_jmp) == 0)
- {
- if (mask & RETURN_MASK_ERROR)
- memcpy (error_return, tmp_jmp, sizeof (SIGJMP_BUF));
- if (mask & RETURN_MASK_QUIT)
- memcpy (quit_return, tmp_jmp, sizeof (SIGJMP_BUF));
- val = (*func) (args);
- /* FIXME: cagney/1999-11-05: A correct FUNC implementaton will
- clean things up (restoring the cleanup chain) to the state
- they were just prior to the call. Technically, this means
- that the below restore_cleanups call is redundant.
- Unfortunatly, many FUNC's are not that well behaved.
- restore_cleanups should either be replaced with a do_cleanups
- call (to cover the problem) or an assertion check to detect
- bad FUNCs code. */
- }
- else
- val = 0;
+ /* Prevent error/quit during FUNC from calling cleanups established
+ prior to here. */
+
+ saved_cleanup_chain = save_cleanups ();
+
+ /* Call FUNC, catching error/quit events. */
+
+ saved_catch = catch_return;
+ catch_return = &catch;
+ caught = SIGSETJMP (catch);
+ if (!caught)
+ val = (*func) (args);
+ catch_return = saved_catch;
+
+ /* FIXME: cagney/1999-11-05: A correct FUNC implementaton will
+ clean things up (restoring the cleanup chain) to the state they
+ were just prior to the call. Unfortunatly, many FUNC's are not
+ that well behaved. This could be fixed by adding either a
+ do_cleanups call (to cover the problem) or an assertion check to
+ detect bad FUNCs code. */
+
+ /* Restore the cleanup chain and error/quit messages to their
+ original states. */
restore_cleanups (saved_cleanup_chain);
- if (mask & RETURN_MASK_ERROR)
- {
- 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 (SIGJMP_BUF));
- quit_pre_print = saved_quit_pre_print;
- }
- return val;
+ quit_pre_print = saved_quit_pre_print;
+ if (mask & RETURN_MASK_ERROR)
+ error_pre_print = saved_error_pre_print;
+
+ /* Return normally if no error/quit event occurred. */
+
+ if (!caught)
+ return val;
+
+ /* If the caller didn't request that the event be caught, relay the
+ event to the next containing catch_errors(). */
+
+ if (!(mask & RETURN_MASK (caught)))
+ return_to_top_level (caught);
+
+ /* Tell the caller that an event was caught.
+
+ FIXME: nsd/2000-02-22: When MASK is RETURN_MASK_ALL, the caller
+ can't tell what type of event occurred.
+
+ A possible fix is to add a new interface, catch_event(), that
+ returns enum return_reason after catching an error or a quit.
+
+ When returning normally, i.e. without catching an error or a
+ quit, catch_event() could return RETURN_NORMAL, which would be
+ added to enum return_reason. FUNC would return information
+ exclusively via ARGS.
+
+ Alternatively, normal catch_event() could return FUNC's return
+ value. The caller would need to be aware of potential overlap
+ with enum return_reason, which could be publicly restricted to
+ negative values to simplify return value processing in FUNC and
+ in the caller. */
+
+ return 0;
}
struct captured_command_args
}
int
-catch_command_errors (catch_command_errors_ftype *command,
+catch_command_errors (catch_command_errors_ftype * command,
char *arg, int from_tty, return_mask mask)
{
struct captured_command_args args;
#ifdef SIGHUP
static void
-disconnect (signo)
- int signo;
+disconnect (int signo)
{
catch_errors (quit_cover, NULL,
"Could not kill the program being debugged", RETURN_MASK_ALL);
gdb to use the event loop as the default command loop and we merge
event-top.c into this file, top.c */
/* static */ int
-quit_cover (s)
- PTR s;
+quit_cover (PTR s)
{
caution = 0; /* Throw caution to the wind -- we're exiting.
This prevents asking the user dumb questions. */
user-defined command). */
static void
-source_cleanup (stream)
- FILE *stream;
+do_restore_instream_cleanup (void *stream)
{
/* Restore the previous input stream. */
instream = stream;
/* Read commands from STREAM. */
void
-read_command_file (stream)
- FILE *stream;
+read_command_file (FILE *stream)
{
struct cleanup *cleanups;
- cleanups = make_cleanup ((make_cleanup_func) source_cleanup, instream);
+ cleanups = make_cleanup (do_restore_instream_cleanup, instream);
instream = stream;
command_loop ();
do_cleanups (cleanups);
}
\f
-extern void init_proc PARAMS ((void));
+extern void init_proc (void);
-void (*pre_init_ui_hook) PARAMS ((void));
+void (*pre_init_ui_hook) (void);
+
+#ifdef __MSDOS__
+void
+do_chdir_cleanup (void *old_dir)
+{
+ chdir (old_dir);
+ free (old_dir);
+}
+#endif
void
-gdb_init (argv0)
- char *argv0;
+gdb_init (char *argv0)
{
if (pre_init_ui_hook)
pre_init_ui_hook ();
#ifdef __MSDOS__
/* Make sure we return to the original directory upon exit, come
what may, since the OS doesn't do that for us. */
- make_final_cleanup ((make_cleanup_func) chdir, strsave (current_directory));
+ make_final_cleanup (do_chdir_cleanup, xstrdup (current_directory));
#endif
init_cmd_lists (); /* This needs to be done first */
set_language (language_c);
expected_language = current_language; /* don't warn about the change. */
+#ifdef UI_OUT
+ /* Install the default UI */
+ uiout = cli_out_new (gdb_stdout);
+#endif
+
+#ifdef UI_OUT
/* All the interpreters should have had a look at things by now.
Initialize the selected interpreter. */
+ if (interpreter_p && !init_ui_hook)
+ {
+ fprintf_unfiltered (gdb_stderr, "Interpreter `%s' unrecognized.\n",
+ interpreter_p);
+ exit (1);
+ }
+#endif
+
if (init_ui_hook)
init_ui_hook (argv0);
}
control commands (if/while). */
static struct command_line *
-build_command_line (type, args)
- enum command_control_type type;
- char *args;
+build_command_line (enum command_control_type type, char *args)
{
struct command_line *cmd;
such as "if" and "while". */
static struct command_line *
-get_command_line (type, arg)
- enum command_control_type type;
- char *arg;
+get_command_line (enum command_control_type type, char *arg)
{
struct command_line *cmd;
struct cleanup *old_chain = NULL;
/* Allocate and build a new command line structure. */
cmd = build_command_line (type, arg);
- old_chain = make_cleanup ((make_cleanup_func) free_command_lines, &cmd);
+ old_chain = make_cleanup_free_command_lines (&cmd);
/* Read in the body of this command. */
if (recurse_read_control_structure (cmd) == invalid_control)
}
/* Recursively print a command (including full control structures). */
+#ifdef UI_OUT
+void
+print_command_lines (struct ui_out *uiout, struct command_line *cmd,
+ unsigned int depth)
+{
+ struct command_line *list;
+
+ list = cmd;
+ while (list)
+ {
+
+ if (depth)
+ ui_out_spaces (uiout, 2 * depth);
+
+ /* A simple command, print it and continue. */
+ if (list->control_type == simple_control)
+ {
+ ui_out_field_string (uiout, NULL, list->line);
+ ui_out_text (uiout, "\n");
+ list = list->next;
+ continue;
+ }
+
+ /* loop_continue to jump to the start of a while loop, print it
+ and continue. */
+ if (list->control_type == continue_control)
+ {
+ ui_out_field_string (uiout, NULL, "loop_continue");
+ ui_out_text (uiout, "\n");
+ list = list->next;
+ continue;
+ }
+
+ /* loop_break to break out of a while loop, print it and continue. */
+ if (list->control_type == break_control)
+ {
+ ui_out_field_string (uiout, NULL, "loop_break");
+ ui_out_text (uiout, "\n");
+ list = list->next;
+ continue;
+ }
+
+ /* A while command. Recursively print its subcommands and continue. */
+ if (list->control_type == while_control)
+ {
+ ui_out_text (uiout, "while ");
+ ui_out_field_fmt (uiout, NULL, "while %s", list->line);
+ ui_out_text (uiout, "\n");
+ print_command_lines (uiout, *list->body_list, depth + 1);
+ ui_out_field_string (uiout, NULL, "end");
+ if (depth)
+ ui_out_spaces (uiout, 2 * depth);
+ ui_out_text (uiout, "end\n");
+ list = list->next;
+ continue;
+ }
+
+ /* An if command. Recursively print both arms before continueing. */
+ if (list->control_type == if_control)
+ {
+ ui_out_text (uiout, "if ");
+ ui_out_field_fmt (uiout, NULL, "if %s", list->line);
+ ui_out_text (uiout, "\n");
+ /* The true arm. */
+ print_command_lines (uiout, list->body_list[0], depth + 1);
+
+ /* Show the false arm if it exists. */
+ if (list->body_count == 2)
+ {
+ if (depth)
+ ui_out_spaces (uiout, 2 * depth);
+ ui_out_field_string (uiout, NULL, "else");
+ ui_out_text (uiout, "else\n");
+ print_command_lines (uiout, list->body_list[1], depth + 1);
+ }
+
+ ui_out_field_string (uiout, NULL, "end");
+ if (depth)
+ ui_out_spaces (uiout, 2 * depth);
+ ui_out_text (uiout, "end\n");
+ list = list->next;
+ continue;
+ }
+
+ /* ignore illegal command type and try next */
+ list = list->next;
+ } /* while (list) */
+}
+#else
void
-print_command_line (cmd, depth, stream)
- struct command_line *cmd;
- unsigned int depth;
- GDB_FILE *stream;
+print_command_line (struct command_line *cmd, unsigned int depth,
+ struct ui_file *stream)
{
unsigned int i;
fputs_filtered ("end\n", stream);
}
}
+#endif
/* Execute the command in CMD. */
enum command_control_type
-execute_control_command (cmd)
- struct command_line *cmd;
+execute_control_command (struct command_line *cmd)
{
struct expression *expr;
struct command_line *current;
new_line = insert_args (cmd->line);
if (!new_line)
return invalid_control;
- old_chain = make_cleanup ((make_cleanup_func) free_current_contents,
- &new_line);
+ old_chain = make_cleanup (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 ((make_cleanup_func) free_current_contents,
- &new_line);
+ old_chain = make_cleanup (free_current_contents, &new_line);
expr = parse_expression (new_line);
- make_cleanup ((make_cleanup_func) free_current_contents, &expr);
+ make_cleanup (free_current_contents, &expr);
ret = simple_control;
loop = 1;
new_line = insert_args (cmd->line);
if (!new_line)
return invalid_control;
- old_chain = make_cleanup ((make_cleanup_func) free_current_contents,
- &new_line);
+ old_chain = make_cleanup (free_current_contents, &new_line);
/* Parse the conditional for the if statement. */
expr = parse_expression (new_line);
- make_cleanup ((make_cleanup_func) free_current_contents, &expr);
+ make_cleanup (free_current_contents, &expr);
current = NULL;
ret = simple_control;
loop condition is nonzero. */
static void
-while_command (arg, from_tty)
- char *arg;
- int from_tty;
+while_command (char *arg, int from_tty)
{
struct command_line *command = NULL;
on the value of the if conditional. */
static void
-if_command (arg, from_tty)
- char *arg;
- int from_tty;
+if_command (char *arg, int from_tty)
{
struct command_line *command = NULL;
/* Cleanup */
static void
-arg_cleanup ()
+arg_cleanup (void *ignore)
{
struct user_args *oargs = user_args;
if (!user_args)
$arg0, $arg1 ... $argMAXUSERARGS. */
static struct cleanup *
-setup_user_args (p)
- char *p;
+setup_user_args (char *p)
{
struct user_args *args;
struct cleanup *old_chain;
args->next = user_args;
user_args = args;
- old_chain = make_cleanup ((make_cleanup_func) arg_cleanup, 0);
+ old_chain = make_cleanup (arg_cleanup, 0/*ignored*/);
if (p == NULL)
return old_chain;
or NULL if P contains no arguments. */
static char *
-locate_arg (p)
- char *p;
+locate_arg (char *p)
{
while ((p = strchr (p, '$')))
{
arguments found in line, with the updated copy being placed into nline. */
static char *
-insert_args (line)
- char *line;
+insert_args (char *line)
{
char *p, *save_line, *new_line;
unsigned len, i;
}
void
-execute_user_command (c, args)
- struct cmd_list_element *c;
- char *args;
+execute_user_command (struct cmd_list_element *c, char *args)
{
register struct command_line *cmdlines;
struct cleanup *old_chain;
/* Set the instream to 0, indicating execution of a
user-defined function. */
- old_chain = make_cleanup ((make_cleanup_func) source_cleanup, instream);
+ old_chain = make_cleanup (do_restore_instream_cleanup, instream);
instream = (FILE *) 0;
while (cmdlines)
{
Pass FROM_TTY as second argument to the defining function. */
void
-execute_command (p, from_tty)
- char *p;
- int from_tty;
+execute_command (char *p, int from_tty)
{
register struct cmd_list_element *c;
register enum language flang;
static int warned = 0;
+ char *line;
/* FIXME: These should really be in an appropriate header file */
- extern void serial_log_command PARAMS ((const char *));
+extern void serial_log_command (const char *);
free_all_values ();
if (*p)
{
char *arg;
+ line = p;
c = lookup_cmd (&p, cmdlist, "", 0, 1);
if (c->hook)
execute_user_command (c->hook, (char *) 0);
+ if (c->flags & DEPRECATED_WARN_USER)
+ deprecated_cmd_warning (&line);
+
if (c->class == class_user)
execute_user_command (c, arg);
else if (c->type == set_cmd || c->type == show_cmd)
}
}
-/* ARGSUSED */
-/* NOTE 1999-04-29: This function will be static again, once we modify
- gdb to use the event loop as the default command loop and we merge
- event-top.c into this file, top.c */
-/* static */ void
-command_loop_marker (foo)
- int foo;
-{
-}
-
/* Read commands from `instream' and execute them
until end of file or error reading instream. */
void
-command_loop ()
+command_loop (void)
{
struct cleanup *old_chain;
char *command;
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)
/* A bit of paranoia: I want to make sure the "insert_mode" global
}
}
+/* Read commands from `instream' and execute them until end of file or
+ error reading instream. This command loop doesnt care about any
+ such things as displaying time and space usage. If the user asks
+ for those, they won't work. */
+void
+simplified_command_loop (read_input_func, execute_command_func)
+ char *(*read_input_func) (char *);
+ void (*execute_command_func) (char *, int);
+{
+ struct cleanup *old_chain;
+ char *command;
+ int stdin_is_tty = ISATTY (stdin);
+
+ while (instream && !feof (instream))
+ {
+ quit_flag = 0;
+ if (instream == stdin && stdin_is_tty)
+ reinitialize_more_filter ();
+ old_chain = make_cleanup (null_cleanup, 0);
+
+ /* Get a command-line. */
+ command = (*read_input_func) (instream == stdin ?
+ get_prompt () : (char *) NULL);
+
+ if (command == 0)
+ return;
+
+ (*execute_command_func) (command, instream == stdin);
+
+ /* Do any commands attached to breakpoint we stopped at. */
+ bpstat_do_actions (&stop_bpstat);
+
+ do_cleanups (old_chain);
+ }
+}
\f
/* Commands call this if they do not want to be repeated by null lines. */
void
-dont_repeat ()
+dont_repeat (void)
{
if (server_command)
return;
A NULL return means end of file. */
char *
-gdb_readline (prompt_arg)
- char *prompt_arg;
+gdb_readline (char *prompt_arg)
{
int c;
char *result;
char *gdb_completer_command_word_break_characters =
" \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,";
+/* When completing on file names, we remove from the list of word
+ break characters any characters that are commonly used in file
+ names, such as '-', '+', '~', etc. Otherwise, readline displays
+ incorrect completion candidates. */
+char *gdb_completer_file_name_break_characters = " \t\n*|\"';:?/><";
+
/* Characters that can be used to quote completion strings. Note that we
can't include '"' because the gdb C parser treats such quoted sequences
as strings. */
but don't want to complete on anything else either. */
/* ARGSUSED */
char **
-noop_completer (text, prefix)
- char *text;
- char *prefix;
+noop_completer (char *text, char *prefix)
{
return NULL;
}
/* Complete on filenames. */
char **
-filename_completer (text, word)
- char *text;
- char *word;
+filename_completer (char *text, char *word)
{
/* From readline. */
- extern char *filename_completion_function PARAMS ((char *, int));
+extern char *filename_completion_function (char *, int);
int subsequent_name;
char **return_val;
int return_val_used;
return_val[return_val_used++] = p;
break;
}
+ /* We need to set subsequent_name to a non-zero value before the
+ continue line below, because otherwise, if the first file seen
+ by GDB is a backup file whose name ends in a `~', we will loop
+ indefinitely. */
+ subsequent_name = 1;
/* Like emacs, don't complete on old versions. Especially useful
in the "source" command. */
if (p[strlen (p) - 1] == '~')
free (p);
}
}
- subsequent_name = 1;
}
#if 0
/* There is no way to do this just long enough to affect quote inserting
free the string. */
static char *
-line_completion_function (text, matches, line_buffer, point)
- char *text;
- int matches;
- char *line_buffer;
- int point;
+line_completion_function (char *text, int matches, char *line_buffer, int point)
{
static char **list = (char **) NULL; /* Cache of completions */
static int index; /* Next cached completion */
/* It is a normal command; what comes after it is
completed by the command's completer function. */
list = (*c->completer) (p, word);
+ if (c->completer == filename_completer)
+ rl_completer_word_break_characters =
+ gdb_completer_file_name_break_characters;
}
}
else
{
/* It is a normal command. */
list = (*c->completer) (p, word);
+ if (c->completer == filename_completer)
+ rl_completer_word_break_characters =
+ gdb_completer_file_name_break_characters;
}
}
}
/* Line completion interface function for readline. */
static char *
-readline_line_completion_function (text, matches)
- char *text;
- int matches;
+readline_line_completion_function (char *text, int matches)
{
return line_completion_function (text, matches, rl_line_buffer, rl_point);
}
location after the "word". */
char *
-skip_quoted (str)
- char *str;
+skip_quoted (char *str)
{
char quote_char = '\0';
char *scan;
#ifdef STOP_SIGNAL
static void
-stop_sig (signo)
- int signo;
+stop_sig (int signo)
{
#if STOP_SIGNAL == SIGTSTP
signal (SIGTSTP, SIG_DFL);
/* Initialize signal handlers. */
static void
-do_nothing (signo)
- int signo;
+do_nothing (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
}
static void
-init_signals ()
+init_signals (void)
{
signal (SIGINT, request_quit);
simple input as the user has requested. */
char *
-command_line_input (prompt_arg, repeat, annotation_suffix)
- char *prompt_arg;
- int repeat;
- char *annotation_suffix;
+command_line_input (char *prompt_arg, int repeat, char *annotation_suffix)
{
static char *linebuffer = 0;
static unsigned linelength = 0;
clause for an "if" command. */
static void
-realloc_body_list (command, new_length)
- struct command_line *command;
- int new_length;
+realloc_body_list (struct command_line *command, int new_length)
{
int n;
struct command_line **body_list;
"end", return such an indication to the caller. */
static enum misc_command_type
-read_next_line (command)
- struct command_line **command;
+read_next_line (struct command_line **command)
{
char *p, *p1, *prompt_ptr, control_prompt[256];
int i = 0;
following commands are nested. */
static enum command_control_type
-recurse_read_control_structure (current_cmd)
- struct command_line *current_cmd;
+recurse_read_control_structure (struct command_line *current_cmd)
{
int current_body, i;
enum misc_command_type val;
#define END_MESSAGE "End with a line saying just \"end\"."
struct command_line *
-read_command_lines (prompt_arg, from_tty)
- char *prompt_arg;
- int from_tty;
+read_command_lines (char *prompt_arg, int from_tty)
{
struct command_line *head, *tail, *next;
struct cleanup *old_chain;
else
{
head = next;
- old_chain = make_cleanup ((make_cleanup_func) free_command_lines,
- &head);
+ old_chain = make_cleanup_free_command_lines (&head);
}
tail = next;
}
/* Free a chain of struct command_line's. */
void
-free_command_lines (lptr)
- struct command_line **lptr;
+free_command_lines (struct command_line **lptr)
{
register struct command_line *l = *lptr;
register struct command_line *next;
l = next;
}
}
+
+static void
+do_free_command_lines_cleanup (void *arg)
+{
+ free_command_lines (arg);
+}
+
+static struct cleanup *
+make_cleanup_free_command_lines (struct command_line **arg)
+{
+ return make_cleanup (do_free_command_lines_cleanup, arg);
+}
\f
/* Add an element to the list of info subcommands. */
-void
+struct cmd_list_element *
add_info (name, fun, doc)
char *name;
- void (*fun) PARAMS ((char *, int));
+ void (*fun) (char *, int);
char *doc;
{
- add_cmd (name, no_class, fun, doc, &infolist);
+ return add_cmd (name, no_class, fun, doc, &infolist);
}
/* Add an alias to the list of info subcommands. */
-void
-add_info_alias (name, oldname, abbrev_flag)
- char *name;
- char *oldname;
- int abbrev_flag;
+struct cmd_list_element *
+add_info_alias (char *name, char *oldname, int abbrev_flag)
{
- add_alias_cmd (name, oldname, 0, abbrev_flag, &infolist);
+ return add_alias_cmd (name, oldname, 0, abbrev_flag, &infolist);
}
/* The "info" command is defined as a prefix, with allow_unknown = 0.
/* ARGSUSED */
static void
-info_command (arg, from_tty)
- char *arg;
- int from_tty;
+info_command (char *arg, int from_tty)
{
printf_unfiltered ("\"info\" must be followed by the name of an info command.\n");
help_list (infolist, "info ", -1, gdb_stdout);
/* ARGSUSED */
static void
-complete_command (arg, from_tty)
- char *arg;
- int from_tty;
+complete_command (char *arg, int from_tty)
{
int i;
int argpoint;
/* ARGSUSED */
static void
-show_command (arg, from_tty)
- char *arg;
- int from_tty;
+show_command (char *arg, int from_tty)
{
cmd_show_list (showlist, from_tty, "");
}
\f
/* Add an element to the list of commands. */
-void
+struct cmd_list_element *
add_com (name, class, fun, doc)
char *name;
enum command_class class;
- void (*fun) PARAMS ((char *, int));
+ void (*fun) (char *, int);
char *doc;
{
- add_cmd (name, class, fun, doc, &cmdlist);
+ return add_cmd (name, class, fun, doc, &cmdlist);
}
/* Add an alias or abbreviation command to the list of commands. */
-void
-add_com_alias (name, oldname, class, abbrev_flag)
- char *name;
- char *oldname;
- enum command_class class;
- int abbrev_flag;
+struct cmd_list_element *
+add_com_alias (char *name, char *oldname, enum command_class class,
+ int abbrev_flag)
{
- add_alias_cmd (name, oldname, class, abbrev_flag, &cmdlist);
+ return add_alias_cmd (name, oldname, class, abbrev_flag, &cmdlist);
}
void
-error_no_arg (why)
- char *why;
+error_no_arg (char *why)
{
error ("Argument required (%s).", why);
}
}
\f
static void
-validate_comname (comname)
- char *comname;
+validate_comname (char *comname)
{
register char *p;
/* This is just a placeholder in the command data structures. */
static void
-user_defined_command (ignore, from_tty)
- char *ignore;
- int from_tty;
+user_defined_command (char *ignore, int from_tty)
{
}
static void
-define_command (comname, from_tty)
- char *comname;
- int from_tty;
+define_command (char *comname, int from_tty)
{
register struct command_line *cmds;
register struct cmd_list_element *c, *newc, *hookc = 0;
}
static void
-document_command (comname, from_tty)
- char *comname;
- int from_tty;
+document_command (char *comname, int from_tty)
{
struct command_line *doclines;
register struct cmd_list_element *c;
\f
/* Print the GDB banner. */
void
-print_gdb_version (stream)
- GDB_FILE *stream;
+print_gdb_version (struct ui_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. */
+#ifdef UI_OUT
+ /* Print it console style until a format is defined */
+ fprintf_filtered (stream, "GNU gdb %s (UI_OUT)\n", version);
+#else
fprintf_filtered (stream, "GNU gdb %s\n", version);
+#endif
/* Second line is a copyright notice. */
- fprintf_filtered (stream, "Copyright 1998 Free Software Foundation, Inc.\n");
+ fprintf_filtered (stream, "Copyright 2000 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
/* ARGSUSED */
static void
-show_version (args, from_tty)
- char *args;
- int from_tty;
+show_version (char *args, int from_tty)
{
immediate_quit++;
print_gdb_version (gdb_stdout);
static int gdb_prompt_escape;
static int
-get_prompt_1 (formatted_prompt)
- char *formatted_prompt;
+get_prompt_1 (void *data)
{
+ char *formatted_prompt = data;
char *local_prompt;
if (event_loop_p)
}
char *
-get_prompt ()
+get_prompt (void)
{
static char buf[MAX_PROMPT_SIZE];
}
void
-set_prompt (s)
- char *s;
+set_prompt (char *s)
{
/* ??rehrauer: I don't know why this fails, since it looks as though
assignments to prompt are wrapped in calls to savestring...
non-zero if we should quit, zero if we shouldn't. */
int
-quit_confirm ()
+quit_confirm (void)
{
if (inferior_pid != 0 && target_has_execution)
{
/* Quit without asking for confirmation. */
void
-quit_force (args, from_tty)
- char *args;
- int from_tty;
+quit_force (char *args, int from_tty)
{
int exit_code = 0;
/* Handle the quit command. */
void
-quit_command (args, from_tty)
- char *args;
- int from_tty;
+quit_command (char *args, int from_tty)
{
if (!quit_confirm ())
error ("Not confirmed.");
desires that questions be asked of them on that terminal. */
int
-input_from_terminal_p ()
+input_from_terminal_p (void)
{
return gdb_has_a_terminal () && (instream == stdin) & caution;
}
\f
/* ARGSUSED */
static void
-pwd_command (args, from_tty)
- char *args;
- int from_tty;
+pwd_command (char *args, int from_tty)
{
if (args)
error ("The \"pwd\" command does not take an argument: %s", args);
}
void
-cd_command (dir, from_tty)
- char *dir;
- int from_tty;
+cd_command (char *dir, int from_tty)
{
int len;
/* Found something other than leading repetitions of "/..". */
#endif
len = strlen (dir);
- if (SLASH_P (dir[len-1]))
+ if (SLASH_P (dir[len - 1]))
{
/* Remove the trailing slash unless this is a root directory
- (including a drive letter on non-Unix systems). */
- if (!(len == 1) /* "/" */
+ (including a drive letter on non-Unix systems). */
+ if (!(len == 1) /* "/" */
#if defined(_WIN32) || defined(__MSDOS__)
- && !(!SLASH_P (*dir) && ROOTED_P (dir) && len <= 3) /* "d:/" */
+ && !(!SLASH_P (*dir) && ROOTED_P (dir) && len <= 3) /* "d:/" */
#endif
)
len--;
};
static void
-source_cleanup_lines (args)
- PTR args;
+source_cleanup_lines (PTR args)
{
struct source_cleanup_lines_args *p =
(struct source_cleanup_lines_args *) args;
}
/* ARGSUSED */
+static void
+do_fclose_cleanup (void *stream)
+{
+ fclose (stream);
+}
+
void
-source_command (args, from_tty)
- char *args;
- int from_tty;
+source_command (char *args, int from_tty)
{
FILE *stream;
struct cleanup *old_cleanups;
return;
}
- make_cleanup ((make_cleanup_func) fclose, stream);
+ make_cleanup (do_fclose_cleanup, stream);
old_lines.old_line = source_line_number;
old_lines.old_file = source_file_name;
/* ARGSUSED */
static void
-echo_command (text, from_tty)
- char *text;
- int from_tty;
+echo_command (char *text, int from_tty)
{
char *p = text;
register int c;
/* ARGSUSED */
static void
-dont_repeat_command (ignored, from_tty)
- char *ignored;
- int from_tty;
+dont_repeat_command (char *ignored, int from_tty)
{
*line = 0; /* Can't call dont_repeat here because we're not
necessarily reading from stdin. */
/* Number of commands to print in each call to show_commands. */
#define Hist_print 10
static void
-show_commands (args, from_tty)
- char *args;
- int from_tty;
+show_commands (char *args, int from_tty)
{
/* Index for history commands. Relative to history_base. */
int offset;
than the number of the last command). Relative to history_base. */
int hist_len;
- extern HIST_ENTRY *history_get PARAMS ((int));
+extern HIST_ENTRY *history_get (int);
/* Print out some of the commands from the command history. */
/* First determine the length of the history list. */
/* Called by do_setshow_command. */
/* ARGSUSED */
static void
-set_history_size_command (args, from_tty, c)
- char *args;
- int from_tty;
- struct cmd_list_element *c;
+set_history_size_command (char *args, int from_tty, struct cmd_list_element *c)
{
if (history_size == INT_MAX)
unstifle_history ();
/* ARGSUSED */
static void
-set_history (args, from_tty)
- char *args;
- int from_tty;
+set_history (char *args, int from_tty)
{
printf_unfiltered ("\"set history\" must be followed by the name of a history subcommand.\n");
help_list (sethistlist, "set history ", -1, gdb_stdout);
/* ARGSUSED */
static void
-show_history (args, from_tty)
- char *args;
- int from_tty;
+show_history (char *args, int from_tty)
{
cmd_show_list (showhistlist, from_tty, "");
}
/* Called by do_setshow_command. An elaborate joke. */
/* ARGSUSED */
static void
-set_verbose (args, from_tty, c)
- char *args;
- int from_tty;
- struct cmd_list_element *c;
+set_verbose (char *args, int from_tty, struct cmd_list_element *c)
{
char *cmdname = "verbose";
struct cmd_list_element *showcmd;
}
static void
-float_handler (signo)
- int signo;
+float_handler (int signo)
{
/* This message is based on ANSI C, section 4.7. Note that integer
divide by zero causes this, so "float" is a misnomer. */
signal (SIGFPE, float_handler);
error ("Erroneous arithmetic operation.");
}
-\f
static void
-init_cmd_lists ()
+set_debug (char *arg, int from_tty)
+{
+ printf_unfiltered ("\"set debug\" must be followed by the name of a print subcommand.\n");
+ help_list (setdebuglist, "set debug ", -1, gdb_stdout);
+}
+
+static void
+show_debug (char *args, int from_tty)
+{
+ cmd_show_list (showdebuglist, from_tty, "");
+}
+
+static void
+init_cmd_lists (void)
{
cmdlist = NULL;
infolist = NULL;
*/
void
-init_history ()
+init_history (void)
{
char *tmpenv;
directories the file written will be the same as the one
that was read. */
#ifdef __MSDOS__
- /* No leading dots in file names are allowed on MSDOS. */
- history_filename = concat (current_directory, "/_gdb_history", NULL);
+ /* No leading dots in file names are allowed on MSDOS. */
+ history_filename = concat (current_directory, "/_gdb_history", NULL);
#else
history_filename = concat (current_directory, "/.gdb_history", NULL);
#endif
}
static void
-init_main ()
+init_main (void)
{
struct cmd_list_element *c;
using remote targets.", &setlist),
&showlist);
- add_show_from_set (
- add_set_cmd ("remotedebug", no_class, var_zinteger, (char *) &remote_debug,
- "Set debugging of remote protocol.\n\
+ c = add_set_cmd ("remotedebug", no_class, var_zinteger,
+ (char *) &remote_debug,
+ "Set debugging of remote protocol.\n\
When enabled, each packet sent or received with the remote target\n\
-is displayed.", &setlist),
- &showlist);
+is displayed.", &setlist);
+ deprecate_cmd (c, "set debug remote");
+ deprecate_cmd (add_show_from_set (c, &showlist), "show debug remote");
+
+ add_show_from_set (add_set_cmd ("remote", no_class, var_zinteger,
+ (char *) &remote_debug,
+ "Set debugging of remote protocol.\n\
+When enabled, each packet sent or received with the remote target\n\
+is displayed.", &setdebuglist),
+ &showdebuglist);
add_show_from_set (
add_set_cmd ("remotetimeout", no_class, var_integer, (char *) &remote_timeout,
Use \"on\" to enable the notification, and \"off\" to disable it.", &setlist),
&showlist);
}
+ add_prefix_cmd ("debug", no_class, set_debug,
+ "Generic command for setting gdb debugging flags",
+ &setdebuglist, "set debug ", 0, &setlist);
+
+ add_prefix_cmd ("debug", no_class, show_debug,
+ "Generic command for showing gdb debugging flags",
+ &showdebuglist, "show debug ", 0, &showlist);
}