2000-12-01 Fernando Nasser <fnasser@redhat.com>

* cli/cli-decode.c: New file. Handle lists of commands, their decoding
        and documentation.
        (add_cmd, deprecate_cmd, add_abbrev_cmd, add_alias_cmd, add_prefix_cmd,
        add_abbrev_prefix_cmd, not_just_help_class_command, empty_sfunc,
        add_set_cmd, add_set_enum_cmd, add_set_auto_boolean_cmd,
        add_show_from_set, delete_cmd, apropos_cmd, help_cmd, help_list,
        help_all, print_doc_line, help_cmd_list, find_cmd, lookup_cmd_1,
        undef_cmd_error, lookup_cmd, deprecated_cmd_warning,
        lookup_cmd_composition, complete_on_cmdlist, complete_on_enum):
        Moved here from command.c.
        (add_info, add_info_alias, add_com, add_com_alias): Moved here from
        top.c.
        * cli/cli-decode.h: Definitions/declarations for the above.
        * cli/cli-cmds.c: New file.  GDB CLI commands.
        (error_no_arg, info_command, show_command, help_command, show_version,
        quit_command, pwd_command, cd_command, echo_command, shell_escape,
        make_command, show_user, set_debug, show_debug, init_cmd_lists):
        Moved here from top.c.
        (apropos_command): Moved here from command.c.
        (complete_command, source_command): Moved here (part) from top.c.
        (is_complete_command): New function. Checks if a command is the
        "complete" command.
        (init_cli_cmds): New function. Add commands to the CLI (from code
        previously in top.c.
        * cli/cli-cmds.h: Definitions/declarations for the above.
        * cli/cli-script.c: New file. GDB CLI command scripting.
        (build_command_line, get_command_line, print_command_lines,
        print_command_line, execute_user_command, execute_control_command,
        while_command, if_command, arg_cleanup, setup_user_args, locate_arg,
        insert_args, realloc_body_list, read_next_line,
        recurse_read_control_structure, read_command_lines, free_command_lines,
        do_free_command_lines_cleanup, make_cleanup_free_command_lines,
        validate_comname, user_defined_command, define_command,
        document_command, source_cleanup_lines, do_fclose_cleanup,
        show_user_1): Moved here from top.c.
        (script_from_file): New function. Implements execution of a script
        contained in a file (part of code for the source_command() that used
        to exist in top.c).
        * cli/cli-script.h: Definitions/declarations for the above.
        * cli/cli-setshow.c: New file. Handle set and show GDB CLI commands.
        (parse_auto_binary_operation, parse_binary_operation,
        do_setshow_command, cmd_show_list): Moved here from command.c.
        * cli/cli-setshow.h: Definitions/declarations for the above.
        * top.c: Remove all CLI code, except the command loop.
        (gdb_init): Call init_cli_cmds().
        * command.c: Remove obsolete file.
        * command.h: Mark as DEPRECATED.
        * gdbcmd.h: Ditto.
        * call-cmds.h: Ditto.
        * Makefile.in (SFILES): Remove command.c.
        (COMMON_OBS): Remove command.o.
        (command.o): Remove obsolete target.
        (cli_decode_h, cli_cmds_h, cli_script_h, cli_setshow_h): New macros.
        Refer to CLI header files.
        (cli-decode.o, cli-cmds.o, cli-setshow.o, cli-script.o): New targets.
        (SUBDIR_CLI_OBS, SUBDIR_CLI_SRCS, SUBDIR_CLI_DEPS, SUBDIR_CLI_INITS,
        SUBDIR_CLI_LDFLAGS, SUBDIR_CLI_CFLAGS, SUBDIR_CLI_ALL, SUBDIR_CLI_CLEAN,
        SUBDIR_CLI_INSTALL, SUBDIR_CLI_UNINSTALL): New macros for new cli
        subdirectory.
        * configure.in (enable_gdbcli): New option. Include the CLI in the
        executable (cannot be disabled yet).
        (CONFIG_OBS, CONFIG_DEPS, CONFIG_SRCS, CONFIG_INITS, ENABLE_CFLAGS,
        CONFIG_ALL, CONFIG_CLEAN, CONFIG_INSTALL, CONFIG_UNINSTALL): Add
        the corresponding SUBDIR_CLI_* macros if CLI requested.
        * configure: Regenerate.
This commit is contained in:
Fernando Nasser 2000-12-01 18:01:38 +00:00
parent 4ce3447c16
commit d318976c46
16 changed files with 3812 additions and 2897 deletions

View File

@ -1,3 +1,71 @@
2000-12-01 Fernando Nasser <fnasser@redhat.com>
* cli/cli-decode.c: New file. Handle lists of commands, their decoding
and documentation.
(add_cmd, deprecate_cmd, add_abbrev_cmd, add_alias_cmd, add_prefix_cmd,
add_abbrev_prefix_cmd, not_just_help_class_command, empty_sfunc,
add_set_cmd, add_set_enum_cmd, add_set_auto_boolean_cmd,
add_show_from_set, delete_cmd, apropos_cmd, help_cmd, help_list,
help_all, print_doc_line, help_cmd_list, find_cmd, lookup_cmd_1,
undef_cmd_error, lookup_cmd, deprecated_cmd_warning,
lookup_cmd_composition, complete_on_cmdlist, complete_on_enum):
Moved here from command.c.
(add_info, add_info_alias, add_com, add_com_alias): Moved here from
top.c.
* cli/cli-decode.h: Definitions/declarations for the above.
* cli/cli-cmds.c: New file. GDB CLI commands.
(error_no_arg, info_command, show_command, help_command, show_version,
quit_command, pwd_command, cd_command, echo_command, shell_escape,
make_command, show_user, set_debug, show_debug, init_cmd_lists):
Moved here from top.c.
(apropos_command): Moved here from command.c.
(complete_command, source_command): Moved here (part) from top.c.
(is_complete_command): New function. Checks if a command is the
"complete" command.
(init_cli_cmds): New function. Add commands to the CLI (from code
previously in top.c.
* cli/cli-cmds.h: Definitions/declarations for the above.
* cli/cli-script.c: New file. GDB CLI command scripting.
(build_command_line, get_command_line, print_command_lines,
print_command_line, execute_user_command, execute_control_command,
while_command, if_command, arg_cleanup, setup_user_args, locate_arg,
insert_args, realloc_body_list, read_next_line,
recurse_read_control_structure, read_command_lines, free_command_lines,
do_free_command_lines_cleanup, make_cleanup_free_command_lines,
validate_comname, user_defined_command, define_command,
document_command, source_cleanup_lines, do_fclose_cleanup,
show_user_1): Moved here from top.c.
(script_from_file): New function. Implements execution of a script
contained in a file (part of code for the source_command() that used
to exist in top.c).
* cli/cli-script.h: Definitions/declarations for the above.
* cli/cli-setshow.c: New file. Handle set and show GDB CLI commands.
(parse_auto_binary_operation, parse_binary_operation,
do_setshow_command, cmd_show_list): Moved here from command.c.
* cli/cli-setshow.h: Definitions/declarations for the above.
* top.c: Remove all CLI code, except the command loop.
(gdb_init): Call init_cli_cmds().
* command.c: Remove obsolete file.
* command.h: Mark as DEPRECATED.
* gdbcmd.h: Ditto.
* call-cmds.h: Ditto.
* Makefile.in (SFILES): Remove command.c.
(COMMON_OBS): Remove command.o.
(command.o): Remove obsolete target.
(cli_decode_h, cli_cmds_h, cli_script_h, cli_setshow_h): New macros.
Refer to CLI header files.
(cli-decode.o, cli-cmds.o, cli-setshow.o, cli-script.o): New targets.
(SUBDIR_CLI_OBS, SUBDIR_CLI_SRCS, SUBDIR_CLI_DEPS, SUBDIR_CLI_INITS,
SUBDIR_CLI_LDFLAGS, SUBDIR_CLI_CFLAGS, SUBDIR_CLI_ALL, SUBDIR_CLI_CLEAN,
SUBDIR_CLI_INSTALL, SUBDIR_CLI_UNINSTALL): New macros for new cli
subdirectory.
* configure.in (enable_gdbcli): New option. Include the CLI in the
executable (cannot be disabled yet).
(CONFIG_OBS, CONFIG_DEPS, CONFIG_SRCS, CONFIG_INITS, ENABLE_CFLAGS,
CONFIG_ALL, CONFIG_CLEAN, CONFIG_INSTALL, CONFIG_UNINSTALL): Add
the corresponding SUBDIR_CLI_* macros if CLI requested.
* configure: Regenerate.
2000-10-27 Pierre Muller <muller@ics.u-strasbg.fr>
* p-exp.y (yylex): avoid problem with symbol name

View File

@ -134,6 +134,22 @@ INTL_DEPS = @INTLDEPS@
INTL_SRC = $(srcdir)/$(INTL_DIR)
INTL_CFLAGS = -I$(INTL_DIR) -I$(INTL_SRC)
#
# CLI sub directory definitons
#
SUBDIR_CLI_OBS = \
cli-decode.o cli-script.o cli-cmds.o cli-setshow.o
SUBDIR_CLI_SRCS = \
cli/cli-decode.c cli/cli-script.c cli/cli-cmds.c cli/cli-setshow.c
SUBDIR_CLI_DEPS =
SUBDIR_CLI_INITS =
SUBDIR_CLI_LDFLAGS=
SUBDIR_CLI_CFLAGS=
SUBDIR_CLI_ALL=
SUBDIR_CLI_CLEAN=
SUBDIR_CLI_INSTALL=
SUBDIR_CLI_UNINSTALL=
#
# MI sub directory definitons
#
@ -477,7 +493,7 @@ TARGET_FLAGS_TO_PASS = \
SFILES = ax-general.c ax-gdb.c bcache.c blockframe.c breakpoint.c \
buildsym.c c-exp.y c-lang.c c-typeprint.c c-valprint.c \
ch-exp.c ch-lang.c ch-typeprint.c ch-valprint.c coffread.c \
command.c complaints.c completer.c corefile.c cp-valprint.c dbxread.c \
complaints.c completer.c corefile.c cp-valprint.c dbxread.c \
demangle.c dwarfread.c dwarf2read.c elfread.c environ.c eval.c \
event-loop.c event-top.c \
expprint.c f-exp.y f-lang.c f-typeprint.c f-valprint.c \
@ -548,8 +564,8 @@ breakpoint_h = breakpoint.h $(frame_h) $(value_h)
command_h = command.h
gdbcmd_h = gdbcmd.h $(command_h)
call_cmds_h = call-cmds.h
xm_h = @xm_h@
tm_h = @tm_h@
nm_h = @nm_h@
@ -568,6 +584,11 @@ ui_out_h = ui-out.h
cli_out_h = cli-out.h
arch_utils_h = arch-utils.h
cli_decode_h = $(srcdir)/cli/cli-decode.h
cli_cmds_h = $(srcdir)/cli/cli-cmds.h
cli_script_h = $(srcdir)/cli/cli-script.h
cli_setshow_h = $(srcdir)/cli/cli-setshow.h
# Header files that need to have srcdir added. Note that in the cases
# where we use a macro like $(gdbcmd_h), things are carefully arranged
# so that each .h file is listed exactly once (M-x tags-search works
@ -621,7 +642,7 @@ TAGFILES_WITH_SRCDIR = $(HFILES_WITH_SRCDIR)
COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o regcache.o \
source.o values.o eval.o valops.o valarith.o valprint.o printcmd.o \
symtab.o symfile.o symmisc.o linespec.o infcmd.o infrun.o command.o \
symtab.o symfile.o symmisc.o linespec.o infcmd.o infrun.o \
expprint.o environ.o stack.o thread.o \
event-loop.o event-top.o inf-loop.o completer.o \
gdbarch.o arch-utils.o gdbtypes.o copying.o $(DEPFILES) \
@ -1214,8 +1235,8 @@ coffread.o: coffread.c $(bfd_h) $(breakpoint_h) buildsym.h \
symfile.h $(symtab_h) gdb-stabs.h stabsread.h target.h \
gdb_string.h
command.o: command.c $(defs_h) $(expression_h) $(gdbcmd_h) \
$(gdbtypes_h) $(symtab_h) $(value_h) gdb_string.h gdb_wait.h
# OBSOLETE command.o: command.c $(defs_h) $(expression_h) $(gdbcmd_h) \
# OBSOLETE $(gdbtypes_h) $(symtab_h) $(value_h) gdb_string.h gdb_wait.h
complaints.o: complaints.c complaints.h $(defs_h) $(gdbcmd_h)
@ -2013,6 +2034,32 @@ varobj.o: varobj.c $(defs_h) $(frame_h) $(value_h) \
$(CC) -c $(INTERNAL_WARN_CFLAGS) $(NO_WERROR_CFLAGS) $<
wrapper.o: wrapper.c $(defs_h) $(frame_h) $(value_h) wrapper.h
#
# CLI dependencies
#
# Need to explicitly specify the compile rule as make will do nothing
# or try to compile the object file into the cli directory.
cli-decode.o: $(srcdir)/cli/cli-decode.c $(cli_decode_h) \
$(cli_cmds_h) $(defs_h) $(ui_out_h) \
$(symtab_h) gnu-regex.h
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-decode.c
cli-cmds.o: $(srcdir)/cli/cli-cmds.c $(cli_cmds_h) $(cli_decode_h) \
$(cli_script_h) $(cli_setshow_h) top.h completer.h $(defs_h) \
$(target_h) gdb_wait.h gnu-regex.h $(ui_out_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-cmds.c
cli-setshow.o: $(srcdir)/cli/cli-setshow.c $(cli_setshow_h) \
$(cli_decode_h) $(cli_cmds_h) $(defs_h) \
$(value_h) $(ui_out_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-setshow.c
cli-script.o: $(srcdir)/cli/cli-script.c $(cli_script_h) \
$(cli_cmds_h) $(cli_decode_h) top.h \
$(defs_h) $(value_h) language.h $(ui_out_h)
$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/cli/cli-script.c
#
# MI dependencies
#

View File

@ -1,3 +1,10 @@
/* ***DEPRECATED*** The gdblib files must not be calling/using things in any
of the possible command languages. If necessary, a hook (that may be
present or not) must be used and set to the appropriate routine by any
command language that cares about it. If you are having to include this
file you are possibly doing things the old way. This file will disapear.
fnasser@redhat.com */
/* Prototypes for GDB commands that are called internally by other functions.
Copyright 1992 Free Software Foundation, Inc.

801
gdb/cli/cli-cmds.c Normal file
View File

@ -0,0 +1,801 @@
/* GDB CLI commands.
Copyright 2000 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "completer.h"
#include "target.h" /* For baud_rate, remote_debug and remote_timeout */
#include "gdb_wait.h" /* For shell escape implementation */
#include "gnu-regex.h" /* Used by apropos_command */
#ifdef UI_OUT
#include "ui-out.h"
#endif
#include "top.h"
#include "cli/cli-decode.h"
#include "cli/cli-script.h"
#include "cli/cli-setshow.h"
#include "cli/cli-cmds.h"
#ifndef GDBINIT_FILENAME
#define GDBINIT_FILENAME ".gdbinit"
#endif
/* FIXME: this should be auto-configured! */
#ifdef __MSDOS__
# define CANT_FORK
#endif
/* From gdb/top.c */
extern void dont_repeat (void);
extern void set_verbose (char *, int, struct cmd_list_element *);
extern void show_history (char *, int);
extern void set_history (char *, int);
extern void show_commands (char *, int);
/* Prototypes for local functions */
static void complete_command (char *, int);
static void echo_command (char *, int);
static void pwd_command (char *, int);
static void show_version (char *, int);
static void validate_comname (char *);
static void help_command (char *, int);
static void show_command (char *, int);
static void info_command (char *, int);
static void show_debug (char *, int);
static void set_debug (char *, int);
static void show_user (char *, int);
static void make_command (char *, int);
static void shell_escape (char *, int);
void apropos_command (char *, int);
/* Define all cmd_list_elements. */
/* Chain containing all defined commands. */
struct cmd_list_element *cmdlist;
/* Chain containing all defined info subcommands. */
struct cmd_list_element *infolist;
/* Chain containing all defined enable subcommands. */
struct cmd_list_element *enablelist;
/* Chain containing all defined disable subcommands. */
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;
/* Chain containing all defined "enable breakpoint" subcommands. */
struct cmd_list_element *enablebreaklist;
/* Chain containing all defined set subcommands */
struct cmd_list_element *setlist;
/* Chain containing all defined unset subcommands */
struct cmd_list_element *unsetlist;
/* Chain containing all defined show subcommands. */
struct cmd_list_element *showlist;
/* Chain containing all defined \"set history\". */
struct cmd_list_element *sethistlist;
/* Chain containing all defined \"show history\". */
struct cmd_list_element *showhistlist;
/* Chain containing all defined \"unset history\". */
struct cmd_list_element *unsethistlist;
/* Chain containing all defined maintenance subcommands. */
struct cmd_list_element *maintenancelist;
/* Chain containing all defined "maintenance info" subcommands. */
struct cmd_list_element *maintenanceinfolist;
/* Chain containing all defined "maintenance print" subcommands. */
struct cmd_list_element *maintenanceprintlist;
struct cmd_list_element *setprintlist;
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;
/* Utility used everywhere when at least one argument is needed and
none is supplied. */
void
error_no_arg (char *why)
{
error ("Argument required (%s).", why);
}
/* The "info" command is defined as a prefix, with allow_unknown = 0.
Therefore, its own definition is called only for "info" with no args. */
/* ARGSUSED */
static void
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);
}
/* The "show" command with no arguments shows all the settings. */
/* ARGSUSED */
static void
show_command (char *arg, int from_tty)
{
cmd_show_list (showlist, from_tty, "");
}
/* Provide documentation on command or list given by COMMAND. FROM_TTY
is ignored. */
/* ARGSUSED */
static void
help_command (char *command, int from_tty)
{
help_cmd (command, gdb_stdout);
}
/* The "complete" command is used by Emacs to implement completion. */
/* ARGSUSED */
static void
complete_command (char *arg, int from_tty)
{
int i;
int argpoint;
char *completion;
dont_repeat ();
if (arg == NULL)
arg = "";
argpoint = strlen (arg);
for (completion = line_completion_function (arg, i = 0, arg, argpoint);
completion;
completion = line_completion_function (arg, ++i, arg, argpoint))
{
printf_unfiltered ("%s\n", completion);
free (completion);
}
}
int is_complete_command (void (*func) (char *args, int from_tty))
{
return func == complete_command;
}
/* ARGSUSED */
static void
show_version (char *args, int from_tty)
{
immediate_quit++;
print_gdb_version (gdb_stdout);
printf_filtered ("\n");
immediate_quit--;
}
/* Handle the quit command. */
void
quit_command (char *args, int from_tty)
{
if (!quit_confirm ())
error ("Not confirmed.");
quit_force (args, from_tty);
}
/* ARGSUSED */
static void
pwd_command (char *args, int from_tty)
{
if (args)
error ("The \"pwd\" command does not take an argument: %s", args);
getcwd (gdb_dirbuf, sizeof (gdb_dirbuf));
if (!STREQ (gdb_dirbuf, current_directory))
printf_unfiltered ("Working directory %s\n (canonically %s).\n",
current_directory, gdb_dirbuf);
else
printf_unfiltered ("Working directory %s.\n", current_directory);
}
void
cd_command (char *dir, int from_tty)
{
int len;
/* Found something other than leading repetitions of "/..". */
int found_real_path;
char *p;
/* If the new directory is absolute, repeat is a no-op; if relative,
repeat might be useful but is more likely to be a mistake. */
dont_repeat ();
if (dir == 0)
error_no_arg ("new working directory");
dir = tilde_expand (dir);
make_cleanup (free, dir);
if (chdir (dir) < 0)
perror_with_name (dir);
#if defined(_WIN32) || defined(__MSDOS__)
/* There's too much mess with DOSish names like "d:", "d:.",
"d:./foo" etc. Instead of having lots of special #ifdef'ed code,
simply get the canonicalized name of the current directory. */
dir = getcwd (gdb_dirbuf, sizeof (gdb_dirbuf));
#endif
len = strlen (dir);
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) /* "/" */
#if defined(_WIN32) || defined(__MSDOS__)
&& !(!SLASH_P (*dir) && ROOTED_P (dir) && len <= 3) /* "d:/" */
#endif
)
len--;
}
dir = savestring (dir, len);
if (ROOTED_P (dir))
current_directory = dir;
else
{
if (SLASH_P (current_directory[strlen (current_directory) - 1]))
current_directory = concat (current_directory, dir, NULL);
else
current_directory = concat (current_directory, SLASH_STRING, dir, NULL);
free (dir);
}
/* Now simplify any occurrences of `.' and `..' in the pathname. */
found_real_path = 0;
for (p = current_directory; *p;)
{
if (SLASH_P (p[0]) && p[1] == '.' && (p[2] == 0 || SLASH_P (p[2])))
strcpy (p, p + 2);
else if (SLASH_P (p[0]) && p[1] == '.' && p[2] == '.'
&& (p[3] == 0 || SLASH_P (p[3])))
{
if (found_real_path)
{
/* Search backwards for the directory just before the "/.."
and obliterate it and the "/..". */
char *q = p;
while (q != current_directory && !SLASH_P (q[-1]))
--q;
if (q == current_directory)
/* current_directory is
a relative pathname ("can't happen"--leave it alone). */
++p;
else
{
strcpy (q - 1, p + 3);
p = q - 1;
}
}
else
/* We are dealing with leading repetitions of "/..", for example
"/../..", which is the Mach super-root. */
p += 3;
}
else
{
found_real_path = 1;
++p;
}
}
forget_cached_source_info ();
if (from_tty)
pwd_command ((char *) 0, 1);
}
void
source_command (char *args, int from_tty)
{
FILE *stream;
struct cleanup *old_cleanups;
char *file = args;
if (file == NULL)
{
error ("source command requires pathname of file to source.");
}
file = tilde_expand (file);
old_cleanups = make_cleanup (free, file);
stream = fopen (file, FOPEN_RT);
if (!stream)
{
if (from_tty)
perror_with_name (file);
else
return;
}
script_from_file (stream, file);
do_cleanups (old_cleanups);
}
/* ARGSUSED */
static void
echo_command (char *text, int from_tty)
{
char *p = text;
register int c;
if (text)
while ((c = *p++) != '\0')
{
if (c == '\\')
{
/* \ at end of argument is used after spaces
so they won't be lost. */
if (*p == 0)
return;
c = parse_escape (&p);
if (c >= 0)
printf_filtered ("%c", c);
}
else
printf_filtered ("%c", c);
}
/* Force this output to appear now. */
wrap_here ("");
gdb_flush (gdb_stdout);
}
/* ARGSUSED */
static void
shell_escape (char *arg, int from_tty)
{
#ifdef CANT_FORK
/* If ARG is NULL, they want an inferior shell, but `system' just
reports if the shell is available when passed a NULL arg. */
int rc = system (arg ? arg : "");
if (!arg)
arg = "inferior shell";
if (rc == -1)
{
fprintf_unfiltered (gdb_stderr, "Cannot execute %s: %s\n", arg,
safe_strerror (errno));
gdb_flush (gdb_stderr);
}
else if (rc)
{
fprintf_unfiltered (gdb_stderr, "%s exited with status %d\n", arg, rc);
gdb_flush (gdb_stderr);
}
#ifdef __DJGPP__
/* Make sure to return to the directory GDB thinks it is, in case the
shell command we just ran changed it. */
chdir (current_directory);
#endif
#else /* Can fork. */
int rc, status, pid;
char *p, *user_shell;
if ((user_shell = (char *) getenv ("SHELL")) == NULL)
user_shell = "/bin/sh";
/* Get the name of the shell for arg0 */
if ((p = strrchr (user_shell, '/')) == NULL)
p = user_shell;
else
p++; /* Get past '/' */
if ((pid = fork ()) == 0)
{
if (!arg)
execl (user_shell, p, 0);
else
execl (user_shell, p, "-c", arg, 0);
fprintf_unfiltered (gdb_stderr, "Cannot execute %s: %s\n", user_shell,
safe_strerror (errno));
gdb_flush (gdb_stderr);
_exit (0177);
}
if (pid != -1)
while ((rc = wait (&status)) != pid && rc != -1)
;
else
error ("Fork failed");
#endif /* Can fork. */
}
static void
make_command (char *arg, int from_tty)
{
char *p;
if (arg == 0)
p = "make";
else
{
p = xmalloc (sizeof ("make ") + strlen (arg));
strcpy (p, "make ");
strcpy (p + sizeof ("make ") - 1, arg);
}
shell_escape (p, from_tty);
}
/* ARGSUSED */
static void
show_user (char *args, int from_tty)
{
struct cmd_list_element *c;
extern struct cmd_list_element *cmdlist;
if (args)
{
c = lookup_cmd (&args, cmdlist, "", 0, 1);
if (c->class != class_user)
error ("Not a user command.");
show_user_1 (c, gdb_stdout);
}
else
{
for (c = cmdlist; c; c = c->next)
{
if (c->class == class_user)
show_user_1 (c, gdb_stdout);
}
}
}
/* Search through names of commands and documentations for a certain
regular expression.
*/
void
apropos_command (char *searchstr, int from_tty)
{
extern struct cmd_list_element *cmdlist; /*This is the main command list*/
regex_t pattern;
char *pattern_fastmap;
char errorbuffer[512];
pattern_fastmap=calloc(256,sizeof(char));
if (searchstr == NULL)
error("REGEXP string is empty");
if (regcomp(&pattern,searchstr,REG_ICASE) == 0)
{
pattern.fastmap=pattern_fastmap;
re_compile_fastmap(&pattern);
apropos_cmd (gdb_stdout,cmdlist,&pattern,"");
}
else
{
regerror(regcomp(&pattern,searchstr,REG_ICASE),NULL,errorbuffer,512);
error("Error in regular expression:%s",errorbuffer);
}
free(pattern_fastmap);
}
static void
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, "");
}
void
init_cmd_lists (void)
{
cmdlist = NULL;
infolist = NULL;
enablelist = NULL;
disablelist = NULL;
togglelist = NULL;
stoplist = NULL;
deletelist = NULL;
enablebreaklist = NULL;
setlist = NULL;
unsetlist = NULL;
showlist = NULL;
sethistlist = NULL;
showhistlist = NULL;
unsethistlist = NULL;
maintenancelist = NULL;
maintenanceinfolist = NULL;
maintenanceprintlist = NULL;
setprintlist = NULL;
showprintlist = NULL;
setchecklist = NULL;
showchecklist = NULL;
}
void
init_cli_cmds (void)
{
struct cmd_list_element *c;
/* Define the classes of commands.
They will appear in the help list in the reverse of this order. */
add_cmd ("internals", class_maintenance, NO_FUNCTION,
"Maintenance commands.\n\
Some gdb commands are provided just for use by gdb maintainers.\n\
These commands are subject to frequent change, and may not be as\n\
well documented as user commands.",
&cmdlist);
add_cmd ("obscure", class_obscure, NO_FUNCTION, "Obscure features.", &cmdlist);
add_cmd ("aliases", class_alias, NO_FUNCTION, "Aliases of other commands.", &cmdlist);
add_cmd ("user-defined", class_user, NO_FUNCTION, "User-defined commands.\n\
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);
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_cmd ("stack", class_stack, NO_FUNCTION, "Examining the stack.\n\
The stack is made up of stack frames. Gdb assigns numbers to stack frames\n\
counting from zero for the innermost (currently executing) frame.\n\n\
At any time gdb identifies one frame as the \"selected\" frame.\n\
Variable lookups are done with respect to the selected frame.\n\
When the program being debugged stops, gdb selects the innermost frame.\n\
The commands below can be used to select other frames by number or address.",
&cmdlist);
add_cmd ("running", class_run, NO_FUNCTION, "Running the program.", &cmdlist);
/* Define general commands. */
add_com ("pwd", class_files, pwd_command,
"Print working directory. This is used for your program as well.");
c = add_cmd ("cd", class_files, cd_command,
"Set working directory to DIR for debugger and program being debugged.\n\
The change does not take effect for the program being debugged\n\
until the next time it is started.", &cmdlist);
c->completer = filename_completer;
add_com ("echo", class_support, echo_command,
"Print a constant string. Give string as argument.\n\
C escape sequences may be used in the argument.\n\
No newline is added at the end of the argument;\n\
use \"\\n\" if you want a newline to be printed.\n\
Since leading and trailing whitespace are ignored in command arguments,\n\
if you want to print some you must use \"\\\" before leading whitespace\n\
to be printed or after trailing whitespace.");
add_com ("document", class_support, document_command,
"Document a user-defined command.\n\
Give command name as argument. Give documentation on following lines.\n\
End with a line of just \"end\".");
add_com ("define", class_support, define_command,
"Define a new command name. Command name is argument.\n\
Definition appears on following lines, one command per line.\n\
End with a line of just \"end\".\n\
Use the \"document\" command to give documentation for the new command.\n\
Commands defined in this way may have up to ten arguments.");
#ifdef __STDC__
c = add_cmd ("source", class_support, source_command,
"Read commands from a file named FILE.\n\
Note that the file \"" GDBINIT_FILENAME "\" is read automatically in this way\n\
when gdb is started.", &cmdlist);
#else
/* Punt file name, we can't help it easily. */
c = add_cmd ("source", class_support, source_command,
"Read commands from a file named FILE.\n\
Note that the file \".gdbinit\" is read automatically in this way\n\
when gdb is started.", &cmdlist);
#endif
c->completer = filename_completer;
add_com ("quit", class_support, quit_command, "Exit gdb.");
add_com ("help", class_support, help_command, "Print list of commands.");
add_com_alias ("q", "quit", class_support, 1);
add_com_alias ("h", "help", class_support, 1);
c = add_set_cmd ("verbose", class_support, var_boolean, (char *) &info_verbose,
"Set ",
&setlist),
add_show_from_set (c, &showlist);
c->function.sfunc = set_verbose;
set_verbose (NULL, 0, c);
add_prefix_cmd ("history", class_support, set_history,
"Generic command for setting command history parameters.",
&sethistlist, "set history ", 0, &setlist);
add_prefix_cmd ("history", class_support, show_history,
"Generic command for showing command history parameters.",
&showhistlist, "show history ", 0, &showlist);
add_show_from_set
(add_set_cmd ("expansion", no_class, var_boolean, (char *) &history_expansion_p,
"Set history expansion on command input.\n\
Without an argument, history expansion is enabled.", &sethistlist),
&showhistlist);
add_prefix_cmd ("info", class_info, info_command,
"Generic command for showing things about the program being debugged.",
&infolist, "info ", 0, &cmdlist);
add_com_alias ("i", "info", class_info, 1);
add_com ("complete", class_obscure, complete_command,
"List the completions for the rest of the line as a command.");
add_prefix_cmd ("show", class_info, show_command,
"Generic command for showing things about the debugger.",
&showlist, "show ", 0, &cmdlist);
/* Another way to get at the same thing. */
add_info ("set", show_command, "Show all GDB settings.");
add_cmd ("commands", no_class, show_commands,
"Show the history of commands you typed.\n\
You can supply a command number to start with, or a `+' to start after\n\
the previous command number shown.",
&showlist);
add_cmd ("version", no_class, show_version,
"Show what version of GDB this is.", &showlist);
add_com ("while", class_support, while_command,
"Execute nested commands WHILE the conditional expression is non zero.\n\
The conditional expression must follow the word `while' and must in turn be\n\
followed by a new line. The nested commands must be entered one per line,\n\
and should be terminated by the word `end'.");
add_com ("if", class_support, if_command,
"Execute nested commands once IF the conditional expression is non zero.\n\
The conditional expression must follow the word `if' and must in turn be\n\
followed by a new line. The nested commands must be entered one per line,\n\
and should be terminated by the word 'else' or `end'. If an else clause\n\
is used, the same rules apply to its nested commands as to the first ones.");
/* If target is open when baud changes, it doesn't take effect until the
next open (I think, not sure). */
add_show_from_set (add_set_cmd ("remotebaud", no_class,
var_zinteger, (char *) &baud_rate,
"Set baud rate for remote serial I/O.\n\
This value is used to set the speed of the serial port when debugging\n\
using remote targets.", &setlist),
&showlist);
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);
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,
"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 the target.", &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);
add_com ("shell", class_support, shell_escape,
"Execute the rest of the line as a shell command. \n\
With no arguments, run an inferior shell.");
/* NOTE: cagney/2000-03-20: Being able to enter ``(gdb) !ls'' would
be a really useful feature. Unfortunately, the below wont do
this. Instead it adds support for the form ``(gdb) ! ls''
(i.e. the space is required). If the ``!'' command below is
added the complains about no ``!'' command would be replaced by
complains about how the ``!'' command is broken :-) */
if (xdb_commands)
add_com_alias ("!", "shell", class_support, 0);
add_com ("make", class_support, make_command,
"Run the ``make'' program using the rest of the line as arguments.");
add_cmd ("user", no_class, show_user,
"Show definitions of user defined commands.\n\
Argument is the name of the user defined command.\n\
With no argument, show definitions of all user defined commands.", &showlist);
add_com ("apropos", class_support, apropos_command, "Search for commands matching a REGEXP");
}

