/* GDB parameters implemented in Python

   Copyright (C) 2008-2012 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 "defs.h"
#include "value.h"
#include "exceptions.h"
#include "python-internal.h"
#include "charset.h"
#include "gdbcmd.h"
#include "cli/cli-decode.h"
#include "completer.h"
#include "language.h"
#include "arch-utils.h"

/* Parameter constants and their values.  */
struct parm_constant
{
  char *name;
  int value;
};

struct parm_constant parm_constants[] =
{
  { "PARAM_BOOLEAN", var_boolean }, /* ARI: var_boolean */
  { "PARAM_AUTO_BOOLEAN", var_auto_boolean },
  { "PARAM_UINTEGER", var_uinteger },
  { "PARAM_INTEGER", var_integer },
  { "PARAM_STRING", var_string },
  { "PARAM_STRING_NOESCAPE", var_string_noescape },
  { "PARAM_OPTIONAL_FILENAME", var_optional_filename },
  { "PARAM_FILENAME", var_filename },
  { "PARAM_ZINTEGER", var_zinteger },
  { "PARAM_ENUM", var_enum },
  { NULL, 0 }
};

/* A union that can hold anything described by enum var_types.  */
union parmpy_variable
{
  /* Hold an integer value, for boolean and integer types.  */
  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.  */
  char *stringval;

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

/* A GDB parameter.  */
struct parmpy_object
{
  PyObject_HEAD

  /* The type of the parameter.  */
  enum var_types type;

  /* 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;
};

typedef struct parmpy_object parmpy_object;

static 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 (PyString_Check (attr_name)
      && ! strcmp (PyString_AsString (attr_name), "value"))
    {
      parmpy_object *self = (parmpy_object *) obj;

      return gdbpy_parameter_value (self->type, &self->value);
    }

  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)
	{
	  xfree (self->value.stringval);
	  if (self->type == var_optional_filename)
	    self->value.stringval = xstrdup ("");
	  else
	    self->value.stringval = NULL;
	}
      else
	{
	  char *string;

	  string = python_string_to_host_string (value);
	  if (string == NULL)
	    return -1;

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

    case var_enum:
      {
	int i;
	char *str;

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

	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))
	    break;
	xfree (str);
	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_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.intval = 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_integer:
    case var_zinteger:
    case var_uinteger:
      {
	long l;
	int ok;

	if (! PyInt_Check (value))
	  {
	    PyErr_SetString (PyExc_RuntimeError, 
			     _("The value must be integer."));
	    return -1;
	  }

	if (! gdb_py_int_as_long (value, &l))
	  return -1;

	if (self->type == var_uinteger)
	  {
	    ok = (l >= 0 && l <= UINT_MAX);
	    if (l == 0)
	      l = UINT_MAX;
	  }
	else if (self->type == var_integer)
	  {
	    ok = (l >= INT_MIN && l <= INT_MAX);
	    if (l == 0)
	      l = INT_MAX;
	  }
	else
	  ok = (l >= INT_MIN && l <= INT_MAX);

	if (! ok)
	  {
	    PyErr_SetString (PyExc_RuntimeError, 
			     _("Range exceeded."));
	    return -1;
	  }

	self->value.intval = (int) l;
	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 (PyString_Check (attr_name)
      && ! strcmp (PyString_AsString (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);
}

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

static char *
get_doc_string (PyObject *object, PyObject *attr)
{
  char *result = NULL;

  if (PyObject_HasAttr (object, attr))
    {
      PyObject *ds_obj = PyObject_GetAttr (object, attr);

      if (ds_obj && gdbpy_is_string (ds_obj))
	{
	  result = python_string_to_host_string (ds_obj);
	  if (result == NULL)
	    gdbpy_print_stack ();
	}
      Py_XDECREF (ds_obj);
    }
  if (! result)
    result = xstrdup (_("This command is not documented."));
  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 char *
call_doc_function (PyObject *obj, PyObject *method, PyObject *arg)
{
  char *data = NULL;
  PyObject *result = PyObject_CallMethodObjArgs (obj, method, arg, NULL);

  if (! result)
    return NULL;

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

  return data;
}

/* A callback function that is registered against the respective
   add_setshow_* set_doc prototype.  This function will either call
   the Python function "get_set_string" or extract the Python
   attribute "set_doc" and return the contents as a string.  If
   neither exist, insert a string indicating the Parameter is not
   documented.  */
static void
get_set_value (char *args, int from_tty,
	       struct cmd_list_element *c)
{
  PyObject *obj = (PyObject *) get_cmd_context (c);
  char *set_doc_string;
  struct cleanup *cleanup = ensure_python_env (get_current_arch (),
					       current_language);
  PyObject *set_doc_func = PyString_FromString ("get_set_string");

