/* Handle lists of commands, their decoding and documentation, for GDB.
- Copyright 1986, 1989, 1990, 1991, 1998, 2000 Free Software Foundation, Inc.
+
+ Copyright 1986, 1989, 1990, 1991, 1998, 2000, 2001, 2002 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
#include "defs.h"
#include "symtab.h"
#include <ctype.h>
-#include "gnu-regex.h"
+#include "gdb_regex.h"
-#ifdef UI_OUT
#include "ui-out.h"
-#endif
#include "cli/cli-cmds.h"
#include "cli/cli-decode.h"
static void help_all (struct ui_file *stream);
\f
+/* Set the callback function for the specified command. For each both
+ the commands callback and func() are set. The latter set to a
+ bounce function (unless cfunc / sfunc is NULL that is). */
+
+static void
+do_cfunc (struct cmd_list_element *c, char *args, int from_tty)
+{
+ c->function.cfunc (args, from_tty); /* Ok. */
+}
+
+void
+set_cmd_cfunc (struct cmd_list_element *cmd,
+ void (*cfunc) (char *args, int from_tty))
+{
+ if (cfunc == NULL)
+ cmd->func = NULL;
+ else
+ cmd->func = do_cfunc;
+ cmd->function.cfunc = cfunc; /* Ok. */
+}
+
+static void
+do_sfunc (struct cmd_list_element *c, char *args, int from_tty)
+{
+ c->function.sfunc (args, from_tty, c); /* Ok. */
+}
+
+void
+set_cmd_sfunc (struct cmd_list_element *cmd,
+ void (*sfunc) (char *args, int from_tty,
+ struct cmd_list_element * c))
+{
+ if (sfunc == NULL)
+ cmd->func = NULL;
+ else
+ cmd->func = do_sfunc;
+ cmd->function.sfunc = sfunc; /* Ok. */
+}
+
+
/* Add element named NAME.
CLASS is the top level category into which commands are broken down
for "help" purposes.
delete_cmd (name, list);
- if (*list == NULL || STRCMP ((*list)->name, name) >= 0)
+ if (*list == NULL || strcmp ((*list)->name, name) >= 0)
{
c->next = *list;
*list = c;
else
{
p = *list;
- while (p->next && STRCMP (p->next->name, name) <= 0)
+ while (p->next && strcmp (p->next->name, name) <= 0)
{
p = p->next;
}
c->name = name;
c->class = class;
- c->function.cfunc = fun;
+ set_cmd_cfunc (c, fun);
c->doc = doc;
c->flags = 0;
c->replacement = NULL;
+ c->pre_show_hook = NULL;
c->hook_pre = NULL;
c->hook_post = NULL;
c->hook_in = 0;
return c;
}
+/* Same as above, except that the abbrev_flag is set. */
+/* Note: Doesn't seem to be used anywhere currently. */
+
+struct cmd_list_element *
+add_abbrev_cmd (char *name, enum command_class class, void (*fun) (char *, int),
+ char *doc, struct cmd_list_element **list)
+{
+ register struct cmd_list_element *c
+ = add_cmd (name, class, fun, doc, list);
+
+ c->abbrev_flag = 1;
+ return c;
+}
/* Deprecates a command CMD.
REPLACEMENT is the name of the command which should be used in place
return cmd;
}
-
-/* Same as above, except that the abbrev_flag is set. */
-
-#if 0 /* Currently unused */
-
-struct cmd_list_element *
-add_abbrev_cmd (char *name, enum command_class class, void (*fun) (char *, int),
- char *doc, struct cmd_list_element **list)
-{
- register struct cmd_list_element *c
- = add_cmd (name, class, fun, doc, list);
-
- c->abbrev_flag = 1;
- return c;
-}
-
-#endif
-
struct cmd_list_element *
add_alias_cmd (char *name, char *oldname, enum command_class class,
int abbrev_flag, struct cmd_list_element **list)
return 0;
}
- c = add_cmd (name, class, old->function.cfunc, old->doc, list);
+ c = add_cmd (name, class, NULL, old->doc, list);
+ /* NOTE: Both FUNC and all the FUNCTIONs need to be copied. */
+ c->func = old->func;
+ c->function = old->function;
c->prefixlist = old->prefixlist;
c->prefixname = old->prefixname;
c->allow_unknown = old->allow_unknown;
char *doc,
struct cmd_list_element **list)
{
- struct cmd_list_element *c
- = add_cmd (name, class, NO_FUNCTION, doc, list);
+ struct cmd_list_element *c = add_cmd (name, class, NULL, doc, list);
c->type = set_cmd;
c->var_type = var_type;
c->var = var;
- /* This needs to be something besides NO_FUNCTION so that this isn't
+ /* This needs to be something besides NULL so that this isn't
treated as a help class. */
- c->function.sfunc = empty_sfunc;
+ set_cmd_sfunc (c, empty_sfunc);
return c;
}
return c;
}
+/* Add element named NAME to command list LIST (the list for set
+ or some sublist thereof).
+ CLASS is as in add_cmd.
+ VAR is address of the variable which will contain the value.
+ DOC is the documentation string. */
+struct cmd_list_element *
+add_set_boolean_cmd (char *name,
+ enum command_class class,
+ int *var,
+ char *doc,
+ struct cmd_list_element **list)
+{
+ static const char *boolean_enums[] = { "on", "off", NULL };
+ struct cmd_list_element *c;
+ c = add_set_cmd (name, class, var_boolean, var, doc, list);
+ c->enums = boolean_enums;
+ return c;
+}
+
/* Where SETCMD has already been added, add the corresponding show
command to LIST and return a pointer to the added command (not
necessarily the head of LIST). */
else
fprintf_unfiltered (gdb_stderr, "GDB internal error: Bad docstring for set command\n");
- if (*list == NULL || STRCMP ((*list)->name, showcmd->name) >= 0)
+ if (*list == NULL || strcmp ((*list)->name, showcmd->name) >= 0)
{
showcmd->next = *list;
*list = showcmd;
else
{
p = *list;
- while (p->next && STRCMP (p->next->name, showcmd->name) <= 0)
+ while (p->next && strcmp (p->next->name, showcmd->name) <= 0)
{
p = p->next;
}
if ((*list)->hookee_post)
(*list)->hookee_post->hook_post = 0; /* Hook slips out of its bottom */
p = (*list)->next;
- free ((PTR) * list);
+ xfree (* list);
*list = p;
}
c->next->hookee_post->hook_post = 0; /* remove post hook */
/* :( no fishing metaphore */
p = c->next->next;
- free ((PTR) c->next);
+ xfree (c->next);
c->next = p;
}
else
If c->prefixlist is nonzero, we have a prefix command.
Print its documentation, then list its subcommands.
- If c->function is nonzero, we really have a command.
- Print its documentation and return.
+ If c->func is non NULL, we really have a command. Print its
+ documentation and return.
- If c->function is zero, we have a class name.
- Print its documentation (as if it were a command)
- and then set class to the number of this class
- so that the commands in the class will be listed. */
+ If c->func is NULL, we have a class name. Print its
+ documentation (as if it were a command) and then set class to the
+ number of this class so that the commands in the class will be
+ listed. */
fputs_filtered (c->doc, stream);
fputs_filtered ("\n", stream);
- if (c->prefixlist == 0 && c->function.cfunc != NULL)
+ if (c->prefixlist == 0 && c->func != NULL)
return;
fprintf_filtered (stream, "\n");
help_list (*c->prefixlist, c->prefixname, all_commands, stream);
/* If this is a class name, print all of the commands in the class */
- if (c->function.cfunc == NULL)
+ if (c->func == NULL)
help_list (cmdlist, "", c->class, stream);
if (c->hook_pre || c->hook_post)
help_cmd_list (*c->prefixlist, all_commands, c->prefixname, 0, stream);
/* If this is a class name, print all of the commands in the class */
- else if (c->function.cfunc == NULL)
+ else if (c->func == NULL)
help_cmd_list (cmdlist, c->class, "", 0, stream);
}
}
if (p - str > line_size - 1)
{
line_size = p - str + 1;
- free ((PTR) line_buffer);
+ xfree (line_buffer);
line_buffer = (char *) xmalloc (line_size);
}
strncpy (line_buffer, str, p - str);
line_buffer[p - str] = '\0';
if (islower (line_buffer[0]))
line_buffer[0] = toupper (line_buffer[0]);
-#ifdef UI_OUT
ui_out_text (uiout, line_buffer);
-#else
- fputs_filtered (line_buffer, stream);
-#endif
}
/*
{
if (c->abbrev_flag == 0 &&
(class == all_commands
- || (class == all_classes && c->function.cfunc == NULL)
- || (class == c->class && c->function.cfunc != NULL)))
+ || (class == all_classes && c->func == NULL)
+ || (class == c->class && c->func != NULL)))
{
fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
print_doc_line (stream, c->doc);
*nfound = 0;
for (c = clist; c; c = c->next)
if (!strncmp (command, c->name, len)
- && (!ignore_help_classes || c->function.cfunc))
+ && (!ignore_help_classes || c->func))
{
found = c;
(*nfound)++;
struct cmd_list_element *last_list = 0;
struct cmd_list_element *c =
lookup_cmd_1 (line, list, &last_list, ignore_help_classes);
-#if 0
- /* This is wrong for complete_command. */
- char *ptr = (*line) + strlen (*line) - 1;
- /* Clear off trailing whitespace. */
- while (ptr >= *line && (*ptr == ' ' || *ptr == '\t'))
- ptr--;
- *(ptr + 1) = '\0';
-#endif
+ /* Note: Do not remove trailing whitespace here because this
+ would be wrong for complete_command. Jim Kingdon */
if (!c)
{
}
}
-
-
-
-#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.
- If it is found, return the struct cmd_list_element for that command
- and update *LINE to point after the command name, at the first argument.
- If not found, call error if ALLOW_UNKNOWN is zero
- otherwise (or if error returns) return zero.
- Call error if specified command is ambiguous,
- unless ALLOW_UNKNOWN is negative.
- CMDTYPE precedes the word "command" in the error message. */
-
-struct cmd_list_element *
-lookup_cmd (char **line, struct cmd_list_element *list, char *cmdtype,
- int allow_unknown)
-{
- register char *p;
- register struct cmd_list_element *c, *found;
- int nfound;
- char ambbuf[100];
- char *processed_cmd;
- int i, cmd_len;
-
- /* Skip leading whitespace. */
-
- while (**line == ' ' || **line == '\t')
- (*line)++;
-
- /* Clear out trailing whitespace. */
-
- p = *line + strlen (*line);
- while (p != *line && (p[-1] == ' ' || p[-1] == '\t'))
- p--;
- *p = 0;
-
- /* Find end of command name. */
-
- p = *line;
- while (*p == '-' || isalnum (*p))
- p++;
-
- /* Look up the command name.
- If exact match, keep that.
- Otherwise, take command abbreviated, if unique. Note that (in my
- opinion) a null string does *not* indicate ambiguity; simply the
- end of the argument. */
-
- if (p == *line)
- {
- if (!allow_unknown)
- error ("Lack of needed %scommand", cmdtype);
- return 0;
- }
-
- /* Copy over to a local buffer, converting to lowercase on the way.
- This is in case the command being parsed is a subcommand which
- doesn't match anything, and that's ok. We want the original
- untouched for the routine of the original command. */
-
- processed_cmd = (char *) alloca (p - *line + 1);
- for (cmd_len = 0; cmd_len < p - *line; cmd_len++)
- {
- char x = (*line)[cmd_len];
- if (isupper (x))
- processed_cmd[cmd_len] = tolower (x);
- else
- processed_cmd[cmd_len] = x;
- }
- processed_cmd[cmd_len] = '\0';
-
- /* Check all possibilities in the current command list. */
- found = 0;
- nfound = 0;
- for (c = list; c; c = c->next)
- {
- if (!strncmp (processed_cmd, c->name, cmd_len))
- {
- found = c;
- nfound++;
- if (c->name[cmd_len] == 0)
- {
- nfound = 1;
- break;
- }
- }
- }
-
- /* Report error for undefined command name. */
-
- if (nfound != 1)
- {
- if (nfound > 1 && allow_unknown >= 0)
- {
- ambbuf[0] = 0;
- for (c = list; c; c = c->next)
- if (!strncmp (processed_cmd, c->name, cmd_len))
- {
- if (strlen (ambbuf) + strlen (c->name) + 6 < sizeof ambbuf)
- {
- if (strlen (ambbuf))
- strcat (ambbuf, ", ");
- strcat (ambbuf, c->name);
- }
- else
- {
- strcat (ambbuf, "..");
- break;
- }
- }
- error ("Ambiguous %scommand \"%s\": %s.", cmdtype,
- processed_cmd, ambbuf);
- }
- else if (!allow_unknown)
- error ("Undefined %scommand: \"%s\".", cmdtype, processed_cmd);
- return 0;
- }
-
- /* Skip whitespace before the argument. */
-
- while (*p == ' ' || *p == '\t')
- p++;
- *line = p;
-
- if (found->prefixlist && *p)
- {
- c = lookup_cmd (line, *found->prefixlist, found->prefixname,
- found->allow_unknown);
- if (c)
- return c;
- }
-
- return found;
-}
-#endif
-
/* Helper function for SYMBOL_COMPLETION_FUNCTION. */
/* Return a vector of char pointers which point to the different
for (ptr = list; ptr; ptr = ptr->next)
if (!strncmp (ptr->name, text, textlen)
&& !ptr->abbrev_flag
- && (ptr->function.cfunc
+ && (ptr->func
|| ptr->prefixlist))
{
if (matches == sizeof_matchlist)
if (matches == 0)
{
- free ((PTR) matchlist);
+ xfree (matchlist);
matchlist = 0;
}
else
if (matches == 0)
{
- free ((PTR) matchlist);
+ xfree (matchlist);
matchlist = 0;
}
else