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