/* CLI options framework, for GDB.

   Copyright (C) 2017-2025 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "cli/cli-option.h"
#include "cli/cli-decode.h"
#include "cli/cli-utils.h"
#include "cli/cli-setshow.h"
#include "command.h"
#include <vector>

namespace gdb {
namespace option {

/* An option's value.  Which field is active depends on the option's
   type.  */
union option_value
{
  /* For var_boolean options.  */
  bool boolean;

  /* For var_uinteger options.  */
  unsigned int uinteger;

  /* For var_integer and var_pinteger options.  */
  int integer;

  /* For var_enum options.  */
  const char *enumeration;

  /* For var_string and var_filename options.  This is allocated with new.  */
  std::string *string;

  /* For var_color options.  */
  ui_file_style::color color = ui_file_style::NONE;
};

/* Holds an options definition and its value.  */
struct option_def_and_value
{
  /* The option definition.  */
  const option_def &option;

  /* A context.  */
  void *ctx;

  /* The option's value, if any.  */
  std::optional<option_value> value;

  /* Constructor.  */
  option_def_and_value (const option_def &option_, void *ctx_,
			std::optional<option_value> &&value_ = {})
    : option (option_),
      ctx (ctx_),
      value (std::move (value_))
  {
    clear_value (option_, value_);
  }

  /* Move constructor.  Need this because for some types the values
     are allocated on the heap.  */
  option_def_and_value (option_def_and_value &&rval)
    : option (rval.option),
      ctx (rval.ctx),
      value (std::move (rval.value))
  {
    clear_value (rval.option, rval.value);
  }

  DISABLE_COPY_AND_ASSIGN (option_def_and_value);

  ~option_def_and_value ()
  {
    if (value.has_value ())
      {
	if (option.type == var_string || option.type == var_filename)
	  delete value->string;
      }
  }

private:

  /* Clear the option_value, without releasing it.  This is used after
     the value has been moved to some other option_def_and_value
     instance.  This is needed because for some types the value is
     allocated on the heap, so we must clear the pointer in the
     source, to avoid a double free.  */
  static void clear_value (const option_def &option,
			   std::optional<option_value> &value)
  {
    if (value.has_value ())
      {
	if (option.type == var_string || option.type == var_filename)
	  value->string = nullptr;
      }
  }
};

static void save_option_value_in_ctx (std::optional<option_def_and_value> &ov);

/* Info passed around when handling completion.  */
struct parse_option_completion_info
{
  /* The completion word.  */
  const char *word;

  /* The tracker.  */
  completion_tracker &tracker;
};

/* If ARGS starts with "-", look for a "--" delimiter.  If one is
   found, then interpret everything up until the "--" as command line
   options.  Otherwise, interpret unknown input as the beginning of
   the command's operands.  */

static const char *
find_end_options_delimiter (const char *args)
{
  if (args[0] == '-')
    {
      const char *p = args;

      p = skip_spaces (p);
      while (*p)
	{
	  if (check_for_argument (&p, "--"))
	    return p;
	  else
	    p = skip_to_space (p);
	  p = skip_spaces (p);
	}
    }

  return nullptr;
}

/* Complete TEXT/WORD on all options in OPTIONS_GROUP.  */

static void
complete_on_options (gdb::array_view<const option_def_group> options_group,
		     completion_tracker &tracker,
		     const char *text, const char *word)
{
  size_t textlen = strlen (text);
  for (const auto &grp : options_group)
    for (const auto &opt : grp.options)
      if (strncmp (opt.name, text, textlen) == 0)
	{
	  tracker.add_completion
	    (make_completion_match_str (opt.name, text, word));
	}
}

/* See cli-option.h.  */

void
complete_on_all_options (completion_tracker &tracker,
			 gdb::array_view<const option_def_group> options_group)
{
  static const char opt[] = "-";
  complete_on_options (options_group, tracker, opt + 1, opt);
}

/* Parse ARGS, guided by OPTIONS_GROUP.  HAVE_DELIMITER is true if the
   whole ARGS line included the "--" options-terminator delimiter.  */

