/* Python interface to ui_file_style objects.

   Copyright (C) 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 "python-internal.h"
#include "ui-style.h"
#include "py-color.h"
#include "cli/cli-decode.h"
#include "cli/cli-style.h"
#include "top.h"

/* Intensity constants and their values.  */
static struct {
  const char *name;
  ui_file_style::intensity value;
} intensity_constants[] =
{
  { "INTENSITY_NORMAL", ui_file_style::NORMAL },
  { "INTENSITY_DIM", ui_file_style::DIM },
  { "INTENSITY_BOLD", ui_file_style::BOLD }
};

/* A style.  */
struct style_object
{
  PyObject_HEAD

  /* Underlying style, only valid when STYLE_NAME is NULL.  */
  ui_file_style style;

  /* The name of the style.  Can be NULL, in which case STYLE holds the
     style value.  */
  char *style_name;
};

extern PyTypeObject style_object_type;

/* Initialize the 'style' module.  */

static int
gdbpy_initialize_style ()
{
  for (auto &pair : intensity_constants)
    if (PyModule_AddIntConstant (gdb_module, pair.name,
				 static_cast<long> (pair.value)) < 0)
      return -1;

  return gdbpy_type_ready (&style_object_type, gdb_module);
}

/* Free any resources help by SELF, and reset points to NULL.  */

static void
stylepy_free_resources (PyObject *self)
{
  style_object *style = (style_object *) self;

  xfree (style->style_name);
  style->style_name = nullptr;
}

/* gdb.Style deallocation method.  */

static void
stylepy_dealloc (PyObject *self)
{
  stylepy_free_resources (self);
  Py_TYPE (self)->tp_free (self);
}

/* Find style NAME and return it.  If NAME cannot be found then an empty
   optional is returned, and a Python error will be set.

   If HAS_INTENSITY_PTR is not NULL, then, if NAME is found,
   *HAS_INTENSITY_PTR will be set true if NAME has an "intensity"
   sub-command, and set false otherwise.  If NAME is not found then
   *HAS_INTENSITY_PTR is left unchanged.

   If FOUND_CMD_PTR is not NULL, then, if NAME is found, *FOUND_CMD_PTR is
   set to point to the prefix command matching NAME.  If NAME is a
   multi-word style name (e.g. 'disassembler comment') then *FOUND_CMD_PTR
   will point to the prefix command for the last word (e.g. 'comment').  */

static std::optional<ui_file_style>
stylepy_style_from_name (const char *name, bool *has_intensity_ptr = nullptr,
			 const cmd_list_element **found_cmd_ptr = nullptr)
{
  std::string cmd_str = std::string ("show style ") + name;

  struct cmd_list_element *cmd = nullptr;
  struct cmd_list_element *alias = nullptr;
  int found;
  try
    {
      struct cmd_list_element *prefix;
      found = lookup_cmd_composition (cmd_str.c_str (), &alias, &prefix, &cmd);
    }
  catch (const gdb_exception &ex)
    {
      PyErr_Format (PyExc_RuntimeError,
		    _("style '%s' cannot be found."), name);
      return {};
    }

  gdb_assert (!found || cmd != nullptr);

  if (!found || cmd == CMD_LIST_AMBIGUOUS || !cmd->is_prefix ())
    {
      PyErr_Format (PyExc_RuntimeError,
		    _("style '%s' cannot be found."), name);
      return {};
    }

  ui_file_style style;
  bool has_fg = false;
  bool has_bg = false;
  bool has_intensity = false;
  for (cmd_list_element *sub = *cmd->subcommands;
       sub != nullptr;
       sub = sub->next)
    {
      if (!sub->var.has_value ())
	continue;

      if (strcmp (sub->name, "foreground") == 0)
	{
	  const ui_file_style::color &color
	    = sub->var->get<ui_file_style::color> ();
	  style.set_fg (color);
	  has_fg = true;
	}
      else if (strcmp (sub->name, "background") == 0)
	{
	  const ui_file_style::color &color
	    = sub->var->get<ui_file_style::color> ();
	  style.set_bg (color);
	  has_bg = true;
	}
      else if (strcmp (sub->name, "intensity") == 0
	       && sub->var->type () == var_enum)
	{
	  const char *intensity_str = sub->var->get<const char *> ();
	  ui_file_style::intensity intensity = ui_file_style::NORMAL;
	  if (strcmp (intensity_str, "bold") == 0)
	    intensity = ui_file_style::BOLD;
	  else if (strcmp (intensity_str, "dim") == 0)
	    intensity = ui_file_style::DIM;
	  style.set_intensity (intensity);
	  has_intensity = true;
	}
    }

  /* All styles should have a foreground and background, but the intensity
     is optional.  */
  if (!has_fg || !has_bg)
    {
      PyErr_Format (PyExc_RuntimeError,
		    _("style '%s' missing '%s' component."), name,
		    (has_fg ? "background" : "foreground"));
      return {};
    }

  if (has_intensity_ptr != nullptr)
    *has_intensity_ptr = has_intensity;

  /* If NAME identified an alias then use that instead of CMD, this means
     the style's cached name will better match the string the user used to
     initialise the style.  */
  if (found_cmd_ptr != nullptr)
    *found_cmd_ptr = alias != nullptr ? alias : cmd;

  return style;
}

