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