+2000-03-23 Fernando Nasser <fnasser@cygnus.com>
+
+ From David Whedon <dwhedon@gordian.com>
+
+ * top.c (execute_command): Checks all commands beore executing
+ to see if the user needs to be warned that the command is
+ deprecated, warns user if appropriate.
+ (add_info), (add_info_alias), (add_com) , (add_com_alias): Changed
+ return values from void to struct cmd_list_element *.
+ * command.c (lookup_cmd_1): Check aliases before following link
+ in case user needs to be warned about a deprecated alias.
+ (deprecate_cmd): new exported function for command deprecation,
+ sets flags and posibly a replacement string.
+ (deprecated_cmd_warning): New exported funciton to warn user about
+ a deprecated command.
+ (lookup_cmd_composition): New exported function that determines
+ alias, prefix_command, and cmd based on a string. This is useful
+ is we want to full name of a command.
+ * command.h : Added prototypes for deprecate_cmd,
+ deprecated_warn_user and lookup_cmd_composition, added flags to
+ the cmd_list_element structure, changed return values for
+ add_com_* and add_info_* from void to cmd_list_element.
+ * maint.c : (maintenance_deprecate): New function to deprecate a
+ command. This exists only so that the testsuite can deprecate
+ commands at runtime and check the warning behavior.
+ (maintenance_undeprecate) : New function, drops deprecated flags.
+ (maintenance_do_deprecate): Actually does the (un)deprecation.
+ (initialize_maint_cmds): Added the above new deprecate commands.
+
+2000-03-22 Daniel Berlin <dan@cgsoftware.com>
+ * command.c (apropos_cmd_helper): New function, meat of the
+ apropos command.
+ (apropos_command): New apropos command to search command
+ names/documentation for regular expressions.
+ (_initialize_command): Add the apropos command.
+
2000-03-23 Michael Snyder <msnyder@cleaver.cygnus.com>
* sol-thread.c (ps_pglobal_lookup): Change argument type from
(delete_file_handler, handle_file_event): Likewise.
(gdb_wait_for_event, poll_timers): Likewise.
-2000-03-22 Daniel Berlin <dan@cgsoftware.com>
- * command.c (apropos_cmd_helper): New function, meat of the
- apropos command.
- (apropos_command): New apropos command to search command
- names/documentation for regular expressions.
- (_initialize_command): Add the apropos command.
-
2000-03-22 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
* printcmd.c (print_scalar_formatted): Truncate addresses to the
c->class = class;
c->function.cfunc = fun;
c->doc = doc;
+ c->flags = 0;
+ c->replacement = NULL;
c->hook = NULL;
c->prefixlist = NULL;
c->prefixname = NULL;
return c;
}
+
+/* Deprecates a command CMD.
+ REPLACEMENT is the name of the command which should be used in place
+ of this command, or NULL if no such command exists.
+
+ This function does not check to see if command REPLACEMENT exists
+ since gdb may not have gotten around to adding REPLACEMENT when this
+ function is called.
+
+ Returns a pointer to the deprecated command. */
+
+struct cmd_list_element *
+deprecate_cmd (cmd, replacement)
+ struct cmd_list_element *cmd;
+ char *replacement;
+{
+ cmd->flags |= (CMD_DEPRECATED | DEPRECATED_WARN_USER);
+
+ if (replacement != NULL)
+ cmd->replacement = replacement;
+ else
+ cmd->replacement = NULL;
+
+ return cmd;
+}
+
+
/* Same as above, except that the abbrev_flag is set. */
#if 0 /* Currently unused */
char *p, *command;
int len, tmp, nfound;
struct cmd_list_element *found, *c;
+ char *line = *text;
while (**text == ' ' || **text == '\t')
(*text)++;
*text = p;
- /* If this was an abbreviation, use the base command instead. */
-
if (found->cmd_pointer)
- found = found->cmd_pointer;
-
+ {
+ /* We drop the alias (abbreviation) in favor of the command it is
+ pointing to. If the alias is deprecated, though, we need to
+ warn the user about it before we drop it. Note that while we
+ are warning about the alias, we may also warn about the command
+ itself and we will adjust the appropriate DEPRECATED_WARN_USER
+ flags */
+
+ if (found->flags & DEPRECATED_WARN_USER)
+ deprecated_cmd_warning (&line);
+ found = found->cmd_pointer;
+ }
/* If we found a prefix command, keep looking. */
if (found->prefixlist)
return 0;
}
+/* We are here presumably because an alias or command in *TEXT is
+ deprecated and a warning message should be generated. This function
+ decodes *TEXT and potentially generates a warning message as outlined
+ below.
+
+ Example for 'set endian big' which has a fictitious alias 'seb'.
+
+ If alias wasn't used in *TEXT, and the command is deprecated:
+ "warning: 'set endian big' is deprecated."
+
+ If alias was used, and only the alias is deprecated:
+ "warning: 'seb' an alias for the command 'set endian big' is deprecated."
+
+ If alias was used and command is deprecated (regardless of whether the
+ alias itself is deprecated:
+
+ "warning: 'set endian big' (seb) is deprecated."
+
+ After the message has been sent, clear the appropriate flags in the
+ command and/or the alias so the user is no longer bothered.
+
+*/
+void
+deprecated_cmd_warning (char **text)
+{
+ struct cmd_list_element *alias = NULL;
+ struct cmd_list_element *prefix_cmd = NULL;
+ struct cmd_list_element *cmd = NULL;
+ struct cmd_list_element *c;
+ char *type;
+
+ if (!lookup_cmd_composition (*text, &alias, &prefix_cmd, &cmd))
+ /* return if text doesn't evaluate to a command */
+ return;
+
+ if (!((alias ? (alias->flags & DEPRECATED_WARN_USER) : 0)
+ || (cmd->flags & DEPRECATED_WARN_USER) ) )
+ /* return if nothing is deprecated */
+ return;
+
+ printf_filtered ("Warning:");
+
+ if (alias && !(cmd->flags & CMD_DEPRECATED))
+ printf_filtered (" '%s', an alias for the", alias->name);
+
+ printf_filtered (" command '");
+
+ if (prefix_cmd)
+ printf_filtered ("%s", prefix_cmd->prefixname);
+
+ printf_filtered ("%s", cmd->name);
+
+ if (alias && (cmd->flags & CMD_DEPRECATED))
+ printf_filtered ("' (%s) is deprecated.\n", alias->name);
+ else
+ printf_filtered ("' is deprecated.\n");
+
+
+ /* if it is only the alias that is deprecated, we want to indicate the
+ new alias, otherwise we'll indicate the new command */
+
+ if (alias && !(cmd->flags & CMD_DEPRECATED))
+ {
+ if (alias->replacement)
+ printf_filtered ("Use '%s'.\n\n", alias->replacement);
+ else
+ printf_filtered ("No alternative known.\n\n");
+ }
+ else
+ {
+ if (cmd->replacement)
+ printf_filtered ("Use '%s'.\n\n", cmd->replacement);
+ else
+ printf_filtered ("No alternative known.\n\n");
+ }
+
+ /* We've warned you, now we'll keep quiet */
+ if (alias)
+ alias->flags &= ~DEPRECATED_WARN_USER;
+
+ cmd->flags &= ~DEPRECATED_WARN_USER;
+}
+
+
+
+/* Look up the contents of LINE as a command in the command list 'cmdlist'.
+ Return 1 on success, 0 on failure.
+
+ If LINE refers to an alias, *alias will point to that alias.
+
+ If LINE is a postfix command (i.e. one that is preceeded by a prefix
+ command) set *prefix_cmd.
+
+ Set *cmd to point to the command LINE indicates.
+
+ If any of *alias, *prefix_cmd, or *cmd cannot be determined or do not
+ exist, they are NULL when we return.
+
+*/
+int
+lookup_cmd_composition (char *text,
+ struct cmd_list_element **alias,
+ struct cmd_list_element **prefix_cmd,
+ struct cmd_list_element **cmd)
+{
+ char *p, *command;
+ int len, tmp, nfound;
+ struct cmd_list_element *cur_list;
+ struct cmd_list_element *prev_cmd;
+ *alias = NULL;
+ *prefix_cmd = NULL;
+ *cmd = NULL;
+
+ cur_list = cmdlist;
+
+ while (1)
+ {
+ /* Go through as many command lists as we need to
+ to find the command TEXT refers to. */
+
+ prev_cmd = *cmd;
+
+ while (*text == ' ' || *text == '\t')
+ (text)++;
+
+ /* Treating underscores as part of command words is important
+ so that "set args_foo()" doesn't get interpreted as
+ "set args _foo()". */
+ for (p = text;
+ *p && (isalnum (*p) || *p == '-' || *p == '_' ||
+ (tui_version &&
+ (*p == '+' || *p == '<' || *p == '>' || *p == '$')) ||
+ (xdb_commands && (*p == '!' || *p == '/' || *p == '?')));
+ p++)
+ ;
+
+ /* If nothing but whitespace, return. */
+ if (p == text)
+ return 0;
+
+ len = p - text;
+
+ /* text and p now bracket the first command word to lookup (and
+ it's length is len). We copy this into a local temporary */
+
+ command = (char *) alloca (len + 1);
+ for (tmp = 0; tmp < len; tmp++)
+ {
+ char x = text[tmp];
+ command[tmp] = x;
+ }
+ command[len] = '\0';
+
+ /* Look it up. */
+ *cmd = 0;
+ nfound = 0;
+ *cmd = find_cmd (command, len, cur_list, 1, &nfound);
+
+ /* We didn't find the command in the entered case, so lower case it
+ and search again.
+ */
+ if (!*cmd || nfound == 0)
+ {
+ for (tmp = 0; tmp < len; tmp++)
+ {
+ char x = command[tmp];
+ command[tmp] = isupper (x) ? tolower (x) : x;
+ }
+ *cmd = find_cmd (command, len, cur_list, 1, &nfound);
+ }
+
+ if (*cmd == (struct cmd_list_element *) -1)
+ {
+ return 0; /* ambiguous */
+ }
+
+ if (*cmd == NULL)
+ return 0; /* nothing found */
+ else
+ {
+ if ((*cmd)->cmd_pointer)
+ {
+ /* cmd was actually an alias, we note that an alias was used
+ (by assigning *alais) and we set *cmd.
+ */
+ *alias = *cmd;
+ *cmd = (*cmd)->cmd_pointer;
+ }
+ *prefix_cmd = prev_cmd;
+ }
+ if ((*cmd)->prefixlist)
+ cur_list = *(*cmd)->prefixlist;
+ else
+ return 1;
+
+ text = p;
+ }
+}
+
+
+
+
#if 0
/* Look up the contents of *LINE as a command in the command list LIST.
LIST is a chain of struct cmd_list_element's.
/* Header file for command-reading library command.c.
- Copyright (C) 1986, 1989, 1990 Free Software Foundation, Inc.
+ Copyright (C) 1986, 1989, 1990, 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 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.
+ 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. */
+ 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 (COMMAND_H)
#define COMMAND_H 1
+/* 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;
+typedef enum cmd_types
+ {
+ not_set_cmd,
+ set_cmd,
+ show_cmd
+ }
+cmd_types;
/* 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,
- /* 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;
+typedef enum var_types
+ {
+ /* "on" or "off". *VAR is an integer which is nonzero for on,
+ zero for off. */
+ var_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. */
/* If type is cmd_set or show_cmd, first set the variables, and
then call this. */
void (*sfunc) PARAMS ((char *args, int from_tty,
- struct cmd_list_element *c));
- } function;
-# define NO_FUNCTION ((void (*) PARAMS((char *args, int from_tty))) 0)
+ struct cmd_list_element * c));
+ }
+ function;
+#define NO_FUNCTION ((void (*) PARAMS((char *args, int from_tty))) 0)
/* Documentation of this command (or help topic).
First line is brief documentation; remaining lines form, with it,
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 comtaining 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;
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) PARAMS ((char *text, char *word));
+ char **(*completer) PARAMS ((char *text, char *word));
/* Type of "set" or "show" command (or SET_NOT_SET if not "set"
or "show"). */
/* Forward-declarations of the entry-points of command.c. */
extern struct cmd_list_element *
-add_cmd PARAMS ((char *, enum command_class, void (*fun) (char *, int),
- char *, struct cmd_list_element **));
+ add_cmd PARAMS ((char *, enum command_class, void (*fun) (char *, int),
+ char *, struct cmd_list_element **));
extern struct cmd_list_element *
-add_alias_cmd PARAMS ((char *, char *, enum command_class, int,
- struct cmd_list_element **));
+ add_alias_cmd PARAMS ((char *, char *, enum command_class, int,
+ struct cmd_list_element **));
+
+extern struct cmd_list_element *
+ add_prefix_cmd PARAMS ((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_prefix_cmd PARAMS ((char *, enum command_class, void (*fun) (char *, int),
- char *, struct cmd_list_element **, char *, int,
- struct cmd_list_element **));
+ add_abbrev_prefix_cmd PARAMS ((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 PARAMS ((char *, enum command_class,
- void (*fun) (char *, int), char *,
- struct cmd_list_element **, char *, int,
- struct cmd_list_element **));
+ lookup_cmd PARAMS ((char **, struct cmd_list_element *, char *, int, int));
extern struct cmd_list_element *
-lookup_cmd PARAMS ((char **, struct cmd_list_element *, char *, int, int));
+ lookup_cmd_1 PARAMS ((char **, struct cmd_list_element *,
+ struct cmd_list_element **, int));
extern struct cmd_list_element *
-lookup_cmd_1 PARAMS ((char **, struct cmd_list_element *,
- struct cmd_list_element **, int));
+ deprecate_cmd (struct cmd_list_element *, char * );
extern void
-add_com PARAMS ((char *, enum command_class, void (*fun)(char *, int),
+ 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 PARAMS ((char *, enum command_class, void (*fun) (char *, int),
char *));
-extern void
-add_com_alias PARAMS ((char *, char *, enum command_class, int));
+extern struct cmd_list_element *
+ add_com_alias PARAMS ((char *, char *, enum command_class, int));
-extern void
-add_info PARAMS ((char *, void (*fun) (char *, int), char *));
+extern struct cmd_list_element *
+ add_info PARAMS ((char *, void (*fun) (char *, int), char *));
-extern void
-add_info_alias PARAMS ((char *, char *, int));
+extern struct cmd_list_element *
+ add_info_alias PARAMS ((char *, char *, int));
extern char **
-complete_on_cmdlist PARAMS ((struct cmd_list_element *, char *, char *));
+ complete_on_cmdlist PARAMS ((struct cmd_list_element *, char *, char *));
extern char **
-complete_on_enum PARAMS ((char **enumlist, char *, char *));
+ complete_on_enum PARAMS ((char **enumlist, char *, char *));
extern void
delete_cmd PARAMS ((char *, struct cmd_list_element **));
-extern void
-help_cmd PARAMS ((char *, GDB_FILE *));
+extern void help_cmd (char *, struct ui_file *);
-extern void
-help_list PARAMS ((struct cmd_list_element *, char *, enum command_class,
- GDB_FILE *));
+extern void help_list (struct cmd_list_element *, char *,
+ enum command_class, struct ui_file *);
-extern void
-help_cmd_list PARAMS ((struct cmd_list_element *, enum command_class, char *,
- int, GDB_FILE *));
+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 PARAMS ((char *, enum command_class, var_types, char *, char *,
- struct cmd_list_element **));
+ add_set_cmd PARAMS ((char *, enum command_class, var_types, char *, char *,
+ struct cmd_list_element **));
extern struct cmd_list_element *
-add_set_enum_cmd PARAMS ((char *name, enum command_class, char *list[],
- char *var, char *doc, struct cmd_list_element **c));
+ add_set_enum_cmd PARAMS ((char *name, enum command_class, char *list[],
+ char *var, char *doc, struct cmd_list_element ** c));
extern struct cmd_list_element *
-add_show_from_set PARAMS ((struct cmd_list_element *,
- struct cmd_list_element **));
+ add_show_from_set PARAMS ((struct cmd_list_element *,
+ struct cmd_list_element **));
/* 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
Copyright 1992, 1993, 1994 Free Software Foundation, Inc.
Written by Fred Fish at Cygnus Support.
-This file is part of GDB.
+ 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 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.
+ 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. */
+ 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"
-
-#if MAINTENANCE_CMDS /* Entire rest of file goes away if not including maint cmds */
-
#include <ctype.h>
#include <signal.h>
#include "command.h"
#include "gdbtypes.h"
#include "demangle.h"
#include "gdbcore.h"
-#include "expression.h" /* For language.h */
+#include "expression.h" /* For language.h */
#include "language.h"
#include "symfile.h"
#include "objfiles.h"
#include "value.h"
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
+extern void _initialize_maint_cmds PARAMS ((void));
static void maintenance_command PARAMS ((char *, int));
static void maintenance_dump_me PARAMS ((char *, int));
+static void maintenance_internal_error PARAMS ((char *args, int from_tty));
+
static void maintenance_demangle PARAMS ((char *, int));
static void maintenance_time_display PARAMS ((char *, int));
/*
-LOCAL FUNCTION
+ LOCAL FUNCTION
- maintenance_command -- access the maintenance subcommands
+ maintenance_command -- access the maintenance subcommands
-SYNOPSIS
+ SYNOPSIS
- void maintenance_command (char *args, int from_tty)
+ void maintenance_command (char *args, int from_tty)
-DESCRIPTION
+ DESCRIPTION
-*/
+ */
static void
maintenance_command (args, from_tty)
{
if (query ("Should GDB dump core? "))
{
+#ifdef __DJGPP__
+ /* SIGQUIT by default is ignored, so use SIGABRT instead. */
+ signal (SIGABRT, SIG_DFL);
+ kill (getpid (), SIGABRT);
+#else
signal (SIGQUIT, SIG_DFL);
kill (getpid (), SIGQUIT);
+#endif
}
}
#endif
+/* Stimulate the internal error mechanism that GDB uses when an
+ internal problem is detected. Allows testing of the mechanism.
+ Also useful when the user wants to drop a core file but not exit
+ GDB. */
+
+static void
+maintenance_internal_error (char *args, int from_tty)
+{
+ internal_error ("internal maintenance");
+}
+
/* Someday we should allow demangling for things other than just
- explicit strings. For example, we might want to be able to
- specify the address of a string in either GDB's process space
- or the debuggee's process space, and have gdb fetch and demangle
- that string. If we have a char* pointer "ptr" that points to
- a string, we might want to be able to given just the name and
- have GDB demangle and print what it points to, etc. (FIXME) */
+ explicit strings. For example, we might want to be able to
+ specify the address of a string in either GDB's process space
+ or the debuggee's process space, and have gdb fetch and demangle
+ that string. If we have a char* pointer "ptr" that points to
+ a string, we might want to be able to given just the name and
+ have GDB demangle and print what it points to, etc. (FIXME) */
static void
maintenance_demangle (args, from_tty)
/* FIXME-32x64: Need print_address_numeric with field width. */
printf_filtered (" %s",
local_hex_string_custom
- ((unsigned long) bfd_section_vma (abfd, asect), "08l"));
+ ((unsigned long) bfd_section_vma (abfd, asect), "08l"));
printf_filtered ("->%s",
local_hex_string_custom
- ((unsigned long) (bfd_section_vma (abfd, asect)
- + bfd_section_size (abfd, asect)),
- "08l"));
+ ((unsigned long) (bfd_section_vma (abfd, asect)
+ + bfd_section_size (abfd, asect)),
+ "08l"));
printf_filtered (" at %s",
local_hex_string_custom
- ((unsigned long) asect->filepos, "08l"));
+ ((unsigned long) asect->filepos, "08l"));
printf_filtered (": %s", bfd_section_name (abfd, asect));
if (flags & SEC_ALLOC)
if (exec_bfd)
{
printf_filtered ("Exec file:\n");
- printf_filtered (" `%s', ", bfd_get_filename(exec_bfd));
+ printf_filtered (" `%s', ", bfd_get_filename (exec_bfd));
wrap_here (" ");
- printf_filtered ("file type %s.\n", bfd_get_target(exec_bfd));
- bfd_map_over_sections(exec_bfd, print_section_table, 0);
+ printf_filtered ("file type %s.\n", bfd_get_target (exec_bfd));
+ bfd_map_over_sections (exec_bfd, print_section_table, 0);
}
if (core_bfd)
{
printf_filtered ("Core file:\n");
- printf_filtered (" `%s', ", bfd_get_filename(core_bfd));
+ printf_filtered (" `%s', ", bfd_get_filename (core_bfd));
wrap_here (" ");
- printf_filtered ("file type %s.\n", bfd_get_target(core_bfd));
- bfd_map_over_sections(core_bfd, print_section_table, 0);
+ printf_filtered ("file type %s.\n", bfd_get_target (core_bfd));
+ bfd_map_over_sections (core_bfd, print_section_table, 0);
}
}
/* The "maintenance translate-address" command converts a section and address
to a symbol. This can be called in two ways:
- maintenance translate-address <secname> <addr>
- or maintenance translate-address <addr>
-*/
+ maintenance translate-address <secname> <addr>
+ or maintenance translate-address <addr>
+ */
static void
maintenance_translate_address (arg, from_tty)
if (!isdigit (*p))
{ /* See if we have a valid section name */
- while (*p && !isspace (*p)) /* Find end of section name */
+ while (*p && !isspace (*p)) /* Find end of section name */
p++;
if (*p == '\000') /* End of command? */
error ("Need to specify <section-name> and <address>");
*p++ = '\000';
- while (isspace (*p)) p++; /* Skip whitespace */
+ while (isspace (*p))
+ p++; /* Skip whitespace */
ALL_OBJFILES (objfile)
- {
- sect = bfd_get_section_by_name (objfile->obfd, arg);
- if (sect != NULL)
- break;
- }
+ {
+ sect = bfd_get_section_by_name (objfile->obfd, arg);
+ if (sect != NULL)
+ break;
+ }
if (!sect)
error ("Unknown section %s.", arg);
sym = lookup_minimal_symbol_by_pc (address);
if (sym)
- printf_filtered ("%s+%u\n",
- SYMBOL_SOURCE_NAME (sym),
- address - SYMBOL_VALUE_ADDRESS (sym));
+ printf_filtered ("%s+%s\n",
+ SYMBOL_SOURCE_NAME (sym),
+ paddr_u (address - SYMBOL_VALUE_ADDRESS (sym)));
else if (sect)
- printf_filtered ("no symbol at %s:0x%08x\n", sect->name, address);
+ printf_filtered ("no symbol at %s:0x%s\n", sect->name, paddr (address));
else
- printf_filtered ("no symbol at 0x%08x\n", address);
+ printf_filtered ("no symbol at 0x%s\n", paddr (address));
return;
}
-#endif /* MAINTENANCE_CMDS */
+
+/* When a comamnd is deprecated the user will be warned the first time
+ the command is used. If possible, a replacement will be offered. */
+
+static void
+maintenance_deprecate (char *args, int from_tty)
+{
+ if (args == NULL || *args == '\0')
+ {
+ printf_unfiltered ("\"maintenance deprecate\" takes an argument, \n\
+the command you want to deprecate, and optionally the replacement command \n\
+enclosed in quotes.\n");
+ }
+
+ maintenance_do_deprecate (args, 1);
+
+}
+
+
+static void
+maintenance_undeprecate (char *args, int from_tty)
+{
+ if (args == NULL || *args == '\0')
+ {
+ printf_unfiltered ("\"maintenance undeprecate\" takes an argument, \n\
+the command you want to undeprecate.\n");
+ }
+
+ maintenance_do_deprecate (args, 0);
+
+}
+
+/*
+ You really shouldn't be using this. It is just for the testsuite.
+ Rather, you should use deprecate_cmd() when the command is created
+ in _initialize_blah().
+
+ This function deprecates a command and optionally assigns it a
+ replacement.
+*/
+
+static void maintenance_do_deprecate(char *text, int deprecate){
+
+ struct cmd_list_element *alias=NULL;
+ struct cmd_list_element *prefix_cmd=NULL;
+ struct cmd_list_element *cmd=NULL;
+
+ char *start_ptr=NULL;
+ char *end_ptr=NULL;
+ int len;
+ char *replacement=NULL;
+
+
+ if (!lookup_cmd_composition (text, &alias, &prefix_cmd, &cmd)){
+ printf_filtered ("Can't find command '%s' to deprecate.\n", text);
+ return;
+ }
+
+ if (deprecate)
+ {
+ /* look for a replacement command */
+ if (start_ptr = strchr (text, '\"'))
+ {
+ start_ptr++;
+ if(end_ptr = strrchr (start_ptr, '\"'))
+ {
+ len = end_ptr-start_ptr;
+ start_ptr[len]='\0';
+ replacement = xstrdup (start_ptr);
+ }
+ }
+ }
+
+ if (!start_ptr || !end_ptr)
+ replacement = NULL;
+
+
+ /* If they used an alias, we only want to deprecate the alias.
+
+ Note the MALLOCED_REPLACEMENT test. If the command's replacement
+ string was allocated at compile time we don't want to free the
+ memory.
+ */
+ if (alias)
+ {
+
+ if (alias->flags & MALLOCED_REPLACEMENT)
+ free (alias->replacement);
+
+ if (deprecate)
+ alias->flags |= (DEPRECATED_WARN_USER | CMD_DEPRECATED);
+ else
+ alias->flags &= ~(DEPRECATED_WARN_USER | CMD_DEPRECATED);
+ alias->replacement=replacement;
+ alias->flags |= MALLOCED_REPLACEMENT;
+ return;
+ }
+ else if (cmd)
+ {
+ if (cmd->flags & MALLOCED_REPLACEMENT)
+ free (cmd->replacement);
+
+ if (deprecate)
+ cmd->flags |= (DEPRECATED_WARN_USER | CMD_DEPRECATED);
+ else
+ cmd->flags &= ~(DEPRECATED_WARN_USER | CMD_DEPRECATED);
+ cmd->replacement=replacement;
+ cmd->flags |= MALLOCED_REPLACEMENT;
+ return;
+ }
+}
+
void
_initialize_maint_cmds ()
{
-#if MAINTENANCE_CMDS /* Entire file goes away if not including maint cmds */
add_prefix_cmd ("maintenance", class_maintenance, maintenance_command,
"Commands for use by GDB maintainers.\n\
Includes commands to dump specific internal GDB structures in\n\
add_com_alias ("mt", "maintenance", class_maintenance, 1);
add_prefix_cmd ("info", class_maintenance, maintenance_info_command,
- "Commands for showing internal info about the program being debugged.",
+ "Commands for showing internal info about the program being debugged.",
&maintenanceinfolist, "maintenance info ", 0,
&maintenancelist);
&maintenancelist);
#endif
+ add_cmd ("internal-error", class_maintenance, maintenance_internal_error,
+ "Give GDB an internal error.\n\
+Cause GDB to behave as if an internal error was detected.",
+ &maintenancelist);
+
add_cmd ("demangle", class_maintenance, maintenance_demangle,
"Demangle a C++ mangled name.\n\
Call internal GDB demangler routine to demangle a C++ link name\n\
"Translate a section name and address to a symbol.",
&maintenancelist);
+ add_cmd ("deprecate", class_maintenance, maintenance_deprecate,
+ "Deprecate a command. Note that this is just in here so the \n\
+testsuite can check the comamnd deprecator. You probably shouldn't use this,\n\
+rather you should use the C function deprecate_cmd(). If you decide you \n\
+want to use it: maintenance deprecate 'commandname' \"replacement\". The \n\
+replacement is optional.", &maintenancelist);
+
+ add_cmd ("undeprecate", class_maintenance, maintenance_undeprecate,
+ "Undeprecate a command. Note that this is just in here so the \n\
+testsuite can check the comamnd deprecator. You probably shouldn't use this,\n\
+If you decide you want to use it: maintenance undeprecate 'commandname'",
+ &maintenancelist);
+
add_show_from_set (
- add_set_cmd ("watchdog", class_maintenance, var_zinteger, (char *)&watchdog,
- "Set watchdog timer.\n\
+ add_set_cmd ("watchdog", class_maintenance, var_zinteger, (char *) &watchdog,
+ "Set watchdog timer.\n\
When non-zero, this timeout is used instead of waiting forever for a target to\n\
finish a low-level step or continue operation. If the specified amount of time\n\
passes without a response from the target, an error occurs.", &setlist),
- &showlist);
-#endif /* MAINTENANCE_CMDS */
+ &showlist);
}
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 *));
if (*p)
{
char *arg;
-
+ line = p;
+
c = lookup_cmd (&p, cmdlist, "", 0, 1);
/* If the target is running, we allow only a limited set of
p--;
*(p + 1) = '\0';
}
-
+
/* If this command has been hooked, run the hook first. */
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)
\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));
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
+struct cmd_list_element *
add_info_alias (name, oldname, abbrev_flag)
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.
\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));
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
+struct cmd_list_element *
add_com_alias (name, oldname, class, abbrev_flag)
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