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