/* GDB parameters implemented in Python

   Copyright (C) 2008-2026 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 "value.h"
#include "python-internal.h"
#include "charset.h"
#include "cli/cli-cmds.h"
#include "cli/cli-decode.h"
#include "completer.h"
#include "language.h"
#include "arch-utils.h"
#include "py-color.h"

/* Python parameter types as in PARM_CONSTANTS below.  */

enum py_param_types
{
  param_boolean,
  param_auto_boolean,
  param_uinteger,
  param_integer,
  param_string,
  param_string_noescape,
  param_optional_filename,
  param_filename,
  param_zinteger,
  param_zuinteger,
  param_zuinteger_unlimited,
  param_enum,
  param_color,
};

/* Translation from Python parameters to GDB variable types.  Keep in the
   same order as PARAM_TYPES due to C++'s lack of designated initializers.  */

static const struct
{
  /* The type of the parameter.  */
  enum var_types type;

  /* Extra literals, such as `unlimited', accepted in lieu of a number.  */
  const literal_def *extra_literals;
}
param_to_var[] =
{
  { var_boolean },
  { var_auto_boolean },
  { var_uinteger, uinteger_unlimited_literals },
  { var_integer, integer_unlimited_literals },
  { var_string },
  { var_string_noescape },
  { var_optional_filename },
  { var_filename },
  { var_integer },
  { var_uinteger },
  { var_pinteger, pinteger_unlimited_literals },
  { var_enum },
  { var_color }
};

/* Parameter constants and their values.  */
static struct {
  const char *name;
  int value;
} parm_constants[] =
{
  { "PARAM_BOOLEAN", param_boolean }, /* ARI: param_boolean */
  { "PARAM_AUTO_BOOLEAN", param_auto_boolean },
  { "PARAM_UINTEGER", param_uinteger },
  { "PARAM_INTEGER", param_integer },
  { "PARAM_STRING", param_string },
  { "PARAM_STRING_NOESCAPE", param_string_noescape },
  { "PARAM_OPTIONAL_FILENAME", param_optional_filename },
  { "PARAM_FILENAME", param_filename },
  { "PARAM_ZINTEGER", param_zinteger },
  { "PARAM_ZUINTEGER", param_zuinteger },
  { "PARAM_ZUINTEGER_UNLIMITED", param_zuinteger_unlimited },
  { "PARAM_ENUM", param_enum },
  { "PARAM_COLOR", param_color },
  { NULL, 0 }
};

/* A union that can hold anything described by enum var_types.  */
union parmpy_variable
{
  /* Hold a boolean value.  */
  bool boolval;

  /* Hold an integer value.  */
  int intval;

  /* Hold an auto_boolean.  */
  enum auto_boolean autoboolval;

  /* Hold an unsigned integer value, for uinteger.  */
  unsigned int uintval;

  /* Hold a string, for the various string types.  The std::string is
     new-ed.  */
  std::string *stringval;

  /* Hold a string, for enums.  */
  const char *cstringval;

  /* Hold a color.  */
  ui_file_style::color color;
};

/* A GDB parameter.  */
struct parmpy_object : public PyObject
{
  /* The type of the parameter.  */
  enum var_types type;

  /* Extra literals, such as `unlimited', accepted in lieu of a number.  */
  const literal_def *extra_literals;

  /* The value of the parameter.  */
  union parmpy_variable value;

  /* For an enum command, the possible values.  The vector is
     allocated with xmalloc, as is each element.  It is
     NULL-terminated.  */
  const char **enumeration;
};

/* Wraps a setting around an existing parmpy_object.  This abstraction
   is used to manipulate the value in S->VALUE in a type safe manner using
   the setting interface.  */

static setting
make_setting (parmpy_object *s)
{
  enum var_types type = s->type;

  if (var_type_uses<bool> (type))
    return setting (type, &s->value.boolval);
  else if (var_type_uses<int> (type))
    return setting (type, &s->value.intval, s->extra_literals);
  else if (var_type_uses<auto_boolean> (type))
    return setting (type, &s->value.autoboolval);
  else if (var_type_uses<unsigned int> (type))
    return setting (type, &s->value.uintval, s->extra_literals);
  else if (var_type_uses<std::string> (type))
    return setting (type, s->value.stringval);
  else if (var_type_uses<const char *> (type))
    return setting (type, &s->value.cstringval);
  else if (var_type_uses<ui_file_style::color> (s->type))
    return setting (s->type, &s->value.color);
  else
    gdb_assert_not_reached ("unhandled var type");
}

