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