1 /* GDB parameters implemented in Guile.
3 Copyright (C) 2008-2022 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 #include "cli/cli-decode.h"
25 #include "completer.h"
27 #include "arch-utils.h"
28 #include "guile-internal.h"
30 /* A union that can hold anything described by enum var_types. */
34 /* Hold an boolean value. */
37 /* Hold an integer value. */
40 /* Hold an auto_boolean. */
41 enum auto_boolean autoboolval
;
43 /* Hold an unsigned integer value, for uinteger. */
46 /* Hold a string, for the various string types. */
47 std::string
*stringval
;
49 /* Hold a string, for enums. */
50 const char *cstringval
;
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. */
64 /* This always appears first. */
67 /* The parameter name. */
70 /* The last word of the command.
71 This is needed because add_cmd requires us to allocate space
75 /* One of the COMMAND_* constants. */
76 enum command_class cmd_class
;
78 /* The type of the parameter. */
81 /* The docs for the parameter. */
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
;
91 /* The value of the parameter. */
92 union pascm_variable value
;
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
;
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. */
103 /* The show_func function or #f if not specified.
104 This function returns the string that is printed. */
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). */
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. */
118 make_setting (param_smob
*s
)
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
);
133 gdb_assert_not_reached ("unhandled var type");
136 static const char param_smob_name
[] = "gdb:parameter";
138 /* The tag Guile knows the param smob by. */
139 static scm_t_bits parameter_smob_tag
;
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
;
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
);
159 /* Administrivia for parameter smobs. */
162 pascm_print_param_smob (SCM self
, SCM port
, scm_print_state
*pstate
)
164 param_smob
*p_smob
= (param_smob
*) SCM_SMOB_DATA (self
);
167 gdbscm_printf (port
, "#<%s", param_smob_name
);
169 gdbscm_printf (port
, " %s", p_smob
->name
);
171 if (! pascm_is_valid (p_smob
))
172 scm_puts (" {invalid}", port
);
174 gdbscm_printf (port
, " %s ", pascm_param_type_name (p_smob
->type
));
176 value
= pascm_param_value (make_setting (p_smob
), GDBSCM_ARG_NONE
, NULL
);
177 scm_display (value
, port
);
179 scm_puts (">", port
);
181 scm_remember_upto_here_1 (self
);
183 /* Non-zero means success. */
187 /* Create an empty (uninitialized) parameter. */
190 pascm_make_param_smob (void)
192 param_smob
*p_smob
= (param_smob
*)
193 scm_gc_malloc (sizeof (param_smob
), param_smob_name
);
196 memset (p_smob
, 0, sizeof (*p_smob
));
197 p_smob
->cmd_class
= no_class
;
198 p_smob
->type
= var_boolean
; /* ARI: var_boolean */
199 p_smob
->set_func
= SCM_BOOL_F
;
200 p_smob
->show_func
= SCM_BOOL_F
;
201 p_scm
= scm_new_smob (parameter_smob_tag
, (scm_t_bits
) p_smob
);
202 p_smob
->containing_scm
= p_scm
;
203 gdbscm_init_gsmob (&p_smob
->base
);
208 /* Returns non-zero if SCM is a <gdb:parameter> object. */
211 pascm_is_parameter (SCM scm
)
213 return SCM_SMOB_PREDICATE (parameter_smob_tag
, scm
);
216 /* (gdb:parameter? scm) -> boolean */
219 gdbscm_parameter_p (SCM scm
)
221 return scm_from_bool (pascm_is_parameter (scm
));
224 /* Returns the <gdb:parameter> object in SELF.
225 Throws an exception if SELF is not a <gdb:parameter> object. */
228 pascm_get_param_arg_unsafe (SCM self
, int arg_pos
, const char *func_name
)
230 SCM_ASSERT_TYPE (pascm_is_parameter (self
), self
, arg_pos
, func_name
,
236 /* Returns a pointer to the parameter smob of SELF.
237 Throws an exception if SELF is not a <gdb:parameter> object. */
240 pascm_get_param_smob_arg_unsafe (SCM self
, int arg_pos
, const char *func_name
)
242 SCM p_scm
= pascm_get_param_arg_unsafe (self
, arg_pos
, func_name
);
243 param_smob
*p_smob
= (param_smob
*) SCM_SMOB_DATA (p_scm
);
248 /* Return non-zero if parameter P_SMOB is valid. */
251 pascm_is_valid (param_smob
*p_smob
)
253 return p_smob
->commands
.set
!= nullptr;
256 /* A helper function which return the default documentation string for
257 a parameter (which is to say that it's undocumented). */
260 get_doc_string (void)
262 return xstrdup (_("This command is not documented."));
265 /* Subroutine of pascm_set_func, pascm_show_func to simplify them.
266 Signal the error returned from calling set_func/show_func. */
269 pascm_signal_setshow_error (SCM exception
, const char *msg
)
271 /* Don't print the stack if this was an error signalled by the command
273 if (gdbscm_user_error_p (gdbscm_exception_key (exception
)))
275 gdb::unique_xmalloc_ptr
<char> excp_text
276 = gdbscm_exception_message_to_string (exception
);
278 error ("%s", excp_text
.get ());
282 gdbscm_print_gdb_exception (SCM_BOOL_F
, exception
);
287 /* A callback function that is registered against the respective
288 add_setshow_* set_func prototype. This function will call
289 the Scheme function "set_func" which must exist.
290 Note: ARGS is always passed as NULL. */
293 pascm_set_func (const char *args
, int from_tty
, struct cmd_list_element
*c
)
295 param_smob
*p_smob
= (param_smob
*) c
->context ();
296 SCM self
, result
, exception
;
298 gdb_assert (gdbscm_is_procedure (p_smob
->set_func
));
300 self
= p_smob
->containing_scm
;
302 result
= gdbscm_safe_call_1 (p_smob
->set_func
, self
, gdbscm_user_error_p
);
304 if (gdbscm_is_exception (result
))
306 pascm_signal_setshow_error (result
,
307 _("Error occurred setting parameter."));
310 if (!scm_is_string (result
))
311 error (_("Result of %s set-func is not a string."), p_smob
->name
);
313 gdb::unique_xmalloc_ptr
<char> msg
= gdbscm_scm_to_host_string (result
, NULL
,
317 gdbscm_print_gdb_exception (SCM_BOOL_F
, exception
);
318 error (_("Error converting show text to host string."));
321 /* GDB is usually silent when a parameter is set. */
322 if (*msg
.get () != '\0')
323 gdb_printf ("%s\n", msg
.get ());
326 /* A callback function that is registered against the respective
327 add_setshow_* show_func prototype. This function will call
328 the Scheme function "show_func" which must exist and must return a
329 string that is then printed to FILE. */
332 pascm_show_func (struct ui_file
*file
, int from_tty
,
333 struct cmd_list_element
*c
, const char *value
)
335 param_smob
*p_smob
= (param_smob
*) c
->context ();
336 SCM value_scm
, self
, result
, exception
;
338 gdb_assert (gdbscm_is_procedure (p_smob
->show_func
));
340 value_scm
= gdbscm_scm_from_host_string (value
, strlen (value
));
341 if (gdbscm_is_exception (value_scm
))
343 error (_("Error converting parameter value \"%s\" to Scheme string."),
346 self
= p_smob
->containing_scm
;
348 result
= gdbscm_safe_call_2 (p_smob
->show_func
, self
, value_scm
,
349 gdbscm_user_error_p
);
351 if (gdbscm_is_exception (result
))
353 pascm_signal_setshow_error (result
,
354 _("Error occurred showing parameter."));
357 gdb::unique_xmalloc_ptr
<char> msg
= gdbscm_scm_to_host_string (result
, NULL
,
361 gdbscm_print_gdb_exception (SCM_BOOL_F
, exception
);
362 error (_("Error converting show text to host string."));
365 gdb_printf (file
, "%s\n", msg
.get ());
368 /* A helper function that dispatches to the appropriate add_setshow
371 static set_show_commands
372 add_setshow_generic (enum var_types param_type
, enum command_class cmd_class
,
373 char *cmd_name
, param_smob
*self
,
374 char *set_doc
, char *show_doc
, char *help_doc
,
375 cmd_func_ftype
*set_func
,
376 show_value_ftype
*show_func
,
377 struct cmd_list_element
**set_list
,
378 struct cmd_list_element
**show_list
)
380 set_show_commands commands
;
385 commands
= add_setshow_boolean_cmd (cmd_name
, cmd_class
,
386 &self
->value
.boolval
, set_doc
,
387 show_doc
, help_doc
, set_func
,
388 show_func
, set_list
, show_list
);
391 case var_auto_boolean
:
392 commands
= add_setshow_auto_boolean_cmd (cmd_name
, cmd_class
,
393 &self
->value
.autoboolval
,
394 set_doc
, show_doc
, help_doc
,
395 set_func
, show_func
, set_list
,
400 commands
= add_setshow_uinteger_cmd (cmd_name
, cmd_class
,
401 &self
->value
.uintval
, set_doc
,
402 show_doc
, help_doc
, set_func
,
403 show_func
, set_list
, show_list
);
407 commands
= add_setshow_zinteger_cmd (cmd_name
, cmd_class
,
408 &self
->value
.intval
, set_doc
,
409 show_doc
, help_doc
, set_func
,
410 show_func
, set_list
, show_list
);
414 commands
= add_setshow_zuinteger_cmd (cmd_name
, cmd_class
,
415 &self
->value
.uintval
, set_doc
,
416 show_doc
, help_doc
, set_func
,
417 show_func
, set_list
, show_list
);
420 case var_zuinteger_unlimited
:
421 commands
= add_setshow_zuinteger_unlimited_cmd (cmd_name
, cmd_class
,
430 commands
= add_setshow_string_cmd (cmd_name
, cmd_class
,
431 self
->value
.stringval
, set_doc
,
432 show_doc
, help_doc
, set_func
,
433 show_func
, set_list
, show_list
);
436 case var_string_noescape
:
437 commands
= add_setshow_string_noescape_cmd (cmd_name
, cmd_class
,
438 self
->value
.stringval
,
439 set_doc
, show_doc
, help_doc
,
440 set_func
, show_func
, set_list
,
445 case var_optional_filename
:
446 commands
= add_setshow_optional_filename_cmd (cmd_name
, cmd_class
,
447 self
->value
.stringval
,
448 set_doc
, show_doc
, help_doc
,
450 set_list
, show_list
);
454 commands
= add_setshow_filename_cmd (cmd_name
, cmd_class
,
455 self
->value
.stringval
, set_doc
,
456 show_doc
, help_doc
, set_func
,
457 show_func
, set_list
, show_list
);
461 /* Initialize the value, just in case. */
462 make_setting (self
).set
<const char *> (self
->enumeration
[0]);
463 commands
= add_setshow_enum_cmd (cmd_name
, cmd_class
, self
->enumeration
,
464 &self
->value
.cstringval
, set_doc
,
465 show_doc
, help_doc
, set_func
, show_func
,
466 set_list
, show_list
);
470 gdb_assert_not_reached ("bad param_type value");
473 /* Register Scheme object against the commandsparameter context. Perform this
474 task against both lists. */
475 commands
.set
->set_context (self
);
476 commands
.show
->set_context (self
);
481 /* Return an array of strings corresponding to the enum values for
483 Throws an exception if there's a problem with the values.
484 Space for the result is allocated from the GC heap. */
486 static const char * const *
487 compute_enum_list (SCM enum_values_scm
, int arg_pos
, const char *func_name
)
491 const char * const *result
;
493 SCM_ASSERT_TYPE (gdbscm_is_true (scm_list_p (enum_values_scm
)),
494 enum_values_scm
, arg_pos
, func_name
, _("list"));
496 size
= scm_ilength (enum_values_scm
);
499 gdbscm_out_of_range_error (FUNC_NAME
, arg_pos
, enum_values_scm
,
500 _("enumeration list is empty"));
503 enum_values
= XCNEWVEC (char *, size
+ 1);
506 while (!scm_is_eq (enum_values_scm
, SCM_EOL
))
508 SCM value
= scm_car (enum_values_scm
);
511 if (!scm_is_string (value
))
513 freeargv (enum_values
);
514 SCM_ASSERT_TYPE (0, value
, arg_pos
, func_name
, _("string"));
516 enum_values
[i
] = gdbscm_scm_to_host_string (value
, NULL
,
517 &exception
).release ();
518 if (enum_values
[i
] == NULL
)
520 freeargv (enum_values
);
521 gdbscm_throw (exception
);
524 enum_values_scm
= scm_cdr (enum_values_scm
);
526 gdb_assert (i
== size
);
528 result
= gdbscm_gc_dup_argv (enum_values
);
529 freeargv (enum_values
);
533 static const scheme_integer_constant parameter_types
[] =
535 /* Note: var_integer is deprecated, and intentionally does not
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
},
549 END_INTEGER_CONSTANTS
552 /* Return non-zero if PARAM_TYPE is a valid parameter type. */
555 pascm_valid_parameter_type_p (int param_type
)
559 for (i
= 0; parameter_types
[i
].name
!= NULL
; ++i
)
561 if (parameter_types
[i
].value
== param_type
)
568 /* Return PARAM_TYPE as a string. */
571 pascm_param_type_name (enum var_types param_type
)
575 for (i
= 0; parameter_types
[i
].name
!= NULL
; ++i
)
577 if (parameter_types
[i
].value
== param_type
)
578 return parameter_types
[i
].name
;
581 gdb_assert_not_reached ("bad parameter type");
584 /* Return the value of a gdb parameter as a Scheme value.
585 If the var_type of VAR is not supported, then a <gdb:exception> object is
589 pascm_param_value (const setting
&var
, int arg_pos
, const char *func_name
)
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. */
598 case var_string_noescape
:
599 case var_optional_filename
:
602 const std::string
&str
= var
.get
<std::string
> ();
603 return gdbscm_scm_from_host_string (str
.c_str (), str
.length ());
608 const char *str
= var
.get
<const char *> ();
611 return gdbscm_scm_from_host_string (str
, strlen (str
));
616 if (var
.get
<bool> ())
622 case var_auto_boolean
:
624 enum auto_boolean ab
= var
.get
<enum auto_boolean
> ();
626 if (ab
== AUTO_BOOLEAN_TRUE
)
628 else if (ab
== AUTO_BOOLEAN_FALSE
)
634 case var_zuinteger_unlimited
:
635 if (var
.get
<int> () == -1)
636 return unlimited_keyword
;
637 gdb_assert (var
.get
<int> () >= 0);
640 return scm_from_int (var
.get
<int> ());
643 if (var
.get
<unsigned int> ()== UINT_MAX
)
644 return unlimited_keyword
;
647 return scm_from_uint (var
.get
<unsigned int> ());
653 return gdbscm_make_out_of_range_error (func_name
, arg_pos
,
654 scm_from_int (var
.type ()),
655 _("program error: unhandled type"));
658 /* Set the value of a parameter of type P_SMOB->TYPE in P_SMOB->VAR from VALUE.
659 ENUMERATION is the list of enum values for enum parameters, otherwise NULL.
660 Throws a Scheme exception if VALUE_SCM is invalid for TYPE. */
663 pascm_set_param_value_x (param_smob
*p_smob
,
664 const char * const *enumeration
,
665 SCM value
, int arg_pos
, const char *func_name
)
667 setting var
= make_setting (p_smob
);
672 case var_string_noescape
:
673 case var_optional_filename
:
675 SCM_ASSERT_TYPE (scm_is_string (value
)
676 || (var
.type () != var_filename
677 && gdbscm_is_false (value
)),
678 value
, arg_pos
, func_name
,
679 _("string or #f for non-PARAM_FILENAME parameters"));
680 if (gdbscm_is_false (value
))
681 var
.set
<std::string
> ("");
686 gdb::unique_xmalloc_ptr
<char> string
687 = gdbscm_scm_to_host_string (value
, nullptr, &exception
);
688 if (string
== nullptr)
689 gdbscm_throw (exception
);
690 var
.set
<std::string
> (string
.release ());
699 SCM_ASSERT_TYPE (scm_is_string (value
), value
, arg_pos
, func_name
,
701 gdb::unique_xmalloc_ptr
<char> str
702 = gdbscm_scm_to_host_string (value
, nullptr, &exception
);
704 gdbscm_throw (exception
);
705 for (i
= 0; enumeration
[i
]; ++i
)
707 if (strcmp (enumeration
[i
], str
.get ()) == 0)
710 if (enumeration
[i
] == nullptr)
712 gdbscm_out_of_range_error (func_name
, arg_pos
, value
,
713 _("not member of enumeration"));
715 var
.set
<const char *> (enumeration
[i
]);
720 SCM_ASSERT_TYPE (gdbscm_is_bool (value
), value
, arg_pos
, func_name
,
722 var
.set
<bool> (gdbscm_is_true (value
));
725 case var_auto_boolean
:
726 SCM_ASSERT_TYPE (gdbscm_is_bool (value
)
727 || scm_is_eq (value
, auto_keyword
),
728 value
, arg_pos
, func_name
,
729 _("boolean or #:auto"));
730 if (scm_is_eq (value
, auto_keyword
))
731 var
.set
<enum auto_boolean
> (AUTO_BOOLEAN_AUTO
);
732 else if (gdbscm_is_true (value
))
733 var
.set
<enum auto_boolean
> (AUTO_BOOLEAN_TRUE
);
735 var
.set
<enum auto_boolean
> (AUTO_BOOLEAN_FALSE
);
741 case var_zuinteger_unlimited
:
742 if (var
.type () == var_uinteger
743 || var
.type () == var_zuinteger_unlimited
)
745 SCM_ASSERT_TYPE (gdbscm_is_bool (value
)
746 || scm_is_eq (value
, unlimited_keyword
),
747 value
, arg_pos
, func_name
,
748 _("integer or #:unlimited"));
749 if (scm_is_eq (value
, unlimited_keyword
))
751 if (var
.type () == var_uinteger
)
752 var
.set
<unsigned int> (UINT_MAX
);
760 SCM_ASSERT_TYPE (scm_is_integer (value
), value
, arg_pos
, func_name
,
764 if (var
.type () == var_uinteger
765 || var
.type () == var_zuinteger
)
767 unsigned int u
= scm_to_uint (value
);
769 if (var
.type () == var_uinteger
&& u
== 0)
771 var
.set
<unsigned int> (u
);
775 int i
= scm_to_int (value
);
777 if (var
.type () == var_zuinteger_unlimited
&& i
< -1)
779 gdbscm_out_of_range_error (func_name
, arg_pos
, value
,
787 gdb_assert_not_reached ("bad parameter type");
791 /* Free function for a param_smob. */
793 pascm_free_parameter_smob (SCM self
)
795 param_smob
*p_smob
= (param_smob
*) SCM_SMOB_DATA (self
);
797 if (var_type_uses
<std::string
> (p_smob
->type
))
799 delete p_smob
->value
.stringval
;
800 p_smob
->value
.stringval
= nullptr;
806 /* Parameter Scheme functions. */
808 /* (make-parameter name
809 [#:command-class cmd-class] [#:parameter-type param-type]
810 [#:enum-list enum-list] [#:set-func function] [#:show-func function]
811 [#:doc <string>] [#:set-doc <string>] [#:show-doc <string>]
812 [#:initial-value initial-value]) -> <gdb:parameter>
814 NAME is the name of the parameter. It may consist of multiple
815 words, in which case the final word is the name of the new parameter,
816 and earlier words must be prefix commands.
818 CMD-CLASS is the kind of command. It should be one of the COMMAND_*
819 constants defined in the gdb module.
821 PARAM_TYPE is the type of the parameter. It should be one of the
822 PARAM_* constants defined in the gdb module.
824 If PARAM-TYPE is PARAM_ENUM, then ENUM-LIST is a list of strings that
825 are the valid values for this parameter. The first value is the default.
827 SET-FUNC, if provided, is called after the parameter is set.
828 It is a function of one parameter: the <gdb:parameter> object.
829 It must return a string to be displayed to the user.
830 Setting a parameter is typically a silent operation, so typically ""
833 SHOW-FUNC, if provided, returns the string that is printed.
834 It is a function of two parameters: the <gdb:parameter> object
835 and the current value of the parameter as a string.
837 DOC, SET-DOC, SHOW-DOC are the doc strings for the parameter.
839 INITIAL-VALUE is the initial value of the parameter.
841 The result is the <gdb:parameter> Scheme object.
842 The parameter is not available to be used yet, however.
843 It must still be added to gdb with register-parameter!. */
846 gdbscm_make_parameter (SCM name_scm
, SCM rest
)
848 const SCM keywords
[] = {
849 command_class_keyword
, parameter_type_keyword
, enum_list_keyword
,
850 set_func_keyword
, show_func_keyword
,
851 doc_keyword
, set_doc_keyword
, show_doc_keyword
,
852 initial_value_keyword
, SCM_BOOL_F
854 int cmd_class_arg_pos
= -1, param_type_arg_pos
= -1;
855 int enum_list_arg_pos
= -1, set_func_arg_pos
= -1, show_func_arg_pos
= -1;
856 int doc_arg_pos
= -1, set_doc_arg_pos
= -1, show_doc_arg_pos
= -1;
857 int initial_value_arg_pos
= -1;
860 int cmd_class
= no_class
;
861 int param_type
= var_boolean
; /* ARI: var_boolean */
862 SCM enum_list_scm
= SCM_BOOL_F
;
863 SCM set_func
= SCM_BOOL_F
, show_func
= SCM_BOOL_F
;
864 char *doc
= NULL
, *set_doc
= NULL
, *show_doc
= NULL
;
865 SCM initial_value_scm
= SCM_BOOL_F
;
866 const char * const *enum_list
= NULL
;
870 gdbscm_parse_function_args (FUNC_NAME
, SCM_ARG1
, keywords
, "s#iiOOOsssO",
871 name_scm
, &name
, rest
,
872 &cmd_class_arg_pos
, &cmd_class
,
873 ¶m_type_arg_pos
, ¶m_type
,
874 &enum_list_arg_pos
, &enum_list_scm
,
875 &set_func_arg_pos
, &set_func
,
876 &show_func_arg_pos
, &show_func
,
878 &set_doc_arg_pos
, &set_doc
,
879 &show_doc_arg_pos
, &show_doc
,
880 &initial_value_arg_pos
, &initial_value_scm
);
882 /* If doc is NULL, leave it NULL. See add_setshow_cmd_full. */
884 set_doc
= get_doc_string ();
885 if (show_doc
== NULL
)
886 show_doc
= get_doc_string ();
889 name
= gdbscm_canonicalize_command_name (s
, 0);
894 doc
= gdbscm_gc_xstrdup (s
);
898 set_doc
= gdbscm_gc_xstrdup (s
);
901 show_doc
= gdbscm_gc_xstrdup (s
);
904 if (!gdbscm_valid_command_class_p (cmd_class
))
906 gdbscm_out_of_range_error (FUNC_NAME
, cmd_class_arg_pos
,
907 scm_from_int (cmd_class
),
908 _("invalid command class argument"));
910 if (!pascm_valid_parameter_type_p (param_type
))
912 gdbscm_out_of_range_error (FUNC_NAME
, param_type_arg_pos
,
913 scm_from_int (param_type
),
914 _("invalid parameter type argument"));
916 if (enum_list_arg_pos
> 0 && param_type
!= var_enum
)
918 gdbscm_misc_error (FUNC_NAME
, enum_list_arg_pos
, enum_list_scm
,
919 _("#:enum-values can only be provided with PARAM_ENUM"));
921 if (enum_list_arg_pos
< 0 && param_type
== var_enum
)
923 gdbscm_misc_error (FUNC_NAME
, GDBSCM_ARG_NONE
, SCM_BOOL_F
,
924 _("PARAM_ENUM requires an enum-values argument"));
926 if (set_func_arg_pos
> 0)
928 SCM_ASSERT_TYPE (gdbscm_is_procedure (set_func
), set_func
,
929 set_func_arg_pos
, FUNC_NAME
, _("procedure"));
931 if (show_func_arg_pos
> 0)
933 SCM_ASSERT_TYPE (gdbscm_is_procedure (show_func
), show_func
,
934 show_func_arg_pos
, FUNC_NAME
, _("procedure"));
936 if (param_type
== var_enum
)
938 /* Note: enum_list lives in GC space, so we don't have to worry about
939 freeing it if we later throw an exception. */
940 enum_list
= compute_enum_list (enum_list_scm
, enum_list_arg_pos
,
944 /* If initial-value is a function, we need the parameter object constructed
945 to pass it to the function. A typical thing the function may want to do
946 is add an object-property to it to record the last known good value. */
947 p_scm
= pascm_make_param_smob ();
948 p_smob
= (param_smob
*) SCM_SMOB_DATA (p_scm
);
949 /* These are all stored in GC space so that we don't have to worry about
950 freeing them if we throw an exception. */
952 p_smob
->cmd_class
= (enum command_class
) cmd_class
;
953 p_smob
->type
= (enum var_types
) param_type
;
955 p_smob
->set_doc
= set_doc
;
956 p_smob
->show_doc
= show_doc
;
957 p_smob
->enumeration
= enum_list
;
958 p_smob
->set_func
= set_func
;
959 p_smob
->show_func
= show_func
;
961 scm_set_smob_free (parameter_smob_tag
, pascm_free_parameter_smob
);
962 if (var_type_uses
<std::string
> (p_smob
->type
))
963 p_smob
->value
.stringval
= new std::string
;
965 if (initial_value_arg_pos
> 0)
967 if (gdbscm_is_procedure (initial_value_scm
))
969 initial_value_scm
= gdbscm_safe_call_1 (initial_value_scm
,
970 p_smob
->containing_scm
, NULL
);
971 if (gdbscm_is_exception (initial_value_scm
))
972 gdbscm_throw (initial_value_scm
);
974 pascm_set_param_value_x (p_smob
, enum_list
,
976 initial_value_arg_pos
, FUNC_NAME
);
982 /* Subroutine of gdbscm_register_parameter_x to simplify it.
983 Return non-zero if parameter NAME is already defined in LIST. */
986 pascm_parameter_defined_p (const char *name
, struct cmd_list_element
*list
)
988 struct cmd_list_element
*c
;
990 c
= lookup_cmd_1 (&name
, list
, NULL
, NULL
, 1);
992 /* If the name is ambiguous that's ok, it's a new parameter still. */
993 return c
!= NULL
&& c
!= CMD_LIST_AMBIGUOUS
;
996 /* (register-parameter! <gdb:parameter>) -> unspecified
998 It is an error to register a pre-existing parameter. */
1001 gdbscm_register_parameter_x (SCM self
)
1004 = pascm_get_param_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
1006 struct cmd_list_element
**set_list
, **show_list
;
1008 if (pascm_is_valid (p_smob
))
1009 scm_misc_error (FUNC_NAME
, _("parameter is already registered"), SCM_EOL
);
1011 cmd_name
= gdbscm_parse_command_name (p_smob
->name
, FUNC_NAME
, SCM_ARG1
,
1012 &set_list
, &setlist
);
1014 cmd_name
= gdbscm_parse_command_name (p_smob
->name
, FUNC_NAME
, SCM_ARG1
,
1015 &show_list
, &showlist
);
1016 p_smob
->cmd_name
= gdbscm_gc_xstrdup (cmd_name
);
1019 if (pascm_parameter_defined_p (p_smob
->cmd_name
, *set_list
))
1021 gdbscm_misc_error (FUNC_NAME
, SCM_ARG1
, self
,
1022 _("parameter exists, \"set\" command is already defined"));
1024 if (pascm_parameter_defined_p (p_smob
->cmd_name
, *show_list
))
1026 gdbscm_misc_error (FUNC_NAME
, SCM_ARG1
, self
,
1027 _("parameter exists, \"show\" command is already defined"));
1030 gdbscm_gdb_exception exc
{};
1033 p_smob
->commands
= add_setshow_generic
1034 (p_smob
->type
, p_smob
->cmd_class
, p_smob
->cmd_name
, p_smob
,
1035 p_smob
->set_doc
, p_smob
->show_doc
, p_smob
->doc
,
1036 (gdbscm_is_procedure (p_smob
->set_func
) ? pascm_set_func
: NULL
),
1037 (gdbscm_is_procedure (p_smob
->show_func
) ? pascm_show_func
: NULL
),
1038 set_list
, show_list
);
1040 catch (const gdb_exception
&except
)
1042 exc
= unpack (except
);
1045 GDBSCM_HANDLE_GDB_EXCEPTION (exc
);
1046 /* Note: At this point the parameter exists in gdb.
1047 So no more errors after this point. */
1049 /* The owner of this parameter is not in GC-controlled memory, so we need
1050 to protect it from GC until the parameter is deleted. */
1051 scm_gc_protect_object (p_smob
->containing_scm
);
1053 return SCM_UNSPECIFIED
;
1056 /* (parameter-value <gdb:parameter>) -> value
1057 (parameter-value <string>) -> value */
1060 gdbscm_parameter_value (SCM self
)
1062 SCM_ASSERT_TYPE (pascm_is_parameter (self
) || scm_is_string (self
),
1063 self
, SCM_ARG1
, FUNC_NAME
, _("<gdb:parameter> or string"));
1065 if (pascm_is_parameter (self
))
1067 param_smob
*p_smob
= pascm_get_param_smob_arg_unsafe (self
, SCM_ARG1
,
1070 return pascm_param_value (make_setting (p_smob
), SCM_ARG1
, FUNC_NAME
);
1075 struct cmd_list_element
*alias
, *prefix
, *cmd
;
1078 gdbscm_gdb_exception except
{};
1080 gdb::unique_xmalloc_ptr
<char> name
1081 = gdbscm_scm_to_host_string (self
, NULL
, &except_scm
);
1083 gdbscm_throw (except_scm
);
1084 newarg
= concat ("show ", name
.get (), (char *) NULL
);
1087 found
= lookup_cmd_composition (newarg
, &alias
, &prefix
, &cmd
);
1089 catch (const gdb_exception
&ex
)
1091 except
= unpack (ex
);
1095 GDBSCM_HANDLE_GDB_EXCEPTION (except
);
1098 gdbscm_out_of_range_error (FUNC_NAME
, SCM_ARG1
, self
,
1099 _("parameter not found"));
1102 if (!cmd
->var
.has_value ())
1104 gdbscm_out_of_range_error (FUNC_NAME
, SCM_ARG1
, self
,
1105 _("not a parameter"));
1108 return pascm_param_value (*cmd
->var
, SCM_ARG1
, FUNC_NAME
);
1112 /* (set-parameter-value! <gdb:parameter> value) -> unspecified */
1115 gdbscm_set_parameter_value_x (SCM self
, SCM value
)
1117 param_smob
*p_smob
= pascm_get_param_smob_arg_unsafe (self
, SCM_ARG1
,
1120 pascm_set_param_value_x (p_smob
, p_smob
->enumeration
,
1121 value
, SCM_ARG2
, FUNC_NAME
);
1123 return SCM_UNSPECIFIED
;
1126 /* Initialize the Scheme parameter support. */
1128 static const scheme_function parameter_functions
[] =
1130 { "make-parameter", 1, 0, 1, as_a_scm_t_subr (gdbscm_make_parameter
),
1132 Make a GDB parameter object.\n\
1135 [#:command-class <cmd-class>] [#:parameter-type <parameter-type>]\n\
1136 [#:enum-list <enum-list>]\n\
1137 [#:set-func function] [#:show-func function]\n\
1138 [#:doc string] [#:set-doc string] [#:show-doc string]\n\
1139 [#:initial-value initial-value]\n\
1140 name: The name of the command. It may consist of multiple words,\n\
1141 in which case the final word is the name of the new parameter, and\n\
1142 earlier words must be prefix commands.\n\
1143 cmd-class: The class of the command, one of COMMAND_*.\n\
1144 The default is COMMAND_NONE.\n\
1145 parameter-type: The kind of parameter, one of PARAM_*\n\
1146 The default is PARAM_BOOLEAN.\n\
1147 enum-list: If parameter-type is PARAM_ENUM, then this specifies the set\n\
1148 of values of the enum.\n\
1149 set-func: A function of one parameter: the <gdb:parameter> object.\n\
1150 Called *after* the parameter has been set. Returns either \"\" or a\n\
1151 non-empty string to be displayed to the user.\n\
1152 If non-empty, GDB will add a trailing newline.\n\
1153 show-func: A function of two parameters: the <gdb:parameter> object\n\
1154 and the string representation of the current value.\n\
1155 The result is a string to be displayed to the user.\n\
1156 GDB will add a trailing newline.\n\
1157 doc: The \"doc string\" of the parameter.\n\
1158 set-doc: The \"doc string\" when setting the parameter.\n\
1159 show-doc: The \"doc string\" when showing the parameter.\n\
1160 initial-value: The initial value of the parameter." },
1162 { "register-parameter!", 1, 0, 0,
1163 as_a_scm_t_subr (gdbscm_register_parameter_x
),
1165 Register a <gdb:parameter> object with GDB." },
1167 { "parameter?", 1, 0, 0, as_a_scm_t_subr (gdbscm_parameter_p
),
1169 Return #t if the object is a <gdb:parameter> object." },
1171 { "parameter-value", 1, 0, 0, as_a_scm_t_subr (gdbscm_parameter_value
),
1173 Return the value of a <gdb:parameter> object\n\
1174 or any gdb parameter if param is a string naming the parameter." },
1176 { "set-parameter-value!", 2, 0, 0,
1177 as_a_scm_t_subr (gdbscm_set_parameter_value_x
),
1179 Set the value of a <gdb:parameter> object.\n\
1181 Arguments: <gdb:parameter> value" },
1187 gdbscm_initialize_parameters (void)
1190 = gdbscm_make_smob_type (param_smob_name
, sizeof (param_smob
));
1191 scm_set_smob_print (parameter_smob_tag
, pascm_print_param_smob
);
1193 gdbscm_define_integer_constants (parameter_types
, 1);
1194 gdbscm_define_functions (parameter_functions
, 1);
1196 command_class_keyword
= scm_from_latin1_keyword ("command-class");
1197 parameter_type_keyword
= scm_from_latin1_keyword ("parameter-type");
1198 enum_list_keyword
= scm_from_latin1_keyword ("enum-list");
1199 set_func_keyword
= scm_from_latin1_keyword ("set-func");
1200 show_func_keyword
= scm_from_latin1_keyword ("show-func");
1201 doc_keyword
= scm_from_latin1_keyword ("doc");
1202 set_doc_keyword
= scm_from_latin1_keyword ("set-doc");
1203 show_doc_keyword
= scm_from_latin1_keyword ("show-doc");
1204 initial_value_keyword
= scm_from_latin1_keyword ("initial-value");
1205 auto_keyword
= scm_from_latin1_keyword ("auto");
1206 unlimited_keyword
= scm_from_latin1_keyword ("unlimited");