extern PyTypeObject parmpy_object_type;

/* Some handy string constants.  */
static PyObject *set_doc_cst;
static PyObject *show_doc_cst;



/* Get an attribute.  */
static PyObject *
get_attr (PyObject *obj, PyObject *attr_name)
{
  if (PyUnicode_Check (attr_name)
      && ! PyUnicode_CompareWithASCIIString (attr_name, "value"))
    {
      parmpy_object *self = (parmpy_object *) obj;

      return gdbpy_parameter_value (make_setting (self));
    }

  return PyObject_GenericGetAttr (obj, attr_name);
}

/* Set a parameter value from a Python value.  Return 0 on success.  Returns
   -1 on error, with a python exception set.  */
static int
set_parameter_value (parmpy_object *self, PyObject *value)
{
  int cmp;

  switch (self->type)
    {
    case var_string:
    case var_string_noescape:
    case var_optional_filename:
    case var_filename:
      if (! gdbpy_is_string (value)
	  && (self->type == var_filename
	      || value != Py_None))
	{
	  PyErr_SetString (PyExc_RuntimeError,
			   _("String required for filename."));

	  return -1;
	}
      if (value == Py_None)
	self->value.stringval->clear ();
      else
	{
	  gdb::unique_xmalloc_ptr<char>
	    string (python_string_to_host_string (value));
	  if (string == NULL)
	    return -1;

	  *self->value.stringval = string.get ();
	}
      break;

    case var_enum:
      {
	int i;

	if (! gdbpy_is_string (value))
	  {
	    PyErr_SetString (PyExc_RuntimeError,
			     _("ENUM arguments must be a string."));
	    return -1;
	  }

	gdb::unique_xmalloc_ptr<char>
	  str (python_string_to_host_string (value));
	if (str == NULL)
	  return -1;
	for (i = 0; self->enumeration[i]; ++i)
	  if (streq (self->enumeration[i], str.get ()))
	    break;
	if (! self->enumeration[i])
	  {
	    PyErr_SetString (PyExc_RuntimeError,
			     _("The value must be member of an enumeration."));
	    return -1;
	  }
	self->value.cstringval = self->enumeration[i];
	break;
      }

    case var_color:
      {
	if (gdbpy_is_color (value))
	  self->value.color = gdbpy_get_color (value);
	else
	  {
	    PyErr_SetString (PyExc_RuntimeError,
			     _("color argument must be a gdb.Color object."));
	    return -1;
	  }
      }
      break;

    case var_boolean:
      if (! PyBool_Check (value))
	{
	  PyErr_SetString (PyExc_RuntimeError,
			   _("A boolean argument is required."));
	  return -1;
	}
      cmp = PyObject_IsTrue (value);
      if (cmp < 0)
	  return -1;
      self->value.boolval = cmp;
      break;

    case var_auto_boolean:
      if (! PyBool_Check (value) && value != Py_None)
	{
	  PyErr_SetString (PyExc_RuntimeError,
			   _("A boolean or None is required"));
	  return -1;
	}

      if (value == Py_None)
	self->value.autoboolval = AUTO_BOOLEAN_AUTO;
      else
	{
	  cmp = PyObject_IsTrue (value);
	  if (cmp < 0 )
	    return -1;
	  if (cmp == 1)
	    self->value.autoboolval = AUTO_BOOLEAN_TRUE;
	  else
	    self->value.autoboolval = AUTO_BOOLEAN_FALSE;
	}
      break;

    case var_uinteger:
    case var_integer:
    case var_pinteger:
      {
	const literal_def *extra_literals = self->extra_literals;
	enum tribool allowed = TRIBOOL_UNKNOWN;
	enum var_types var_type = self->type;
	std::string buffer = "";
	size_t count = 0;
	LONGEST val;

	if (extra_literals != nullptr)
	  {
	    gdb::unique_xmalloc_ptr<char>
	      str (python_string_to_host_string (value));
	    const char *s = str != nullptr ? str.get () : nullptr;
	    PyErr_Clear ();

	    for (const literal_def *l = extra_literals;
		 l->literal != nullptr;
		 l++, count++)
	      {
		if (count != 0)
		  buffer += ", ";
		buffer = buffer + "'" + l->literal + "'";
		if (allowed == TRIBOOL_UNKNOWN
		    && ((value == Py_None && streq ("unlimited", l->literal))
			|| (s != nullptr && streq (s, l->literal))))
		  {
		    val = l->use;
		    allowed = TRIBOOL_TRUE;
		  }
	      }
	  }

	if (allowed == TRIBOOL_UNKNOWN)
	  {
	    val = PyLong_AsLongLong (value);

	    if (PyErr_Occurred ())
	      {
		if (extra_literals == nullptr)
		  PyErr_SetString (PyExc_RuntimeError,
				   _("The value must be integer."));
		else if (count > 1)
		  PyErr_SetString (PyExc_RuntimeError,
				   string_printf (_("integer or one of: %s"),
						  buffer.c_str ()).c_str ());
		else
		  PyErr_SetString (PyExc_RuntimeError,
				   string_printf (_("integer or %s"),
						  buffer.c_str ()).c_str ());
		return -1;
	      }


	    if (extra_literals != nullptr)
	      for (const literal_def *l = extra_literals;
		   l->literal != nullptr;
		   l++)
		{
		  if (l->val.has_value () && val == *l->val)
		    {
		      allowed = TRIBOOL_TRUE;
		      val = l->use;
		      break;
		    }
		  else if (val == l->use)
		    allowed = TRIBOOL_FALSE;
		}
	    }

	if (allowed == TRIBOOL_UNKNOWN)
	  {
	    if (val > UINT_MAX || val < INT_MIN
		|| (var_type == var_uinteger && val < 0)
		|| (var_type == var_integer && val > INT_MAX)
		|| (var_type == var_pinteger && val < 0)
		|| (var_type == var_pinteger && val > INT_MAX))
	      allowed = TRIBOOL_FALSE;
	  }
	if (allowed == TRIBOOL_FALSE)
	  {
	    PyErr_SetString (PyExc_RuntimeError,
			     _("Range exceeded."));
	    return -1;
	  }

	if (self->type == var_uinteger)
	  self->value.uintval = (unsigned) val;
	else
	  self->value.intval = (int) val;
	break;
      }

    default:
      PyErr_SetString (PyExc_RuntimeError,
		       _("Unhandled type in parameter value."));
      return -1;
    }

  return 0;
}

