aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/auto-load.c2
-rw-r--r--gdb/bt-utils.c10
-rw-r--r--gdb/cli/cli-cmds.c115
-rw-r--r--gdb/cli/cli-decode.c150
-rw-r--r--gdb/cli/cli-decode.h9
-rw-r--r--gdb/cli/cli-setshow.c168
-rw-r--r--gdb/cli/cli-setshow.h4
-rw-r--r--gdb/command.h143
-rw-r--r--gdb/guile/scm-param.c141
-rw-r--r--gdb/maint.c2
-rw-r--r--gdb/python/py-param.c26
-rw-r--r--gdb/python/python-internal.h2
-rw-r--r--gdb/python/python.c29
-rw-r--r--gdb/remote.c3
14 files changed, 547 insertions, 257 deletions
diff --git a/gdb/auto-load.c b/gdb/auto-load.c
index 9cd70f1..7f0bb74 100644
--- a/gdb/auto-load.c
+++ b/gdb/auto-load.c
@@ -1408,7 +1408,7 @@ set_auto_load_cmd (const char *args, int from_tty)
"otherwise check the auto-load sub-commands."));
for (list = *auto_load_set_cmdlist_get (); list != NULL; list = list->next)
- if (list->var_type == var_boolean)
+ if (list->var->type () == var_boolean)
{
gdb_assert (list->type == set_cmd);
do_set_command (args, from_tty, list);
diff --git a/gdb/bt-utils.c b/gdb/bt-utils.c
index dfe429e..8110f10 100644
--- a/gdb/bt-utils.c
+++ b/gdb/bt-utils.c
@@ -29,15 +29,13 @@ gdb_internal_backtrace_set_cmd (const char *args, int from_tty,
cmd_list_element *c)
{
gdb_assert (c->type == set_cmd);
- gdb_assert (c->var_type == var_boolean);
- gdb_assert (c->var != nullptr);
+ gdb_assert (c->var.has_value ());
+ gdb_assert (c->var->type () == var_boolean);
#ifndef GDB_PRINT_INTERNAL_BACKTRACE
- bool *var_ptr = (bool *) c->var;
-
- if (*var_ptr)
+ if (c->var->get<bool> ())
{
- *var_ptr = false;
+ c->var->set<bool> (false);
error (_("support for this feature is not compiled into GDB"));
}
#endif
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index e5c7152..ecbe5a4 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -236,7 +236,7 @@ with_command_1 (const char *set_cmd_prefix,
/*ignore_help_classes=*/ 1);
gdb_assert (set_cmd != nullptr);
- if (set_cmd->var == nullptr)
+ if (!set_cmd->var.has_value ())
error (_("Cannot use this setting with the \"with\" command"));
std::string temp_value
@@ -245,7 +245,8 @@ with_command_1 (const char *set_cmd_prefix,
if (nested_cmd == nullptr)
nested_cmd = skip_spaces (delim + 2);
- std::string org_value = get_setshow_command_value_string (set_cmd);
+ gdb_assert (set_cmd->var.has_value ());
+ std::string org_value = get_setshow_command_value_string (*set_cmd->var);
/* Tweak the setting to the new temporary value. */
do_set_command (temp_value.c_str (), from_tty, set_cmd);
@@ -2092,31 +2093,31 @@ setting_cmd (const char *fnname, struct cmd_list_element *showlist,
/* Builds a value from the show CMD. */
static struct value *
-value_from_setting (const cmd_list_element *cmd, struct gdbarch *gdbarch)
+value_from_setting (const setting &var, struct gdbarch *gdbarch)
{
- switch (cmd->var_type)
+ switch (var.type ())
{
case var_integer:
- if (*(int *) cmd->var == INT_MAX)
+ if (var.get<int> () == INT_MAX)
return value_from_longest (builtin_type (gdbarch)->builtin_int,
0);
else
return value_from_longest (builtin_type (gdbarch)->builtin_int,
- *(int *) cmd->var);
+ var.get<int> ());
case var_zinteger:
return value_from_longest (builtin_type (gdbarch)->builtin_int,
- *(int *) cmd->var);
+ var.get<int> ());
case var_boolean:
return value_from_longest (builtin_type (gdbarch)->builtin_int,
- *(bool *) cmd->var ? 1 : 0);
+ var.get<bool> () ? 1 : 0);
case var_zuinteger_unlimited:
return value_from_longest (builtin_type (gdbarch)->builtin_int,
- *(int *) cmd->var);
+ var.get<int> ());
case var_auto_boolean:
{
int val;
- switch (*(enum auto_boolean*) cmd->var)
+ switch (var.get<enum auto_boolean> ())
{
case AUTO_BOOLEAN_TRUE:
val = 1;
@@ -2134,27 +2135,35 @@ value_from_setting (const cmd_list_element *cmd, struct gdbarch *gdbarch)
val);
}
case var_uinteger:
- if (*(unsigned int *) cmd->var == UINT_MAX)
+ if (var.get<unsigned int> () == UINT_MAX)
return value_from_ulongest
(builtin_type (gdbarch)->builtin_unsigned_int, 0);
else
return value_from_ulongest
(builtin_type (gdbarch)->builtin_unsigned_int,
- *(unsigned int *) cmd->var);
+ var.get<unsigned int> ());
case var_zuinteger:
return value_from_ulongest (builtin_type (gdbarch)->builtin_unsigned_int,
- *(unsigned int *) cmd->var);
+ var.get<unsigned int> ());
case var_string:
case var_string_noescape:
case var_optional_filename:
case var_filename:
case var_enum:
- if (*(char **) cmd->var)
- return value_cstring (*(char **) cmd->var, strlen (*(char **) cmd->var),
- builtin_type (gdbarch)->builtin_char);
- else
- return value_cstring ("", 1,
- builtin_type (gdbarch)->builtin_char);
+ {
+ const char *value;
+ if (var.type () == var_enum)
+ value = var.get<const char *> ();
+ else
+ value = var.get<char *> ();
+
+ if (value != nullptr)
+ return value_cstring (value, strlen (value),
+ builtin_type (gdbarch)->builtin_char);
+ else
+ return value_cstring ("", 1,
+ builtin_type (gdbarch)->builtin_char);
+ }
default:
gdb_assert_not_reached ("bad var_type");
}
@@ -2167,9 +2176,12 @@ gdb_setting_internal_fn (struct gdbarch *gdbarch,
const struct language_defn *language,
void *cookie, int argc, struct value **argv)
{
- return value_from_setting (setting_cmd ("$_gdb_setting", showlist,
- argc, argv),
- gdbarch);
+ cmd_list_element *show_cmd
+ = setting_cmd ("$_gdb_setting", showlist, argc, argv);
+
+ gdb_assert (show_cmd->var.has_value ());
+
+ return value_from_setting (*show_cmd->var, gdbarch);
}
/* Implementation of the convenience function $_gdb_maint_setting. */
@@ -2179,18 +2191,20 @@ gdb_maint_setting_internal_fn (struct gdbarch *gdbarch,
const struct language_defn *language,
void *cookie, int argc, struct value **argv)
{
- return value_from_setting (setting_cmd ("$_gdb_maint_setting",
- maintenance_show_cmdlist,
- argc, argv),
- gdbarch);
+ cmd_list_element *show_cmd
+ = setting_cmd ("$_gdb_maint_setting", maintenance_show_cmdlist, argc, argv);
+
+ gdb_assert (show_cmd->var.has_value ());
+
+ return value_from_setting (*show_cmd->var, gdbarch);
}
/* Builds a string value from the show CMD. */
static struct value *
-str_value_from_setting (const cmd_list_element *cmd, struct gdbarch *gdbarch)
+str_value_from_setting (const setting &var, struct gdbarch *gdbarch)
{
- switch (cmd->var_type)
+ switch (var.type ())
{
case var_integer:
case var_zinteger:
@@ -2200,7 +2214,7 @@ str_value_from_setting (const cmd_list_element *cmd, struct gdbarch *gdbarch)
case var_uinteger:
case var_zuinteger:
{
- std::string cmd_val = get_setshow_command_value_string (cmd);
+ std::string cmd_val = get_setshow_command_value_string (var);
return value_cstring (cmd_val.c_str (), cmd_val.size (),
builtin_type (gdbarch)->builtin_char);
@@ -2213,15 +2227,22 @@ str_value_from_setting (const cmd_list_element *cmd, struct gdbarch *gdbarch)
case var_enum:
/* For these cases, we do not use get_setshow_command_value_string,
as this function handle some characters specially, e.g. by
- escaping quotes. So, we directly use the cmd->var string value,
- similarly to the value_from_setting code for these cases. */
- if (*(char **) cmd->var)
- return value_cstring (*(char **) cmd->var, strlen (*(char **) cmd->var),
- builtin_type (gdbarch)->builtin_char);
- else
- return value_cstring ("", 1,
- builtin_type (gdbarch)->builtin_char);
+ escaping quotevar. So, we directly use the var string value,
+ similarly to the value_from_setting code for these casevar. */
+ {
+ const char *value;
+ if (var.type () == var_enum)
+ value = var.get<const char *> ();
+ else
+ value = var.get<char *> ();
+ if (value != nullptr)
+ return value_cstring (value, strlen (value),
+ builtin_type (gdbarch)->builtin_char);
+ else
+ return value_cstring ("", 1,
+ builtin_type (gdbarch)->builtin_char);
+ }
default:
gdb_assert_not_reached ("bad var_type");
}
@@ -2234,9 +2255,12 @@ gdb_setting_str_internal_fn (struct gdbarch *gdbarch,
const struct language_defn *language,
void *cookie, int argc, struct value **argv)
{
- return str_value_from_setting (setting_cmd ("$_gdb_setting_str",
- showlist, argc, argv),
- gdbarch);
+ cmd_list_element *show_cmd
+ = setting_cmd ("$_gdb_setting_str", showlist, argc, argv);
+
+ gdb_assert (show_cmd->var.has_value ());
+
+ return str_value_from_setting (*show_cmd->var, gdbarch);
}
@@ -2247,10 +2271,13 @@ gdb_maint_setting_str_internal_fn (struct gdbarch *gdbarch,
const struct language_defn *language,
void *cookie, int argc, struct value **argv)
{
- return str_value_from_setting (setting_cmd ("$_gdb_maint_setting_str",
- maintenance_show_cmdlist,
- argc, argv),
- gdbarch);
+ cmd_list_element *show_cmd
+ = setting_cmd ("$_gdb_maint_setting_str", maintenance_show_cmdlist, argc,
+ argv);
+
+ gdb_assert (show_cmd->var.has_value ());
+
+ return str_value_from_setting (*show_cmd->var, gdbarch);
}
void _initialize_cli_cmds ();
diff --git a/gdb/cli/cli-decode.c b/gdb/cli/cli-decode.c
index 06f3de0..56befc9 100644
--- a/gdb/cli/cli-decode.c
+++ b/gdb/cli/cli-decode.c
@@ -467,7 +467,7 @@ add_set_or_show_cmd (const char *name,
enum cmd_types type,
enum command_class theclass,
var_types var_type,
- void *var,
+ const setting::erased_args &arg,
const char *doc,
struct cmd_list_element **list)
{
@@ -475,8 +475,8 @@ add_set_or_show_cmd (const char *name,
gdb_assert (type == set_cmd || type == show_cmd);
c->type = type;
- c->var_type = var_type;
- c->var = var;
+ c->var.emplace (var_type, arg);
+
/* This needs to be something besides NULL so that this isn't
treated as a help class. */
c->func = empty_func;
@@ -493,15 +493,16 @@ add_set_or_show_cmd (const char *name,
Return the newly created set and show commands. */
static set_show_commands
-add_setshow_cmd_full (const char *name,
- enum command_class theclass,
- var_types var_type, void *var,
- const char *set_doc, const char *show_doc,
- const char *help_doc,
- cmd_func_ftype *set_func,
- show_value_ftype *show_func,
- struct cmd_list_element **set_list,
- struct cmd_list_element **show_list)
+add_setshow_cmd_full_erased (const char *name,
+ enum command_class theclass,
+ var_types var_type,
+ const setting::erased_args &args,
+ const char *set_doc, const char *show_doc,
+ const char *help_doc,
+ cmd_func_ftype *set_func,
+ show_value_ftype *show_func,
+ struct cmd_list_element **set_list,
+ struct cmd_list_element **show_list)
{
struct cmd_list_element *set;
struct cmd_list_element *show;
@@ -518,14 +519,14 @@ add_setshow_cmd_full (const char *name,
full_set_doc = xstrdup (set_doc);
full_show_doc = xstrdup (show_doc);
}
- set = add_set_or_show_cmd (name, set_cmd, theclass, var_type, var,
+ set = add_set_or_show_cmd (name, set_cmd, theclass, var_type, args,
full_set_doc, set_list);
set->doc_allocated = 1;
if (set_func != NULL)
set->func = set_func;
- show = add_set_or_show_cmd (name, show_cmd, theclass, var_type, var,
+ show = add_set_or_show_cmd (name, show_cmd, theclass, var_type, args,
full_show_doc, show_list);
show->doc_allocated = 1;
show->show_value_func = show_func;
@@ -536,6 +537,32 @@ add_setshow_cmd_full (const char *name,
return {set, show};
}
+template<typename T>
+static set_show_commands
+add_setshow_cmd_full (const char *name,
+ enum command_class theclass,
+ var_types var_type, T *var,
+ const char *set_doc, const char *show_doc,
+ const char *help_doc,
+ cmd_func_ftype *set_func,
+ show_value_ftype *show_func,
+ struct cmd_list_element **set_list,
+ struct cmd_list_element **show_list)
+{
+ auto erased_args
+ = setting::erase_args (var_type, var);
+
+ return add_setshow_cmd_full_erased (name,
+ theclass,
+ var_type, erased_args,
+ set_doc, show_doc,
+ help_doc,
+ set_func,
+ show_func,
+ set_list,
+ show_list);
+}
+
/* Add element named NAME to command list LIST (the list for set or
some sublist thereof). CLASS is as in add_cmd. ENUMLIST is a list
of strings which may follow NAME. VAR is address of the variable
@@ -555,10 +582,10 @@ add_setshow_enum_cmd (const char *name,
struct cmd_list_element **show_list)
{
set_show_commands commands
- = add_setshow_cmd_full (name, theclass, var_enum, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list);
+ = add_setshow_cmd_full<const char *> (name, theclass, var_enum, var,
+ set_doc, show_doc, help_doc,
+ set_func, show_func,
+ set_list, show_list);
commands.set->enums = enumlist;
return commands;
}
@@ -583,10 +610,11 @@ add_setshow_auto_boolean_cmd (const char *name,
struct cmd_list_element **show_list)
{
set_show_commands commands
- = add_setshow_cmd_full (name, theclass, var_auto_boolean, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list);
+ = add_setshow_cmd_full<enum auto_boolean> (name, theclass,
+ var_auto_boolean,var,
+ set_doc, show_doc, help_doc,
+ set_func, show_func,
+ set_list, show_list);
commands.set->enums = auto_boolean_enums;
@@ -612,10 +640,10 @@ add_setshow_boolean_cmd (const char *name, enum command_class theclass, bool *va
struct cmd_list_element **show_list)
{
set_show_commands commands
- = add_setshow_cmd_full (name, theclass, var_boolean, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list);
+ = add_setshow_cmd_full<bool> (name, theclass, var_boolean, var,
+ set_doc, show_doc, help_doc,
+ set_func, show_func,
+ set_list, show_list);
commands.set->enums = boolean_enums;
@@ -636,10 +664,10 @@ add_setshow_filename_cmd (const char *name, enum command_class theclass,
struct cmd_list_element **show_list)
{
set_show_commands commands
- = add_setshow_cmd_full (name, theclass, var_filename, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list);
+ = add_setshow_cmd_full<char *> (name, theclass, var_filename, var,
+ set_doc, show_doc, help_doc,
+ set_func, show_func,
+ set_list, show_list);
set_cmd_completer (commands.set, filename_completer);
@@ -660,10 +688,10 @@ add_setshow_string_cmd (const char *name, enum command_class theclass,
struct cmd_list_element **show_list)
{
set_show_commands commands
- = add_setshow_cmd_full (name, theclass, var_string, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list);
+ = add_setshow_cmd_full<char *> (name, theclass, var_string, var,
+ set_doc, show_doc, help_doc,
+ set_func, show_func,
+ set_list, show_list);
/* Disable the default symbol completer. */
set_cmd_completer (commands.set, nullptr);
@@ -685,10 +713,9 @@ add_setshow_string_noescape_cmd (const char *name, enum command_class theclass,
struct cmd_list_element **show_list)
{
set_show_commands commands
- = add_setshow_cmd_full (name, theclass, var_string_noescape, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list);
+ = add_setshow_cmd_full<char *> (name, theclass, var_string_noescape, var,
+ set_doc, show_doc, help_doc, set_func,
+ show_func, set_list, show_list);
/* Disable the default symbol completer. */
set_cmd_completer (commands.set, nullptr);
@@ -710,11 +737,10 @@ add_setshow_optional_filename_cmd (const char *name, enum command_class theclass
struct cmd_list_element **show_list)
{
set_show_commands commands
- = add_setshow_cmd_full (name, theclass, var_optional_filename, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list);
-
+ = add_setshow_cmd_full<char *> (name, theclass, var_optional_filename,
+ var, set_doc, show_doc, help_doc,
+ set_func, show_func, set_list, show_list);
+
set_cmd_completer (commands.set, filename_completer);
return commands;
@@ -754,10 +780,9 @@ add_setshow_integer_cmd (const char *name, enum command_class theclass,
struct cmd_list_element **show_list)
{
set_show_commands commands
- = add_setshow_cmd_full (name, theclass, var_integer, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list);
+ = add_setshow_cmd_full<int> (name, theclass, var_integer, var, set_doc,
+ show_doc, help_doc, set_func, show_func,
+ set_list, show_list);
set_cmd_completer (commands.set, integer_unlimited_completer);
@@ -780,10 +805,10 @@ add_setshow_uinteger_cmd (const char *name, enum command_class theclass,
struct cmd_list_element **show_list)
{
set_show_commands commands
- = add_setshow_cmd_full (name, theclass, var_uinteger, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list);
+ = add_setshow_cmd_full<unsigned int> (name, theclass, var_uinteger, var,
+ set_doc, show_doc, help_doc,
+ set_func, show_func,
+ set_list, show_list);
set_cmd_completer (commands.set, integer_unlimited_completer);
@@ -805,10 +830,10 @@ add_setshow_zinteger_cmd (const char *name, enum command_class theclass,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
- return add_setshow_cmd_full (name, theclass, var_zinteger, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list);
+ return add_setshow_cmd_full<int> (name, theclass, var_zinteger, var,
+ set_doc, show_doc, help_doc,
+ set_func, show_func,
+ set_list, show_list);
}
set_show_commands
@@ -824,10 +849,9 @@ add_setshow_zuinteger_unlimited_cmd (const char *name,
struct cmd_list_element **show_list)
{
set_show_commands commands
- = add_setshow_cmd_full (name, theclass, var_zuinteger_unlimited, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list);
+ = add_setshow_cmd_full<int> (name, theclass, var_zuinteger_unlimited, var,
+ set_doc, show_doc, help_doc, set_func,
+ show_func, set_list, show_list);
set_cmd_completer (commands.set, integer_unlimited_completer);
@@ -849,10 +873,10 @@ add_setshow_zuinteger_cmd (const char *name, enum command_class theclass,
struct cmd_list_element **set_list,
struct cmd_list_element **show_list)
{
- return add_setshow_cmd_full (name, theclass, var_zuinteger, var,
- set_doc, show_doc, help_doc,
- set_func, show_func,
- set_list, show_list);
+ return add_setshow_cmd_full<unsigned int> (name, theclass, var_zuinteger,
+ var, set_doc, show_doc, help_doc,
+ set_func, show_func, set_list,
+ show_list);
}
/* Remove the command named NAME from the command list. Return the
diff --git a/gdb/cli/cli-decode.h b/gdb/cli/cli-decode.h
index 651d1ef..f7945ba 100644
--- a/gdb/cli/cli-decode.h
+++ b/gdb/cli/cli-decode.h
@@ -55,7 +55,6 @@ struct cmd_list_element
allow_unknown (0),
abbrev_flag (0),
type (not_set_cmd),
- var_type (var_boolean),
doc (doc_)
{
memset (&function, 0, sizeof (function));
@@ -160,9 +159,6 @@ struct cmd_list_element
or "show"). */
ENUM_BITFIELD (cmd_types) type : 2;
- /* What kind of variable is *VAR? */
- ENUM_BITFIELD (var_types) var_type : 4;
-
/* Function definition of this command. NULL for command class
names and for help topics that are not really commands. NOTE:
cagney/2002-02-02: This function signature is evolving. For
@@ -228,9 +224,8 @@ struct cmd_list_element
used to finalize the CONTEXT field, if needed. */
void (*destroyer) (struct cmd_list_element *self, void *context) = nullptr;
- /* Pointer to variable affected by "set" and "show". Doesn't
- matter if type is not_set. */
- void *var = nullptr;
+ /* Setting affected by "set" and "show". Not used if type is not_set_cmd. */
+ gdb::optional<setting> var;
/* Pointer to NULL terminated list of enumerated values (like
argv). */
diff --git a/gdb/cli/cli-setshow.c b/gdb/cli/cli-setshow.c
index 1025ed2..86ab553 100644
--- a/gdb/cli/cli-setshow.c
+++ b/gdb/cli/cli-setshow.c
@@ -130,10 +130,14 @@ deprecated_show_value_hack (struct ui_file *ignore_file,
/* If there's no command or value, don't try to print it out. */
if (c == NULL || value == NULL)
return;
+
/* Print doc minus "Show " at start. Tell print_doc_line that
this is for a 'show value' prefix. */
print_doc_line (gdb_stdout, c->doc + 5, true);
- switch (c->var_type)
+
+ gdb_assert (c->var.has_value ());
+
+ switch (c->var->type ())
{
case var_string:
case var_string_noescape:
@@ -142,6 +146,7 @@ deprecated_show_value_hack (struct ui_file *ignore_file,
case var_enum:
printf_filtered ((" is \"%s\".\n"), value);
break;
+
default:
printf_filtered ((" is %s.\n"), value);
break;
@@ -312,7 +317,9 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
if (arg == NULL)
arg = "";
- switch (c->var_type)
+ gdb_assert (c->var.has_value ());
+
+ switch (c->var->type ())
{
case var_string:
{
@@ -353,11 +360,12 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
*q++ = '\0';
newobj = (char *) xrealloc (newobj, q - newobj);
- if (*(char **) c->var == NULL
- || strcmp (*(char **) c->var, newobj) != 0)
+ char * const var = c->var->get<char *> ();
+ if (var == nullptr
+ || strcmp (var, newobj) != 0)
{
- xfree (*(char **) c->var);
- *(char **) c->var = newobj;
+ xfree (var);
+ c->var->set<char *> (newobj);
option_changed = true;
}
@@ -366,13 +374,17 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
}
break;
case var_string_noescape:
- if (*(char **) c->var == NULL || strcmp (*(char **) c->var, arg) != 0)
- {
- xfree (*(char **) c->var);
- *(char **) c->var = xstrdup (arg);
+ {
+ char * const var = c->var->get<char *> ();
+ if (var == nullptr
+ || strcmp (var, arg) != 0)
+ {
+ xfree (var);
+ c->var->set<char *> (xstrdup (arg));
- option_changed = true;
- }
+ option_changed = true;
+ }
+ }
break;
case var_filename:
if (*arg == '\0')
@@ -398,11 +410,12 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
else
val = xstrdup ("");
- if (*(char **) c->var == NULL
- || strcmp (*(char **) c->var, val) != 0)
+ char * const var = c->var->get<char *> ();
+ if (var == nullptr
+ || strcmp (var, val) != 0)
{
- xfree (*(char **) c->var);
- *(char **) c->var = val;
+ xfree (var);
+ c->var->set<char *> (val);
option_changed = true;
}
@@ -416,9 +429,9 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
if (val < 0)
error (_("\"on\" or \"off\" expected."));
- if (val != *(bool *) c->var)
+ if (val != c->var->get<bool> ())
{
- *(bool *) c->var = val;
+ c->var->set<bool> (val);
option_changed = true;
}
@@ -428,9 +441,9 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
{
enum auto_boolean val = parse_auto_binary_operation (arg);
- if (*(enum auto_boolean *) c->var != val)
+ if (c->var->get<enum auto_boolean> () != val)
{
- *(enum auto_boolean *) c->var = val;
+ c->var->set<enum auto_boolean> (val);
option_changed = true;
}
@@ -439,11 +452,12 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
case var_uinteger:
case var_zuinteger:
{
- unsigned int val = parse_cli_var_uinteger (c->var_type, &arg, true);
+ unsigned int val
+ = parse_cli_var_uinteger (c->var->type (), &arg, true);
- if (*(unsigned int *) c->var != val)
+ if (c->var->get<unsigned int> () != val)
{
- *(unsigned int *) c->var = val;
+ c->var->set<unsigned int> (val);
option_changed = true;
}
@@ -456,35 +470,35 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
if (*arg == '\0')
{
- if (c->var_type == var_integer)
+ if (c->var->type () == var_integer)
error_no_arg (_("integer to set it to, or \"unlimited\"."));
else
error_no_arg (_("integer to set it to."));
}
- if (c->var_type == var_integer && is_unlimited_literal (&arg, true))
+ if (c->var->type () == var_integer && is_unlimited_literal (&arg, true))
val = 0;
else
val = parse_and_eval_long (arg);
- if (val == 0 && c->var_type == var_integer)
+ 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))
+ || (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)
+ if (c->var->get<int> () != val)
{
- *(int *) c->var = val;
+ c->var->set<int> (val);
option_changed = true;
}
- break;
}
+ break;
case var_enum:
{
const char *end_arg = arg;
@@ -495,9 +509,9 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
if (*after != '\0')
error (_("Junk after item \"%.*s\": %s"), len, arg, after);
- if (*(const char **) c->var != match)
+ if (c->var->get<const char *> () != match)
{
- *(const char **) c->var = match;
+ c->var->set<const char *> (match);
option_changed = true;
}
@@ -507,9 +521,9 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
{
int val = parse_cli_var_zuinteger_unlimited (&arg, true);
- if (*(int *) c->var != val)
+ if (c->var->get<int> () != val)
{
- *(int *) c->var = val;
+ c->var->set<int> (val);
option_changed = true;
}
}
@@ -578,25 +592,33 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
xfree (cmds);
- switch (c->var_type)
+ switch (c->var->type ())
{
case var_string:
case var_string_noescape:
case var_filename:
case var_optional_filename:
case var_enum:
- gdb::observers::command_param_changed.notify (name, *(char **) c->var);
+ {
+ const char *var;
+ if (c->var->type () == var_enum)
+ var = c->var->get<const char *> ();
+ else
+ var = c->var->get<char *> ();
+ gdb::observers::command_param_changed.notify (name, var);
+ }
break;
case var_boolean:
{
- const char *opt = *(bool *) c->var ? "on" : "off";
+ const char *opt = c->var->get<bool> () ? "on" : "off";
gdb::observers::command_param_changed.notify (name, opt);
}
break;
case var_auto_boolean:
{
- const char *s = auto_boolean_enums[*(enum auto_boolean *) c->var];
+ const char *s
+ = auto_boolean_enums[c->var->get<enum auto_boolean> ()];
gdb::observers::command_param_changed.notify (name, s);
}
@@ -606,7 +628,7 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
{
char s[64];
- xsnprintf (s, sizeof s, "%u", *(unsigned int *) c->var);
+ xsnprintf (s, sizeof s, "%u", c->var->get<unsigned int> ());
gdb::observers::command_param_changed.notify (name, s);
}
break;
@@ -616,7 +638,7 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
{
char s[64];
- xsnprintf (s, sizeof s, "%d", *(int *) c->var);
+ xsnprintf (s, sizeof s, "%d", c->var->get<int> ());
gdb::observers::command_param_changed.notify (name, s);
}
break;
@@ -628,28 +650,40 @@ do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
/* See cli/cli-setshow.h. */
std::string
-get_setshow_command_value_string (const cmd_list_element *c)
+get_setshow_command_value_string (const setting &var)
{
string_file stb;
- switch (c->var_type)
+ switch (var.type ())
{
case var_string:
- if (*(char **) c->var)
- stb.putstr (*(char **) c->var, '"');
+ {
+ char *value = var.get<char *> ();
+
+ if (value != nullptr)
+ stb.putstr (value, '"');
+ }
break;
case var_string_noescape:
case var_optional_filename:
case var_filename:
case var_enum:
- if (*(char **) c->var)
- stb.puts (*(char **) c->var);
+ {
+ const char *value;
+ if (var.type () == var_enum)
+ value = var.get<const char *> ();
+ else
+ value = var.get<char *> ();
+
+ if (value != nullptr)
+ stb.puts (value);
+ }
break;
case var_boolean:
- stb.puts (*(bool *) c->var ? "on" : "off");
+ stb.puts (var.get<bool> () ? "on" : "off");
break;
case var_auto_boolean:
- switch (*(enum auto_boolean*) c->var)
+ switch (var.get<enum auto_boolean> ())
{
case AUTO_BOOLEAN_TRUE:
stb.puts ("on");
@@ -667,26 +701,35 @@ get_setshow_command_value_string (const cmd_list_element *c)
break;
case var_uinteger:
case var_zuinteger:
- if (c->var_type == var_uinteger
- && *(unsigned int *) c->var == UINT_MAX)
- stb.puts ("unlimited");
- else
- stb.printf ("%u", *(unsigned int *) c->var);
+ {
+ const unsigned int value = var.get<unsigned int> ();
+
+ if (var.type () == var_uinteger
+ && value == UINT_MAX)
+ stb.puts ("unlimited");
+ else
+ stb.printf ("%u", value);
+ }
break;
case var_integer:
case var_zinteger:
- if (c->var_type == var_integer
- && *(int *) c->var == INT_MAX)
- stb.puts ("unlimited");
- else
- stb.printf ("%d", *(int *) c->var);
+ {
+ const int value = var.get<int> ();
+
+ if (var.type () == var_integer
+ && value == INT_MAX)
+ stb.puts ("unlimited");
+ else
+ stb.printf ("%d", value);
+ }
break;
case var_zuinteger_unlimited:
{
- if (*(int *) c->var == -1)
+ const int value = var.get<int> ();
+ if (value == -1)
stb.puts ("unlimited");
else
- stb.printf ("%d", *(int *) c->var);
+ stb.printf ("%d", value);
}
break;
default:
@@ -708,8 +751,9 @@ do_show_command (const char *arg, int from_tty, struct cmd_list_element *c)
struct ui_out *uiout = current_uiout;
gdb_assert (c->type == show_cmd);
+ gdb_assert (c->var.has_value ());
- std::string val = get_setshow_command_value_string (c);
+ std::string val = get_setshow_command_value_string (*c->var);
/* FIXME: cagney/2005-02-10: There should be MI and CLI specific
versions of code to print the value out. */
diff --git a/gdb/cli/cli-setshow.h b/gdb/cli/cli-setshow.h
index 05f11b1..5a8f321 100644
--- a/gdb/cli/cli-setshow.h
+++ b/gdb/cli/cli-setshow.h
@@ -57,8 +57,8 @@ extern void do_set_command (const char *arg, int from_tty,
extern void do_show_command (const char *arg, int from_tty,
struct cmd_list_element *c);
-/* Get a string version of C's current value. */
-extern std::string get_setshow_command_value_string (const cmd_list_element *c);
+/* Get a string version of VAR's value. */
+extern std::string get_setshow_command_value_string (const setting &var);
extern void cmd_show_list (struct cmd_list_element *list, int from_tty);
diff --git a/gdb/command.h b/gdb/command.h
index baf3440..e7b8110 100644
--- a/gdb/command.h
+++ b/gdb/command.h
@@ -125,6 +125,149 @@ typedef enum var_types
}
var_types;
+/* Return true if a setting of type VAR_TYPE is backed with type T.
+
+ This function is left without definition intentionally. This template is
+ specialized for all valid types that are used to back var_types. Therefore
+ if one tries to instantiate this un-specialized template it means the T
+ parameter is not a type used to back a var_type and it is most likely a
+ programming error. */
+template<typename T>
+bool var_type_uses (var_types var_type) = delete;
+
+/* Return true if a setting of type T is backed by a bool variable. */
+template<>
+inline bool var_type_uses<bool> (var_types t)
+{
+ return t == var_boolean;
+};
+
+/* Return true if a setting of type T is backed by a auto_boolean variable.
+*/
+template<>
+inline bool var_type_uses<enum auto_boolean> (var_types t)
+{
+ return t == var_auto_boolean;
+}
+
+/* Return true if a setting of type T is backed by an unsigned int variable.
+*/
+template<>
+inline bool var_type_uses<unsigned int> (var_types t)
+{
+ return (t == var_uinteger || t == var_zinteger || t == var_zuinteger);
+}
+
+/* Return true if a setting of type T is backed by an int variable. */
+template<>
+inline bool var_type_uses<int> (var_types t)
+{
+ return (t == var_integer || t == var_zinteger
+ || t == var_zuinteger_unlimited);
+}
+
+/* Return true if a setting of type T is backed by a char * variable. */
+template<>
+inline bool var_type_uses<char *> (var_types t)
+{
+ return (t == var_string || t == var_string_noescape
+ || t == var_optional_filename || t == var_filename);
+}
+
+/* Return true if a setting of type T is backed by a const char * variable.
+*/
+template<>
+inline bool var_type_uses<const char *> (var_types t)
+{
+ return t == var_enum;
+}
+
+/* Interface for getting and setting a setting's value.
+
+ The underlying data can be of any VAR_TYPES type. */
+struct setting
+{
+ /* Create a setting backed by a variable of type T.
+
+ Type T must match the var type VAR_TYPE (see VAR_TYPE_USES). */
+ template<typename T>
+ setting (var_types var_type, T *var)
+ : m_var_type (var_type), m_var (var)
+ {
+ gdb_assert (var != nullptr);
+ gdb_assert (var_type_uses<T> (var_type));
+ }
+
+ /* A setting can also be constructed with a pre-validated
+ type-erased variable. Use the following function to
+ validate & type-erase said variable/function pointers. */
+
+ struct erased_args
+ {
+ void *var;
+ };
+
+ template<typename T>
+ static erased_args erase_args (var_types var_type, T *var)
+ {
+ gdb_assert (var_type_uses<T> (var_type));
+
+ return {var};
+ }
+
+ /* Create a setting backed by pre-validated type-erased args.
+ ERASED_VAR's fields' real types must match the var type VAR_TYPE
+ (see VAR_TYPE_USES). */
+ setting (var_types var_type, const erased_args &args)
+ : m_var_type (var_type),
+ m_var (args.var)
+ {
+ }
+
+ /* Access the type of the current setting. */
+ var_types type () const
+ {
+ return m_var_type;
+ }
+
+ /* Return the current value.
+
+ The template parameter T is the type of the variable used to store the
+ setting. */
+ template<typename T>
+ const T &get () const
+ {
+ gdb_assert (var_type_uses<T> (m_var_type));
+ gdb_assert (m_var != nullptr);
+
+ return *static_cast<const T *> (m_var);
+ }
+
+ /* Sets the value of the setting to V.
+
+ The template parameter T indicates the type of the variable used to
+ store the setting.
+
+ The var_type of the setting must match T. */
+ template<typename T>
+ void set (const T &v)
+ {
+ /* Check that the current instance is of one of the supported types for
+ this instantiation. */
+ gdb_assert (var_type_uses<T> (m_var_type));
+
+ *static_cast<T *> (m_var) = v;
+ }
+
+private:
+ /* The type of the variable M_VAR is pointing to. */
+ var_types m_var_type;
+
+ /* Pointer to the enclosed variable. The type of the variable is encoded
+ in M_VAR_TYPE. */
+ void *m_var;
+};
+
/* This structure records one command'd definition. */
struct cmd_list_element;
diff --git a/gdb/guile/scm-param.c b/gdb/guile/scm-param.c
index 44ea167..0ae368a 100644
--- a/gdb/guile/scm-param.c
+++ b/gdb/guile/scm-param.c
@@ -113,6 +113,30 @@ struct param_smob
SCM containing_scm;
};
+/* Wraps a setting around an existing param_smob. This abstraction
+ is used to manipulate the value in S->VALUE in a type safe manner using
+ the setting interface. */
+
+static setting
+make_setting (param_smob *s)
+{
+
+ if (var_type_uses<bool> (s->type))
+ return setting (s->type, &s->value.boolval);
+ else if (var_type_uses<int> (s->type))
+ return setting (s->type, &s->value.intval);
+ else if (var_type_uses<auto_boolean> (s->type))
+ return setting (s->type, &s->value.autoboolval);
+ else if (var_type_uses<unsigned int> (s->type))
+ return setting (s->type, &s->value.uintval);
+ else if (var_type_uses<char *> (s->type))
+ return setting (s->type, &s->value.stringval);
+ else if (var_type_uses<const char *> (s->type))
+ return setting (s->type, &s->value.cstringval);
+ else
+ gdb_assert_not_reached ("unhandled var type");
+}
+
static const char param_smob_name[] = "gdb:parameter";
/* The tag Guile knows the param smob by. */
@@ -133,8 +157,8 @@ static SCM unlimited_keyword;
static int pascm_is_valid (param_smob *);
static const char *pascm_param_type_name (enum var_types type);
-static SCM pascm_param_value (enum var_types type, void *var,
- int arg_pos, const char *func_name);
+static SCM pascm_param_value (const setting &var, int arg_pos,
+ const char *func_name);
/* Administrivia for parameter smobs. */
@@ -153,8 +177,7 @@ pascm_print_param_smob (SCM self, SCM port, scm_print_state *pstate)
gdbscm_printf (port, " %s ", pascm_param_type_name (p_smob->type));
- value = pascm_param_value (p_smob->type, &p_smob->value,
- GDBSCM_ARG_NONE, NULL);
+ value = pascm_param_value (make_setting (p_smob), GDBSCM_ARG_NONE, NULL);
scm_display (value, port);
scm_puts (">", port);
@@ -444,7 +467,7 @@ add_setshow_generic (enum var_types param_type, enum command_class cmd_class,
show_doc, help_doc, set_func, show_func,
set_list, show_list);
/* Initialize the value, just in case. */
- self->value.cstringval = self->enumeration[0];
+ make_setting (self).set<const char *> (self->enumeration[0]);
break;
default:
@@ -563,17 +586,17 @@ pascm_param_type_name (enum var_types param_type)
}
/* Return the value of a gdb parameter as a Scheme value.
- If TYPE is not supported, then a <gdb:exception> object is returned. */
+ If the var_type of VAR is not supported, then a <gdb:exception> object is
+ returned. */
static SCM
-pascm_param_value (enum var_types type, void *var,
- int arg_pos, const char *func_name)
+pascm_param_value (const setting &var, int arg_pos, const char *func_name)
{
/* Note: We *could* support var_integer here in case someone is trying to get
the value of a Python-created parameter (which is the only place that
still supports var_integer). To further discourage its use we do not. */
- switch (type)
+ switch (var.type ())
{
case var_string:
case var_string_noescape:
@@ -581,16 +604,20 @@ pascm_param_value (enum var_types type, void *var,
case var_filename:
case var_enum:
{
- const char *str = *(char **) var;
+ const char *str;
+ if (var.type () == var_enum)
+ str = var.get<const char *> ();
+ else
+ str = var.get<char *> ();
- if (str == NULL)
+ if (str == nullptr)
str = "";
return gdbscm_scm_from_host_string (str, strlen (str));
}
case var_boolean:
{
- if (* (bool *) var)
+ if (var.get<bool> ())
return SCM_BOOL_T;
else
return SCM_BOOL_F;
@@ -598,7 +625,7 @@ pascm_param_value (enum var_types type, void *var,
case var_auto_boolean:
{
- enum auto_boolean ab = * (enum auto_boolean *) var;
+ enum auto_boolean ab = var.get<enum auto_boolean> ();
if (ab == AUTO_BOOLEAN_TRUE)
return SCM_BOOL_T;
@@ -609,67 +636,69 @@ pascm_param_value (enum var_types type, void *var,
}
case var_zuinteger_unlimited:
- if (* (int *) var == -1)
+ if (var.get<int> () == -1)
return unlimited_keyword;
- gdb_assert (* (int *) var >= 0);
+ gdb_assert (var.get<int> () >= 0);
/* Fall through. */
case var_zinteger:
- return scm_from_int (* (int *) var);
+ return scm_from_int (var.get<int> ());
case var_uinteger:
- if (* (unsigned int *) var == UINT_MAX)
+ if (var.get<unsigned int> ()== UINT_MAX)
return unlimited_keyword;
/* Fall through. */
case var_zuinteger:
- return scm_from_uint (* (unsigned int *) var);
+ return scm_from_uint (var.get<unsigned int> ());
default:
break;
}
return gdbscm_make_out_of_range_error (func_name, arg_pos,
- scm_from_int (type),
+ scm_from_int (var.type ()),
_("program error: unhandled type"));
}
-/* Set the value of a parameter of type TYPE in VAR from VALUE.
+/* Set the value of a parameter of type P_SMOB->TYPE in P_SMOB->VAR from VALUE.
ENUMERATION is the list of enum values for enum parameters, otherwise NULL.
Throws a Scheme exception if VALUE_SCM is invalid for TYPE. */
static void
-pascm_set_param_value_x (enum var_types type, union pascm_variable *var,
+pascm_set_param_value_x (param_smob *p_smob,
const char * const *enumeration,
SCM value, int arg_pos, const char *func_name)
{
- switch (type)
+ setting var = make_setting (p_smob);
+
+ switch (var.type ())
{
case var_string:
case var_string_noescape:
case var_optional_filename:
case var_filename:
SCM_ASSERT_TYPE (scm_is_string (value)
- || (type != var_filename
+ || (var.type () != var_filename
&& gdbscm_is_false (value)),
value, arg_pos, func_name,
_("string or #f for non-PARAM_FILENAME parameters"));
if (gdbscm_is_false (value))
{
- xfree (var->stringval);
- if (type == var_optional_filename)
- var->stringval = xstrdup ("");
+ xfree (var.get<char *> ());
+ if (var.type () == var_optional_filename)
+ var.set<char *> (xstrdup (""));
else
- var->stringval = NULL;
+ var.set<char *> (nullptr);
}
else
{
SCM exception;
gdb::unique_xmalloc_ptr<char> string
- = gdbscm_scm_to_host_string (value, NULL, &exception);
- if (string == NULL)
+ = gdbscm_scm_to_host_string (value, nullptr, &exception);
+ if (string == nullptr)
gdbscm_throw (exception);
- xfree (var->stringval);
- var->stringval = string.release ();
+ xfree (var.get<char *> ());
+ var.set<char *> (string.release ());
}
break;
@@ -681,27 +710,27 @@ pascm_set_param_value_x (enum var_types type, union pascm_variable *var,
SCM_ASSERT_TYPE (scm_is_string (value), value, arg_pos, func_name,
_("string"));
gdb::unique_xmalloc_ptr<char> str
- = gdbscm_scm_to_host_string (value, NULL, &exception);
- if (str == NULL)
+ = gdbscm_scm_to_host_string (value, nullptr, &exception);
+ if (str == nullptr)
gdbscm_throw (exception);
for (i = 0; enumeration[i]; ++i)
{
if (strcmp (enumeration[i], str.get ()) == 0)
break;
}
- if (enumeration[i] == NULL)
+ if (enumeration[i] == nullptr)
{
gdbscm_out_of_range_error (func_name, arg_pos, value,
_("not member of enumeration"));
}
- var->cstringval = enumeration[i];
+ var.set<const char *> (enumeration[i]);
break;
}
case var_boolean:
SCM_ASSERT_TYPE (gdbscm_is_bool (value), value, arg_pos, func_name,
_("boolean"));
- var->boolval = gdbscm_is_true (value);
+ var.set<bool> (gdbscm_is_true (value));
break;
case var_auto_boolean:
@@ -710,19 +739,19 @@ pascm_set_param_value_x (enum var_types type, union pascm_variable *var,
value, arg_pos, func_name,
_("boolean or #:auto"));
if (scm_is_eq (value, auto_keyword))
- var->autoboolval = AUTO_BOOLEAN_AUTO;
+ var.set<enum auto_boolean> (AUTO_BOOLEAN_AUTO);
else if (gdbscm_is_true (value))
- var->autoboolval = AUTO_BOOLEAN_TRUE;
+ var.set<enum auto_boolean> (AUTO_BOOLEAN_TRUE);
else
- var->autoboolval = AUTO_BOOLEAN_FALSE;
+ var.set<enum auto_boolean> (AUTO_BOOLEAN_FALSE);
break;
case var_zinteger:
case var_uinteger:
case var_zuinteger:
case var_zuinteger_unlimited:
- if (type == var_uinteger
- || type == var_zuinteger_unlimited)
+ if (var.type () == var_uinteger
+ || var.type () == var_zuinteger_unlimited)
{
SCM_ASSERT_TYPE (gdbscm_is_bool (value)
|| scm_is_eq (value, unlimited_keyword),
@@ -730,10 +759,10 @@ pascm_set_param_value_x (enum var_types type, union pascm_variable *var,
_("integer or #:unlimited"));
if (scm_is_eq (value, unlimited_keyword))
{
- if (type == var_uinteger)
- var->intval = UINT_MAX;
+ if (var.type () == var_uinteger)
+ var.set<unsigned int> (UINT_MAX);
else
- var->intval = -1;
+ var.set<int> (-1);
break;
}
}
@@ -743,25 +772,25 @@ pascm_set_param_value_x (enum var_types type, union pascm_variable *var,
_("integer"));
}
- if (type == var_uinteger
- || type == var_zuinteger)
+ if (var.type () == var_uinteger
+ || var.type () == var_zuinteger)
{
unsigned int u = scm_to_uint (value);
- if (type == var_uinteger && u == 0)
+ if (var.type () == var_uinteger && u == 0)
u = UINT_MAX;
- var->uintval = u;
+ var.set<unsigned int> (u);
}
else
{
int i = scm_to_int (value);
- if (type == var_zuinteger_unlimited && i < -1)
+ if (var.type () == var_zuinteger_unlimited && i < -1)
{
gdbscm_out_of_range_error (func_name, arg_pos, value,
_("must be >= -1"));
}
- var->intval = i;
+ var.set<int> (i);
}
break;
@@ -934,7 +963,7 @@ gdbscm_make_parameter (SCM name_scm, SCM rest)
if (gdbscm_is_exception (initial_value_scm))
gdbscm_throw (initial_value_scm);
}
- pascm_set_param_value_x (p_smob->type, &p_smob->value, enum_list,
+ pascm_set_param_value_x (p_smob, enum_list,
initial_value_scm,
initial_value_arg_pos, FUNC_NAME);
}
@@ -1030,8 +1059,7 @@ gdbscm_parameter_value (SCM self)
param_smob *p_smob = pascm_get_param_smob_arg_unsafe (self, SCM_ARG1,
FUNC_NAME);
- return pascm_param_value (p_smob->type, &p_smob->value,
- SCM_ARG1, FUNC_NAME);
+ return pascm_param_value (make_setting (p_smob), SCM_ARG1, FUNC_NAME);
}
else
{
@@ -1062,13 +1090,14 @@ gdbscm_parameter_value (SCM self)
gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
_("parameter not found"));
}
- if (cmd->var == NULL)
+
+ if (!cmd->var.has_value ())
{
gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
_("not a parameter"));
}
- return pascm_param_value (cmd->var_type, cmd->var, SCM_ARG1, FUNC_NAME);
+ return pascm_param_value (*cmd->var, SCM_ARG1, FUNC_NAME);
}
}
@@ -1080,7 +1109,7 @@ gdbscm_set_parameter_value_x (SCM self, SCM value)
param_smob *p_smob = pascm_get_param_smob_arg_unsafe (self, SCM_ARG1,
FUNC_NAME);
- pascm_set_param_value_x (p_smob->type, &p_smob->value, p_smob->enumeration,
+ pascm_set_param_value_x (p_smob, p_smob->enumeration,
value, SCM_ARG2, FUNC_NAME);
return SCM_UNSPECIFIED;
diff --git a/gdb/maint.c b/gdb/maint.c
index c6d13a3..8aae53b 100644
--- a/gdb/maint.c
+++ b/gdb/maint.c
@@ -1112,7 +1112,7 @@ set_per_command_cmd (const char *args, int from_tty)
error (_("Bad value for 'mt set per-command no'."));
for (list = per_command_setlist; list != NULL; list = list->next)
- if (list->var_type == var_boolean)
+ if (list->var->type () == var_boolean)
{
gdb_assert (list->type == set_cmd);
do_set_command (args, from_tty, list);
diff --git a/gdb/python/py-param.c b/gdb/python/py-param.c
index f9dcb07..1dd716b 100644
--- a/gdb/python/py-param.c
+++ b/gdb/python/py-param.c
@@ -88,6 +88,30 @@ struct parmpy_object
const char **enumeration;
};
+/* Wraps a setting around an existing parmpy_object. This abstraction
+ is used to manipulate the value in S->VALUE in a type safe manner using
+ the setting interface. */
+
+static setting
+make_setting (parmpy_object *s)
+{
+
+ if (var_type_uses<bool> (s->type))
+ return setting (s->type, &s->value.boolval);
+ else if (var_type_uses<int> (s->type))
+ return setting (s->type, &s->value.intval);
+ else if (var_type_uses<auto_boolean> (s->type))
+ return setting (s->type, &s->value.autoboolval);
+ else if (var_type_uses<unsigned int> (s->type))
+ return setting (s->type, &s->value.uintval);
+ else if (var_type_uses<char *> (s->type))
+ return setting (s->type, &s->value.stringval);
+ else if (var_type_uses<const char *> (s->type))
+ return setting (s->type, &s->value.cstringval);
+ else
+ gdb_assert_not_reached ("unhandled var type");
+}
+
extern PyTypeObject parmpy_object_type
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("parmpy_object");
@@ -110,7 +134,7 @@ get_attr (PyObject *obj, PyObject *attr_name)
{
parmpy_object *self = (parmpy_object *) obj;
- return gdbpy_parameter_value (self->type, &self->value);
+ return gdbpy_parameter_value (make_setting (self));
}
return PyObject_GenericGetAttr (obj, attr_name);
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 368681b..022d4a6 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -438,7 +438,7 @@ PyObject *gdbpy_create_ptid_object (ptid_t ptid);
PyObject *gdbpy_selected_thread (PyObject *self, PyObject *args);
PyObject *gdbpy_selected_inferior (PyObject *self, PyObject *args);
PyObject *gdbpy_string_to_argv (PyObject *self, PyObject *args);
-PyObject *gdbpy_parameter_value (enum var_types type, void *var);
+PyObject *gdbpy_parameter_value (const setting &var);
gdb::unique_xmalloc_ptr<char> gdbpy_parse_command_name
(const char *name, struct cmd_list_element ***base_list,
struct cmd_list_element **start_list);
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 37eacef..a26c373 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -449,9 +449,9 @@ python_command (const char *arg, int from_tty)
NULL (and set a Python exception) on error. Helper function for
get_parameter. */
PyObject *
-gdbpy_parameter_value (enum var_types type, void *var)
+gdbpy_parameter_value (const setting &var)
{
- switch (type)
+ switch (var.type ())
{
case var_string:
case var_string_noescape:
@@ -459,16 +459,20 @@ gdbpy_parameter_value (enum var_types type, void *var)
case var_filename:
case var_enum:
{
- const char *str = *(char **) var;
+ const char *str;
+ if (var.type () == var_enum)
+ str = var.get<const char *> ();
+ else
+ str = var.get<char *> ();
- if (! str)
+ if (str == nullptr)
str = "";
return host_string_to_python_string (str).release ();
}
case var_boolean:
{
- if (* (bool *) var)
+ if (var.get<bool> ())
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
@@ -476,7 +480,7 @@ gdbpy_parameter_value (enum var_types type, void *var)
case var_auto_boolean:
{
- enum auto_boolean ab = * (enum auto_boolean *) var;
+ enum auto_boolean ab = var.get<enum auto_boolean> ();
if (ab == AUTO_BOOLEAN_TRUE)
Py_RETURN_TRUE;
@@ -487,16 +491,16 @@ gdbpy_parameter_value (enum var_types type, void *var)
}
case var_integer:
- if ((* (int *) var) == INT_MAX)
+ if (var.get<int> () == INT_MAX)
Py_RETURN_NONE;
/* Fall through. */
case var_zinteger:
case var_zuinteger_unlimited:
- return gdb_py_object_from_longest (* (int *) var).release ();
+ return gdb_py_object_from_longest (var.get<int> ()).release ();
case var_uinteger:
{
- unsigned int val = * (unsigned int *) var;
+ unsigned int val = var.get<unsigned int> ();
if (val == UINT_MAX)
Py_RETURN_NONE;
@@ -505,7 +509,7 @@ gdbpy_parameter_value (enum var_types type, void *var)
case var_zuinteger:
{
- unsigned int val = * (unsigned int *) var;
+ unsigned int val = var.get<unsigned int> ();
return gdb_py_object_from_ulongest (val).release ();
}
}
@@ -542,10 +546,11 @@ gdbpy_parameter (PyObject *self, PyObject *args)
return PyErr_Format (PyExc_RuntimeError,
_("Could not find parameter `%s'."), arg);
- if (! cmd->var)
+ if (!cmd->var.has_value ())
return PyErr_Format (PyExc_RuntimeError,
_("`%s' is not a parameter."), arg);
- return gdbpy_parameter_value (cmd->var_type, cmd->var);
+
+ return gdbpy_parameter_value (*cmd->var);
}
/* Wrapper for target_charset. */
diff --git a/gdb/remote.c b/gdb/remote.c
index c4a31e0..29b18c9 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -2239,12 +2239,13 @@ show_remote_protocol_packet_cmd (struct ui_file *file, int from_tty,
const char *value)
{
struct packet_config *packet;
+ gdb_assert (c->var.has_value ());
for (packet = remote_protocol_packets;
packet < &remote_protocol_packets[PACKET_MAX];
packet++)
{
- if (&packet->detect == c->var)
+ if (&packet->detect == &c->var->get<enum auto_boolean> ())
{
show_packet_config_cmd (packet);
return;