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