/* Set an attribute.  Returns -1 on error, with a python exception set.  */
static int
set_attr (PyObject *obj, PyObject *attr_name, PyObject *val)
{
  if (PyUnicode_Check (attr_name)
      && ! PyUnicode_CompareWithASCIIString (attr_name, "value"))
    {
      if (!val)
	{
	  PyErr_SetString (PyExc_RuntimeError,
			   _("Cannot delete a parameter's value."));
	  return -1;
	}
      return set_parameter_value ((parmpy_object *) obj, val);
    }

  return PyObject_GenericSetAttr (obj, attr_name, val);
}

/* Build up the path to command C, but drop the first component of the
   command prefix.  This is only intended for use with the set/show
   parameters this file deals with, the first prefix should always be
   either 'set' or 'show'.

   As an example, if this full command is 'set prefix_a prefix_b command'
   this function will return the string 'prefix_a prefix_b command'.  */

static std::string
full_cmd_name_without_first_prefix (struct cmd_list_element *c)
{
  std::vector<std::string> components
    = c->command_components ();
  gdb_assert (components.size () > 1);
  std::string result = components[1];
  for (int i = 2; i < components.size (); ++i)
    result += " " + components[i];
  return result;
}

/* The different types of documentation string.  */

enum doc_string_type
{
  doc_string_set,
  doc_string_show,
  doc_string_description
};

/* A helper function which returns a documentation string for an
   object. */