125
gdb/cli/cli-cmds.h Normal file
View File

@ -0,0 +1,125 @@
/* Header file for GDB CLI command implementation library.
Copyright (C) 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#if !defined (CLI_CMDS_H)
#define CLI_CMDS_H 1
/* Chain containing all defined commands. */
extern struct cmd_list_element *cmdlist;
/* Chain containing all defined info subcommands. */
extern struct cmd_list_element *infolist;
/* Chain containing all defined enable subcommands. */
extern struct cmd_list_element *enablelist;
/* Chain containing all defined disable subcommands. */
extern struct cmd_list_element *disablelist;
/* Chain containing all defined delete subcommands. */
extern struct cmd_list_element *deletelist;
/* Chain containing all defined toggle subcommands. */
extern struct cmd_list_element *togglelist;
/* Chain containing all defined stop subcommands. */
extern struct cmd_list_element *stoplist;
/* Chain containing all defined "enable breakpoint" subcommands. */
extern struct cmd_list_element *enablebreaklist;
/* Chain containing all defined set subcommands */
extern struct cmd_list_element *setlist;
/* Chain containing all defined unset subcommands */
extern struct cmd_list_element *unsetlist;
/* Chain containing all defined show subcommands. */
extern struct cmd_list_element *showlist;
/* Chain containing all defined \"set history\". */
extern struct cmd_list_element *sethistlist;
/* Chain containing all defined \"show history\". */
extern struct cmd_list_element *showhistlist;
/* Chain containing all defined \"unset history\". */
extern struct cmd_list_element *unsethistlist;
/* Chain containing all defined maintenance subcommands. */
extern struct cmd_list_element *maintenancelist;
/* Chain containing all defined "maintenance info" subcommands. */
extern struct cmd_list_element *maintenanceinfolist;
/* Chain containing all defined "maintenance print" subcommands. */
extern struct cmd_list_element *maintenanceprintlist;
extern struct cmd_list_element *setprintlist;
extern struct cmd_list_element *showprintlist;
extern struct cmd_list_element *setdebuglist;
extern struct cmd_list_element *showdebuglist;
extern struct cmd_list_element *setchecklist;
extern struct cmd_list_element *showchecklist;
/* Exported to gdb/top.c */
void init_cmd_lists (void);
void init_cli_cmds (void);
int is_complete_command (void (*func) (char *args, int from_tty));
/* Exported to gdb/main.c */
extern void cd_command (char *, int);
/* Exported to gdb/top.c and gdb/main.c */
extern void quit_command (char *, int);
extern void source_command (char *, int);
/* Used everywhere whenever at least one parameter is required and
none is specified. */
extern NORETURN void error_no_arg (char *) ATTR_NORETURN;
#endif /* !defined (CLI_CMDS_H) */

