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.
This commit is contained in:
Fernando Nasser 2000-03-23 23:43:19 +00:00
parent 4fb431855b
commit 5638284566
5 changed files with 474 additions and 28 deletions

View File

@ -1,3 +1,39 @@
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
@ -40,13 +76,6 @@
(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

View File

@ -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.

View File

@ -82,6 +82,15 @@ 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. */
@ -115,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;
@ -208,18 +242,30 @@ extern struct cmd_list_element *
lookup_cmd_1 PARAMS ((char **, struct cmd_list_element *,
struct cmd_list_element **, int));
extern struct cmd_list_element *
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 *));

View File

@ -358,6 +358,119 @@ maintenance_translate_address (arg, from_tty)
return;
}
/* 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 ()
{
@ -456,6 +569,19 @@ 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\

View File

@ -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