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