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