/* General utility routines for GDB/Python.

   Copyright (C) 2008-2024 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 "top.h"
#include "charset.h"
#include "value.h"
#include "python-internal.h"

/* Converts a Python 8-bit string to a unicode string object.  Assumes the
   8-bit string is in the host charset.  If an error occurs during conversion,
   returns NULL with a python exception set.

   As an added bonus, the functions accepts a unicode string and returns it
   right away, so callers don't need to check which kind of string they've
   got.  In Python 3, all strings are Unicode so this case is always the
   one that applies.

   If the given object is not one of the mentioned string types, NULL is
   returned, with the TypeError python exception set.  */
gdbpy_ref<>
python_string_to_unicode (PyObject *obj)
{
  PyObject *unicode_str;

  /* If obj is already a unicode string, just return it.
     I wish life was always that simple...  */
  if (PyUnicode_Check (obj))
    {
      unicode_str = obj;
      Py_INCREF (obj);
    }
  else
    {
      PyErr_SetString (PyExc_TypeError,
		       _("Expected a string object."));
      unicode_str = NULL;
    }

  return gdbpy_ref<> (unicode_str);
}

/* Returns a newly allocated string with the contents of the given unicode
   string object converted to CHARSET.  If an error occurs during the
   conversion, NULL will be returned and a python exception will be
   set.  */
static gdb::unique_xmalloc_ptr<char>
unicode_to_encoded_string (PyObject *unicode_str, const char *charset)
{
  /* Translate string to named charset.  */
  gdbpy_ref<> string (PyUnicode_AsEncodedString (unicode_str, charset, NULL));
  if (string == NULL)
    return NULL;

  return gdb::unique_xmalloc_ptr<char>
    (xstrdup (PyBytes_AsString (string.get ())));
}

/* Returns a PyObject with the contents of the given unicode string
   object converted to a named charset.  If an error occurs during
   the conversion, NULL will be returned and a python exception will
   be set.  */
static gdbpy_ref<>
unicode_to_encoded_python_string (PyObject *unicode_str, const char *charset)
{
  /* Translate string to named charset.  */
  return gdbpy_ref<> (PyUnicode_AsEncodedString (unicode_str, charset, NULL));
}

/* Returns a newly allocated string with the contents of the given
   unicode string object converted to the target's charset.  If an
   error occurs during the conversion, NULL will be returned and a
   python exception will be set.  */
gdb::unique_xmalloc_ptr<char>
unicode_to_target_string (PyObject *unicode_str)
{
  return (unicode_to_encoded_string
	  (unicode_str,
	   target_charset (gdbpy_enter::get_gdbarch ())));
}

/* Returns a PyObject with the contents of the given unicode string
   object converted to the target's charset.  If an error occurs
   during the conversion, NULL will be returned and a python exception
   will be set.  */
static gdbpy_ref<>
unicode_to_target_python_string (PyObject *unicode_str)
{
  return (unicode_to_encoded_python_string
	  (unicode_str,
	   target_charset (gdbpy_enter::get_gdbarch ())));
}

/* Converts a python string (8-bit or unicode) to a target string in
   the target's charset.  Returns NULL on error, with a python
   exception set.  */
gdb::unique_xmalloc_ptr<char>
python_string_to_target_string (PyObject *obj)
{
  gdbpy_ref<> str = python_string_to_unicode (obj);
  if (str == NULL)
    return NULL;

  return unicode_to_target_string (str.get ());
}

/* Converts a python string (8-bit or unicode) to a target string in the
   target's charset.  Returns NULL on error, with a python exception
   set.

   In Python 3, the returned object is a "bytes" object (not a string).  */
gdbpy_ref<>
python_string_to_target_python_string (PyObject *obj)
{
  gdbpy_ref<> str = python_string_to_unicode (obj);
  if (str == NULL)
    return str;

  return unicode_to_target_python_string (str.get ());
}

