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