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_optional_filename:
184           if (arg == NULL)
185             arg = "";
186           if (*(char **) c->var != NULL)
187             xfree (*(char **) c->var);
188           *(char **) c->var = savestring (arg, strlen (arg));
189           break;
190         case var_filename:
191           if (arg == NULL)
192             error_no_arg (_("filename to set it to."));
193           if (*(char **) c->var != NULL)
194             xfree (*(char **) c->var);
195           *(char **) c->var = tilde_expand (arg);
196           break;
197         case var_boolean:
198           *(int *) c->var = parse_binary_operation (arg);
199           break;
200         case var_auto_boolean:
201           *(enum auto_boolean *) c->var = parse_auto_binary_operation (arg);
202           break;
203         case var_uinteger:
204           if (arg == NULL)
205             error_no_arg (_("integer to set it to."));
206           *(unsigned int *) c->var = parse_and_eval_long (arg);
207           if (*(unsigned int *) c->var == 0)
208             *(unsigned int *) c->var = UINT_MAX;
209           break;
210         case var_integer:
211           {
212             unsigned int val;
213             if (arg == NULL)
214               error_no_arg (_("integer to set it to."));
215             val = parse_and_eval_long (arg);
216             if (val == 0)
217               *(int *) c->var = INT_MAX;
218             else if (val >= INT_MAX)
219               error (_("integer %u out of range"), val);
220             else
221               *(int *) c->var = val;
222             break;
223           }
224         case var_zinteger:
225           if (arg == NULL)
226             error_no_arg (_("integer to set it to."));
227           *(int *) c->var = parse_and_eval_long (arg);
228           break;
229         case var_enum:
230           {
231             int i;
232             int len;
233             int nmatches;
234             const char *match = NULL;
235             char *p;
236
237             /* if no argument was supplied, print an informative error message */
238             if (arg == NULL)
239               {
240                 char msg[1024];
241                 strcpy (msg, "Requires an argument. Valid arguments are ");
242                 for (i = 0; c->enums[i]; i++)
243                   {
244                     if (i != 0)
245                       strcat (msg, ", ");
246                     strcat (msg, c->enums[i]);
247                   }
248                 strcat (msg, ".");
249                 error (("%s"), msg);
250               }
251
252             p = strchr (arg, ' ');
253
254             if (p)
255               len = p - arg;
256             else
257               len = strlen (arg);
258
259             nmatches = 0;
260             for (i = 0; c->enums[i]; i++)
261               if (strncmp (arg, c->enums[i], len) == 0)
262                 {
263                   if (c->enums[i][len] == '\0')
264                     {
265                       match = c->enums[i];
266                       nmatches = 1;
267                       break; /* exact match. */
268                     }
269                   else
270                     {
271                       match = c->enums[i];
272                       nmatches++;
273                     }
274                 }
275
276             if (nmatches <= 0)
277               error (_("Undefined item: \"%s\"."), arg);
278
279             if (nmatches > 1)
280               error (_("Ambiguous item \"%s\"."), arg);
281
282             *(const char **) c->var = match;
283           }
284           break;
285         default:
286           error (_("gdb internal error: bad var_type in do_setshow_command"));
287         }
288     }
289   else if (c->type == show_cmd)
290     {
291       struct cleanup *old_chain;
292       struct ui_stream *stb;
293
294       stb = ui_out_stream_new (uiout);
295       old_chain = make_cleanup_ui_out_stream_delete (stb);
296
297       /* Possibly call the pre hook.  */
298       if (c->pre_show_hook)
299         (c->pre_show_hook) (c);
300
301       switch (c->var_type)
302         {
303         case var_string:
304           {
305             unsigned char *p;
306
307             if (*(unsigned char **) c->var)
308               fputstr_filtered (*(unsigned char **) c->var, '"', stb->stream);
309           }
310           break;
311         case var_string_noescape:
312         case var_optional_filename:
313         case var_filename:
314         case var_enum:
315           if (*(char **) c->var)
316             fputs_filtered (*(char **) c->var, stb->stream);
317           break;
318         case var_boolean:
319           fputs_filtered (*(int *) c->var ? "on" : "off", stb->stream);
320           break;
321         case var_auto_boolean:
322           switch (*(enum auto_boolean*) c->var)
323             {
324             case AUTO_BOOLEAN_TRUE:
325               fputs_filtered ("on", stb->stream);
326               break;
327             case AUTO_BOOLEAN_FALSE:
328               fputs_filtered ("off", stb->stream);
329               break;
330             case AUTO_BOOLEAN_AUTO:
331               fputs_filtered ("auto", stb->stream);
332               break;
333             default:
334               internal_error (__FILE__, __LINE__,
335                               _("do_setshow_command: invalid var_auto_boolean"));
336               break;
337             }
338           break;
339         case var_uinteger:
340           if (*(unsigned int *) c->var == UINT_MAX)
341             {
342               fputs_filtered ("unlimited", stb->stream);
343               break;
344             }
345           /* else fall through */
346         case var_zinteger:
347           fprintf_filtered (stb->stream, "%u", *(unsigned int *) c->var);
348           break;
349         case var_integer:
350           if (*(int *) c->var == INT_MAX)
351             {
352               fputs_filtered ("unlimited", stb->stream);
353             }
354           else
355             fprintf_filtered (stb->stream, "%d", *(int *) c->var);
356           break;
357
358         default:
359           error (_("gdb internal error: bad var_type in do_setshow_command"));
360         }
361
362
363       /* FIXME: cagney/2005-02-10: Need to split this in half: code to
364          convert the value into a string (esentially the above); and
365          code to print the value out.  For the latter there should be
366          MI and CLI specific versions.  */
367
368       if (ui_out_is_mi_like_p (uiout))
369         ui_out_field_stream (uiout, "value", stb);
370       else
371         {
372           long length;
373           char *value = ui_file_xstrdup (stb->stream, &length);
374           make_cleanup (xfree, value);
375           if (c->show_value_func != NULL)
376             c->show_value_func (gdb_stdout, from_tty, c, value);
377           else
378             deprecated_show_value_hack (gdb_stdout, from_tty, c, value);
379         }
380       do_cleanups (old_chain);
381     }
382   else
383     error (_("gdb internal error: bad cmd_type in do_setshow_command"));
384   c->func (c, NULL, from_tty);
385   if (c->type == set_cmd && deprecated_set_hook)
386     deprecated_set_hook (c);
387 }
388
389 /* Show all the settings in a list of show commands.  */
390
391 void
392 cmd_show_list (struct cmd_list_element *list, int from_tty, char *prefix)
393 {
394   struct cleanup *showlist_chain;
395
396   showlist_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "showlist");
397   for (; list != NULL; list = list->next)
398     {
399       /* If we find a prefix, run its list, prefixing our output by its
400          prefix (with "show " skipped).  */
401       if (list->prefixlist && !list->abbrev_flag)
402         {
403           struct cleanup *optionlist_chain
404             = make_cleanup_ui_out_tuple_begin_end (uiout, "optionlist");
405           char *new_prefix = strstr (list->prefixname, "show ") + 5;
406           if (ui_out_is_mi_like_p (uiout))
407             ui_out_field_string (uiout, "prefix", new_prefix);
408           cmd_show_list (*list->prefixlist, from_tty, new_prefix);
409           /* Close the tuple.  */
410           do_cleanups (optionlist_chain);
411         }
412       if (list->type == show_cmd)
413         {
414           struct cleanup *option_chain
415             = make_cleanup_ui_out_tuple_begin_end (uiout, "option");
416           ui_out_text (uiout, prefix);
417           ui_out_field_string (uiout, "name", list->name);
418           ui_out_text (uiout, ":  ");
419           do_setshow_command ((char *) NULL, from_tty, list);
420           /* Close the tuple.  */
421           do_cleanups (option_chain);
422         }
423     }
424   /* Close the tuple.  */
425   do_cleanups (showlist_chain);
426 }
427