More updated translations
[binutils-gdb.git] / gdb / guile / scm-param.c
blob749c5ea1f7d06de6baab814e3cf52c414c594239
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 "cli/cli-cmds.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;
51 /* Hold a color. */
52 ui_file_style::color color;
55 /* A GDB parameter.
57 Note: Parameters are added to gdb using a two step process:
58 1) Call make-parameter to create a <gdb:parameter> object.
59 2) Call register-parameter! to add the parameter to gdb.
60 It is done this way so that the constructor, make-parameter, doesn't have
61 any side-effects. This means that the smob needs to store everything
62 that was passed to make-parameter. */
64 struct param_smob
66 /* This always appears first. */
67 gdb_smob base;
69 /* The parameter name. */
70 char *name;
72 /* The last word of the command.
73 This is needed because add_cmd requires us to allocate space
74 for it. :-( */
75 char *cmd_name;
77 /* One of the COMMAND_* constants. */
78 enum command_class cmd_class;
80 /* Guile parameter type name. */
81 const char *pname;
83 /* The type of the parameter. */
84 enum var_types type;
86 /* Extra literals, such as `unlimited', accepted in lieu of a number. */
87 const literal_def *extra_literals;
89 /* The docs for the parameter. */
90 char *set_doc;
91 char *show_doc;
92 char *doc;
94 /* The corresponding gdb command objects.
95 These are NULL if the parameter has not been registered yet, or
96 is no longer registered. */
97 set_show_commands commands;
99 /* The value of the parameter. */
100 union pascm_variable value;
102 /* For an enum parameter, the possible values. The vector lives in GC
103 space, it will be freed with the smob. */
104 const char * const *enumeration;
106 /* The set_func function or #f if not specified.
107 This function is called *after* the parameter is set.
108 It returns a string that will be displayed to the user. */
109 SCM set_func;
111 /* The show_func function or #f if not specified.
112 This function returns the string that is printed. */
113 SCM show_func;
115 /* The <gdb:parameter> object we are contained in, needed to
116 protect/unprotect the object since a reference to it comes from
117 non-gc-managed space (the command context pointer). */
118 SCM containing_scm;
121 /* Guile parameter types as in PARAMETER_TYPES later on. */
123 enum scm_param_types
125 param_boolean,
126 param_auto_boolean,
127 param_zinteger,
128 param_uinteger,
129 param_zuinteger,
130 param_zuinteger_unlimited,
131 param_string,
132 param_string_noescape,
133 param_optional_filename,
134 param_filename,
135 param_enum,
136 param_color,
139 /* Translation from Guile parameters to GDB variable types. Keep in the
140 same order as SCM_PARAM_TYPES due to C++'s lack of designated initializers. */
142 static const struct
144 /* The type of the parameter. */
145 enum var_types type;
147 /* Extra literals, such as `unlimited', accepted in lieu of a number. */
148 const literal_def *extra_literals;
150 param_to_var[] =
152 { var_boolean },
153 { var_auto_boolean },
154 { var_integer },
155 { var_uinteger, uinteger_unlimited_literals },
156 { var_uinteger },
157 { var_pinteger, pinteger_unlimited_literals },
158 { var_string },
159 { var_string_noescape },
160 { var_optional_filename },
161 { var_filename },
162 { var_enum },
163 { var_color }
166 /* Wraps a setting around an existing param_smob. This abstraction
167 is used to manipulate the value in S->VALUE in a type safe manner using
168 the setting interface. */
170 static setting
171 make_setting (param_smob *s)
173 enum var_types type = s->type;
175 if (var_type_uses<bool> (type))
176 return setting (type, &s->value.boolval);
177 else if (var_type_uses<int> (type))
178 return setting (type, &s->value.intval, s->extra_literals);
179 else if (var_type_uses<auto_boolean> (type))
180 return setting (type, &s->value.autoboolval);
181 else if (var_type_uses<unsigned int> (type))
182 return setting (type, &s->value.uintval, s->extra_literals);
183 else if (var_type_uses<std::string> (type))
184 return setting (type, s->value.stringval);
185 else if (var_type_uses<const char *> (type))
186 return setting (type, &s->value.cstringval);
187 else if (var_type_uses<ui_file_style::color> (s->type))
188 return setting (s->type, &s->value.color);
189 else
190 gdb_assert_not_reached ("unhandled var type");
193 static const char param_smob_name[] = "gdb:parameter";
195 /* The tag Guile knows the param smob by. */
196 static scm_t_bits parameter_smob_tag;
198 /* Keywords used by make-parameter!. */
199 static SCM command_class_keyword;
200 static SCM parameter_type_keyword;
201 static SCM enum_list_keyword;
202 static SCM set_func_keyword;
203 static SCM show_func_keyword;
204 static SCM doc_keyword;
205 static SCM set_doc_keyword;
206 static SCM show_doc_keyword;
207 static SCM initial_value_keyword;
208 static SCM auto_keyword;
210 static int pascm_is_valid (param_smob *);
211 static const char *pascm_param_type_name (enum scm_param_types type);
212 static SCM pascm_param_value (const setting &var, int arg_pos,
213 const char *func_name);
215 /* Administrivia for parameter smobs. */
217 static int
218 pascm_print_param_smob (SCM self, SCM port, scm_print_state *pstate)
220 param_smob *p_smob = (param_smob *) SCM_SMOB_DATA (self);
221 SCM value;
223 gdbscm_printf (port, "#<%s", param_smob_name);
225 gdbscm_printf (port, " %s", p_smob->name);
227 if (! pascm_is_valid (p_smob))
228 scm_puts (" {invalid}", port);
230 gdbscm_printf (port, " %s ", p_smob->pname);
232 value = pascm_param_value (make_setting (p_smob), GDBSCM_ARG_NONE, NULL);
233 scm_display (value, port);
235 scm_puts (">", port);
237 scm_remember_upto_here_1 (self);
239 /* Non-zero means success. */
240 return 1;
243 /* Create an empty (uninitialized) parameter. */
245 static SCM
246 pascm_make_param_smob (void)
248 param_smob *p_smob = (param_smob *)
249 scm_gc_calloc (sizeof (param_smob), param_smob_name);
250 SCM p_scm;
252 p_smob->cmd_class = no_class;
253 p_smob->type = var_boolean; /* ARI: var_boolean */
254 p_smob->set_func = SCM_BOOL_F;
255 p_smob->show_func = SCM_BOOL_F;
256 p_scm = scm_new_smob (parameter_smob_tag, (scm_t_bits) p_smob);
257 p_smob->containing_scm = p_scm;
258 gdbscm_init_gsmob (&p_smob->base);
260 return p_scm;
263 /* Returns non-zero if SCM is a <gdb:parameter> object. */
265 static int
266 pascm_is_parameter (SCM scm)
268 return SCM_SMOB_PREDICATE (parameter_smob_tag, scm);
271 /* (gdb:parameter? scm) -> boolean */
273 static SCM
274 gdbscm_parameter_p (SCM scm)
276 return scm_from_bool (pascm_is_parameter (scm));
279 /* Returns the <gdb:parameter> object in SELF.
280 Throws an exception if SELF is not a <gdb:parameter> object. */
282 static SCM
283 pascm_get_param_arg_unsafe (SCM self, int arg_pos, const char *func_name)
285 SCM_ASSERT_TYPE (pascm_is_parameter (self), self, arg_pos, func_name,
286 param_smob_name);
288 return self;
291 /* Returns a pointer to the parameter smob of SELF.
292 Throws an exception if SELF is not a <gdb:parameter> object. */
294 static param_smob *
295 pascm_get_param_smob_arg_unsafe (SCM self, int arg_pos, const char *func_name)
297 SCM p_scm = pascm_get_param_arg_unsafe (self, arg_pos, func_name);
298 param_smob *p_smob = (param_smob *) SCM_SMOB_DATA (p_scm);
300 return p_smob;
303 /* Return non-zero if parameter P_SMOB is valid. */
305 static int
306 pascm_is_valid (param_smob *p_smob)
308 return p_smob->commands.set != nullptr;
311 /* A helper function which return the default documentation string for
312 a parameter (which is to say that it's undocumented). */
314 static char *
315 get_doc_string (void)
317 return xstrdup (_("This command is not documented."));
320 /* Subroutine of pascm_set_func, pascm_show_func to simplify them.
321 Signal the error returned from calling set_func/show_func. */
323 static void
324 pascm_signal_setshow_error (SCM exception, const char *msg)
326 /* Don't print the stack if this was an error signalled by the command
327 itself. */
328 if (gdbscm_user_error_p (gdbscm_exception_key (exception)))
330 gdb::unique_xmalloc_ptr<char> excp_text
331 = gdbscm_exception_message_to_string (exception);
333 error ("%s", excp_text.get ());
335 else
337 gdbscm_print_gdb_exception (SCM_BOOL_F, exception);
338 error ("%s", msg);
342 /* A callback function that is registered against the respective
343 add_setshow_* set_func prototype. This function will call
344 the Scheme function "set_func" which must exist.
345 Note: ARGS is always passed as NULL. */
347 static void
348 pascm_set_func (const char *args, int from_tty, struct cmd_list_element *c)
350 param_smob *p_smob = (param_smob *) c->context ();
351 SCM self, result, exception;
353 gdb_assert (gdbscm_is_procedure (p_smob->set_func));
355 self = p_smob->containing_scm;
357 result = gdbscm_safe_call_1 (p_smob->set_func, self, gdbscm_user_error_p);
359 if (gdbscm_is_exception (result))
361 pascm_signal_setshow_error (result,
362 _("Error occurred setting parameter."));
365 if (!scm_is_string (result))
366 error (_("Result of %s set-func is not a string."), p_smob->name);
368 gdb::unique_xmalloc_ptr<char> msg = gdbscm_scm_to_host_string (result, NULL,
369 &exception);
370 if (msg == NULL)
372 gdbscm_print_gdb_exception (SCM_BOOL_F, exception);
373 error (_("Error converting show text to host string."));
376 /* GDB is usually silent when a parameter is set. */
377 if (*msg.get () != '\0')
378 gdb_printf ("%s\n", msg.get ());
381 /* A callback function that is registered against the respective
382 add_setshow_* show_func prototype. This function will call
383 the Scheme function "show_func" which must exist and must return a
384 string that is then printed to FILE. */
386 static void
387 pascm_show_func (struct ui_file *file, int from_tty,
388 struct cmd_list_element *c, const char *value)
390 param_smob *p_smob = (param_smob *) c->context ();
391 SCM value_scm, self, result, exception;
393 gdb_assert (gdbscm_is_procedure (p_smob->show_func));
395 value_scm = gdbscm_scm_from_host_string (value, strlen (value));
396 if (gdbscm_is_exception (value_scm))
398 error (_("Error converting parameter value \"%s\" to Scheme string."),
399 value);
401 self = p_smob->containing_scm;
403 result = gdbscm_safe_call_2 (p_smob->show_func, self, value_scm,
404 gdbscm_user_error_p);
406 if (gdbscm_is_exception (result))
408 pascm_signal_setshow_error (result,
409 _("Error occurred showing parameter."));
412 gdb::unique_xmalloc_ptr<char> msg = gdbscm_scm_to_host_string (result, NULL,
413 &exception);
414 if (msg == NULL)
416 gdbscm_print_gdb_exception (SCM_BOOL_F, exception);
417 error (_("Error converting show text to host string."));
420 gdb_printf (file, "%s\n", msg.get ());
423 /* A helper function that dispatches to the appropriate add_setshow
424 function. */
426 static set_show_commands
427 add_setshow_generic (enum var_types param_type,
428 const literal_def *extra_literals,
429 enum command_class cmd_class,
430 char *cmd_name, param_smob *self,
431 char *set_doc, char *show_doc, char *help_doc,
432 cmd_func_ftype *set_func,
433 show_value_ftype *show_func,
434 struct cmd_list_element **set_list,
435 struct cmd_list_element **show_list)
437 set_show_commands commands;
439 switch (param_type)
441 case var_boolean:
442 commands = add_setshow_boolean_cmd (cmd_name, cmd_class,
443 &self->value.boolval, set_doc,
444 show_doc, help_doc, set_func,
445 show_func, set_list, show_list);
446 break;
448 case var_auto_boolean:
449 commands = add_setshow_auto_boolean_cmd (cmd_name, cmd_class,
450 &self->value.autoboolval,
451 set_doc, show_doc, help_doc,
452 set_func, show_func, set_list,
453 show_list);
454 break;
456 case var_uinteger:
457 commands = add_setshow_uinteger_cmd (cmd_name, cmd_class,
458 &self->value.uintval,
459 extra_literals, set_doc,
460 show_doc, help_doc, set_func,
461 show_func, set_list, show_list);
462 break;
464 case var_integer:
465 commands = add_setshow_integer_cmd (cmd_name, cmd_class,
466 &self->value.intval,
467 extra_literals, set_doc,
468 show_doc, help_doc, set_func,
469 show_func, set_list, show_list);
470 break;
472 case var_pinteger:
473 commands = add_setshow_pinteger_cmd (cmd_name, cmd_class,
474 &self->value.intval,
475 extra_literals, set_doc,
476 show_doc, help_doc, set_func,
477 show_func, set_list, show_list);
478 break;
480 case var_string:
481 commands = add_setshow_string_cmd (cmd_name, cmd_class,
482 self->value.stringval, set_doc,
483 show_doc, help_doc, set_func,
484 show_func, set_list, show_list);
485 break;
487 case var_string_noescape:
488 commands = add_setshow_string_noescape_cmd (cmd_name, cmd_class,
489 self->value.stringval,
490 set_doc, show_doc, help_doc,
491 set_func, show_func, set_list,
492 show_list);
494 break;
496 case var_optional_filename:
497 commands = add_setshow_optional_filename_cmd (cmd_name, cmd_class,
498 self->value.stringval,
499 set_doc, show_doc, help_doc,
500 set_func, show_func,
501 set_list, show_list);
502 break;
504 case var_filename:
505 commands = add_setshow_filename_cmd (cmd_name, cmd_class,
506 self->value.stringval, set_doc,
507 show_doc, help_doc, set_func,
508 show_func, set_list, show_list);
509 break;
511 case var_enum:
512 /* Initialize the value, just in case. */
513 make_setting (self).set<const char *> (self->enumeration[0]);
514 commands = add_setshow_enum_cmd (cmd_name, cmd_class, self->enumeration,
515 &self->value.cstringval, set_doc,
516 show_doc, help_doc, set_func, show_func,
517 set_list, show_list);
518 break;
520 case var_color:
521 commands = add_setshow_color_cmd (cmd_name, cmd_class, &self->value.color,
522 set_doc, show_doc, help_doc,
523 set_func, show_func,
524 set_list, show_list);
525 break;
527 default:
528 gdb_assert_not_reached ("bad param_type value");
531 /* Register Scheme object against the commandsparameter context. Perform this
532 task against both lists. */
533 commands.set->set_context (self);
534 commands.show->set_context (self);
536 return commands;
539 /* Return an array of strings corresponding to the enum values for
540 ENUM_VALUES_SCM.
541 Throws an exception if there's a problem with the values.
542 Space for the result is allocated from the GC heap. */
544 static const char * const *
545 compute_enum_list (SCM enum_values_scm, int arg_pos, const char *func_name)
547 long i, size;
548 char **enum_values;
549 const char * const *result;
551 SCM_ASSERT_TYPE (gdbscm_is_true (scm_list_p (enum_values_scm)),
552 enum_values_scm, arg_pos, func_name, _("list"));
554 size = scm_ilength (enum_values_scm);
555 if (size == 0)
557 gdbscm_out_of_range_error (FUNC_NAME, arg_pos, enum_values_scm,
558 _("enumeration list is empty"));
561 enum_values = XCNEWVEC (char *, size + 1);
563 i = 0;
564 while (!scm_is_eq (enum_values_scm, SCM_EOL))
566 SCM value = scm_car (enum_values_scm);
567 SCM exception;
569 if (!scm_is_string (value))
571 freeargv (enum_values);
572 SCM_ASSERT_TYPE (0, value, arg_pos, func_name, _("string"));
574 enum_values[i] = gdbscm_scm_to_host_string (value, NULL,
575 &exception).release ();
576 if (enum_values[i] == NULL)
578 freeargv (enum_values);
579 gdbscm_throw (exception);
581 ++i;
582 enum_values_scm = scm_cdr (enum_values_scm);
584 gdb_assert (i == size);
586 result = gdbscm_gc_dup_argv (enum_values);
587 freeargv (enum_values);
588 return result;
591 static const scheme_integer_constant parameter_types[] =
593 { "PARAM_BOOLEAN", param_boolean }, /* ARI: param_boolean */
594 { "PARAM_AUTO_BOOLEAN", param_auto_boolean },
595 { "PARAM_ZINTEGER", param_zinteger },
596 { "PARAM_UINTEGER", param_uinteger },
597 { "PARAM_ZUINTEGER", param_zuinteger },
598 { "PARAM_ZUINTEGER_UNLIMITED", param_zuinteger_unlimited },
599 { "PARAM_STRING", param_string },
600 { "PARAM_STRING_NOESCAPE", param_string_noescape },
601 { "PARAM_OPTIONAL_FILENAME", param_optional_filename },
602 { "PARAM_FILENAME", param_filename },
603 { "PARAM_ENUM", param_enum },
604 { "PARAM_COLOR", param_color },
606 END_INTEGER_CONSTANTS
609 /* Return non-zero if PARAM_TYPE is a valid parameter type. */
611 static int
612 pascm_valid_parameter_type_p (int param_type)
614 int i;
616 for (i = 0; parameter_types[i].name != NULL; ++i)
618 if (parameter_types[i].value == param_type)
619 return 1;
622 return 0;
625 /* Return PARAM_TYPE as a string. */
627 static const char *
628 pascm_param_type_name (enum scm_param_types param_type)
630 int i;
632 for (i = 0; parameter_types[i].name != NULL; ++i)
634 if (parameter_types[i].value == param_type)
635 return parameter_types[i].name;
638 gdb_assert_not_reached ("bad parameter type");
641 /* Return the value of a gdb parameter as a Scheme value.
642 If the var_type of VAR is not supported, then a <gdb:exception> object is
643 returned. */
645 static SCM
646 pascm_param_value (const setting &var, int arg_pos, const char *func_name)
648 switch (var.type ())
650 case var_string:
651 case var_string_noescape:
652 case var_optional_filename:
653 case var_filename:
655 const std::string &str = var.get<std::string> ();
656 return gdbscm_scm_from_host_string (str.c_str (), str.length ());
659 case var_enum:
661 const char *str = var.get<const char *> ();
662 if (str == nullptr)
663 str = "";
664 return gdbscm_scm_from_host_string (str, strlen (str));
667 case var_color:
669 return coscm_scm_from_color (var.get<ui_file_style::color> ());
672 case var_boolean:
674 if (var.get<bool> ())
675 return SCM_BOOL_T;
676 else
677 return SCM_BOOL_F;
680 case var_auto_boolean:
682 enum auto_boolean ab = var.get<enum auto_boolean> ();
684 if (ab == AUTO_BOOLEAN_TRUE)
685 return SCM_BOOL_T;
686 else if (ab == AUTO_BOOLEAN_FALSE)
687 return SCM_BOOL_F;
688 else
689 return auto_keyword;
692 case var_uinteger:
693 case var_integer:
694 case var_pinteger:
696 LONGEST value
697 = (var.type () == var_uinteger
698 ? static_cast<LONGEST> (var.get<unsigned int> ())
699 : static_cast<LONGEST> (var.get<int> ()));
701 if (var.extra_literals () != nullptr)
702 for (const literal_def *l = var.extra_literals ();
703 l->literal != nullptr;
704 l++)
705 if (value == l->use)
706 return scm_from_latin1_keyword (l->literal);
707 if (var.type () == var_pinteger)
708 gdb_assert (value >= 0);
710 if (var.type () == var_uinteger)
711 return scm_from_uint (static_cast<unsigned int> (value));
712 else
713 return scm_from_int (static_cast<int> (value));
716 default:
717 break;
720 return gdbscm_make_out_of_range_error (func_name, arg_pos,
721 scm_from_int (var.type ()),
722 _("program error: unhandled type"));
725 /* Set the value of a parameter of type P_SMOB->TYPE in P_SMOB->VAR from VALUE.
726 ENUMERATION is the list of enum values for enum parameters, otherwise NULL.
727 Throws a Scheme exception if VALUE_SCM is invalid for TYPE. */
729 static void
730 pascm_set_param_value_x (param_smob *p_smob,
731 const char * const *enumeration,
732 SCM value, int arg_pos, const char *func_name)
734 setting var = make_setting (p_smob);
736 switch (var.type ())
738 case var_string:
739 case var_string_noescape:
740 case var_optional_filename:
741 case var_filename:
742 SCM_ASSERT_TYPE (scm_is_string (value)
743 || (var.type () != var_filename
744 && gdbscm_is_false (value)),
745 value, arg_pos, func_name,
746 _("string or #f for non-PARAM_FILENAME parameters"));
747 if (gdbscm_is_false (value))
748 var.set<std::string> ("");
749 else
751 SCM exception;
753 gdb::unique_xmalloc_ptr<char> string
754 = gdbscm_scm_to_host_string (value, nullptr, &exception);
755 if (string == nullptr)
756 gdbscm_throw (exception);
757 var.set<std::string> (string.release ());
759 break;
761 case var_enum:
763 int i;
764 SCM exception;
766 SCM_ASSERT_TYPE (scm_is_string (value), value, arg_pos, func_name,
767 _("string"));
768 gdb::unique_xmalloc_ptr<char> str
769 = gdbscm_scm_to_host_string (value, nullptr, &exception);
770 if (str == nullptr)
771 gdbscm_throw (exception);
772 for (i = 0; enumeration[i]; ++i)
774 if (strcmp (enumeration[i], str.get ()) == 0)
775 break;
777 if (enumeration[i] == nullptr)
779 gdbscm_out_of_range_error (func_name, arg_pos, value,
780 _("not member of enumeration"));
782 var.set<const char *> (enumeration[i]);
783 break;
786 case var_color:
787 SCM_ASSERT_TYPE (coscm_is_color (value), value, arg_pos, func_name,
788 _("<gdb:color>"));
789 var.set<ui_file_style::color> (coscm_get_color (value));
790 break;
792 case var_boolean:
793 SCM_ASSERT_TYPE (gdbscm_is_bool (value), value, arg_pos, func_name,
794 _("boolean"));
795 var.set<bool> (gdbscm_is_true (value));
796 break;
798 case var_auto_boolean:
799 SCM_ASSERT_TYPE (gdbscm_is_bool (value)
800 || scm_is_eq (value, auto_keyword),
801 value, arg_pos, func_name,
802 _("boolean or #:auto"));
803 if (scm_is_eq (value, auto_keyword))
804 var.set<enum auto_boolean> (AUTO_BOOLEAN_AUTO);
805 else if (gdbscm_is_true (value))
806 var.set<enum auto_boolean> (AUTO_BOOLEAN_TRUE);
807 else
808 var.set<enum auto_boolean> (AUTO_BOOLEAN_FALSE);
809 break;
811 case var_integer:
812 case var_uinteger:
813 case var_pinteger:
815 const literal_def *extra_literals = p_smob->extra_literals;
816 enum tribool allowed = TRIBOOL_UNKNOWN;
817 enum var_types var_type = var.type ();
818 bool integer = scm_is_integer (value);
819 bool keyword = scm_is_keyword (value);
820 std::string buffer = "";
821 size_t count = 0;
822 LONGEST val;
824 if (extra_literals != nullptr)
825 for (const literal_def *l = extra_literals;
826 l->literal != nullptr;
827 l++, count++)
829 if (count != 0)
830 buffer += ", ";
831 buffer = buffer + "#:" + l->literal;
832 if (keyword
833 && allowed == TRIBOOL_UNKNOWN
834 && scm_is_eq (value,
835 scm_from_latin1_keyword (l->literal)))
837 val = l->use;
838 allowed = TRIBOOL_TRUE;
842 if (allowed == TRIBOOL_UNKNOWN)
844 if (extra_literals == nullptr)
845 SCM_ASSERT_TYPE (integer, value, arg_pos, func_name,
846 _("integer"));
847 else if (count > 1)
848 SCM_ASSERT_TYPE (integer, value, arg_pos, func_name,
849 string_printf (_("integer or one of: %s"),
850 buffer.c_str ()).c_str ());
851 else
852 SCM_ASSERT_TYPE (integer, value, arg_pos, func_name,
853 string_printf (_("integer or %s"),
854 buffer.c_str ()).c_str ());
856 val = (var_type == var_uinteger
857 ? static_cast<LONGEST> (scm_to_uint (value))
858 : static_cast<LONGEST> (scm_to_int (value)));
860 if (extra_literals != nullptr)
861 for (const literal_def *l = extra_literals;
862 l->literal != nullptr;
863 l++)
865 if (l->val.has_value () && val == *l->val)
867 allowed = TRIBOOL_TRUE;
868 val = l->use;
869 break;
871 else if (val == l->use)
872 allowed = TRIBOOL_FALSE;
876 if (allowed == TRIBOOL_UNKNOWN)
878 if (val > UINT_MAX || val < INT_MIN
879 || (var_type == var_uinteger && val < 0)
880 || (var_type == var_integer && val > INT_MAX)
881 || (var_type == var_pinteger && val < 0)
882 || (var_type == var_pinteger && val > INT_MAX))
883 allowed = TRIBOOL_FALSE;
885 if (allowed == TRIBOOL_FALSE)
886 gdbscm_out_of_range_error (func_name, arg_pos, value,
887 _("integer out of range"));
889 if (var_type == var_uinteger)
890 var.set<unsigned int> (static_cast<unsigned int> (val));
891 else
892 var.set<int> (static_cast<int> (val));
894 break;
897 default:
898 gdb_assert_not_reached ("bad parameter type");
902 /* Free function for a param_smob. */
903 static size_t
904 pascm_free_parameter_smob (SCM self)
906 param_smob *p_smob = (param_smob *) SCM_SMOB_DATA (self);
908 if (var_type_uses<std::string> (p_smob->type))
910 delete p_smob->value.stringval;
911 p_smob->value.stringval = nullptr;
914 return 0;
917 /* Parameter Scheme functions. */
919 /* (make-parameter name
920 [#:command-class cmd-class] [#:parameter-type param-type]
921 [#:enum-list enum-list] [#:set-func function] [#:show-func function]
922 [#:doc <string>] [#:set-doc <string>] [#:show-doc <string>]
923 [#:initial-value initial-value]) -> <gdb:parameter>
925 NAME is the name of the parameter. It may consist of multiple
926 words, in which case the final word is the name of the new parameter,
927 and earlier words must be prefix commands.
929 CMD-CLASS is the kind of command. It should be one of the COMMAND_*
930 constants defined in the gdb module.
932 PARAM_TYPE is the type of the parameter. It should be one of the
933 PARAM_* constants defined in the gdb module.
935 If PARAM-TYPE is PARAM_ENUM, then ENUM-LIST is a list of strings that
936 are the valid values for this parameter. The first value is the default.
938 SET-FUNC, if provided, is called after the parameter is set.
939 It is a function of one parameter: the <gdb:parameter> object.
940 It must return a string to be displayed to the user.
941 Setting a parameter is typically a silent operation, so typically ""
942 should be returned.
944 SHOW-FUNC, if provided, returns the string that is printed.
945 It is a function of two parameters: the <gdb:parameter> object
946 and the current value of the parameter as a string.
948 DOC, SET-DOC, SHOW-DOC are the doc strings for the parameter.
950 INITIAL-VALUE is the initial value of the parameter.
952 The result is the <gdb:parameter> Scheme object.
953 The parameter is not available to be used yet, however.
954 It must still be added to gdb with register-parameter!. */
956 static SCM
957 gdbscm_make_parameter (SCM name_scm, SCM rest)
959 const SCM keywords[] = {
960 command_class_keyword, parameter_type_keyword, enum_list_keyword,
961 set_func_keyword, show_func_keyword,
962 doc_keyword, set_doc_keyword, show_doc_keyword,
963 initial_value_keyword, SCM_BOOL_F
965 int cmd_class_arg_pos = -1, param_type_arg_pos = -1;
966 int enum_list_arg_pos = -1, set_func_arg_pos = -1, show_func_arg_pos = -1;
967 int doc_arg_pos = -1, set_doc_arg_pos = -1, show_doc_arg_pos = -1;
968 int initial_value_arg_pos = -1;
969 char *s;
970 char *name;
971 int cmd_class = no_class;
972 int param_type = param_boolean; /* ARI: param_boolean */
973 SCM enum_list_scm = SCM_BOOL_F;
974 SCM set_func = SCM_BOOL_F, show_func = SCM_BOOL_F;
975 char *doc = NULL, *set_doc = NULL, *show_doc = NULL;
976 SCM initial_value_scm = SCM_BOOL_F;
977 const char * const *enum_list = NULL;
978 SCM p_scm;
979 param_smob *p_smob;
981 gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, keywords, "s#iiOOOsssO",
982 name_scm, &name, rest,
983 &cmd_class_arg_pos, &cmd_class,
984 &param_type_arg_pos, &param_type,
985 &enum_list_arg_pos, &enum_list_scm,
986 &set_func_arg_pos, &set_func,
987 &show_func_arg_pos, &show_func,
988 &doc_arg_pos, &doc,
989 &set_doc_arg_pos, &set_doc,
990 &show_doc_arg_pos, &show_doc,
991 &initial_value_arg_pos, &initial_value_scm);
993 /* If doc is NULL, leave it NULL. See add_setshow_cmd_full. */
994 if (set_doc == NULL)
995 set_doc = get_doc_string ();
996 if (show_doc == NULL)
997 show_doc = get_doc_string ();
999 s = name;
1000 name = gdbscm_canonicalize_command_name (s, 0);
1001 xfree (s);
1002 if (doc != NULL)
1004 s = doc;
1005 doc = gdbscm_gc_xstrdup (s);
1006 xfree (s);
1008 s = set_doc;
1009 set_doc = gdbscm_gc_xstrdup (s);
1010 xfree (s);
1011 s = show_doc;
1012 show_doc = gdbscm_gc_xstrdup (s);
1013 xfree (s);
1015 if (!gdbscm_valid_command_class_p (cmd_class))
1017 gdbscm_out_of_range_error (FUNC_NAME, cmd_class_arg_pos,
1018 scm_from_int (cmd_class),
1019 _("invalid command class argument"));
1021 if (!pascm_valid_parameter_type_p (param_type))
1023 gdbscm_out_of_range_error (FUNC_NAME, param_type_arg_pos,
1024 scm_from_int (param_type),
1025 _("invalid parameter type argument"));
1027 if (enum_list_arg_pos > 0 && param_type != param_enum)
1029 gdbscm_misc_error (FUNC_NAME, enum_list_arg_pos, enum_list_scm,
1030 _("#:enum-values can only be provided with PARAM_ENUM"));
1032 if (enum_list_arg_pos < 0 && param_type == param_enum)
1034 gdbscm_misc_error (FUNC_NAME, GDBSCM_ARG_NONE, SCM_BOOL_F,
1035 _("PARAM_ENUM requires an enum-values argument"));
1037 if (set_func_arg_pos > 0)
1039 SCM_ASSERT_TYPE (gdbscm_is_procedure (set_func), set_func,
1040 set_func_arg_pos, FUNC_NAME, _("procedure"));
1042 if (show_func_arg_pos > 0)
1044 SCM_ASSERT_TYPE (gdbscm_is_procedure (show_func), show_func,
1045 show_func_arg_pos, FUNC_NAME, _("procedure"));
1047 if (param_type == param_enum)
1049 /* Note: enum_list lives in GC space, so we don't have to worry about
1050 freeing it if we later throw an exception. */
1051 enum_list = compute_enum_list (enum_list_scm, enum_list_arg_pos,
1052 FUNC_NAME);
1055 /* If initial-value is a function, we need the parameter object constructed
1056 to pass it to the function. A typical thing the function may want to do
1057 is add an object-property to it to record the last known good value. */
1058 p_scm = pascm_make_param_smob ();
1059 p_smob = (param_smob *) SCM_SMOB_DATA (p_scm);
1060 /* These are all stored in GC space so that we don't have to worry about
1061 freeing them if we throw an exception. */
1062 p_smob->name = name;
1063 p_smob->cmd_class = (enum command_class) cmd_class;
1064 p_smob->pname
1065 = pascm_param_type_name (static_cast<enum scm_param_types> (param_type));
1066 p_smob->type = param_to_var[param_type].type;
1067 p_smob->extra_literals = param_to_var[param_type].extra_literals;
1068 p_smob->doc = doc;
1069 p_smob->set_doc = set_doc;
1070 p_smob->show_doc = show_doc;
1071 p_smob->enumeration = enum_list;
1072 p_smob->set_func = set_func;
1073 p_smob->show_func = show_func;
1075 scm_set_smob_free (parameter_smob_tag, pascm_free_parameter_smob);
1076 if (var_type_uses<std::string> (p_smob->type))
1077 p_smob->value.stringval = new std::string;
1078 else if (var_type_uses<ui_file_style::color> (p_smob->type))
1079 p_smob->value.color = ui_file_style::NONE;
1081 if (initial_value_arg_pos > 0)
1083 if (gdbscm_is_procedure (initial_value_scm))
1085 initial_value_scm = gdbscm_safe_call_1 (initial_value_scm,
1086 p_smob->containing_scm, NULL);
1087 if (gdbscm_is_exception (initial_value_scm))
1088 gdbscm_throw (initial_value_scm);
1090 pascm_set_param_value_x (p_smob, enum_list,
1091 initial_value_scm,
1092 initial_value_arg_pos, FUNC_NAME);
1095 return p_scm;
1098 /* Subroutine of gdbscm_register_parameter_x to simplify it.
1099 Return non-zero if parameter NAME is already defined in LIST. */
1101 static int
1102 pascm_parameter_defined_p (const char *name, struct cmd_list_element *list)
1104 struct cmd_list_element *c;
1106 c = lookup_cmd_1 (&name, list, NULL, NULL, 1);
1108 /* If the name is ambiguous that's ok, it's a new parameter still. */
1109 return c != NULL && c != CMD_LIST_AMBIGUOUS;
1112 /* (register-parameter! <gdb:parameter>) -> unspecified
1114 It is an error to register a pre-existing parameter. */
1116 static SCM
1117 gdbscm_register_parameter_x (SCM self)
1119 param_smob *p_smob
1120 = pascm_get_param_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
1121 char *cmd_name;
1122 struct cmd_list_element **set_list, **show_list;
1124 if (pascm_is_valid (p_smob))
1125 scm_misc_error (FUNC_NAME, _("parameter is already registered"), SCM_EOL);
1127 cmd_name = gdbscm_parse_command_name (p_smob->name, FUNC_NAME, SCM_ARG1,
1128 &set_list, &setlist);
1129 xfree (cmd_name);
1130 cmd_name = gdbscm_parse_command_name (p_smob->name, FUNC_NAME, SCM_ARG1,
1131 &show_list, &showlist);
1132 p_smob->cmd_name = gdbscm_gc_xstrdup (cmd_name);
1133 xfree (cmd_name);
1135 if (pascm_parameter_defined_p (p_smob->cmd_name, *set_list))
1137 gdbscm_misc_error (FUNC_NAME, SCM_ARG1, self,
1138 _("parameter exists, \"set\" command is already defined"));
1140 if (pascm_parameter_defined_p (p_smob->cmd_name, *show_list))
1142 gdbscm_misc_error (FUNC_NAME, SCM_ARG1, self,
1143 _("parameter exists, \"show\" command is already defined"));
1146 gdbscm_gdb_exception exc {};
1149 p_smob->commands = add_setshow_generic
1150 (p_smob->type, p_smob->extra_literals,
1151 p_smob->cmd_class, p_smob->cmd_name, p_smob,
1152 p_smob->set_doc, p_smob->show_doc, p_smob->doc,
1153 (gdbscm_is_procedure (p_smob->set_func) ? pascm_set_func : NULL),
1154 (gdbscm_is_procedure (p_smob->show_func) ? pascm_show_func : NULL),
1155 set_list, show_list);
1157 catch (const gdb_exception &except)
1159 exc = unpack (except);
1162 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
1163 /* Note: At this point the parameter exists in gdb.
1164 So no more errors after this point. */
1166 /* The owner of this parameter is not in GC-controlled memory, so we need
1167 to protect it from GC until the parameter is deleted. */
1168 scm_gc_protect_object (p_smob->containing_scm);
1170 return SCM_UNSPECIFIED;
1173 /* (parameter-value <gdb:parameter>) -> value
1174 (parameter-value <string>) -> value */
1176 static SCM
1177 gdbscm_parameter_value (SCM self)
1179 SCM_ASSERT_TYPE (pascm_is_parameter (self) || scm_is_string (self),
1180 self, SCM_ARG1, FUNC_NAME, _("<gdb:parameter> or string"));
1182 if (pascm_is_parameter (self))
1184 param_smob *p_smob = pascm_get_param_smob_arg_unsafe (self, SCM_ARG1,
1185 FUNC_NAME);
1187 return pascm_param_value (make_setting (p_smob), SCM_ARG1, FUNC_NAME);
1189 else
1191 SCM except_scm;
1192 struct cmd_list_element *alias, *prefix, *cmd;
1193 char *newarg;
1194 int found = -1;
1195 gdbscm_gdb_exception except {};
1197 gdb::unique_xmalloc_ptr<char> name
1198 = gdbscm_scm_to_host_string (self, NULL, &except_scm);
1199 if (name == NULL)
1200 gdbscm_throw (except_scm);
1201 newarg = concat ("show ", name.get (), (char *) NULL);
1204 found = lookup_cmd_composition (newarg, &alias, &prefix, &cmd);
1206 catch (const gdb_exception &ex)
1208 except = unpack (ex);
1211 xfree (newarg);
1212 GDBSCM_HANDLE_GDB_EXCEPTION (except);
1213 if (!found)
1215 gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
1216 _("parameter not found"));
1219 if (!cmd->var.has_value ())
1221 gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self,
1222 _("not a parameter"));
1225 return pascm_param_value (*cmd->var, SCM_ARG1, FUNC_NAME);
1229 /* (set-parameter-value! <gdb:parameter> value) -> unspecified */
1231 static SCM
1232 gdbscm_set_parameter_value_x (SCM self, SCM value)
1234 param_smob *p_smob = pascm_get_param_smob_arg_unsafe (self, SCM_ARG1,
1235 FUNC_NAME);
1237 pascm_set_param_value_x (p_smob, p_smob->enumeration,
1238 value, SCM_ARG2, FUNC_NAME);
1240 return SCM_UNSPECIFIED;
1243 /* Initialize the Scheme parameter support. */
1245 static const scheme_function parameter_functions[] =
1247 { "make-parameter", 1, 0, 1, as_a_scm_t_subr (gdbscm_make_parameter),
1249 Make a GDB parameter object.\n\
1251 Arguments: name\n\
1252 [#:command-class <cmd-class>] [#:parameter-type <parameter-type>]\n\
1253 [#:enum-list <enum-list>]\n\
1254 [#:set-func function] [#:show-func function]\n\
1255 [#:doc string] [#:set-doc string] [#:show-doc string]\n\
1256 [#:initial-value initial-value]\n\
1257 name: The name of the command. It may consist of multiple words,\n\
1258 in which case the final word is the name of the new parameter, and\n\
1259 earlier words must be prefix commands.\n\
1260 cmd-class: The class of the command, one of COMMAND_*.\n\
1261 The default is COMMAND_NONE.\n\
1262 parameter-type: The kind of parameter, one of PARAM_*\n\
1263 The default is PARAM_BOOLEAN.\n\
1264 enum-list: If parameter-type is PARAM_ENUM, then this specifies the set\n\
1265 of values of the enum.\n\
1266 set-func: A function of one parameter: the <gdb:parameter> object.\n\
1267 Called *after* the parameter has been set. Returns either \"\" or a\n\
1268 non-empty string to be displayed to the user.\n\
1269 If non-empty, GDB will add a trailing newline.\n\
1270 show-func: A function of two parameters: the <gdb:parameter> object\n\
1271 and the string representation of the current value.\n\
1272 The result is a string to be displayed to the user.\n\
1273 GDB will add a trailing newline.\n\
1274 doc: The \"doc string\" of the parameter.\n\
1275 set-doc: The \"doc string\" when setting the parameter.\n\
1276 show-doc: The \"doc string\" when showing the parameter.\n\
1277 initial-value: The initial value of the parameter." },
1279 { "register-parameter!", 1, 0, 0,
1280 as_a_scm_t_subr (gdbscm_register_parameter_x),
1282 Register a <gdb:parameter> object with GDB." },
1284 { "parameter?", 1, 0, 0, as_a_scm_t_subr (gdbscm_parameter_p),
1286 Return #t if the object is a <gdb:parameter> object." },
1288 { "parameter-value", 1, 0, 0, as_a_scm_t_subr (gdbscm_parameter_value),
1290 Return the value of a <gdb:parameter> object\n\
1291 or any gdb parameter if param is a string naming the parameter." },
1293 { "set-parameter-value!", 2, 0, 0,
1294 as_a_scm_t_subr (gdbscm_set_parameter_value_x),
1296 Set the value of a <gdb:parameter> object.\n\
1298 Arguments: <gdb:parameter> value" },
1300 END_FUNCTIONS
1303 void
1304 gdbscm_initialize_parameters (void)
1306 parameter_smob_tag
1307 = gdbscm_make_smob_type (param_smob_name, sizeof (param_smob));
1308 scm_set_smob_print (parameter_smob_tag, pascm_print_param_smob);
1310 gdbscm_define_integer_constants (parameter_types, 1);
1311 gdbscm_define_functions (parameter_functions, 1);
1313 command_class_keyword = scm_from_latin1_keyword ("command-class");
1314 parameter_type_keyword = scm_from_latin1_keyword ("parameter-type");
1315 enum_list_keyword = scm_from_latin1_keyword ("enum-list");
1316 set_func_keyword = scm_from_latin1_keyword ("set-func");
1317 show_func_keyword = scm_from_latin1_keyword ("show-func");
1318 doc_keyword = scm_from_latin1_keyword ("doc");
1319 set_doc_keyword = scm_from_latin1_keyword ("set-doc");
1320 show_doc_keyword = scm_from_latin1_keyword ("show-doc");
1321 initial_value_keyword = scm_from_latin1_keyword ("initial-value");
1322 auto_keyword = scm_from_latin1_keyword ("auto");