Subject: Fix range validation of integer commands with "unlimited".
[binutils-gdb.git] / gdb / cli / cli-setshow.c
1 /* Handle set and show GDB commands.
2
3 Copyright (C) 2000-2013 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 "gdb_string.h"
23 #include "arch-utils.h"
24 #include "observer.h"
25
26 #include "ui-out.h"
27
28 #include "cli/cli-decode.h"
29 #include "cli/cli-cmds.h"
30 #include "cli/cli-setshow.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->class == class_maintenance || c->class == class_deprecated
41 || c->class == 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 if (strncmp (arg, "on", length) == 0
58 || strncmp (arg, "1", length) == 0
59 || strncmp (arg, "yes", length) == 0
60 || strncmp (arg, "enable", length) == 0)
61 return AUTO_BOOLEAN_TRUE;
62 else if (strncmp (arg, "off", length) == 0
63 || strncmp (arg, "0", length) == 0
64 || strncmp (arg, "no", length) == 0
65 || strncmp (arg, "disable", length) == 0)
66 return AUTO_BOOLEAN_FALSE;
67 else if (strncmp (arg, "auto", length) == 0
68 || (strncmp (arg, "-1", length) == 0 && length > 1))
69 return AUTO_BOOLEAN_AUTO;
70 }
71 error (_("\"on\", \"off\" or \"auto\" expected."));
72 return AUTO_BOOLEAN_AUTO; /* Pacify GCC. */
73 }
74
75 /* See cli-setshow.h. */
76
77 int
78 parse_cli_boolean_value (char *arg)
79 {
80 int length;
81
82 if (!arg || !*arg)
83 return 1;
84
85 length = strlen (arg);
86
87 while (arg[length - 1] == ' ' || arg[length - 1] == '\t')
88 length--;
89
90 if (strncmp (arg, "on", length) == 0
91 || strncmp (arg, "1", length) == 0
92 || strncmp (arg, "yes", length) == 0
93 || strncmp (arg, "enable", length) == 0)
94 return 1;
95 else if (strncmp (arg, "off", length) == 0
96 || strncmp (arg, "0", length) == 0
97 || strncmp (arg, "no", length) == 0
98 || strncmp (arg, "disable", length) == 0)
99 return 0;
100 else
101 return -1;
102 }
103 \f
104 void
105 deprecated_show_value_hack (struct ui_file *ignore_file,
106 int ignore_from_tty,
107 struct cmd_list_element *c,
108 const char *value)
109 {
110 /* If there's no command or value, don't try to print it out. */
111 if (c == NULL || value == NULL)
112 return;
113 /* Print doc minus "show" at start. */
114 print_doc_line (gdb_stdout, c->doc + 5);
115 switch (c->var_type)
116 {
117 case var_string:
118 case var_string_noescape:
119 case var_optional_filename:
120 case var_filename:
121 case var_enum:
122 printf_filtered ((" is \"%s\".\n"), value);
123 break;
124 default:
125 printf_filtered ((" is %s.\n"), value);
126 break;
127 }
128 }
129
130 /* Do a "set" command. ARG is NULL if no argument, or the
131 text of the argument, and FROM_TTY is nonzero if this command is
132 being entered directly by the user (i.e. these are just like any
133 other command). C is the command list element for the command. */
134
135 void
136 do_set_command (char *arg, int from_tty, struct cmd_list_element *c)
137 {
138 /* A flag to indicate the option is changed or not. */
139 int option_changed = 0;
140
141 gdb_assert (c->type == set_cmd);
142
143 switch (c->var_type)
144 {
145 case var_string:
146 {
147 char *new;
148 char *p;
149 char *q;
150 int ch;
151
152 if (arg == NULL)
153 arg = "";
154 new = (char *) xmalloc (strlen (arg) + 2);
155 p = arg;
156 q = new;
157 while ((ch = *p++) != '\000')
158 {
159 if (ch == '\\')
160 {
161 /* \ at end of argument is used after spaces
162 so they won't be lost. */
163 /* This is obsolete now that we no longer strip
164 trailing whitespace and actually, the backslash
165 didn't get here in my test, readline or
166 something did something funky with a backslash
167 right before a newline. */
168 if (*p == 0)
169 break;
170 ch = parse_escape (get_current_arch (), &p);
171 if (ch == 0)
172 break; /* C loses */
173 else if (ch > 0)
174 *q++ = ch;
175 }
176 else
177 *q++ = ch;
178 }
179 #if 0
180 if (*(p - 1) != '\\')
181 *q++ = ' ';
182 #endif
183 *q++ = '\0';
184 new = (char *) xrealloc (new, q - new);
185
186 if (*(char **) c->var == NULL
187 || strcmp (*(char **) c->var, new) != 0)
188 {
189 xfree (*(char **) c->var);
190 *(char **) c->var = new;
191
192 option_changed = 1;
193 }
194 else
195 xfree (new);
196 }
197 break;
198 case var_string_noescape:
199 if (arg == NULL)
200 arg = "";
201
202 if (*(char **) c->var == NULL || strcmp (*(char **) c->var, arg) != 0)
203 {
204 xfree (*(char **) c->var);
205 *(char **) c->var = xstrdup (arg);
206
207 option_changed = 1;
208 }
209 break;
210 case var_filename:
211 if (arg == NULL)
212 error_no_arg (_("filename to set it to."));
213 /* FALLTHROUGH */
214 case var_optional_filename:
215 {
216 char *val = NULL;
217
218 if (arg != NULL)
219 {
220 /* Clear trailing whitespace of filename. */
221 char *ptr = arg + strlen (arg) - 1;
222
223 while (ptr >= arg && (*ptr == ' ' || *ptr == '\t'))
224 ptr--;
225 *(ptr + 1) = '\0';
226
227 val = tilde_expand (arg);
228 }
229 else
230 val = xstrdup ("");
231
232 if (*(char **) c->var == NULL
233 || strcmp (*(char **) c->var, val) != 0)
234 {
235 xfree (*(char **) c->var);
236 *(char **) c->var = val;
237
238 option_changed = 1;
239 }
240 else
241 xfree (val);
242 }
243 break;
244 case var_boolean:
245 {
246 int val = parse_cli_boolean_value (arg);
247
248 if (val < 0)
249 error (_("\"on\" or \"off\" expected."));
250 if (val != *(int *) c->var)
251 {
252 *(int *) c->var = val;
253
254 option_changed = 1;
255 }
256 }
257 break;
258 case var_auto_boolean:
259 {
260 enum auto_boolean val = parse_auto_binary_operation (arg);
261
262 if (*(enum auto_boolean *) c->var != val)
263 {
264 *(enum auto_boolean *) c->var = val;
265
266 option_changed = 1;
267 }
268 }
269 break;
270 case var_uinteger:
271 case var_zuinteger:
272 {
273 LONGEST val;
274
275 if (arg == NULL)
276 error_no_arg (_("integer to set it to."));
277 val = parse_and_eval_long (arg);
278
279 if (c->var_type == var_uinteger && val == 0)
280 val = UINT_MAX;
281 /* For var_uinteger, don't let the user set the value to
282 UINT_MAX directly, as that exposes an implementation detail
283 to the user interface. */
284 else if ((c->var_type == var_uinteger && val >= UINT_MAX)
285 || (c->var_type == var_zuinteger && val > UINT_MAX))
286 error (_("integer %s out of range"), plongest (val));
287
288 if (*(unsigned int *) c->var != val)
289 {
290 *(unsigned int *) c->var = val;
291
292 option_changed = 1;
293 }
294 }
295 break;
296 case var_integer:
297 case var_zinteger:
298 {
299 LONGEST val;
300
301 if (arg == NULL)
302 error_no_arg (_("integer to set it to."));
303 val = parse_and_eval_long (arg);
304
305 if (val == 0 && c->var_type == var_integer)
306 val = INT_MAX;
307 /* For var_integer, don't let the user set the value to
308 INT_MAX directly, as that exposes an implementation detail
309 to the user interface. */
310 else if ((c->var_type == var_integer && val >= INT_MAX)
311 || (c->var_type == var_zinteger && val > INT_MAX)
312 || val < INT_MIN)
313 error (_("integer %s out of range"), plongest (val));
314
315 if (*(int *) c->var != val)
316 {
317 *(int *) c->var = val;
318
319 option_changed = 1;
320 }
321 break;
322 }
323 case var_enum:
324 {
325 int i;
326 int len;
327 int nmatches;
328 const char *match = NULL;
329 char *p;
330
331 /* If no argument was supplied, print an informative error
332 message. */
333 if (arg == NULL)
334 {
335 char *msg;
336 int msg_len = 0;
337
338 for (i = 0; c->enums[i]; i++)
339 msg_len += strlen (c->enums[i]) + 2;
340
341 msg = xmalloc (msg_len);
342 *msg = '\0';
343 make_cleanup (xfree, msg);
344
345 for (i = 0; c->enums[i]; i++)
346 {
347 if (i != 0)
348 strcat (msg, ", ");
349 strcat (msg, c->enums[i]);
350 }
351 error (_("Requires an argument. Valid arguments are %s."),
352 msg);
353 }
354
355 p = strchr (arg, ' ');
356
357 if (p)
358 len = p - arg;
359 else
360 len = strlen (arg);
361
362 nmatches = 0;
363 for (i = 0; c->enums[i]; i++)
364 if (strncmp (arg, c->enums[i], len) == 0)
365 {
366 if (c->enums[i][len] == '\0')
367 {
368 match = c->enums[i];
369 nmatches = 1;
370 break; /* Exact match. */
371 }
372 else
373 {
374 match = c->enums[i];
375 nmatches++;
376 }
377 }
378
379 if (nmatches <= 0)
380 error (_("Undefined item: \"%s\"."), arg);
381
382 if (nmatches > 1)
383 error (_("Ambiguous item \"%s\"."), arg);
384
385 if (*(const char **) c->var != match)
386 {
387 *(const char **) c->var = match;
388
389 option_changed = 1;
390 }
391 }
392 break;
393 case var_zuinteger_unlimited:
394 {
395 LONGEST val;
396
397 if (arg == NULL)
398 error_no_arg (_("integer to set it to."));
399 val = parse_and_eval_long (arg);
400
401 if (val > INT_MAX)
402 error (_("integer %s out of range"), plongest (val));
403 else if (val < -1)
404 error (_("only -1 is allowed to set as unlimited"));
405
406 if (*(int *) c->var != val)
407 {
408 *(int *) c->var = val;
409 option_changed = 1;
410 }
411 }
412 break;
413 default:
414 error (_("gdb internal error: bad var_type in do_setshow_command"));
415 }
416 c->func (c, NULL, from_tty);
417 if (deprecated_set_hook)
418 deprecated_set_hook (c);
419
420 if (notify_command_param_changed_p (option_changed, c))
421 {
422 char *name, *cp;
423 struct cmd_list_element **cmds;
424 struct cmd_list_element *p;
425 int i;
426 int length = 0;
427
428 /* Compute the whole multi-word command options. If user types command
429 'set foo bar baz on', c->name is 'baz', and GDB can't pass "bar" to
430 command option change notification, because it is confusing. We can
431 trace back through field 'prefix' to compute the whole options,
432 and pass "foo bar baz" to notification. */
433
434 for (i = 0, p = c; p != NULL; i++)
435 {
436 length += strlen (p->name);
437 length++;
438
439 p = p->prefix;
440 }
441 cp = name = xmalloc (length);
442 cmds = xmalloc (sizeof (struct cmd_list_element *) * i);
443
444 /* Track back through filed 'prefix' and cache them in CMDS. */
445 for (i = 0, p = c; p != NULL; i++)
446 {
447 cmds[i] = p;
448 p = p->prefix;
449 }
450
451 /* Don't trigger any observer notification if prefixlist is not
452 setlist. */
453 i--;
454 if (cmds[i]->prefixlist != &setlist)
455 {
456 xfree (cmds);
457 xfree (name);
458
459 return;
460 }
461 /* Traverse them in the reversed order, and copy their names into
462 NAME. */
463 for (i--; i >= 0; i--)
464 {
465 memcpy (cp, cmds[i]->name, strlen (cmds[i]->name));
466 cp += strlen (cmds[i]->name);
467
468 if (i != 0)
469 {
470 cp[0] = ' ';
471 cp++;
472 }
473 }
474 cp[0] = 0;
475
476 xfree (cmds);
477
478 switch (c->var_type)
479 {
480 case var_string:
481 case var_string_noescape:
482 case var_filename:
483 case var_optional_filename:
484 case var_enum:
485 observer_notify_command_param_changed (name, *(char **) c->var);
486 break;
487 case var_boolean:
488 {
489 char *opt = *(int *) c->var ? "on" : "off";
490
491 observer_notify_command_param_changed (name, opt);
492 }
493 break;
494 case var_auto_boolean:
495 {
496 const char *s = auto_boolean_enums[*(enum auto_boolean *) c->var];
497
498 observer_notify_command_param_changed (name, s);
499 }
500 break;
501 case var_uinteger:
502 case var_zuinteger:
503 {
504 char s[64];
505
506 xsnprintf (s, sizeof s, "%u", *(unsigned int *) c->var);
507 observer_notify_command_param_changed (name, s);
508 }
509 break;
510 case var_integer:
511 case var_zinteger:
512 case var_zuinteger_unlimited:
513 {
514 char s[64];
515
516 xsnprintf (s, sizeof s, "%d", *(int *) c->var);
517 observer_notify_command_param_changed (name, s);
518 }
519 break;
520 }
521 xfree (name);
522 }
523 }
524
525 /* Do a "show" command. ARG is NULL if no argument, or the
526 text of the argument, and FROM_TTY is nonzero if this command is
527 being entered directly by the user (i.e. these are just like any
528 other command). C is the command list element for the command. */
529
530 void
531 do_show_command (char *arg, int from_tty, struct cmd_list_element *c)
532 {
533 struct ui_out *uiout = current_uiout;
534 struct cleanup *old_chain;
535 struct ui_file *stb;
536
537 gdb_assert (c->type == show_cmd);
538
539 stb = mem_fileopen ();
540 old_chain = make_cleanup_ui_file_delete (stb);
541
542 /* Possibly call the pre hook. */
543 if (c->pre_show_hook)
544 (c->pre_show_hook) (c);
545
546 switch (c->var_type)
547 {
548 case var_string:
549 if (*(char **) c->var)
550 fputstr_filtered (*(char **) c->var, '"', stb);
551 break;
552 case var_string_noescape:
553 case var_optional_filename:
554 case var_filename:
555 case var_enum:
556 if (*(char **) c->var)
557 fputs_filtered (*(char **) c->var, stb);
558 break;
559 case var_boolean:
560 fputs_filtered (*(int *) c->var ? "on" : "off", stb);
561 break;
562 case var_auto_boolean:
563 switch (*(enum auto_boolean*) c->var)
564 {
565 case AUTO_BOOLEAN_TRUE:
566 fputs_filtered ("on", stb);
567 break;
568 case AUTO_BOOLEAN_FALSE:
569 fputs_filtered ("off", stb);
570 break;
571 case AUTO_BOOLEAN_AUTO:
572 fputs_filtered ("auto", stb);
573 break;
574 default:
575 internal_error (__FILE__, __LINE__,
576 _("do_show_command: "
577 "invalid var_auto_boolean"));
578 break;
579 }
580 break;
581 case var_uinteger:
582 case var_zuinteger:
583 if (c->var_type == var_uinteger
584 && *(unsigned int *) c->var == UINT_MAX)
585 fputs_filtered ("unlimited", stb);
586 else
587 fprintf_filtered (stb, "%u", *(unsigned int *) c->var);
588 break;
589 case var_integer:
590 case var_zinteger:
591 if (c->var_type == var_integer
592 && *(int *) c->var == INT_MAX)
593 fputs_filtered ("unlimited", stb);
594 else
595 fprintf_filtered (stb, "%d", *(int *) c->var);
596 break;
597 case var_zuinteger_unlimited:
598 {
599 if (*(int *) c->var == -1)
600 fputs_filtered ("unlimited", stb);
601 else
602 fprintf_filtered (stb, "%d", *(int *) c->var);
603 }
604 break;
605 default:
606 error (_("gdb internal error: bad var_type in do_show_command"));
607 }
608
609
610 /* FIXME: cagney/2005-02-10: Need to split this in half: code to
611 convert the value into a string (esentially the above); and
612 code to print the value out. For the latter there should be
613 MI and CLI specific versions. */
614
615 if (ui_out_is_mi_like_p (uiout))
616 ui_out_field_stream (uiout, "value", stb);
617 else
618 {
619 char *value = ui_file_xstrdup (stb, NULL);
620
621 make_cleanup (xfree, value);
622 if (c->show_value_func != NULL)
623 c->show_value_func (gdb_stdout, from_tty, c, value);
624 else
625 deprecated_show_value_hack (gdb_stdout, from_tty, c, value);
626 }
627 do_cleanups (old_chain);
628
629 c->func (c, NULL, from_tty);
630 }
631
632 /* Show all the settings in a list of show commands. */
633
634 void
635 cmd_show_list (struct cmd_list_element *list, int from_tty, char *prefix)
636 {
637 struct cleanup *showlist_chain;
638 struct ui_out *uiout = current_uiout;
639
640 showlist_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "showlist");
641 for (; list != NULL; list = list->next)
642 {
643 /* If we find a prefix, run its list, prefixing our output by its
644 prefix (with "show " skipped). */
645 if (list->prefixlist && !list->abbrev_flag)
646 {
647 struct cleanup *optionlist_chain
648 = make_cleanup_ui_out_tuple_begin_end (uiout, "optionlist");
649 char *new_prefix = strstr (list->prefixname, "show ") + 5;
650
651 if (ui_out_is_mi_like_p (uiout))
652 ui_out_field_string (uiout, "prefix", new_prefix);
653 cmd_show_list (*list->prefixlist, from_tty, new_prefix);
654 /* Close the tuple. */
655 do_cleanups (optionlist_chain);
656 }
657 else
658 {
659 if (list->class != no_set_class)
660 {
661 struct cleanup *option_chain
662 = make_cleanup_ui_out_tuple_begin_end (uiout, "option");
663
664 ui_out_text (uiout, prefix);
665 ui_out_field_string (uiout, "name", list->name);
666 ui_out_text (uiout, ": ");
667 if (list->type == show_cmd)
668 do_show_command ((char *) NULL, from_tty, list);
669 else
670 cmd_func (list, NULL, from_tty);
671 /* Close the tuple. */
672 do_cleanups (option_chain);
673 }
674 }
675 }
676 /* Close the tuple. */
677 do_cleanups (showlist_chain);
678 }
679