Automatic date update in version.in
[binutils-gdb.git] / gdb / guile / scm-param.c
blob018bd1499c9924d4898b713a78039fd89587e12f
1 /* GDB parameters implemented in Guile.
3 Copyright (C) 2008-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
20 #include "value.h"
21 #include "charset.h"
22 #include "gdbcmd.h"
23 #include "cli/cli-decode.h"
24 #include "completer.h"
25 #include "language.h"
26 #include "arch-utils.h"
27 #include "guile-internal.h"
29 /* A union that can hold anything described by enum var_types. */
31 union pascm_variable
33 /* Hold an boolean value. */
34 bool boolval;
36 /* Hold an integer value. */
37 int intval;
39 /* Hold an auto_boolean. */
40 enum auto_boolean autoboolval;
42 /* Hold an unsigned integer value, for uinteger. */
43 unsigned int uintval;
45 /* Hold a string, for the various string types. */
46 std::string *stringval;
48 /* Hold a string, for enums. */
49 const char *cstringval;
52 /* A GDB parameter.
54 Note: Parameters are added to gdb using a two step process:
55 1) Call make-parameter to create a <gdb:parameter> object.
56 2) Call register-parameter! to add the parameter to gdb.
57 It is done this way so that the constructor, make-parameter, doesn't have
58 any side-effects. This means that the smob needs to store everything
59 that was passed to make-parameter. */
61 struct param_smob
63 /* This always appears first. */
64 gdb_smob base;
66 /* The parameter name. */
67 char *name;
69 /* The last word of the command.
70 This is needed because add_cmd requires us to allocate space
71 for it. :-( */
72 char *cmd_name;
74 /* One of the COMMAND_* constants. */
75 enum command_class cmd_class;
77 /* Guile parameter type name. */
78 const char *pname;
80 /* The type of the parameter. */
81 enum var_types type;
83 /* Extra literals, such as `unlimited', accepted in lieu of a number. */
84 const literal_def *extra_literals;
86 /* The docs for the parameter. */
87 char *set_doc;
88 char *show_doc;
89 char *doc;
91 /* The corresponding gdb command objects.
92 These are NULL if the parameter has not been registered yet, or
93 is no longer registered. */
94 set_show_commands commands;
96 /* The value of the parameter. */
97 union pascm_variable value;
99 /* For an enum parameter, the possible values. The vector lives in GC
100 space, it will be freed with the smob. */
101 const char * const *enumeration;
103 /* The set_func function or #f if not specified.
104 This function is called *after* the parameter is set.
105 It returns a string that will be displayed to the user. */
106 SCM set_func;
108 /* The show_func function or #f if not specified.
109 This function returns the string that is printed. */
110 SCM show_func;
112 /* The <gdb:parameter> object we are contained in, needed to
113 protect/unprotect the object since a reference to it comes from
114 non-gc-managed space (the command context pointer). */
115 SCM containing_scm;
118 /* Guile parameter types as in PARAMETER_TYPES later on. */
120 enum scm_param_types
122 param_boolean,
123 param_auto_boolean,
124 param_zinteger,
125 param_uinteger,
126 param_zuinteger,
127 param_zuinteger_unlimited,
128 param_string,
129 param_string_noescape,
130 param_optional_filename,
131 param_filename,
132 param_enum,
135 /* Translation from Guile parameters to GDB variable types. Keep in the
136 same order as SCM_PARAM_TYPES due to C++'s lack of designated initializers. */
138 static const struct
140 /* The type of the parameter. */
141 enum var_types type;
143 /* Extra literals, such as `unlimited', accepted in lieu of a number. */
144 const literal_def *extra_literals;
146 param_to_var[] =
148 { var_boolean },
149 { var_auto_boolean },
150 { var_integer },
151 { var_uinteger, uinteger_unlimited_literals },
152 { var_uinteger },
153 { var_pinteger, pinteger_unlimited_literals },
154 { var_string },
155 { var_string_noescape },
156 { var_optional_filename },
157 { var_filename },
158 { var_enum }
161 /* Wraps a setting around an existing param_smob. This abstraction
162 is used to manipulate the value in S->VALUE in a type safe manner using
163 the setting interface. */
165 static setting
166 make_setting (param_smob *s)
168 enum var_types type = s->type;
170 if (var_type_uses<bool> (type))
171 return setting (type, &s->value.boolval);
172 else if (var_type_uses<int> (type))
173 return setting (type, &s->value.intval, s->extra_literals);
174 else if (var_type_uses<auto_boolean> (type))
175 return setting (type, &s->value.autoboolval);
176 else if (var_type_uses<unsigned int> (type))
177 return setting (type, &s->value.uintval, s->extra_literals);
178 else if (var_type_uses<std::string> (type))
179 return setting (type, s->value.stringval);
180 else if (var_type_uses<const char *> (type))
181 return setting (type, &s->value.cstringval);
182 else
183 gdb_assert_not_reached ("unhandled var type");
186 static const char param_smob_name[] = "gdb:parameter";
188 /* The tag Guile knows the param smob by. */
189 static scm_t_bits parameter_smob_tag;
191 /* Keywords used by make-parameter!. */
192 static SCM command_class_keyword;
193 static SCM parameter_type_keyword;
194 static SCM enum_list_keyword;
195 static SCM set_func_keyword;
196 static SCM show_func_keyword;
197 static SCM doc_keyword;
198 static SCM set_doc_keyword;
199 static SCM show_doc_keyword;
200 static SCM initial_value_keyword;
201 static SCM auto_keyword;
203 static int pascm_is_valid (param_smob *);
204 static const char *pascm_param_type_name (enum scm_param_types type);
205 static SCM pascm_param_value (const setting &var, int arg_pos,
206 const char *func_name);
208 /* Administrivia for parameter smobs. */
210 static int
211 pascm_print_param_smob (SCM self, SCM port, scm_print_state *pstate)
213 param_smob *p_smob = (param_smob *) SCM_SMOB_DATA (self);
214 SCM value;
216 gdbscm_printf (port, "#<%s", param_smob_name);
218 gdbscm_printf (port, " %s", p_smob->name);
220 if (! pascm_is_valid (p_smob))
221 scm_puts (" {invalid}", port);
223 gdbscm_printf (port, " %s ", p_smob->pname);
225 value = pascm_param_value (make_setting (p_smob), GDBSCM_ARG_NONE, NULL);
226 scm_display (value, port);
228 scm_puts (">", port);
230 scm_remember_upto_here_1 (self);
232 /* Non-zero means success. */
233 return 1;
236 /* Create an empty (uninitialized) parameter. */
238 static SCM
239 pascm_make_param_smob (void)
241 param_smob *p_smob = (param_smob *)
242 scm_gc_malloc (sizeof (param_smob), param_smob_name);
243 SCM p_scm;
245 memset (p_smob, 0, sizeof (*p_smob));
246 p_smob->cmd_class = no_class;
247 p_smob->type = var_boolean; /* ARI: var_boolean */
248 p_smob->set_func = SCM_BOOL_F;
249 p_smob->show_func = SCM_BOOL_F;
250 p_scm = scm_new_smob (parameter_smob_tag, (scm_t_bits) p_smob);
251 p_smob->containing_scm = p_scm;
252 gdbscm_init_gsmob (&p_smob->base);
254 return p_scm;
257 /* Returns non-zero if SCM is a <gdb:parameter> object. */
259 static int
260 pascm_is_parameter (SCM scm)
262 return SCM_SMOB_PREDICATE (parameter_smob_tag, scm);
265 /* (gdb:parameter? scm) -> boolean */
267 static SCM
268 gdbscm_parameter_p (SCM scm)
270 return scm_from_bool (pascm_is_parameter (scm));
273 /* Returns the <gdb:parameter> object in SELF.
274 Throws an exception if SELF is not a <gdb:parameter> object. */
276 static SCM
277 pascm_get_param_arg_unsafe (SCM self, int arg_pos, const char *func_name)
279 SCM_ASSERT_TYPE (pascm_is_parameter (self), self, arg_pos, func_name,
280 param_smob_name);
282 return self;
285 /* Returns a pointer to the parameter smob of SELF.
286 Throws an exception if SELF is not a <gdb:parameter> object. */
288 static param_smob *
289 pascm_get_param_smob_arg_unsafe (SCM self, int arg_pos, const char *func_name)
291 SCM p_scm = pascm_get_param_arg_unsafe (self, arg_pos, func_name);
292 param_smob *p_smob = (param_smob *) SCM_SMOB_DATA (p_scm);
294 return p_smob;
297 /* Return non-zero if parameter P_SMOB is valid. */
299 static int
300 pascm_is_valid (param_smob *p_smob)
302 return p_smob->commands.set != nullptr;
305 /* A helper function which return the default documentation string for
306 a parameter (which is to say that it's undocumented). */
308 static char *
309 get_doc_string (void)
311 return xstrdup (_("This command is not documented."));
314 /* Subroutine of pascm_set_func, pascm_show_func to simplify them.
315 Signal the error returned from calling set_func/show_func. */
317 static void
318 pascm_signal_setshow_error (SCM exception, const char *msg)
320 /* Don't print the stack if this was an error signalled by the command
321 itself. */
322 if (gdbscm_user_error_p (gdbscm_exception_key (exception)))
324 gdb::unique_xmalloc_ptr<char> excp_text
325 = gdbscm_exception_message_to_string (exception);
327 error ("%s", excp_text.get ());
329 else
331 gdbscm_print_gdb_exception (SCM_BOOL_F, exception);
332 error ("%s", msg);
336 /* A callback function that is registered against the respective
337 add_setshow_* set_func prototype. This function will call
338 the Scheme function "set_func" which must exist.
339 Note: ARGS is always passed as NULL. */
341 static void
342 pascm_set_func (const char *args, int from_tty, struct cmd_list_element *c)
344 param_smob *p_smob = (param_smob *) c->context ();
345 SCM self, result, exception;
347 gdb_assert (gdbscm_is_procedure (p_smob->set_func));
349 self = p_smob->containing_scm;
351 result = gdbscm_safe_call_1 (p_smob->set_func, self, gdbscm_user_error_p);
353 if (gdbscm_is_exception (result))
355 pascm_signal_setshow_error (result,
356 _("Error occurred setting parameter."));
359 if (!scm_is_string (result))
360 error (_("Result of %s set-func is not a string."), p_smob->name);
362 gdb::unique_xmalloc_ptr<char> msg = gdbscm_scm_to_host_string (result, NULL,
363 &exception);
364 if (msg == NULL)
366 gdbscm_print_gdb_exception (SCM_BOOL_F, exception);
367 error (_("Error converting show text to host string."));
370 /* GDB is usually silent when a parameter is set. */
371 if (*msg.get () != '\0')
372 gdb_printf ("%s\n", msg.get ());
375 /* A callback function that is registered against the respective
376 add_setshow_* show_func prototype. This function will call
377 the Scheme function "show_func" which must exist and must return a
378 string that is then printed to FILE. */
380 static void
381 pascm_show_func (struct ui_file *file, int from_tty,
382 struct cmd_list_element *c, const char *value)
384 param_smob *p_smob = (param_smob *) c->context ();
385 SCM value_scm, self, result, exception;
387 gdb_assert (gdbscm_is_procedure (p_smob->show_func));
389 value_scm = gdbscm_scm_from_host_string (value, strlen (value));
390 if (gdbscm_is_exception (value_scm))
392 error (_("Error converting parameter value \"%s\" to Scheme string."),
393 value);
395 self = p_smob->containing_scm;
397 result = gdbscm_safe_call_2 (p_smob->show_func, self, value_scm,
398 gdbscm_user_error_p);
400 if (gdbscm_is_exception (result))
402 pascm_signal_setshow_error (result,
403 _("Error occurred showing parameter."));
406 gdb::unique_xmalloc_ptr<char> msg = gdbscm_scm_to_host_string (result, NULL,
407 &exception);
408 if (msg == NULL)
410 gdbscm_print_gdb_exception (SCM_BOOL_F, exception);
411 error (_("Error converting show text to host string."));
414 gdb_printf (file, "%s\n", msg.get ());
417 /* A helper function that dispatches to the appropriate add_setshow
418 function. */
420 static set_show_commands
421 add_setshow_generic (enum var_types param_type,
422 const literal_def *extra_literals,
423 enum command_class cmd_class,
424 char *cmd_name, param_smob *self,
425 char *set_doc, char *show_doc, char *help_doc,
426 cmd_func_ftype *set_func,
427 show_value_ftype *show_func,
428 struct cmd_list_element **set_list,
429 struct cmd_list_element **show_list)
431 set_show_commands commands;
433 switch (param_type)
435 case var_boolean:
436 commands = add_setshow_boolean_cmd (cmd_name, cmd_class,
437 &self->value.boolval, set_doc,
438 show_doc, help_doc, set_func,
439 show_func, set_list, show_list);
440 break;
442 case var_auto_boolean:
443 commands = add_setshow_auto_boolean_cmd (cmd_name, cmd_class,
444 &self->value.autoboolval,
445 set_doc, show_doc, help_doc,
446 set_func, show_func, set_list,
447 show_list);
448 break;
450 case var_uinteger:
451 commands = add_setshow_uinteger_cmd (cmd_name, cmd_class,
452 &self->value.uintval,
453 extra_literals, set_doc,
454 show_doc, help_doc, set_func,
455 show_func, set_list, show_list);
456 break;
458 case var_integer:
459 commands = add_setshow_integer_cmd (cmd_name, cmd_class,
460 &self->value.intval,
461 extra_literals, set_doc,
462 show_doc, help_doc, set_func,
463 show_func, set_list, show_list);
464 break;
466 case var_pinteger:
467 commands = add_setshow_pinteger_cmd (cmd_name, cmd_class,
468 &self->value.intval,
469 extra_literals, set_doc,
470 show_doc, help_doc, set_func,
471 show_func, set_list, show_list);
472 break;
474 case var_string:
475 commands = add_setshow_string_cmd (cmd_name, cmd_class,
476 self->value.stringval, set_doc,
477 show_doc, help_doc, set_func,
478 show_func, set_list, show_list);
479 break;
481 case var_string_noescape:
482 commands = add_setshow_string_noescape_cmd (cmd_name, cmd_class,
483 self->value.stringval,
484 set_doc, show_doc, help_doc,
485 set_func, show_func, set_list,
486 show_list);
488 break;
490 case var_optional_filename:
491 commands = add_setshow_optional_filename_cmd (cmd_name, cmd_class,
492 self->value.stringval,
493 set_doc, show_doc, help_doc,
494 set_func, show_func,
495 set_list, show_list);
496 break;
498 case var_filename:
499 commands = add_setshow_filename_cmd (cmd_name, cmd_class,
500 self->value.stringval, set_doc,
501 show_doc, help_doc, set_func,
502 show_func, set_list, show_list);
503 break;
505 case var_enum:
506 /* Initialize the value, just in case. */
507 make_setting (self).set<const char *> (self->enumeration[0]);
508 commands = add_setshow_enum_cmd (cmd_name, cmd_class, self->enumeration,
509 &self->value.cstringval, set_doc,
510 show_doc, help_doc, set_func, show_func,
511 set_list, show_list);
512 break;
514 default:
515 gdb_assert_not_reached ("bad param_type value");
518 /* Register Scheme object against the commandsparameter context. Perform this
519 task against both lists. */
520 commands.set->set_context (self);
521 commands.show->set_context (self);
523 return commands;
526 /* Return an array of strings corresponding to the enum values for
527 ENUM_VALUES_SCM.
528 Throws an exception if there's a problem with the values.
529 Space for the result is allocated from the GC heap. */
531 static const char * const *
532 compute_enum_list (SCM enum_values_scm, int arg_pos, const char *func_name)
534 long i, size;
535 char **enum_values;
536 const char * const *result;
538 SCM_ASSERT_TYPE (gdbscm_is_true (scm_list_p (enum_values_scm)),
539 enum_values_scm, arg_pos, func_name, _("list"));
541 size = scm_ilength (enum_values_scm);
542 if (size == 0)
544 gdbscm_out_of_range_error (FUNC_NAME, arg_pos, enum_values_scm,
545 _("enumeration list is empty"));
548 enum_values = XCNEWVEC (char *, size + 1);
550 i = 0;
551 while (!scm_is_eq (enum_values_scm, SCM_EOL))
553 SCM value = scm_car (enum_values_scm);
554 SCM exception;
556 if (!scm_is_string (value))
558 freeargv (enum_values);
559 SCM_ASSERT_TYPE (0, value, arg_pos, func_name, _("string"));
561 enum_values[i] = gdbscm_scm_to_host_string (value, NULL,
562 &exception).release ();
563 if (enum_values[i] == NULL)
565 freeargv (enum_values);
566 gdbscm_throw (exception);
568 ++i;
569 enum_values_scm = scm_cdr (enum_values_scm);
571 gdb_assert (i == size);
573 result = gdbscm_gc_dup_argv (enum_values);
574 freeargv (enum_values);
575 return result;
578 static const scheme_integer_constant parameter_types[] =
580 { "PARAM_BOOLEAN", param_boolean }, /* ARI: param_boolean */
581 { "PARAM_AUTO_BOOLEAN", param_auto_boolean },
582 { "PARAM_ZINTEGER", param_zinteger },
583 { "PARAM_UINTEGER", param_uinteger },
584 { "PARAM_ZUINTEGER", param_zuinteger },
585 { "PARAM_ZUINTEGER_UNLIMITED", param_zuinteger_unlimited },
586 { "PARAM_STRING", param_string },
587 { "PARAM_STRING_NOESCAPE", param_string_noescape },
588 { "PARAM_OPTIONAL_FILENAME", param_optional_filename },
589 { "PARAM_FILENAME", param_filename },
590 { "PARAM_ENUM", param_enum },
592 END_INTEGER_CONSTANTS
595 /* Return non-zero if PARAM_TYPE is a valid parameter type. */
597 static int
598 pascm_valid_parameter_type_p (int param_type)
600 int i;
602 for (i = 0; parameter_types[i].name != NULL; ++i)
604 if (parameter_types[i].value == param_type)
605 return 1;
608 return 0;
611 /* Return PARAM_TYPE as a string. */
613 static const char *
614 pascm_param_type_name (enum scm_param_types param_type)
616 int i;
618 for (i = 0; parameter_types[i].name != NULL; ++i)
620 if (parameter_types[i].value == param_type)
621 return parameter_types[i].name;
624 gdb_assert_not_reached ("bad parameter type");
627 /* Return the value of a gdb parameter as a Scheme value.
628 If the var_type of VAR is not supported, then a <gdb:exception> object is
629 returned. */
631 static SCM
632 pascm_param_value (const setting &var, int arg_pos, const char *func_name)
634 switch (var.type ())
636 case var_string:
637 case var_string_noescape:
638 case var_optional_filename:
639 case var_filename:
641 const std::string &str = var.get<std::string> ();
642 return gdbscm_scm_from_host_string (str.c_str (), str.length ());
645 case var_enum:
647 const char *str = var.get<const char *> ();
648 if (str == nullptr)
649 str = "";
650 return gdbscm_scm_from_host_string (str, strlen (str));
653 case var_boolean:
655 if (var.get<bool> ())
656 return SCM_BOOL_T;
657 else
658 return SCM_BOOL_F;
661 case var_auto_boolean:
663 enum auto_boolean ab = var.get<enum auto_boolean> ();
665 if (ab == AUTO_BOOLEAN_TRUE)
666 return SCM_BOOL_T;
667 else if (ab == AUTO_BOOLEAN_FALSE)
668 return SCM_BOOL_F;
669 else
670 return auto_keyword;
673 case var_uinteger:
674 case var_integer:
675 case var_pinteger:
677 LONGEST value
678 = (var.type () == var_uinteger
679 ? static_cast<LONGEST> (var.get<unsigned int> ())
680 : static_cast<LONGEST> (var.get<int> ()));
682 if (var.extra_literals () != nullptr)
683 for (const literal_def *l = var.extra_literals ();
684 l->literal != nullptr;
685 l++)
686 if (value == l->use)
687 return scm_from_latin1_keyword (l->literal);
688 if (var.type () == var_pinteger)
689 gdb_assert (value >= 0);
691 if (var.type () == var_uinteger)
692 return scm_from_uint (static_cast<unsigned int> (value));
693 else
694 return scm_from_int (static_cast<int> (value));
697 default:
698 break;
701 return gdbscm_make_out_of_range_error (func_name, arg_pos,
702 scm_from_int (var.type ()),
703 _("program error: unhandled type"));
706 /* Set the value of a parameter of type P_SMOB->TYPE in P_SMOB->VAR from VALUE.
707 ENUMERATION is the list of enum values for enum parameters, otherwise NULL.
708 Throws a Scheme exception if VALUE_SCM is invalid for TYPE. */
710 static void
711 pascm_set_param_value_x (param_smob *p_smob,
712 const char * const *enumeration,
713 SCM value, int arg_pos, const char *func_name)
715 setting var = make_setting (p_smob);
717 switch (var.type ())
719 case var_string:
720 case var_string_noescape:
721 case var_optional_filename:
722 case var_filename:
723 SCM_ASSERT_TYPE (scm_is_string (value)
724 || (var.type () != var_filename
725 && gdbscm_is_false (value)),
726 value, arg_pos, func_name,
727 _("string or #f for non-PARAM_FILENAME parameters"));
728 if (gdbscm_is_false (value))
729 var.set<std::string> ("");
730 else
732 SCM exception;
734 gdb::unique_xmalloc_ptr<char> string
735 = gdbscm_scm_to_host_string (value, nullptr, &exception);
736 if (string == nullptr)
737 gdbscm_throw (exception);
738 var.set<std::string> (string.release ());
740 break;
742 case var_enum:
744 int i;
745 SCM exception;
747 SCM_ASSERT_TYPE (scm_is_string (value), value, arg_pos, func_name,
748 _("string"));
749 gdb::unique_xmalloc_ptr<char> str
750 = gdbscm_scm_to_host_string (value, nullptr, &exception);
751 if (str == nullptr)
752 gdbscm_throw (exception);
753 for (i = 0; enumeration[i]; ++i)
755 if (strcmp (enumeration[i], str.get ()) == 0)
756 break;
758 if (enumeration[i] == nullptr)
760 gdbscm_out_of_range_error (func_name, arg_pos, value,
761 _("not member of enumeration"));
763 var.set<const char *> (enumeration[i]);
764 break;
767 case var_boolean:
768 SCM_ASSERT_TYPE (gdbscm_is_bool (value), value, arg_pos, func_name,
769 _("boolean"));
770 var.set<bool> (gdbscm_is_true (value));
771 break;
773 case var_auto_boolean:
774 SCM_ASSERT_TYPE (gdbscm_is_bool (value)
775 || scm_is_eq (value, auto_keyword),
776 value, arg_pos, func_name,
777 _("boolean or #:auto"));
778 if (scm_is_eq (value, auto_keyword))
779 var.set<enum auto_boolean> (AUTO_BOOLEAN_AUTO);
780 else if (gdbscm_is_true (value))
781 var.set<enum auto_boolean> (AUTO_BOOLEAN_TRUE);
782 else
783 var.set<enum auto_boolean> (AUTO_BOOLEAN_FALSE);
784 break;
786 case var_integer:
787 case var_uinteger:
788 case var_pinteger:
790 const literal_def *extra_literals = p_smob->extra_literals;
791 enum tribool allowed = TRIBOOL_UNKNOWN;
792 enum var_types var_type = var.type ();
793 bool integer = scm_is_integer (value);
794 bool keyword = scm_is_keyword (value);
795 std::string buffer = "";
796 size_t count = 0;
797 LONGEST val;
799 if (extra_literals != nullptr)
800 for (const literal_def *l = extra_literals;
801 l->literal != nullptr;
802 l++, count++)
804 if (count != 0)
805 buffer += ", ";
806 buffer = buffer + "#:" + l->literal;
807 if (keyword
808 && allowed == TRIBOOL_UNKNOWN
809 && scm_is_eq (value,
810 scm_from_latin1_keyword (l->literal)))
812 val = l->use;
813 allowed = TRIBOOL_TRUE;
817 if (allowed == TRIBOOL_UNKNOWN)
819 if (extra_literals == nullptr)
820 SCM_ASSERT_TYPE (integer, value, arg_pos, func_name,
821 _("integer"));
822 else if (count > 1)
823 SCM_ASSERT_TYPE (integer, value, arg_pos, func_name,
824 string_printf (_("integer or one of: %s"),
825 buffer.c_str ()).c_str ());
826 else
827 SCM_ASSERT_TYPE (integer, value, arg_pos, func_name,
828 string_printf (_("integer or %s"),
829 buffer.c_str ()).c_str ());
831 val = (var_type == var_uinteger
832 ? static_cast<LONGEST> (scm_to_uint (value))
833 : static_cast<LONGEST> (scm_to_int (value)));
835 if (extra_literals != nullptr)
836 for (const literal_def *l = extra_literals;
837 l->literal != nullptr;
838 l++)
840 if (l->val.has_value () && val == *l->val)
842 allowed = TRIBOOL_TRUE;
843 val = l->use;
844 break;
846 else if (val == l->use)
847 allowed = TRIBOOL_FALSE;
851 if (allowed == TRIBOOL_UNKNOWN)
853 if (val > UINT_MAX || val < INT_MIN
854 || (var_type == var_uinteger && val < 0)
855 || (var_type == var_integer && val > INT_MAX)
856 || (var_type == var_pinteger && val < 0)
857 || (var_type == var_pinteger && val > INT_MAX))
858 allowed = TRIBOOL_FALSE;
860 if (allowed == TRIBOOL_FALSE)
861 gdbscm_out_of_range_error (func_name, arg_pos, value,
862 _("integer out of range"));
864 if (var_type == var_uinteger)
865 var.set<unsigned int> (static_cast<unsigned int> (val));
866 else
867 var.set<int> (static_cast<int> (val));
869 break;
872 default:
873 gdb_assert_not_reached ("bad parameter type");
877 /* Free function for a param_smob. */
878 static size_t
879 pascm_free_parameter_smob (SCM self)
881 param_smob *p_smob = (param_smob *) SCM_SMOB_DATA (self);
883 if (var_type_uses<std::string> (p_smob->type))
885 delete p_smob->value.stringval;
886 p_smob->value.stringval = nullptr;
889 return 0;
892 /* Parameter Scheme functions. */
894 /* (make-parameter name
895 [#:command-class cmd-class] [#:parameter-type param-type]
896 [#:enum-list enum-list] [#:set-func function] [#:show-func function]
897 [#:doc <string>] [#:set-doc <string>] [#:show-doc <string>]
898 [#:initial-value initial-value]) -> <gdb:parameter>
900 NAME is the name of the parameter. It may consist of multiple
901 words, in which case the final word is the name of the new parameter,
902 and earlier words must be prefix commands.
904 CMD-CLASS is the kind of command. It should be one of the COMMAND_*
905 constants defined in the gdb module.
907 PARAM_TYPE is the type of the parameter. It should be one of the
908 PARAM_* constants defined in the gdb module.
910 If PARAM-TYPE is PARAM_ENUM, then ENUM-LIST is a list of strings that
911 are the valid values for this parameter. The first value is the default.
913 SET-FUNC, if provided, is called after the parameter is set.
914 It is a function of one parameter: the <gdb:parameter> object.
915 It must return a string to be displayed to the user.
916 Setting a parameter is typically a silent operation, so typically ""
917 should be returned.
919 SHOW-FUNC, if provided, returns the string that is printed.
920 It is a function of two parameters: the <gdb:parameter> object
921 and the current value of the parameter as a string.
923 DOC, SET-DOC, SHOW-DOC are the doc strings for the parameter.
925 INITIAL-VALUE is the initial value of the parameter.
927 The result is the <gdb:parameter> Scheme object.
928 The parameter is not available to be used yet, however.
929 It must still be added to gdb with register-parameter!. */
931 static SCM
932 gdbscm_make_parameter (SCM name_scm, SCM rest)
934 const SCM keywords[] = {
935 command_class_keyword, parameter_type_keyword, enum_list_keyword,
936 set_func_keyword, show_func_keyword,
937 doc_keyword, set_doc_keyword, show_doc_keyword,
938 initial_value_keyword, SCM_BOOL_F
940 int cmd_class_arg_pos = -1, param_type_arg_pos = -1;
941 int enum_list_arg_pos = -1, set_func_arg_pos = -1, show_func_arg_pos = -1;
942 int doc_arg_pos = -1, set_doc_arg_pos = -1, show_doc_arg_pos = -1;
943 int initial_value_arg_pos = -1;
944 char *s;
945 char *name;
946 int cmd_class = no_class;
947 int param_type = param_boolean; /* ARI: param_boolean */
948 SCM enum_list_scm = SCM_BOOL_F;
949 SCM set_func = SCM_BOOL_F, show_func = SCM_BOOL_F;
950 char *doc = NULL, *set_doc = NULL, *show_doc = NULL;
951 SCM initial_value_scm = SCM_BOOL_F;
952 const char * const *enum_list = NULL;
953 SCM p_scm;
954 param_smob *p_smob;
956 gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, keywords, "s#iiOOOsssO",
957 name_scm, &name, rest,
958 &cmd_class_arg_pos, &cmd_class,
959 &param_type_arg_pos, &param_type,
960 &enum_list_arg_pos, &enum_list_scm,
961 &set_func_arg_pos, &set_func,
962 &show_func_arg_pos, &show_func,
963 &doc_arg_pos, &doc,
964 &set_doc_arg_pos, &set_doc,
965 &show_doc_arg_pos, &show_doc,
966 &initial_value_arg_pos, &initial_value_scm);
968 /* If doc is NULL, leave it NULL. See add_setshow_cmd_full. */
969 if (set_doc == NULL)
970 set_doc = get_doc_string ();
971 if (show_doc == NULL)
972 show_doc = get_doc_string ();
974 s = name;
975 name = gdbscm_canonicalize_command_name (s, 0);
976 xfree (s);
977 if (doc != NULL)
979 s = doc;
980 doc = gdbscm_gc_xstrdup (s);
981 xfree (s);
983 s = set_doc;
984 set_doc = gdbscm_gc_xstrdup (s);
985 xfree (s);
986 s = show_doc;
987 show_doc = gdbscm_gc_xstrdup (s);
988 xfree (s);
990 if (!gdbscm_valid_command_class_p (cmd_class))
992 gdbscm_out_of_range_error (FUNC_NAME, cmd_class_arg_pos,
993 scm_from_int (cmd_class),
994 _("invalid command class argument"));
996 if (!pascm_valid_parameter_type_p (param_type))
998 gdbscm_out_of_range_error (FUNC_NAME, param_type_arg_pos,
999 scm_from_int (param_type),
1000 _("invalid parameter type argument"));
1002 if (enum_list_arg_pos > 0 && param_type != param_enum)
1004 gdbscm_misc_error (FUNC_NAME, enum_list_arg_pos, enum_list_scm,
1005 _("#:enum-values can only be provided with PARAM_ENUM"));
1007 if (enum_list_arg_pos < 0 && param_type == param_enum)
1009 gdbscm_misc_error (FUNC_NAME, GDBSCM_ARG_NONE, SCM_BOOL_F,
1010 _("PARAM_ENUM requires an enum-values argument"));
1012 if (set_func_arg_pos > 0)
1014 SCM_ASSERT_TYPE (gdbscm_is_procedure (set_func), set_func,
1015 set_func_arg_pos, FUNC_NAME, _("procedure"));
1017 if (show_func_arg_pos > 0)
1019 SCM_ASSERT_TYPE (gdbscm_is_procedure (show_func), show_func,
1020 show_func_arg_pos, FUNC_NAME, _("procedure"));
1022 if (param_type == param_enum)
1024 /* Note: enum_list lives in GC space, so we don't have to worry about
1025 freeing it if we later throw an exception. */
1026 enum_list = compute_enum_list (enum_list_scm, enum_list_arg_pos,
1027 FUNC_NAME);
1030 /* If initial-value is a function, we need the parameter object constructed
1031 to pass it to the function. A typical thing the function may want to do
1032 is add an object-property to it to record the last known good value. */
1033 p_scm = pascm_make_param_smob ();
1034 p_smob = (param_smob *) SCM_SMOB_DATA (p_scm);
1035 /* These are all stored in GC space so that we don't have to worry about
1036 freeing them if we throw an exception. */
1037 p_smob->name = name;
1038 p_smob->cmd_class = (enum command_class) cmd_class;
1039 p_smob->pname
1040 = pascm_param_type_name (static_cast<enum scm_param_types> (param_type));
1041 p_smob->type = param_to_var[param_type].type;
1042 p_smob->extra_literals = param_to_var[param_type].extra_literals;
1043 p_smob->doc = doc;
1044 p_smob->set_doc = set_doc;
1045 p_smob->show_doc = show_doc;
1046 p_smob->enumeration = enum_list;
1047 p_smob->set_func = set_func;
1048 p_smob->show_func = show_func;
1050 scm_set_smob_free (parameter_smob_tag, pascm_free_parameter_smob);
1051 if (var_type_uses<std::string> (p_smob->type))
1052 p_smob->value.stringval = new std::string;
1054 if (initial_value_arg_pos > 0)
1056 if (gdbscm_is_procedure (initial_value_scm))
1058 initial_value_scm = gdbscm_safe_call_1 (initial_value_scm,
1059 p_smob->containing_scm, NULL);
1060 if (gdbscm_is_exception (initial_value_scm))
1061 gdbscm_throw (initial_value_scm);
1063 pascm_set_param_value_x (p_smob, enum_list,
1064 initial_value_scm,
1065 initial_value_arg_pos, FUNC_NAME);
1068 return p_scm;
1071 /* Subroutine of gdbscm_register_parameter_x to simplify it.
1072 Return non-zero if parameter NAME is already defined in LIST. */
1074 static int
1075 pascm_parameter_defined_p (const char *name, struct cmd_list_element *list)
1077 struct cmd_list_element *c;
1079 c = lookup_cmd_1 (&name, list, NULL, NULL, 1);
1081 /* If the name is ambiguous that's ok, it's a new parameter still. */
1082 return c != NULL && c != CMD_LIST_AMBIGUOUS;
1085 /* (register-parameter! <gdb:parameter>) -> unspecified
1087 It is an error to register a pre-existing parameter. */
1089 static SCM
1090 gdbscm_register_parameter_x (SCM self)
1092 param_smob *p_smob
1093 = pascm_get_param_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
1094 char *cmd_name;
1095 struct cmd_list_element **set_list, **show_list;
1097 if (pascm_is_valid (p_smob))
1098 scm_misc_error (FUNC_NAME, _("parameter is already registered"), SCM_EOL);
1100 cmd_name = gdbscm_parse_command_name (p_smob->name, FUNC_NAME, SCM_ARG1,
1101 &set_list, &setlist);
1102 xfree (cmd_name);
1103 cmd_name = gdbscm_parse_command_name (p_smob->name, FUNC_NAME, SCM_ARG1,
1104 &show_list, &showlist);
1105 p_smob->cmd_name = gdbscm_gc_xstrdup (cmd_name);
1106 xfree (cmd_name);
1108 if (pascm_parameter_defined_p (p_smob->cmd_name, *set_list))
1110 gdbscm_misc_error (FUNC_NAME, SCM_ARG1, self,
1111 _("parameter exists, \"set\" command is already defined"));
1113 if (pascm_parameter_defined_p (p_smob->cmd_name, *show_list))
1115 gdbscm_misc_error (FUNC_NAME, SCM_ARG1, self,
1116 _("parameter exists, \"show\" command is already defined"));
1119 gdbscm_gdb_exception exc {};
1122 p_smob->commands = add_setshow_generic
1123 (p_smob->type, p_smob->extra_literals,
1124 p_smob->cmd_class, p_smob->cmd_name, p_smob,
1125 p_smob->set_doc, p_smob->show_doc, p_smob->doc,
1126 (gdbscm_is_procedure (p_smob->set_func) ? pascm_set_func : NULL),
1127 (gdbscm_is_procedure (p_smob->show_func) ? pascm_show_func : NULL),
1128 set_list, show_list);
1130 catch (const gdb_exception &except)
1132 exc = unpack (except);
1135 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
1136 /* Note: At this point the parameter exists in gdb.
1137 So no more errors after this point. */
1139 /* The owner of this parameter is not in GC-controlled memory, so we need
1140 to protect it from GC until the parameter is deleted. */
1141 scm_gc_protect_object (p_smob->containing_scm);
1143 return SCM_UNSPECIFIED;
1146 /* (parameter-value <gdb:parameter>) -> value
1147 (parameter-value <string>) -> value */
1149 static SCM
1150 gdbscm_parameter_value (SCM self)
1152 SCM_ASSERT_TYPE (pascm_is_parameter (self) || scm_is_string (self),
1153 self, SCM_ARG1, FUNC_NAME, _("<gdb:parameter> or string"));
1155 if (pascm_is_parameter (self))
1157 param_smob *p_smob = pascm_get_param_smob_arg_unsafe (self, SCM_ARG1,
1158 FUNC_NAME);
1160 return pascm_param_value (make_setting (p_smob), SCM_ARG1, FUNC_NAME);
1162 else
1164 SCM except_scm;
1165 struct cmd_list_element *alias, *prefix, *cmd;
1166 char *newarg;
1167 int found = -1;
1168 gdbscm_gdb_exception except {};
1170 gdb::unique_xmalloc_ptr<char> name
1171 = gdbscm_scm_to_host_string (self, NULL, &except_scm);
1172 if (name == NULL)
1173 gdbscm_throw (except_scm);
1174 newarg = concat ("show ", name.get (), (char *) NULL);
1177 found = lookup_cmd_composition (newarg, &alias, &prefix, &cmd);
1179 catch (const gdb_exception &ex)
1181 except = unpack (ex);
1184 xfree (newarg);
1185 GDBSCM_HANDLE_GDB_EXCEPTION (except);
1186 if (!found)
1188 gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
1189 _("parameter not found"));
1192 if (!cmd->var.has_value ())
1194 gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
1195 _("not a parameter"));
1198 return pascm_param_value (*cmd->var, SCM_ARG1, FUNC_NAME);
1202 /* (set-parameter-value! <gdb:parameter> value) -> unspecified */
1204 static SCM
1205 gdbscm_set_parameter_value_x (SCM self, SCM value)
1207 param_smob *p_smob = pascm_get_param_smob_arg_unsafe (self, SCM_ARG1,
1208 FUNC_NAME);
1210 pascm_set_param_value_x (p_smob, p_smob->enumeration,
1211 value, SCM_ARG2, FUNC_NAME);
1213 return SCM_UNSPECIFIED;
1216 /* Initialize the Scheme parameter support. */
1218 static const scheme_function parameter_functions[] =
1220 { "make-parameter", 1, 0, 1, as_a_scm_t_subr (gdbscm_make_parameter),
1222 Make a GDB parameter object.\n\
1224 Arguments: name\n\
1225 [#:command-class <cmd-class>] [#:parameter-type <parameter-type>]\n\
1226 [#:enum-list <enum-list>]\n\
1227 [#:set-func function] [#:show-func function]\n\
1228 [#:doc string] [#:set-doc string] [#:show-doc string]\n\
1229 [#:initial-value initial-value]\n\
1230 name: The name of the command. It may consist of multiple words,\n\
1231 in which case the final word is the name of the new parameter, and\n\
1232 earlier words must be prefix commands.\n\
1233 cmd-class: The class of the command, one of COMMAND_*.\n\
1234 The default is COMMAND_NONE.\n\
1235 parameter-type: The kind of parameter, one of PARAM_*\n\
1236 The default is PARAM_BOOLEAN.\n\
1237 enum-list: If parameter-type is PARAM_ENUM, then this specifies the set\n\
1238 of values of the enum.\n\
1239 set-func: A function of one parameter: the <gdb:parameter> object.\n\
1240 Called *after* the parameter has been set. Returns either \"\" or a\n\
1241 non-empty string to be displayed to the user.\n\
1242 If non-empty, GDB will add a trailing newline.\n\
1243 show-func: A function of two parameters: the <gdb:parameter> object\n\
1244 and the string representation of the current value.\n\
1245 The result is a string to be displayed to the user.\n\
1246 GDB will add a trailing newline.\n\
1247 doc: The \"doc string\" of the parameter.\n\
1248 set-doc: The \"doc string\" when setting the parameter.\n\
1249 show-doc: The \"doc string\" when showing the parameter.\n\
1250 initial-value: The initial value of the parameter." },
1252 { "register-parameter!", 1, 0, 0,
1253 as_a_scm_t_subr (gdbscm_register_parameter_x),
1255 Register a <gdb:parameter> object with GDB." },
1257 { "parameter?", 1, 0, 0, as_a_scm_t_subr (gdbscm_parameter_p),
1259 Return #t if the object is a <gdb:parameter> object." },
1261 { "parameter-value", 1, 0, 0, as_a_scm_t_subr (gdbscm_parameter_value),
1263 Return the value of a <gdb:parameter> object\n\
1264 or any gdb parameter if param is a string naming the parameter." },
1266 { "set-parameter-value!", 2, 0, 0,
1267 as_a_scm_t_subr (gdbscm_set_parameter_value_x),
1269 Set the value of a <gdb:parameter> object.\n\
1271 Arguments: <gdb:parameter> value" },
1273 END_FUNCTIONS
1276 void
1277 gdbscm_initialize_parameters (void)
1279 parameter_smob_tag
1280 = gdbscm_make_smob_type (param_smob_name, sizeof (param_smob));
1281 scm_set_smob_print (parameter_smob_tag, pascm_print_param_smob);
1283 gdbscm_define_integer_constants (parameter_types, 1);
1284 gdbscm_define_functions (parameter_functions, 1);
1286 command_class_keyword = scm_from_latin1_keyword ("command-class");
1287 parameter_type_keyword = scm_from_latin1_keyword ("parameter-type");
1288 enum_list_keyword = scm_from_latin1_keyword ("enum-list");
1289 set_func_keyword = scm_from_latin1_keyword ("set-func");
1290 show_func_keyword = scm_from_latin1_keyword ("show-func");
1291 doc_keyword = scm_from_latin1_keyword ("doc");
1292 set_doc_keyword = scm_from_latin1_keyword ("set-doc");
1293 show_doc_keyword = scm_from_latin1_keyword ("show-doc");
1294 initial_value_keyword = scm_from_latin1_keyword ("initial-value");
1295 auto_keyword = scm_from_latin1_keyword ("auto");