#include "defs.h"
#include "symtab.h"
#include <ctype.h>
#include "gdb_regex.h"
#include "gdb_string.h"
#include "ui-out.h"
#include "cli/cli-cmds.h"
#include "cli/cli-decode.h"
#include "gdb_assert.h"
static void undef_cmd_error (char *, char *);
static struct cmd_list_element *find_cmd (char *command,
int len,
struct cmd_list_element *clist,
int ignore_help_classes,
int *nfound);
static void help_all (struct ui_file *stream);
static void
do_cfunc (struct cmd_list_element *c, char *args, int from_tty)
{
c->function.cfunc (args, from_tty);
}
void
set_cmd_cfunc (struct cmd_list_element *cmd, cmd_cfunc_ftype *cfunc)
{
if (cfunc == NULL)
cmd->func = NULL;
else
cmd->func = do_cfunc;
cmd->function.cfunc = cfunc;
}
static void
do_sfunc (struct cmd_list_element *c, char *args, int from_tty)
{
c->function.sfunc (args, from_tty, c);
}
void
set_cmd_sfunc (struct cmd_list_element *cmd, cmd_sfunc_ftype *sfunc)
{
if (sfunc == NULL)
cmd->func = NULL;
else
cmd->func = do_sfunc;
cmd->function.sfunc = sfunc;
}
int
cmd_cfunc_eq (struct cmd_list_element *cmd,
void (*cfunc) (char *args, int from_tty))
{
return cmd->func == do_cfunc && cmd->function.cfunc == cfunc;
}
void
set_cmd_context (struct cmd_list_element *cmd, void *context)
{
cmd->context = context;
}
void *
get_cmd_context (struct cmd_list_element *cmd)
{
return cmd->context;
}
enum cmd_types
cmd_type (struct cmd_list_element *cmd)
{
return cmd->type;
}
void
set_cmd_completer (struct cmd_list_element *cmd,
char **(*completer) (char *text, char *word))
{
cmd->completer = completer;
}
struct cmd_list_element *
add_cmd (char *name, enum command_class class, void (*fun) (char *, int),
char *doc, struct cmd_list_element **list)
{
register struct cmd_list_element *c
= (struct cmd_list_element *) xmalloc (sizeof (struct cmd_list_element));
struct cmd_list_element *p;
delete_cmd (name, list);
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)
{
p = p->next;
}
c->next = p->next;
p->next = c;
}
c->name = name;
c->class = class;
set_cmd_cfunc (c, fun);
set_cmd_context (c, NULL);
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;
c->prefixlist = NULL;
c->prefixname = NULL;
c->allow_unknown = 0;
c->abbrev_flag = 0;
set_cmd_completer (c, make_symbol_completion_list);
c->type = not_set_cmd;
c->var = NULL;
c->var_type = var_boolean;
c->enums = NULL;
c->user_commands = NULL;
c->hookee_pre = NULL;
c->hookee_post = NULL;
c->cmd_pointer = NULL;
return c;
}
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;
}
struct cmd_list_element *
deprecate_cmd (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;
}
struct cmd_list_element *
add_alias_cmd (char *name, char *oldname, enum command_class class,
int abbrev_flag, struct cmd_list_element **list)
{
char *copied_name;
register struct cmd_list_element *old;
register struct cmd_list_element *c;
copied_name = (char *) alloca (strlen (oldname) + 1);
strcpy (copied_name, oldname);
old = lookup_cmd (&copied_name, *list, "", 1, 1);
if (old == 0)
{
delete_cmd (name, list);
return 0;
}
c = add_cmd (name, class, NULL, old->doc, list);
c->func = old->func;
c->function = old->function;
c->prefixlist = old->prefixlist;
c->prefixname = old->prefixname;
c->allow_unknown = old->allow_unknown;
c->abbrev_flag = abbrev_flag;
c->cmd_pointer = old;
return c;
}
struct cmd_list_element *
add_prefix_cmd (char *name, enum command_class class, void (*fun) (char *, int),
char *doc, struct cmd_list_element **prefixlist,
char *prefixname, int allow_unknown,
struct cmd_list_element **list)
{
register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list);
c->prefixlist = prefixlist;
c->prefixname = prefixname;
c->allow_unknown = allow_unknown;
return c;
}
struct cmd_list_element *
add_abbrev_prefix_cmd (char *name, enum command_class class,
void (*fun) (char *, int), char *doc,
struct cmd_list_element **prefixlist, char *prefixname,
int allow_unknown, struct cmd_list_element **list)
{
register struct cmd_list_element *c = add_cmd (name, class, fun, doc, list);
c->prefixlist = prefixlist;
c->prefixname = prefixname;
c->allow_unknown = allow_unknown;
c->abbrev_flag = 1;
return c;
}
void
not_just_help_class_command (char *args, int from_tty)
{
}
static void empty_sfunc (char *, int, struct cmd_list_element *);
static void
empty_sfunc (char *args, int from_tty, struct cmd_list_element *c)
{
}
static struct cmd_list_element *
add_set_or_show_cmd (char *name,
enum cmd_types type,
enum command_class class,
var_types var_type,
void *var,
char *doc,
struct cmd_list_element **list)
{
struct cmd_list_element *c = add_cmd (name, class, NULL, doc, list);
gdb_assert (type == set_cmd || type == show_cmd);
c->type = type;
c->var_type = var_type;
c->var = var;
set_cmd_sfunc (c, empty_sfunc);
return c;
}
void
add_setshow_cmd_full (char *name,
enum command_class class,
var_types var_type, void *var,
char *set_doc, char *show_doc,
cmd_sfunc_ftype *set_func, cmd_sfunc_ftype *show_func,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list,
struct cmd_list_element **set_result,
struct cmd_list_element **show_result)
{
struct cmd_list_element *set;
struct cmd_list_element *show;
set = add_set_or_show_cmd (name, set_cmd, class, var_type, var,
set_doc, set_list);
if (set_func != NULL)
set_cmd_sfunc (set, set_func);
show = add_set_or_show_cmd (name, show_cmd, class, var_type, var,
show_doc, show_list);
if (show_func != NULL)
set_cmd_sfunc (show, show_func);
if (set_result != NULL)
*set_result = set;
if (show_result != NULL)
*show_result = show;
}
void
add_setshow_cmd (char *name,
enum command_class class,
var_types var_type, void *var,
char *set_doc, char *show_doc,
cmd_sfunc_ftype *set_func, cmd_sfunc_ftype *show_func,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
add_setshow_cmd_full (name, class, var_type, var, set_doc, show_doc,
set_func, show_func, set_list, show_list,
NULL, NULL);
}
struct cmd_list_element *
add_set_cmd (char *name,
enum command_class class,
var_types var_type,
void *var,
char *doc,
struct cmd_list_element **list)
{
return add_set_or_show_cmd (name, set_cmd, class, var_type, var, doc, list);
}
struct cmd_list_element *
add_set_enum_cmd (char *name,
enum command_class class,
const char *enumlist[],
const char **var,
char *doc,
struct cmd_list_element **list)
{
struct cmd_list_element *c
= add_set_cmd (name, class, var_enum, var, doc, list);
c->enums = enumlist;
return c;
}
void
add_setshow_auto_boolean_cmd (char *name,
enum command_class class,
enum auto_boolean *var,
char *set_doc, char *show_doc,
cmd_sfunc_ftype *set_func,
cmd_sfunc_ftype *show_func,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
static const char *auto_boolean_enums[] = { "on", "off", "auto", NULL };
struct cmd_list_element *c;
add_setshow_cmd_full (name, class, var_auto_boolean, var,
set_doc, show_doc, set_func, show_func,
set_list, show_list,
&c, NULL);
c->enums = auto_boolean_enums;
}
void
add_setshow_boolean_cmd (char *name,
enum command_class class,
int *var, char *set_doc, char *show_doc,
cmd_sfunc_ftype *set_func,
cmd_sfunc_ftype *show_func,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
static const char *boolean_enums[] = { "on", "off", NULL };
struct cmd_list_element *c;
add_setshow_cmd_full (name, class, var_boolean, var,
set_doc, show_doc,
set_func, show_func,
set_list, show_list,
&c, NULL);
c->enums = boolean_enums;
}
struct cmd_list_element *
add_show_from_set (struct cmd_list_element *setcmd,
struct cmd_list_element **list)
{
char *doc;
const static char setstring[] = "Set ";
gdb_assert (strncmp (setcmd->doc, setstring, sizeof (setstring) - 1) == 0);
doc = concat ("Show ", setcmd->doc + sizeof (setstring) - 1, NULL);
return add_set_or_show_cmd (setcmd->name, show_cmd, setcmd->class,
setcmd->var_type, setcmd->var, doc, list);
}
void
delete_cmd (char *name, struct cmd_list_element **list)
{
register struct cmd_list_element *c;
struct cmd_list_element *p;
while (*list && STREQ ((*list)->name, name))
{
if ((*list)->hookee_pre)
(*list)->hookee_pre->hook_pre = 0;
if ((*list)->hookee_post)
(*list)->hookee_post->hook_post = 0;
p = (*list)->next;
xfree (* list);
*list = p;
}
if (*list)
for (c = *list; c->next;)
{
if (STREQ (c->next->name, name))
{
if (c->next->hookee_pre)
c->next->hookee_pre->hook_pre = 0;
if (c->next->hookee_post)
c->next->hookee_post->hook_post = 0;
p = c->next->next;
xfree (c->next);
c->next = p;
}
else
c = c->next;
}
}
struct cmd_list_element *
add_info (char *name, void (*fun) (char *, int), char *doc)
{
return add_cmd (name, no_class, fun, doc, &infolist);
}
struct cmd_list_element *
add_info_alias (char *name, char *oldname, int abbrev_flag)
{
return add_alias_cmd (name, oldname, 0, abbrev_flag, &infolist);
}
struct cmd_list_element *
add_com (char *name, enum command_class class, void (*fun) (char *, int),
char *doc)
{
return add_cmd (name, class, fun, doc, &cmdlist);
}
struct cmd_list_element *
add_com_alias (char *name, char *oldname, enum command_class class,
int abbrev_flag)
{
return add_alias_cmd (name, oldname, class, abbrev_flag, &cmdlist);
}
void
apropos_cmd (struct ui_file *stream, struct cmd_list_element *commandlist,
struct re_pattern_buffer *regex, char *prefix)
{
register struct cmd_list_element *c;
int returnvalue=1;
for (c=commandlist;c;c=c->next)
{
if (c->name != NULL)
{
returnvalue=re_search(regex,c->name,strlen(c->name),0,strlen(c->name),NULL);
if (returnvalue >= 0)
{
fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
print_doc_line (stream, c->doc);
fputs_filtered ("\n", stream);
returnvalue=0;
}
}
if (c->doc != NULL && returnvalue != 0)
{
if (re_search(regex,c->doc,strlen(c->doc),0,strlen(c->doc),NULL) >=0)
{
fprintf_filtered (stream, "%s%s -- ", prefix, c->name);
print_doc_line (stream, c->doc);
fputs_filtered ("\n", stream);
}
}
if (c->prefixlist != NULL)
{
apropos_cmd (stream,*c->prefixlist,regex,c->prefixname);
}
}
}
void
help_cmd (char *command, struct ui_file *stream)
{
struct cmd_list_element *c;
extern struct cmd_list_element *cmdlist;
if (!command)
{
help_list (cmdlist, "", all_classes, stream);
return;
}
if (strcmp (command, "all") == 0)
{
help_all (stream);
return;
}
c = lookup_cmd (&command, cmdlist, "", 0, 0);
if (c == 0)
return;
fputs_filtered (c->doc, stream);
fputs_filtered ("\n", stream);
if (c->prefixlist == 0 && c->func != NULL)
return;
fprintf_filtered (stream, "\n");
if (c->prefixlist)
help_list (*c->prefixlist, c->prefixname, all_commands, stream);
if (c->func == NULL)
help_list (cmdlist, "", c->class, stream);
if (c->hook_pre || c->hook_post)
fprintf_filtered (stream,
"\nThis command has a hook (or hooks) defined:\n");
if (c->hook_pre)
fprintf_filtered (stream,
"\tThis command is run after : %s (pre hook)\n",
c->hook_pre->name);
if (c->hook_post)
fprintf_filtered (stream,
"\tThis command is run before : %s (post hook)\n",
c->hook_post->name);
}
void
help_list (struct cmd_list_element *list, char *cmdtype,
enum command_class class, struct ui_file *stream)
{
int len;
char *cmdtype1, *cmdtype2;
len = strlen (cmdtype);
cmdtype1 = (char *) alloca (len + 1);
cmdtype1[0] = 0;
cmdtype2 = (char *) alloca (len + 4);
cmdtype2[0] = 0;
if (len)
{
cmdtype1[0] = ' ';
strncpy (cmdtype1 + 1, cmdtype, len - 1);
cmdtype1[len] = 0;
strncpy (cmdtype2, cmdtype, len - 1);
strcpy (cmdtype2 + len - 1, " sub");
}
if (class == all_classes)
fprintf_filtered (stream, "List of classes of %scommands:\n\n", cmdtype2);
else
fprintf_filtered (stream, "List of %scommands:\n\n", cmdtype2);
help_cmd_list (list, class, cmdtype, (int) class >= 0, stream);
if (class == all_classes)
{
fprintf_filtered (stream, "\n\
Type \"help%s\" followed by a class name for a list of commands in ",
cmdtype1);
wrap_here ("");
fprintf_filtered (stream, "that class.");
}
fprintf_filtered (stream, "\nType \"help%s\" followed by %scommand name ",
cmdtype1, cmdtype2);
wrap_here ("");
fputs_filtered ("for ", stream);
wrap_here ("");
fputs_filtered ("full ", stream);
wrap_here ("");
fputs_filtered ("documentation.\n", stream);
fputs_filtered ("Command name abbreviations are allowed if unambiguous.\n",
stream);
}
static void
help_all (struct ui_file *stream)
{
struct cmd_list_element *c;
extern struct cmd_list_element *cmdlist;
for (c = cmdlist; c; c = c->next)
{
if (c->abbrev_flag)
continue;
if (c->prefixlist)
help_cmd_list (*c->prefixlist, all_commands, c->prefixname, 0, stream);
else if (c->func == NULL)
help_cmd_list (cmdlist, c->class, "", 0, stream);
}
}
void
print_doc_line (struct ui_file *stream, char *str)
{
static char *line_buffer = 0;
static int line_size;
register char *p;
if (!line_buffer)
{
line_size = 80;
line_buffer = (char *) xmalloc (line_size);
}
p = str;
while (*p && *p != '\n' && *p != '.' && *p != ',')
p++;
if (p - str > line_size - 1)
{
line_size = p - str + 1;
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]);
fputs_unfiltered (line_buffer, stream);
}
void
help_cmd_list (struct cmd_list_element *list, enum command_class class,
char *prefix, int recurse, struct ui_file *stream)
{
register struct cmd_list_element *c;
for (c = list; c; c = c->next)
{
if (c->abbrev_flag == 0 &&
(class == all_commands
|| (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);
fputs_filtered ("\n", stream);
}
if (recurse
&& c->prefixlist != 0
&& c->abbrev_flag == 0)
help_cmd_list (*c->prefixlist, class, c->prefixname, 1, stream);
}
}
static struct cmd_list_element *
find_cmd (char *command, int len, struct cmd_list_element *clist,
int ignore_help_classes, int *nfound)
{
struct cmd_list_element *found, *c;
found = (struct cmd_list_element *) NULL;
*nfound = 0;
for (c = clist; c; c = c->next)
if (!strncmp (command, c->name, len)
&& (!ignore_help_classes || c->func))
{
found = c;
(*nfound)++;
if (c->name[len] == '\0')
{
*nfound = 1;
break;
}
}
return found;
}
struct cmd_list_element *
lookup_cmd_1 (char **text, struct cmd_list_element *clist,
struct cmd_list_element **result_list, int ignore_help_classes)
{
char *p, *command;
int len, tmp, nfound;
struct cmd_list_element *found, *c;
char *line = *text;
while (**text == ' ' || **text == '\t')
(*text)++;
for (p = *text;
*p && (isalnum (*p) || *p == '-' || *p == '_' ||
(tui_version &&
(*p == '+' || *p == '<' || *p == '>' || *p == '$')) ||
(xdb_commands && (*p == '!' || *p == '/' || *p == '?')));
p++)
;
if (p == *text)
return 0;
len = p - *text;
command = (char *) alloca (len + 1);
for (tmp = 0; tmp < len; tmp++)
{
char x = (*text)[tmp];
command[tmp] = x;
}
command[len] = '\0';
found = 0;
nfound = 0;
found = find_cmd (command, len, clist, ignore_help_classes, &nfound);
if (!found || nfound == 0)
{
for (tmp = 0; tmp < len; tmp++)
{
char x = command[tmp];
command[tmp] = isupper (x) ? tolower (x) : x;
}
found = find_cmd (command, len, clist, ignore_help_classes, &nfound);
}
if (nfound == 0)
return 0;
if (nfound > 1)
{
if (result_list != NULL)
*result_list = 0;
return (struct cmd_list_element *) -1;
}
*text = p;
if (found->cmd_pointer)
{
if (found->flags & DEPRECATED_WARN_USER)
deprecated_cmd_warning (&line);
found = found->cmd_pointer;
}
if (found->prefixlist)
{
c = lookup_cmd_1 (text, *found->prefixlist, result_list,
ignore_help_classes);
if (!c)
{
if (result_list != NULL)
*result_list = clist;
return found;
}
else if (c == (struct cmd_list_element *) -1)
{
if (result_list != NULL)
if (!*result_list)
*result_list = found;
return c;
}
else
{
return c;
}
}
else
{
if (result_list != NULL)
*result_list = clist;
return found;
}
}
static void
undef_cmd_error (char *cmdtype, char *q)
{
error ("Undefined %scommand: \"%s\". Try \"help%s%.*s\".",
cmdtype,
q,
*cmdtype ? " " : "",
(int) strlen (cmdtype) - 1,
cmdtype);
}
struct cmd_list_element *
lookup_cmd (char **line, struct cmd_list_element *list, char *cmdtype,
int allow_unknown, int ignore_help_classes)
{
struct cmd_list_element *last_list = 0;
struct cmd_list_element *c =
lookup_cmd_1 (line, list, &last_list, ignore_help_classes);
if (!c)
{
if (!allow_unknown)
{
if (!*line)
error ("Lack of needed %scommand", cmdtype);
else
{
char *p = *line, *q;
while (isalnum (*p) || *p == '-')
p++;
q = (char *) alloca (p - *line + 1);
strncpy (q, *line, p - *line);
q[p - *line] = '\0';
undef_cmd_error (cmdtype, q);
}
}
else
return 0;
}
else if (c == (struct cmd_list_element *) -1)
{
int local_allow_unknown = (last_list ? last_list->allow_unknown :
allow_unknown);
char *local_cmdtype = last_list ? last_list->prefixname : cmdtype;
struct cmd_list_element *local_list =
(last_list ? *(last_list->prefixlist) : list);
if (local_allow_unknown < 0)
{
if (last_list)
return last_list;
else
return 0;
}
else
{
int amb_len;
char ambbuf[100];
for (amb_len = 0;
((*line)[amb_len] && (*line)[amb_len] != ' '
&& (*line)[amb_len] != '\t');
amb_len++)
;
ambbuf[0] = 0;
for (c = local_list; c; c = c->next)
if (!strncmp (*line, c->name, amb_len))
{
if (strlen (ambbuf) + strlen (c->name) + 6 < (int) sizeof ambbuf)
{
if (strlen (ambbuf))
strcat (ambbuf, ", ");
strcat (ambbuf, c->name);
}
else
{
strcat (ambbuf, "..");
break;
}
}
error ("Ambiguous %scommand \"%s\": %s.", local_cmdtype,
*line, ambbuf);
return 0;
}
}
else
{
while (**line == ' ' || **line == '\t')
(*line)++;
if (c->prefixlist && **line && !c->allow_unknown)
undef_cmd_error (c->prefixname, *line);
return c;
}
return 0;
}
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 (!((alias ? (alias->flags & DEPRECATED_WARN_USER) : 0)
|| (cmd->flags & DEPRECATED_WARN_USER) ) )
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 (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");
}
if (alias)
alias->flags &= ~DEPRECATED_WARN_USER;
cmd->flags &= ~DEPRECATED_WARN_USER;
}
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)
{
prev_cmd = *cmd;
while (*text == ' ' || *text == '\t')
(text)++;
for (p = text;
*p && (isalnum (*p) || *p == '-' || *p == '_' ||
(tui_version &&
(*p == '+' || *p == '<' || *p == '>' || *p == '$')) ||
(xdb_commands && (*p == '!' || *p == '/' || *p == '?')));
p++)
;
if (p == text)
return 0;
len = p - text;
command = (char *) alloca (len + 1);
for (tmp = 0; tmp < len; tmp++)
{
char x = text[tmp];
command[tmp] = x;
}
command[len] = '\0';
*cmd = 0;
nfound = 0;
*cmd = find_cmd (command, len, cur_list, 1, &nfound);
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;
}
if (*cmd == NULL)
return 0;
else
{
if ((*cmd)->cmd_pointer)
{
*alias = *cmd;
*cmd = (*cmd)->cmd_pointer;
}
*prefix_cmd = prev_cmd;
}
if ((*cmd)->prefixlist)
cur_list = *(*cmd)->prefixlist;
else
return 1;
text = p;
}
}
char **
complete_on_cmdlist (struct cmd_list_element *list, char *text, char *word)
{
struct cmd_list_element *ptr;
char **matchlist;
int sizeof_matchlist;
int matches;
int textlen = strlen (text);
sizeof_matchlist = 10;
matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *));
matches = 0;
for (ptr = list; ptr; ptr = ptr->next)
if (!strncmp (ptr->name, text, textlen)
&& !ptr->abbrev_flag
&& (ptr->func
|| ptr->prefixlist))
{
if (matches == sizeof_matchlist)
{
sizeof_matchlist *= 2;
matchlist = (char **) xrealloc ((char *) matchlist,
(sizeof_matchlist
* sizeof (char *)));
}
matchlist[matches] = (char *)
xmalloc (strlen (word) + strlen (ptr->name) + 1);
if (word == text)
strcpy (matchlist[matches], ptr->name);
else if (word > text)
{
strcpy (matchlist[matches], ptr->name + (word - text));
}
else
{
strncpy (matchlist[matches], word, text - word);
matchlist[matches][text - word] = '\0';
strcat (matchlist[matches], ptr->name);
}
++matches;
}
if (matches == 0)
{
xfree (matchlist);
matchlist = 0;
}
else
{
matchlist = (char **) xrealloc ((char *) matchlist, ((matches + 1)
* sizeof (char *)));
matchlist[matches] = (char *) 0;
}
return matchlist;
}
char **
complete_on_enum (const char *enumlist[],
char *text,
char *word)
{
char **matchlist;
int sizeof_matchlist;
int matches;
int textlen = strlen (text);
int i;
const char *name;
sizeof_matchlist = 10;
matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *));
matches = 0;
for (i = 0; (name = enumlist[i]) != NULL; i++)
if (strncmp (name, text, textlen) == 0)
{
if (matches == sizeof_matchlist)
{
sizeof_matchlist *= 2;
matchlist = (char **) xrealloc ((char *) matchlist,
(sizeof_matchlist
* sizeof (char *)));
}
matchlist[matches] = (char *)
xmalloc (strlen (word) + strlen (name) + 1);
if (word == text)
strcpy (matchlist[matches], name);
else if (word > text)
{
strcpy (matchlist[matches], name + (word - text));
}
else
{
strncpy (matchlist[matches], word, text - word);
matchlist[matches][text - word] = '\0';
strcat (matchlist[matches], name);
}
++matches;
}
if (matches == 0)
{
xfree (matchlist);
matchlist = 0;
}
else
{
matchlist = (char **) xrealloc ((char *) matchlist, ((matches + 1)
* sizeof (char *)));
matchlist[matches] = (char *) 0;
}
return matchlist;
}
int
cmd_func_p (struct cmd_list_element *cmd)
{
return (cmd->func != NULL);
}
void
cmd_func (struct cmd_list_element *cmd, char *args, int from_tty)
{
if (cmd_func_p (cmd))
(*cmd->func) (cmd, args, from_tty);
else
error ("Invalid command");
}