Home | History | Annotate | Line # | Download | only in guile
scm-param.c revision 1.8
      1 /* GDB parameters implemented in Guile.
      2 
      3    Copyright (C) 2008-2023 Free Software Foundation, Inc.
      4 
      5    This file is part of GDB.
      6 
      7    This program is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3 of the License, or
     10    (at your option) any later version.
     11 
     12    This program is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19 
     20 #include "defs.h"
     21 #include "value.h"
     22 #include "charset.h"
     23 #include "gdbcmd.h"
     24 #include "cli/cli-decode.h"
     25 #include "completer.h"
     26 #include "language.h"
     27 #include "arch-utils.h"
     28 #include "guile-internal.h"
     29 
     30 /* A union that can hold anything described by enum var_types.  */
     31 
     32 union pascm_variable
     33 {
     34   /* Hold an boolean value.  */
     35   bool boolval;
     36 
     37   /* Hold an integer value.  */
     38   int intval;
     39 
     40   /* Hold an auto_boolean.  */
     41   enum auto_boolean autoboolval;
     42 
     43   /* Hold an unsigned integer value, for uinteger.  */
     44   unsigned int uintval;
     45 
     46   /* Hold a string, for the various string types.  */
     47   std::string *stringval;
     48 
     49   /* Hold a string, for enums.  */
     50   const char *cstringval;
     51 };
     52 
     53 /* A GDB parameter.
     54 
     55    Note: Parameters are added to gdb using a two step process:
     56    1) Call make-parameter to create a <gdb:parameter> object.
     57    2) Call register-parameter! to add the parameter to gdb.
     58    It is done this way so that the constructor, make-parameter, doesn't have
     59    any side-effects.  This means that the smob needs to store everything
     60    that was passed to make-parameter.  */
     61 
     62 struct param_smob
     63 {
     64   /* This always appears first.  */
     65   gdb_smob base;
     66 
     67   /* The parameter name.  */
     68   char *name;
     69 
     70   /* The last word of the command.
     71      This is needed because add_cmd requires us to allocate space
     72      for it. :-(  */
     73   char *cmd_name;
     74 
     75   /* One of the COMMAND_* constants.  */
     76   enum command_class cmd_class;
     77 
     78   /* The type of the parameter.  */
     79   enum var_types type;
     80 
     81   /* The docs for the parameter.  */
     82   char *set_doc;
     83   char *show_doc;
     84   char *doc;
     85 
     86   /* The corresponding gdb command objects.
     87      These are NULL if the parameter has not been registered yet, or
     88      is no longer registered.  */
     89   set_show_commands commands;
     90 
     91   /* The value of the parameter.  */
     92   union pascm_variable value;
     93 
     94   /* For an enum parameter, the possible values.  The vector lives in GC
     95      space, it will be freed with the smob.  */
     96   const char * const *enumeration;
     97 
     98   /* The set_func funcion or #f if not specified.
     99      This function is called *after* the parameter is set.
    100      It returns a string that will be displayed to the user.  */
    101   SCM set_func;
    102 
    103   /* The show_func function or #f if not specified.
    104      This function returns the string that is printed.  */
    105   SCM show_func;
    106 
    107   /* The <gdb:parameter> object we are contained in, needed to
    108      protect/unprotect the object since a reference to it comes from
    109      non-gc-managed space (the command context pointer).  */
    110   SCM containing_scm;
    111 };
    112 
    113 /* Wraps a setting around an existing param_smob.  This abstraction
    114    is used to manipulate the value in S->VALUE in a type safe manner using
    115    the setting interface.  */
    116 
    117 static setting
    118 make_setting (param_smob *s)
    119 {
    120   if (var_type_uses<bool> (s->type))
    121     return setting (s->type, &s->value.boolval);
    122   else if (var_type_uses<int> (s->type))
    123     return setting (s->type, &s->value.intval);
    124   else if (var_type_uses<auto_boolean> (s->type))
    125     return setting (s->type, &s->value.autoboolval);
    126   else if (var_type_uses<unsigned int> (s->type))
    127     return setting (s->type, &s->value.uintval);
    128   else if (var_type_uses<std::string> (s->type))
    129     return setting (s->type, s->value.stringval);
    130   else if (var_type_uses<const char *> (s->type))
    131     return setting (s->type, &s->value.cstringval);
    132   else
    133     gdb_assert_not_reached ("unhandled var type");
    134 }
    135 
    136 static const char param_smob_name[] = "gdb:parameter";
    137 
    138 /* The tag Guile knows the param smob by.  */
    139 static scm_t_bits parameter_smob_tag;
    140 
    141 /* Keywords used by make-parameter!.  */
    142 static SCM command_class_keyword;
    143 static SCM parameter_type_keyword;
    144 static SCM enum_list_keyword;
    145 static SCM set_func_keyword;
    146 static SCM show_func_keyword;
    147 static SCM doc_keyword;
    148 static SCM set_doc_keyword;
    149 static SCM show_doc_keyword;
    150 static SCM initial_value_keyword;
    151 static SCM auto_keyword;
    152 static SCM unlimited_keyword;
    153 
    154 static int pascm_is_valid (param_smob *);
    155 static const char *pascm_param_type_name (enum var_types type);
    156 static SCM pascm_param_value (const setting &var, int arg_pos,
    157 			      const char *func_name);
    158 
    159 /* Administrivia for parameter smobs.  */
    161 
    162 static int
    163 pascm_print_param_smob (SCM self, SCM port, scm_print_state *pstate)
    164 {
    165   param_smob *p_smob = (param_smob *) SCM_SMOB_DATA (self);
    166   SCM value;
    167 
    168   gdbscm_printf (port, "#<%s", param_smob_name);
    169 
    170   gdbscm_printf (port, " %s", p_smob->name);
    171 
    172   if (! pascm_is_valid (p_smob))
    173     scm_puts (" {invalid}", port);
    174 
    175   gdbscm_printf (port, " %s ", pascm_param_type_name (p_smob->type));
    176 
    177   value = pascm_param_value (make_setting (p_smob), GDBSCM_ARG_NONE, NULL);
    178   scm_display (value, port);
    179 
    180   scm_puts (">", port);
    181 
    182   scm_remember_upto_here_1 (self);
    183 
    184   /* Non-zero means success.  */
    185   return 1;
    186 }
    187 
    188 /* Create an empty (uninitialized) parameter.  */
    189 
    190 static SCM
    191 pascm_make_param_smob (void)
    192 {
    193   param_smob *p_smob = (param_smob *)
    194     scm_gc_malloc (sizeof (param_smob), param_smob_name);
    195   SCM p_scm;
    196 
    197   memset (p_smob, 0, sizeof (*p_smob));
    198   p_smob->cmd_class = no_class;
    199   p_smob->type = var_boolean; /* ARI: var_boolean */
    200   p_smob->set_func = SCM_BOOL_F;
    201   p_smob->show_func = SCM_BOOL_F;
    202   p_scm = scm_new_smob (parameter_smob_tag, (scm_t_bits) p_smob);
    203   p_smob->containing_scm = p_scm;
    204   gdbscm_init_gsmob (&p_smob->base);
    205 
    206   return p_scm;
    207 }
    208 
    209 /* Returns non-zero if SCM is a <gdb:parameter> object.  */
    210 
    211 static int
    212 pascm_is_parameter (SCM scm)
    213 {
    214   return SCM_SMOB_PREDICATE (parameter_smob_tag, scm);
    215 }
    216 
    217 /* (gdb:parameter? scm) -> boolean */
    218 
    219 static SCM
    220 gdbscm_parameter_p (SCM scm)
    221 {
    222   return scm_from_bool (pascm_is_parameter (scm));
    223 }
    224 
    225 /* Returns the <gdb:parameter> object in SELF.
    226    Throws an exception if SELF is not a <gdb:parameter> object.  */
    227 
    228 static SCM
    229 pascm_get_param_arg_unsafe (SCM self, int arg_pos, const char *func_name)
    230 {
    231   SCM_ASSERT_TYPE (pascm_is_parameter (self), self, arg_pos, func_name,
    232 		   param_smob_name);
    233 
    234   return self;
    235 }
    236 
    237 /* Returns a pointer to the parameter smob of SELF.
    238    Throws an exception if SELF is not a <gdb:parameter> object.  */
    239 
    240 static param_smob *
    241 pascm_get_param_smob_arg_unsafe (SCM self, int arg_pos, const char *func_name)
    242 {
    243   SCM p_scm = pascm_get_param_arg_unsafe (self, arg_pos, func_name);
    244   param_smob *p_smob = (param_smob *) SCM_SMOB_DATA (p_scm);
    245 
    246   return p_smob;
    247 }
    248 
    249 /* Return non-zero if parameter P_SMOB is valid.  */
    250 
    251 static int
    252 pascm_is_valid (param_smob *p_smob)
    253 {
    254   return p_smob->commands.set != nullptr;
    255 }
    256 
    257 /* A helper function which return the default documentation string for
    259    a parameter (which is to say that it's undocumented).  */
    260 
    261 static char *
    262 get_doc_string (void)
    263 {
    264   return xstrdup (_("This command is not documented."));
    265 }
    266 
    267 /* Subroutine of pascm_set_func, pascm_show_func to simplify them.
    268    Signal the error returned from calling set_func/show_func.  */
    269 
    270 static void
    271 pascm_signal_setshow_error (SCM exception, const char *msg)
    272 {
    273   /* Don't print the stack if this was an error signalled by the command
    274      itself.  */
    275   if (gdbscm_user_error_p (gdbscm_exception_key (exception)))
    276     {
    277       gdb::unique_xmalloc_ptr<char> excp_text
    278 	= gdbscm_exception_message_to_string (exception);
    279 
    280       error ("%s", excp_text.get ());
    281     }
    282   else
    283     {
    284       gdbscm_print_gdb_exception (SCM_BOOL_F, exception);
    285       error ("%s", msg);
    286     }
    287 }
    288 
    289 /* A callback function that is registered against the respective
    290    add_setshow_* set_func prototype.  This function will call
    291    the Scheme function "set_func" which must exist.
    292    Note: ARGS is always passed as NULL.  */
    293 
    294 static void
    295 pascm_set_func (const char *args, int from_tty, struct cmd_list_element *c)
    296 {
    297   param_smob *p_smob = (param_smob *) c->context ();
    298   SCM self, result, exception;
    299 
    300   gdb_assert (gdbscm_is_procedure (p_smob->set_func));
    301 
    302   self = p_smob->containing_scm;
    303 
    304   result = gdbscm_safe_call_1 (p_smob->set_func, self, gdbscm_user_error_p);
    305 
    306   if (gdbscm_is_exception (result))
    307     {
    308       pascm_signal_setshow_error (result,
    309 				  _("Error occurred setting parameter."));
    310     }
    311 
    312   if (!scm_is_string (result))
    313     error (_("Result of %s set-func is not a string."), p_smob->name);
    314 
    315   gdb::unique_xmalloc_ptr<char> msg = gdbscm_scm_to_host_string (result, NULL,
    316 								 &exception);
    317   if (msg == NULL)
    318     {
    319       gdbscm_print_gdb_exception (SCM_BOOL_F, exception);
    320       error (_("Error converting show text to host string."));
    321     }
    322 
    323   /* GDB is usually silent when a parameter is set.  */
    324   if (*msg.get () != '\0')
    325     gdb_printf ("%s\n", msg.get ());
    326 }
    327 
    328 /* A callback function that is registered against the respective
    329    add_setshow_* show_func prototype.  This function will call
    330    the Scheme function "show_func" which must exist and must return a
    331    string that is then printed to FILE.  */
    332 
    333 static void
    334 pascm_show_func (struct ui_file *file, int from_tty,
    335 		 struct cmd_list_element *c, const char *value)
    336 {
    337   param_smob *p_smob = (param_smob *) c->context ();
    338   SCM value_scm, self, result, exception;
    339 
    340   gdb_assert (gdbscm_is_procedure (p_smob->show_func));
    341 
    342   value_scm = gdbscm_scm_from_host_string (value, strlen (value));
    343   if (gdbscm_is_exception (value_scm))
    344     {
    345       error (_("Error converting parameter value \"%s\" to Scheme string."),
    346 	     value);
    347     }
    348   self = p_smob->containing_scm;
    349 
    350   result = gdbscm_safe_call_2 (p_smob->show_func, self, value_scm,
    351 			       gdbscm_user_error_p);
    352 
    353   if (gdbscm_is_exception (result))
    354     {
    355       pascm_signal_setshow_error (result,
    356 				  _("Error occurred showing parameter."));
    357     }
    358 
    359   gdb::unique_xmalloc_ptr<char> msg = gdbscm_scm_to_host_string (result, NULL,
    360 								 &exception);
    361   if (msg == NULL)
    362     {
    363       gdbscm_print_gdb_exception (SCM_BOOL_F, exception);
    364       error (_("Error converting show text to host string."));
    365     }
    366 
    367   gdb_printf (file, "%s\n", msg.get ());
    368 }
    369 
    370 /* A helper function that dispatches to the appropriate add_setshow
    371    function.  */
    372 
    373 static set_show_commands
    374 add_setshow_generic (enum var_types param_type, enum command_class cmd_class,
    375 		     char *cmd_name, param_smob *self,
    376 		     char *set_doc, char *show_doc, char *help_doc,
    377 		     cmd_func_ftype *set_func,
    378 		     show_value_ftype *show_func,
    379 		     struct cmd_list_element **set_list,
    380 		     struct cmd_list_element **show_list)
    381 {
    382   set_show_commands commands;
    383 
    384   switch (param_type)
    385     {
    386     case var_boolean:
    387       commands = add_setshow_boolean_cmd (cmd_name, cmd_class,
    388 					  &self->value.boolval, set_doc,
    389 					  show_doc, help_doc, set_func,
    390 					  show_func, set_list, show_list);
    391       break;
    392 
    393     case var_auto_boolean:
    394       commands = add_setshow_auto_boolean_cmd (cmd_name, cmd_class,
    395 					       &self->value.autoboolval,
    396 					       set_doc, show_doc, help_doc,
    397 					       set_func, show_func, set_list,
    398 					       show_list);
    399       break;
    400 
    401     case var_uinteger:
    402       commands = add_setshow_uinteger_cmd (cmd_name, cmd_class,
    403 					   &self->value.uintval, set_doc,
    404 					   show_doc, help_doc, set_func,
    405 					   show_func, set_list, show_list);
    406       break;
    407 
    408     case var_zinteger:
    409       commands = add_setshow_zinteger_cmd (cmd_name, cmd_class,
    410 					   &self->value.intval, set_doc,
    411 					   show_doc, help_doc, set_func,
    412 					   show_func, set_list, show_list);
    413       break;
    414 
    415     case var_zuinteger:
    416       commands = add_setshow_zuinteger_cmd (cmd_name, cmd_class,
    417 					    &self->value.uintval, set_doc,
    418 					    show_doc, help_doc, set_func,
    419 					    show_func, set_list, show_list);
    420       break;
    421 
    422     case var_zuinteger_unlimited:
    423       commands = add_setshow_zuinteger_unlimited_cmd (cmd_name, cmd_class,
    424 						      &self->value.intval,
    425 						      set_doc, show_doc,
    426 						      help_doc, set_func,
    427 						      show_func, set_list,
    428 						      show_list);
    429       break;
    430 
    431     case var_string:
    432       commands = add_setshow_string_cmd (cmd_name, cmd_class,
    433 					 self->value.stringval, set_doc,
    434 					 show_doc, help_doc, set_func,
    435 					 show_func, set_list, show_list);
    436       break;
    437 
    438     case var_string_noescape:
    439       commands = add_setshow_string_noescape_cmd (cmd_name, cmd_class,
    440 						  self->value.stringval,
    441 						  set_doc, show_doc, help_doc,
    442 						  set_func, show_func, set_list,
    443 						  show_list);
    444 
    445       break;
    446 
    447     case var_optional_filename:
    448       commands = add_setshow_optional_filename_cmd (cmd_name, cmd_class,
    449 						    self->value.stringval,
    450 						    set_doc, show_doc, help_doc,
    451 						    set_func, show_func,
    452 						    set_list, show_list);
    453       break;
    454 
    455     case var_filename:
    456       commands = add_setshow_filename_cmd (cmd_name, cmd_class,
    457 					   self->value.stringval, set_doc,
    458 					   show_doc, help_doc, set_func,
    459 					   show_func, set_list, show_list);
    460       break;
    461 
    462     case var_enum:
    463       /* Initialize the value, just in case.  */
    464       make_setting (self).set<const char *> (self->enumeration[0]);
    465       commands = add_setshow_enum_cmd (cmd_name, cmd_class, self->enumeration,
    466 				       &self->value.cstringval, set_doc,
    467 				       show_doc, help_doc, set_func, show_func,
    468 				       set_list, show_list);
    469       break;
    470 
    471     default:
    472       gdb_assert_not_reached ("bad param_type value");
    473     }
    474 
    475   /* Register Scheme object against the commandsparameter context.  Perform this
    476      task against both lists.  */
    477   commands.set->set_context (self);
    478   commands.show->set_context (self);
    479 
    480   return commands;
    481 }
    482 
    483 /* Return an array of strings corresponding to the enum values for
    484    ENUM_VALUES_SCM.
    485    Throws an exception if there's a problem with the values.
    486    Space for the result is allocated from the GC heap.  */
    487 
    488 static const char * const *
    489 compute_enum_list (SCM enum_values_scm, int arg_pos, const char *func_name)
    490 {
    491   long i, size;
    492   char **enum_values;
    493   const char * const *result;
    494 
    495   SCM_ASSERT_TYPE (gdbscm_is_true (scm_list_p (enum_values_scm)),
    496 		   enum_values_scm, arg_pos, func_name, _("list"));
    497 
    498   size = scm_ilength (enum_values_scm);
    499   if (size == 0)
    500     {
    501       gdbscm_out_of_range_error (FUNC_NAME, arg_pos, enum_values_scm,
    502 				 _("enumeration list is empty"));
    503     }
    504 
    505   enum_values = XCNEWVEC (char *, size + 1);
    506 
    507   i = 0;
    508   while (!scm_is_eq (enum_values_scm, SCM_EOL))
    509     {
    510       SCM value = scm_car (enum_values_scm);
    511       SCM exception;
    512 
    513       if (!scm_is_string (value))
    514 	{
    515 	  freeargv (enum_values);
    516 	  SCM_ASSERT_TYPE (0, value, arg_pos, func_name, _("string"));
    517 	}
    518       enum_values[i] = gdbscm_scm_to_host_string (value, NULL,
    519 						  &exception).release ();
    520       if (enum_values[i] == NULL)
    521 	{
    522 	  freeargv (enum_values);
    523 	  gdbscm_throw (exception);
    524 	}
    525       ++i;
    526       enum_values_scm = scm_cdr (enum_values_scm);
    527     }
    528   gdb_assert (i == size);
    529 
    530   result = gdbscm_gc_dup_argv (enum_values);
    531   freeargv (enum_values);
    532   return result;
    533 }
    534 
    535 static const scheme_integer_constant parameter_types[] =
    536 {
    537   /* Note: var_integer is deprecated, and intentionally does not
    538      appear here.  */
    539   { "PARAM_BOOLEAN", var_boolean }, /* ARI: var_boolean */
    540   { "PARAM_AUTO_BOOLEAN", var_auto_boolean },
    541   { "PARAM_ZINTEGER", var_zinteger },
    542   { "PARAM_UINTEGER", var_uinteger },
    543   { "PARAM_ZUINTEGER", var_zuinteger },
    544   { "PARAM_ZUINTEGER_UNLIMITED", var_zuinteger_unlimited },
    545   { "PARAM_STRING", var_string },
    546   { "PARAM_STRING_NOESCAPE", var_string_noescape },
    547   { "PARAM_OPTIONAL_FILENAME", var_optional_filename },
    548   { "PARAM_FILENAME", var_filename },
    549   { "PARAM_ENUM", var_enum },
    550 
    551   END_INTEGER_CONSTANTS
    552 };
    553 
    554 /* Return non-zero if PARAM_TYPE is a valid parameter type.  */
    555 
    556 static int
    557 pascm_valid_parameter_type_p (int param_type)
    558 {
    559   int i;
    560 
    561   for (i = 0; parameter_types[i].name != NULL; ++i)
    562     {
    563       if (parameter_types[i].value == param_type)
    564 	return 1;
    565     }
    566 
    567   return 0;
    568 }
    569 
    570 /* Return PARAM_TYPE as a string.  */
    571 
    572 static const char *
    573 pascm_param_type_name (enum var_types param_type)
    574 {
    575   int i;
    576 
    577   for (i = 0; parameter_types[i].name != NULL; ++i)
    578     {
    579       if (parameter_types[i].value == param_type)
    580 	return parameter_types[i].name;
    581     }
    582 
    583   gdb_assert_not_reached ("bad parameter type");
    584 }
    585 
    586 /* Return the value of a gdb parameter as a Scheme value.
    587    If the var_type of VAR is not supported, then a <gdb:exception> object is
    588    returned.  */
    589 
    590 static SCM
    591 pascm_param_value (const setting &var, int arg_pos, const char *func_name)
    592 {
    593   /* Note: We *could* support var_integer here in case someone is trying to get
    594      the value of a Python-created parameter (which is the only place that
    595      still supports var_integer).  To further discourage its use we do not.  */
    596 
    597   switch (var.type ())
    598     {
    599     case var_string:
    600     case var_string_noescape:
    601     case var_optional_filename:
    602     case var_filename:
    603       {
    604 	const std::string &str = var.get<std::string> ();
    605 	return gdbscm_scm_from_host_string (str.c_str (), str.length ());
    606       }
    607 
    608     case var_enum:
    609       {
    610 	const char *str = var.get<const char *> ();
    611 	if (str == nullptr)
    612 	  str = "";
    613 	return gdbscm_scm_from_host_string (str, strlen (str));
    614       }
    615 
    616     case var_boolean:
    617       {
    618 	if (var.get<bool> ())
    619 	  return SCM_BOOL_T;
    620 	else
    621 	  return SCM_BOOL_F;
    622       }
    623 
    624     case var_auto_boolean:
    625       {
    626 	enum auto_boolean ab = var.get<enum auto_boolean> ();
    627 
    628 	if (ab == AUTO_BOOLEAN_TRUE)
    629 	  return SCM_BOOL_T;
    630 	else if (ab == AUTO_BOOLEAN_FALSE)
    631 	  return SCM_BOOL_F;
    632 	else
    633 	  return auto_keyword;
    634       }
    635 
    636     case var_zuinteger_unlimited:
    637       if (var.get<int> () == -1)
    638 	return unlimited_keyword;
    639       gdb_assert (var.get<int> () >= 0);
    640       /* Fall through.  */
    641     case var_zinteger:
    642       return scm_from_int (var.get<int> ());
    643 
    644     case var_uinteger:
    645       if (var.get<unsigned int> ()== UINT_MAX)
    646 	return unlimited_keyword;
    647       /* Fall through.  */
    648     case var_zuinteger:
    649       return scm_from_uint (var.get<unsigned int> ());
    650 
    651     default:
    652       break;
    653     }
    654 
    655   return gdbscm_make_out_of_range_error (func_name, arg_pos,
    656 					 scm_from_int (var.type ()),
    657 					 _("program error: unhandled type"));
    658 }
    659 
    660 /* Set the value of a parameter of type P_SMOB->TYPE in P_SMOB->VAR from VALUE.
    661    ENUMERATION is the list of enum values for enum parameters, otherwise NULL.
    662    Throws a Scheme exception if VALUE_SCM is invalid for TYPE.  */
    663 
    664 static void
    665 pascm_set_param_value_x (param_smob *p_smob,
    666 			 const char * const *enumeration,
    667 			 SCM value, int arg_pos, const char *func_name)
    668 {
    669   setting var = make_setting (p_smob);
    670 
    671   switch (var.type ())
    672     {
    673     case var_string:
    674     case var_string_noescape:
    675     case var_optional_filename:
    676     case var_filename:
    677       SCM_ASSERT_TYPE (scm_is_string (value)
    678 		       || (var.type () != var_filename
    679 			   && gdbscm_is_false (value)),
    680 		       value, arg_pos, func_name,
    681 		       _("string or #f for non-PARAM_FILENAME parameters"));
    682       if (gdbscm_is_false (value))
    683 	var.set<std::string> ("");
    684       else
    685 	{
    686 	  SCM exception;
    687 
    688 	  gdb::unique_xmalloc_ptr<char> string
    689 	    = gdbscm_scm_to_host_string (value, nullptr, &exception);
    690 	  if (string == nullptr)
    691 	    gdbscm_throw (exception);
    692 	  var.set<std::string> (string.release ());
    693 	}
    694       break;
    695 
    696     case var_enum:
    697       {
    698 	int i;
    699 	SCM exception;
    700 
    701 	SCM_ASSERT_TYPE (scm_is_string (value), value, arg_pos, func_name,
    702 		       _("string"));
    703 	gdb::unique_xmalloc_ptr<char> str
    704 	  = gdbscm_scm_to_host_string (value, nullptr, &exception);
    705 	if (str == nullptr)
    706 	  gdbscm_throw (exception);
    707 	for (i = 0; enumeration[i]; ++i)
    708 	  {
    709 	    if (strcmp (enumeration[i], str.get ()) == 0)
    710 	      break;
    711 	  }
    712 	if (enumeration[i] == nullptr)
    713 	  {
    714 	    gdbscm_out_of_range_error (func_name, arg_pos, value,
    715 				       _("not member of enumeration"));
    716 	  }
    717 	var.set<const char *> (enumeration[i]);
    718 	break;
    719       }
    720 
    721     case var_boolean:
    722       SCM_ASSERT_TYPE (gdbscm_is_bool (value), value, arg_pos, func_name,
    723 		       _("boolean"));
    724       var.set<bool> (gdbscm_is_true (value));
    725       break;
    726 
    727     case var_auto_boolean:
    728       SCM_ASSERT_TYPE (gdbscm_is_bool (value)
    729 		       || scm_is_eq (value, auto_keyword),
    730 		       value, arg_pos, func_name,
    731 		       _("boolean or #:auto"));
    732       if (scm_is_eq (value, auto_keyword))
    733 	var.set<enum auto_boolean> (AUTO_BOOLEAN_AUTO);
    734       else if (gdbscm_is_true (value))
    735 	var.set<enum auto_boolean> (AUTO_BOOLEAN_TRUE);
    736       else
    737 	var.set<enum auto_boolean> (AUTO_BOOLEAN_FALSE);
    738       break;
    739 
    740     case var_zinteger:
    741     case var_uinteger:
    742     case var_zuinteger:
    743     case var_zuinteger_unlimited:
    744       if (var.type () == var_uinteger
    745 	  || var.type () == var_zuinteger_unlimited)
    746 	{
    747 	  SCM_ASSERT_TYPE (scm_is_integer (value)
    748 			   || scm_is_eq (value, unlimited_keyword),
    749 			   value, arg_pos, func_name,
    750 			   _("integer or #:unlimited"));
    751 	  if (scm_is_eq (value, unlimited_keyword))
    752 	    {
    753 	      if (var.type () == var_uinteger)
    754 		var.set<unsigned int> (UINT_MAX);
    755 	      else
    756 		var.set<int> (-1);
    757 	      break;
    758 	    }
    759 	}
    760       else
    761 	{
    762 	  SCM_ASSERT_TYPE (scm_is_integer (value), value, arg_pos, func_name,
    763 			   _("integer"));
    764 	}
    765 
    766       if (var.type () == var_uinteger
    767 	  || var.type () == var_zuinteger)
    768 	{
    769 	  unsigned int u = scm_to_uint (value);
    770 
    771 	  if (var.type () == var_uinteger && u == 0)
    772 	    u = UINT_MAX;
    773 	  var.set<unsigned int> (u);
    774 	}
    775       else
    776 	{
    777 	  int i = scm_to_int (value);
    778 
    779 	  if (var.type () == var_zuinteger_unlimited && i < -1)
    780 	    {
    781 	      gdbscm_out_of_range_error (func_name, arg_pos, value,
    782 					 _("must be >= -1"));
    783 	    }
    784 	  var.set<int> (i);
    785 	}
    786       break;
    787 
    788     default:
    789       gdb_assert_not_reached ("bad parameter type");
    790     }
    791 }
    792 
    793 /* Free function for a param_smob.  */
    794 static size_t
    795 pascm_free_parameter_smob (SCM self)
    796 {
    797   param_smob *p_smob = (param_smob *) SCM_SMOB_DATA (self);
    798 
    799   if (var_type_uses<std::string> (p_smob->type))
    800     {
    801       delete p_smob->value.stringval;
    802       p_smob->value.stringval = nullptr;
    803     }
    804 
    805   return 0;
    806 }
    807 
    808 /* Parameter Scheme functions.  */
    810 
    811 /* (make-parameter name
    812      [#:command-class cmd-class] [#:parameter-type param-type]
    813      [#:enum-list enum-list] [#:set-func function] [#:show-func function]
    814      [#:doc <string>] [#:set-doc <string>] [#:show-doc <string>]
    815      [#:initial-value initial-value]) -> <gdb:parameter>
    816 
    817    NAME is the name of the parameter.  It may consist of multiple
    818    words, in which case the final word is the name of the new parameter,
    819    and earlier words must be prefix commands.
    820 
    821    CMD-CLASS is the kind of command.  It should be one of the COMMAND_*
    822    constants defined in the gdb module.
    823 
    824    PARAM_TYPE is the type of the parameter.  It should be one of the
    825    PARAM_* constants defined in the gdb module.
    826 
    827    If PARAM-TYPE is PARAM_ENUM, then ENUM-LIST is a list of strings that
    828    are the valid values for this parameter.  The first value is the default.
    829 
    830    SET-FUNC, if provided, is called after the parameter is set.
    831    It is a function of one parameter: the <gdb:parameter> object.
    832    It must return a string to be displayed to the user.
    833    Setting a parameter is typically a silent operation, so typically ""
    834    should be returned.
    835 
    836    SHOW-FUNC, if provided, returns the string that is printed.
    837    It is a function of two parameters: the <gdb:parameter> object
    838    and the current value of the parameter as a string.
    839 
    840    DOC, SET-DOC, SHOW-DOC are the doc strings for the parameter.
    841 
    842    INITIAL-VALUE is the initial value of the parameter.
    843 
    844    The result is the <gdb:parameter> Scheme object.
    845    The parameter is not available to be used yet, however.
    846    It must still be added to gdb with register-parameter!.  */
    847 
    848 static SCM
    849 gdbscm_make_parameter (SCM name_scm, SCM rest)
    850 {
    851   const SCM keywords[] = {
    852     command_class_keyword, parameter_type_keyword, enum_list_keyword,
    853     set_func_keyword, show_func_keyword,
    854     doc_keyword, set_doc_keyword, show_doc_keyword,
    855     initial_value_keyword, SCM_BOOL_F
    856   };
    857   int cmd_class_arg_pos = -1, param_type_arg_pos = -1;
    858   int enum_list_arg_pos = -1, set_func_arg_pos = -1, show_func_arg_pos = -1;
    859   int doc_arg_pos = -1, set_doc_arg_pos = -1, show_doc_arg_pos = -1;
    860   int initial_value_arg_pos = -1;
    861   char *s;
    862   char *name;
    863   int cmd_class = no_class;
    864   int param_type = var_boolean; /* ARI: var_boolean */
    865   SCM enum_list_scm = SCM_BOOL_F;
    866   SCM set_func = SCM_BOOL_F, show_func = SCM_BOOL_F;
    867   char *doc = NULL, *set_doc = NULL, *show_doc = NULL;
    868   SCM initial_value_scm = SCM_BOOL_F;
    869   const char * const *enum_list = NULL;
    870   SCM p_scm;
    871   param_smob *p_smob;
    872 
    873   gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, keywords, "s#iiOOOsssO",
    874 			      name_scm, &name, rest,
    875 			      &cmd_class_arg_pos, &cmd_class,
    876 			      &param_type_arg_pos, &param_type,
    877 			      &enum_list_arg_pos, &enum_list_scm,
    878 			      &set_func_arg_pos, &set_func,
    879 			      &show_func_arg_pos, &show_func,
    880 			      &doc_arg_pos, &doc,
    881 			      &set_doc_arg_pos, &set_doc,
    882 			      &show_doc_arg_pos, &show_doc,
    883 			      &initial_value_arg_pos, &initial_value_scm);
    884 
    885   /* If doc is NULL, leave it NULL.  See add_setshow_cmd_full.  */
    886   if (set_doc == NULL)
    887     set_doc = get_doc_string ();
    888   if (show_doc == NULL)
    889     show_doc = get_doc_string ();
    890 
    891   s = name;
    892   name = gdbscm_canonicalize_command_name (s, 0);
    893   xfree (s);
    894   if (doc != NULL)
    895     {
    896       s = doc;
    897       doc = gdbscm_gc_xstrdup (s);
    898       xfree (s);
    899     }
    900   s = set_doc;
    901   set_doc = gdbscm_gc_xstrdup (s);
    902   xfree (s);
    903   s = show_doc;
    904   show_doc = gdbscm_gc_xstrdup (s);
    905   xfree (s);
    906 
    907   if (!gdbscm_valid_command_class_p (cmd_class))
    908     {
    909       gdbscm_out_of_range_error (FUNC_NAME, cmd_class_arg_pos,
    910 				 scm_from_int (cmd_class),
    911 				 _("invalid command class argument"));
    912     }
    913   if (!pascm_valid_parameter_type_p (param_type))
    914     {
    915       gdbscm_out_of_range_error (FUNC_NAME, param_type_arg_pos,
    916 				 scm_from_int (param_type),
    917 				 _("invalid parameter type argument"));
    918     }
    919   if (enum_list_arg_pos > 0 && param_type != var_enum)
    920     {
    921       gdbscm_misc_error (FUNC_NAME, enum_list_arg_pos, enum_list_scm,
    922 		_("#:enum-values can only be provided with PARAM_ENUM"));
    923     }
    924   if (enum_list_arg_pos < 0 && param_type == var_enum)
    925     {
    926       gdbscm_misc_error (FUNC_NAME, GDBSCM_ARG_NONE, SCM_BOOL_F,
    927 			 _("PARAM_ENUM requires an enum-values argument"));
    928     }
    929   if (set_func_arg_pos > 0)
    930     {
    931       SCM_ASSERT_TYPE (gdbscm_is_procedure (set_func), set_func,
    932 		       set_func_arg_pos, FUNC_NAME, _("procedure"));
    933     }
    934   if (show_func_arg_pos > 0)
    935     {
    936       SCM_ASSERT_TYPE (gdbscm_is_procedure (show_func), show_func,
    937 		       show_func_arg_pos, FUNC_NAME, _("procedure"));
    938     }
    939   if (param_type == var_enum)
    940     {
    941       /* Note: enum_list lives in GC space, so we don't have to worry about
    942 	 freeing it if we later throw an exception.  */
    943       enum_list = compute_enum_list (enum_list_scm, enum_list_arg_pos,
    944 				     FUNC_NAME);
    945     }
    946 
    947   /* If initial-value is a function, we need the parameter object constructed
    948      to pass it to the function.  A typical thing the function may want to do
    949      is add an object-property to it to record the last known good value.  */
    950   p_scm = pascm_make_param_smob ();
    951   p_smob = (param_smob *) SCM_SMOB_DATA (p_scm);
    952   /* These are all stored in GC space so that we don't have to worry about
    953      freeing them if we throw an exception.  */
    954   p_smob->name = name;
    955   p_smob->cmd_class = (enum command_class) cmd_class;
    956   p_smob->type = (enum var_types) param_type;
    957   p_smob->doc = doc;
    958   p_smob->set_doc = set_doc;
    959   p_smob->show_doc = show_doc;
    960   p_smob->enumeration = enum_list;
    961   p_smob->set_func = set_func;
    962   p_smob->show_func = show_func;
    963 
    964   scm_set_smob_free (parameter_smob_tag, pascm_free_parameter_smob);
    965   if (var_type_uses<std::string> (p_smob->type))
    966     p_smob->value.stringval = new std::string;
    967 
    968   if (initial_value_arg_pos > 0)
    969     {
    970       if (gdbscm_is_procedure (initial_value_scm))
    971 	{
    972 	  initial_value_scm = gdbscm_safe_call_1 (initial_value_scm,
    973 						  p_smob->containing_scm, NULL);
    974 	  if (gdbscm_is_exception (initial_value_scm))
    975 	    gdbscm_throw (initial_value_scm);
    976 	}
    977       pascm_set_param_value_x (p_smob, enum_list,
    978 			       initial_value_scm,
    979 			       initial_value_arg_pos, FUNC_NAME);
    980     }
    981 
    982   return p_scm;
    983 }
    984 
    985 /* Subroutine of gdbscm_register_parameter_x to simplify it.
    986    Return non-zero if parameter NAME is already defined in LIST.  */
    987 
    988 static int
    989 pascm_parameter_defined_p (const char *name, struct cmd_list_element *list)
    990 {
    991   struct cmd_list_element *c;
    992 
    993   c = lookup_cmd_1 (&name, list, NULL, NULL, 1);
    994 
    995   /* If the name is ambiguous that's ok, it's a new parameter still.  */
    996   return c != NULL && c != CMD_LIST_AMBIGUOUS;
    997 }
    998 
    999 /* (register-parameter! <gdb:parameter>) -> unspecified
   1000 
   1001    It is an error to register a pre-existing parameter.  */
   1002 
   1003 static SCM
   1004 gdbscm_register_parameter_x (SCM self)
   1005 {
   1006   param_smob *p_smob
   1007     = pascm_get_param_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
   1008   char *cmd_name;
   1009   struct cmd_list_element **set_list, **show_list;
   1010 
   1011   if (pascm_is_valid (p_smob))
   1012     scm_misc_error (FUNC_NAME, _("parameter is already registered"), SCM_EOL);
   1013 
   1014   cmd_name = gdbscm_parse_command_name (p_smob->name, FUNC_NAME, SCM_ARG1,
   1015 					&set_list, &setlist);
   1016   xfree (cmd_name);
   1017   cmd_name = gdbscm_parse_command_name (p_smob->name, FUNC_NAME, SCM_ARG1,
   1018 					&show_list, &showlist);
   1019   p_smob->cmd_name = gdbscm_gc_xstrdup (cmd_name);
   1020   xfree (cmd_name);
   1021 
   1022   if (pascm_parameter_defined_p (p_smob->cmd_name, *set_list))
   1023     {
   1024       gdbscm_misc_error (FUNC_NAME, SCM_ARG1, self,
   1025 		_("parameter exists, \"set\" command is already defined"));
   1026     }
   1027   if (pascm_parameter_defined_p (p_smob->cmd_name, *show_list))
   1028     {
   1029       gdbscm_misc_error (FUNC_NAME, SCM_ARG1, self,
   1030 		_("parameter exists, \"show\" command is already defined"));
   1031     }
   1032 
   1033   gdbscm_gdb_exception exc {};
   1034   try
   1035     {
   1036       p_smob->commands = add_setshow_generic
   1037 	(p_smob->type, p_smob->cmd_class, p_smob->cmd_name, p_smob,
   1038 	 p_smob->set_doc, p_smob->show_doc, p_smob->doc,
   1039 	 (gdbscm_is_procedure (p_smob->set_func) ? pascm_set_func : NULL),
   1040 	 (gdbscm_is_procedure (p_smob->show_func) ? pascm_show_func : NULL),
   1041 	 set_list, show_list);
   1042     }
   1043   catch (const gdb_exception &except)
   1044     {
   1045       exc = unpack (except);
   1046     }
   1047 
   1048   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   1049   /* Note: At this point the parameter exists in gdb.
   1050      So no more errors after this point.  */
   1051 
   1052   /* The owner of this parameter is not in GC-controlled memory, so we need
   1053      to protect it from GC until the parameter is deleted.  */
   1054   scm_gc_protect_object (p_smob->containing_scm);
   1055 
   1056   return SCM_UNSPECIFIED;
   1057 }
   1058 
   1059 /* (parameter-value <gdb:parameter>) -> value
   1060    (parameter-value <string>) -> value */
   1061 
   1062 static SCM
   1063 gdbscm_parameter_value (SCM self)
   1064 {
   1065   SCM_ASSERT_TYPE (pascm_is_parameter (self) || scm_is_string (self),
   1066 		   self, SCM_ARG1, FUNC_NAME, _("<gdb:parameter> or string"));
   1067 
   1068   if (pascm_is_parameter (self))
   1069     {
   1070       param_smob *p_smob = pascm_get_param_smob_arg_unsafe (self, SCM_ARG1,
   1071 							    FUNC_NAME);
   1072 
   1073       return pascm_param_value (make_setting (p_smob), SCM_ARG1, FUNC_NAME);
   1074     }
   1075   else
   1076     {
   1077       SCM except_scm;
   1078       struct cmd_list_element *alias, *prefix, *cmd;
   1079       char *newarg;
   1080       int found = -1;
   1081       gdbscm_gdb_exception except {};
   1082 
   1083       gdb::unique_xmalloc_ptr<char> name
   1084 	= gdbscm_scm_to_host_string (self, NULL, &except_scm);
   1085       if (name == NULL)
   1086 	gdbscm_throw (except_scm);
   1087       newarg = concat ("show ", name.get (), (char *) NULL);
   1088       try
   1089 	{
   1090 	  found = lookup_cmd_composition (newarg, &alias, &prefix, &cmd);
   1091 	}
   1092       catch (const gdb_exception &ex)
   1093 	{
   1094 	  except = unpack (ex);
   1095 	}
   1096 
   1097       xfree (newarg);
   1098       GDBSCM_HANDLE_GDB_EXCEPTION (except);
   1099       if (!found)
   1100 	{
   1101 	  gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
   1102 				     _("parameter not found"));
   1103 	}
   1104 
   1105       if (!cmd->var.has_value ())
   1106 	{
   1107 	  gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
   1108 				     _("not a parameter"));
   1109 	}
   1110 
   1111       return pascm_param_value (*cmd->var, SCM_ARG1, FUNC_NAME);
   1112     }
   1113 }
   1114 
   1115 /* (set-parameter-value! <gdb:parameter> value) -> unspecified */
   1116 
   1117 static SCM
   1118 gdbscm_set_parameter_value_x (SCM self, SCM value)
   1119 {
   1120   param_smob *p_smob = pascm_get_param_smob_arg_unsafe (self, SCM_ARG1,
   1121 							FUNC_NAME);
   1122 
   1123   pascm_set_param_value_x (p_smob, p_smob->enumeration,
   1124 			   value, SCM_ARG2, FUNC_NAME);
   1125 
   1126   return SCM_UNSPECIFIED;
   1127 }
   1128 
   1129 /* Initialize the Scheme parameter support.  */
   1131 
   1132 static const scheme_function parameter_functions[] =
   1133 {
   1134   { "make-parameter", 1, 0, 1, as_a_scm_t_subr (gdbscm_make_parameter),
   1135     "\
   1136 Make a GDB parameter object.\n\
   1137 \n\
   1138   Arguments: name\n\
   1139       [#:command-class <cmd-class>] [#:parameter-type <parameter-type>]\n\
   1140       [#:enum-list <enum-list>]\n\
   1141       [#:set-func function] [#:show-func function]\n\
   1142       [#:doc string] [#:set-doc string] [#:show-doc string]\n\
   1143       [#:initial-value initial-value]\n\
   1144     name: The name of the command.  It may consist of multiple words,\n\
   1145       in which case the final word is the name of the new parameter, and\n\
   1146       earlier words must be prefix commands.\n\
   1147     cmd-class: The class of the command, one of COMMAND_*.\n\
   1148       The default is COMMAND_NONE.\n\
   1149     parameter-type: The kind of parameter, one of PARAM_*\n\
   1150       The default is PARAM_BOOLEAN.\n\
   1151     enum-list: If parameter-type is PARAM_ENUM, then this specifies the set\n\
   1152       of values of the enum.\n\
   1153     set-func: A function of one parameter: the <gdb:parameter> object.\n\
   1154       Called *after* the parameter has been set.  Returns either \"\" or a\n\
   1155       non-empty string to be displayed to the user.\n\
   1156       If non-empty, GDB will add a trailing newline.\n\
   1157     show-func: A function of two parameters: the <gdb:parameter> object\n\
   1158       and the string representation of the current value.\n\
   1159       The result is a string to be displayed to the user.\n\
   1160       GDB will add a trailing newline.\n\
   1161     doc: The \"doc string\" of the parameter.\n\
   1162     set-doc: The \"doc string\" when setting the parameter.\n\
   1163     show-doc: The \"doc string\" when showing the parameter.\n\
   1164     initial-value: The initial value of the parameter." },
   1165 
   1166   { "register-parameter!", 1, 0, 0,
   1167     as_a_scm_t_subr (gdbscm_register_parameter_x),
   1168     "\
   1169 Register a <gdb:parameter> object with GDB." },
   1170 
   1171   { "parameter?", 1, 0, 0, as_a_scm_t_subr (gdbscm_parameter_p),
   1172     "\
   1173 Return #t if the object is a <gdb:parameter> object." },
   1174 
   1175   { "parameter-value", 1, 0, 0, as_a_scm_t_subr (gdbscm_parameter_value),
   1176     "\
   1177 Return the value of a <gdb:parameter> object\n\
   1178 or any gdb parameter if param is a string naming the parameter." },
   1179 
   1180   { "set-parameter-value!", 2, 0, 0,
   1181     as_a_scm_t_subr (gdbscm_set_parameter_value_x),
   1182     "\
   1183 Set the value of a <gdb:parameter> object.\n\
   1184 \n\
   1185   Arguments: <gdb:parameter> value" },
   1186 
   1187   END_FUNCTIONS
   1188 };
   1189 
   1190 void
   1191 gdbscm_initialize_parameters (void)
   1192 {
   1193   parameter_smob_tag
   1194     = gdbscm_make_smob_type (param_smob_name, sizeof (param_smob));
   1195   scm_set_smob_print (parameter_smob_tag, pascm_print_param_smob);
   1196 
   1197   gdbscm_define_integer_constants (parameter_types, 1);
   1198   gdbscm_define_functions (parameter_functions, 1);
   1199 
   1200   command_class_keyword = scm_from_latin1_keyword ("command-class");
   1201   parameter_type_keyword = scm_from_latin1_keyword ("parameter-type");
   1202   enum_list_keyword = scm_from_latin1_keyword ("enum-list");
   1203   set_func_keyword = scm_from_latin1_keyword ("set-func");
   1204   show_func_keyword = scm_from_latin1_keyword ("show-func");
   1205   doc_keyword = scm_from_latin1_keyword ("doc");
   1206   set_doc_keyword = scm_from_latin1_keyword ("set-doc");
   1207   show_doc_keyword = scm_from_latin1_keyword ("show-doc");
   1208   initial_value_keyword = scm_from_latin1_keyword ("initial-value");
   1209   auto_keyword = scm_from_latin1_keyword ("auto");
   1210   unlimited_keyword = scm_from_latin1_keyword ("unlimited");
   1211 }
   1212