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