2010-05-17 Michael Snyder <msnyder@vmware.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
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 text
121    of the argument, and FROM_TTY is nonzero if this command is being entered
122    directly by the user (i.e. these are just like any other
123    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   if (c->type == set_cmd)
129     {
130       switch (c->var_type)
131         {
132         case var_string:
133           {
134             char *new;
135             char *p;
136             char *q;
137             int ch;
138
139             if (arg == NULL)
140               arg = "";
141             new = (char *) xmalloc (strlen (arg) + 2);
142             p = arg;
143             q = new;
144             while ((ch = *p++) != '\000')
145               {
146                 if (ch == '\\')
147                   {
148                     /* \ at end of argument is used after spaces
149                        so they won't be lost.  */
150                     /* This is obsolete now that we no longer strip
151                        trailing whitespace and actually, the backslash
152                        didn't get here in my test, readline or
153                        something did something funky with a backslash
154                        right before a newline.  */
155                     if (*p == 0)
156                       break;
157                     ch = parse_escape (get_current_arch (), &p);
158                     if (ch == 0)
159                       break;    /* C loses */
160                     else if (ch > 0)
161                       *q++ = ch;
162                   }
163                 else
164                   *q++ = ch;
165               }
166 #if 0
167             if (*(p - 1) != '\\')
168               *q++ = ' ';
169 #endif
170             *q++ = '\0';
171             new = (char *) xrealloc (new, q - new);
172             if (*(char **) c->var != NULL)
173               xfree (*(char **) c->var);
174             *(char **) c->var = new;
175           }
176           break;
177         case var_string_noescape:
178           if (arg == NULL)
179             arg = "";
180           if (*(char **) c->var != NULL)
181             xfree (*(char **) c->var);
182           *(char **) c->var = xstrdup (arg);
183           break;
184         case var_optional_filename:
185           if (arg == NULL)
186             arg = "";
187           if (*(char **) c->var != NULL)
188             xfree (*(char **) c->var);
189           *(char **) c->var = xstrdup (arg);
190           break;
191         case var_filename:
192           if (arg == NULL)
193             error_no_arg (_("filename to set it to."));
194           if (*(char **) c->var != NULL)
195             xfree (*(char **) c->var);
196           {
197             /* Clear trailing whitespace of filename.  */
198             char *ptr = arg + strlen (arg) - 1;
199
200             while (ptr >= arg && (*ptr == ' ' || *ptr == '\t'))
201               ptr--;
202             *(ptr + 1) = '\0';
203           }
204           *(char **) c->var = tilde_expand (arg);
205           break;
206         case var_boolean:
207           *(int *) c->var = parse_binary_operation (arg);
208           break;
209         case var_auto_boolean:
210           *(enum auto_boolean *) c->var = parse_auto_binary_operation (arg);
211           break;
212         case var_uinteger:
213           if (arg == NULL)
214             error_no_arg (_("integer to set it to."));
215           *(unsigned int *) c->var = parse_and_eval_long (arg);
216           if (*(unsigned int *) c->var == 0)
217             *(unsigned int *) c->var = UINT_MAX;
218           break;
219         case var_integer:
220           {
221             unsigned int val;
222
223             if (arg == NULL)
224               error_no_arg (_("integer to set it to."));
225             val = parse_and_eval_long (arg);
226             if (val == 0)
227               *(int *) c->var = INT_MAX;
228             else if (val >= INT_MAX)
229               error (_("integer %u out of range"), val);
230             else
231               *(int *) c->var = val;
232             break;
233           }
234         case var_zinteger:
235           if (arg == NULL)
236             error_no_arg (_("integer to set it to."));
237           *(int *) c->var = parse_and_eval_long (arg);
238           break;
239         case var_zuinteger:
240           if (arg == NULL)
241             error_no_arg (_("integer to set it to."));
242           *(unsigned int *) c->var = parse_and_eval_long (arg);
243           break;
244         case var_enum:
245           {
246             int i;
247             int len;
248             int nmatches;
249             const char *match = NULL;
250             char *p;
251
252             /* if no argument was supplied, print an informative error message */
253             if (arg == NULL)
254               {
255                 char *msg;
256                 int msg_len = 0;
257
258                 for (i = 0; c->enums[i]; i++)
259                   msg_len += strlen (c->enums[i]) + 2;
260
261                 msg = xmalloc (msg_len);
262                 *msg = '\0';
263                 make_cleanup (xfree, msg);
264                 
265                 for (i = 0; c->enums[i]; i++)
266                   {
267                     if (i != 0)
268                       strcat (msg, ", ");
269                     strcat (msg, c->enums[i]);
270                   }
271                 error (_("Requires an argument. Valid arguments are %s."), msg);
272               }
273
274             p = strchr (arg, ' ');
275
276             if (p)
277               len = p - arg;
278             else
279               len = strlen (arg);
280
281             nmatches = 0;
282             for (i = 0; c->enums[i]; i++)
283               if (strncmp (arg, c->enums[i], len) == 0)
284                 {
285                   if (c->enums[i][len] == '\0')
286                     {
287                       match = c->enums[i];
288                       nmatches = 1;
289                       break; /* exact match. */
290                     }
291                   else
292                     {
293                       match = c->enums[i];
294                       nmatches++;
295                     }
296                 }
297
298             if (nmatches <= 0)
299               error (_("Undefined item: \"%s\"."), arg);
300
301             if (nmatches > 1)
302               error (_("Ambiguous item \"%s\"."), arg);
303
304             *(const char **) c->var = match;
305           }
306           break;
307         default:
308           error (_("gdb internal error: bad var_type in do_setshow_command"));
309         }
310     }
311   else if (c->type == show_cmd)
312     {
313       struct cleanup *old_chain;
314       struct ui_stream *stb;
315
316       stb = ui_out_stream_new (uiout);
317       old_chain = make_cleanup_ui_out_stream_delete (stb);
318
319       /* Possibly call the pre hook.  */
320       if (c->pre_show_hook)
321         (c->pre_show_hook) (c);
322
323       switch (c->var_type)
324         {
325         case var_string:
326           if (*(char **) c->var)
327             fputstr_filtered (*(char **) c->var, '"', stb->stream);
328           break;
329         case var_string_noescape:
330         case var_optional_filename:
331         case var_filename:
332         case var_enum:
333           if (*(char **) c->var)
334             fputs_filtered (*(char **) c->var, stb->stream);
335           break;
336         case var_boolean:
337           fputs_filtered (*(int *) c->var ? "on" : "off", stb->stream);
338           break;
339         case var_auto_boolean:
340           switch (*(enum auto_boolean*) c->var)
341             {
342             case AUTO_BOOLEAN_TRUE:
343               fputs_filtered ("on", stb->stream);
344               break;
345             case AUTO_BOOLEAN_FALSE:
346               fputs_filtered ("off", stb->stream);
347               break;
348             case AUTO_BOOLEAN_AUTO:
349               fputs_filtered ("auto", stb->stream);
350               break;
351             default:
352               internal_error (__FILE__, __LINE__,
353                               _("do_setshow_command: invalid var_auto_boolean"));
354               break;
355             }
356           break;
357         case var_uinteger:
358           if (*(unsigned int *) c->var == UINT_MAX)
359             {
360               fputs_filtered ("unlimited", stb->stream);
361               break;
362             }
363           /* else fall through */
364         case var_zuinteger:
365         case var_zinteger:
366           fprintf_filtered (stb->stream, "%u", *(unsigned int *) c->var);
367           break;
368         case var_integer:
369           if (*(int *) c->var == INT_MAX)
370             {
371               fputs_filtered ("unlimited", stb->stream);
372             }
373           else
374             fprintf_filtered (stb->stream, "%d", *(int *) c->var);
375           break;
376
377         default:
378           error (_("gdb internal error: bad var_type in do_setshow_command"));
379         }
380
381
382       /* FIXME: cagney/2005-02-10: Need to split this in half: code to
383          convert the value into a string (esentially the above); and
384          code to print the value out.  For the latter there should be
385          MI and CLI specific versions.  */
386
387       if (ui_out_is_mi_like_p (uiout))
388         ui_out_field_stream (uiout, "value", stb);
389       else
390         {
391           char *value = ui_file_xstrdup (stb->stream, NULL);
392
393           make_cleanup (xfree, value);
394           if (c->show_value_func != NULL)
395             c->show_value_func (gdb_stdout, from_tty, c, value);
396           else
397             deprecated_show_value_hack (gdb_stdout, from_tty, c, value);
398         }
399       do_cleanups (old_chain);
400     }
401   else
402     error (_("gdb internal error: bad cmd_type in do_setshow_command"));
403   c->func (c, NULL, from_tty);
404   if (c->type == set_cmd && deprecated_set_hook)
405     deprecated_set_hook (c);
406 }
407
408 /* Show all the settings in a list of show commands.  */
409
410 void
411 cmd_show_list (struct cmd_list_element *list, int from_tty, char *prefix)
412 {
413   struct cleanup *showlist_chain;
414
415   showlist_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "showlist");
416   for (; list != NULL; list = list->next)
417     {
418       /* If we find a prefix, run its list, prefixing our output by its
419          prefix (with "show " skipped).  */
420       if (list->prefixlist && !list->abbrev_flag)
421         {
422           struct cleanup *optionlist_chain
423             = make_cleanup_ui_out_tuple_begin_end (uiout, "optionlist");
424           char *new_prefix = strstr (list->prefixname, "show ") + 5;
425
426           if (ui_out_is_mi_like_p (uiout))
427             ui_out_field_string (uiout, "prefix", new_prefix);
428           cmd_show_list (*list->prefixlist, from_tty, new_prefix);
429           /* Close the tuple.  */
430           do_cleanups (optionlist_chain);
431         }
432       else
433         {
434           struct cleanup *option_chain
435             = make_cleanup_ui_out_tuple_begin_end (uiout, "option");
436
437           ui_out_text (uiout, prefix);
438           ui_out_field_string (uiout, "name", list->name);
439           ui_out_text (uiout, ":  ");
440           if (list->type == show_cmd)
441             do_setshow_command ((char *) NULL, from_tty, list);
442           else
443             cmd_func (list, NULL, from_tty);
444           /* Close the tuple.  */
445           do_cleanups (option_chain);
446         }
447     }
448   /* Close the tuple.  */
449   do_cleanups (showlist_chain);
450 }
451