/* Initialise a gdb.Style object from a named style.  We only store the
   style name within SELF, each time the style is used, we look up its
   current value, this allows the style to change if the user adjusts the
   settings.  */

static int
stylepy_init_from_style_name (PyObject *self, const char *style_name)
{
  style_object *style = (style_object *) self;
  gdb_assert (style->style_name == nullptr);

  gdb_assert (style_name != nullptr);

  const cmd_list_element *cmd = nullptr;
  std::optional<ui_file_style> maybe_style
    = stylepy_style_from_name (style_name, nullptr, &cmd);
  if (!maybe_style.has_value ())
    return -1;

  /* If we found a style then we must have found a prefix command.  */
  gdb_assert (cmd != nullptr);
  gdb_assert (cmd->is_prefix ());

  /* Get the components of this command.  */
  std::vector<std::string> components = cmd->command_components ();
  gdb_assert (components.size () > 2);
  gdb_assert (components[0] == "show");
  gdb_assert (components[1] == "style");

  /* And build the components into a string, but without the 'show style'
     part at the start.  */
  std::string expanded_style_name (components[2]);
  for (int i = 3; i < components.size (); ++i)
    expanded_style_name += " " + components[i];

  style->style_name = xstrdup (expanded_style_name.c_str ());

  return 0;
}

/* Convert INTENSITY_VALUE to a valid intensity enum value, if possible,
   and return the enum value.  If INTENSITY_VALUE is not a valid intensity
   value then set a Python error, and return an empty optional.  */

static std::optional<ui_file_style::intensity>
stylepy_long_to_intensity (long intensity_value)
{
  ui_file_style::intensity intensity
    = static_cast<ui_file_style::intensity> (intensity_value);
  switch (intensity)
    {
    case ui_file_style::NORMAL:
    case ui_file_style::DIM:
    case ui_file_style::BOLD:
      break;

    default:
      PyErr_Format
	(PyExc_ValueError, _("invalid 'intensity' value %d."),
	 intensity_value);
      return {};
    }

  return intensity;
}

/* Initialise a gdb.Style object from a foreground and background
   gdb.Color object, and an intensity.  */

static int
stylepy_init_from_parts (PyObject *self, PyObject *fg, PyObject *bg,
			 int intensity_value)
{
  style_object *style = (style_object *) self;
  gdb_assert (style->style_name == nullptr);

  if (fg == Py_None)
    fg = nullptr;

  if (bg == Py_None)
    bg = nullptr;

  if (fg != nullptr && !gdbpy_is_color (fg))
    {
      PyErr_Format
	(PyExc_TypeError,
	 _("'foreground' argument must be gdb.Color or None, not %s."),
	 Py_TYPE (fg)->tp_name);
      return -1;
    }

  if (bg != nullptr && !gdbpy_is_color (bg))
    {
      PyErr_Format
	(PyExc_TypeError,
	 _("'background' argument must be gdb.Color or None, not %s."),
	 Py_TYPE (bg)->tp_name);
      return -1;
    }

  if (fg != nullptr)
    style->style.set_fg (gdbpy_get_color (fg));
  else
    style->style.set_fg (ui_file_style::color (ui_file_style::NONE));

  if (bg != nullptr)
    style->style.set_bg (gdbpy_get_color (bg));
  else
    style->style.set_bg (ui_file_style::color (ui_file_style::NONE));

  /* Convert INTENSITY_VALUE into the enum.  */
  std::optional<ui_file_style::intensity> intensity
    = stylepy_long_to_intensity (intensity_value);
  if (!intensity.has_value ())
    return -1;
  style->style.set_intensity (intensity.value ());

  return 0;
}

