2005-02-10 Andrew Cagney <cagney@gnu.org>
[external/binutils.git] / gdb / cli / cli-setshow.c
1 /* Handle set and show GDB commands.
2
3    Copyright 2000, 2001, 2002, 2003 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 2 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, write to the Free Software
17    Foundation, Inc., 59 Temple Place - Suite 330,
18    Boston, MA 02111-1307, USA.  */
19
20 #include "defs.h"
21 #include "readline/tilde.h"
22 #include "value.h"
23 #include <ctype.h>
24 #include "gdb_string.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       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 /* Do a "set" or "show" command.  ARG is NULL if no argument, or the text
94    of the argument, and FROM_TTY is nonzero if this command is being entered
95    directly by the user (i.e. these are just like any other
96    command).  C is the command list element for the command.  */
97
98 void
99 do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c)
100 {
101   if (c->type == set_cmd)
102     {
103       switch (c->var_type)
104         {
105         case var_string:
106           {
107             char *new;
108             char *p;
109             char *q;
110             int ch;
111
112             if (arg == NULL)
113               arg = "";
114             new = (char *) xmalloc (strlen (arg) + 2);
115             p = arg;
116             q = new;
117             while ((ch = *p++) != '\000')
118               {
119                 if (ch == '\\')
120                   {
121                     /* \ at end of argument is used after spaces
122                        so they won't be lost.  */
123                     /* This is obsolete now that we no longer strip
124                        trailing whitespace and actually, the backslash
125                        didn't get here in my test, readline or
126                        something did something funky with a backslash
127                        right before a newline.  */
128                     if (*p == 0)
129                       break;
130                     ch = parse_escape (&p);
131                     if (ch == 0)
132                       break;    /* C loses */
133                     else if (ch > 0)
134                       *q++ = ch;
135                   }
136                 else
137                   *q++ = ch;
138               }
139 #if 0
140             if (*(p - 1) != '\\')
141               *q++ = ' ';
142 #endif
143             *q++ = '\0';
144             new = (char *) xrealloc (new, q - new);
145             if (*(char **) c->var != NULL)
146               xfree (*(char **) c->var);
147             *(char **) c->var = new;
148           }
149           break;
150         case var_string_noescape:
151           if (arg == NULL)
152             arg = "";
153           if (*(char **) c->var != NULL)
154             xfree (*(char **) c->var);
155           *(char **) c->var = savestring (arg, strlen (arg));
156           break;
157         case var_filename:
158           if (arg == NULL)
159             error_no_arg ("filename to set it to.");
160           if (*(char **) c->var != NULL)
161             xfree (*(char **) c->var);
162           *(char **) c->var = tilde_expand (arg);
163           break;
164         case var_boolean:
165           *(int *) c->var = parse_binary_operation (arg);
166           break;
167         case var_auto_boolean:
168           *(enum auto_boolean *) c->var = parse_auto_binary_operation (arg);
169           break;
170         case var_uinteger:
171           if (arg == NULL)
172             error_no_arg ("integer to set it to.");
173           *(unsigned int *) c->var = parse_and_eval_long (arg);
174           if (*(unsigned int *) c->var == 0)
175             *(unsigned int *) c->var = UINT_MAX;
176           break;
177         case var_integer:
178           {
179             unsigned int val;
180             if (arg == NULL)
181               error_no_arg ("integer to set it to.");
182             val = parse_and_eval_long (arg);
183             if (val == 0)
184               *(int *) c->var = INT_MAX;
185             else if (val >= INT_MAX)
186               error (_("integer %u out of range"), val);
187             else
188               *(int *) c->var = val;
189             break;
190           }
191         case var_zinteger:
192           if (arg == NULL)
193             error_no_arg ("integer to set it to.");
194           *(int *) c->var = parse_and_eval_long (arg);
195           break;
196         case var_enum:
197           {
198             int i;
199             int len;
200             int nmatches;
201             const char *match = NULL;
202             char *p;
203
204             /* if no argument was supplied, print an informative error message */
205             if (arg == NULL)
206               {
207                 char msg[1024];
208                 strcpy (msg, "Requires an argument. Valid arguments are ");
209                 for (i = 0; c->enums[i]; i++)
210                   {
211                     if (i != 0)
212                       strcat (msg, ", ");
213                     strcat (msg, c->enums[i]);
214                   }
215                 strcat (msg, ".");
216                 error (("%s"), msg);
217               }
218
219             p = strchr (arg, ' ');
220
221             if (p)
222               len = p - arg;
223             else
224               len = strlen (arg);
225
226             nmatches = 0;
227             for (i = 0; c->enums[i]; i++)
228               if (strncmp (arg, c->enums[i], len) == 0)
229                 {
230                   if (c->enums[i][len] == '\0')
231                     {
232                       match = c->enums[i];
233                       nmatches = 1;
234                       break; /* exact match. */
235                     }
236                   else
237                     {
238                       match = c->enums[i];
239                       nmatches++;
240                     }
241                 }
242
243             if (nmatches <= 0)
244               error (_("Undefined item: \"%s\"."), arg);
245
246             if (nmatches > 1)
247               error (_("Ambiguous item \"%s\"."), arg);
248
249             *(const char **) c->var = match;
250           }
251           break;
252         default:
253           error (_("gdb internal error: bad var_type in do_setshow_command"));
254         }
255     }
256   else if (c->type == show_cmd)
257     {
258       struct cleanup *old_chain;
259       struct ui_stream *stb;
260       int quote;
261
262       stb = ui_out_stream_new (uiout);
263       old_chain = make_cleanup_ui_out_stream_delete (stb);
264
265       /* Possibly call the pre hook.  */
266       if (c->pre_show_hook)
267         (c->pre_show_hook) (c);
268
269       quote = 0;
270       switch (c->var_type)
271         {
272         case var_string:
273           {
274             unsigned char *p;
275
276             if (*(unsigned char **) c->var)
277               fputstr_filtered (*(unsigned char **) c->var, '"', stb->stream);
278             quote = 1;
279           }
280           break;
281         case var_string_noescape:
282         case var_filename:
283         case var_enum:
284           if (*(char **) c->var)
285             fputs_filtered (*(char **) c->var, stb->stream);
286           quote = 1;
287           break;
288         case var_boolean:
289           fputs_filtered (*(int *) c->var ? "on" : "off", stb->stream);
290           break;
291         case var_auto_boolean:
292           switch (*(enum auto_boolean*) c->var)
293             {
294             case AUTO_BOOLEAN_TRUE:
295               fputs_filtered ("on", stb->stream);
296               break;
297             case AUTO_BOOLEAN_FALSE:
298               fputs_filtered ("off", stb->stream);
299               break;
300             case AUTO_BOOLEAN_AUTO:
301               fputs_filtered ("auto", stb->stream);
302               break;
303             default:
304               internal_error (__FILE__, __LINE__,
305                               "do_setshow_command: invalid var_auto_boolean");
306               break;
307             }
308           break;
309         case var_uinteger:
310           if (*(unsigned int *) c->var == UINT_MAX)
311             {
312               fputs_filtered ("unlimited", stb->stream);
313               break;
314             }
315           /* else fall through */
316         case var_zinteger:
317           fprintf_filtered (stb->stream, "%u", *(unsigned int *) c->var);
318           break;
319         case var_integer:
320           if (*(int *) c->var == INT_MAX)
321             {
322               fputs_filtered ("unlimited", stb->stream);
323             }
324           else
325             fprintf_filtered (stb->stream, "%d", *(int *) c->var);
326           break;
327
328         default:
329           error (_("gdb internal error: bad var_type in do_setshow_command"));
330         }
331
332
333       /* FIXME: cagney/2005-02-10: Need to split this in half: code to
334          convert the value into a string (esentially the above); and
335          code to print the value out.  For the latter there should be
336          MI and CLI specific versions.  */
337
338       if (ui_out_is_mi_like_p (uiout))
339         ui_out_field_stream (uiout, "value", stb);
340       else if (c->fprint_setshow != NULL)
341         {
342           long length;
343           char *value = ui_file_xstrdup (stb->stream, &length);
344           make_cleanup (xfree, value);
345           c->fprint_setshow (c, gdb_stdout, value);
346           fprintf_filtered (gdb_stdout, "\n");
347         }
348       else
349         {
350           /* Print doc minus "show" at start.  */
351           print_doc_line (gdb_stdout, c->doc + 5);
352
353           ui_out_text (uiout, " is ");
354           ui_out_wrap_hint (uiout, "    ");
355           if (quote)
356             ui_out_text (uiout, "\"");
357           ui_out_field_stream (uiout, "value", stb);
358           if (quote)
359             ui_out_text (uiout, "\"");
360           ui_out_text (uiout, ".\n");
361           do_cleanups (old_chain);
362         }
363       do_cleanups (old_chain);
364     }
365   else
366     error (_("gdb internal error: bad cmd_type in do_setshow_command"));
367   c->func (c, NULL, from_tty);
368   if (c->type == set_cmd && deprecated_set_hook)
369     deprecated_set_hook (c);
370 }
371
372 /* Show all the settings in a list of show commands.  */
373
374 void
375 cmd_show_list (struct cmd_list_element *list, int from_tty, char *prefix)
376 {
377   struct cleanup *showlist_chain;
378
379   showlist_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "showlist");
380   for (; list != NULL; list = list->next)
381     {
382       /* If we find a prefix, run its list, prefixing our output by its
383          prefix (with "show " skipped).  */
384       if (list->prefixlist && !list->abbrev_flag)
385         {
386           struct cleanup *optionlist_chain
387             = make_cleanup_ui_out_tuple_begin_end (uiout, "optionlist");
388           char *new_prefix = strstr (list->prefixname, "show ") + 5;
389           if (ui_out_is_mi_like_p (uiout))
390             ui_out_field_string (uiout, "prefix", new_prefix);
391           cmd_show_list (*list->prefixlist, from_tty, new_prefix);
392           /* Close the tuple.  */
393           do_cleanups (optionlist_chain);
394         }
395       if (list->type == show_cmd)
396         {
397           struct cleanup *option_chain
398             = make_cleanup_ui_out_tuple_begin_end (uiout, "option");
399           ui_out_text (uiout, prefix);
400           ui_out_field_string (uiout, "name", list->name);
401           ui_out_text (uiout, ":  ");
402           do_setshow_command ((char *) NULL, from_tty, list);
403           /* Close the tuple.  */
404           do_cleanups (option_chain);
405         }
406     }
407   /* Close the tuple.  */
408   do_cleanups (showlist_chain);
409 }
410