View File

@ -17,52 +17,29 @@
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "gdbcmd.h"
#include "symtab.h"
#include "value.h"
#include <ctype.h>
#include "gdb_string.h"
#include "gnu-regex.h"
#ifdef UI_OUT
#include "ui-out.h"
#endif
#include "gdb_wait.h"
#include "gnu-regex.h"
/* FIXME: this should be auto-configured! */
#ifdef __MSDOS__
# define CANT_FORK
#endif
#include "cli/cli-cmds.h"
#include "cli/cli-decode.h"
/* Prototypes for local functions */
static void undef_cmd_error (char *, char *);
static void show_user (char *, int);
static void show_user_1 (struct cmd_list_element *, struct ui_file *);
static void make_command (char *, int);
static void shell_escape (char *, int);
static int parse_binary_operation (char *);
static void print_doc_line (struct ui_file *, char *);
static struct cmd_list_element *find_cmd (char *command,
int len,
struct cmd_list_element *clist,
int ignore_help_classes,
int *nfound);
static void apropos_cmd_helper (struct ui_file *, struct cmd_list_element *,
struct re_pattern_buffer *, char *);
static void help_all (struct ui_file *stream);
void apropos_command (char *, int);
void _initialize_command (void);
/* Add element named NAME.
CLASS is the top level category into which commands are broken down
for "help" purposes.
@ -396,12 +373,49 @@ delete_cmd (char *name, struct cmd_list_element **list)
c = c->next;
}
}
/* Shorthands to the commands above. */
/* Add an element to the list of info subcommands. */
struct cmd_list_element *
add_info (char *name, void (*fun) (char *, int), char *doc)
{
return add_cmd (name, no_class, fun, doc, &infolist);
}
/* Add an alias to the list of info subcommands. */
struct cmd_list_element *
add_info_alias (char *name, char *oldname, int abbrev_flag)
{
return add_alias_cmd (name, oldname, 0, abbrev_flag, &infolist);
}
/* Add an element to the list of commands. */
struct cmd_list_element *
add_com (char *name, enum command_class class, void (*fun) (char *, int),
char *doc)
{
return add_cmd (name, class, fun, doc, &cmdlist);
}
/* Add an alias or abbreviation command to the list of commands. */
struct cmd_list_element *
add_com_alias (char *name, char *oldname, enum command_class class,
int abbrev_flag)
{
return add_alias_cmd (name, oldname, class, abbrev_flag, &cmdlist);
}
/* Recursively walk the commandlist structures, and print out the
documentation of commands that match our regex in either their
name, or their documentation.
*/
static void
apropos_cmd_helper (struct ui_file *stream, struct cmd_list_element *commandlist,
void
apropos_cmd (struct ui_file *stream, struct cmd_list_element *commandlist,
struct re_pattern_buffer *regex, char *prefix)
{
register struct cmd_list_element *c;
@ -445,38 +459,10 @@ apropos_cmd_helper (struct ui_file *stream, struct cmd_list_element *commandlist
/* Recursively call ourselves on the subcommand list,
passing the right prefix in.
*/
apropos_cmd_helper(stream,*c->prefixlist,regex,c->prefixname);
apropos_cmd (stream,*c->prefixlist,regex,c->prefixname);
}
}
}
/* Search through names of commands and documentations for a certain
regular expression.
*/
void
apropos_command (char *searchstr, int from_tty)
{
extern struct cmd_list_element *cmdlist; /*This is the main command list*/
regex_t pattern;
char *pattern_fastmap;
char errorbuffer[512];
pattern_fastmap=calloc(256,sizeof(char));
if (searchstr == NULL)
error("REGEXP string is empty");
if (regcomp(&pattern,searchstr,REG_ICASE) == 0)
{
pattern.fastmap=pattern_fastmap;
re_compile_fastmap(&pattern);
apropos_cmd_helper(gdb_stdout,cmdlist,&pattern,"");
}
else
{
regerror(regcomp(&pattern,searchstr,REG_ICASE),NULL,errorbuffer,512);
error("Error in regular expression:%s",errorbuffer);
}
free(pattern_fastmap);
}
/* This command really has to deal with two things:
* 1) I want documentation on *this string* (usually called by
@ -626,7 +612,7 @@ help_all (struct ui_file *stream)
}
/* Print only the first line of STR on STREAM. */
static void
void
print_doc_line (struct ui_file *stream, char *str)
{
static char *line_buffer = 0;
@ -1504,577 +1490,3 @@ complete_on_enum (const char *enumlist[],
return matchlist;
}
static enum cmd_auto_boolean
parse_auto_binary_operation (const char *arg)
{
if (arg != NULL && *arg != '\0')
{
int length = strlen (arg);
while (isspace (arg[length - 1]) && length > 0)
length--;
if (strncmp (arg, "on", length) == 0
|| strncmp (arg, "1", length) == 0
|| strncmp (arg, "yes", length) == 0
|| strncmp (arg, "enable", length) == 0)
return CMD_AUTO_BOOLEAN_TRUE;
else if (strncmp (arg, "off", length) == 0
|| strncmp (arg, "0", length) == 0
|| strncmp (arg, "no", length) == 0
|| strncmp (arg, "disable", length) == 0)
return CMD_AUTO_BOOLEAN_FALSE;
else if (strncmp (arg, "auto", length) == 0
|| (strncmp (arg, "-1", length) == 0 && length > 1))
return CMD_AUTO_BOOLEAN_AUTO;
}
error ("\"on\", \"off\" or \"auto\" expected.");
return CMD_AUTO_BOOLEAN_AUTO; /* pacify GCC */
}
static int
parse_binary_operation (char *arg)
{
int length;
if (!arg || !*arg)
return 1;
length = strlen (arg);
while (arg[length - 1] == ' ' || arg[length - 1] == '\t')
length--;
if (strncmp (arg, "on", length) == 0
|| strncmp (arg, "1", length) == 0
|| strncmp (arg, "yes", length) == 0
|| strncmp (arg, "enable", length) == 0)
return 1;
else if (strncmp (arg, "off", length) == 0
|| strncmp (arg, "0", length) == 0
|| strncmp (arg, "no", length) == 0
|| strncmp (arg, "disable", length) == 0)
return 0;
else
{
error ("\"on\" or \"off\" expected.");
return 0;
}
}
/* Do a "set" or "show" command. ARG is NULL if no argument, or the text
of the argument, and FROM_TTY is nonzero if this command is being entered
directly by the user (i.e. these are just like any other
command). C is the command list element for the command. */
void
do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c)
{
if (c->type == set_cmd)
{
switch (c->var_type)
{
case var_string:
{
char *new;
char *p;
char *q;
int ch;
if (arg == NULL)
arg = "";
new = (char *) xmalloc (strlen (arg) + 2);
p = arg;
q = new;
while ((ch = *p++) != '\000')
{
if (ch == '\\')
{
/* \ at end of argument is used after spaces
so they won't be lost. */
/* This is obsolete now that we no longer strip
trailing whitespace and actually, the backslash
didn't get here in my test, readline or
something did something funky with a backslash
right before a newline. */
if (*p == 0)
break;
ch = parse_escape (&p);
if (ch == 0)
break; /* C loses */
else if (ch > 0)
*q++ = ch;
}
else
*q++ = ch;
}
#if 0
if (*(p - 1) != '\\')
*q++ = ' ';
#endif
*q++ = '\0';
new = (char *) xrealloc (new, q - new);
if (*(char **) c->var != NULL)
free (*(char **) c->var);
*(char **) c->var = new;
}
break;
case var_string_noescape:
if (arg == NULL)
arg = "";
if (*(char **) c->var != NULL)
free (*(char **) c->var);
*(char **) c->var = savestring (arg, strlen (arg));
break;
case var_filename:
if (arg == NULL)
error_no_arg ("filename to set it to.");
if (*(char **) c->var != NULL)
free (*(char **) c->var);
*(char **) c->var = tilde_expand (arg);
break;
case var_boolean:
*(int *) c->var = parse_binary_operation (arg);
break;
case var_auto_boolean:
*(enum cmd_auto_boolean *) c->var = parse_auto_binary_operation (arg);
break;
case var_uinteger:
if (arg == NULL)
error_no_arg ("integer to set it to.");
*(unsigned int *) c->var = parse_and_eval_long (arg);
if (*(unsigned int *) c->var == 0)
*(unsigned int *) c->var = UINT_MAX;
break;
case var_integer:
{
unsigned int val;
if (arg == NULL)
error_no_arg ("integer to set it to.");
val = parse_and_eval_long (arg);
if (val == 0)
*(int *) c->var = INT_MAX;
else if (val >= INT_MAX)
error ("integer %u out of range", val);
else
*(int *) c->var = val;
break;
}
case var_zinteger:
if (arg == NULL)
error_no_arg ("integer to set it to.");
*(int *) c->var = parse_and_eval_long (arg);
break;
case var_enum:
{
int i;
int len;
int nmatches;
const char *match = NULL;
char *p;
/* if no argument was supplied, print an informative error message */
if (arg == NULL)
{
char msg[1024];
strcpy (msg, "Requires an argument. Valid arguments are ");
for (i = 0; c->enums[i]; i++)
{
if (i != 0)
strcat (msg, ", ");
strcat (msg, c->enums[i]);
}
strcat (msg, ".");
error (msg);
}
p = strchr (arg, ' ');
if (p)
len = p - arg;
else
len = strlen (arg);
nmatches = 0;
for (i = 0; c->enums[i]; i++)
if (strncmp (arg, c->enums[i], len) == 0)
{
if (c->enums[i][len] == '\0')
{
match = c->enums[i];
nmatches = 1;
break; /* exact match. */
}
else
{
match = c->enums[i];
nmatches++;
}
}
if (nmatches <= 0)
error ("Undefined item: \"%s\".", arg);
if (nmatches > 1)
error ("Ambiguous item \"%s\".", arg);
*(const char **) c->var = match;
}
break;
default:
error ("gdb internal error: bad var_type in do_setshow_command");
}
}
else if (c->type == show_cmd)
{
#ifdef UI_OUT
struct cleanup *old_chain;
struct ui_stream *stb;
int quote;
stb = ui_out_stream_new (uiout);
old_chain = make_cleanup_ui_out_stream_delete (stb);
#endif /* UI_OUT */
/* Print doc minus "show" at start. */
print_doc_line (gdb_stdout, c->doc + 5);
#ifdef UI_OUT
ui_out_text (uiout, " is ");
ui_out_wrap_hint (uiout, " ");
quote = 0;
switch (c->var_type)
{
case var_string:
{
unsigned char *p;
if (*(unsigned char **) c->var)
fputstr_filtered (*(unsigned char **) c->var, '"', stb->stream);
quote = 1;
}
break;
case var_string_noescape:
case var_filename:
case var_enum:
if (*(char **) c->var)
fputs_filtered (*(char **) c->var, stb->stream);
quote = 1;
break;
case var_boolean:
fputs_filtered (*(int *) c->var ? "on" : "off", stb->stream);
break;
case var_auto_boolean:
switch (*(enum cmd_auto_boolean*) c->var)
{
case CMD_AUTO_BOOLEAN_TRUE:
fputs_filtered ("on", stb->stream);
break;
case CMD_AUTO_BOOLEAN_FALSE:
fputs_filtered ("off", stb->stream);
break;
case CMD_AUTO_BOOLEAN_AUTO:
fputs_filtered ("auto", stb->stream);
break;
default:
internal_error ("do_setshow_command: invalid var_auto_boolean");
break;
}
break;
case var_uinteger:
if (*(unsigned int *) c->var == UINT_MAX)
{
fputs_filtered ("unlimited", stb->stream);
break;
}
/* else fall through */
case var_zinteger:
fprintf_filtered (stb->stream, "%u", *(unsigned int *) c->var);
break;
case var_integer:
if (*(int *) c->var == INT_MAX)
{
fputs_filtered ("unlimited", stb->stream);
}
else
fprintf_filtered (stb->stream, "%d", *(int *) c->var);
break;
default:
error ("gdb internal error: bad var_type in do_setshow_command");
}
if (quote)
ui_out_text (uiout, "\"");
ui_out_field_stream (uiout, "value", stb);
if (quote)
ui_out_text (uiout, "\"");
ui_out_text (uiout, ".\n");
do_cleanups (old_chain);
#else
fputs_filtered (" is ", gdb_stdout);
wrap_here (" ");
switch (c->var_type)
{
case var_string:
{
fputs_filtered ("\"", gdb_stdout);
if (*(unsigned char **) c->var)
fputstr_filtered (*(unsigned char **) c->var, '"', gdb_stdout);
fputs_filtered ("\"", gdb_stdout);
}
break;
case var_string_noescape:
case var_filename:
case var_enum:
fputs_filtered ("\"", gdb_stdout);
if (*(char **) c->var)
fputs_filtered (*(char **) c->var, gdb_stdout);
fputs_filtered ("\"", gdb_stdout);
break;
case var_boolean:
fputs_filtered (*(int *) c->var ? "on" : "off", gdb_stdout);
break;
case var_auto_boolean:
switch (*(enum cmd_auto_boolean*) c->var)
{
case CMD_AUTO_BOOLEAN_TRUE:
fputs_filtered ("on", gdb_stdout);
break;
case CMD_AUTO_BOOLEAN_FALSE:
fputs_filtered ("off", gdb_stdout);
break;
case CMD_AUTO_BOOLEAN_AUTO:
fputs_filtered ("auto", gdb_stdout);
break;
default:
internal_error ("do_setshow_command: invalid var_auto_boolean");
break;
}
break;
case var_uinteger:
if (*(unsigned int *) c->var == UINT_MAX)
{
fputs_filtered ("unlimited", gdb_stdout);
break;
}
/* else fall through */
case var_zinteger:
fprintf_filtered (gdb_stdout, "%u", *(unsigned int *) c->var);
break;
case var_integer:
if (*(int *) c->var == INT_MAX)
{
fputs_filtered ("unlimited", gdb_stdout);
}
else
fprintf_filtered (gdb_stdout, "%d", *(int *) c->var);
break;
default:
error ("gdb internal error: bad var_type in do_setshow_command");
}
fputs_filtered (".\n", gdb_stdout);
#endif
}
else
error ("gdb internal error: bad cmd_type in do_setshow_command");
(*c->function.sfunc) (NULL, from_tty, c);
if (c->type == set_cmd && set_hook)
set_hook (c);
}
/* Show all the settings in a list of show commands. */
void
cmd_show_list (struct cmd_list_element *list, int from_tty, char *prefix)
{
#ifdef UI_OUT
ui_out_list_begin (uiout, "showlist");
#endif
for (; list != NULL; list = list->next)
{
/* If we find a prefix, run its list, prefixing our output by its
prefix (with "show " skipped). */
#ifdef UI_OUT
if (list->prefixlist && !list->abbrev_flag)
{
ui_out_list_begin (uiout, "optionlist");
ui_out_field_string (uiout, "prefix", list->prefixname + 5);
cmd_show_list (*list->prefixlist, from_tty, list->prefixname + 5);
ui_out_list_end (uiout);
}
if (list->type == show_cmd)
{
ui_out_list_begin (uiout, "option");
ui_out_text (uiout, prefix);
ui_out_field_string (uiout, "name", list->name);
ui_out_text (uiout, ": ");
do_setshow_command ((char *) NULL, from_tty, list);
ui_out_list_end (uiout);
}
#else
if (list->prefixlist && !list->abbrev_flag)
cmd_show_list (*list->prefixlist, from_tty, list->prefixname + 5);
if (list->type == show_cmd)
{
fputs_filtered (prefix, gdb_stdout);
fputs_filtered (list->name, gdb_stdout);
fputs_filtered (": ", gdb_stdout);
do_setshow_command ((char *) NULL, from_tty, list);
}
#endif
}
#ifdef UI_OUT
ui_out_list_end (uiout);
#endif
}
/* ARGSUSED */
static void
shell_escape (char *arg, int from_tty)
{
#ifdef CANT_FORK
/* If ARG is NULL, they want an inferior shell, but `system' just
reports if the shell is available when passed a NULL arg. */
int rc = system (arg ? arg : "");
if (!arg)
arg = "inferior shell";
if (rc == -1)
{
fprintf_unfiltered (gdb_stderr, "Cannot execute %s: %s\n", arg,
safe_strerror (errno));
gdb_flush (gdb_stderr);
}
else if (rc)
{
fprintf_unfiltered (gdb_stderr, "%s exited with status %d\n", arg, rc);
gdb_flush (gdb_stderr);
}
#ifdef __DJGPP__
/* Make sure to return to the directory GDB thinks it is, in case the
shell command we just ran changed it. */
chdir (current_directory);
#endif
#else /* Can fork. */
int rc, status, pid;
char *p, *user_shell;
if ((user_shell = (char *) getenv ("SHELL")) == NULL)
user_shell = "/bin/sh";
/* Get the name of the shell for arg0 */
if ((p = strrchr (user_shell, '/')) == NULL)
p = user_shell;
else
p++; /* Get past '/' */
if ((pid = fork ()) == 0)
{
if (!arg)
execl (user_shell, p, 0);
else
execl (user_shell, p, "-c", arg, 0);
fprintf_unfiltered (gdb_stderr, "Cannot execute %s: %s\n", user_shell,
safe_strerror (errno));
gdb_flush (gdb_stderr);
_exit (0177);
}
if (pid != -1)
while ((rc = wait (&status)) != pid && rc != -1)
;
else
error ("Fork failed");
#endif /* Can fork. */
}
static void
make_command (char *arg, int from_tty)
{
char *p;
if (arg == 0)
p = "make";
else
{
p = xmalloc (sizeof ("make ") + strlen (arg));
strcpy (p, "make ");
strcpy (p + sizeof ("make ") - 1, arg);
}
shell_escape (p, from_tty);
}
static void
show_user_1 (struct cmd_list_element *c, struct ui_file *stream)
{
register struct command_line *cmdlines;
cmdlines = c->user_commands;
if (!cmdlines)
return;
fputs_filtered ("User command ", stream);
fputs_filtered (c->name, stream);
fputs_filtered (":\n", stream);
#ifdef UI_OUT
print_command_lines (uiout, cmdlines, 1);
fputs_filtered ("\n", stream);
#else
while (cmdlines)
{
print_command_line (cmdlines, 4, stream);
cmdlines = cmdlines->next;
}
fputs_filtered ("\n", stream);
#endif
}
/* ARGSUSED */
static void
show_user (char *args, int from_tty)
{
struct cmd_list_element *c;
extern struct cmd_list_element *cmdlist;
if (args)
{
c = lookup_cmd (&args, cmdlist, "", 0, 1);
if (c->class != class_user)
error ("Not a user command.");
show_user_1 (c, gdb_stdout);
}
else
{
for (c = cmdlist; c; c = c->next)
{
if (c->class == class_user)
show_user_1 (c, gdb_stdout);
}
}
}
void
_initialize_command (void)
{
add_com ("shell", class_support, shell_escape,
"Execute the rest of the line as a shell command. \n\
With no arguments, run an inferior shell.");
/* NOTE: cagney/2000-03-20: Being able to enter ``(gdb) !ls'' would
be a really useful feature. Unfortunately, the below wont do
this. Instead it adds support for the form ``(gdb) ! ls''
(i.e. the space is required). If the ``!'' command below is
added the complains about no ``!'' command would be replaced by
complains about how the ``!'' command is broken :-) */
if (xdb_commands)
add_com_alias ("!", "shell", class_support, 0);
add_com ("make", class_support, make_command,
"Run the ``make'' program using the rest of the line as arguments.");
add_cmd ("user", no_class, show_user,
"Show definitions of user defined commands.\n\
Argument is the name of the user defined command.\n\
With no argument, show definitions of all user defined commands.", &showlist);
add_com ("apropos", class_support, apropos_command, "Search for commands matching a REGEXP");
}