/* gdb.Style object initializer.  Either:
   gdb.Style.__init__("style name")
   gdb.Style.__init__(fg, bg, intensity)

   This init function supports two possible sets of arguments.  Both
   options are different enough that we can distinguish the two by the
   argument types.  Dispatch to one of the two stylepy_init_from_*
   functions above.  */

static int
stylepy_init (PyObject *self, PyObject *args, PyObject *kwargs)
{
  /* If this object was previously initialised, then clear it out now.  */
  stylepy_free_resources (self);

  /* Try to parse the incoming arguments as a string, this is a style
     name.  */
  const char *style_name = nullptr;
  static const char *keywords_style[] = { "style", nullptr };
  if (gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "s", keywords_style,
				       &style_name))
    return stylepy_init_from_style_name (self, style_name);

  /* That didn't work, discard any errors.  */
  PyErr_Clear ();

  /* Try to parse the incoming arguments as a list of parts, this is an
     unnamed style.  */
  PyObject *foreground_color = nullptr;
  PyObject *background_color = nullptr;
  int intensity_value = static_cast<int> (ui_file_style::NORMAL);
  static const char *keywords_parts[]
    = { "foreground", "background", "intensity", nullptr };
  if (gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "|OOi", keywords_parts,
				       &foreground_color,
				       &background_color,
				       &intensity_value))
    return stylepy_init_from_parts (self, foreground_color,
				    background_color, intensity_value);

  /* Return the error gdb_PyArg_ParseTupleAndKeywords set.  */
  return -1;
}



/* See python-internal.h.   */

bool
gdbpy_is_style (PyObject *obj)
{
  gdb_assert (obj != nullptr);
  return PyObject_TypeCheck (obj, &style_object_type);
}

/* Return the ui_file_style for STYLEPY.  If the style cannot be found,
   then return an empty optional, and set a Python error.  */

static std::optional<ui_file_style>
stylepy_to_style (style_object *stylepy)
{
  std::optional<ui_file_style> style;

  if (stylepy->style_name != nullptr)
    style = stylepy_style_from_name (stylepy->style_name);
  else
    style.emplace (stylepy->style);

  return style;
}

/* See python-internal.h.   */

std::optional<ui_file_style>
gdbpy_style_object_to_ui_file_style (PyObject *obj)
{
  gdb_assert (obj != nullptr);
  gdb_assert (gdbpy_is_style (obj));

  style_object *style_obj = (style_object *) obj;
  return stylepy_to_style (style_obj);
}

/* Implementation of gdb.Style.escape_sequence().  Return the escape
   sequence to apply Style.  If styling is turned off, then this returns
   the empty string.  Can raise an exception if a named style can no longer
   be read.  */

static PyObject *
stylepy_escape_sequence (PyObject *self, PyObject *args)
{
  style_object *style_obj = (style_object *) self;

  std::optional<ui_file_style> style = stylepy_to_style (style_obj);
  if (!style.has_value ())
    return nullptr;

  std::string style_str;
  if (term_cli_styling ())
    style_str = style->to_ansi ();

  return host_string_to_python_string (style_str.c_str ()).release ();
}

/* Implement gdb.Style.apply(STR).  Return a new string which is STR with
   escape sequences added so that STR is formatted in this style.  A
   trailing escape sequence is added to restore the default style.

   If styling is currently disabled ('set style enabled off'), then no
   escape sequences are added, but all the checks for the validity of the
   current style are still performed, and a new string, a copy of the
   input string is returned.

   Can raise a Python exception and return NULL if the argument types are
   wrong, or if a named style can no longer be read.  */

