/* Python interface to line tables.

   Copyright (C) 2013-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"

struct linetable_entry_object : public PyObject
{
  /* The line table source line.  */
  int line;
  /* The pc associated with the source line.  */
  CORE_ADDR pc;
};

extern PyTypeObject linetable_entry_object_type;

struct linetable_object : public PyObject
{
  /* The symtab python object.  We store the Python object here as the
     underlying symtab can become invalid, and we have to run validity
     checks on it.  */
  PyObject *symtab;
};

extern PyTypeObject linetable_object_type;

struct ltpy_iterator_object : public PyObject
{
  /* The current entry in the line table for the iterator  */
  int current_index;
  /* Pointer back to the original source line table object.  Needed to
     check if the line table is still valid, and has not been invalidated
     when an object file has been freed.  */
  PyObject *source;
};

extern PyTypeObject ltpy_iterator_object_type;

/* Internal helper function to extract gdb.Symtab from a gdb.LineTable
   object.  */

static PyObject *
get_symtab (PyObject *linetable)
{
  linetable_object *lt = (linetable_object *) linetable;

  return lt->symtab;
}

#define LTPY_REQUIRE_VALID(lt_obj, symtab)				\
  do {									\
    symtab = symtab_object_to_symtab (get_symtab (lt_obj));		\
    if (symtab == NULL)							\
      {									\
	  PyErr_SetString (PyExc_RuntimeError,				\
			   _("Symbol Table in line table is invalid."));\
	  return NULL;							\
	}								\
  } while (0)


/* Helper function to create a line table object that wraps a
   gdb.Symtab object.  */

gdbpy_ref<>
symtab_to_linetable_object (PyObject *symtab)
{
  linetable_object *ltable;

  ltable = PyObject_New (linetable_object, &linetable_object_type);
  if (ltable != NULL)
    {
      ltable->symtab = symtab;
      Py_INCREF (symtab);
    }
  return gdbpy_ref<> (ltable);
}

/* Internal helper function to build a line table object from a line
   and an address.  */

static PyObject *
build_linetable_entry (int line, CORE_ADDR address)
{
  linetable_entry_object *obj;

  obj = PyObject_New (linetable_entry_object,
		      &linetable_entry_object_type);
  if (obj != NULL)
    {
      obj->line = line;
      obj->pc = address;
    }

  return (PyObject *) obj;
}

/* Internal helper function to build a Python Tuple from a vector.
   A line table entry can have multiple PCs for a given source line.
   Construct a Tuple of all entries for the given source line, LINE
   from the line table PCS.  Construct one line table entry object per
   address.  */

static PyObject *
build_line_table_tuple_from_entries
	(const struct objfile *objfile,
	 const std::vector<const linetable_entry *> &entries)
{
  int i;

  if (entries.size () < 1)
    Py_RETURN_NONE;

  gdbpy_ref<> tuple (PyTuple_New (entries.size ()));

  if (tuple == NULL)
    return NULL;

  for (i = 0; i < entries.size (); ++i)
    {
      auto entry = entries[i];
      gdbpy_ref<> obj (build_linetable_entry
			(entry->line, entry->pc (objfile)));

      if (obj == NULL)
	return NULL;
      else if (PyTuple_SetItem (tuple.get (), i, obj.release ()) != 0)
	return NULL;
    }

  return tuple.release ();
}

/* Implementation of gdb.LineTable.line (self) -> Tuple.  Returns a
   tuple of LineTableEntry objects associated with this line from the
   in the line table.  */

