/* gdb commands implemented in Python

   Copyright (C) 2008-2026 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */


#include "arch-utils.h"
#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"

/* Struct representing built-in completion types.  */
struct cmdpy_completer
{
  /* Python symbol name.  */
  const char *name;
  /* Completion function.  */
  completer_ftype *completer;
};

static const struct cmdpy_completer completers[] =
{
  { "COMPLETE_NONE", noop_completer },
  { "COMPLETE_FILENAME", filename_maybe_quoted_completer },
  { "COMPLETE_LOCATION", location_completer },
  { "COMPLETE_COMMAND", command_completer },
  { "COMPLETE_SYMBOL", symbol_completer },
  { "COMPLETE_EXPRESSION", expression_completer },
};

#define N_COMPLETERS (sizeof (completers) / sizeof (completers[0]))

/* A gdb command.  For the time being only ordinary commands (not
   set/show commands) are allowed.  */
struct cmdpy_object : public PyObject
{
  /* The corresponding gdb command object, or NULL if the command is
     no longer installed.  */
  struct cmd_list_element *command;

  /* A prefix command requires storage for a list of its sub-commands.
     A pointer to this is passed to add_prefix_command, and to add_cmd
     for sub-commands of that prefix.  If this Command is not a prefix
     command, then this field is unused.  */
  struct cmd_list_element *sub_list;
};

static_assert (gdb::is_python_allocatable_v<cmdpy_object>);

extern PyTypeObject cmdpy_object_type;

/* Constants used by this module.  */
static PyObject *invoke_cst;
static PyObject *complete_cst;



/* Python function which wraps dont_repeat.  */
static PyObject *
cmdpy_dont_repeat (PyObject *self, PyObject *args)
{
  dont_repeat ();
  return py_none ().release ();
}



/* Called if the gdb cmd_list_element is destroyed.  */

static void
cmdpy_destroyer (struct cmd_list_element *self, void *context)
{
  gdbpy_enter enter_py;

  /* Release our hold on the command object.  */
  gdbpy_ref<cmdpy_object> cmd ((cmdpy_object *) context);
  cmd->command = NULL;
}

/* Called by gdb to invoke the command.  */

static void
cmdpy_function (const char *args, int from_tty, cmd_list_element *command)
{
  cmdpy_object *obj = (cmdpy_object *) command->context ();

  gdbpy_enter enter_py;

  if (obj == nullptr)
    error (_("Invalid invocation of Python command object."));

  /* If we get here for a prefix command then the prefix command had an
     'invoke' method when it was created.  If the 'invoke' method is now
     missing, then the user has done something weird (like deleting the
     invoke method, yuck!).  */
  if (!PyObject_HasAttr ((PyObject *) obj, invoke_cst))
    error (_("Python command object missing 'invoke' method."));

  if (args == nullptr)
    args = "";
  gdbpy_ref<> argobj (PyUnicode_Decode (args, strlen (args), host_charset (),
					NULL));
  if (argobj == NULL)
    {
      gdbpy_print_stack ();
      error (_("Could not convert arguments to Python string."));
    }

  gdbpy_ref<> ttyobj (PyBool_FromLong (from_tty));
  gdbpy_ref<> result (PyObject_CallMethodObjArgs ((PyObject *) obj, invoke_cst,
						  argobj.get (), ttyobj.get (),
						  NULL));

  if (result == NULL)
    gdbpy_handle_exception ();
}

/* Helper function for the Python command completers (both "pure"
   completer and brkchar handler).  This function takes COMMAND, TEXT
   and WORD and tries to call the Python method for completion with
   these arguments.

   This function is usually called twice: once when we are figuring out
   the break characters to be used, and another to perform the real
   completion itself.  The reason for this two step dance is that we
   need to know the set of "brkchars" to use early on, before we
   actually try to perform the completion.  But if a Python command
   supplies a "complete" method then we have to call that method
   first: it may return as its result the kind of completion to
   perform and that will in turn specify which brkchars to use.  IOW,
   we need the result of the "complete" method before we actually
   perform the completion.  The only situation when this function is
   not called twice is when the user uses the "complete" command: in
   this scenario, there is no call to determine the "brkchars".

   Ideally, it would be nice to cache the result of the first call (to
   determine the "brkchars") and return this value directly in the
   second call (to perform the actual completion).  However, due to
   the peculiarity of the "complete" command mentioned above, it is
   possible to put GDB in a bad state if you perform a TAB-completion
   and then a "complete"-completion sequentially.  Therefore, we just
   recalculate everything twice for TAB-completions.

   This function returns a reference to the PyObject representing the
   Python method call.  */