/* Converts a python string (8-bit or unicode) to a target string in
   the host's charset.  Returns NULL on error, with a python exception
   set.  */
gdb::unique_xmalloc_ptr<char>
python_string_to_host_string (PyObject *obj)
{
  gdbpy_ref<> str = python_string_to_unicode (obj);
  if (str == NULL)
    return NULL;

  return unicode_to_encoded_string (str.get (), host_charset ());
}

/* Convert a host string to a python string.  */

gdbpy_ref<>
host_string_to_python_string (const char *str)
{
  return gdbpy_ref<> (PyUnicode_Decode (str, strlen (str), host_charset (),
					NULL));
}

/* Return true if OBJ is a Python string or unicode object, false
   otherwise.  */

int
gdbpy_is_string (PyObject *obj)
{
  return PyUnicode_Check (obj);
}

/* Return the string representation of OBJ, i.e., str (obj).
   If the result is NULL a python error occurred, the caller must clear it.  */

gdb::unique_xmalloc_ptr<char>
gdbpy_obj_to_string (PyObject *obj)
{
  gdbpy_ref<> str_obj (PyObject_Str (obj));

  if (str_obj != NULL)
    return python_string_to_host_string (str_obj.get ());

  return NULL;
}

/* See python-internal.h.  */

gdb::unique_xmalloc_ptr<char>
gdbpy_err_fetch::to_string () const
{
  /* There are a few cases to consider.
     For example:
     value is a string when PyErr_SetString is used.
     value is not a string when raise "foo" is used, instead it is None
     and type is "foo".
     So the algorithm we use is to print `str (value)' if it's not
     None, otherwise we print `str (type)'.
     Using str (aka PyObject_Str) will fetch the error message from
     gdb.GdbError ("message").  */

  gdbpy_ref<> value = this->value ();
  if (value.get () != nullptr && value.get () != Py_None)
    return gdbpy_obj_to_string (value.get ());
  else
    return gdbpy_obj_to_string (this->type ().get ());
}

/* See python-internal.h.  */

gdb::unique_xmalloc_ptr<char>
gdbpy_err_fetch::type_to_string () const
{
  return gdbpy_obj_to_string (this->type ().get ());
}

/* Convert a GDB exception to the appropriate Python exception.

   This sets the Python error indicator.  */

void
gdbpy_convert_exception (const struct gdb_exception &exception)
{
  PyObject *exc_class;

  if (exception.reason == RETURN_QUIT)
    exc_class = PyExc_KeyboardInterrupt;
  else if (exception.reason == RETURN_FORCED_QUIT)
    quit_force (NULL, 0);
  else if (exception.error == MEMORY_ERROR)
    exc_class = gdbpy_gdb_memory_error;
  else
    exc_class = gdbpy_gdb_error;

  PyErr_Format (exc_class, "%s", exception.what ());
}

/* Converts OBJ to a CORE_ADDR value.

   Returns 0 on success or -1 on failure, with a Python exception set.
*/

int
get_addr_from_python (PyObject *obj, CORE_ADDR *addr)
{
  if (gdbpy_is_value_object (obj))
    {

      try
	{
	  *addr = value_as_address (value_object_to_value (obj));
	}
      catch (const gdb_exception &except)
	{
	  return gdbpy_handle_gdb_exception (-1, except);
	}
    }
  else
    {
      gdbpy_ref<> num (PyNumber_Long (obj));
      gdb_py_ulongest val;

      if (num == NULL)
	return -1;

      val = gdb_py_long_as_ulongest (num.get ());
      if (PyErr_Occurred ())
	return -1;

      if (sizeof (val) > sizeof (CORE_ADDR) && ((CORE_ADDR) val) != val)
	{
	  PyErr_SetString (PyExc_ValueError,
			   _("Overflow converting to address."));
	  return -1;
	}

      *addr = val;
    }

  return 0;
}