357
gdb/cli/cli-decode.h Normal file
View File

@ -0,0 +1,357 @@
/* Header file for GDB command decoding library.
Copyright (C) 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#if !defined (CLI_DECODE_H)
#define CLI_DECODE_H 1
#include "gnu-regex.h" /* Needed by apropos_cmd. */
/* Command classes are top-level categories into which commands are broken
down for "help" purposes.
Notes on classes: class_alias is for alias commands which are not
abbreviations of the original command. class-pseudo is for
commands which are not really commands nor help topics ("stop"). */
enum command_class
{
/* Special args to help_list */
class_deprecated, all_classes = -2, all_commands = -1,
/* Classes of commands */
no_class = -1, class_run = 0, class_vars, class_stack,
class_files, class_support, class_info, class_breakpoint, class_trace,
class_alias, class_obscure, class_user, class_maintenance,
class_pseudo, class_tui, class_xdb
};
/* Not a set/show command. Note that some commands which begin with
"set" or "show" might be in this category, if their syntax does
not fall into one of the following categories. */
typedef enum cmd_types
{
not_set_cmd,
set_cmd,
show_cmd
}
cmd_types;
/* Reasonable values for an AUTO_BOOLEAN variable. */
enum cmd_auto_boolean
{
CMD_AUTO_BOOLEAN_TRUE,
CMD_AUTO_BOOLEAN_FALSE,
CMD_AUTO_BOOLEAN_AUTO
};
/* Types of "set" or "show" command. */
typedef enum var_types
{
/* "on" or "off". *VAR is an integer which is nonzero for on,
zero for off. */
var_boolean,
/* "on" / "true" / "enable" or "off" / "false" / "disable" or
"auto. *VAR is an ``enum cmd_auto_boolean''. NOTE: In general
a custom show command will need to be implemented - one that
for "auto" prints both the "auto" and the current auto-selected
value. */
var_auto_boolean,
/* Unsigned Integer. *VAR is an unsigned int. The user can type 0
to mean "unlimited", which is stored in *VAR as UINT_MAX. */
var_uinteger,
/* Like var_uinteger but signed. *VAR is an int. The user can type 0
to mean "unlimited", which is stored in *VAR as INT_MAX. */
var_integer,
/* String which the user enters with escapes (e.g. the user types \n and
it is a real newline in the stored string).
*VAR is a malloc'd string, or NULL if the string is empty. */
var_string,
/* String which stores what the user types verbatim.
*VAR is a malloc'd string, or NULL if the string is empty. */
var_string_noescape,
/* String which stores a filename.
*VAR is a malloc'd string, or NULL if the string is empty. */
var_filename,
/* ZeroableInteger. *VAR is an int. Like Unsigned Integer except
that zero really means zero. */
var_zinteger,
/* Enumerated type. Can only have one of the specified values. *VAR is a
char pointer to the name of the element that we find. */
var_enum
}
var_types;
/* This structure records one command'd definition. */
/* This flag is used by the code executing commands to warn the user
the first time a deprecated command is used, see the 'flags' field in
the following struct.
*/
#define CMD_DEPRECATED 0x1
#define DEPRECATED_WARN_USER 0x2
#define MALLOCED_REPLACEMENT 0x4
struct cmd_list_element
{
/* Points to next command in this list. */
struct cmd_list_element *next;
/* Name of this command. */
char *name;
/* Command class; class values are chosen by application program. */
enum command_class class;
/* Function definition of this command.
NO_FUNCTION for command class names and for help topics that
are not really commands. */
union
{
/* If type is not_set_cmd, call it like this: */
void (*cfunc) (char *args, int from_tty);
/* If type is cmd_set or show_cmd, first set the variables, and
then call this. */
void (*sfunc) (char *args, int from_tty, struct cmd_list_element * c);
}
function;
#define NO_FUNCTION ((void (*) (char *args, int from_tty)) 0)
/* Documentation of this command (or help topic).
First line is brief documentation; remaining lines form, with it,
the full documentation. First line should end with a period.
Entire string should also end with a period, not a newline. */
char *doc;
/* flags : a bitfield
bit 0: (LSB) CMD_DEPRECATED, when 1 indicated that this command
is deprecated. It may be removed from gdb's command set in the
future.
bit 1: DEPRECATED_WARN_USER, the user needs to be warned that
this is a deprecated command. The user should only be warned
the first time a command is used.
bit 2: MALLOCED_REPLACEMENT, when functions are deprecated at
compile time (this is the way it should, in general, be done)
the memory containing the replacement string is statically
allocated. In some cases it makes sense to deprecate commands
at runtime (the testsuite is one example). In this case the
memory for replacement is malloc'ed. When a command is
undeprecated or re-deprecated at runtime we don't want to risk
calling free on statically allocated memory, so we check this
flag.
*/
int flags;
/* if this command is deprecated, this is the replacement name */
char *replacement;
/* Hook for another command to be executed before this command. */
struct cmd_list_element *hook_pre;
/* Hook for another command to be executed after this command. */
struct cmd_list_element *hook_post;
/* Flag that specifies if this command is already running it's hook. */
/* Prevents the possibility of hook recursion. */
int hook_in;
/* Nonzero identifies a prefix command. For them, the address
of the variable containing the list of subcommands. */
struct cmd_list_element **prefixlist;
/* For prefix commands only:
String containing prefix commands to get here: this one
plus any others needed to get to it. Should end in a space.
It is used before the word "command" in describing the
commands reached through this prefix. */
char *prefixname;
/* For prefix commands only:
nonzero means do not get an error if subcommand is not
recognized; call the prefix's own function in that case. */
char allow_unknown;
/* Nonzero says this is an abbreviation, and should not
be mentioned in lists of commands.
This allows "br<tab>" to complete to "break", which it
otherwise wouldn't. */
char abbrev_flag;
/* Completion routine for this command. TEXT is the text beyond
what was matched for the command itself (leading whitespace is
skipped). It stops where we are supposed to stop completing
(rl_point) and is '\0' terminated.
Return value is a malloc'd vector of pointers to possible completions
terminated with NULL. If there are no completions, returning a pointer
to a NULL would work but returning NULL itself is also valid.
WORD points in the same buffer as TEXT, and completions should be
returned relative to this position. For example, suppose TEXT is "foo"
and we want to complete to "foobar". If WORD is "oo", return
"oobar"; if WORD is "baz/foo", return "baz/foobar". */
char **(*completer) (char *text, char *word);
/* Type of "set" or "show" command (or SET_NOT_SET if not "set"
or "show"). */
cmd_types type;
/* Pointer to variable affected by "set" and "show". Doesn't matter
if type is not_set. */
void *var;
/* What kind of variable is *VAR? */
var_types var_type;
/* Pointer to NULL terminated list of enumerated values (like argv). */
const char **enums;
/* Pointer to command strings of user-defined commands */
struct command_line *user_commands;
/* Pointer to command that is hooked by this one, (by hook_pre)
so the hook can be removed when this one is deleted. */
struct cmd_list_element *hookee_pre;
/* Pointer to command that is hooked by this one, (by hook_post)
so the hook can be removed when this one is deleted. */
struct cmd_list_element *hookee_post;
/* Pointer to command that is aliased by this one, so the
aliased command can be located in case it has been hooked. */
struct cmd_list_element *cmd_pointer;
};
/* API to the manipulation of command lists. */
extern struct cmd_list_element *add_cmd (char *, enum command_class,
void (*fun) (char *, int), char *,
struct cmd_list_element **);
extern struct cmd_list_element *add_alias_cmd (char *, char *,
enum command_class, int,
struct cmd_list_element **);
extern struct cmd_list_element *add_prefix_cmd (char *, enum command_class,
void (*fun) (char *, int),
char *,
struct cmd_list_element **,
char *, int,
struct cmd_list_element **);
extern struct cmd_list_element *add_abbrev_prefix_cmd (char *,
enum command_class,
void (*fun) (char *,
int),
char *,
struct cmd_list_element
**, char *, int,
struct cmd_list_element
**);
extern struct cmd_list_element *lookup_cmd (char **,
struct cmd_list_element *, char *,
int, int);
extern struct cmd_list_element *lookup_cmd_1 (char **,
struct cmd_list_element *,
struct cmd_list_element **,
int);
extern struct cmd_list_element *
deprecate_cmd (struct cmd_list_element *, char * );
extern void
deprecated_cmd_warning (char **);
extern int
lookup_cmd_composition (char *text,
struct cmd_list_element **alias,
struct cmd_list_element **prefix_cmd,
struct cmd_list_element **cmd);
extern struct cmd_list_element *add_com (char *, enum command_class,
void (*fun) (char *, int), char *);
extern struct cmd_list_element *add_com_alias (char *, char *,
enum command_class, int);
extern struct cmd_list_element *add_info (char *, void (*fun) (char *, int),
char *);
extern struct cmd_list_element *add_info_alias (char *, char *, int);
extern char **complete_on_cmdlist (struct cmd_list_element *, char *, char *);
extern char **complete_on_enum (const char *enumlist[], char *, char *);
extern void delete_cmd (char *, struct cmd_list_element **);
extern void help_cmd_list (struct cmd_list_element *, enum command_class,
char *, int, struct ui_file *);
extern struct cmd_list_element *add_set_cmd (char *name, enum
command_class class,
var_types var_type, void *var,
char *doc,
struct cmd_list_element **list);
extern struct cmd_list_element *add_set_enum_cmd (char *name,
enum command_class class,
const char *enumlist[],
const char **var,
char *doc,
struct cmd_list_element **list);
extern struct cmd_list_element *add_set_auto_boolean_cmd (char *name,
enum command_class class,
enum cmd_auto_boolean *var,
char *doc,
struct cmd_list_element **list);
extern struct cmd_list_element *add_show_from_set (struct cmd_list_element *,
struct cmd_list_element
**);
/* Functions that implement commands about CLI commands. */
extern void help_cmd (char *, struct ui_file *);
extern void help_list (struct cmd_list_element *, char *,
enum command_class, struct ui_file *);
extern void apropos_cmd (struct ui_file *, struct cmd_list_element *,
struct re_pattern_buffer *, char *);
/* Used to mark commands that don't do anything. If we just leave the
function field NULL, the command is interpreted as a help topic, or
as a class of commands. */
extern void not_just_help_class_command (char *arg, int from_tty);
/* Exported to cli/cli-setshow.c */
extern void print_doc_line (struct ui_file *, char *);
#endif /* !defined (CLI_DECODE_H) */

