1 /* Handle set and show GDB commands. 2 3 Copyright (C) 2000-2023 Free Software Foundation, Inc. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 18 #include "defs.h" 19 #include "readline/tilde.h" 20 #include "value.h" 21 #include <ctype.h> 22 #include "arch-utils.h" 23 #include "observable.h" 24 25 #include "ui-out.h" 26 27 #include "cli/cli-decode.h" 28 #include "cli/cli-cmds.h" 29 #include "cli/cli-setshow.h" 30 #include "cli/cli-utils.h" 31 32 /* Return true if the change of command parameter should be notified. */ 33 34 static bool 35 notify_command_param_changed_p (bool param_changed, struct cmd_list_element *c) 36 { 37 if (!param_changed) 38 return false; 39 40 return c->theclass != class_maintenance && c->theclass != class_obscure; 41 } 42 43 44 static enum auto_boolean 45 parse_auto_binary_operation (const char *arg) 46 { 47 if (arg != NULL && *arg != '\0') 48 { 49 int length = strlen (arg); 50 51 while (isspace (arg[length - 1]) && length > 0) 52 length--; 53 54 /* Note that "o" is ambiguous. */ 55 56 if ((length == 2 && strncmp (arg, "on", length) == 0) 57 || strncmp (arg, "1", length) == 0 58 || strncmp (arg, "yes", length) == 0 59 || strncmp (arg, "enable", length) == 0) 60 return AUTO_BOOLEAN_TRUE; 61 else if ((length >= 2 && strncmp (arg, "off", length) == 0) 62 || strncmp (arg, "0", length) == 0 63 || strncmp (arg, "no", length) == 0 64 || strncmp (arg, "disable", length) == 0) 65 return AUTO_BOOLEAN_FALSE; 66 else if (strncmp (arg, "auto", length) == 0 67 || (length > 1 && strncmp (arg, "-1", length) == 0)) 68 return AUTO_BOOLEAN_AUTO; 69 } 70 error (_("\"on\", \"off\" or \"auto\" expected.")); 71 return AUTO_BOOLEAN_AUTO; /* Pacify GCC. */ 72 } 73 74 /* See cli-setshow.h. */ 75 76 int 77 parse_cli_boolean_value (const char **arg) 78 { 79 const char *p = skip_to_space (*arg); 80 size_t length = p - *arg; 81 82 /* Note that "o" is ambiguous. */ 83 84 if ((length == 2 && strncmp (*arg, "on", length) == 0) 85 || strncmp (*arg, "1", length) == 0 86 || strncmp (*arg, "yes", length) == 0 87 || strncmp (*arg, "enable", length) == 0) 88 { 89 *arg = skip_spaces (*arg + length); 90 return 1; 91 } 92 else if ((length >= 2 && strncmp (*arg, "off", length) == 0) 93 || strncmp (*arg, "0", length) == 0 94 || strncmp (*arg, "no", length) == 0 95 || strncmp (*arg, "disable", length) == 0) 96 { 97 *arg = skip_spaces (*arg + length); 98 return 0; 99 } 100 else 101 return -1; 102 } 103 104 /* See cli-setshow.h. */ 105 106 int 107 parse_cli_boolean_value (const char *arg) 108 { 109 if (!arg || !*arg) 110 return 1; 111 112 int b = parse_cli_boolean_value (&arg); 113 if (b >= 0 && *arg != '\0') 114 return -1; 115 116 return b; 117 } 118 119 120 void 121 deprecated_show_value_hack (struct ui_file *ignore_file, 122 int ignore_from_tty, 123 struct cmd_list_element *c, 124 const char *value) 125 { 126 /* If there's no command or value, don't try to print it out. */ 127 if (c == NULL || value == NULL) 128 return; 129 130 /* Print doc minus "Show " at start. Tell print_doc_line that 131 this is for a 'show value' prefix. */ 132 print_doc_line (gdb_stdout, c->doc + 5, true); 133 134 gdb_assert (c->var.has_value ()); 135 136 switch (c->var->type ()) 137 { 138 case var_string: 139 case var_string_noescape: 140 case var_optional_filename: 141 case var_filename: 142 case var_enum: 143 gdb_printf ((" is \"%s\".\n"), value); 144 break; 145 146 default: 147 gdb_printf ((" is %s.\n"), value); 148 break; 149 } 150 } 151 152 /* Returns true if ARG is "unlimited". */ 153 154 static bool 155 is_unlimited_literal (const char **arg, bool expression) 156 { 157 *arg = skip_spaces (*arg); 158 159 const char *unl_start = *arg; 160 161 const char *p = skip_to_space (*arg); 162 163 size_t len = p - *arg; 164 165 if (len > 0 && strncmp ("unlimited", *arg, len) == 0) 166 { 167 *arg += len; 168 169 /* If parsing an expression (i.e., parsing for a "set" command), 170 anything after "unlimited" is junk. For options, anything 171 after "unlimited" might be a command argument or another 172 option. */ 173 if (expression) 174 { 175 const char *after = skip_spaces (*arg); 176 if (*after != '\0') 177 error (_("Junk after \"%.*s\": %s"), 178 (int) len, unl_start, after); 179 } 180 181 return true; 182 } 183 184 return false; 185 } 186 187 /* See cli-setshow.h. */ 188 189 unsigned int 190 parse_cli_var_uinteger (var_types var_type, const char **arg, 191 bool expression) 192 { 193 LONGEST val; 194 195 if (*arg == nullptr || **arg == '\0') 196 { 197 if (var_type == var_uinteger) 198 error_no_arg (_("integer to set it to, or \"unlimited\"")); 199 else 200 error_no_arg (_("integer to set it to")); 201 } 202 203 if (var_type == var_uinteger && is_unlimited_literal (arg, expression)) 204 val = 0; 205 else if (expression) 206 val = parse_and_eval_long (*arg); 207 else 208 val = get_ulongest (arg); 209 210 if (var_type == var_uinteger && val == 0) 211 val = UINT_MAX; 212 else if (val < 0 213 /* For var_uinteger, don't let the user set the value 214 to UINT_MAX directly, as that exposes an 215 implementation detail to the user interface. */ 216 || (var_type == var_uinteger && val >= UINT_MAX) 217 || (var_type == var_zuinteger && val > UINT_MAX)) 218 error (_("integer %s out of range"), plongest (val)); 219 220 return val; 221 } 222 223 /* See cli-setshow.h. */ 224 225 int 226 parse_cli_var_zuinteger_unlimited (const char **arg, bool expression) 227 { 228 LONGEST val; 229 230 if (*arg == nullptr || **arg == '\0') 231 error_no_arg (_("integer to set it to, or \"unlimited\"")); 232 233 if (is_unlimited_literal (arg, expression)) 234 val = -1; 235 else if (expression) 236 val = parse_and_eval_long (*arg); 237 else 238 val = get_ulongest (arg); 239 240 if (val > INT_MAX) 241 error (_("integer %s out of range"), plongest (val)); 242 else if (val < -1) 243 error (_("only -1 is allowed to set as unlimited")); 244 245 return val; 246 } 247 248 /* See cli-setshow.h. */ 249 250 const char * 251 parse_cli_var_enum (const char **args, const char *const *enums) 252 { 253 /* If no argument was supplied, print an informative error 254 message. */ 255 if (args == NULL || *args == NULL || **args == '\0') 256 { 257 std::string msg; 258 259 for (size_t i = 0; enums[i]; i++) 260 { 261 if (i != 0) 262 msg += ", "; 263 msg += enums[i]; 264 } 265 error (_("Requires an argument. Valid arguments are %s."), 266 msg.c_str ()); 267 } 268 269 const char *p = skip_to_space (*args); 270 size_t len = p - *args; 271 272 int nmatches = 0; 273 const char *match = NULL; 274 for (size_t i = 0; enums[i]; i++) 275 if (strncmp (*args, enums[i], len) == 0) 276 { 277 if (enums[i][len] == '\0') 278 { 279 match = enums[i]; 280 nmatches = 1; 281 break; /* Exact match. */ 282 } 283 else 284 { 285 match = enums[i]; 286 nmatches++; 287 } 288 } 289 290 if (nmatches == 0) 291 error (_("Undefined item: \"%.*s\"."), (int) len, *args); 292 293 if (nmatches > 1) 294 error (_("Ambiguous item \"%.*s\"."), (int) len, *args); 295 296 *args += len; 297 return match; 298 } 299 300 /* Do a "set" command. ARG is NULL if no argument, or the 301 text of the argument, and FROM_TTY is nonzero if this command is 302 being entered directly by the user (i.e. these are just like any 303 other command). C is the command list element for the command. */ 304 305 void 306 do_set_command (const char *arg, int from_tty, struct cmd_list_element *c) 307 { 308 /* A flag to indicate the option is changed or not. */ 309 bool option_changed = false; 310 311 gdb_assert (c->type == set_cmd); 312 313 if (arg == NULL) 314 arg = ""; 315 316 gdb_assert (c->var.has_value ()); 317 318 switch (c->var->type ()) 319 { 320 case var_string: 321 { 322 char *newobj; 323 const char *p; 324 char *q; 325 int ch; 326 327 newobj = (char *) xmalloc (strlen (arg) + 2); 328 p = arg; 329 q = newobj; 330 while ((ch = *p++) != '\000') 331 { 332 if (ch == '\\') 333 { 334 /* \ at end of argument is used after spaces 335 so they won't be lost. */ 336 /* This is obsolete now that we no longer strip 337 trailing whitespace and actually, the backslash 338 didn't get here in my test, readline or 339 something did something funky with a backslash 340 right before a newline. */ 341 if (*p == 0) 342 break; 343 ch = parse_escape (get_current_arch (), &p); 344 if (ch == 0) 345 break; /* C loses */ 346 else if (ch > 0) 347 *q++ = ch; 348 } 349 else 350 *q++ = ch; 351 } 352 #if 0 353 if (*(p - 1) != '\\') 354 *q++ = ' '; 355 #endif 356 *q++ = '\0'; 357 newobj = (char *) xrealloc (newobj, q - newobj); 358 359 option_changed = c->var->set<std::string> (std::string (newobj)); 360 xfree (newobj); 361 } 362 break; 363 case var_string_noescape: 364 option_changed = c->var->set<std::string> (std::string (arg)); 365 break; 366 case var_filename: 367 if (*arg == '\0') 368 error_no_arg (_("filename to set it to.")); 369 /* FALLTHROUGH */ 370 case var_optional_filename: 371 { 372 char *val = NULL; 373 374 if (*arg != '\0') 375 { 376 /* Clear trailing whitespace of filename. */ 377 const char *ptr = arg + strlen (arg) - 1; 378 379 while (ptr >= arg && (*ptr == ' ' || *ptr == '\t')) 380 ptr--; 381 gdb::unique_xmalloc_ptr<char> copy 382 = make_unique_xstrndup (arg, ptr + 1 - arg); 383 384 val = tilde_expand (copy.get ()); 385 } 386 else 387 val = xstrdup (""); 388 389 option_changed 390 = c->var->set<std::string> (std::string (val)); 391 xfree (val); 392 } 393 break; 394 case var_boolean: 395 { 396 int val = parse_cli_boolean_value (arg); 397 398 if (val < 0) 399 error (_("\"on\" or \"off\" expected.")); 400 401 option_changed = c->var->set<bool> (val); 402 } 403 break; 404 case var_auto_boolean: 405 option_changed = c->var->set<enum auto_boolean> (parse_auto_binary_operation (arg)); 406 break; 407 case var_uinteger: 408 case var_zuinteger: 409 option_changed 410 = c->var->set<unsigned int> (parse_cli_var_uinteger (c->var->type (), 411 &arg, true)); 412 break; 413 case var_integer: 414 case var_zinteger: 415 { 416 LONGEST val; 417 418 if (*arg == '\0') 419 { 420 if (c->var->type () == var_integer) 421 error_no_arg (_("integer to set it to, or \"unlimited\"")); 422 else 423 error_no_arg (_("integer to set it to")); 424 } 425 426 if (c->var->type () == var_integer && is_unlimited_literal (&arg, true)) 427 val = 0; 428 else 429 val = parse_and_eval_long (arg); 430 431 if (val == 0 && c->var->type () == var_integer) 432 val = INT_MAX; 433 else if (val < INT_MIN 434 /* For var_integer, don't let the user set the value 435 to INT_MAX directly, as that exposes an 436 implementation detail to the user interface. */ 437 || (c->var->type () == var_integer && val >= INT_MAX) 438 || (c->var->type () == var_zinteger && val > INT_MAX)) 439 error (_("integer %s out of range"), plongest (val)); 440 441 option_changed = c->var->set<int> (val); 442 } 443 break; 444 case var_enum: 445 { 446 const char *end_arg = arg; 447 const char *match = parse_cli_var_enum (&end_arg, c->enums); 448 449 int len = end_arg - arg; 450 const char *after = skip_spaces (end_arg); 451 if (*after != '\0') 452 error (_("Junk after item \"%.*s\": %s"), len, arg, after); 453 454 option_changed = c->var->set<const char *> (match); 455 } 456 break; 457 case var_zuinteger_unlimited: 458 option_changed = c->var->set<int> 459 (parse_cli_var_zuinteger_unlimited (&arg, true)); 460 break; 461 default: 462 error (_("gdb internal error: bad var_type in do_setshow_command")); 463 } 464 465 c->func (NULL, from_tty, c); 466 467 if (notify_command_param_changed_p (option_changed, c)) 468 { 469 char *name, *cp; 470 struct cmd_list_element **cmds; 471 struct cmd_list_element *p; 472 int i; 473 int length = 0; 474 475 /* Compute the whole multi-word command options. If user types command 476 'set foo bar baz on', c->name is 'baz', and GDB can't pass "bar" to 477 command option change notification, because it is confusing. We can 478 trace back through field 'prefix' to compute the whole options, 479 and pass "foo bar baz" to notification. */ 480 481 for (i = 0, p = c; p != NULL; i++) 482 { 483 length += strlen (p->name); 484 length++; 485 486 p = p->prefix; 487 } 488 cp = name = (char *) xmalloc (length); 489 cmds = XNEWVEC (struct cmd_list_element *, i); 490 491 /* Track back through filed 'prefix' and cache them in CMDS. */ 492 for (i = 0, p = c; p != NULL; i++) 493 { 494 cmds[i] = p; 495 p = p->prefix; 496 } 497 498 /* Don't trigger any observer notification if subcommands is not 499 setlist. */ 500 i--; 501 if (cmds[i]->subcommands != &setlist) 502 { 503 xfree (cmds); 504 xfree (name); 505 506 return; 507 } 508 /* Traverse them in the reversed order, and copy their names into 509 NAME. */ 510 for (i--; i >= 0; i--) 511 { 512 memcpy (cp, cmds[i]->name, strlen (cmds[i]->name)); 513 cp += strlen (cmds[i]->name); 514 515 if (i != 0) 516 { 517 cp[0] = ' '; 518 cp++; 519 } 520 } 521 cp[0] = 0; 522 523 xfree (cmds); 524 525 switch (c->var->type ()) 526 { 527 case var_string: 528 case var_string_noescape: 529 case var_filename: 530 case var_optional_filename: 531 gdb::observers::command_param_changed.notify 532 (name, c->var->get<std::string> ().c_str ()); 533 break; 534 case var_enum: 535 gdb::observers::command_param_changed.notify 536 (name, c->var->get<const char *> ()); 537 break; 538 case var_boolean: 539 { 540 const char *opt = c->var->get<bool> () ? "on" : "off"; 541 542 gdb::observers::command_param_changed.notify (name, opt); 543 } 544 break; 545 case var_auto_boolean: 546 { 547 const char *s 548 = auto_boolean_enums[c->var->get<enum auto_boolean> ()]; 549 550 gdb::observers::command_param_changed.notify (name, s); 551 } 552 break; 553 case var_uinteger: 554 case var_zuinteger: 555 { 556 char s[64]; 557 558 xsnprintf (s, sizeof s, "%u", c->var->get<unsigned int> ()); 559 gdb::observers::command_param_changed.notify (name, s); 560 } 561 break; 562 case var_integer: 563 case var_zinteger: 564 case var_zuinteger_unlimited: 565 { 566 char s[64]; 567 568 xsnprintf (s, sizeof s, "%d", c->var->get<int> ()); 569 gdb::observers::command_param_changed.notify (name, s); 570 } 571 break; 572 } 573 xfree (name); 574 } 575 } 576 577 /* See cli/cli-setshow.h. */ 578 579 std::string 580 get_setshow_command_value_string (const setting &var) 581 { 582 string_file stb; 583 584 switch (var.type ()) 585 { 586 case var_string: 587 { 588 std::string value = var.get<std::string> (); 589 if (!value.empty ()) 590 stb.putstr (value.c_str (), '"'); 591 } 592 break; 593 case var_string_noescape: 594 case var_optional_filename: 595 case var_filename: 596 stb.puts (var.get<std::string> ().c_str ()); 597 break; 598 case var_enum: 599 { 600 const char *value = var.get<const char *> (); 601 if (value != nullptr) 602 stb.puts (value); 603 } 604 break; 605 case var_boolean: 606 stb.puts (var.get<bool> () ? "on" : "off"); 607 break; 608 case var_auto_boolean: 609 switch (var.get<enum auto_boolean> ()) 610 { 611 case AUTO_BOOLEAN_TRUE: 612 stb.puts ("on"); 613 break; 614 case AUTO_BOOLEAN_FALSE: 615 stb.puts ("off"); 616 break; 617 case AUTO_BOOLEAN_AUTO: 618 stb.puts ("auto"); 619 break; 620 default: 621 gdb_assert_not_reached ("invalid var_auto_boolean"); 622 break; 623 } 624 break; 625 case var_uinteger: 626 case var_zuinteger: 627 { 628 const unsigned int value = var.get<unsigned int> (); 629 630 if (var.type () == var_uinteger 631 && value == UINT_MAX) 632 stb.puts ("unlimited"); 633 else 634 stb.printf ("%u", value); 635 } 636 break; 637 case var_integer: 638 case var_zinteger: 639 { 640 const int value = var.get<int> (); 641 642 if (var.type () == var_integer 643 && value == INT_MAX) 644 stb.puts ("unlimited"); 645 else 646 stb.printf ("%d", value); 647 } 648 break; 649 case var_zuinteger_unlimited: 650 { 651 const int value = var.get<int> (); 652 if (value == -1) 653 stb.puts ("unlimited"); 654 else 655 stb.printf ("%d", value); 656 } 657 break; 658 default: 659 gdb_assert_not_reached ("bad var_type"); 660 } 661 662 return stb.release (); 663 } 664 665 666 /* Do a "show" command. ARG is NULL if no argument, or the 667 text of the argument, and FROM_TTY is nonzero if this command is 668 being entered directly by the user (i.e. these are just like any 669 other command). C is the command list element for the command. */ 670 671 void 672 do_show_command (const char *arg, int from_tty, struct cmd_list_element *c) 673 { 674 struct ui_out *uiout = current_uiout; 675 676 gdb_assert (c->type == show_cmd); 677 gdb_assert (c->var.has_value ()); 678 679 std::string val = get_setshow_command_value_string (*c->var); 680 681 /* FIXME: cagney/2005-02-10: There should be MI and CLI specific 682 versions of code to print the value out. */ 683 684 if (uiout->is_mi_like_p ()) 685 uiout->field_string ("value", val); 686 else 687 { 688 if (c->show_value_func != NULL) 689 c->show_value_func (gdb_stdout, from_tty, c, val.c_str ()); 690 else 691 deprecated_show_value_hack (gdb_stdout, from_tty, c, val.c_str ()); 692 } 693 694 c->func (NULL, from_tty, c); 695 } 696 697 /* Show all the settings in a list of show commands. */ 698 699 void 700 cmd_show_list (struct cmd_list_element *list, int from_tty) 701 { 702 struct ui_out *uiout = current_uiout; 703 704 ui_out_emit_tuple tuple_emitter (uiout, "showlist"); 705 for (; list != NULL; list = list->next) 706 { 707 /* We skip show command aliases to avoid showing duplicated values. */ 708 709 /* If we find a prefix, run its list, prefixing our output by its 710 prefix (with "show " skipped). */ 711 if (list->is_prefix () && !list->is_alias ()) 712 { 713 ui_out_emit_tuple optionlist_emitter (uiout, "optionlist"); 714 std::string prefixname = list->prefixname (); 715 const char *new_prefix = strstr (prefixname.c_str (), "show ") + 5; 716 717 if (uiout->is_mi_like_p ()) 718 uiout->field_string ("prefix", new_prefix); 719 cmd_show_list (*list->subcommands, from_tty); 720 } 721 else if (list->theclass != no_set_class && !list->is_alias ()) 722 { 723 ui_out_emit_tuple option_emitter (uiout, "option"); 724 725 if (list->prefix != nullptr) 726 { 727 /* If we find a prefix, output it (with "show " skipped). */ 728 std::string prefixname = list->prefix->prefixname (); 729 prefixname = (!list->prefix->is_prefix () ? "" 730 : strstr (prefixname.c_str (), "show ") + 5); 731 uiout->text (prefixname); 732 } 733 uiout->field_string ("name", list->name); 734 uiout->text (": "); 735 if (list->type == show_cmd) 736 do_show_command (NULL, from_tty, list); 737 else 738 cmd_func (list, NULL, from_tty); 739 } 740 } 741 } 742 743 744