/* GDB parameters implemented in Python

   Copyright (C) 2008-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 "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
{
  PyObject_HEAD

  /* 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
    CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("parmpy_object");

/* 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 (! strcmp (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 && !strcmp ("unlimited", l->literal))
			|| (s != nullptr && !strcmp (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.reset (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 CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
gdbpy_initialize_parameters (void)
{
  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 */
};