static gdbpy_ref<>
cmdpy_completer_helper (struct cmd_list_element *command,
			const char *text, const char *word)
{
  cmdpy_object *obj = (cmdpy_object *) command->context ();

  if (obj == NULL)
    error (_("Invalid invocation of Python command object."));
  if (!PyObject_HasAttr ((PyObject *) obj, complete_cst))
    {
      /* If there is no complete method, don't error.  */
      return NULL;
    }

  gdbpy_ref<> textobj (PyUnicode_Decode (text, strlen (text), host_charset (),
					 NULL));
  if (textobj == NULL)
    {
      gdbpy_print_stack ();
      error (_("Could not convert argument to Python string."));
    }

  gdbpy_ref<> wordobj;
  if (word == NULL)
    {
      /* "brkchars" phase.  */
      wordobj = py_none ();
    }
  else
    {
      wordobj.reset (PyUnicode_Decode (word, strlen (word), host_charset (),
				       NULL));
      if (wordobj == NULL)
	{
	  gdbpy_print_stack ();
	  error (_("Could not convert argument to Python string."));
	}
    }

  gdbpy_ref<> resultobj (PyObject_CallMethodObjArgs ((PyObject *) obj,
						     complete_cst,
						     textobj.get (),
						     wordobj.get (), NULL));

  /* Check if an exception was raised by the Command.complete method.  */
  if (resultobj == nullptr)
    {
      gdbpy_print_stack_or_quit ();
      error (_("exception raised during Command.complete method"));
    }

  return resultobj;
}

/* Python function called to determine the break characters of a
   certain completer.  We are only interested in knowing if the
   completer registered by the user will return one of the integer
   codes (see COMPLETER_* symbols).  */

static void
cmdpy_completer_handle_brkchars (struct cmd_list_element *command,
				 completion_tracker &tracker,
				 const char *text, const char *word)
{
  gdbpy_enter enter_py;

  /* Calling our helper to obtain a reference to the PyObject of the Python
     function.  */
  gdbpy_ref<> resultobj = cmdpy_completer_helper (command, text, word);

  /* Check if there was an error.  */
  if (resultobj == NULL)
    return;

  if (PyLong_Check (resultobj.get ()))
    {
      /* User code may also return one of the completion constants,
	 thus requesting that sort of completion.  We are only
	 interested in this kind of return.  */
      long value;

      if (!gdb_py_int_as_long (resultobj.get (), &value))
	gdbpy_print_stack ();
      else if (value >= 0 && value < (long) N_COMPLETERS)
	{
	  completer_handle_brkchars_ftype *brkchars_fn;

	  /* This is the core of this function.  Depending on which
	     completer type the Python function returns, we have to
	     adjust the break characters accordingly.  */
	  brkchars_fn = (completer_handle_brkchars_func_for_completer
			 (completers[value].completer));
	  brkchars_fn (command, tracker, text, word);
	}
    }
}

/* Called by gdb for command completion.  */