  if (! set_doc_func)
    goto error;

  make_cleanup_py_decref (set_doc_func);

  if (PyObject_HasAttr (obj, set_doc_func))
    {
      set_doc_string = call_doc_function (obj, set_doc_func, NULL);
      if (! set_doc_string)
	goto error;
    }
  else
    {
      /* We have to preserve the existing < GDB 7.3 API.  If a
	 callback function does not exist, then attempt to read the
	 set_doc attribute.  */
      set_doc_string  = get_doc_string (obj, set_doc_cst);
    }

  make_cleanup (xfree, set_doc_string);
  fprintf_filtered (gdb_stdout, "%s\n", set_doc_string);

  do_cleanups (cleanup);
  return;

 error:
  gdbpy_print_stack ();
  do_cleanups (cleanup);
  return;
}

/* 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 *) get_cmd_context (c);
  char *show_doc_string = NULL;
  struct cleanup *cleanup = ensure_python_env (get_current_arch (),
					       current_language);
  PyObject *show_doc_func = PyString_FromString ("get_show_string");

  if (! show_doc_func)
    goto error;

  make_cleanup_py_decref (show_doc_func);

  if (PyObject_HasAttr (obj, show_doc_func))
    {
      PyObject *val_obj = PyString_FromString (value);

      if (! val_obj)
	goto error;

      make_cleanup_py_decref (val_obj);

      show_doc_string = call_doc_function (obj, show_doc_func, val_obj);
      if (! show_doc_string)
	goto error;

      make_cleanup (xfree, show_doc_string);

      fprintf_filtered (file, "%s\n", show_doc_string);
    }
  else
    {
      /* We have to preserve the existing < GDB 7.3 API.  If a
	 callback function does not exist, then attempt to read the
	 show_doc attribute.  */
      show_doc_string  = get_doc_string (obj, show_doc_cst);
      make_cleanup (xfree, show_doc_string);
      fprintf_filtered (file, "%s %s\n", show_doc_string, value);
    }

  do_cleanups (cleanup);
  return;

 error:
  gdbpy_print_stack ();
  do_cleanups (cleanup);
  return;
}


/* A helper function that dispatches to the appropriate add_setshow
   function.  */
static void
add_setshow_generic (int parmclass, enum command_class cmdclass,
		     char *cmd_name, parmpy_object *self,
		     char *set_doc, char *show_doc, char *help_doc,
		     struct cmd_list_element **set_list,
		     struct cmd_list_element **show_list)
{
  struct cmd_list_element *param = NULL;
  char *tmp_name = NULL;

