diff options
Diffstat (limited to 'gdb/guile/scm-param.c')
-rw-r--r-- | gdb/guile/scm-param.c | 141 |
1 files changed, 85 insertions, 56 deletions
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; |