http://sourceware.org/ml/gdb-patches/2011-07/msg00085.html
[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   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
253                message.  */
254             if (arg == NULL)
255               {
256                 char *msg;
257                 int msg_len = 0;
258
259                 for (i = 0; c->enums[i]; i++)
260                   msg_len += strlen (c->enums[i]) + 2;
261
262                 msg = xmalloc (msg_len);
263                 *msg = '\0';
264                 make_cleanup (xfree, msg);
265                 
266                 for (i = 0; c->enums[i]; i++)
267                   {
268                     if (i != 0)
269                       strcat (msg, ", ");
270                     strcat (msg, c->enums[i]);
271                   }
272                 error (_("Requires an argument. Valid arguments are %s."), 
273                        msg);
274               }
275
276             p = strchr (arg, ' ');
277
278             if (p)
279               len = p - arg;
280             else
281               len = strlen (arg);
282
283             nmatches = 0;
284             for (i = 0; c->enums[i]; i++)
285               if (strncmp (arg, c->enums[i], len) == 0)
286                 {
287                   if (c->enums[i][len] == '\0')
288                     {
289                       match = c->enums[i];
290                       nmatches = 1;
291                       break; /* Exact match.  */
292                     }
293                   else
294                     {
295                       match = c->enums[i];
296                       nmatches++;
297                     }
298                 }
299
300             if (nmatches <= 0)
301               error (_("Undefined item: \"%s\"."), arg);
302
303             if (nmatches > 1)
304               error (_("Ambiguous item \"%s\"."), arg);
305
306             *(const char **) c->var = match;
307           }
308           break;
309         default:
310           error (_("gdb internal error: bad var_type in do_setshow_command"));
311         }
312     }
313   else if (c->type == show_cmd)
314     {
315       struct cleanup *old_chain;
316       struct ui_stream *stb;
317
318       stb = ui_out_stream_new (uiout);
319       old_chain = make_cleanup_ui_out_stream_delete (stb);
320
321       /* Possibly call the pre hook.  */
322       if (c->pre_show_hook)
323         (c->pre_show_hook) (c);
324
325       switch (c->var_type)
326         {
327         case var_string:
328           if (*(char **) c->var)
329             fputstr_filtered (*(char **) c->var, '"', stb->stream);
330           break;
331         case var_string_noescape:
332         case var_optional_filename:
333         case var_filename:
334         case var_enum:
335           if (*(char **) c->var)
336             fputs_filtered (*(char **) c->var, stb->stream);
337           break;
338         case var_boolean:
339           fputs_filtered (*(int *) c->var ? "on" : "off", stb->stream);
340           break;
341         case var_auto_boolean:
342           switch (*(enum auto_boolean*) c->var)
343             {
344             case AUTO_BOOLEAN_TRUE:
345               fputs_filtered ("on", stb->stream);
346               break;
347             case AUTO_BOOLEAN_FALSE:
348               fputs_filtered ("off", stb->stream);
349               break;
350             case AUTO_BOOLEAN_AUTO:
351               fputs_filtered ("auto", stb->stream);
352               break;
353             default:
354               internal_error (__FILE__, __LINE__,
355                               _("do_setshow_command: "
356                                 "invalid var_auto_boolean"));
357               break;
358             }
359           break;
360         case var_uinteger:
361         case var_zuinteger:
362           if (c->var_type == var_uinteger
363               && *(unsigned int *) c->var == UINT_MAX)
364             fputs_filtered ("unlimited", stb->stream);
365           else
366             fprintf_filtered (stb->stream, "%u", *(unsigned int *) c->var);
367           break;
368         case var_integer:
369         case var_zinteger:
370           if (c->var_type == var_integer
371               && *(int *) c->var == INT_MAX)
372             fputs_filtered ("unlimited", stb->stream);
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           if (list->class != no_set_class)
435             {
436               struct cleanup *option_chain
437                 = make_cleanup_ui_out_tuple_begin_end (uiout, "option");
438
439               ui_out_text (uiout, prefix);
440               ui_out_field_string (uiout, "name", list->name);
441               ui_out_text (uiout, ":  ");
442               if (list->type == show_cmd)
443                 do_setshow_command ((char *) NULL, from_tty, list);
444               else
445                 cmd_func (list, NULL, from_tty);
446               /* Close the tuple.  */
447               do_cleanups (option_chain);
448             }
449         }
450     }
451   /* Close the tuple.  */
452   do_cleanups (showlist_chain);
453 }
454