static void
cmdpy_completer (struct cmd_list_element *command,
		 completion_tracker &tracker,
		 const char *text, const char *word)
{
  gdbpy_enter enter_py;

  /* Calling our helper to obtain a reference to the PyObject of the Python
     function.  */
  gdbpy_ref<> resultobj = cmdpy_completer_helper (command, text, word);

  /* If the result object of calling the Python function is NULL, it
     means that there was an error.  In this case, just give up.  */
  if (resultobj == NULL)
    return;

  if (PyLong_Check (resultobj.get ()))
    {
      /* User code may also return one of the completion constants,
	 thus requesting that sort of completion.  */
      long value;

      if (! gdb_py_int_as_long (resultobj.get (), &value))
	gdbpy_print_stack ();
      else if (value >= 0 && value < (long) N_COMPLETERS)
	completers[value].completer (command, tracker, text, word);
    }
  else if (PySequence_Check (resultobj.get ()))
    {
      gdbpy_ref<> iter (PyObject_GetIter (resultobj.get ()));

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

      while (true)
	{
	  gdbpy_ref<> elt (PyIter_Next (iter.get ()));
	  if (elt == NULL)
	    {
	      if (PyErr_Occurred() != nullptr)
		gdbpy_print_stack ();
	      break;
	    }

	  if (! gdbpy_is_string (elt.get ()))
	    {
	      /* Skip problem elements.  */
	      continue;
	    }

	  gdb::unique_xmalloc_ptr<char>
	    item (python_string_to_host_string (elt.get ()));
	  if (item == NULL)
	    {
	      gdbpy_print_stack ();
	      continue;
	    }
	  tracker.add_completion (std::move (item));
	}
    }
}

/* Helper for cmdpy_init which locates the command list to use and
   pulls out the command name.

   NAME is the command name list.  The final word in the list is the
   name of the new command.  All earlier words must be existing prefix
   commands.

   *BASE_LIST is set to the final prefix command's list of sub-commands.

   START_LIST is the list in which the search starts.

   When PREFIX_CMD is not NULL then *PREFIX_CMD is set to the prefix
   command itself, or NULL, if there is no prefix command.

   This function returns the name of the new command.  On error sets the Python
   error and returns NULL.  */

gdb::unique_xmalloc_ptr<char>
gdbpy_parse_command_name (const char *name,
			  struct cmd_list_element ***base_list,
			  struct cmd_list_element **start_list,
			  struct cmd_list_element **prefix_cmd)
{
  struct cmd_list_element *elt;
  int len = strlen (name);
  int i, lastchar;
  const char *prefix_text2;

  if (prefix_cmd != nullptr)
    *prefix_cmd = nullptr;

  /* Skip trailing whitespace.  */
  for (i = len - 1; i >= 0 && (name[i] == ' ' || name[i] == '\t'); --i)
    ;
  if (i < 0)
    {
      PyErr_SetString (PyExc_RuntimeError, _("No command name found."));
      return NULL;
    }
  lastchar = i;

  /* Find first character of the final word.  */
  for (; i > 0 && valid_cmd_char_p (name[i - 1]); --i)
    ;

  gdb::unique_xmalloc_ptr<char> result
    = make_unique_xstrndup (&name[i], lastchar - i + 1);

  /* Skip whitespace again.  */
  for (--i; i >= 0 && (name[i] == ' ' || name[i] == '\t'); --i)
    ;
  if (i < 0)
    {
      *base_list = start_list;
      return result;
    }

  std::string prefix_text (name, i + 1);

  prefix_text2 = prefix_text.c_str ();
  elt = lookup_cmd_1 (&prefix_text2, *start_list, NULL, NULL, 1);
  if (elt == nullptr || elt == CMD_LIST_AMBIGUOUS || *prefix_text2 != '\0')
    {
      PyErr_Format (PyExc_RuntimeError, _("Could not find command prefix %s."),
		    prefix_text.c_str ());
      return NULL;
    }

  if (elt->is_prefix ())
    {
      *base_list = elt->subcommands;
      if (prefix_cmd != nullptr)
	*prefix_cmd = elt;
      return result;
    }

  PyErr_Format (PyExc_RuntimeError, _("'%s' is not a prefix command."),
		prefix_text.c_str ());
  return NULL;
}

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

   Use: __init__(NAME, COMMAND_CLASS [, COMPLETER_CLASS][, PREFIX]]).

   NAME is the name of the command.  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.

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

   COMPLETER_CLASS is the kind of completer.  If not given, the
   "complete" method will be used.  Otherwise, it should be one of the
   COMPLETE_* constants defined in the gdb module.

   If PREFIX is True, then this command is a prefix command.

   The documentation for the command is taken from the doc string for
   the python class.  */

