/* Handle lists of commands, their decoding and documentation, for GDB.
- Copyright (c) 1986, 1989-1991, 1998, 2000-2002, 2004, 2007-2012 Free
- Software Foundation, Inc.
+ Copyright (c) 1986-2013 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
static void help_all (struct ui_file *stream);
+/* Look up a command whose 'prefixlist' is KEY. Return the command if found,
+ otherwise return NULL. */
+
+static struct cmd_list_element *
+lookup_cmd_for_prefixlist (struct cmd_list_element **key,
+ struct cmd_list_element *list)
+{
+ struct cmd_list_element *p = NULL;
+
+ for (p = list; p != NULL; p = p->next)
+ {
+ struct cmd_list_element *q;
+
+ if (p->prefixlist == NULL)
+ continue;
+ else if (p->prefixlist == key)
+ return p;
+
+ q = lookup_cmd_for_prefixlist (key, *(p->prefixlist));
+ if (q != NULL)
+ return q;
+ }
+
+ return NULL;
+}
+
+static void
+set_cmd_prefix (struct cmd_list_element *c, struct cmd_list_element **list)
+{
+ struct cmd_list_element *p;
+
+ /* Check to see if *LIST contains any element other than C. */
+ for (p = *list; p != NULL; p = p->next)
+ if (p != c)
+ break;
+
+ if (p == NULL)
+ {
+ /* *SET_LIST only contains SET. */
+ p = lookup_cmd_for_prefixlist (list, setlist);
+
+ c->prefix = p ? (p->cmd_pointer ? p->cmd_pointer : p) : p;
+ }
+ else
+ c->prefix = p->prefix;
+}
+
static void
print_help_for_command (struct cmd_list_element *c, char *prefix, int recurse,
struct ui_file *stream);
}
void
-set_cmd_completer (struct cmd_list_element *cmd,
- char **(*completer) (struct cmd_list_element *self,
- char *text, char *word))
+set_cmd_completer (struct cmd_list_element *cmd, completer_ftype *completer)
{
cmd->completer = completer; /* Ok. */
}
c->prefixlist = NULL;
c->prefixname = NULL;
c->allow_unknown = 0;
+ c->prefix = NULL;
c->abbrev_flag = 0;
set_cmd_completer (c, make_symbol_completion_list_fn);
c->destroyer = NULL;
}
c = add_cmd (name, class, NULL, old->doc, list);
+
+ /* If OLD->DOC can be freed, we should make another copy. */
+ if ((old->flags & DOC_ALLOCATED) != 0)
+ {
+ c->doc = xstrdup (old->doc);
+ c->flags |= DOC_ALLOCATED;
+ }
/* NOTE: Both FUNC and all the FUNCTIONs need to be copied. */
c->func = old->func;
c->function = old->function;
c->cmd_pointer = old;
c->alias_chain = old->aliases;
old->aliases = c;
+
+ set_cmd_prefix (c, list);
return c;
}
struct cmd_list_element **list)
{
struct cmd_list_element *c = add_cmd (name, class, fun, doc, list);
+ struct cmd_list_element *p;
c->prefixlist = prefixlist;
c->prefixname = prefixname;
c->allow_unknown = allow_unknown;
+
+ if (list == &cmdlist)
+ c->prefix = NULL;
+ else
+ set_cmd_prefix (c, list);
+
+ /* Update the field 'prefix' of each cmd_list_element in *PREFIXLIST. */
+ for (p = *prefixlist; p != NULL; p = p->next)
+ p->prefix = c;
+
return c;
}
}
set = add_set_or_show_cmd (name, set_cmd, class, var_type, var,
full_set_doc, set_list);
+ set->flags |= DOC_ALLOCATED;
+
if (set_func != NULL)
set_cmd_sfunc (set, set_func);
+
+ set_cmd_prefix (set, set_list);
+
show = add_set_or_show_cmd (name, show_cmd, class, var_type, var,
full_show_doc, show_list);
+ show->flags |= DOC_ALLOCATED;
show->show_value_func = show_func;
if (set_result != NULL)
c->enums = enumlist;
}
+const char * const auto_boolean_enums[] = { "on", "off", "auto", NULL };
+
/* Add an auto-boolean command named NAME to both the set and show
command list lists. CLASS is as in add_cmd. VAR is address of the
variable which will contain the value. DOC is the documentation
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,
/* Add element named NAME to both the set and show command LISTs (the
list for set/show or some sublist thereof). */
-void
+struct cmd_list_element *
add_setshow_string_noescape_cmd (char *name, enum command_class class,
char **var,
const char *set_doc, const char *show_doc,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
+ struct cmd_list_element *set_cmd;
+
add_setshow_cmd_full (name, class, var_string_noescape, var,
set_doc, show_doc, help_doc,
set_func, show_func,
set_list, show_list,
- NULL, NULL);
+ &set_cmd, NULL);
+ return set_cmd;
}
/* Add element named NAME to both the set and show command LISTs (the
/* Add element named NAME to both the set and show command LISTs (the
list for set/show or some sublist thereof). CLASS is as in
add_cmd. VAR is address of the variable which will contain the
- value. SET_DOC and SHOW_DOC are the documentation strings. */
+ value. SET_DOC and SHOW_DOC are the documentation strings. This
+ function is only used in Python API. Please don't use it elsewhere. */
void
add_setshow_integer_cmd (char *name, enum command_class class,
int *var,
NULL, NULL);
}
+void
+add_setshow_zuinteger_unlimited_cmd (char *name,
+ enum command_class class,
+ unsigned int *var,
+ const char *set_doc,
+ const char *show_doc,
+ const char *help_doc,
+ cmd_sfunc_ftype *set_func,
+ show_value_ftype *show_func,
+ struct cmd_list_element **set_list,
+ struct cmd_list_element **show_list)
+{
+ add_setshow_cmd_full (name, class, var_zuinteger_unlimited, var,
+ set_doc, show_doc, help_doc,
+ set_func, show_func,
+ set_list, show_list,
+ NULL, NULL);
+}
+
/* Add element named NAME to both the set and show command LISTs (the
list for set/show or some sublist thereof). CLASS is as in
add_cmd. VAR is address of the variable which will contain the
*prehookee = iter->hookee_pre;
if (iter->hookee_post)
iter->hookee_post->hook_post = 0;
+ if (iter->doc && (iter->flags & DOC_ALLOCATED) != 0)
+ xfree (iter->doc);
*posthook = iter->hook_post;
*posthookee = iter->hookee_post;
line_buffer = (char *) xmalloc (line_size);
}
+ /* Keep printing '.' or ',' not followed by a whitespace for embedded strings
+ like '.gdbinit'. */
p = str;
- while (*p && *p != '\n' && *p != '.' && *p != ',')
+ while (*p && *p != '\n'
+ && ((*p != '.' && *p != ',') || (p[1] && !isspace (p[1]))))
p++;
if (p - str > line_size - 1)
{
line_buffer[p - str] = '\0';
if (islower (line_buffer[0]))
line_buffer[0] = toupper (line_buffer[0]);
- ui_out_text (current_uiout, line_buffer);
+ fputs_filtered (line_buffer, stream);
}
/* Print one-line help for command C.
"foo" and we want to complete to "foobar". If WORD is "oo", return
"oobar"; if WORD is "baz/foo", return "baz/foobar". */
-char **
-complete_on_cmdlist (struct cmd_list_element *list, char *text, char *word)
+VEC (char_ptr) *
+complete_on_cmdlist (struct cmd_list_element *list, char *text, char *word,
+ int ignore_help_classes)
{
struct cmd_list_element *ptr;
- char **matchlist;
- int sizeof_matchlist;
- int matches;
+ VEC (char_ptr) *matchlist = NULL;
int textlen = strlen (text);
int pass;
int saw_deprecated_match = 0;
- sizeof_matchlist = 10;
- matchlist = (char **) xmalloc (sizeof_matchlist * sizeof (char *));
- matches = 0;
-
/* We do one or two passes. In the first pass, we skip deprecated
commands. If we see no matching commands in the first pass, and
if we did happen to see a matching deprecated command, we do
another loop to collect those. */
- for (pass = 0; matches == 0 && pass < 2; ++pass)
+ for (pass = 0; matchlist == 0 && pass < 2; ++pass)
{
for (ptr = list; ptr; ptr = ptr->next)
if (!strncmp (ptr->name, text, textlen)
&& !ptr->abbrev_flag
- && (ptr->func
+ && (!ignore_help_classes || ptr->func
|| ptr->prefixlist))
{
+ char *match;
+
if (pass == 0)
{
if ((ptr->flags & CMD_DEPRECATED) != 0)
}
}
- 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);
+ match = (char *) xmalloc (strlen (word) + strlen (ptr->name) + 1);
if (word == text)
- strcpy (matchlist[matches], ptr->name);
+ strcpy (match, ptr->name);
else if (word > text)
{
/* Return some portion of ptr->name. */
- strcpy (matchlist[matches], ptr->name + (word - text));
+ strcpy (match, ptr->name + (word - text));
}
else
{
/* Return some of text plus ptr->name. */
- strncpy (matchlist[matches], word, text - word);
- matchlist[matches][text - word] = '\0';
- strcat (matchlist[matches], ptr->name);
+ strncpy (match, word, text - word);
+ match[text - word] = '\0';
+ strcat (match, ptr->name);
}
- ++matches;
+ VEC_safe_push (char_ptr, matchlist, match);
}
/* If we saw no matching deprecated commands in the first pass,
just bail out. */
break;
}
- if (matches == 0)
- {
- xfree (matchlist);
- matchlist = 0;
- }
- else
- {
- matchlist = (char **) xrealloc ((char *) matchlist, ((matches + 1)
- * sizeof (char *)));
- matchlist[matches] = (char *) 0;
- }
-
return matchlist;
}
and we want to complete to "foobar". If WORD is "oo", return
"oobar"; if WORD is "baz/foo", return "baz/foobar". */
-char **
+VEC (char_ptr) *
complete_on_enum (const char *const *enumlist,
char *text,
char *word)
{
- char **matchlist;
- int sizeof_matchlist;
- int matches;
+ VEC (char_ptr) *matchlist = NULL;
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 *)));
- }
+ char *match;
- matchlist[matches] = (char *)
- xmalloc (strlen (word) + strlen (name) + 1);
+ match = (char *) xmalloc (strlen (word) + strlen (name) + 1);
if (word == text)
- strcpy (matchlist[matches], name);
+ strcpy (match, name);
else if (word > text)
{
/* Return some portion of name. */
- strcpy (matchlist[matches], name + (word - text));
+ strcpy (match, name + (word - text));
}
else
{
/* Return some of text plus name. */
- strncpy (matchlist[matches], word, text - word);
- matchlist[matches][text - word] = '\0';
- strcat (matchlist[matches], name);
+ strncpy (match, word, text - word);
+ match[text - word] = '\0';
+ strcat (match, name);
}
- ++matches;
+ VEC_safe_push (char_ptr, matchlist, match);
}
- if (matches == 0)
- {
- xfree (matchlist);
- matchlist = 0;
- }
- else
- {
- matchlist = (char **) xrealloc ((char *) matchlist, ((matches + 1)
- * sizeof (char *)));
- matchlist[matches] = (char *) 0;
- }
-
return matchlist;
}