1315
gdb/cli/cli-script.c Normal file

File diff suppressed because it is too large Load Diff

50
gdb/cli/cli-script.h Normal file
View File

@ -0,0 +1,50 @@
/* Header file for GDB CLI command implementation library.
Copyright (C) 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#if !defined (CLI_SCRIPT_H)
#define CLI_SCRIPT_H 1
/* Exported to cli/cli-cmds.c */
extern void script_from_file (FILE *stream, char *file);
extern void document_command (char *, int);
extern void define_command (char *, int);
extern void while_command (char *arg, int from_tty);
extern void if_command (char *arg, int from_tty);
extern void show_user_1 (struct cmd_list_element *c, struct ui_file *stream);
/* Exported to gdb/breakpoint.c */
extern enum command_control_type
execute_control_command (struct command_line *cmd);
#ifdef UI_OUT
extern void print_command_lines (struct ui_out *,
struct command_line *, unsigned int);
#endif
/* Exported to gdb/infrun.c */
extern void execute_user_command (struct cmd_list_element *c, char *args);
#endif /* !defined (CLI_SCRIPT_H) */

462
gdb/cli/cli-setshow.c Normal file
View File

@ -0,0 +1,462 @@
/* Handle set and show GDB commands.
Copyright 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "value.h"
#include <ctype.h>
#if 0
#include "gdb_string.h"
#endif
#ifdef UI_OUT
#include "ui-out.h"
#endif
#include "cli/cli-decode.h"
#include "cli/cli-cmds.h"
#include "cli/cli-setshow.h"
/* Prototypes for local functions */
static int parse_binary_operation (char *);
static enum cmd_auto_boolean parse_auto_binary_operation (const char *arg);
static enum cmd_auto_boolean
parse_auto_binary_operation (const char *arg)
{
if (arg != NULL && *arg != '\0')
{
int length = strlen (arg);
while (isspace (arg[length - 1]) && length > 0)
length--;
if (strncmp (arg, "on", length) == 0
|| strncmp (arg, "1", length) == 0
|| strncmp (arg, "yes", length) == 0
|| strncmp (arg, "enable", length) == 0)
return CMD_AUTO_BOOLEAN_TRUE;
else if (strncmp (arg, "off", length) == 0
|| strncmp (arg, "0", length) == 0
|| strncmp (arg, "no", length) == 0
|| strncmp (arg, "disable", length) == 0)
return CMD_AUTO_BOOLEAN_FALSE;
else if (strncmp (arg, "auto", length) == 0
|| (strncmp (arg, "-1", length) == 0 && length > 1))
return CMD_AUTO_BOOLEAN_AUTO;
}
error ("\"on\", \"off\" or \"auto\" expected.");
return CMD_AUTO_BOOLEAN_AUTO; /* pacify GCC */
}
static int
parse_binary_operation (char *arg)
{
int length;
if (!arg || !*arg)
return 1;
length = strlen (arg);
while (arg[length - 1] == ' ' || arg[length - 1] == '\t')
length--;
if (strncmp (arg, "on", length) == 0
|| strncmp (arg, "1", length) == 0
|| strncmp (arg, "yes", length) == 0
|| strncmp (arg, "enable", length) == 0)
return 1;
else if (strncmp (arg, "off", length) == 0
|| strncmp (arg, "0", length) == 0
|| strncmp (arg, "no", length) == 0
|| strncmp (arg, "disable", length) == 0)
return 0;
else
{
error ("\"on\" or \"off\" expected.");
return 0;
}
}
/* Do a "set" or "show" command. ARG is NULL if no argument, or the text
of the argument, and FROM_TTY is nonzero if this command is being entered
directly by the user (i.e. these are just like any other
command). C is the command list element for the command. */
void
do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c)
{
if (c->type == set_cmd)
{
switch (c->var_type)
{
case var_string:
{
char *new;
char *p;
char *q;
int ch;
if (arg == NULL)
arg = "";
new = (char *) xmalloc (strlen (arg) + 2);
p = arg;
q = new;
while ((ch = *p++) != '\000')
{
if (ch == '\\')
{
/* \ at end of argument is used after spaces
so they won't be lost. */
/* This is obsolete now that we no longer strip
trailing whitespace and actually, the backslash
didn't get here in my test, readline or
something did something funky with a backslash
right before a newline. */
if (*p == 0)
break;
ch = parse_escape (&p);
if (ch == 0)
break; /* C loses */
else if (ch > 0)
*q++ = ch;
}
else
*q++ = ch;
}
#if 0
if (*(p - 1) != '\\')
*q++ = ' ';
#endif
*q++ = '\0';
new = (char *) xrealloc (new, q - new);
if (*(char **) c->var != NULL)
free (*(char **) c->var);
*(char **) c->var = new;
}
break;
case var_string_noescape:
if (arg == NULL)
arg = "";
if (*(char **) c->var != NULL)
free (*(char **) c->var);
*(char **) c->var = savestring (arg, strlen (arg));
break;
case var_filename:
if (arg == NULL)
error_no_arg ("filename to set it to.");
if (*(char **) c->var != NULL)
free (*(char **) c->var);
*(char **) c->var = tilde_expand (arg);
break;
case var_boolean:
*(int *) c->var = parse_binary_operation (arg);
break;
case var_auto_boolean:
*(enum cmd_auto_boolean *) c->var = parse_auto_binary_operation (arg);
break;
case var_uinteger:
if (arg == NULL)
error_no_arg ("integer to set it to.");
*(unsigned int *) c->var = parse_and_eval_long (arg);
if (*(unsigned int *) c->var == 0)
*(unsigned int *) c->var = UINT_MAX;
break;
case var_integer:
{
unsigned int val;
if (arg == NULL)
error_no_arg ("integer to set it to.");
val = parse_and_eval_long (arg);
if (val == 0)
*(int *) c->var = INT_MAX;
else if (val >= INT_MAX)
error ("integer %u out of range", val);
else
*(int *) c->var = val;
break;
}
case var_zinteger:
if (arg == NULL)
error_no_arg ("integer to set it to.");
*(int *) c->var = parse_and_eval_long (arg);
break;
case var_enum:
{
int i;
int len;
int nmatches;
const char *match = NULL;
char *p;
/* if no argument was supplied, print an informative error message */
if (arg == NULL)
{
char msg[1024];
strcpy (msg, "Requires an argument. Valid arguments are ");
for (i = 0; c->enums[i]; i++)
{
if (i != 0)
strcat (msg, ", ");
strcat (msg, c->enums[i]);
}
strcat (msg, ".");
error (msg);
}
p = strchr (arg, ' ');
if (p)
len = p - arg;
else
len = strlen (arg);
nmatches = 0;
for (i = 0; c->enums[i]; i++)
if (strncmp (arg, c->enums[i], len) == 0)
{
if (c->enums[i][len] == '\0')
{
match = c->enums[i];
nmatches = 1;
break; /* exact match. */
}
else
{
match = c->enums[i];
nmatches++;
}
}
if (nmatches <= 0)
error ("Undefined item: \"%s\".", arg);
if (nmatches > 1)
error ("Ambiguous item \"%s\".", arg);
*(const char **) c->var = match;
}
break;
default:
error ("gdb internal error: bad var_type in do_setshow_command");
}
}
else if (c->type == show_cmd)
{
#ifdef UI_OUT
struct cleanup *old_chain;
struct ui_stream *stb;
int quote;
stb = ui_out_stream_new (uiout);
old_chain = make_cleanup_ui_out_stream_delete (stb);
#endif /* UI_OUT */
/* Print doc minus "show" at start. */
print_doc_line (gdb_stdout, c->doc + 5);
#ifdef UI_OUT
ui_out_text (uiout, " is ");
ui_out_wrap_hint (uiout, " ");
quote = 0;
switch (c->var_type)
{
case var_string:
{
unsigned char *p;
if (*(unsigned char **) c->var)
fputstr_filtered (*(unsigned char **) c->var, '"', stb->stream);
quote = 1;
}
break;
case var_string_noescape:
case var_filename:
case var_enum:
if (*(char **) c->var)
fputs_filtered (*(char **) c->var, stb->stream);
quote = 1;
break;
case var_boolean:
fputs_filtered (*(int *) c->var ? "on" : "off", stb->stream);
break;
case var_auto_boolean:
switch (*(enum cmd_auto_boolean*) c->var)
{
case CMD_AUTO_BOOLEAN_TRUE:
fputs_filtered ("on", stb->stream);
break;
case CMD_AUTO_BOOLEAN_FALSE:
fputs_filtered ("off", stb->stream);
break;
case CMD_AUTO_BOOLEAN_AUTO:
fputs_filtered ("auto", stb->stream);
break;
default:
internal_error ("do_setshow_command: invalid var_auto_boolean");
break;
}
break;
case var_uinteger:
if (*(unsigned int *) c->var == UINT_MAX)
{
fputs_filtered ("unlimited", stb->stream);
break;
}
/* else fall through */
case var_zinteger:
fprintf_filtered (stb->stream, "%u", *(unsigned int *) c->var);
break;
case var_integer:
if (*(int *) c->var == INT_MAX)
{
fputs_filtered ("unlimited", stb->stream);
}
else
fprintf_filtered (stb->stream, "%d", *(int *) c->var);
break;
default:
error ("gdb internal error: bad var_type in do_setshow_command");
}
if (quote)
ui_out_text (uiout, "\"");
ui_out_field_stream (uiout, "value", stb);
if (quote)
ui_out_text (uiout, "\"");
ui_out_text (uiout, ".\n");
do_cleanups (old_chain);
#else
fputs_filtered (" is ", gdb_stdout);
wrap_here (" ");
switch (c->var_type)
{
case var_string:
{
fputs_filtered ("\"", gdb_stdout);
if (*(unsigned char **) c->var)
fputstr_filtered (*(unsigned char **) c->var, '"', gdb_stdout);
fputs_filtered ("\"", gdb_stdout);
}
break;
case var_string_noescape:
case var_filename:
case var_enum:
fputs_filtered ("\"", gdb_stdout);
if (*(char **) c->var)
fputs_filtered (*(char **) c->var, gdb_stdout);
fputs_filtered ("\"", gdb_stdout);
break;
case var_boolean:
fputs_filtered (*(int *) c->var ? "on" : "off", gdb_stdout);
break;
case var_auto_boolean:
switch (*(enum cmd_auto_boolean*) c->var)
{
case CMD_AUTO_BOOLEAN_TRUE:
fputs_filtered ("on", gdb_stdout);
break;
case CMD_AUTO_BOOLEAN_FALSE:
fputs_filtered ("off", gdb_stdout);
break;
case CMD_AUTO_BOOLEAN_AUTO:
fputs_filtered ("auto", gdb_stdout);
break;
default:
internal_error ("do_setshow_command: invalid var_auto_boolean");
break;
}
break;
case var_uinteger:
if (*(unsigned int *) c->var == UINT_MAX)
{
fputs_filtered ("unlimited", gdb_stdout);
break;
}
/* else fall through */
case var_zinteger:
fprintf_filtered (gdb_stdout, "%u", *(unsigned int *) c->var);
break;
case var_integer:
if (*(int *) c->var == INT_MAX)
{
fputs_filtered ("unlimited", gdb_stdout);
}
else
fprintf_filtered (gdb_stdout, "%d", *(int *) c->var);
break;
default:
error ("gdb internal error: bad var_type in do_setshow_command");
}
fputs_filtered (".\n", gdb_stdout);
#endif
}
else
error ("gdb internal error: bad cmd_type in do_setshow_command");
(*c->function.sfunc) (NULL, from_tty, c);
if (c->type == set_cmd && set_hook)
set_hook (c);
}
/* Show all the settings in a list of show commands. */
void
cmd_show_list (struct cmd_list_element *list, int from_tty, char *prefix)
{
#ifdef UI_OUT
ui_out_list_begin (uiout, "showlist");
#endif
for (; list != NULL; list = list->next)
{
/* If we find a prefix, run its list, prefixing our output by its
prefix (with "show " skipped). */
#ifdef UI_OUT
if (list->prefixlist && !list->abbrev_flag)
{
ui_out_list_begin (uiout, "optionlist");
ui_out_field_string (uiout, "prefix", list->prefixname + 5);
cmd_show_list (*list->prefixlist, from_tty, list->prefixname + 5);
ui_out_list_end (uiout);
}
if (list->type == show_cmd)
{
ui_out_list_begin (uiout, "option");
ui_out_text (uiout, prefix);
ui_out_field_string (uiout, "name", list->name);
ui_out_text (uiout, ": ");
do_setshow_command ((char *) NULL, from_tty, list);
ui_out_list_end (uiout);
}
#else
if (list->prefixlist && !list->abbrev_flag)
cmd_show_list (*list->prefixlist, from_tty, list->prefixname + 5);
if (list->type == show_cmd)
{
fputs_filtered (prefix, gdb_stdout);
fputs_filtered (list->name, gdb_stdout);
fputs_filtered (": ", gdb_stdout);
do_setshow_command ((char *) NULL, from_tty, list);
}
#endif
}
#ifdef UI_OUT
ui_out_list_end (uiout);
#endif
}

