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