  switch (parmclass)
    {
    case var_boolean:

      add_setshow_boolean_cmd (cmd_name, cmdclass,
			       &self->value.intval, set_doc, show_doc,
			       help_doc, get_set_value, get_show_value,
			       set_list, show_list);

      break;

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

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

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

    case var_string:
      add_setshow_string_cmd (cmd_name, 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:
      add_setshow_string_noescape_cmd (cmd_name, 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:
      add_setshow_optional_filename_cmd (cmd_name, cmdclass,
					 &self->value.stringval, set_doc,
					 show_doc, help_doc, get_set_value,
					 get_show_value, set_list,
					 show_list);
      break;

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

    case var_zinteger:
      add_setshow_zinteger_cmd (cmd_name, cmdclass,
				&self->value.intval, set_doc, show_doc,
				help_doc, get_set_value, get_show_value,
				set_list, show_list);
      break;

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

  /* Lookup created parameter, and register Python object against the
     parameter context.  Perform this task against both lists.  */
  tmp_name = cmd_name;
  param = lookup_cmd (&tmp_name, *show_list, "", 0, 1);
  if (param)
    set_cmd_context (param, self);

  tmp_name = cmd_name;
  param = lookup_cmd (&tmp_name, *set_list, "", 0, 1);
  if (param)
    set_cmd_context (param, self);
}

/* 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;
  struct cleanup *back_to;

  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;
    }

  self->enumeration = xmalloc ((size + 1) * sizeof (char *));
  back_to = make_cleanup (free_current_contents, &self->enumeration);
  memset (self->enumeration, 0, (size + 1) * sizeof (char *));

  for (i = 0; i < size; ++i)
    {
      PyObject *item = PySequence_GetItem (enum_values, i);

      if (! item)
	{
	  do_cleanups (back_to);
	  return 0;
	}
      if (! gdbpy_is_string (item))
	{
	  do_cleanups (back_to);
	  PyErr_SetString (PyExc_RuntimeError, 
			   _("The enumeration item not a string."));
	  return 0;
	}
      self->enumeration[i] = python_string_to_host_string (item);
      if (self->enumeration[i] == NULL)
	{
	  do_cleanups (back_to);
	  return 0;
	}
      make_cleanup (xfree, (char *) self->enumeration[i]);
    }

  discard_cleanups (back_to);
  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;
  char *set_doc, *show_doc, *doc;
  char *cmd_name;
  int parmclass, cmdtype;
  PyObject *enum_values = NULL;
  struct cmd_list_element **set_list, **show_list;
  volatile struct gdb_exception except;

  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 != var_boolean /* ARI: var_boolean */
      && parmclass != var_auto_boolean
      && parmclass != var_uinteger && parmclass != var_integer
      && parmclass != var_string && parmclass != var_string_noescape
      && parmclass != var_optional_filename && parmclass != var_filename
      && parmclass != var_zinteger && parmclass != var_enum)
    {
      PyErr_SetString (PyExc_RuntimeError,
		       _("Invalid parameter class argument."));
      return -1;
    }

  if (enum_values && parmclass != var_enum)
    {
      PyErr_SetString (PyExc_RuntimeError,
		       _("Only PARAM_ENUM accepts a fourth argument."));
      return -1;
    }
  if (parmclass == var_enum)
    {
      if (! compute_enum_values (obj, enum_values))
	return -1;
    }
  else
    obj->enumeration = NULL;
  obj->type = (enum var_types) parmclass;
  memset (&obj->value, 0, sizeof (obj->value));

  cmd_name = gdbpy_parse_command_name (name, &set_list,
				       &setlist);

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

  set_doc = get_doc_string (self, set_doc_cst);
  show_doc = get_doc_string (self, show_doc_cst);
  doc = get_doc_string (self, gdbpy_doc_cst);

  Py_INCREF (self);

  TRY_CATCH (except, RETURN_MASK_ALL)
    {
      add_setshow_generic (parmclass, (enum command_class) cmdtype,
			   cmd_name, obj,
			   set_doc, show_doc,
			   doc, set_list, show_list);
    }
  if (except.reason < 0)
    {
      xfree (cmd_name);
      xfree (set_doc);
      xfree (show_doc);
      xfree (doc);
      Py_DECREF (self);
      PyErr_Format (except.reason == RETURN_QUIT
		    ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
		    "%s", except.message);
      return -1;
    }
  return 0;
}



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

  parmpy_object_type.tp_new = PyType_GenericNew;
  if (PyType_Ready (&parmpy_object_type) < 0)
    return;

  set_doc_cst = PyString_FromString ("set_doc");
  if (! set_doc_cst)
    return;
  show_doc_cst = PyString_FromString ("show_doc");
  if (! show_doc_cst)
    return;

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

  Py_INCREF (&parmpy_object_type);
  PyModule_AddObject (gdb_module, "Parameter",
		      (PyObject *) &parmpy_object_type);
}



static PyTypeObject parmpy_object_type =
{
  PyObject_HEAD_INIT (NULL)
  0,				  /*ob_size*/
  "gdb.Parameter",		  /*tp_name*/
  sizeof (parmpy_object),	  /*tp_basicsize*/
  0,				  /*tp_itemsize*/
  0,				  /*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 */
};
