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