static int
cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
{
  cmdpy_object *obj = (cmdpy_object *) self;
  const char *name;
  int cmdtype;
  int completetype = -1;
  struct cmd_list_element **cmd_list;
  static const char *keywords[] = { "name", "command_class", "completer_class",
				    "prefix", NULL };
  PyObject *is_prefix_obj = NULL;
  bool is_prefix = false;

  if (obj->command)
    {
      /* Note: this is apparently not documented in Python.  We return
	 0 for success, -1 for failure.  */
      PyErr_Format (PyExc_RuntimeError,
		    _("Command object already initialized."));
      return -1;
    }

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "si|iO",
					keywords, &name, &cmdtype,
					&completetype, &is_prefix_obj))
    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 && cmdtype != class_user
      && cmdtype != class_tui && cmdtype != class_essential)
    {
      PyErr_Format (PyExc_RuntimeError, _("Invalid command class argument."));
      return -1;
    }

  if (completetype < -1 || completetype >= (int) N_COMPLETERS)
    {
      PyErr_Format (PyExc_RuntimeError,
		    _("Invalid completion type argument."));
      return -1;
    }

  cmd_list_element *prefix_cmd = nullptr;
  gdb::unique_xmalloc_ptr<char> cmd_name
    = gdbpy_parse_command_name (name, &cmd_list, &cmdlist, &prefix_cmd);
  if (cmd_name == nullptr)
    return -1;

  if (is_prefix_obj != NULL)
    {
      int cmp = PyObject_IsTrue (is_prefix_obj);
      if (cmp < 0)
	return -1;

      is_prefix = cmp > 0;
    }

  gdb::unique_xmalloc_ptr<char> docstring = nullptr;
  if (PyObject_HasAttr (self, gdbpy_doc_cst))
    {
      gdbpy_ref<> ds_obj (PyObject_GetAttr (self, gdbpy_doc_cst));

      if (ds_obj != NULL && gdbpy_is_string (ds_obj.get ()))
	{
	  docstring = python_string_to_host_string (ds_obj.get ());
	  if (docstring == nullptr)
	    return -1;
	  docstring = gdbpy_fix_doc_string_indentation (std::move (docstring));
	}
    }
  if (docstring == nullptr)
    docstring = make_unique_xstrdup (_("This command is not documented."));

  gdbpy_ref<> self_ref = gdbpy_ref<>::new_reference (self);

  try
    {
      struct cmd_list_element *cmd;

      if (is_prefix)
	{
	  bool has_invoke = PyObject_HasAttr (self, invoke_cst) == 1;
	  if (has_invoke)
	    {
	      /* If there's an 'invoke' method, then create the prefix
		 command, but call cmdpy_function to dispatch to the invoke
		 method when the user runs the prefix with no sub-command.  */
	      cmd = add_prefix_cmd (cmd_name.get (),
				    (enum command_class) cmdtype,
				    nullptr,
				    docstring.release (), &obj->sub_list,
				    1 /* allow_unknown */, cmd_list);
	      cmd->func = cmdpy_function;
	    }
	  else
	    {
	      /* If there is no 'invoke' method, then create the prefix
		 using the standard prefix callbacks.  This means that for
		 'set prefix' the user will get the help text listing all
		 of the sub-commands, and for 'show prefix', the user will
		 see all of the sub-command values.  */
	      if (prefix_cmd != nullptr)
		{
		  while (prefix_cmd->prefix != nullptr)
		    prefix_cmd = prefix_cmd->prefix;
		}

	      bool is_show = (prefix_cmd != nullptr
			      && prefix_cmd->subcommands == &showlist);

	      if (is_show)
		cmd = add_show_prefix_cmd (cmd_name.get (),
					   (enum command_class) cmdtype,
					   docstring.release (),
					   &obj->sub_list,
					   0 /* allow_unknown */, cmd_list);
	      else
		cmd = add_basic_prefix_cmd (cmd_name.get (),
					    (enum command_class) cmdtype,
					    docstring.release (),
					    &obj->sub_list,
					    0 /* allow_unknown */, cmd_list);
	    }
	}
      else
	{
	  /* For non-prefix commands, arrange to call cmdpy_function, which
	     invokes the Python 'invoke' method, or raises an exception if
	     the 'invoke' method is missing.  */
	  cmd = add_cmd (cmd_name.get (), (enum command_class) cmdtype,
			 docstring.release (), cmd_list);
	  cmd->func = cmdpy_function;
	}

      /* If successful, the above takes ownership of the name, since we set
	 name_allocated, so release it.  */
      cmd_name.release ();

      /* There appears to be no API to set these member variables.  */
      cmd->destroyer = cmdpy_destroyer;
      cmd->doc_allocated = 1;
      cmd->name_allocated = 1;

      obj->command = cmd;
      cmd->set_context (self_ref.release ());
      set_cmd_completer (cmd, ((completetype == -1) ? cmdpy_completer
			       : completers[completetype].completer));
      if (completetype == -1)
	set_cmd_completer_handle_brkchars (cmd,
					   cmdpy_completer_handle_brkchars);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (-1, except);
    }

  return 0;
}