static std::optional<option_def_and_value>
parse_option (gdb::array_view<const option_def_group> options_group,
	      process_options_mode mode,
	      bool have_delimiter,
	      const char **args,
	      parse_option_completion_info *completion = nullptr)
{
  if (*args == nullptr)
    return {};
  else if (**args != '-')
    {
      if (have_delimiter)
	error (_("Unrecognized option at: %s"), *args);
      return {};
    }
  else if (check_for_argument (args, "--"))
    return {};

  /* Skip the initial '-'.  */
  const char *arg = *args + 1;

  const char *after = skip_to_space (arg);
  size_t len = after - arg;
  const option_def *match = nullptr;
  void *match_ctx = nullptr;

  for (const auto &grp : options_group)
    {
      for (const auto &o : grp.options)
	{
	  if (strncmp (o.name, arg, len) == 0)
	    {
	      if (match != nullptr)
		{
		  if (completion != nullptr && arg[len] == '\0')
		    {
		      complete_on_options (options_group,
					   completion->tracker,
					   arg, completion->word);
		      return {};
		    }

		  error (_("Ambiguous option at: -%s"), arg);
		}

	      match = &o;
	      match_ctx = grp.ctx;

	      if ((isspace (arg[len]) || arg[len] == '\0')
		  && strlen (o.name) == len)
		break; /* Exact match.  */
	    }
	}
    }

  if (match == nullptr)
    {
      if (have_delimiter || mode != PROCESS_OPTIONS_UNKNOWN_IS_OPERAND)
	error (_("Unrecognized option at: %s"), *args);

      return {};
    }

  if (completion != nullptr && arg[len] == '\0')
    {
      complete_on_options (options_group, completion->tracker,
			   arg, completion->word);
      return {};
    }

  *args += 1 + len;
  *args = skip_spaces (*args);
  if (completion != nullptr)
    completion->word = *args;

  switch (match->type)
    {
    case var_boolean:
      {
	if (!match->have_argument)
	  {
	    option_value val;
	    val.boolean = true;
	    return option_def_and_value {*match, match_ctx, val};
	  }

	const char *val_str = *args;
	int res;

	if (**args == '\0' && completion != nullptr)
	  {
	    /* Complete on both "on/off" and more options.  */

	    if (mode == PROCESS_OPTIONS_REQUIRE_DELIMITER)
	      {
		complete_on_enum (completion->tracker,
				  boolean_enums, val_str, val_str);
		complete_on_all_options (completion->tracker, options_group);
	      }
	    return option_def_and_value {*match, match_ctx};
	  }
	else if (**args == '-')
	  {
	    /* Treat:
		 "cmd -boolean-option -another-opt..."
	       as:
		 "cmd -boolean-option on -another-opt..."
	     */
	    res = 1;
	  }
	else if (**args == '\0')
	  {
	    /* Treat:
		 (1) "cmd -boolean-option "
	       as:
		 (1) "cmd -boolean-option on"
	     */
	    res = 1;
	  }
	else
	  {
	    res = parse_cli_boolean_value (args);
	    if (res < 0)
	      {
		const char *end = skip_to_space (*args);
		if (completion != nullptr)
		  {
		    if (*end == '\0')
		      {
			complete_on_enum (completion->tracker,
					  boolean_enums, val_str, val_str);
			return option_def_and_value {*match, match_ctx};
		      }
		  }

		if (have_delimiter)
		  error (_("Value given for `-%s' is not a boolean: %.*s"),
			 match->name, (int) (end - val_str), val_str);
		/* The user didn't separate options from operands
		   using "--", so treat this unrecognized value as the
		   start of the operands.  This makes "frame apply all
		   -past-main CMD" work.  */
		return option_def_and_value {*match, match_ctx};
	      }
	    else if (completion != nullptr && **args == '\0')
	      {
		/* While "cmd -boolean [TAB]" only offers "on" and
		   "off", the boolean option actually accepts "1",
		   "yes", etc. as boolean values.  We complete on all
		   of those instead of BOOLEAN_ENUMS here to make
		   these work:

		    "p -object 1[TAB]" -> "p -object 1 "
		    "p -object ye[TAB]" -> "p -object yes "

		   Etc.  Note that it's important that the space is
		   auto-appended.  Otherwise, if we only completed on
		   on/off here, then it might look to the user like
		   "1" isn't valid, like:
		   "p -object 1[TAB]" -> "p -object 1" (i.e., nothing happens).
		*/
		static const char *const all_boolean_enums[] = {
		  "on", "off",
		  "yes", "no",
		  "enable", "disable",
		  "0", "1",
		  nullptr,
		};
		complete_on_enum (completion->tracker, all_boolean_enums,
				  val_str, val_str);
		return {};
	      }
	  }

	option_value val;
	val.boolean = res;
	return option_def_and_value {*match, match_ctx, val};
      }
    case var_uinteger:
    case var_integer:
    case var_pinteger:
      {
	if (completion != nullptr && match->extra_literals != nullptr)
	  {
	    /* Convenience to let the user know what the option can
	       accept.  Make sure there's no common prefix between
	       "NUMBER" and all the strings when adding new ones,
	       so that readline doesn't do a partial match.  */
	    if (**args == '\0')
	      {
		completion->tracker.add_completion
		  (make_unique_xstrdup ("NUMBER"));
		for (const literal_def *l = match->extra_literals;
		     l->literal != nullptr;
		     l++)
		  completion->tracker.add_completion
		    (make_unique_xstrdup (l->literal));
		return {};
	      }
	    else
	      {
		bool completions = false;
		for (const literal_def *l = match->extra_literals;
		     l->literal != nullptr;
		     l++)
		  if (startswith (l->literal, *args))
		    {
		      completion->tracker.add_completion
			(make_unique_xstrdup (l->literal));
		      completions = true;
		    }
		if (completions)
		  return {};
	      }
	  }

	LONGEST v = parse_cli_var_integer (match->type,
					   match->extra_literals,
					   args, false);
	option_value val;
	if (match->type == var_uinteger)
	  val.uinteger = v;
	else
	  val.integer = v;
	return option_def_and_value {*match, match_ctx, val};
      }
    case var_enum:
      {
	if (completion != nullptr)
	  {
	    const char *after_arg = skip_to_space (*args);
	    if (*after_arg == '\0')
	      {
		complete_on_enum (completion->tracker,
				  match->enums, *args, *args);
		if (completion->tracker.have_completions ())
		  return {};

		/* If we don't have completions, let the
		   non-completion path throw on invalid enum value
		   below, so that completion processing stops.  */
	      }
	  }

	if (check_for_argument (args, "--"))
	  {
	    /* Treat e.g., "backtrace -entry-values --" as if there
	       was no argument after "-entry-values".  This makes
	       parse_cli_var_enum throw an error with a suggestion of
	       what are the valid options.  */
	    args = nullptr;
	  }

	option_value val;
	val.enumeration = parse_cli_var_enum (args, match->enums);
	return option_def_and_value {*match, match_ctx, val};
      }
    case var_color:
      {
	if (completion != nullptr)
	  {
	    const char *after_arg = skip_to_space (*args);
	    if (*after_arg == '\0')
	      {
		complete_on_color (completion->tracker, *args, *args);

		if (completion->tracker.have_completions ())
		  return {};
	      }
	  }

	if (check_for_argument (args, "--"))
	  {
	    /* Treat e.g., "backtrace -entry-values --" as if there
	       was no argument after "-entry-values".  This makes
	       parse_cli_var_color throw an error with a suggestion of
	       what are the valid options.  */
	    args = nullptr;
	  }

	option_value val;
	ui_file_style::color color = parse_cli_var_color (args);
	ui_file_style::color approx_color = color.approximate (colorsupport ());
	val.color = approx_color;
	return option_def_and_value {*match, match_ctx, val};
      }
    case var_string:
      {
	if (check_for_argument (args, "--"))
	  {
	    /* Treat e.g., "maint test-options -string --" as if there
	       was no argument after "-string".  */
	    error (_("-%s requires an argument"), match->name);
	  }

	const char *arg_start = *args;
	std::string str = extract_string_maybe_quoted (args);
	if (*args == arg_start)
	  error (_("-%s requires an argument"), match->name);

	option_value val;
	val.string = new std::string (std::move (str));
	return option_def_and_value {*match, match_ctx, val};
      }

    case var_filename:
      {
	if (check_for_argument (args, "--"))
	  {
	    /* Treat e.g., "maint test-options -filename --" as if there
	       was no argument after "-filename".  */
	    error (_("-%s requires an argument"), match->name);
	  }

	const char *arg_start = *args;
	std::string str = extract_string_maybe_quoted (args);

	/* If we are performing completion, and extracting STR moved ARGS
	   to the end of the line, then the user is trying to complete the
	   filename value.

	   If ARGS didn't make it to the end of the line then the filename
	   value is already complete and the user is trying to complete
	   something later on the line.  */
	if (completion != nullptr && **args == '\0')
	  {
	    /* Preserve the current custom word point.  If the call to
	       advance_to_filename_maybe_quoted_complete_word_point below
	       skips to the end of the command line then the custom word
	       point will have been updated even though we generate no
	       completions.

	       However, *ARGS will also have been updated, and the general
	       option completion code (which we will return too) also
	       updates the custom word point based on the adjustment made
	       to *ARGS.

	       And so, if we don't find any completions, we should restore
	       the custom word point value, this leaves the generic option
	       completion code free to make its own adjustments.  */
	    int prev_word_pt = completion->tracker.custom_word_point ();

	    /* From ARG_START move forward to the start of the completion
	       word, this will skip over any opening quote if there is
	       one.

	       If the word to complete is fully quoted, i.e. has an
	       opening and closing quote, then this will skip over the
	       word entirely and leave WORD pointing to the end of the
	       input string.  */
	    const char *word
	      = advance_to_filename_maybe_quoted_complete_word_point
	      (completion->tracker, arg_start);

	    if (word == arg_start || *word != '\0')
	      {
		filename_maybe_quoted_completer (nullptr, completion->tracker,
						 arg_start, word);

		if (completion->tracker.have_completions ())
		  return {};
	      }

	    /* No completions.  Restore the custom word point.  See the
	       comment above for why this is needed.  */
	    completion->tracker.set_custom_word_point (prev_word_pt);
	  }

	/* Check we did manage to extract something.  */
	if (*args == arg_start)
	  error (_("-%s requires an argument"), match->name);

	option_value val;
	val.string = new std::string (std::move (str));
	return option_def_and_value {*match, match_ctx, val};
      }

    default:
      /* Not yet.  */
      gdb_assert_not_reached ("option type not supported");
    }

  return {};
}

