xref: /openbsd-src/gnu/usr.bin/binutils/gdb/cli/cli-setshow.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
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