static PyObject *
stylepy_apply (PyObject *self, PyObject *args, PyObject *kw)
{
  style_object *style_obj = (style_object *) self;

  static const char *keywords[] = { "string", nullptr };
  PyObject *input_obj;

  /* Grab the incoming string as a Python object.  In the case where
     styling is not being applied we can just return this object with the
     reference count incremented.  */
  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O!", keywords,
					&PyUnicode_Type, &input_obj))
    return nullptr;

  std::optional<ui_file_style> style = stylepy_to_style (style_obj);
  if (!style.has_value ())
    return nullptr;

  if (gdb_stdout->can_emit_style_escape ())
    {
      gdb_assert (gdbpy_is_string (input_obj));
      gdb::unique_xmalloc_ptr<char>
	input (python_string_to_host_string (input_obj));

      std::string output
	= style->to_ansi () + input.get () + ui_file_style ().to_ansi ();

      return host_string_to_python_string (output.c_str ()).release ();
    }
  else
    {
      /* Return an unmodified "copy" of INPUT_OBJ by just incrementing the
	 reference count.  */
      Py_INCREF (input_obj);
      return input_obj;
    }
}



/* Implement reading the gdb.Style.foreground attribute.  */

static PyObject *
stylepy_get_foreground (PyObject *self, void *closure)
{
  style_object *style_obj = (style_object *) self;

  std::optional<ui_file_style> style = stylepy_to_style (style_obj);
  if (!style.has_value ())
    return nullptr;

  gdbpy_ref<> color = create_color_object (style->get_foreground ());
  if (color == nullptr)
    return nullptr;

  return color.release ();
}

/* Implement writing the gdb.Style.foreground attribute.  */

static int
stylepy_set_foreground (PyObject *self, PyObject *newvalue, void *closure)
{
  if (!gdbpy_is_color (newvalue))
    {
      PyErr_Format (PyExc_TypeError, _("value must be gdb.Color, not %s"),
		    Py_TYPE (newvalue)->tp_name);
      return -1;
    }

  style_object *style_obj = (style_object *) self;

  /* Handle unnamed styles.  This is easy, just update the embedded style
     object.  */
  if (style_obj->style_name == nullptr)
    {
      style_obj->style.set_fg (gdbpy_get_color (newvalue));
      return 0;
    }

  /* Handle named styles.  This is harder, we need to write to the actual
     parameter.  */
  std::string cmd_string
    = string_printf ("set style %s foreground %s",
		     style_obj->style_name,
		     gdbpy_get_color (newvalue).to_string ().c_str ());
  try
    {
      execute_command (cmd_string.c_str (), 0);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (-1, except);
    }

  return 0;
}

/* Implement reading the gdb.Style.background attribute.  */

static PyObject *
stylepy_get_background (PyObject *self, void *closure)
{
  style_object *style_obj = (style_object *) self;

  std::optional<ui_file_style> style = stylepy_to_style (style_obj);
  if (!style.has_value ())
    return nullptr;

  gdbpy_ref<> color = create_color_object (style->get_background ());
  if (color == nullptr)
    return nullptr;

  return color.release ();
}

/* Implement writing the gdb.Style.background attribute.  */

static int
stylepy_set_background (PyObject *self, PyObject *newvalue, void *closure)
{
  if (!gdbpy_is_color (newvalue))
    {
      PyErr_Format (PyExc_TypeError, _("value must be gdb.Color, not %s"),
		    Py_TYPE (newvalue)->tp_name);
      return -1;
    }

  style_object *style_obj = (style_object *) self;

  /* Handle unnamed styles.  This is easy, just update the embedded style
     object.  */
  if (style_obj->style_name == nullptr)
    {
      style_obj->style.set_bg (gdbpy_get_color (newvalue));
      return 0;
    }

  /* Handle named styles.  This is harder, we need to write to the actual
     parameter.  */
  std::string cmd_string
    = string_printf ("set style %s background %s",
		     style_obj->style_name,
		     gdbpy_get_color (newvalue).to_string ().c_str ());
  try
    {
      execute_command (cmd_string.c_str (), 0);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (-1, except);
    }

  return 0;
}