static gdb::unique_xmalloc_ptr<char>
get_doc_string (PyObject *object, enum doc_string_type doc_type,
		const char *cmd_name)
{
  gdb::unique_xmalloc_ptr<char> result;

  PyObject *attr = nullptr;
  switch (doc_type)
    {
    case doc_string_set:
      attr = set_doc_cst;
      break;
    case doc_string_show:
      attr = show_doc_cst;
      break;
    case doc_string_description:
      attr = gdbpy_doc_cst;
      break;
    }
  gdb_assert (attr != nullptr);

  if (PyObject_HasAttr (object, attr))
    {
      gdbpy_ref<> ds_obj (PyObject_GetAttr (object, attr));

      if (ds_obj != NULL && gdbpy_is_string (ds_obj.get ()))
	{
	  result = python_string_to_host_string (ds_obj.get ());
	  if (result == NULL)
	    gdbpy_print_stack ();
	  else if (doc_type == doc_string_description)
	    result = gdbpy_fix_doc_string_indentation (std::move (result));
	}
    }

  /* For the set/show docs, if these strings are empty then we set then to
     a non-empty string.  This ensures that the command has some sane
     documentation for its 'help' text.  */
  if (result == nullptr
      || (doc_type != doc_string_description && *result == '\0'))
    {
      if (doc_type == doc_string_description)
	result = make_unique_xstrdup (_("This command is not documented."));
      else
	{
	  if (doc_type == doc_string_show)
	    result = xstrprintf (_("Show the current value of '%s'."),
				 cmd_name);
	  else
	    result = xstrprintf (_("Set the current value of '%s'."),
				 cmd_name);
	}
    }
  return result;
}

/* Helper function which will execute a METHOD in OBJ passing the
   argument ARG.  ARG can be NULL.  METHOD should return a Python
   string.  If this function returns NULL, there has been an error and
   the appropriate exception set.  */
static gdb::unique_xmalloc_ptr<char>
call_doc_function (PyObject *obj, PyObject *method, PyObject *arg)
{
  gdb::unique_xmalloc_ptr<char> data;
  gdbpy_ref<> result (PyObject_CallMethodObjArgs (obj, method, arg, NULL));

  if (result == NULL)
    return NULL;

  if (gdbpy_is_string (result.get ()))
    {
      data = python_string_to_host_string (result.get ());
      if (! data)
	return NULL;
    }
  else
    {
      PyErr_SetString (PyExc_RuntimeError,
		       _("Parameter must return a string value."));
      return NULL;
    }

  return data;
}

/* A callback function that is registered against the respective
   add_setshow_* set_doc prototype.  This function calls the Python function
   "get_set_string" if it exists, which will return a string.  That string
   is then printed.  If "get_set_string" does not exist, or returns an
   empty string, then nothing is printed.  */
static void
get_set_value (const char *args, int from_tty,
	       struct cmd_list_element *c)
{
  PyObject *obj = (PyObject *) c->context ();
  gdb::unique_xmalloc_ptr<char> set_doc_string;

  gdbpy_enter enter_py;
  gdbpy_ref<> set_doc_func (PyUnicode_FromString ("get_set_string"));

  if (set_doc_func == NULL)
    {
      gdbpy_print_stack ();
      return;
    }

  if (PyObject_HasAttr (obj, set_doc_func.get ()))
    {
      set_doc_string = call_doc_function (obj, set_doc_func.get (), NULL);
      if (! set_doc_string)
	gdbpy_handle_exception ();
    }

  const char *str = set_doc_string.get ();
  if (str != nullptr && str[0] != '\0')
    gdb_printf ("%s\n", str);
}

/* A callback function that is registered against the respective
   add_setshow_* show_doc prototype.  This function will either call
   the Python function "get_show_string" or extract the Python
   attribute "show_doc" and return the contents as a string.  If
   neither exist, insert a string indicating the Parameter is not
   documented.  */
static void
get_show_value (struct ui_file *file, int from_tty,
		struct cmd_list_element *c,
		const char *value)
{
  PyObject *obj = (PyObject *) c->context ();
  gdb::unique_xmalloc_ptr<char> show_doc_string;

  gdbpy_enter enter_py;
  gdbpy_ref<> show_doc_func (PyUnicode_FromString ("get_show_string"));

  if (show_doc_func == NULL)
    {
      gdbpy_print_stack ();
      return;
    }

  if (PyObject_HasAttr (obj, show_doc_func.get ()))
    {
      gdbpy_ref<> val_obj (PyUnicode_FromString (value));

      if (val_obj == NULL)
	{
	  gdbpy_print_stack ();
	  return;
	}

      show_doc_string = call_doc_function (obj, show_doc_func.get (),
					   val_obj.get ());
      if (! show_doc_string)
	{
	  gdbpy_print_stack ();
	  return;
	}

      gdb_printf (file, "%s\n", show_doc_string.get ());
    }
  else
    {
      /* If there is no 'get_show_string' callback then we want to show
	 something sensible here.  In older versions of GDB (< 7.3) we
	 didn't support 'get_show_string', and instead we just made use of
	 GDB's builtin use of the show_doc.  However, GDB's builtin
	 show_doc adjustment is not i18n friendly, so, instead, we just
	 print this generic string.  */
      std::string cmd_path = full_cmd_name_without_first_prefix (c);
      gdb_printf (file, _("The current value of '%s' is \"%s\".\n"),
		  cmd_path.c_str (), value);
    }
}


