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