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