/* See cli-option.h.  */

bool
complete_options (completion_tracker &tracker,
		  const char **args,
		  process_options_mode mode,
		  gdb::array_view<const option_def_group> options_group)
{
  const char *text = *args;

  tracker.set_use_custom_word_point (true);

  const char *delimiter = find_end_options_delimiter (text);
  bool have_delimiter = delimiter != nullptr;

  if (text[0] == '-' && (!have_delimiter || *delimiter == '\0'))
    {
      parse_option_completion_info completion_info {nullptr, tracker};

      while (1)
	{
	  *args = skip_spaces (*args);
	  completion_info.word = *args;

	  if (strcmp (*args, "-") == 0)
	    {
	      complete_on_options (options_group, tracker, *args + 1,
				   completion_info.word);
	    }
	  else if (strcmp (*args, "--") == 0)
	    {
	      tracker.add_completion (make_unique_xstrdup (*args));
	    }
	  else if (**args == '-')
	    {
	      std::optional<option_def_and_value> ov
		= parse_option (options_group, mode, have_delimiter,
				args, &completion_info);
	      if (!ov && !tracker.have_completions ())
		{
		  tracker.advance_custom_word_point_by (*args - text);
		  return mode == PROCESS_OPTIONS_REQUIRE_DELIMITER;
		}

	      if (ov
		  && ov->option.type == var_boolean
		  && !ov->value.has_value ())
		{
		  /* Looked like a boolean option, but we failed to
		     parse the value.  If this command requires a
		     delimiter, this value can't be the start of the
		     operands, so return true.  Otherwise, if the
		     command doesn't require a delimiter return false
		     so that the caller tries to complete on the
		     operand.  */
		  tracker.advance_custom_word_point_by (*args - text);
		  return mode == PROCESS_OPTIONS_REQUIRE_DELIMITER;
		}

	      /* If we parsed an option with an argument, and reached
		 the end of the input string with no trailing space,
		 return true, so that our callers don't try to
		 complete anything by themselves.  E.g., this makes it
		 so that with:

		  (gdb) frame apply all -limit 10[TAB]

		 we don't try to complete on command names.  */
	      if (ov
		  && !tracker.have_completions ()
		  && **args == '\0'
		  && *args > text && !isspace ((*args)[-1]))
		{
		  tracker.advance_custom_word_point_by
		    (*args - text);
		  return true;
		}

	      /* If the caller passed in a context, then it is
		 interested in the option argument values.  */
	      if (ov && ov->ctx != nullptr)
		save_option_value_in_ctx (ov);
	    }
	  else
	    {
	      tracker.advance_custom_word_point_by
		(completion_info.word - text);

	      /* If the command requires a delimiter, but we haven't
		 seen one, then return true, so that the caller
		 doesn't try to complete on whatever follows options,
		 which for these commands should only be done if
		 there's a delimiter.  */
	      if (mode == PROCESS_OPTIONS_REQUIRE_DELIMITER
		  && !have_delimiter)
		{
		  /* If we reached the end of the input string, then
		     offer all options, since that's all the user can
		     type (plus "--").  */
		  if (completion_info.word[0] == '\0')
		    complete_on_all_options (tracker, options_group);
		  return true;
		}
	      else
		return false;
	    }

	  if (tracker.have_completions ())
	    {
	      tracker.advance_custom_word_point_by
		(completion_info.word - text);
	      return true;
	    }
	}
    }
  else if (delimiter != nullptr)
    {
      tracker.advance_custom_word_point_by (delimiter - text);
      *args = delimiter;
      return false;
    }

  return false;
}