/* Initialize the 'commands' code.  */

static int
gdbpy_initialize_commands ()
{
  int i;

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

  /* Note: alias and user are special.  */
  if (PyModule_AddIntConstant (gdb_module, "COMMAND_NONE", no_class) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_RUNNING", class_run) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_DATA", class_vars) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_STACK", class_stack) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_FILES", class_files) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_SUPPORT",
				  class_support) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_STATUS", class_info) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_BREAKPOINTS",
				  class_breakpoint) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_TRACEPOINTS",
				  class_trace) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_OBSCURE",
				  class_obscure) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_MAINTENANCE",
				  class_maintenance) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_USER", class_user) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_ESSENTIAL",
				  class_essential) < 0
      || PyModule_AddIntConstant (gdb_module, "COMMAND_TUI", class_tui) < 0)
    return -1;

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

  invoke_cst = PyUnicode_FromString ("invoke");
  if (invoke_cst == NULL)
    return -1;
  complete_cst = PyUnicode_FromString ("complete");
  if (complete_cst == NULL)
    return -1;

  return 0;
}

GDBPY_INITIALIZE_FILE (gdbpy_initialize_commands);



static PyMethodDef cmdpy_object_methods[] =
{
  { "dont_repeat", cmdpy_dont_repeat, METH_NOARGS,
    "Prevent command repetition when user enters empty line." },

  { 0 }
};

PyTypeObject cmdpy_object_type =
{
  PyVarObject_HEAD_INIT (NULL, 0)
  "gdb.Command",		  /*tp_name*/
  sizeof (cmdpy_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*/
  0,				  /*tp_getattro*/
  0,				  /*tp_setattro*/
  0,				  /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
  "GDB command object",		  /* tp_doc */
  0,				  /* tp_traverse */
  0,				  /* tp_clear */
  0,				  /* tp_richcompare */
  0,				  /* tp_weaklistoffset */
  0,				  /* tp_iter */
  0,				  /* tp_iternext */
  cmdpy_object_methods,		  /* 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 */
  cmdpy_init,			  /* tp_init */
  0,				  /* tp_alloc */
};



/* Utility to build a buildargv-like result from ARGS.
   This intentionally parses arguments the way libiberty/argv.c:buildargv
   does.  It splits up arguments in a reasonable way, and we want a standard
   way of parsing arguments.  Several gdb commands use buildargv to parse their
   arguments.  Plus we want to be able to write compatible python
   implementations of gdb commands.  */

PyObject *
gdbpy_string_to_argv (PyObject *self, PyObject *args)
{
  const char *input;

  if (!PyArg_ParseTuple (args, "s", &input))
    return NULL;

  gdbpy_ref<> py_argv (PyList_New (0));
  if (py_argv == NULL)
    return NULL;

  /* buildargv uses NULL to represent an empty argument list, but we can't use
     that in Python.  Instead, if ARGS is "" then return an empty list.
     This undoes the NULL -> "" conversion that cmdpy_function does.  */

  if (*input != '\0')
    {
      gdb_argv c_argv (input);

      for (char *arg : c_argv)
	{
	  gdbpy_ref<> argp (PyUnicode_FromString (arg));

	  if (argp == NULL
	      || PyList_Append (py_argv.get (), argp.get ()) < 0)
	    return NULL;
	}
    }

  return py_argv.release ();
}