/* Implement reading the gdb.Style.intensity attribute.  */

static PyObject *
stylepy_get_intensity (PyObject *self, void *closure)
{
  style_object *style_obj = (style_object *) self;

  std::optional<ui_file_style> style = stylepy_to_style (style_obj);
  if (!style.has_value ())
    return nullptr;

  ui_file_style::intensity intensity = style->get_intensity ();
  return PyLong_FromLong (static_cast<long> (intensity));
}

/* Return a string representing INTENSITY.  */

static const char *
stylepy_intensity_to_string (ui_file_style::intensity intensity)
{
  const char *intensity_str = nullptr;
  switch (intensity)
    {
    case ui_file_style::NORMAL:
      intensity_str = "normal";
      break;
    case ui_file_style::BOLD:
      intensity_str = "bold";
      break;
    case ui_file_style::DIM:
      intensity_str = "dim";
      break;
    }

  gdb_assert (intensity_str != nullptr);
  return intensity_str;
}

/* Implement writing the gdb.Style.intensity attribute.  */

static int
stylepy_set_intensity (PyObject *self, PyObject *newvalue, void *closure)
{
  style_object *style_obj = (style_object *) self;

  if (!PyLong_Check (newvalue))
    {
      PyErr_Format
	(PyExc_TypeError,
	 _("value must be a Long (a gdb.INTENSITY constant), not %s"),
	 Py_TYPE (newvalue)->tp_name);
      return -1;
    }

  /* Convert the Python object to a value we can use.  */
  long intensity_value;
  if (!gdb_py_int_as_long (newvalue, &intensity_value))
    return -1;

  std::optional<ui_file_style::intensity> intensity
    = stylepy_long_to_intensity (intensity_value);
  if (!intensity.has_value ())
    return -1;

  /* Handle unnamed styles.  This is easy, just update the embedded style
     object.  */
  if (style_obj->style_name == nullptr)
    {
      style_obj->style.set_intensity (intensity.value ());
      return 0;
    }

  /* Handle named styles.  This is harder, we need to write to the actual
     parameter.  First though, look up the named style to see if it has an
     intensity.  HAS_INTENSITY will be set true only if the style exists,
     and has an 'intensity' setting.  */
  bool has_intensity = false;
  std::optional<ui_file_style> style
    = stylepy_style_from_name (style_obj->style_name, &has_intensity);
  if (!style.has_value ())
    return -1;
  if (!has_intensity)
    {
      PyErr_Format
	(PyExc_ValueError, "the intensity of style '%s' is not writable.",
	 style_obj->style_name);
      return -1;
    }

  const char *intensity_str = stylepy_intensity_to_string (intensity.value ());
  gdb_assert (intensity_str != nullptr);

  std::string cmd_string
    = string_printf ("set style %s intensity %s",
		     style_obj->style_name, intensity_str);
  try
    {
      execute_command (cmd_string.c_str (), 0);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (-1, except);
    }

  return 0;
}



/* Call FETCH_ATTR, passing in SELF, to get a PyObject*, then convert it to
   a Python string, and finally into a C++ managed string.  Will return
   nullptr and set a Python error if something goes wrong.

   The FETCH_ATTR function will be a function that returns an attribute
   from SELF.  */

static gdb::unique_xmalloc_ptr<char>
stylepy_attribute_to_string
  (PyObject *self,
   gdb::function_view<PyObject * (PyObject *, void *)> fetch_attr)
{
  PyObject *attr_obj = fetch_attr (self, nullptr);
  if (attr_obj == nullptr)
    return nullptr;

  PyObject *str_obj = PyObject_Str (attr_obj);
  if (str_obj == nullptr)
    return nullptr;

  return python_string_to_host_string (str_obj);
}

/* __repr__ implementation for gdb.Style.  */

