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