/* A helper function that dispatches to the appropriate add_setshow
   function.  */
static void
add_setshow_generic (enum var_types type, const literal_def *extra_literals,
		     enum command_class cmdclass,
		     gdb::unique_xmalloc_ptr<char> cmd_name,
		     parmpy_object *self,
		     const char *set_doc, const char *show_doc,
		     const char *help_doc,
		     struct cmd_list_element **set_list,
		     struct cmd_list_element **show_list)
{
  set_show_commands commands;

  switch (type)
    {
    case var_boolean:
      commands = add_setshow_boolean_cmd (cmd_name.get (), cmdclass,
					  &self->value.boolval, set_doc,
					  show_doc, help_doc, get_set_value,
					  get_show_value, set_list, show_list);

      break;

    case var_auto_boolean:
      commands = add_setshow_auto_boolean_cmd (cmd_name.get (), cmdclass,
					       &self->value.autoboolval,
					       set_doc, show_doc, help_doc,
					       get_set_value, get_show_value,
					       set_list, show_list);
      break;

    case var_uinteger:
      commands = add_setshow_uinteger_cmd (cmd_name.get (), cmdclass,
					   &self->value.uintval,
					   extra_literals, set_doc,
					   show_doc, help_doc, get_set_value,
					   get_show_value, set_list, show_list);
      break;

    case var_integer:
      commands = add_setshow_integer_cmd (cmd_name.get (), cmdclass,
					  &self->value.intval,
					  extra_literals, set_doc,
					  show_doc, help_doc, get_set_value,
					  get_show_value, set_list, show_list);
      break;

    case var_pinteger:
      commands = add_setshow_pinteger_cmd (cmd_name.get (), cmdclass,
					   &self->value.intval,
					   extra_literals, set_doc,
					   show_doc, help_doc, get_set_value,
					   get_show_value, set_list, show_list);
      break;

    case var_string:
      commands = add_setshow_string_cmd (cmd_name.get (), cmdclass,
					 self->value.stringval, set_doc,
					 show_doc, help_doc, get_set_value,
					 get_show_value, set_list, show_list);
      break;

    case var_string_noescape:
      commands = add_setshow_string_noescape_cmd (cmd_name.get (), cmdclass,
						  self->value.stringval,
						  set_doc, show_doc, help_doc,
						  get_set_value, get_show_value,
						  set_list, show_list);
      break;

    case var_optional_filename:
      commands = add_setshow_optional_filename_cmd (cmd_name.get (), cmdclass,
						    self->value.stringval,
						    set_doc, show_doc, help_doc,
						    get_set_value,
						    get_show_value, set_list,
						    show_list);
      break;

    case var_filename:
      commands = add_setshow_filename_cmd (cmd_name.get (), cmdclass,
					   self->value.stringval, set_doc,
					   show_doc, help_doc, get_set_value,
					   get_show_value, set_list, show_list);
      break;

    case var_enum:
      /* Initialize the value, just in case.  */
      self->value.cstringval = self->enumeration[0];
      commands = add_setshow_enum_cmd (cmd_name.get (), cmdclass,
				       self->enumeration,
				       &self->value.cstringval, set_doc,
				       show_doc, help_doc, get_set_value,
				       get_show_value, set_list, show_list);
      break;

    case var_color:
      /* Initialize the value, just in case.  */
      self->value.color = ui_file_style::NONE;
      commands = add_setshow_color_cmd (cmd_name.get (), cmdclass,
					&self->value.color, set_doc,
					show_doc, help_doc, get_set_value,
					get_show_value, set_list, show_list);
      break;

    default:
      gdb_assert_not_reached ("Unhandled parameter class.");
    }

  /* Register Python objects in both commands' context.  */
  commands.set->set_context (self);
  commands.show->set_context (self);

  /* We (unfortunately) currently leak the command name.  */
  cmd_name.release ();
}

