2000-12-01 Fernando Nasser <fnasser@redhat.com>
[external/binutils.git] / gdb / cli / cli-setshow.c
1 /* Handle set and show GDB commands.
2    Copyright 2000 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place - Suite 330,
17    Boston, MA 02111-1307, USA.  */
18
19 #include "defs.h"
20 #include "value.h"
21 #include <ctype.h>
22 #if 0
23 #include "gdb_string.h"
24 #endif
25
26 #ifdef UI_OUT
27 #include "ui-out.h"
28 #endif
29
30 #include "cli/cli-decode.h"
31 #include "cli/cli-cmds.h"
32 #include "cli/cli-setshow.h"
33
34 /* Prototypes for local functions */
35
36 static int parse_binary_operation (char *);
37
38 static enum cmd_auto_boolean parse_auto_binary_operation (const char *arg);
39 \f
40 static enum cmd_auto_boolean
41 parse_auto_binary_operation (const char *arg)
42 {
43   if (arg != NULL && *arg != '\0')
44     {
45       int length = strlen (arg);
46       while (isspace (arg[length - 1]) && length > 0)
47         length--;
48       if (strncmp (arg, "on", length) == 0
49           || strncmp (arg, "1", length) == 0
50           || strncmp (arg, "yes", length) == 0
51           || strncmp (arg, "enable", length) == 0)
52         return CMD_AUTO_BOOLEAN_TRUE;
53       else if (strncmp (arg, "off", length) == 0
54                || strncmp (arg, "0", length) == 0
55                || strncmp (arg, "no", length) == 0
56                || strncmp (arg, "disable", length) == 0)
57         return CMD_AUTO_BOOLEAN_FALSE;
58       else if (strncmp (arg, "auto", length) == 0
59                || (strncmp (arg, "-1", length) == 0 && length > 1))
60         return CMD_AUTO_BOOLEAN_AUTO;
61     }
62   error ("\"on\", \"off\" or \"auto\" expected.");
63   return CMD_AUTO_BOOLEAN_AUTO; /* pacify GCC */
64 }
65
66 static int
67 parse_binary_operation (char *arg)
68 {
69   int length;
70
71   if (!arg || !*arg)
72     return 1;
73
74   length = strlen (arg);
75
76   while (arg[length - 1] == ' ' || arg[length - 1] == '\t')
77     length--;
78
79   if (strncmp (arg, "on", length) == 0
80       || strncmp (arg, "1", length) == 0
81       || strncmp (arg, "yes", length) == 0
82       || strncmp (arg, "enable", length) == 0)
83     return 1;
84   else if (strncmp (arg, "off", length) == 0
85            || strncmp (arg, "0", length) == 0
86            || strncmp (arg, "no", length) == 0
87            || strncmp (arg, "disable", length) == 0)
88     return 0;
89   else
90     {
91       error ("\"on\" or \"off\" expected.");
92       return 0;
93     }
94 }
95 \f
96 /* Do a "set" or "show" command.  ARG is NULL if no argument, or the text
97    of the argument, and FROM_TTY is nonzero if this command is being entered
98    directly by the user (i.e. these are just like any other
99    command).  C is the command list element for the command.  */
100
101 void
102 do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c)
103 {
104   if (c->type == set_cmd)
105     {
106       switch (c->var_type)
107         {
108         case var_string:
109           {
110             char *new;
111             char *p;
112             char *q;
113             int ch;
114
115             if (arg == NULL)
116               arg = "";
117             new = (char *) xmalloc (strlen (arg) + 2);
118             p = arg;
119             q = new;
120             while ((ch = *p++) != '\000')
121               {
122                 if (ch == '\\')
123                   {
124                     /* \ at end of argument is used after spaces
125                        so they won't be lost.  */
126                     /* This is obsolete now that we no longer strip
127                        trailing whitespace and actually, the backslash
128                        didn't get here in my test, readline or
129                        something did something funky with a backslash
130                        right before a newline.  */
131                     if (*p == 0)
132                       break;
133                     ch = parse_escape (&p);
134                     if (ch == 0)
135                       break;    /* C loses */
136                     else if (ch > 0)
137                       *q++ = ch;
138                   }
139                 else
140                   *q++ = ch;
141               }
142 #if 0
143             if (*(p - 1) != '\\')
144               *q++ = ' ';
145 #endif
146             *q++ = '\0';
147             new = (char *) xrealloc (new, q - new);
148             if (*(char **) c->var != NULL)
149               free (*(char **) c->var);
150             *(char **) c->var = new;
151           }
152           break;
153         case var_string_noescape:
154           if (arg == NULL)
155             arg = "";
156           if (*(char **) c->var != NULL)
157             free (*(char **) c->var);
158           *(char **) c->var = savestring (arg, strlen (arg));
159           break;
160         case var_filename:
161           if (arg == NULL)
162             error_no_arg ("filename to set it to.");
163           if (*(char **) c->var != NULL)
164             free (*(char **) c->var);
165           *(char **) c->var = tilde_expand (arg);
166           break;
167         case var_boolean:
168           *(int *) c->var = parse_binary_operation (arg);
169           break;
170         case var_auto_boolean:
171           *(enum cmd_auto_boolean *) c->var = parse_auto_binary_operation (arg);
172           break;
173         case var_uinteger:
174           if (arg == NULL)
175             error_no_arg ("integer to set it to.");
176           *(unsigned int *) c->var = parse_and_eval_long (arg);
177           if (*(unsigned int *) c->var == 0)
178             *(unsigned int *) c->var = UINT_MAX;
179           break;
180         case var_integer:
181           {
182             unsigned int val;
183             if (arg == NULL)
184               error_no_arg ("integer to set it to.");
185             val = parse_and_eval_long (arg);
186             if (val == 0)
187               *(int *) c->var = INT_MAX;
188             else if (val >= INT_MAX)
189               error ("integer %u out of range", val);
190             else
191               *(int *) c->var = val;
192             break;
193           }
194         case var_zinteger:
195           if (arg == NULL)
196             error_no_arg ("integer to set it to.");
197           *(int *) c->var = parse_and_eval_long (arg);
198           break;
199         case var_enum:
200           {
201             int i;
202             int len;
203             int nmatches;
204             const char *match = NULL;
205             char *p;
206
207             /* if no argument was supplied, print an informative error message */
208             if (arg == NULL)
209               {
210                 char msg[1024];
211                 strcpy (msg, "Requires an argument. Valid arguments are ");
212                 for (i = 0; c->enums[i]; i++)
213                   {
214                     if (i != 0)
215                       strcat (msg, ", ");
216                     strcat (msg, c->enums[i]);
217                   }
218                 strcat (msg, ".");
219                 error (msg);
220               }
221
222             p = strchr (arg, ' ');
223
224             if (p)
225               len = p - arg;
226             else
227               len = strlen (arg);
228
229             nmatches = 0;
230             for (i = 0; c->enums[i]; i++)
231               if (strncmp (arg, c->enums[i], len) == 0)
232                 {
233                   if (c->enums[i][len] == '\0')
234                     {
235                       match = c->enums[i];
236                       nmatches = 1;
237                       break; /* exact match. */
238                     }
239                   else
240                     {
241                       match = c->enums[i];
242                       nmatches++;
243                     }
244                 }
245
246             if (nmatches <= 0)
247               error ("Undefined item: \"%s\".", arg);
248
249             if (nmatches > 1)
250               error ("Ambiguous item \"%s\".", arg);
251
252             *(const char **) c->var = match;
253           }
254           break;
255         default:
256           error ("gdb internal error: bad var_type in do_setshow_command");
257         }
258     }
259   else if (c->type == show_cmd)
260     {
261 #ifdef UI_OUT
262       struct cleanup *old_chain;
263       struct ui_stream *stb;
264       int quote;
265
266       stb = ui_out_stream_new (uiout);
267       old_chain = make_cleanup_ui_out_stream_delete (stb);
268 #endif /* UI_OUT */
269
270       /* Print doc minus "show" at start.  */
271       print_doc_line (gdb_stdout, c->doc + 5);
272
273 #ifdef UI_OUT
274       ui_out_text (uiout, " is ");
275       ui_out_wrap_hint (uiout, "    ");
276       quote = 0;
277       switch (c->var_type)
278         {
279         case var_string:
280           {
281             unsigned char *p;
282
283             if (*(unsigned char **) c->var)
284               fputstr_filtered (*(unsigned char **) c->var, '"', stb->stream);
285             quote = 1;
286           }
287           break;
288         case var_string_noescape:
289         case var_filename:
290         case var_enum:
291           if (*(char **) c->var)
292             fputs_filtered (*(char **) c->var, stb->stream);
293           quote = 1;
294           break;
295         case var_boolean:
296           fputs_filtered (*(int *) c->var ? "on" : "off", stb->stream);
297           break;
298         case var_auto_boolean:
299           switch (*(enum cmd_auto_boolean*) c->var)
300             {
301             case CMD_AUTO_BOOLEAN_TRUE:
302               fputs_filtered ("on", stb->stream);
303               break;
304             case CMD_AUTO_BOOLEAN_FALSE:
305               fputs_filtered ("off", stb->stream);
306               break;
307             case CMD_AUTO_BOOLEAN_AUTO:
308               fputs_filtered ("auto", stb->stream);
309               break;
310             default:
311               internal_error ("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 #else
345       fputs_filtered (" is ", gdb_stdout);
346       wrap_here ("    ");
347       switch (c->var_type)
348         {
349         case var_string:
350           {
351             fputs_filtered ("\"", gdb_stdout);
352             if (*(unsigned char **) c->var)
353               fputstr_filtered (*(unsigned char **) c->var, '"', gdb_stdout);
354             fputs_filtered ("\"", gdb_stdout);
355           }
356           break;
357         case var_string_noescape:
358         case var_filename:
359         case var_enum:
360           fputs_filtered ("\"", gdb_stdout);
361           if (*(char **) c->var)
362             fputs_filtered (*(char **) c->var, gdb_stdout);
363           fputs_filtered ("\"", gdb_stdout);
364           break;
365         case var_boolean:
366           fputs_filtered (*(int *) c->var ? "on" : "off", gdb_stdout);
367           break;
368         case var_auto_boolean:
369           switch (*(enum cmd_auto_boolean*) c->var)
370             {
371             case CMD_AUTO_BOOLEAN_TRUE:
372               fputs_filtered ("on", gdb_stdout);
373               break;
374             case CMD_AUTO_BOOLEAN_FALSE:
375               fputs_filtered ("off", gdb_stdout);
376               break;
377             case CMD_AUTO_BOOLEAN_AUTO:
378               fputs_filtered ("auto", gdb_stdout);
379               break;
380             default:
381               internal_error ("do_setshow_command: invalid var_auto_boolean");
382               break;
383             }
384           break;
385         case var_uinteger:
386           if (*(unsigned int *) c->var == UINT_MAX)
387             {
388               fputs_filtered ("unlimited", gdb_stdout);
389               break;
390             }
391           /* else fall through */
392         case var_zinteger:
393           fprintf_filtered (gdb_stdout, "%u", *(unsigned int *) c->var);
394           break;
395         case var_integer:
396           if (*(int *) c->var == INT_MAX)
397             {
398               fputs_filtered ("unlimited", gdb_stdout);
399             }
400           else
401             fprintf_filtered (gdb_stdout, "%d", *(int *) c->var);
402           break;
403
404         default:
405           error ("gdb internal error: bad var_type in do_setshow_command");
406         }
407       fputs_filtered (".\n", gdb_stdout);
408 #endif
409     }
410   else
411     error ("gdb internal error: bad cmd_type in do_setshow_command");
412   (*c->function.sfunc) (NULL, from_tty, c);
413   if (c->type == set_cmd && set_hook)
414     set_hook (c);
415 }
416
417 /* Show all the settings in a list of show commands.  */
418
419 void
420 cmd_show_list (struct cmd_list_element *list, int from_tty, char *prefix)
421 {
422 #ifdef UI_OUT
423   ui_out_list_begin (uiout, "showlist");
424 #endif
425   for (; list != NULL; list = list->next)
426     {
427       /* If we find a prefix, run its list, prefixing our output by its
428          prefix (with "show " skipped).  */
429 #ifdef UI_OUT
430       if (list->prefixlist && !list->abbrev_flag)
431         {
432           ui_out_list_begin (uiout, "optionlist");
433           ui_out_field_string (uiout, "prefix", list->prefixname + 5);
434           cmd_show_list (*list->prefixlist, from_tty, list->prefixname + 5);
435           ui_out_list_end (uiout);
436         }
437       if (list->type == show_cmd)
438         {
439           ui_out_list_begin (uiout, "option");
440           ui_out_text (uiout, prefix);
441           ui_out_field_string (uiout, "name", list->name);
442           ui_out_text (uiout, ":  ");
443           do_setshow_command ((char *) NULL, from_tty, list);
444           ui_out_list_end (uiout);
445         }
446 #else
447       if (list->prefixlist && !list->abbrev_flag)
448         cmd_show_list (*list->prefixlist, from_tty, list->prefixname + 5);
449       if (list->type == show_cmd)
450         {
451           fputs_filtered (prefix, gdb_stdout);
452           fputs_filtered (list->name, gdb_stdout);
453           fputs_filtered (":  ", gdb_stdout);
454           do_setshow_command ((char *) NULL, from_tty, list);
455         }
456 #endif
457     }
458 #ifdef UI_OUT
459   ui_out_list_end (uiout);
460 #endif
461 }
462