Subject: Fix range validation of integer commands with "unlimited".
[external/binutils.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