diff options
Diffstat (limited to 'gdb/cli/cli-setshow.c')
-rw-r--r-- | gdb/cli/cli-setshow.c | 280 |
1 files changed, 163 insertions, 117 deletions
diff --git a/gdb/cli/cli-setshow.c b/gdb/cli/cli-setshow.c index 9841ec1..14ea723 100644 --- a/gdb/cli/cli-setshow.c +++ b/gdb/cli/cli-setshow.c @@ -78,33 +78,48 @@ parse_auto_binary_operation (const char *arg) /* See cli-setshow.h. */ int -parse_cli_boolean_value (const char *arg) +parse_cli_boolean_value (const char **arg) { - int length; - - if (!arg || !*arg) - return 1; + const char *p = skip_to_space (*arg); + size_t length = p - *arg; - length = strlen (arg); + /* Note that "o" is ambiguous. */ - while (arg[length - 1] == ' ' || arg[length - 1] == '\t') - length--; + if ((length == 2 && strncmp (*arg, "on", length) == 0) + || strncmp (*arg, "1", length) == 0 + || strncmp (*arg, "yes", length) == 0 + || strncmp (*arg, "enable", length) == 0) + { + *arg = skip_spaces (*arg + length); + return 1; + } + else if ((length >= 2 && strncmp (*arg, "off", length) == 0) + || strncmp (*arg, "0", length) == 0 + || strncmp (*arg, "no", length) == 0 + || strncmp (*arg, "disable", length) == 0) + { + *arg = skip_spaces (*arg + length); + return 0; + } + else + return -1; +} - /* Note that "o" is ambiguous. */ +/* See cli-setshow.h. */ - if ((length == 2 && strncmp (arg, "on", length) == 0) - || strncmp (arg, "1", length) == 0 - || strncmp (arg, "yes", length) == 0 - || strncmp (arg, "enable", length) == 0) +int +parse_cli_boolean_value (const char *arg) +{ + if (!arg || !*arg) return 1; - else if ((length >= 2 && strncmp (arg, "off", length) == 0) - || strncmp (arg, "0", length) == 0 - || strncmp (arg, "no", length) == 0 - || strncmp (arg, "disable", length) == 0) - return 0; - else + + int b = parse_cli_boolean_value (&arg); + if (b >= 0 && *arg != '\0') return -1; + + return b; } + void deprecated_show_value_hack (struct ui_file *ignore_file, @@ -134,21 +149,136 @@ deprecated_show_value_hack (struct ui_file *ignore_file, /* Returns true if ARG is "unlimited". */ -static int -is_unlimited_literal (const char *arg) +static bool +is_unlimited_literal (const char **arg) { - arg = skip_spaces (arg); + *arg = skip_spaces (*arg); - const char *p = skip_to_space (arg); + const char *p = skip_to_space (*arg); - size_t len = p - arg; + size_t len = p - *arg; - if (len > 0 && strncmp ("unlimited", arg, len) == 0) - return true; + if (len > 0 && strncmp ("unlimited", *arg, len) == 0) + { + *arg += len; + return true; + } return false; } +/* See cli-setshow.h. */ + +unsigned int +parse_cli_var_uinteger (var_types var_type, const char **arg, + bool expression) +{ + LONGEST val; + + if (*arg == nullptr) + { + if (var_type == var_uinteger) + error_no_arg (_("integer to set it to, or \"unlimited\".")); + else + error_no_arg (_("integer to set it to.")); + } + + if (var_type == var_uinteger && is_unlimited_literal (arg)) + val = 0; + else if (expression) + val = parse_and_eval_long (*arg); + else + val = get_ulongest (arg); + + if (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. */ + || (var_type == var_uinteger && val >= UINT_MAX) + || (var_type == var_zuinteger && val > UINT_MAX)) + error (_("integer %s out of range"), plongest (val)); + + return val; +} + +/* See cli-setshow.h. */ + +int +parse_cli_var_zuinteger_unlimited (const char **arg, bool expression) +{ + LONGEST val; + + if (*arg == nullptr) + error_no_arg (_("integer to set it to, or \"unlimited\".")); + + if (is_unlimited_literal (arg)) + val = -1; + else if (expression) + val = parse_and_eval_long (*arg); + else + val = get_ulongest (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")); + + return val; +} + +/* See cli-setshow.h. */ + +const char * +parse_cli_var_enum (const char **args, const char *const *enums) +{ + /* If no argument was supplied, print an informative error + message. */ + if (args == NULL || *args == NULL || **args == '\0') + { + std::string msg; + + for (size_t i = 0; enums[i]; i++) + { + if (i != 0) + msg += ", "; + msg += enums[i]; + } + error (_("Requires an argument. Valid arguments are %s."), + msg.c_str ()); + } + + const char *p = skip_to_space (*args); + size_t len = p - *args; + + int nmatches = 0; + const char *match = NULL; + for (size_t i = 0; enums[i]; i++) + if (strncmp (*args, enums[i], len) == 0) + { + if (enums[i][len] == '\0') + { + match = enums[i]; + nmatches = 1; + break; /* Exact match. */ + } + else + { + match = enums[i]; + nmatches++; + } + } + + if (nmatches == 0) + error (_("Undefined item: \"%.*s\"."), (int) len, *args); + + if (nmatches > 1) + error (_("Ambiguous item \"%.*s\"."), (int) len, *args); + + *args += len; + return match; +} /* 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 @@ -295,30 +425,7 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c) 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.")); - } - - 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)); + unsigned int val = parse_cli_var_uinteger (c->var_type, &arg, true); if (*(unsigned int *) c->var != val) { @@ -341,7 +448,7 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c) error_no_arg (_("integer to set it to.")); } - if (c->var_type == var_integer && is_unlimited_literal (arg)) + if (c->var_type == var_integer && is_unlimited_literal (&arg)) val = 0; else val = parse_and_eval_long (arg); @@ -366,59 +473,11 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c) } case var_enum: { - int i; - int len; - int nmatches; - const char *match = NULL; - const char *p; - - /* If no argument was supplied, print an informative error - message. */ - if (arg == NULL) - { - std::string msg; - - for (i = 0; c->enums[i]; i++) - { - if (i != 0) - msg += ", "; - msg += c->enums[i]; - } - error (_("Requires an argument. Valid arguments are %s."), - msg.c_str ()); - } - - p = strchr (arg, ' '); + const char *end_arg = arg; + const char *match = parse_cli_var_enum (&end_arg, c->enums); - 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) - { - if (c->enums[i][len] == '\0') - { - match = c->enums[i]; - nmatches = 1; - break; /* Exact match. */ - } - else - { - match = c->enums[i]; - nmatches++; - } - } - - if (nmatches <= 0) - error (_("Undefined item: \"%s\"."), arg); - - if (nmatches > 1) - error (_("Ambiguous item \"%s\"."), arg); - - const char *after = skip_spaces (arg + len); + int len = end_arg - arg; + const char *after = skip_spaces (end_arg); if (*after != '\0') error (_("Junk after item \"%.*s\": %s"), len, arg, after); @@ -432,20 +491,7 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c) 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")); + int val = parse_cli_var_zuinteger_unlimited (&arg, true); if (*(int *) c->var != val) { |