xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/cli/cli-setshow.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /* Handle set and show GDB commands.
2 
3    Copyright (C) 2000-2016 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 "arch-utils.h"
23 #include "observer.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 #include "cli/cli-utils.h"
31 
32 /* Return true if the change of command parameter should be notified.  */
33 
34 static int
35 notify_command_param_changed_p (int param_changed, struct cmd_list_element *c)
36 {
37   if (param_changed == 0)
38     return 0;
39 
40   if (c->theclass == class_maintenance || c->theclass == class_deprecated
41       || c->theclass == class_obscure)
42     return 0;
43 
44   return 1;
45 }
46 
47 
48 static enum auto_boolean
49 parse_auto_binary_operation (const char *arg)
50 {
51   if (arg != NULL && *arg != '\0')
52     {
53       int length = strlen (arg);
54 
55       while (isspace (arg[length - 1]) && length > 0)
56 	length--;
57       if (strncmp (arg, "on", length) == 0
58 	  || strncmp (arg, "1", length) == 0
59 	  || strncmp (arg, "yes", length) == 0
60 	  || strncmp (arg, "enable", length) == 0)
61 	return AUTO_BOOLEAN_TRUE;
62       else if (strncmp (arg, "off", length) == 0
63 	       || strncmp (arg, "0", length) == 0
64 	       || strncmp (arg, "no", length) == 0
65 	       || strncmp (arg, "disable", length) == 0)
66 	return AUTO_BOOLEAN_FALSE;
67       else if (strncmp (arg, "auto", length) == 0
68 	       || (strncmp (arg, "-1", length) == 0 && length > 1))
69 	return AUTO_BOOLEAN_AUTO;
70     }
71   error (_("\"on\", \"off\" or \"auto\" expected."));
72   return AUTO_BOOLEAN_AUTO; /* Pacify GCC.  */
73 }
74 
75 /* See cli-setshow.h.  */
76 
77 int
78 parse_cli_boolean_value (const char *arg)
79 {
80   int length;
81 
82   if (!arg || !*arg)
83     return 1;
84 
85   length = strlen (arg);
86 
87   while (arg[length - 1] == ' ' || arg[length - 1] == '\t')
88     length--;
89 
90   if (strncmp (arg, "on", length) == 0
91       || strncmp (arg, "1", length) == 0
92       || strncmp (arg, "yes", length) == 0
93       || strncmp (arg, "enable", length) == 0)
94     return 1;
95   else if (strncmp (arg, "off", length) == 0
96 	   || strncmp (arg, "0", length) == 0
97 	   || strncmp (arg, "no", length) == 0
98 	   || strncmp (arg, "disable", length) == 0)
99     return 0;
100   else
101     return -1;
102 }
103 
104 void
105 deprecated_show_value_hack (struct ui_file *ignore_file,
106 			    int ignore_from_tty,
107 			    struct cmd_list_element *c,
108 			    const char *value)
109 {
110   /* If there's no command or value, don't try to print it out.  */
111   if (c == NULL || value == NULL)
112     return;
113   /* Print doc minus "show" at start.  */
114   print_doc_line (gdb_stdout, c->doc + 5);
115   switch (c->var_type)
116     {
117     case var_string:
118     case var_string_noescape:
119     case var_optional_filename:
120     case var_filename:
121     case var_enum:
122       printf_filtered ((" is \"%s\".\n"), value);
123       break;
124     default:
125       printf_filtered ((" is %s.\n"), value);
126       break;
127     }
128 }
129 
130 /* Returns true if ARG is "unlimited".  */
131 
132 static int
133 is_unlimited_literal (const char *arg)
134 {
135   size_t len = sizeof ("unlimited") - 1;
136 
137   arg = skip_spaces_const (arg);
138 
139   return (strncmp (arg, "unlimited", len) == 0
140 	  && (isspace (arg[len]) || arg[len] == '\0'));
141 }
142 
143 
144 /* Do a "set" command.  ARG is NULL if no argument, or the
145    text of the argument, and FROM_TTY is nonzero if this command is
146    being entered directly by the user (i.e. these are just like any
147    other command).  C is the command list element for the command.  */
148 
149 void
150 do_set_command (const char *arg, int from_tty, struct cmd_list_element *c)
151 {
152   /* A flag to indicate the option is changed or not.  */
153   int option_changed = 0;
154 
155   gdb_assert (c->type == set_cmd);
156 
157   switch (c->var_type)
158     {
159     case var_string:
160       {
161 	char *newobj;
162 	const char *p;
163 	char *q;
164 	int ch;
165 
166 	if (arg == NULL)
167 	  arg = "";
168 	newobj = (char *) xmalloc (strlen (arg) + 2);
169 	p = arg;
170 	q = newobj;
171 	while ((ch = *p++) != '\000')
172 	  {
173 	    if (ch == '\\')
174 	      {
175 		/* \ at end of argument is used after spaces
176 		   so they won't be lost.  */
177 		/* This is obsolete now that we no longer strip
178 		   trailing whitespace and actually, the backslash
179 		   didn't get here in my test, readline or
180 		   something did something funky with a backslash
181 		   right before a newline.  */
182 		if (*p == 0)
183 		  break;
184 		ch = parse_escape (get_current_arch (), &p);
185 		if (ch == 0)
186 		  break;	/* C loses */
187 		else if (ch > 0)
188 		  *q++ = ch;
189 	      }
190 	    else
191 	      *q++ = ch;
192 	  }
193 #if 0
194 	if (*(p - 1) != '\\')
195 	  *q++ = ' ';
196 #endif
197 	*q++ = '\0';
198 	newobj = (char *) xrealloc (newobj, q - newobj);
199 
200 	if (*(char **) c->var == NULL
201 	    || strcmp (*(char **) c->var, newobj) != 0)
202 	  {
203 	    xfree (*(char **) c->var);
204 	    *(char **) c->var = newobj;
205 
206 	    option_changed = 1;
207 	  }
208 	else
209 	  xfree (newobj);
210       }
211       break;
212     case var_string_noescape:
213       if (arg == NULL)
214 	arg = "";
215 
216       if (*(char **) c->var == NULL || strcmp (*(char **) c->var, arg) != 0)
217 	{
218 	  xfree (*(char **) c->var);
219 	  *(char **) c->var = xstrdup (arg);
220 
221 	  option_changed = 1;
222 	}
223       break;
224     case var_filename:
225       if (arg == NULL)
226 	error_no_arg (_("filename to set it to."));
227       /* FALLTHROUGH */
228     case var_optional_filename:
229       {
230 	char *val = NULL;
231 
232 	if (arg != NULL)
233 	  {
234 	    /* Clear trailing whitespace of filename.  */
235 	    const char *ptr = arg + strlen (arg) - 1;
236 	    char *copy;
237 
238 	    while (ptr >= arg && (*ptr == ' ' || *ptr == '\t'))
239 	      ptr--;
240 	    copy = xstrndup (arg, ptr + 1 - arg);
241 
242 	    val = tilde_expand (copy);
243 	    xfree (copy);
244 	  }
245 	else
246 	  val = xstrdup ("");
247 
248 	if (*(char **) c->var == NULL
249 	    || strcmp (*(char **) c->var, val) != 0)
250 	  {
251 	    xfree (*(char **) c->var);
252 	    *(char **) c->var = val;
253 
254 	    option_changed = 1;
255 	  }
256 	else
257 	  xfree (val);
258       }
259       break;
260     case var_boolean:
261       {
262 	int val = parse_cli_boolean_value (arg);
263 
264 	if (val < 0)
265 	  error (_("\"on\" or \"off\" expected."));
266 	if (val != *(int *) c->var)
267 	  {
268 	    *(int *) c->var = val;
269 
270 	    option_changed = 1;
271 	  }
272       }
273       break;
274     case var_auto_boolean:
275       {
276 	enum auto_boolean val = parse_auto_binary_operation (arg);
277 
278 	if (*(enum auto_boolean *) c->var != val)
279 	  {
280 	    *(enum auto_boolean *) c->var = val;
281 
282 	    option_changed = 1;
283 	  }
284       }
285       break;
286     case var_uinteger:
287     case var_zuinteger:
288       {
289 	LONGEST val;
290 
291 	if (arg == NULL)
292 	  {
293 	    if (c->var_type == var_uinteger)
294 	      error_no_arg (_("integer to set it to, or \"unlimited\"."));
295 	    else
296 	      error_no_arg (_("integer to set it to."));
297 	  }
298 
299 	if (c->var_type == var_uinteger && is_unlimited_literal (arg))
300 	  val = 0;
301 	else
302 	  val = parse_and_eval_long (arg);
303 
304 	if (c->var_type == var_uinteger && val == 0)
305 	  val = UINT_MAX;
306 	else if (val < 0
307 		 /* For var_uinteger, don't let the user set the value
308 		    to UINT_MAX directly, as that exposes an
309 		    implementation detail to the user interface.  */
310 		 || (c->var_type == var_uinteger && val >= UINT_MAX)
311 		 || (c->var_type == var_zuinteger && val > UINT_MAX))
312 	  error (_("integer %s out of range"), plongest (val));
313 
314 	if (*(unsigned int *) c->var != val)
315 	  {
316 	    *(unsigned int *) c->var = val;
317 
318 	    option_changed = 1;
319 	  }
320       }
321       break;
322     case var_integer:
323     case var_zinteger:
324       {
325 	LONGEST val;
326 
327 	if (arg == NULL)
328 	  {
329 	    if (c->var_type == var_integer)
330 	      error_no_arg (_("integer to set it to, or \"unlimited\"."));
331 	    else
332 	      error_no_arg (_("integer to set it to."));
333 	  }
334 
335 	if (c->var_type == var_integer && is_unlimited_literal (arg))
336 	  val = 0;
337 	else
338 	  val = parse_and_eval_long (arg);
339 
340 	if (val == 0 && c->var_type == var_integer)
341 	  val = INT_MAX;
342 	else if (val < INT_MIN
343 		 /* For var_integer, don't let the user set the value
344 		    to INT_MAX directly, as that exposes an
345 		    implementation detail to the user interface.  */
346 		 || (c->var_type == var_integer && val >= INT_MAX)
347 		 || (c->var_type == var_zinteger && val > INT_MAX))
348 	  error (_("integer %s out of range"), plongest (val));
349 
350 	if (*(int *) c->var != val)
351 	  {
352 	    *(int *) c->var = val;
353 
354 	    option_changed = 1;
355 	  }
356 	break;
357       }
358     case var_enum:
359       {
360 	int i;
361 	int len;
362 	int nmatches;
363 	const char *match = NULL;
364 	const char *p;
365 
366 	/* If no argument was supplied, print an informative error
367 	   message.  */
368 	if (arg == NULL)
369 	  {
370 	    char *msg;
371 	    int msg_len = 0;
372 
373 	    for (i = 0; c->enums[i]; i++)
374 	      msg_len += strlen (c->enums[i]) + 2;
375 
376 	    msg = (char *) xmalloc (msg_len);
377 	    *msg = '\0';
378 	    make_cleanup (xfree, msg);
379 
380 	    for (i = 0; c->enums[i]; i++)
381 	      {
382 		if (i != 0)
383 		  strcat (msg, ", ");
384 		strcat (msg, c->enums[i]);
385 	      }
386 	    error (_("Requires an argument. Valid arguments are %s."),
387 		   msg);
388 	  }
389 
390 	p = strchr (arg, ' ');
391 
392 	if (p)
393 	  len = p - arg;
394 	else
395 	  len = strlen (arg);
396 
397 	nmatches = 0;
398 	for (i = 0; c->enums[i]; i++)
399 	  if (strncmp (arg, c->enums[i], len) == 0)
400 	    {
401 	      if (c->enums[i][len] == '\0')
402 		{
403 		  match = c->enums[i];
404 		  nmatches = 1;
405 		  break; /* Exact match.  */
406 		}
407 	      else
408 		{
409 		  match = c->enums[i];
410 		  nmatches++;
411 		}
412 	    }
413 
414 	if (nmatches <= 0)
415 	  error (_("Undefined item: \"%s\"."), arg);
416 
417 	if (nmatches > 1)
418 	  error (_("Ambiguous item \"%s\"."), arg);
419 
420 	if (*(const char **) c->var != match)
421 	  {
422 	    *(const char **) c->var = match;
423 
424 	    option_changed = 1;
425 	  }
426       }
427       break;
428     case var_zuinteger_unlimited:
429       {
430 	LONGEST val;
431 
432 	if (arg == NULL)
433 	  error_no_arg (_("integer to set it to, or \"unlimited\"."));
434 
435 	if (is_unlimited_literal (arg))
436 	  val = -1;
437 	else
438 	  val = parse_and_eval_long (arg);
439 
440 	if (val > INT_MAX)
441 	  error (_("integer %s out of range"), plongest (val));
442 	else if (val < -1)
443 	  error (_("only -1 is allowed to set as unlimited"));
444 
445 	if (*(int *) c->var != val)
446 	  {
447 	    *(int *) c->var = val;
448 	    option_changed = 1;
449 	  }
450       }
451       break;
452     default:
453       error (_("gdb internal error: bad var_type in do_setshow_command"));
454     }
455   c->func (c, NULL, from_tty);
456 
457   if (notify_command_param_changed_p (option_changed, c))
458     {
459       char *name, *cp;
460       struct cmd_list_element **cmds;
461       struct cmd_list_element *p;
462       int i;
463       int length = 0;
464 
465       /* Compute the whole multi-word command options.  If user types command
466 	 'set foo bar baz on', c->name is 'baz', and GDB can't pass "bar" to
467 	 command option change notification, because it is confusing.  We can
468 	 trace back through field 'prefix' to compute the whole options,
469 	 and pass "foo bar baz" to notification.  */
470 
471       for (i = 0, p = c; p != NULL; i++)
472 	{
473 	  length += strlen (p->name);
474 	  length++;
475 
476 	  p = p->prefix;
477 	}
478       cp = name = (char *) xmalloc (length);
479       cmds = XNEWVEC (struct cmd_list_element *, i);
480 
481       /* Track back through filed 'prefix' and cache them in CMDS.  */
482       for (i = 0, p = c; p != NULL; i++)
483 	{
484 	  cmds[i] = p;
485 	  p = p->prefix;
486 	}
487 
488       /* Don't trigger any observer notification if prefixlist is not
489 	 setlist.  */
490       i--;
491       if (cmds[i]->prefixlist != &setlist)
492 	{
493 	  xfree (cmds);
494 	  xfree (name);
495 
496 	  return;
497 	}
498       /* Traverse them in the reversed order, and copy their names into
499 	 NAME.  */
500       for (i--; i >= 0; i--)
501 	{
502 	  memcpy (cp, cmds[i]->name, strlen (cmds[i]->name));
503 	  cp += strlen (cmds[i]->name);
504 
505 	  if (i != 0)
506 	    {
507 	      cp[0] = ' ';
508 	      cp++;
509 	    }
510 	}
511       cp[0] = 0;
512 
513       xfree (cmds);
514 
515       switch (c->var_type)
516 	{
517 	case var_string:
518 	case var_string_noescape:
519 	case var_filename:
520 	case var_optional_filename:
521 	case var_enum:
522 	  observer_notify_command_param_changed (name, *(char **) c->var);
523 	  break;
524 	case var_boolean:
525 	  {
526 	    const char *opt = *(int *) c->var ? "on" : "off";
527 
528 	    observer_notify_command_param_changed (name, opt);
529 	  }
530 	  break;
531 	case var_auto_boolean:
532 	  {
533 	    const char *s = auto_boolean_enums[*(enum auto_boolean *) c->var];
534 
535 	    observer_notify_command_param_changed (name, s);
536 	  }
537 	  break;
538 	case var_uinteger:
539 	case var_zuinteger:
540 	  {
541 	    char s[64];
542 
543 	    xsnprintf (s, sizeof s, "%u", *(unsigned int *) c->var);
544 	    observer_notify_command_param_changed (name, s);
545 	  }
546 	  break;
547 	case var_integer:
548 	case var_zinteger:
549 	case var_zuinteger_unlimited:
550 	  {
551 	    char s[64];
552 
553 	    xsnprintf (s, sizeof s, "%d", *(int *) c->var);
554 	    observer_notify_command_param_changed (name, s);
555 	  }
556 	  break;
557 	}
558       xfree (name);
559     }
560 }
561 
562 /* Do a "show" command.  ARG is NULL if no argument, or the
563    text of the argument, and FROM_TTY is nonzero if this command is
564    being entered directly by the user (i.e. these are just like any
565    other command).  C is the command list element for the command.  */
566 
567 void
568 do_show_command (const char *arg, int from_tty, struct cmd_list_element *c)
569 {
570   struct ui_out *uiout = current_uiout;
571   struct cleanup *old_chain;
572   struct ui_file *stb;
573 
574   gdb_assert (c->type == show_cmd);
575 
576   stb = mem_fileopen ();
577   old_chain = make_cleanup_ui_file_delete (stb);
578 
579   /* Possibly call the pre hook.  */
580   if (c->pre_show_hook)
581     (c->pre_show_hook) (c);
582 
583   switch (c->var_type)
584     {
585     case var_string:
586       if (*(char **) c->var)
587 	fputstr_filtered (*(char **) c->var, '"', stb);
588       break;
589     case var_string_noescape:
590     case var_optional_filename:
591     case var_filename:
592     case var_enum:
593       if (*(char **) c->var)
594 	fputs_filtered (*(char **) c->var, stb);
595       break;
596     case var_boolean:
597       fputs_filtered (*(int *) c->var ? "on" : "off", stb);
598       break;
599     case var_auto_boolean:
600       switch (*(enum auto_boolean*) c->var)
601 	{
602 	case AUTO_BOOLEAN_TRUE:
603 	  fputs_filtered ("on", stb);
604 	  break;
605 	case AUTO_BOOLEAN_FALSE:
606 	  fputs_filtered ("off", stb);
607 	  break;
608 	case AUTO_BOOLEAN_AUTO:
609 	  fputs_filtered ("auto", stb);
610 	  break;
611 	default:
612 	  internal_error (__FILE__, __LINE__,
613 			  _("do_show_command: "
614 			    "invalid var_auto_boolean"));
615 	  break;
616 	}
617       break;
618     case var_uinteger:
619     case var_zuinteger:
620       if (c->var_type == var_uinteger
621 	  && *(unsigned int *) c->var == UINT_MAX)
622 	fputs_filtered ("unlimited", stb);
623       else
624 	fprintf_filtered (stb, "%u", *(unsigned int *) c->var);
625       break;
626     case var_integer:
627     case var_zinteger:
628       if (c->var_type == var_integer
629 	  && *(int *) c->var == INT_MAX)
630 	fputs_filtered ("unlimited", stb);
631       else
632 	fprintf_filtered (stb, "%d", *(int *) c->var);
633       break;
634     case var_zuinteger_unlimited:
635       {
636 	if (*(int *) c->var == -1)
637 	  fputs_filtered ("unlimited", stb);
638 	else
639 	  fprintf_filtered (stb, "%d", *(int *) c->var);
640       }
641       break;
642     default:
643       error (_("gdb internal error: bad var_type in do_show_command"));
644     }
645 
646 
647   /* FIXME: cagney/2005-02-10: Need to split this in half: code to
648      convert the value into a string (esentially the above); and
649      code to print the value out.  For the latter there should be
650      MI and CLI specific versions.  */
651 
652   if (ui_out_is_mi_like_p (uiout))
653     ui_out_field_stream (uiout, "value", stb);
654   else
655     {
656       char *value = ui_file_xstrdup (stb, NULL);
657 
658       make_cleanup (xfree, value);
659       if (c->show_value_func != NULL)
660 	c->show_value_func (gdb_stdout, from_tty, c, value);
661       else
662 	deprecated_show_value_hack (gdb_stdout, from_tty, c, value);
663     }
664   do_cleanups (old_chain);
665 
666   c->func (c, NULL, from_tty);
667 }
668 
669 /* Show all the settings in a list of show commands.  */
670 
671 void
672 cmd_show_list (struct cmd_list_element *list, int from_tty, const char *prefix)
673 {
674   struct cleanup *showlist_chain;
675   struct ui_out *uiout = current_uiout;
676 
677   showlist_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "showlist");
678   for (; list != NULL; list = list->next)
679     {
680       /* If we find a prefix, run its list, prefixing our output by its
681          prefix (with "show " skipped).  */
682       if (list->prefixlist && !list->abbrev_flag)
683 	{
684 	  struct cleanup *optionlist_chain
685 	    = make_cleanup_ui_out_tuple_begin_end (uiout, "optionlist");
686 	  const char *new_prefix = strstr (list->prefixname, "show ") + 5;
687 
688 	  if (ui_out_is_mi_like_p (uiout))
689 	    ui_out_field_string (uiout, "prefix", new_prefix);
690 	  cmd_show_list (*list->prefixlist, from_tty, new_prefix);
691 	  /* Close the tuple.  */
692 	  do_cleanups (optionlist_chain);
693 	}
694       else
695 	{
696 	  if (list->theclass != no_set_class)
697 	    {
698 	      struct cleanup *option_chain
699 		= make_cleanup_ui_out_tuple_begin_end (uiout, "option");
700 
701 	      ui_out_text (uiout, prefix);
702 	      ui_out_field_string (uiout, "name", list->name);
703 	      ui_out_text (uiout, ":  ");
704 	      if (list->type == show_cmd)
705 		do_show_command ((char *) NULL, from_tty, list);
706 	      else
707 		cmd_func (list, NULL, from_tty);
708 	      /* Close the tuple.  */
709 	      do_cleanups (option_chain);
710 	    }
711 	}
712     }
713   /* Close the tuple.  */
714   do_cleanups (showlist_chain);
715 }
716 
717