/* Python interface to ui_file_style objects.

   Copyright (C) 2025-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 "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)
{
  switch (intensity_value)
    {
    case ui_file_style::NORMAL:
    case ui_file_style::DIM:
    case ui_file_style::BOLD:
      return static_cast<ui_file_style::intensity> (intensity_value);

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

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