xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/cli/cli-setshow.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 /* Handle set and show GDB commands.
2 
3    Copyright (C) 2000-2019 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 "observable.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 (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 	    std::string msg;
371 
372 	    for (i = 0; c->enums[i]; i++)
373 	      {
374 		if (i != 0)
375 		  msg += ", ";
376 		msg += c->enums[i];
377 	      }
378 	    error (_("Requires an argument. Valid arguments are %s."),
379 		   msg.c_str ());
380 	  }
381 
382 	p = strchr (arg, ' ');
383 
384 	if (p)
385 	  len = p - arg;
386 	else
387 	  len = strlen (arg);
388 
389 	nmatches = 0;
390 	for (i = 0; c->enums[i]; i++)
391 	  if (strncmp (arg, c->enums[i], len) == 0)
392 	    {
393 	      if (c->enums[i][len] == '\0')
394 		{
395 		  match = c->enums[i];
396 		  nmatches = 1;
397 		  break; /* Exact match.  */
398 		}
399 	      else
400 		{
401 		  match = c->enums[i];
402 		  nmatches++;
403 		}
404 	    }
405 
406 	if (nmatches <= 0)
407 	  error (_("Undefined item: \"%s\"."), arg);
408 
409 	if (nmatches > 1)
410 	  error (_("Ambiguous item \"%s\"."), arg);
411 
412 	if (*(const char **) c->var != match)
413 	  {
414 	    *(const char **) c->var = match;
415 
416 	    option_changed = 1;
417 	  }
418       }
419       break;
420     case var_zuinteger_unlimited:
421       {
422 	LONGEST val;
423 
424 	if (arg == NULL)
425 	  error_no_arg (_("integer to set it to, or \"unlimited\"."));
426 
427 	if (is_unlimited_literal (arg))
428 	  val = -1;
429 	else
430 	  val = parse_and_eval_long (arg);
431 
432 	if (val > INT_MAX)
433 	  error (_("integer %s out of range"), plongest (val));
434 	else if (val < -1)
435 	  error (_("only -1 is allowed to set as unlimited"));
436 
437 	if (*(int *) c->var != val)
438 	  {
439 	    *(int *) c->var = val;
440 	    option_changed = 1;
441 	  }
442       }
443       break;
444     default:
445       error (_("gdb internal error: bad var_type in do_setshow_command"));
446     }
447   c->func (c, NULL, from_tty);
448 
449   if (notify_command_param_changed_p (option_changed, c))
450     {
451       char *name, *cp;
452       struct cmd_list_element **cmds;
453       struct cmd_list_element *p;
454       int i;
455       int length = 0;
456 
457       /* Compute the whole multi-word command options.  If user types command
458 	 'set foo bar baz on', c->name is 'baz', and GDB can't pass "bar" to
459 	 command option change notification, because it is confusing.  We can
460 	 trace back through field 'prefix' to compute the whole options,
461 	 and pass "foo bar baz" to notification.  */
462 
463       for (i = 0, p = c; p != NULL; i++)
464 	{
465 	  length += strlen (p->name);
466 	  length++;
467 
468 	  p = p->prefix;
469 	}
470       cp = name = (char *) xmalloc (length);
471       cmds = XNEWVEC (struct cmd_list_element *, i);
472 
473       /* Track back through filed 'prefix' and cache them in CMDS.  */
474       for (i = 0, p = c; p != NULL; i++)
475 	{
476 	  cmds[i] = p;
477 	  p = p->prefix;
478 	}
479 
480       /* Don't trigger any observer notification if prefixlist is not
481 	 setlist.  */
482       i--;
483       if (cmds[i]->prefixlist != &setlist)
484 	{
485 	  xfree (cmds);
486 	  xfree (name);
487 
488 	  return;
489 	}
490       /* Traverse them in the reversed order, and copy their names into
491 	 NAME.  */
492       for (i--; i >= 0; i--)
493 	{
494 	  memcpy (cp, cmds[i]->name, strlen (cmds[i]->name));
495 	  cp += strlen (cmds[i]->name);
496 
497 	  if (i != 0)
498 	    {
499 	      cp[0] = ' ';
500 	      cp++;
501 	    }
502 	}
503       cp[0] = 0;
504 
505       xfree (cmds);
506 
507       switch (c->var_type)
508 	{
509 	case var_string:
510 	case var_string_noescape:
511 	case var_filename:
512 	case var_optional_filename:
513 	case var_enum:
514 	  gdb::observers::command_param_changed.notify (name, *(char **) c->var);
515 	  break;
516 	case var_boolean:
517 	  {
518 	    const char *opt = *(int *) c->var ? "on" : "off";
519 
520 	    gdb::observers::command_param_changed.notify (name, opt);
521 	  }
522 	  break;
523 	case var_auto_boolean:
524 	  {
525 	    const char *s = auto_boolean_enums[*(enum auto_boolean *) c->var];
526 
527 	    gdb::observers::command_param_changed.notify (name, s);
528 	  }
529 	  break;
530 	case var_uinteger:
531 	case var_zuinteger:
532 	  {
533 	    char s[64];
534 
535 	    xsnprintf (s, sizeof s, "%u", *(unsigned int *) c->var);
536 	    gdb::observers::command_param_changed.notify (name, s);
537 	  }
538 	  break;
539 	case var_integer:
540 	case var_zinteger:
541 	case var_zuinteger_unlimited:
542 	  {
543 	    char s[64];
544 
545 	    xsnprintf (s, sizeof s, "%d", *(int *) c->var);
546 	    gdb::observers::command_param_changed.notify (name, s);
547 	  }
548 	  break;
549 	}
550       xfree (name);
551     }
552 }
553 
554 /* Do a "show" command.  ARG is NULL if no argument, or the
555    text of the argument, and FROM_TTY is nonzero if this command is
556    being entered directly by the user (i.e. these are just like any
557    other command).  C is the command list element for the command.  */
558 
559 void
560 do_show_command (const char *arg, int from_tty, struct cmd_list_element *c)
561 {
562   struct ui_out *uiout = current_uiout;
563 
564   gdb_assert (c->type == show_cmd);
565 
566   string_file stb;
567 
568   /* Possibly call the pre hook.  */
569   if (c->pre_show_hook)
570     (c->pre_show_hook) (c);
571 
572   switch (c->var_type)
573     {
574     case var_string:
575       if (*(char **) c->var)
576 	stb.putstr (*(char **) c->var, '"');
577       break;
578     case var_string_noescape:
579     case var_optional_filename:
580     case var_filename:
581     case var_enum:
582       if (*(char **) c->var)
583 	stb.puts (*(char **) c->var);
584       break;
585     case var_boolean:
586       stb.puts (*(int *) c->var ? "on" : "off");
587       break;
588     case var_auto_boolean:
589       switch (*(enum auto_boolean*) c->var)
590 	{
591 	case AUTO_BOOLEAN_TRUE:
592 	  stb.puts ("on");
593 	  break;
594 	case AUTO_BOOLEAN_FALSE:
595 	  stb.puts ("off");
596 	  break;
597 	case AUTO_BOOLEAN_AUTO:
598 	  stb.puts ("auto");
599 	  break;
600 	default:
601 	  internal_error (__FILE__, __LINE__,
602 			  _("do_show_command: "
603 			    "invalid var_auto_boolean"));
604 	  break;
605 	}
606       break;
607     case var_uinteger:
608     case var_zuinteger:
609       if (c->var_type == var_uinteger
610 	  && *(unsigned int *) c->var == UINT_MAX)
611 	stb.puts ("unlimited");
612       else
613 	stb.printf ("%u", *(unsigned int *) c->var);
614       break;
615     case var_integer:
616     case var_zinteger:
617       if (c->var_type == var_integer
618 	  && *(int *) c->var == INT_MAX)
619 	stb.puts ("unlimited");
620       else
621 	stb.printf ("%d", *(int *) c->var);
622       break;
623     case var_zuinteger_unlimited:
624       {
625 	if (*(int *) c->var == -1)
626 	  stb.puts ("unlimited");
627 	else
628 	  stb.printf ("%d", *(int *) c->var);
629       }
630       break;
631     default:
632       error (_("gdb internal error: bad var_type in do_show_command"));
633     }
634 
635 
636   /* FIXME: cagney/2005-02-10: Need to split this in half: code to
637      convert the value into a string (esentially the above); and
638      code to print the value out.  For the latter there should be
639      MI and CLI specific versions.  */
640 
641   if (uiout->is_mi_like_p ())
642     uiout->field_stream ("value", stb);
643   else
644     {
645       if (c->show_value_func != NULL)
646 	c->show_value_func (gdb_stdout, from_tty, c, stb.c_str ());
647       else
648 	deprecated_show_value_hack (gdb_stdout, from_tty, c, stb.c_str ());
649     }
650 
651   c->func (c, NULL, from_tty);
652 }
653 
654 /* Show all the settings in a list of show commands.  */
655 
656 void
657 cmd_show_list (struct cmd_list_element *list, int from_tty, const char *prefix)
658 {
659   struct ui_out *uiout = current_uiout;
660 
661   ui_out_emit_tuple tuple_emitter (uiout, "showlist");
662   for (; list != NULL; list = list->next)
663     {
664       /* If we find a prefix, run its list, prefixing our output by its
665          prefix (with "show " skipped).  */
666       if (list->prefixlist && !list->abbrev_flag)
667 	{
668 	  ui_out_emit_tuple optionlist_emitter (uiout, "optionlist");
669 	  const char *new_prefix = strstr (list->prefixname, "show ") + 5;
670 
671 	  if (uiout->is_mi_like_p ())
672 	    uiout->field_string ("prefix", new_prefix);
673 	  cmd_show_list (*list->prefixlist, from_tty, new_prefix);
674 	}
675       else
676 	{
677 	  if (list->theclass != no_set_class)
678 	    {
679 	      ui_out_emit_tuple option_emitter (uiout, "option");
680 
681 	      uiout->text (prefix);
682 	      uiout->field_string ("name", list->name);
683 	      uiout->text (":  ");
684 	      if (list->type == show_cmd)
685 		do_show_command ((char *) NULL, from_tty, list);
686 	      else
687 		cmd_func (list, NULL, from_tty);
688 	    }
689 	}
690     }
691 }
692 
693