From: fnasser Date: Thu, 23 Mar 2000 23:43:19 +0000 (+0000) Subject: 2000-03-23 Fernando Nasser X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=e60a535aa5c5ac1995eacd4527ff39fba86c5c2f;p=pf3gnuchains%2Fsourceware.git 2000-03-23 Fernando Nasser From David Whedon * 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8d5b70e565..d4ec901f39 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,39 @@ +2000-03-23 Fernando Nasser + + From David Whedon + + * 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 + * 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 * sol-thread.c (ps_pglobal_lookup): Change argument type from @@ -40,13 +76,6 @@ (delete_file_handler, handle_file_event): Likewise. (gdb_wait_for_event, poll_timers): Likewise. -2000-03-22 Daniel Berlin - * 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 * printcmd.c (print_scalar_formatted): Truncate addresses to the diff --git a/gdb/command.c b/gdb/command.c index 826cc46dfc..737ac77122 100644 --- a/gdb/command.c +++ b/gdb/command.c @@ -112,6 +112,8 @@ add_cmd (name, class, fun, doc, list) 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; @@ -129,6 +131,33 @@ add_cmd (name, class, fun, doc, list) 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 */ @@ -730,6 +759,7 @@ lookup_cmd_1 (text, clist, result_list, ignore_help_classes) char *p, *command; int len, tmp, nfound; struct cmd_list_element *found, *c; + char *line = *text; while (**text == ' ' || **text == '\t') (*text)++; @@ -799,11 +829,19 @@ lookup_cmd_1 (text, clist, result_list, ignore_help_classes) *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) @@ -982,6 +1020,208 @@ lookup_cmd (line, list, cmdtype, allow_unknown, ignore_help_classes) 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. diff --git a/gdb/command.h b/gdb/command.h index 5a209234e0..200a48703e 100644 --- a/gdb/command.h +++ b/gdb/command.h @@ -1,65 +1,96 @@ /* 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. */ @@ -82,9 +113,10 @@ struct cmd_list_element /* 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, @@ -92,6 +124,31 @@ struct cmd_list_element 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; @@ -129,7 +186,7 @@ struct cmd_list_element 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"). */ @@ -160,75 +217,84 @@ struct cmd_list_element /* 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 diff --git a/gdb/maint.c b/gdb/maint.c index cf4ceb7e9a..e443522936 100644 --- a/gdb/maint.c +++ b/gdb/maint.c @@ -2,27 +2,25 @@ 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 #include #include "command.h" @@ -31,20 +29,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #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 -#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)); @@ -69,17 +67,17 @@ int watchdog = 0; /* -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) @@ -99,19 +97,36 @@ maintenance_dump_me (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) @@ -192,15 +207,15 @@ print_section_table (abfd, asect, ignore) /* 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) @@ -240,19 +255,19 @@ maintenance_info_sections (arg, from_tty) 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); } } @@ -282,9 +297,9 @@ maintenance_print_command (arg, from_tty) /* The "maintenance translate-address" command converts a section and address to a symbol. This can be called in two ways: - maintenance translate-address - or maintenance translate-address -*/ + maintenance translate-address + or maintenance translate-address + */ static void maintenance_translate_address (arg, from_tty) @@ -305,19 +320,20 @@ 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 and
"); *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); @@ -331,23 +347,133 @@ maintenance_translate_address (arg, from_tty) 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\ @@ -359,7 +485,7 @@ to test internal functions such as the C++ demangler, etc.", 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); @@ -380,6 +506,11 @@ itself a SIGQUIT signal.", &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\ @@ -438,12 +569,24 @@ If a SOURCE file is specified, dump only that file's partial symbols.", "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); } diff --git a/gdb/top.c b/gdb/top.c index 4acf4db4ad..0fac46d96b 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -1474,6 +1474,7 @@ execute_command (p, from_tty) register struct cmd_list_element *c; register enum language flang; static int warned = 0; + char *line; /* FIXME: These should really be in an appropriate header file */ extern void serial_log_command PARAMS ((const char *)); @@ -1494,7 +1495,8 @@ execute_command (p, from_tty) 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 @@ -1517,11 +1519,14 @@ execute_command (p, from_tty) 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) @@ -2892,24 +2897,24 @@ free_command_lines (lptr) /* 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. @@ -2965,26 +2970,26 @@ show_command (arg, from_tty) /* 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