/* Convert a LONGEST to the appropriate Python object -- either an
   integer object or a long object, depending on its value.  */

gdbpy_ref<>
gdb_py_object_from_longest (LONGEST l)
{
  if (sizeof (l) > sizeof (long))
    return gdbpy_ref<> (PyLong_FromLongLong (l));
  return gdbpy_ref<> (PyLong_FromLong (l));
}

/* Convert a ULONGEST to the appropriate Python object -- either an
   integer object or a long object, depending on its value.  */

gdbpy_ref<>
gdb_py_object_from_ulongest (ULONGEST l)
{
  if (sizeof (l) > sizeof (unsigned long))
    return gdbpy_ref<> (PyLong_FromUnsignedLongLong (l));
  return gdbpy_ref<> (PyLong_FromUnsignedLong (l));
}

/* Like PyLong_AsLong, but returns 0 on failure, 1 on success, and puts
   the value into an out parameter.  */

int
gdb_py_int_as_long (PyObject *obj, long *result)
{
  *result = PyLong_AsLong (obj);
  return ! (*result == -1 && PyErr_Occurred ());
}



/* Generic implementation of the __dict__ attribute for objects that
   have a dictionary.  The CLOSURE argument should be the type object.
   This only handles positive values for tp_dictoffset.  */

PyObject *
gdb_py_generic_dict (PyObject *self, void *closure)
{
  PyObject *result;
  PyTypeObject *type_obj = (PyTypeObject *) closure;
  char *raw_ptr;

  raw_ptr = (char *) self + type_obj->tp_dictoffset;
  result = * (PyObject **) raw_ptr;

  Py_INCREF (result);
  return result;
}

/* Like PyModule_AddObject, but does not steal a reference to
   OBJECT.  */

int
gdb_pymodule_addobject (PyObject *module, const char *name, PyObject *object)
{
  int result;

  Py_INCREF (object);
  result = PyModule_AddObject (module, name, object);
  if (result < 0)
    Py_DECREF (object);
  return result;
}

/* See python-internal.h.  */

void
gdbpy_error (const char *fmt, ...)
{
  va_list ap;
  va_start (ap, fmt);
  std::string str = string_vprintf (fmt, ap);
  va_end (ap);

  const char *msg = str.c_str ();
  if (msg != nullptr && *msg != '\0')
    error (_("Error occurred in Python: %s"), msg);
  else
    error (_("Error occurred in Python."));
}

/* Handle a Python exception when the special gdb.GdbError treatment
   is desired.  This should only be called when an exception is set.
   If the exception is a gdb.GdbError, throw a gdb exception with the
   exception text.  For other exceptions, print the Python stack and
   then throw a gdb exception.  */

void
gdbpy_handle_exception ()
{
  gdbpy_err_fetch fetched_error;
  gdb::unique_xmalloc_ptr<char> msg = fetched_error.to_string ();

  if (msg == NULL)
    {
      /* An error occurred computing the string representation of the
	 error message.  This is rare, but we should inform the user.  */
      gdb_printf (_("An error occurred in Python "
		    "and then another occurred computing the "
		    "error message.\n"));
      gdbpy_print_stack ();
    }

  /* Don't print the stack for gdb.GdbError exceptions.
     It is generally used to flag user errors.

     We also don't want to print "Error occurred in Python command"
     for user errors.  However, a missing message for gdb.GdbError
     exceptions is arguably a bug, so we flag it as such.  */

  if (fetched_error.type_matches (PyExc_KeyboardInterrupt))
    throw_quit ("Quit");
  else if (fetched_error.type_matches (PyExc_SystemExit))
    {
      gdbpy_ref<> value = fetched_error.value ();
      gdbpy_ref<> code (PyObject_GetAttrString (value.get (), "code"));
      int exit_arg;

      if (code.get () == Py_None)
	{
	  /* CODE == None: exit status is 0.  */
	  exit_arg = 0;
	}
      else if (code.get () != nullptr && PyLong_Check (code.get ()))
	{
	  /* CODE == integer: exit status is aforementioned integer.  */
	  exit_arg = PyLong_AsLong (code.get ());
	}
      else
	{
	  if (code.get () == nullptr)
	    gdbpy_print_stack ();

	  /* Otherwise: exit status is 1, print code to stderr.  */
	  if (msg != nullptr)
	    gdb_printf (gdb_stderr, "%s\n", msg.get ());
	  exit_arg = 1;
	}

      quit_force (&exit_arg, 0);
    }
  else if (! fetched_error.type_matches (gdbpy_gdberror_exc)
	   || msg == NULL || *msg == '\0')
    {
      fetched_error.restore ();
      gdbpy_print_stack ();
      if (msg != NULL && *msg != '\0')
	error (_("Error occurred in Python: %s"), msg.get ());
      else
	error (_("Error occurred in Python."));
    }
  else
    error ("%s", msg.get ());
}

