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