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