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