/* See python-internal.h.  */

gdb::unique_xmalloc_ptr<char>
gdbpy_fix_doc_string_indentation (gdb::unique_xmalloc_ptr<char> doc)
{
  /* A structure used to track the white-space information on each line of
     DOC.  */
  struct line_whitespace
  {
    /* Constructor.  OFFSET is the offset from the start of DOC, WS_COUNT
       is the number of whitespace characters starting at OFFSET.  */
    line_whitespace (size_t offset, int ws_count)
      : m_offset (offset),
	m_ws_count (ws_count)
    { /* Nothing.  */ }

    /* The offset from the start of DOC.  */
    size_t offset () const
    { return m_offset; }

    /* The number of white-space characters at the start of this line.  */
    int ws () const
    { return m_ws_count; }

  private:
    /* The offset from the start of DOC to the first character of this
       line.  */
    size_t m_offset;

    /* White space count on this line, the first character of this
       whitespace is at OFFSET.  */
    int m_ws_count;
  };

  /* Count the number of white-space character starting at TXT.  We
     currently only count true single space characters, things like tabs,
     newlines, etc are not counted.  */
  auto count_whitespace = [] (const char *txt) -> int
  {
    int count = 0;

    while (*txt == ' ')
      {
	++txt;
	++count;
      }

    return count;
  };

  /* In MIN_WHITESPACE we track the smallest number of whitespace
     characters seen at the start of a line (that has actual content), this
     is the number of characters that we can delete off all lines without
     altering the relative indentation of all lines in DOC.

     The first line often has no indentation, but instead starts immediates
     after the 3-quotes marker within the Python doc string, so, if the
     first line has zero white-space then we just ignore it, and don't set
     MIN_WHITESPACE to zero.

     Lines without any content should (ideally) have no white-space at
     all, but if they do then they might have an artificially low number
     (user left a single stray space at the start of an otherwise blank
     line), we don't consider lines without content when updating the
     MIN_WHITESPACE value.  */
  std::optional<int> min_whitespace;

  /* The index into WS_INFO at which the processing of DOC can be
     considered "all done", that is, after this point there are no further
     lines with useful content and we should just stop.  */
  std::optional<size_t> all_done_idx;

  /* White-space information for each line in DOC.  */
  std::vector<line_whitespace> ws_info;

  /* Now look through DOC and collect the required information.  */
  const char *tmp = doc.get ();
  while (*tmp != '\0')
    {
      /* Add an entry for the offset to the start of this line, and how
	 much white-space there is at the start of this line.  */
      size_t offset = tmp - doc.get ();
      int ws_count = count_whitespace (tmp);
      ws_info.emplace_back (offset, ws_count);

      /* Skip over the white-space.  */
      tmp += ws_count;

      /* Remember where the content of this line starts, and skip forward
	 to either the end of this line (newline) or the end of the DOC
	 string (null character), whichever comes first.  */
      const char *content_start = tmp;
      while (*tmp != '\0' && *tmp != '\n')
	++tmp;

      /* If this is not the first line, and if this line has some content,
	 then update MIN_WHITESPACE, this reflects the smallest number of
	 whitespace characters we can delete from all lines without
	 impacting the relative indentation of all the lines of DOC.  */
      if (offset > 0 && tmp > content_start)
	{
	  if (!min_whitespace.has_value ())
	    min_whitespace = ws_count;
	  else
	    min_whitespace = std::min (*min_whitespace, ws_count);
	}

      /* Each time we encounter a line that has some content we update
	 ALL_DONE_IDX to be the index of the next line.  If the last lines
	 of DOC don't contain any content then ALL_DONE_IDX will be left
	 pointing at an earlier line.  When we rewrite DOC, when we reach
	 ALL_DONE_IDX then we can stop, the allows us to trim any blank
	 lines from the end of DOC.  */
      if (tmp > content_start)
	all_done_idx = ws_info.size ();

      /* If we reached a newline then skip forward to the start of the next
	 line.  The other possibility at this point is that we're at the
	 very end of the DOC string (null terminator).  */
      if (*tmp == '\n')
	++tmp;
    }

  /* We found no lines with content, fail safe by just returning the
     original documentation string.  */
  if (!all_done_idx.has_value () || !min_whitespace.has_value ())
    return doc;

  /* Setup DST and SRC, both pointing into the DOC string.  We're going to
     rewrite DOC in-place, as we only ever make DOC shorter (by removing
     white-space), thus we know this will not overflow.  */
  char *dst = doc.get ();
  char *src = doc.get ();

  /* Array indices used with DST, SRC, and WS_INFO respectively.  */
  size_t dst_offset = 0;
  size_t src_offset = 0;
  size_t ws_info_offset = 0;

  /* Now, walk over the source string, this is the original DOC.  */
  while (src[src_offset] != '\0')
    {
      /* If we are at the start of the next line (in WS_INFO), then we may
	 need to skip some white-space characters.  */
      if (src_offset == ws_info[ws_info_offset].offset ())
	{
	  /* If a line has leading white-space then we need to skip over
	     some number of characters now.  */
	  if (ws_info[ws_info_offset].ws () > 0)
	    {
	      /* If the line is entirely white-space then we skip all of
		 the white-space, the next character to copy will be the
		 newline or null character.  Otherwise, we skip the just
		 some portion of the leading white-space.  */
	      if (src[src_offset + ws_info[ws_info_offset].ws ()] == '\n'
		  || src[src_offset + ws_info[ws_info_offset].ws ()] == '\0')
		src_offset += ws_info[ws_info_offset].ws ();
	      else
		src_offset += std::min (*min_whitespace,
					ws_info[ws_info_offset].ws ());

	      /* If we skipped white-space, and are now at the end of the
		 input, then we're done.  */
	      if (src[src_offset] == '\0')
		break;
	    }
	  if (ws_info_offset < (ws_info.size () - 1))
	    ++ws_info_offset;
	  if (ws_info_offset > *all_done_idx)
	    break;
	}

      /* Don't copy a newline to the start of the DST string, this would
	 result in a leading blank line.  But in all other cases, copy the
	 next character into the destination string.  */
      if ((dst_offset > 0 || src[src_offset] != '\n'))
	{
	  dst[dst_offset] = src[src_offset];
	  ++dst_offset;
	}

      /* Move to the next source character.  */
      ++src_offset;
    }

  /* Remove the trailing newline character(s), and ensure we have a null
     terminator in place.  */
  while (dst_offset > 1 && dst[dst_offset - 1] == '\n')
    --dst_offset;
  dst[dst_offset] = '\0';

  return doc;
}

/* See python-internal.h.  */

PyObject *
gdb_py_invalid_object_repr (PyObject *self)
{
  return PyUnicode_FromFormat ("<%s (invalid)>", Py_TYPE (self)->tp_name);
}