/* Save the parsed value in the option's context.  */

static void
save_option_value_in_ctx (std::optional<option_def_and_value> &ov)
{
  switch (ov->option.type)
    {
    case var_boolean:
      {
	bool value = ov->value.has_value () ? ov->value->boolean : true;
	*ov->option.var_address.boolean (ov->option, ov->ctx) = value;
      }
      break;
    case var_uinteger:
      *ov->option.var_address.uinteger (ov->option, ov->ctx)
	= ov->value->uinteger;
      break;
    case var_integer:
    case var_pinteger:
      *ov->option.var_address.integer (ov->option, ov->ctx)
	= ov->value->integer;
      break;
    case var_enum:
      *ov->option.var_address.enumeration (ov->option, ov->ctx)
	= ov->value->enumeration;
      break;
    case var_color:
      *ov->option.var_address.color (ov->option, ov->ctx)
	= ov->value->color;
      break;
    case var_string:
    case var_filename:
      *ov->option.var_address.string (ov->option, ov->ctx)
	= std::move (*ov->value->string);
      break;
    default:
      gdb_assert_not_reached ("unhandled option type");
    }
}

/* See cli-option.h.  */

bool
process_options (const char **args,
		 process_options_mode mode,
		 gdb::array_view<const option_def_group> options_group)
{
  if (*args == nullptr)
    return false;

  /* If ARGS starts with "-", look for a "--" sequence.  If one is
     found, then interpret everything up until the "--" as
     'gdb::option'-style command line options.  Otherwise, interpret
     ARGS as possibly the command's operands.  */
  bool have_delimiter = find_end_options_delimiter (*args) != nullptr;

  if (mode == PROCESS_OPTIONS_REQUIRE_DELIMITER && !have_delimiter)
    return false;

  bool processed_any = false;

  while (1)
    {
      *args = skip_spaces (*args);

      auto ov = parse_option (options_group, mode, have_delimiter, args);
      if (!ov)
	{
	  if (processed_any)
	    return true;
	  return false;
	}

      processed_any = true;

      save_option_value_in_ctx (ov);
    }
}