/* A helper which computes enum values.  Returns 1 on success.  Returns 0 on
   error, with a python exception set.  */
static int
compute_enum_values (parmpy_object *self, PyObject *enum_values)
{
  Py_ssize_t size, i;

  if (! enum_values)
    {
      PyErr_SetString (PyExc_RuntimeError,
		       _("An enumeration is required for PARAM_ENUM."));
      return 0;
    }

  if (! PySequence_Check (enum_values))
    {
      PyErr_SetString (PyExc_RuntimeError,
		       _("The enumeration is not a sequence."));
      return 0;
    }

  size = PySequence_Size (enum_values);
  if (size < 0)
    return 0;
  if (size == 0)
    {
      PyErr_SetString (PyExc_RuntimeError,
		       _("The enumeration is empty."));
      return 0;
    }

  gdb_argv holder (XCNEWVEC (char *, size + 1));
  char **enumeration = holder.get ();

  for (i = 0; i < size; ++i)
    {
      gdbpy_ref<> item (PySequence_GetItem (enum_values, i));

      if (item == NULL)
	return 0;
      if (! gdbpy_is_string (item.get ()))
	{
	  PyErr_SetString (PyExc_RuntimeError,
			   _("The enumeration item not a string."));
	  return 0;
	}
      enumeration[i] = python_string_to_host_string (item.get ()).release ();
      if (enumeration[i] == NULL)
	return 0;
    }

  self->enumeration = const_cast<const char**> (holder.release ());
  return 1;
}

/* Object initializer; sets up gdb-side structures for command.

   Use: __init__(NAME, CMDCLASS, PARMCLASS, [ENUM])

   NAME is the name of the parameter.  It may consist of multiple
   words, in which case the final word is the name of the new command,
   and earlier words must be prefix commands.

   CMDCLASS is the kind of command.  It should be one of the COMMAND_*
   constants defined in the gdb module.

   PARMCLASS is the type of the parameter.  It should be one of the
   PARAM_* constants defined in the gdb module.

   If PARMCLASS is PARAM_ENUM, then the final argument should be a
   collection of strings.  These strings are the valid values for this
   parameter.

   The documentation for the parameter is taken from the doc string
   for the python class.

   Returns -1 on error, with a python exception set.  */

static int
parmpy_init (PyObject *self, PyObject *args, PyObject *kwds)
{
  parmpy_object *obj = (parmpy_object *) self;
  const char *name;
  gdb::unique_xmalloc_ptr<char> set_doc, show_doc, doc;
  int parmclass, cmdtype;
  PyObject *enum_values = NULL;
  struct cmd_list_element **set_list, **show_list;
  const literal_def *extra_literals;
  enum var_types type;

  if (! PyArg_ParseTuple (args, "sii|O", &name, &cmdtype, &parmclass,
			  &enum_values))
    return -1;

  if (cmdtype != no_class && cmdtype != class_run
      && cmdtype != class_vars && cmdtype != class_stack
      && cmdtype != class_files && cmdtype != class_support
      && cmdtype != class_info && cmdtype != class_breakpoint
      && cmdtype != class_trace && cmdtype != class_obscure
      && cmdtype != class_maintenance)
    {
      PyErr_Format (PyExc_RuntimeError, _("Invalid command class argument."));
      return -1;
    }

  if (parmclass != param_boolean /* ARI: param_boolean */
      && parmclass != param_auto_boolean
      && parmclass != param_uinteger && parmclass != param_integer
      && parmclass != param_string && parmclass != param_string_noescape
      && parmclass != param_optional_filename && parmclass != param_filename
      && parmclass != param_zinteger && parmclass != param_zuinteger
      && parmclass != param_zuinteger_unlimited && parmclass != param_enum
      && parmclass != param_color)
    {
      PyErr_SetString (PyExc_RuntimeError,
		       _("Invalid parameter class argument."));
      return -1;
    }

  if (enum_values && parmclass != param_enum)
    {
      PyErr_SetString (PyExc_RuntimeError,
		       _("Only PARAM_ENUM accepts a fourth argument."));
      return -1;
    }
  if (parmclass == param_enum)
    {
      if (! compute_enum_values (obj, enum_values))
	return -1;
    }
  else
    obj->enumeration = NULL;
  type = param_to_var[parmclass].type;
  extra_literals = param_to_var[parmclass].extra_literals;
  obj->type = type;
  obj->extra_literals = extra_literals;
  obj->value = {}; /* zeros initialization */

  if (var_type_uses<std::string> (obj->type))
    obj->value.stringval = new std::string;

  gdb::unique_xmalloc_ptr<char> cmd_name
    = gdbpy_parse_command_name (name, &set_list, &setlist);
  if (cmd_name == nullptr)
    return -1;

  cmd_name = gdbpy_parse_command_name (name, &show_list, &showlist);
  if (cmd_name == nullptr)
    return -1;

  set_doc = get_doc_string (self, doc_string_set, name);
  show_doc = get_doc_string (self, doc_string_show, name);
  doc = get_doc_string (self, doc_string_description, cmd_name.get ());

  /* The set/show docs should always be a non-empty string.  */
  gdb_assert (set_doc != nullptr && *set_doc != '\0');
  gdb_assert (show_doc != nullptr && *show_doc != '\0');

  /* For the DOC string only, if it is the empty string, then we convert it
     to NULL.  This means GDB will not even display a blank line for this
     part of the help text, instead the set/show line is all the user will
     get.  */
  gdb_assert (doc != nullptr);
  if (*doc == '\0')
    doc = nullptr;

  Py_INCREF (self);

  try
    {
      add_setshow_generic (type, extra_literals,
			   (enum command_class) cmdtype,
			   std::move (cmd_name), obj,
			   set_doc.get (), show_doc.get (),
			   doc.get (), set_list, show_list);
    }
  catch (const gdb_exception &except)
    {
      Py_DECREF (self);
      return gdbpy_handle_gdb_exception (-1, except);
    }

  return 0;
}

