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