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 
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 
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 && deprecated_set_hook)
348     deprecated_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 	  char *new_prefix = strstr (list->prefixname, "show ") + 5;
368 	  if (ui_out_is_mi_like_p (uiout))
369 	    ui_out_field_string (uiout, "prefix", new_prefix);
370 	  cmd_show_list (*list->prefixlist, from_tty, new_prefix);
371 	  /* Close the tuple.  */
372 	  do_cleanups (optionlist_chain);
373 	}
374       if (list->type == show_cmd)
375 	{
376 	  struct cleanup *option_chain
377 	    = make_cleanup_ui_out_tuple_begin_end (uiout, "option");
378 	  ui_out_text (uiout, prefix);
379 	  ui_out_field_string (uiout, "name", list->name);
380 	  ui_out_text (uiout, ":  ");
381 	  do_setshow_command ((char *) NULL, from_tty, list);
382           /* Close the tuple.  */
383 	  do_cleanups (option_chain);
384 	}
385     }
386   /* Close the tuple.  */
387   do_cleanups (showlist_chain);
388 }
389 
390