/* Deallocate function for a gdb.Parameter.  */

static void
parmpy_dealloc (PyObject *obj)
{
  parmpy_object *parm_obj = (parmpy_object *) obj;

  if (var_type_uses<std::string> (parm_obj->type))
    delete parm_obj->value.stringval;
  else if (var_type_uses<ui_file_style::color> (parm_obj->type))
    parm_obj->value.color.~color();
}

/* Initialize the 'parameters' module.  */
static int
gdbpy_initialize_parameters ()
{
  int i;

  parmpy_object_type.tp_new = PyType_GenericNew;
  if (gdbpy_type_ready (&parmpy_object_type) < 0)
    return -1;

  set_doc_cst = PyUnicode_FromString ("set_doc");
  if (! set_doc_cst)
    return -1;
  show_doc_cst = PyUnicode_FromString ("show_doc");
  if (! show_doc_cst)
    return -1;

  for (i = 0; parm_constants[i].name; ++i)
    {
      if (PyModule_AddIntConstant (gdb_module,
				   parm_constants[i].name,
				   parm_constants[i].value) < 0)
	return -1;
    }

  return 0;
}

GDBPY_INITIALIZE_FILE (gdbpy_initialize_parameters);



PyTypeObject parmpy_object_type =
{
  PyVarObject_HEAD_INIT (NULL, 0)
  "gdb.Parameter",		  /*tp_name*/
  sizeof (parmpy_object),	  /*tp_basicsize*/
  0,				  /*tp_itemsize*/
  parmpy_dealloc,		  /*tp_dealloc*/
  0,				  /*tp_print*/
  0,				  /*tp_getattr*/
  0,				  /*tp_setattr*/
  0,				  /*tp_compare*/
  0,				  /*tp_repr*/
  0,				  /*tp_as_number*/
  0,				  /*tp_as_sequence*/
  0,				  /*tp_as_mapping*/
  0,				  /*tp_hash */
  0,				  /*tp_call*/
  0,				  /*tp_str*/
  get_attr,			  /*tp_getattro*/
  set_attr,			  /*tp_setattro*/
  0,				  /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
  "GDB parameter object",	  /* tp_doc */
  0,				  /* tp_traverse */
  0,				  /* tp_clear */
  0,				  /* tp_richcompare */
  0,				  /* tp_weaklistoffset */
  0,				  /* tp_iter */
  0,				  /* tp_iternext */
  0,				  /* tp_methods */
  0,				  /* tp_members */
  0,				  /* tp_getset */
  0,				  /* tp_base */
  0,				  /* tp_dict */
  0,				  /* tp_descr_get */
  0,				  /* tp_descr_set */
  0,				  /* tp_dictoffset */
  parmpy_init,			  /* tp_init */
  0,				  /* tp_alloc */
};
