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