/* Helper for build_help.  Append a fragment of a help string showing
   OPT's possible values.  LEN_AT_START is the length of HELP at the
   start of the current line.  This is used when wrapping is
   needed.  */

static void
append_val_type_str (std::string &help, const option_def &opt,
		     size_t len_at_start)
{
  if (!opt.have_argument)
    return;

  switch (opt.type)
    {
    case var_boolean:
      help += " [on|off]";
      break;
    case var_uinteger:
    case var_integer:
    case var_pinteger:
      {
	help += " NUMBER";
	if (opt.extra_literals != nullptr)
	  for (const literal_def *l = opt.extra_literals;
	       l->literal != nullptr;
	       l++)
	    {
	      help += '|';
	      help += l->literal;
	    }
      }
      break;
    case var_enum:
      {
	help += ' ';
	/* If wrapping is needed, subsequent lines will be indented
	   this amount.  */
	size_t indent = help.length () - len_at_start;
	for (size_t i = 0; opt.enums[i] != nullptr; i++)
	  {
	    if (i != 0)
	      {
		size_t new_len = help.length () + 1 + strlen (opt.enums[i]);

		if (new_len - len_at_start >= cli_help_line_length)
		  {
		    help += "\n";
		    len_at_start = help.length ();

		    help.append (indent, ' ');
		  }
		help += "|";
	      }
	    help += opt.enums[i];
	  }
      }
      break;
    case var_color:
      help += ' ';
      for (size_t i = 0; ui_file_style::basic_color_enums[i]; ++i)
	help.append (ui_file_style::basic_color_enums[i]).append ("|");
      help += "NUMBER|#RRGGBB";
      break;
    case var_string:
      help += " STRING";
      break;
    case var_filename:
      help += " FILENAME";
      break;
    default:
      break;
    }
}

