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