static PyObject *
ltpy_get_pcs_for_line (PyObject *self, PyObject *args)
{
  struct symtab *symtab;
  gdb_py_longest py_line;
  const linetable_entry *best_entry = nullptr;
  std::vector<const linetable_entry*> entries;

  LTPY_REQUIRE_VALID (self, symtab);

  if (! PyArg_ParseTuple (args, GDB_PY_LL_ARG, &py_line))
    return NULL;

  try
    {
      entries = find_linetable_entries_for_symtab_line (symtab, py_line,
							&best_entry);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  struct objfile *objfile = symtab->compunit ()->objfile ();
  return build_line_table_tuple_from_entries (objfile, entries);
}

/* Implementation of gdb.LineTable.has_line (self, line) -> Boolean.
   Returns a Python Boolean indicating whether a source line has any
   line table entries corresponding to it.  */

static PyObject *
ltpy_has_line (PyObject *self, PyObject *args)
{
  struct symtab *symtab;
  gdb_py_longest py_line;
  int index;

  LTPY_REQUIRE_VALID (self, symtab);

  if (! PyArg_ParseTuple (args, GDB_PY_LL_ARG, &py_line))
    return NULL;

  if (symtab->linetable () == NULL)
    {
      PyErr_SetString (PyExc_RuntimeError,
		       _("Linetable information not found in symbol table"));
      return NULL;
    }

  for (index = 0; index < symtab->linetable ()->nitems; index++)
    {
      const linetable_entry *item = &(symtab->linetable ()->item[index]);
      if (item->line == py_line)
	  Py_RETURN_TRUE;
    }

  Py_RETURN_FALSE;
}

/* Implementation of gdb.LineTable.source_lines (self) -> List.
   Returns a Python List that contains source line entries in the
   line table.  This function will just return the source lines
   without corresponding addresses.  */

static PyObject *
ltpy_get_all_source_lines (PyObject *self, PyObject *args)
{
  struct symtab *symtab;
  Py_ssize_t index;

  LTPY_REQUIRE_VALID (self, symtab);

  if (symtab->linetable () == NULL)
    {
      PyErr_SetString (PyExc_RuntimeError,
		       _("Linetable information not found in symbol table"));
      return NULL;
    }

  gdbpy_ref<> source_dict (PyDict_New ());
  if (source_dict == NULL)
    return NULL;

  for (index = 0; index < symtab->linetable ()->nitems; index++)
    {
      const linetable_entry *item = &(symtab->linetable ()->item[index]);

      /* 0 is used to signify end of line table information.  Do not
	 include in the source set. */
      if (item->line > 0)
	{
	  gdbpy_ref<> line = gdb_py_object_from_longest (item->line);

	  if (line == NULL)
	    return NULL;

	  if (PyDict_SetItem (source_dict.get (), line.get (), Py_None) == -1)
	    return NULL;
	}
    }

  return PyDict_Keys (source_dict.get ());
}

/* Implementation of gdb.LineTable.is_valid (self) -> Boolean.
   Returns True if this line table object still exists in GDB.  */

static PyObject *
ltpy_is_valid (PyObject *self, PyObject *args)
{
  struct symtab *symtab = NULL;

  symtab = symtab_object_to_symtab (get_symtab (self));

  if (symtab == NULL)
    Py_RETURN_FALSE;

  Py_RETURN_TRUE;
}

/* Deconstructor for the line table object.  Decrement the reference
   to the symbol table object before calling the default free.  */

static void
ltpy_dealloc (PyObject *self)
{
  linetable_object *obj = (linetable_object *) self;

  Py_DECREF (obj->symtab);
  Py_TYPE (self)->tp_free (self);
}

/* Initialize LineTable, LineTableEntry and LineTableIterator
   objects.  */

static int
gdbpy_initialize_linetable ()
{
  if (gdbpy_type_ready (&linetable_object_type) < 0)
    return -1;
  if (gdbpy_type_ready (&linetable_entry_object_type) < 0)
    return -1;
  if (gdbpy_type_ready (&ltpy_iterator_object_type) < 0)
    return -1;

  return 0;
}

/* LineTable entry object get functions.  */

/* Implementation of gdb.LineTableEntry.line (self) -> Long.  Returns
   a long integer associated with the line table entry.  */

static PyObject *
ltpy_entry_get_line (PyObject *self, void *closure)
{
  linetable_entry_object *obj = (linetable_entry_object *) self;

  return gdb_py_object_from_longest (obj->line).release ();
}

/* Implementation of gdb.LineTableEntry.pc (self) -> Long.  Returns a
   a long integer associated with the PC of the line table entry.  */

static PyObject *
ltpy_entry_get_pc (PyObject *self, void *closure)
{
  linetable_entry_object *obj = (linetable_entry_object *) self;

  return gdb_py_object_from_ulongest (obj->pc).release ();
}

/* LineTable iterator functions.  */

/* Return a new line table iterator.  */

static PyObject *
ltpy_iter (PyObject *self)
{
  ltpy_iterator_object *ltpy_iter_obj;
  struct symtab *symtab = NULL;

  LTPY_REQUIRE_VALID (self, symtab);

  ltpy_iter_obj = PyObject_New (ltpy_iterator_object,
				&ltpy_iterator_object_type);
  if (ltpy_iter_obj == NULL)
    return NULL;

  ltpy_iter_obj->current_index = 0;
  ltpy_iter_obj->source = self;

  Py_INCREF (self);
  return (PyObject *) ltpy_iter_obj;
}

static void
ltpy_iterator_dealloc (PyObject *obj)
{
  ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) obj;

  Py_DECREF (iter_obj->source);
  Py_TYPE (obj)->tp_free (obj);
}

/* Return a reference to the line table iterator.  */

static PyObject *
ltpy_iterator (PyObject *self)
{
  ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self;
  struct symtab *symtab;

  LTPY_REQUIRE_VALID (iter_obj->source, symtab);

  Py_INCREF (self);
  return self;
}

/* Return the next line table entry in the iteration through the line
   table data structure.  */

