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