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