Fix "set integer-command unlimited junk"
[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)
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)
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 switch (c->var_type)
312 {
313 case var_string:
314 {
315 char *newobj;
316 const char *p;
317 char *q;
318 int ch;
319
320 if (arg == NULL)
321 arg = "";
322 newobj = (char *) xmalloc (strlen (arg) + 2);
323 p = arg;
324 q = newobj;
325 while ((ch = *p++) != '\000')
326 {
327 if (ch == '\\')
328 {
329 /* \ at end of argument is used after spaces
330 so they won't be lost. */
331 /* This is obsolete now that we no longer strip
332 trailing whitespace and actually, the backslash
333 didn't get here in my test, readline or
334 something did something funky with a backslash
335 right before a newline. */
336 if (*p == 0)
337 break;
338 ch = parse_escape (get_current_arch (), &p);
339 if (ch == 0)
340 break; /* C loses */
341 else if (ch > 0)
342 *q++ = ch;
343 }
344 else
345 *q++ = ch;
346 }
347 #if 0
348 if (*(p - 1) != '\\')
349 *q++ = ' ';
350 #endif
351 *q++ = '\0';
352 newobj = (char *) xrealloc (newobj, q - newobj);
353
354 if (*(char **) c->var == NULL
355 || strcmp (*(char **) c->var, newobj) != 0)
356 {
357 xfree (*(char **) c->var);
358 *(char **) c->var = newobj;
359
360 option_changed = 1;
361 }
362 else
363 xfree (newobj);
364 }
365 break;
366 case var_string_noescape:
367 if (arg == NULL)
368 arg = "";
369
370 if (*(char **) c->var == NULL || strcmp (*(char **) c->var, arg) != 0)
371 {
372 xfree (*(char **) c->var);
373 *(char **) c->var = xstrdup (arg);
374
375 option_changed = 1;
376 }
377 break;
378 case var_filename:
379 if (arg == NULL)
380 error_no_arg (_("filename to set it to."));
381 /* FALLTHROUGH */
382 case var_optional_filename:
383 {
384 char *val = NULL;
385
386 if (arg != NULL)
387 {
388 /* Clear trailing whitespace of filename. */
389 const char *ptr = arg + strlen (arg) - 1;
390 char *copy;
391
392 while (ptr >= arg && (*ptr == ' ' || *ptr == '\t'))
393 ptr--;
394 copy = xstrndup (arg, ptr + 1 - arg);
395
396 val = tilde_expand (copy);
397 xfree (copy);
398 }
399 else
400 val = xstrdup ("");
401
402 if (*(char **) c->var == NULL
403 || strcmp (*(char **) c->var, val) != 0)
404 {
405 xfree (*(char **) c->var);
406 *(char **) c->var = val;
407
408 option_changed = 1;
409 }
410 else
411 xfree (val);
412 }
413 break;
414 case var_boolean:
415 {
416 int val = parse_cli_boolean_value (arg);
417
418 if (val < 0)
419 error (_("\"on\" or \"off\" expected."));
420 if (val != *(int *) c->var)
421 {
422 *(int *) c->var = val;
423
424 option_changed = 1;
425 }
426 }
427 break;
428 case var_auto_boolean:
429 {
430 enum auto_boolean val = parse_auto_binary_operation (arg);
431
432 if (*(enum auto_boolean *) c->var != val)
433 {
434 *(enum auto_boolean *) c->var = val;
435
436 option_changed = 1;
437 }
438 }
439 break;
440 case var_uinteger:
441 case var_zuinteger:
442 {
443 unsigned int val = parse_cli_var_uinteger (c->var_type, &arg, true);
444
445 if (*(unsigned int *) c->var != val)
446 {
447 *(unsigned int *) c->var = val;
448
449 option_changed = 1;
450 }
451 }
452 break;
453 case var_integer:
454 case var_zinteger:
455 {
456 LONGEST val;
457
458 if (arg == NULL)
459 {
460 if (c->var_type == var_integer)
461 error_no_arg (_("integer to set it to, or \"unlimited\"."));
462 else
463 error_no_arg (_("integer to set it to."));
464 }
465
466 if (c->var_type == var_integer && is_unlimited_literal (&arg, true))
467 val = 0;
468 else
469 val = parse_and_eval_long (arg);
470
471 if (val == 0 && c->var_type == var_integer)
472 val = INT_MAX;
473 else if (val < INT_MIN
474 /* For var_integer, don't let the user set the value
475 to INT_MAX directly, as that exposes an
476 implementation detail to the user interface. */
477 || (c->var_type == var_integer && val >= INT_MAX)
478 || (c->var_type == var_zinteger && val > INT_MAX))
479 error (_("integer %s out of range"), plongest (val));
480
481 if (*(int *) c->var != val)
482 {
483 *(int *) c->var = val;
484
485 option_changed = 1;
486 }
487 break;
488 }
489 case var_enum:
490 {
491 const char *end_arg = arg;
492 const char *match = parse_cli_var_enum (&end_arg, c->enums);
493
494 int len = end_arg - arg;
495 const char *after = skip_spaces (end_arg);
496 if (*after != '\0')
497 error (_("Junk after item \"%.*s\": %s"), len, arg, after);
498
499 if (*(const char **) c->var != match)
500 {
501 *(const char **) c->var = match;
502
503 option_changed = 1;
504 }
505 }
506 break;
507 case var_zuinteger_unlimited:
508 {
509 int val = parse_cli_var_zuinteger_unlimited (&arg, true);
510
511 if (*(int *) c->var != val)
512 {
513 *(int *) c->var = val;
514 option_changed = 1;
515 }
516 }
517 break;
518 default:
519 error (_("gdb internal error: bad var_type in do_setshow_command"));
520 }
521 c->func (c, NULL, from_tty);
522
523 if (notify_command_param_changed_p (option_changed, c))
524 {
525 char *name, *cp;
526 struct cmd_list_element **cmds;
527 struct cmd_list_element *p;
528 int i;
529 int length = 0;
530
531 /* Compute the whole multi-word command options. If user types command
532 'set foo bar baz on', c->name is 'baz', and GDB can't pass "bar" to
533 command option change notification, because it is confusing. We can
534 trace back through field 'prefix' to compute the whole options,
535 and pass "foo bar baz" to notification. */
536
537 for (i = 0, p = c; p != NULL; i++)
538 {
539 length += strlen (p->name);
540 length++;
541
542 p = p->prefix;
543 }
544 cp = name = (char *) xmalloc (length);
545 cmds = XNEWVEC (struct cmd_list_element *, i);
546
547 /* Track back through filed 'prefix' and cache them in CMDS. */
548 for (i = 0, p = c; p != NULL; i++)
549 {
550 cmds[i] = p;
551 p = p->prefix;
552 }
553
554 /* Don't trigger any observer notification if prefixlist is not
555 setlist. */
556 i--;
557 if (cmds[i]->prefixlist != &setlist)
558 {
559 xfree (cmds);
560 xfree (name);
561
562 return;
563 }
564 /* Traverse them in the reversed order, and copy their names into
565 NAME. */
566 for (i--; i >= 0; i--)
567 {
568 memcpy (cp, cmds[i]->name, strlen (cmds[i]->name));
569 cp += strlen (cmds[i]->name);
570
571 if (i != 0)
572 {
573 cp[0] = ' ';
574 cp++;
575 }
576 }
577 cp[0] = 0;
578
579 xfree (cmds);
580
581 switch (c->var_type)
582 {
583 case var_string:
584 case var_string_noescape:
585 case var_filename:
586 case var_optional_filename:
587 case var_enum:
588 gdb::observers::command_param_changed.notify (name, *(char **) c->var);
589 break;
590 case var_boolean:
591 {
592 const char *opt = *(int *) c->var ? "on" : "off";
593
594 gdb::observers::command_param_changed.notify (name, opt);
595 }
596 break;
597 case var_auto_boolean:
598 {
599 const char *s = auto_boolean_enums[*(enum auto_boolean *) c->var];
600
601 gdb::observers::command_param_changed.notify (name, s);
602 }
603 break;
604 case var_uinteger:
605 case var_zuinteger:
606 {
607 char s[64];
608
609 xsnprintf (s, sizeof s, "%u", *(unsigned int *) c->var);
610 gdb::observers::command_param_changed.notify (name, s);
611 }
612 break;
613 case var_integer:
614 case var_zinteger:
615 case var_zuinteger_unlimited:
616 {
617 char s[64];
618
619 xsnprintf (s, sizeof s, "%d", *(int *) c->var);
620 gdb::observers::command_param_changed.notify (name, s);
621 }
622 break;
623 }
624 xfree (name);
625 }
626 }
627
628 /* Do a "show" command. ARG is NULL if no argument, or the
629 text of the argument, and FROM_TTY is nonzero if this command is
630 being entered directly by the user (i.e. these are just like any
631 other command). C is the command list element for the command. */
632
633 void
634 do_show_command (const char *arg, int from_tty, struct cmd_list_element *c)
635 {
636 struct ui_out *uiout = current_uiout;
637
638 gdb_assert (c->type == show_cmd);
639
640 string_file stb;
641
642 /* Possibly call the pre hook. */
643 if (c->pre_show_hook)
644 (c->pre_show_hook) (c);
645
646 switch (c->var_type)
647 {
648 case var_string:
649 if (*(char **) c->var)
650 stb.putstr (*(char **) c->var, '"');
651 break;
652 case var_string_noescape:
653 case var_optional_filename:
654 case var_filename:
655 case var_enum:
656 if (*(char **) c->var)
657 stb.puts (*(char **) c->var);
658 break;
659 case var_boolean:
660 stb.puts (*(int *) c->var ? "on" : "off");
661 break;
662 case var_auto_boolean:
663 switch (*(enum auto_boolean*) c->var)
664 {
665 case AUTO_BOOLEAN_TRUE:
666 stb.puts ("on");
667 break;
668 case AUTO_BOOLEAN_FALSE:
669 stb.puts ("off");
670 break;
671 case AUTO_BOOLEAN_AUTO:
672 stb.puts ("auto");
673 break;
674 default:
675 internal_error (__FILE__, __LINE__,
676 _("do_show_command: "
677 "invalid var_auto_boolean"));
678 break;
679 }
680 break;
681 case var_uinteger:
682 case var_zuinteger:
683 if (c->var_type == var_uinteger
684 && *(unsigned int *) c->var == UINT_MAX)
685 stb.puts ("unlimited");
686 else
687 stb.printf ("%u", *(unsigned int *) c->var);
688 break;
689 case var_integer:
690 case var_zinteger:
691 if (c->var_type == var_integer
692 && *(int *) c->var == INT_MAX)
693 stb.puts ("unlimited");
694 else
695 stb.printf ("%d", *(int *) c->var);
696 break;
697 case var_zuinteger_unlimited:
698 {
699 if (*(int *) c->var == -1)
700 stb.puts ("unlimited");
701 else
702 stb.printf ("%d", *(int *) c->var);
703 }
704 break;
705 default:
706 error (_("gdb internal error: bad var_type in do_show_command"));
707 }
708
709
710 /* FIXME: cagney/2005-02-10: Need to split this in half: code to
711 convert the value into a string (esentially the above); and
712 code to print the value out. For the latter there should be
713 MI and CLI specific versions. */
714
715 if (uiout->is_mi_like_p ())
716 uiout->field_stream ("value", stb);
717 else
718 {
719 if (c->show_value_func != NULL)
720 c->show_value_func (gdb_stdout, from_tty, c, stb.c_str ());
721 else
722 deprecated_show_value_hack (gdb_stdout, from_tty, c, stb.c_str ());
723 }
724
725 c->func (c, NULL, from_tty);
726 }
727
728 /* Show all the settings in a list of show commands. */
729
730 void
731 cmd_show_list (struct cmd_list_element *list, int from_tty, const char *prefix)
732 {
733 struct ui_out *uiout = current_uiout;
734
735 ui_out_emit_tuple tuple_emitter (uiout, "showlist");
736 for (; list != NULL; list = list->next)
737 {
738 /* If we find a prefix, run its list, prefixing our output by its
739 prefix (with "show " skipped). */
740 if (list->prefixlist && !list->abbrev_flag)
741 {
742 ui_out_emit_tuple optionlist_emitter (uiout, "optionlist");
743 const char *new_prefix = strstr (list->prefixname, "show ") + 5;
744
745 if (uiout->is_mi_like_p ())
746 uiout->field_string ("prefix", new_prefix);
747 cmd_show_list (*list->prefixlist, from_tty, new_prefix);
748 }
749 else
750 {
751 if (list->theclass != no_set_class)
752 {
753 ui_out_emit_tuple option_emitter (uiout, "option");
754
755 uiout->text (prefix);
756 uiout->field_string ("name", list->name);
757 uiout->text (": ");
758 if (list->type == show_cmd)
759 do_show_command ((char *) NULL, from_tty, list);
760 else
761 cmd_func (list, NULL, from_tty);
762 }
763 }
764 }
765 }
766
This page took 0.059563 seconds and 4 git commands to generate.