2012-03-27 Pedro Alves <palves@redhat.com>
[external/binutils.git] / gdb / cli / cli-setshow.c
1 /* Handle set and show GDB commands.
2
3    Copyright (c) 2000-2003, 2007-2012 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
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
31 /* Prototypes for local functions.  */
32
33 static int parse_binary_operation (char *);
34
35 \f
36 static enum auto_boolean
37 parse_auto_binary_operation (const char *arg)
38 {
39   if (arg != NULL && *arg != '\0')
40     {
41       int length = strlen (arg);
42
43       while (isspace (arg[length - 1]) && length > 0)
44         length--;
45       if (strncmp (arg, "on", length) == 0
46           || strncmp (arg, "1", length) == 0
47           || strncmp (arg, "yes", length) == 0
48           || strncmp (arg, "enable", length) == 0)
49         return AUTO_BOOLEAN_TRUE;
50       else if (strncmp (arg, "off", length) == 0
51                || strncmp (arg, "0", length) == 0
52                || strncmp (arg, "no", length) == 0
53                || strncmp (arg, "disable", length) == 0)
54         return AUTO_BOOLEAN_FALSE;
55       else if (strncmp (arg, "auto", length) == 0
56                || (strncmp (arg, "-1", length) == 0 && length > 1))
57         return AUTO_BOOLEAN_AUTO;
58     }
59   error (_("\"on\", \"off\" or \"auto\" expected."));
60   return AUTO_BOOLEAN_AUTO; /* Pacify GCC.  */
61 }
62
63 static int
64 parse_binary_operation (char *arg)
65 {
66   int length;
67
68   if (!arg || !*arg)
69     return 1;
70
71   length = strlen (arg);
72
73   while (arg[length - 1] == ' ' || arg[length - 1] == '\t')
74     length--;
75
76   if (strncmp (arg, "on", length) == 0
77       || strncmp (arg, "1", length) == 0
78       || strncmp (arg, "yes", length) == 0
79       || strncmp (arg, "enable", length) == 0)
80     return 1;
81   else if (strncmp (arg, "off", length) == 0
82            || strncmp (arg, "0", length) == 0
83            || strncmp (arg, "no", length) == 0
84            || strncmp (arg, "disable", length) == 0)
85     return 0;
86   else
87     {
88       error (_("\"on\" or \"off\" expected."));
89       return 0;
90     }
91 }
92 \f
93 void
94 deprecated_show_value_hack (struct ui_file *ignore_file,
95                             int ignore_from_tty,
96                             struct cmd_list_element *c,
97                             const char *value)
98 {
99   /* If there's no command or value, don't try to print it out.  */
100   if (c == NULL || value == NULL)
101     return;
102   /* Print doc minus "show" at start.  */
103   print_doc_line (gdb_stdout, c->doc + 5);
104   switch (c->var_type)
105     {
106     case var_string:
107     case var_string_noescape:
108     case var_optional_filename:
109     case var_filename:
110     case var_enum:
111       printf_filtered ((" is \"%s\".\n"), value);
112       break;
113     default:
114       printf_filtered ((" is %s.\n"), value);
115       break;
116     }
117 }
118
119 /* Do a "set" or "show" command.  ARG is NULL if no argument, or the
120    text of the argument, and FROM_TTY is nonzero if this command is
121    being entered directly by the user (i.e. these are just like any
122    other command).  C is the command list element for the command.  */
123
124 void
125 do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c)
126 {
127   struct ui_out *uiout = current_uiout;
128
129   if (c->type == set_cmd)
130     {
131       switch (c->var_type)
132         {
133         case var_string:
134           {
135             char *new;
136             char *p;
137             char *q;
138             int ch;
139
140             if (arg == NULL)
141               arg = "";
142             new = (char *) xmalloc (strlen (arg) + 2);
143             p = arg;
144             q = new;
145             while ((ch = *p++) != '\000')
146               {
147                 if (ch == '\\')
148                   {
149                     /* \ at end of argument is used after spaces
150                        so they won't be lost.  */
151                     /* This is obsolete now that we no longer strip
152                        trailing whitespace and actually, the backslash
153                        didn't get here in my test, readline or
154                        something did something funky with a backslash
155                        right before a newline.  */
156                     if (*p == 0)
157                       break;
158                     ch = parse_escape (get_current_arch (), &p);
159                     if (ch == 0)
160                       break;    /* C loses */
161                     else if (ch > 0)
162                       *q++ = ch;
163                   }
164                 else
165                   *q++ = ch;
166               }
167 #if 0
168             if (*(p - 1) != '\\')
169               *q++ = ' ';
170 #endif
171             *q++ = '\0';
172             new = (char *) xrealloc (new, q - new);
173             if (*(char **) c->var != NULL)
174               xfree (*(char **) c->var);
175             *(char **) c->var = new;
176           }
177           break;
178         case var_string_noescape:
179           if (arg == NULL)
180             arg = "";
181           if (*(char **) c->var != NULL)
182             xfree (*(char **) c->var);
183           *(char **) c->var = xstrdup (arg);
184           break;
185         case var_optional_filename:
186           if (arg == NULL)
187             arg = "";
188           if (*(char **) c->var != NULL)
189             xfree (*(char **) c->var);
190           *(char **) c->var = xstrdup (arg);
191           break;
192         case var_filename:
193           if (arg == NULL)
194             error_no_arg (_("filename to set it to."));
195           if (*(char **) c->var != NULL)
196             xfree (*(char **) c->var);
197           {
198             /* Clear trailing whitespace of filename.  */
199             char *ptr = arg + strlen (arg) - 1;
200
201             while (ptr >= arg && (*ptr == ' ' || *ptr == '\t'))
202               ptr--;
203             *(ptr + 1) = '\0';
204           }
205           *(char **) c->var = tilde_expand (arg);
206           break;
207         case var_boolean:
208           *(int *) c->var = parse_binary_operation (arg);
209           break;
210         case var_auto_boolean:
211           *(enum auto_boolean *) c->var = parse_auto_binary_operation (arg);
212           break;
213         case var_uinteger:
214           if (arg == NULL)
215             error_no_arg (_("integer to set it to."));
216           *(unsigned int *) c->var = parse_and_eval_long (arg);
217           if (*(unsigned int *) c->var == 0)
218             *(unsigned int *) c->var = UINT_MAX;
219           break;
220         case var_integer:
221           {
222             unsigned int val;
223
224             if (arg == NULL)
225               error_no_arg (_("integer to set it to."));
226             val = parse_and_eval_long (arg);
227             if (val == 0)
228               *(int *) c->var = INT_MAX;
229             else if (val >= INT_MAX)
230               error (_("integer %u out of range"), val);
231             else
232               *(int *) c->var = val;
233             break;
234           }
235         case var_zinteger:
236           if (arg == NULL)
237             error_no_arg (_("integer to set it to."));
238           *(int *) c->var = parse_and_eval_long (arg);
239           break;
240         case var_zuinteger:
241           if (arg == NULL)
242             error_no_arg (_("integer to set it to."));
243           *(unsigned int *) c->var = parse_and_eval_long (arg);
244           break;
245         case var_enum:
246           {
247             int i;
248             int len;
249             int nmatches;
250             const char *match = NULL;
251             char *p;
252
253             /* If no argument was supplied, print an informative error
254                message.  */
255             if (arg == NULL)
256               {
257                 char *msg;
258                 int msg_len = 0;
259
260                 for (i = 0; c->enums[i]; i++)
261                   msg_len += strlen (c->enums[i]) + 2;
262
263                 msg = xmalloc (msg_len);
264                 *msg = '\0';
265                 make_cleanup (xfree, msg);
266                 
267                 for (i = 0; c->enums[i]; i++)
268                   {
269                     if (i != 0)
270                       strcat (msg, ", ");
271                     strcat (msg, c->enums[i]);
272                   }
273                 error (_("Requires an argument. Valid arguments are %s."), 
274                        msg);
275               }
276
277             p = strchr (arg, ' ');
278
279             if (p)
280               len = p - arg;
281             else
282               len = strlen (arg);
283
284             nmatches = 0;
285             for (i = 0; c->enums[i]; i++)
286               if (strncmp (arg, c->enums[i], len) == 0)
287                 {
288                   if (c->enums[i][len] == '\0')
289                     {
290                       match = c->enums[i];
291                       nmatches = 1;
292                       break; /* Exact match.  */
293                     }
294                   else
295                     {
296                       match = c->enums[i];
297                       nmatches++;
298                     }
299                 }
300
301             if (nmatches <= 0)
302               error (_("Undefined item: \"%s\"."), arg);
303
304             if (nmatches > 1)
305               error (_("Ambiguous item \"%s\"."), arg);
306
307             *(const char **) c->var = match;
308           }
309           break;
310         default:
311           error (_("gdb internal error: bad var_type in do_setshow_command"));
312         }
313     }
314   else if (c->type == show_cmd)
315     {
316       struct cleanup *old_chain;
317       struct ui_file *stb;
318
319       stb = mem_fileopen ();
320       old_chain = make_cleanup_ui_file_delete (stb);
321
322       /* Possibly call the pre hook.  */
323       if (c->pre_show_hook)
324         (c->pre_show_hook) (c);
325
326       switch (c->var_type)
327         {
328         case var_string:
329           if (*(char **) c->var)
330             fputstr_filtered (*(char **) c->var, '"', stb);
331           break;
332         case var_string_noescape:
333         case var_optional_filename:
334         case var_filename:
335         case var_enum:
336           if (*(char **) c->var)
337             fputs_filtered (*(char **) c->var, stb);
338           break;
339         case var_boolean:
340           fputs_filtered (*(int *) c->var ? "on" : "off", stb);
341           break;
342         case var_auto_boolean:
343           switch (*(enum auto_boolean*) c->var)
344             {
345             case AUTO_BOOLEAN_TRUE:
346               fputs_filtered ("on", stb);
347               break;
348             case AUTO_BOOLEAN_FALSE:
349               fputs_filtered ("off", stb);
350               break;
351             case AUTO_BOOLEAN_AUTO:
352               fputs_filtered ("auto", stb);
353               break;
354             default:
355               internal_error (__FILE__, __LINE__,
356                               _("do_setshow_command: "
357                                 "invalid var_auto_boolean"));
358               break;
359             }
360           break;
361         case var_uinteger:
362         case var_zuinteger:
363           if (c->var_type == var_uinteger
364               && *(unsigned int *) c->var == UINT_MAX)
365             fputs_filtered ("unlimited", stb);
366           else
367             fprintf_filtered (stb, "%u", *(unsigned int *) c->var);
368           break;
369         case var_integer:
370         case var_zinteger:
371           if (c->var_type == var_integer
372               && *(int *) c->var == INT_MAX)
373             fputs_filtered ("unlimited", stb);
374           else
375             fprintf_filtered (stb, "%d", *(int *) c->var);
376           break;
377
378         default:
379           error (_("gdb internal error: bad var_type in do_setshow_command"));
380         }
381
382
383       /* FIXME: cagney/2005-02-10: Need to split this in half: code to
384          convert the value into a string (esentially the above); and
385          code to print the value out.  For the latter there should be
386          MI and CLI specific versions.  */
387
388       if (ui_out_is_mi_like_p (uiout))
389         ui_out_field_stream (uiout, "value", stb);
390       else
391         {
392           char *value = ui_file_xstrdup (stb, NULL);
393
394           make_cleanup (xfree, value);
395           if (c->show_value_func != NULL)
396             c->show_value_func (gdb_stdout, from_tty, c, value);
397           else
398             deprecated_show_value_hack (gdb_stdout, from_tty, c, value);
399         }
400       do_cleanups (old_chain);
401     }
402   else
403     error (_("gdb internal error: bad cmd_type in do_setshow_command"));
404   c->func (c, NULL, from_tty);
405   if (c->type == set_cmd && deprecated_set_hook)
406     deprecated_set_hook (c);
407 }
408
409 /* Show all the settings in a list of show commands.  */
410
411 void
412 cmd_show_list (struct cmd_list_element *list, int from_tty, char *prefix)
413 {
414   struct cleanup *showlist_chain;
415   struct ui_out *uiout = current_uiout;
416
417   showlist_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "showlist");
418   for (; list != NULL; list = list->next)
419     {
420       /* If we find a prefix, run its list, prefixing our output by its
421          prefix (with "show " skipped).  */
422       if (list->prefixlist && !list->abbrev_flag)
423         {
424           struct cleanup *optionlist_chain
425             = make_cleanup_ui_out_tuple_begin_end (uiout, "optionlist");
426           char *new_prefix = strstr (list->prefixname, "show ") + 5;
427
428           if (ui_out_is_mi_like_p (uiout))
429             ui_out_field_string (uiout, "prefix", new_prefix);
430           cmd_show_list (*list->prefixlist, from_tty, new_prefix);
431           /* Close the tuple.  */
432           do_cleanups (optionlist_chain);
433         }
434       else
435         {
436           if (list->class != no_set_class)
437             {
438               struct cleanup *option_chain
439                 = make_cleanup_ui_out_tuple_begin_end (uiout, "option");
440
441               ui_out_text (uiout, prefix);
442               ui_out_field_string (uiout, "name", list->name);
443               ui_out_text (uiout, ":  ");
444               if (list->type == show_cmd)
445                 do_setshow_command ((char *) NULL, from_tty, list);
446               else
447                 cmd_func (list, NULL, from_tty);
448               /* Close the tuple.  */
449               do_cleanups (option_chain);
450             }
451         }
452     }
453   /* Close the tuple.  */
454   do_cleanups (showlist_chain);
455 }
456