static PyObject *
ltpy_iternext (PyObject *self)
{
  ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self;
  struct symtab *symtab;
  PyObject *obj;

  LTPY_REQUIRE_VALID (iter_obj->source, symtab);

  if (symtab->linetable () == nullptr
      || iter_obj->current_index >= symtab->linetable ()->nitems)
    {
      PyErr_SetNone (PyExc_StopIteration);
      return NULL;
    }

  const linetable_entry *item
    = &(symtab->linetable ()->item[iter_obj->current_index]);

  /* Skip over internal entries such as 0.  0 signifies the end of
     line table data and is not useful to the API user.  */
  while (item->line < 1)
    {
      iter_obj->current_index++;

      /* Exit if the internal value is the last item in the line table.  */
      if (iter_obj->current_index >= symtab->linetable ()->nitems)
	{
	  PyErr_SetNone (PyExc_StopIteration);
	  return NULL;
	}
      item = &(symtab->linetable ()->item[iter_obj->current_index]);
    }

  struct objfile *objfile = symtab->compunit ()->objfile ();
  obj = build_linetable_entry (item->line, item->pc (objfile));
  iter_obj->current_index++;

  return obj;
}

/* Implementation of gdb.LineTableIterator.is_valid (self) -> Boolean.
   Returns True if this line table iterator object still exists in
   GDB.  */

static PyObject *
ltpy_iter_is_valid (PyObject *self, PyObject *args)
{
  struct symtab *symtab = NULL;
  ltpy_iterator_object *iter_obj = (ltpy_iterator_object *) self;

  symtab = symtab_object_to_symtab (get_symtab (iter_obj->source));

  if (symtab == NULL)
    Py_RETURN_FALSE;

  Py_RETURN_TRUE;
}

GDBPY_INITIALIZE_FILE (gdbpy_initialize_linetable);



static PyMethodDef linetable_object_methods[] = {
  { "line", ltpy_get_pcs_for_line, METH_VARARGS,
    "line (lineno) -> Tuple\n\
Return executable locations for a given source line." },
  { "has_line", ltpy_has_line, METH_VARARGS,
    "has_line (lineno) -> Boolean\n\
Return TRUE if this line has executable information, FALSE if not." },
  { "source_lines", ltpy_get_all_source_lines, METH_NOARGS,
    "source_lines () -> List\n\
Return a list of all executable source lines." },
  { "is_valid", ltpy_is_valid, METH_NOARGS,
    "is_valid () -> Boolean.\n\
Return True if this LineTable is valid, False if not." },
  {NULL}  /* Sentinel */
};

PyTypeObject linetable_object_type = {
  PyVarObject_HEAD_INIT (NULL, 0)
  "gdb.LineTable",	          /*tp_name*/
  sizeof (linetable_object),	  /*tp_basicsize*/
  0,				  /*tp_itemsize*/
  ltpy_dealloc,                   /*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,             /*tp_flags*/
  "GDB line table object",	  /* tp_doc */
  0,				  /* tp_traverse */
  0,				  /* tp_clear */
  0,				  /* tp_richcompare */
  0,				  /* tp_weaklistoffset */
  ltpy_iter,			  /* tp_iter */
  0,				  /* tp_iternext */
  linetable_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 */
  0,    			  /* tp_init */
  0,				  /* tp_alloc */
};

static PyMethodDef ltpy_iterator_methods[] = {
  { "is_valid", ltpy_iter_is_valid, METH_NOARGS,
    "is_valid () -> Boolean.\n\
Return True if this LineTable iterator is valid, False if not." },
  {NULL}  /* Sentinel */
};

PyTypeObject ltpy_iterator_object_type = {
  PyVarObject_HEAD_INIT (NULL, 0)
  "gdb.LineTableIterator",		  /*tp_name*/
  sizeof (ltpy_iterator_object),  /*tp_basicsize*/
  0,				  /*tp_itemsize*/
  ltpy_iterator_dealloc,	  /*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,		  /*tp_flags*/
  "GDB line table iterator object",	      /*tp_doc */
  0,				  /*tp_traverse */
  0,				  /*tp_clear */
  0,				  /*tp_richcompare */
  0,				  /*tp_weaklistoffset */
  ltpy_iterator,                  /*tp_iter */
  ltpy_iternext,	          /*tp_iternext */
  ltpy_iterator_methods           /*tp_methods */
};


static gdb_PyGetSetDef linetable_entry_object_getset[] = {
  { "line", ltpy_entry_get_line, NULL,
    "The line number in the source file.", NULL },
  { "pc", ltpy_entry_get_pc, NULL,
    "The memory address for this line number.", NULL },
  { NULL }  /* Sentinel */
};

PyTypeObject linetable_entry_object_type = {
  PyVarObject_HEAD_INIT (NULL, 0)
  "gdb.LineTableEntry",	          /*tp_name*/
  sizeof (linetable_entry_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,             /*tp_flags*/
  "GDB line table entry 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 */
  linetable_entry_object_getset,  /* tp_getset */
  0,				  /* tp_base */
  0,				  /* tp_dict */
  0,				  /* tp_descr_get */
  0,				  /* tp_descr_set */
  0,				  /* tp_dictoffset */
  0,	                          /* tp_init */
  0,				  /* tp_alloc */
};
