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