static PyObject *
stylepy_repr (PyObject *self)
{
  style_object *style_obj = (style_object *) self;

  gdb::unique_xmalloc_ptr<char> fg_str
    (stylepy_attribute_to_string (self, stylepy_get_foreground));
  gdb::unique_xmalloc_ptr<char> bg_str
    (stylepy_attribute_to_string (self, stylepy_get_background));

  PyObject *intensity_obj = stylepy_get_intensity (self, nullptr);
  if (intensity_obj == nullptr)
    return nullptr;
  gdb_assert (PyLong_Check (intensity_obj));
  long intensity_value;
  if (!gdb_py_int_as_long (intensity_obj, &intensity_value))
    return nullptr;
  std::optional<ui_file_style::intensity> intensity
    = stylepy_long_to_intensity (intensity_value);
  if (!intensity.has_value ())
    return nullptr;
  const char *intensity_str = stylepy_intensity_to_string (intensity.value ());
  gdb_assert (intensity_str != nullptr);

  if (style_obj->style_name == nullptr)
    return PyUnicode_FromFormat ("<%s fg=%s, bg=%s, intensity=%s>",
				 Py_TYPE (self)->tp_name,
				 fg_str.get (), bg_str.get (),
				 intensity_str);
  else
    return PyUnicode_FromFormat ("<%s name='%s', fg=%s, bg=%s, intensity=%s>",
				 Py_TYPE (self)->tp_name,
				 style_obj->style_name, fg_str.get (),
				 bg_str.get (), intensity_str);
}



/* Style methods.  */

static PyMethodDef stylepy_methods[] =
{
  { "escape_sequence", stylepy_escape_sequence, METH_NOARGS,
    "escape_sequence () -> str.\n\
Return the ANSI escape sequence for this style."},
  { "apply", (PyCFunction) stylepy_apply, METH_VARARGS | METH_KEYWORDS,
    "apply(String) -> String.\n\
Apply this style to the input string.  Return an updated string."},
  {nullptr}
};

/* Attribute get/set Python definitions. */

static gdb_PyGetSetDef style_object_getset[] = {
  { "foreground", stylepy_get_foreground, stylepy_set_foreground,
    "The gdb.Color for the foreground of this style.", NULL },
  { "background", stylepy_get_background, stylepy_set_background,
    "The gdb.Color for the background of this style.", NULL },
  { "intensity", stylepy_get_intensity, stylepy_set_intensity,
    "The Str for the intensity of this style.", NULL },
  { nullptr }  /* Sentinel.  */
};

PyTypeObject style_object_type =
{
  PyVarObject_HEAD_INIT (nullptr, 0)
  "gdb.Style",			  /*tp_name*/
  sizeof (style_object),	  /*tp_basicsize*/
  0,				  /*tp_itemsize*/
  stylepy_dealloc,		  /*tp_dealloc*/
  0,				  /*tp_print*/
  0,				  /*tp_getattr*/
  0,				  /*tp_setattr*/
  0,				  /*tp_compare*/
  stylepy_repr,			  /*tp_repr*/
  0,				  /*tp_as_number*/
  0,				  /*tp_as_sequence*/
  0,				  /*tp_as_mapping*/
  0,				  /*tp_hash */
  0,				  /*tp_call*/
  0,				  /*tp_str*/
  0,				  /*tp_getattro*/
  0,				  /*tp_setattro*/
  0,				  /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
  "GDB style object",	  	  /* tp_doc */
  0,				  /* tp_traverse */
  0,				  /* tp_clear */
  0,				  /* tp_richcompare */
  0,				  /* tp_weaklistoffset */
  0,				  /* tp_iter */
  0,				  /* tp_iternext */
  stylepy_methods,		  /* tp_methods */
  0,				  /* tp_members */
  style_object_getset,		  /* tp_getset */
  0,				  /* tp_base */
  0,				  /* tp_dict */
  0,				  /* tp_descr_get */
  0,				  /* tp_descr_set */
  0,				  /* tp_dictoffset */
  stylepy_init,			  /* tp_init */
  0,				  /* tp_alloc */
  PyType_GenericNew		  /* tp_new */
};

GDBPY_INITIALIZE_FILE (gdbpy_initialize_style);
