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