32
gdb/cli/cli-setshow.h Normal file
View File

@ -0,0 +1,32 @@
/* Header file for GDB CLI set and show commands implementation.
Copyright (C) 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#if !defined (CLI_SETSHOW_H)
#define CLI_SETSHOW_H 1
/* Exported to cli/cli-cmds.c and gdb/top.c */
extern void do_setshow_command (char *arg, int from_tty,
struct cmd_list_element *c);
/* Exported to cli/cli-cmds.c and gdb/top.c, language.c and valprint.c */
extern void cmd_show_list (struct cmd_list_element *list, int from_tty,
char *prefix);
#endif /* !defined (CLI_SETSHOW_H) */

View File

@ -1,3 +1,10 @@
/* ***DEPRECATED*** The gdblib files must not be calling/using things in any
of the possible command languages. If necessary, a hook (that may be
present or not) must be used and set to the appropriate routine by any
command language that cares about it. If you are having to include this
file you are possibly doing things the old way. This file will disapear.
fnasser@redhat.com */
/* Header file for command-reading library command.c.
Copyright (C) 1986, 1989, 1990, 2000 Free Software Foundation, Inc.

780
gdb/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -460,6 +460,40 @@ if test ${build} = ${host} -a ${host} = ${target} ; then
AC_SUBST(CONFIG_LDFLAGS)
fi
dnl The CLI cannot be disabled yet, but may be in the future
dnl Handle CLI sub-directory configury.
AC_ARG_ENABLE(gdbcli,
[ --enable-gdbcli Enable GDB-CLI interface],
[
case "${enable_gdbcli}" in
yes) ;;
"") enable_gdbcli=yes ;;
no)
AC_MSG_ERROR(The CLI cannot be disabled yet)
;;
*)
AC_MSG_ERROR(Bad value for --enable-gdbmi: ${enableval})
;;
esac
],
[enable_gdbcli=yes])
case ${enable_gdbcli} in
"yes" )
if test -d "${srcdir}/mi" ; then
CONFIG_OBS="${CONFIG_OBS} \$(SUBDIR_CLI_OBS)"
CONFIG_DEPS="${CONFIG_DEPS} \$(SUBDIR_CLI_DEPS)"
CONFIG_SRCS="${CONFIG_SRS} \$(SUBDIR_CLI_SRCS)"
CONFIG_INITS="${CONFIG_INITS} \$(SUBDIR_CLI_INITS)"
ENABLE_CFLAGS="${ENABLE_CFLAGS} \$(SUBDIR_CLI_CFLAGS)"
CONFIG_ALL="${CONFIG_ALL} \$(SUBDIR_CLI_ALL)"
CONFIG_CLEAN="${CONFIG_CLEAN} \$(SUBDIR_CLI_CLEAN)"
CONFIG_INSTALL="${CONFIG_INSTALL} \$(SUBDIR_CLI_INSTALL)"
CONFIG_UNINSTALL="${CONFIG_UNINSTALL} \$(SUBDIR_CLI_UNINSTALL)"
fi
;;
esac
dnl Handle optional features that can be enabled.
dnl Handle MI sub-directory configury.

View File

@ -1,3 +1,10 @@
/* ***DEPRECATED*** The gdblib files must not be calling/using things in any
of the possible command languages. If necessary, a hook (that may be
present or not) must be used and set to the appropriate routine by any
command language that cares about it. If you are having to include this
file you are possibly doing things the old way. This file will disapear.
fnasser@redhat.com */
/* Header file for GDB-specific command-line stuff.
Copyright 1986, 1989, 1990, 1992, 2000 Free Software Foundation, Inc.

1927
gdb/top.c

File diff suppressed because it is too large Load Diff