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