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