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