| Index: gdb/cli/cli-setshow.c
|
| diff --git a/gdb/cli/cli-setshow.c b/gdb/cli/cli-setshow.c
|
| index 521ac0e00111327bddbea65eef1d13c4f964c2a0..9222091ac4ed8edd41cd1662078b697e1e1fb3aa 100644
|
| --- a/gdb/cli/cli-setshow.c
|
| +++ b/gdb/cli/cli-setshow.c
|
| @@ -1,6 +1,6 @@
|
| /* Handle set and show GDB commands.
|
|
|
| - Copyright (c) 2000-2003, 2007-2012 Free Software Foundation, Inc.
|
| + Copyright (C) 2000-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
|
| @@ -19,18 +19,31 @@
|
| #include "readline/tilde.h"
|
| #include "value.h"
|
| #include <ctype.h>
|
| -#include "gdb_string.h"
|
| +#include <string.h>
|
| #include "arch-utils.h"
|
| +#include "observer.h"
|
|
|
| #include "ui-out.h"
|
|
|
| #include "cli/cli-decode.h"
|
| #include "cli/cli-cmds.h"
|
| #include "cli/cli-setshow.h"
|
| +#include "cli/cli-utils.h"
|
|
|
| -/* Prototypes for local functions. */
|
| +/* Return true if the change of command parameter should be notified. */
|
|
|
| -static int parse_binary_operation (char *);
|
| +static int
|
| +notify_command_param_changed_p (int param_changed, struct cmd_list_element *c)
|
| +{
|
| + if (param_changed == 0)
|
| + return 0;
|
| +
|
| + if (c->class == class_maintenance || c->class == class_deprecated
|
| + || c->class == class_obscure)
|
| + return 0;
|
| +
|
| + return 1;
|
| +}
|
|
|
|
|
| static enum auto_boolean
|
| @@ -60,8 +73,10 @@ parse_auto_binary_operation (const char *arg)
|
| return AUTO_BOOLEAN_AUTO; /* Pacify GCC. */
|
| }
|
|
|
| -static int
|
| -parse_binary_operation (char *arg)
|
| +/* See cli-setshow.h. */
|
| +
|
| +int
|
| +parse_cli_boolean_value (char *arg)
|
| {
|
| int length;
|
|
|
| @@ -84,10 +99,7 @@ parse_binary_operation (char *arg)
|
| || strncmp (arg, "disable", length) == 0)
|
| return 0;
|
| else
|
| - {
|
| - error (_("\"on\" or \"off\" expected."));
|
| - return 0;
|
| - }
|
| + return -1;
|
| }
|
|
|
| void
|
| @@ -116,84 +128,109 @@ deprecated_show_value_hack (struct ui_file *ignore_file,
|
| }
|
| }
|
|
|
| -/* Do a "set" or "show" command. ARG is NULL if no argument, or the
|
| +/* Returns true if ARG is "unlimited". */
|
| +
|
| +static int
|
| +is_unlimited_literal (const char *arg)
|
| +{
|
| + size_t len = sizeof ("unlimited") - 1;
|
| +
|
| + arg = skip_spaces_const (arg);
|
| +
|
| + return (strncmp (arg, "unlimited", len) == 0
|
| + && (isspace (arg[len]) || arg[len] == '\0'));
|
| +}
|
| +
|
| +
|
| +/* Do a "set" command. ARG is NULL if no argument, or the
|
| text of the argument, and FROM_TTY is nonzero if this command is
|
| being entered directly by the user (i.e. these are just like any
|
| other command). C is the command list element for the command. */
|
|
|
| void
|
| -do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c)
|
| +do_set_command (char *arg, int from_tty, struct cmd_list_element *c)
|
| {
|
| - struct ui_out *uiout = current_uiout;
|
| + /* A flag to indicate the option is changed or not. */
|
| + int option_changed = 0;
|
|
|
| - if (c->type == set_cmd)
|
| + gdb_assert (c->type == set_cmd);
|
| +
|
| + switch (c->var_type)
|
| {
|
| - switch (c->var_type)
|
| - {
|
| - case var_string:
|
| + case var_string:
|
| + {
|
| + char *new;
|
| + const char *p;
|
| + char *q;
|
| + int ch;
|
| +
|
| + if (arg == NULL)
|
| + arg = "";
|
| + new = (char *) xmalloc (strlen (arg) + 2);
|
| + p = arg;
|
| + q = new;
|
| + while ((ch = *p++) != '\000')
|
| {
|
| - char *new;
|
| - char *p;
|
| - char *q;
|
| - int ch;
|
| -
|
| - if (arg == NULL)
|
| - arg = "";
|
| - new = (char *) xmalloc (strlen (arg) + 2);
|
| - p = arg;
|
| - q = new;
|
| - while ((ch = *p++) != '\000')
|
| + if (ch == '\\')
|
| {
|
| - if (ch == '\\')
|
| - {
|
| - /* \ at end of argument is used after spaces
|
| - so they won't be lost. */
|
| - /* This is obsolete now that we no longer strip
|
| - trailing whitespace and actually, the backslash
|
| - didn't get here in my test, readline or
|
| - something did something funky with a backslash
|
| - right before a newline. */
|
| - if (*p == 0)
|
| - break;
|
| - ch = parse_escape (get_current_arch (), &p);
|
| - if (ch == 0)
|
| - break; /* C loses */
|
| - else if (ch > 0)
|
| - *q++ = ch;
|
| - }
|
| - else
|
| + /* \ at end of argument is used after spaces
|
| + so they won't be lost. */
|
| + /* This is obsolete now that we no longer strip
|
| + trailing whitespace and actually, the backslash
|
| + didn't get here in my test, readline or
|
| + something did something funky with a backslash
|
| + right before a newline. */
|
| + if (*p == 0)
|
| + break;
|
| + ch = parse_escape (get_current_arch (), &p);
|
| + if (ch == 0)
|
| + break; /* C loses */
|
| + else if (ch > 0)
|
| *q++ = ch;
|
| }
|
| + else
|
| + *q++ = ch;
|
| + }
|
| #if 0
|
| - if (*(p - 1) != '\\')
|
| - *q++ = ' ';
|
| + if (*(p - 1) != '\\')
|
| + *q++ = ' ';
|
| #endif
|
| - *q++ = '\0';
|
| - new = (char *) xrealloc (new, q - new);
|
| - if (*(char **) c->var != NULL)
|
| - xfree (*(char **) c->var);
|
| + *q++ = '\0';
|
| + new = (char *) xrealloc (new, q - new);
|
| +
|
| + if (*(char **) c->var == NULL
|
| + || strcmp (*(char **) c->var, new) != 0)
|
| + {
|
| + xfree (*(char **) c->var);
|
| *(char **) c->var = new;
|
| +
|
| + option_changed = 1;
|
| }
|
| - break;
|
| - case var_string_noescape:
|
| - if (arg == NULL)
|
| - arg = "";
|
| - if (*(char **) c->var != NULL)
|
| - xfree (*(char **) c->var);
|
| - *(char **) c->var = xstrdup (arg);
|
| - break;
|
| - case var_optional_filename:
|
| - if (arg == NULL)
|
| - arg = "";
|
| - if (*(char **) c->var != NULL)
|
| - xfree (*(char **) c->var);
|
| + else
|
| + xfree (new);
|
| + }
|
| + break;
|
| + case var_string_noescape:
|
| + if (arg == NULL)
|
| + arg = "";
|
| +
|
| + if (*(char **) c->var == NULL || strcmp (*(char **) c->var, arg) != 0)
|
| + {
|
| + xfree (*(char **) c->var);
|
| *(char **) c->var = xstrdup (arg);
|
| - break;
|
| - case var_filename:
|
| - if (arg == NULL)
|
| - error_no_arg (_("filename to set it to."));
|
| - if (*(char **) c->var != NULL)
|
| - xfree (*(char **) c->var);
|
| +
|
| + option_changed = 1;
|
| + }
|
| + break;
|
| + case var_filename:
|
| + if (arg == NULL)
|
| + error_no_arg (_("filename to set it to."));
|
| + /* FALLTHROUGH */
|
| + case var_optional_filename:
|
| + {
|
| + char *val = NULL;
|
| +
|
| + if (arg != NULL)
|
| {
|
| /* Clear trailing whitespace of filename. */
|
| char *ptr = arg + strlen (arg) - 1;
|
| @@ -201,209 +238,433 @@ do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c)
|
| while (ptr >= arg && (*ptr == ' ' || *ptr == '\t'))
|
| ptr--;
|
| *(ptr + 1) = '\0';
|
| +
|
| + val = tilde_expand (arg);
|
| }
|
| - *(char **) c->var = tilde_expand (arg);
|
| - break;
|
| - case var_boolean:
|
| - *(int *) c->var = parse_binary_operation (arg);
|
| - break;
|
| - case var_auto_boolean:
|
| - *(enum auto_boolean *) c->var = parse_auto_binary_operation (arg);
|
| - break;
|
| - case var_uinteger:
|
| - if (arg == NULL)
|
| - error_no_arg (_("integer to set it to."));
|
| - *(unsigned int *) c->var = parse_and_eval_long (arg);
|
| - if (*(unsigned int *) c->var == 0)
|
| - *(unsigned int *) c->var = UINT_MAX;
|
| - break;
|
| - case var_integer:
|
| + else
|
| + val = xstrdup ("");
|
| +
|
| + if (*(char **) c->var == NULL
|
| + || strcmp (*(char **) c->var, val) != 0)
|
| + {
|
| + xfree (*(char **) c->var);
|
| + *(char **) c->var = val;
|
| +
|
| + option_changed = 1;
|
| + }
|
| + else
|
| + xfree (val);
|
| + }
|
| + break;
|
| + case var_boolean:
|
| + {
|
| + int val = parse_cli_boolean_value (arg);
|
| +
|
| + if (val < 0)
|
| + error (_("\"on\" or \"off\" expected."));
|
| + if (val != *(int *) c->var)
|
| {
|
| - unsigned int val;
|
| + *(int *) c->var = val;
|
| +
|
| + option_changed = 1;
|
| + }
|
| + }
|
| + break;
|
| + case var_auto_boolean:
|
| + {
|
| + enum auto_boolean val = parse_auto_binary_operation (arg);
|
|
|
| - if (arg == NULL)
|
| + if (*(enum auto_boolean *) c->var != val)
|
| + {
|
| + *(enum auto_boolean *) c->var = val;
|
| +
|
| + option_changed = 1;
|
| + }
|
| + }
|
| + break;
|
| + case var_uinteger:
|
| + case var_zuinteger:
|
| + {
|
| + LONGEST val;
|
| +
|
| + if (arg == NULL)
|
| + {
|
| + if (c->var_type == var_uinteger)
|
| + error_no_arg (_("integer to set it to, or \"unlimited\"."));
|
| + else
|
| error_no_arg (_("integer to set it to."));
|
| - val = parse_and_eval_long (arg);
|
| - if (val == 0)
|
| - *(int *) c->var = INT_MAX;
|
| - else if (val >= INT_MAX)
|
| - error (_("integer %u out of range"), val);
|
| + }
|
| +
|
| + if (c->var_type == var_uinteger && is_unlimited_literal (arg))
|
| + val = 0;
|
| + else
|
| + val = parse_and_eval_long (arg);
|
| +
|
| + if (c->var_type == var_uinteger && val == 0)
|
| + val = UINT_MAX;
|
| + else if (val < 0
|
| + /* For var_uinteger, don't let the user set the value
|
| + to UINT_MAX directly, as that exposes an
|
| + implementation detail to the user interface. */
|
| + || (c->var_type == var_uinteger && val >= UINT_MAX)
|
| + || (c->var_type == var_zuinteger && val > UINT_MAX))
|
| + error (_("integer %s out of range"), plongest (val));
|
| +
|
| + if (*(unsigned int *) c->var != val)
|
| + {
|
| + *(unsigned int *) c->var = val;
|
| +
|
| + option_changed = 1;
|
| + }
|
| + }
|
| + break;
|
| + case var_integer:
|
| + case var_zinteger:
|
| + {
|
| + LONGEST val;
|
| +
|
| + if (arg == NULL)
|
| + {
|
| + if (c->var_type == var_integer)
|
| + error_no_arg (_("integer to set it to, or \"unlimited\"."));
|
| else
|
| - *(int *) c->var = val;
|
| - break;
|
| + error_no_arg (_("integer to set it to."));
|
| }
|
| - case var_zinteger:
|
| - if (arg == NULL)
|
| - error_no_arg (_("integer to set it to."));
|
| - *(int *) c->var = parse_and_eval_long (arg);
|
| - break;
|
| - case var_zuinteger:
|
| - if (arg == NULL)
|
| - error_no_arg (_("integer to set it to."));
|
| - *(unsigned int *) c->var = parse_and_eval_long (arg);
|
| - break;
|
| - case var_enum:
|
| +
|
| + if (c->var_type == var_integer && is_unlimited_literal (arg))
|
| + val = 0;
|
| + else
|
| + val = parse_and_eval_long (arg);
|
| +
|
| + if (val == 0 && c->var_type == var_integer)
|
| + val = INT_MAX;
|
| + else if (val < INT_MIN
|
| + /* For var_integer, don't let the user set the value
|
| + to INT_MAX directly, as that exposes an
|
| + implementation detail to the user interface. */
|
| + || (c->var_type == var_integer && val >= INT_MAX)
|
| + || (c->var_type == var_zinteger && val > INT_MAX))
|
| + error (_("integer %s out of range"), plongest (val));
|
| +
|
| + if (*(int *) c->var != val)
|
| + {
|
| + *(int *) c->var = val;
|
| +
|
| + option_changed = 1;
|
| + }
|
| + break;
|
| + }
|
| + case var_enum:
|
| + {
|
| + int i;
|
| + int len;
|
| + int nmatches;
|
| + const char *match = NULL;
|
| + char *p;
|
| +
|
| + /* If no argument was supplied, print an informative error
|
| + message. */
|
| + if (arg == NULL)
|
| {
|
| - int i;
|
| - int len;
|
| - int nmatches;
|
| - const char *match = NULL;
|
| - char *p;
|
| -
|
| - /* If no argument was supplied, print an informative error
|
| - message. */
|
| - if (arg == NULL)
|
| + char *msg;
|
| + int msg_len = 0;
|
| +
|
| + for (i = 0; c->enums[i]; i++)
|
| + msg_len += strlen (c->enums[i]) + 2;
|
| +
|
| + msg = xmalloc (msg_len);
|
| + *msg = '\0';
|
| + make_cleanup (xfree, msg);
|
| +
|
| + for (i = 0; c->enums[i]; i++)
|
| {
|
| - char *msg;
|
| - int msg_len = 0;
|
| -
|
| - for (i = 0; c->enums[i]; i++)
|
| - msg_len += strlen (c->enums[i]) + 2;
|
| -
|
| - msg = xmalloc (msg_len);
|
| - *msg = '\0';
|
| - make_cleanup (xfree, msg);
|
| -
|
| - for (i = 0; c->enums[i]; i++)
|
| - {
|
| - if (i != 0)
|
| - strcat (msg, ", ");
|
| - strcat (msg, c->enums[i]);
|
| - }
|
| - error (_("Requires an argument. Valid arguments are %s."),
|
| - msg);
|
| + if (i != 0)
|
| + strcat (msg, ", ");
|
| + strcat (msg, c->enums[i]);
|
| }
|
| + error (_("Requires an argument. Valid arguments are %s."),
|
| + msg);
|
| + }
|
|
|
| - p = strchr (arg, ' ');
|
| + p = strchr (arg, ' ');
|
|
|
| - if (p)
|
| - len = p - arg;
|
| - else
|
| - len = strlen (arg);
|
| + if (p)
|
| + len = p - arg;
|
| + else
|
| + len = strlen (arg);
|
|
|
| - nmatches = 0;
|
| - for (i = 0; c->enums[i]; i++)
|
| - if (strncmp (arg, c->enums[i], len) == 0)
|
| + nmatches = 0;
|
| + for (i = 0; c->enums[i]; i++)
|
| + if (strncmp (arg, c->enums[i], len) == 0)
|
| + {
|
| + if (c->enums[i][len] == '\0')
|
| + {
|
| + match = c->enums[i];
|
| + nmatches = 1;
|
| + break; /* Exact match. */
|
| + }
|
| + else
|
| {
|
| - if (c->enums[i][len] == '\0')
|
| - {
|
| - match = c->enums[i];
|
| - nmatches = 1;
|
| - break; /* Exact match. */
|
| - }
|
| - else
|
| - {
|
| - match = c->enums[i];
|
| - nmatches++;
|
| - }
|
| + match = c->enums[i];
|
| + nmatches++;
|
| }
|
| + }
|
|
|
| - if (nmatches <= 0)
|
| - error (_("Undefined item: \"%s\"."), arg);
|
| + if (nmatches <= 0)
|
| + error (_("Undefined item: \"%s\"."), arg);
|
|
|
| - if (nmatches > 1)
|
| - error (_("Ambiguous item \"%s\"."), arg);
|
| + if (nmatches > 1)
|
| + error (_("Ambiguous item \"%s\"."), arg);
|
|
|
| + if (*(const char **) c->var != match)
|
| + {
|
| *(const char **) c->var = match;
|
| +
|
| + option_changed = 1;
|
| }
|
| - break;
|
| - default:
|
| - error (_("gdb internal error: bad var_type in do_setshow_command"));
|
| - }
|
| + }
|
| + break;
|
| + case var_zuinteger_unlimited:
|
| + {
|
| + LONGEST val;
|
| +
|
| + if (arg == NULL)
|
| + error_no_arg (_("integer to set it to, or \"unlimited\"."));
|
| +
|
| + if (is_unlimited_literal (arg))
|
| + val = -1;
|
| + else
|
| + val = parse_and_eval_long (arg);
|
| +
|
| + if (val > INT_MAX)
|
| + error (_("integer %s out of range"), plongest (val));
|
| + else if (val < -1)
|
| + error (_("only -1 is allowed to set as unlimited"));
|
| +
|
| + if (*(int *) c->var != val)
|
| + {
|
| + *(int *) c->var = val;
|
| + option_changed = 1;
|
| + }
|
| + }
|
| + break;
|
| + default:
|
| + error (_("gdb internal error: bad var_type in do_setshow_command"));
|
| }
|
| - else if (c->type == show_cmd)
|
| + c->func (c, NULL, from_tty);
|
| + if (deprecated_set_hook)
|
| + deprecated_set_hook (c);
|
| +
|
| + if (notify_command_param_changed_p (option_changed, c))
|
| {
|
| - struct cleanup *old_chain;
|
| - struct ui_file *stb;
|
| + char *name, *cp;
|
| + struct cmd_list_element **cmds;
|
| + struct cmd_list_element *p;
|
| + int i;
|
| + int length = 0;
|
| +
|
| + /* Compute the whole multi-word command options. If user types command
|
| + 'set foo bar baz on', c->name is 'baz', and GDB can't pass "bar" to
|
| + command option change notification, because it is confusing. We can
|
| + trace back through field 'prefix' to compute the whole options,
|
| + and pass "foo bar baz" to notification. */
|
| +
|
| + for (i = 0, p = c; p != NULL; i++)
|
| + {
|
| + length += strlen (p->name);
|
| + length++;
|
|
|
| - stb = mem_fileopen ();
|
| - old_chain = make_cleanup_ui_file_delete (stb);
|
| + p = p->prefix;
|
| + }
|
| + cp = name = xmalloc (length);
|
| + cmds = xmalloc (sizeof (struct cmd_list_element *) * i);
|
| +
|
| + /* Track back through filed 'prefix' and cache them in CMDS. */
|
| + for (i = 0, p = c; p != NULL; i++)
|
| + {
|
| + cmds[i] = p;
|
| + p = p->prefix;
|
| + }
|
| +
|
| + /* Don't trigger any observer notification if prefixlist is not
|
| + setlist. */
|
| + i--;
|
| + if (cmds[i]->prefixlist != &setlist)
|
| + {
|
| + xfree (cmds);
|
| + xfree (name);
|
| +
|
| + return;
|
| + }
|
| + /* Traverse them in the reversed order, and copy their names into
|
| + NAME. */
|
| + for (i--; i >= 0; i--)
|
| + {
|
| + memcpy (cp, cmds[i]->name, strlen (cmds[i]->name));
|
| + cp += strlen (cmds[i]->name);
|
| +
|
| + if (i != 0)
|
| + {
|
| + cp[0] = ' ';
|
| + cp++;
|
| + }
|
| + }
|
| + cp[0] = 0;
|
|
|
| - /* Possibly call the pre hook. */
|
| - if (c->pre_show_hook)
|
| - (c->pre_show_hook) (c);
|
| + xfree (cmds);
|
|
|
| switch (c->var_type)
|
| {
|
| case var_string:
|
| - if (*(char **) c->var)
|
| - fputstr_filtered (*(char **) c->var, '"', stb);
|
| - break;
|
| case var_string_noescape:
|
| - case var_optional_filename:
|
| case var_filename:
|
| + case var_optional_filename:
|
| case var_enum:
|
| - if (*(char **) c->var)
|
| - fputs_filtered (*(char **) c->var, stb);
|
| + observer_notify_command_param_changed (name, *(char **) c->var);
|
| break;
|
| case var_boolean:
|
| - fputs_filtered (*(int *) c->var ? "on" : "off", stb);
|
| + {
|
| + char *opt = *(int *) c->var ? "on" : "off";
|
| +
|
| + observer_notify_command_param_changed (name, opt);
|
| + }
|
| break;
|
| case var_auto_boolean:
|
| - switch (*(enum auto_boolean*) c->var)
|
| - {
|
| - case AUTO_BOOLEAN_TRUE:
|
| - fputs_filtered ("on", stb);
|
| - break;
|
| - case AUTO_BOOLEAN_FALSE:
|
| - fputs_filtered ("off", stb);
|
| - break;
|
| - case AUTO_BOOLEAN_AUTO:
|
| - fputs_filtered ("auto", stb);
|
| - break;
|
| - default:
|
| - internal_error (__FILE__, __LINE__,
|
| - _("do_setshow_command: "
|
| - "invalid var_auto_boolean"));
|
| - break;
|
| - }
|
| + {
|
| + const char *s = auto_boolean_enums[*(enum auto_boolean *) c->var];
|
| +
|
| + observer_notify_command_param_changed (name, s);
|
| + }
|
| break;
|
| case var_uinteger:
|
| case var_zuinteger:
|
| - if (c->var_type == var_uinteger
|
| - && *(unsigned int *) c->var == UINT_MAX)
|
| - fputs_filtered ("unlimited", stb);
|
| - else
|
| - fprintf_filtered (stb, "%u", *(unsigned int *) c->var);
|
| + {
|
| + char s[64];
|
| +
|
| + xsnprintf (s, sizeof s, "%u", *(unsigned int *) c->var);
|
| + observer_notify_command_param_changed (name, s);
|
| + }
|
| break;
|
| case var_integer:
|
| case var_zinteger:
|
| - if (c->var_type == var_integer
|
| - && *(int *) c->var == INT_MAX)
|
| - fputs_filtered ("unlimited", stb);
|
| - else
|
| - fprintf_filtered (stb, "%d", *(int *) c->var);
|
| - break;
|
| + case var_zuinteger_unlimited:
|
| + {
|
| + char s[64];
|
|
|
| - default:
|
| - error (_("gdb internal error: bad var_type in do_setshow_command"));
|
| + xsnprintf (s, sizeof s, "%d", *(int *) c->var);
|
| + observer_notify_command_param_changed (name, s);
|
| + }
|
| + break;
|
| }
|
| + xfree (name);
|
| + }
|
| +}
|
| +
|
| +/* Do a "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 directly by the user (i.e. these are just like any
|
| + other command). C is the command list element for the command. */
|
|
|
| +void
|
| +do_show_command (char *arg, int from_tty, struct cmd_list_element *c)
|
| +{
|
| + struct ui_out *uiout = current_uiout;
|
| + struct cleanup *old_chain;
|
| + struct ui_file *stb;
|
|
|
| - /* FIXME: cagney/2005-02-10: Need to split this in half: code to
|
| - convert the value into a string (esentially the above); and
|
| - code to print the value out. For the latter there should be
|
| - MI and CLI specific versions. */
|
| + gdb_assert (c->type == show_cmd);
|
|
|
| - if (ui_out_is_mi_like_p (uiout))
|
| - ui_out_field_stream (uiout, "value", stb);
|
| - else
|
| - {
|
| - char *value = ui_file_xstrdup (stb, NULL);
|
| + stb = mem_fileopen ();
|
| + old_chain = make_cleanup_ui_file_delete (stb);
|
| +
|
| + /* Possibly call the pre hook. */
|
| + if (c->pre_show_hook)
|
| + (c->pre_show_hook) (c);
|
|
|
| - make_cleanup (xfree, value);
|
| - if (c->show_value_func != NULL)
|
| - c->show_value_func (gdb_stdout, from_tty, c, value);
|
| - else
|
| - deprecated_show_value_hack (gdb_stdout, from_tty, c, value);
|
| + switch (c->var_type)
|
| + {
|
| + case var_string:
|
| + if (*(char **) c->var)
|
| + fputstr_filtered (*(char **) c->var, '"', stb);
|
| + break;
|
| + case var_string_noescape:
|
| + case var_optional_filename:
|
| + case var_filename:
|
| + case var_enum:
|
| + if (*(char **) c->var)
|
| + fputs_filtered (*(char **) c->var, stb);
|
| + break;
|
| + case var_boolean:
|
| + fputs_filtered (*(int *) c->var ? "on" : "off", stb);
|
| + break;
|
| + case var_auto_boolean:
|
| + switch (*(enum auto_boolean*) c->var)
|
| + {
|
| + case AUTO_BOOLEAN_TRUE:
|
| + fputs_filtered ("on", stb);
|
| + break;
|
| + case AUTO_BOOLEAN_FALSE:
|
| + fputs_filtered ("off", stb);
|
| + break;
|
| + case AUTO_BOOLEAN_AUTO:
|
| + fputs_filtered ("auto", stb);
|
| + break;
|
| + default:
|
| + internal_error (__FILE__, __LINE__,
|
| + _("do_show_command: "
|
| + "invalid var_auto_boolean"));
|
| + break;
|
| }
|
| - do_cleanups (old_chain);
|
| + break;
|
| + case var_uinteger:
|
| + case var_zuinteger:
|
| + if (c->var_type == var_uinteger
|
| + && *(unsigned int *) c->var == UINT_MAX)
|
| + fputs_filtered ("unlimited", stb);
|
| + else
|
| + fprintf_filtered (stb, "%u", *(unsigned int *) c->var);
|
| + break;
|
| + case var_integer:
|
| + case var_zinteger:
|
| + if (c->var_type == var_integer
|
| + && *(int *) c->var == INT_MAX)
|
| + fputs_filtered ("unlimited", stb);
|
| + else
|
| + fprintf_filtered (stb, "%d", *(int *) c->var);
|
| + break;
|
| + case var_zuinteger_unlimited:
|
| + {
|
| + if (*(int *) c->var == -1)
|
| + fputs_filtered ("unlimited", stb);
|
| + else
|
| + fprintf_filtered (stb, "%d", *(int *) c->var);
|
| + }
|
| + break;
|
| + default:
|
| + error (_("gdb internal error: bad var_type in do_show_command"));
|
| }
|
| +
|
| +
|
| + /* FIXME: cagney/2005-02-10: Need to split this in half: code to
|
| + convert the value into a string (esentially the above); and
|
| + code to print the value out. For the latter there should be
|
| + MI and CLI specific versions. */
|
| +
|
| + if (ui_out_is_mi_like_p (uiout))
|
| + ui_out_field_stream (uiout, "value", stb);
|
| else
|
| - error (_("gdb internal error: bad cmd_type in do_setshow_command"));
|
| + {
|
| + char *value = ui_file_xstrdup (stb, NULL);
|
| +
|
| + make_cleanup (xfree, value);
|
| + if (c->show_value_func != NULL)
|
| + c->show_value_func (gdb_stdout, from_tty, c, value);
|
| + else
|
| + deprecated_show_value_hack (gdb_stdout, from_tty, c, value);
|
| + }
|
| + do_cleanups (old_chain);
|
| +
|
| c->func (c, NULL, from_tty);
|
| - if (c->type == set_cmd && deprecated_set_hook)
|
| - deprecated_set_hook (c);
|
| }
|
|
|
| /* Show all the settings in a list of show commands. */
|
| @@ -442,7 +703,7 @@ cmd_show_list (struct cmd_list_element *list, int from_tty, char *prefix)
|
| ui_out_field_string (uiout, "name", list->name);
|
| ui_out_text (uiout, ": ");
|
| if (list->type == show_cmd)
|
| - do_setshow_command ((char *) NULL, from_tty, list);
|
| + do_show_command ((char *) NULL, from_tty, list);
|
| else
|
| cmd_func (list, NULL, from_tty);
|
| /* Close the tuple. */
|
|
|