/* Helper for build_help.  Appends an indented version of DOC into
   HELP.  */

static void
append_indented_doc (const char *doc, std::string &help)
{
  const char *p = doc;
  const char *n = strchr (p, '\n');

  while (n != nullptr)
    {
      help += "    ";
      help.append (p, n - p + 1);
      p = n + 1;
      n = strchr (p, '\n');
    }
  help += "    ";
  help += p;
}

/* Fill HELP with an auto-generated "help" string fragment for
   OPTIONS.  */

static void
build_help_option (gdb::array_view<const option_def> options,
		   std::string &help)
{
  std::string buffer;

  for (const auto &o : options)
    {
      if (o.set_doc == nullptr)
	continue;

      size_t initial_len = help.length ();
      help += "  -";
      help += o.name;

      append_val_type_str (help, o, initial_len);
      help += "\n";
      append_indented_doc (o.set_doc, help);
      if (o.help_doc != nullptr)
	{
	  help += "\n";
	  append_indented_doc (o.help_doc, help);
	}
    }
}

/* See cli-option.h.  */

std::string
build_help (const char *help_tmpl,
	    gdb::array_view<const option_def_group> options_group)
{
  bool need_newlines = false;
  std::string help_str;

  const char *p = strstr (help_tmpl, "%OPTIONS%");
  help_str.assign (help_tmpl, p);

  for (const auto &grp : options_group)
    for (const auto &opt : grp.options)
      {
	if (need_newlines)
	  help_str += "\n\n";
	else
	  need_newlines = true;
	build_help_option (opt, help_str);
      }

  p += strlen ("%OPTIONS%");
  help_str.append (p);

  return help_str;
}

/* See cli-option.h.  */

void
add_setshow_cmds_for_options (command_class cmd_class,
			      void *data,
			      gdb::array_view<const option_def> options,
			      struct cmd_list_element **set_list,
			      struct cmd_list_element **show_list)
{
  for (const auto &option : options)
    {
      if (option.type == var_boolean)
	{
	  add_setshow_boolean_cmd (option.name, cmd_class,
				   option.var_address.boolean (option, data),
				   option.set_doc, option.show_doc,
				   option.help_doc,
				   nullptr, option.show_cmd_cb,
				   set_list, show_list);
	}
      else if (option.type == var_uinteger)
	{
	  add_setshow_uinteger_cmd (option.name, cmd_class,
				    option.var_address.uinteger (option, data),
				    option.extra_literals,
				    option.set_doc, option.show_doc,
				    option.help_doc,
				    nullptr, option.show_cmd_cb,
				    set_list, show_list);
	}
      else if (option.type == var_integer)
	{
	  add_setshow_integer_cmd (option.name, cmd_class,
				   option.var_address.integer (option, data),
				   option.extra_literals,
				   option.set_doc, option.show_doc,
				   option.help_doc,
				   nullptr, option.show_cmd_cb,
				   set_list, show_list);
	}
      else if (option.type == var_pinteger)
	{
	  add_setshow_pinteger_cmd (option.name, cmd_class,
				    option.var_address.integer (option, data),
				    option.extra_literals,
				    option.set_doc, option.show_doc,
				    option.help_doc,
				    nullptr, option.show_cmd_cb,
				    set_list, show_list);
	}
      else if (option.type == var_enum)
	{
	  add_setshow_enum_cmd (option.name, cmd_class,
				option.enums,
				option.var_address.enumeration (option, data),
				option.set_doc, option.show_doc,
				option.help_doc,
				nullptr, option.show_cmd_cb,
				set_list, show_list);
	}
      else if (option.type == var_string)
	{
	  add_setshow_string_cmd (option.name, cmd_class,
				  option.var_address.string (option, data),
				  option.set_doc, option.show_doc,
				  option.help_doc,
				  nullptr, option.show_cmd_cb,
				  set_list, show_list);
	}
      else if (option.type == var_filename)
	{
	  add_setshow_filename_cmd (option.name, cmd_class,
				    option.var_address.string (option, data),
				    option.set_doc, option.show_doc,
				    option.help_doc,
				    nullptr, option.show_cmd_cb,
				    set_list, show_list);
	}
      else
	gdb_assert_not_reached ("option type not handled");
    }
}

} /* namespace option */
} /* namespace gdb */
