/* Python frame filters

   Copyright (C) 2013-2016 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 "defs.h"
#include "objfiles.h"
#include "symtab.h"
#include "language.h"
#include "arch-utils.h"
#include "python.h"
#include "ui-out.h"
#include "valprint.h"
#include "annotate.h"
#include "hashtab.h"
#include "demangle.h"
#include "mi/mi-cmds.h"
#include "python-internal.h"

enum mi_print_types
{
  MI_PRINT_ARGS,
  MI_PRINT_LOCALS
};

/* Helper  function  to  extract  a  symbol, a  name  and  a  language
   definition from a Python object that conforms to the "Symbol Value"
   interface.  OBJ  is the Python  object to extract the  values from.
   NAME is a  pass-through argument where the name of  the symbol will
   be written.  NAME is allocated in  this function, but the caller is
   responsible for clean up.  SYM is a pass-through argument where the
   symbol will be written and  SYM_BLOCK is a pass-through argument to
   write  the block where the symbol lies in.  In the case of the  API
   returning a  string,  this will be set to NULL.  LANGUAGE is also a
   pass-through  argument  denoting  the  language  attributed  to the
   Symbol.  In the case of SYM being  NULL, this  will be  set to  the
   current  language.  Returns  EXT_LANG_BT_ERROR  on  error  with the
   appropriate Python exception set, and EXT_LANG_BT_OK on success.  */

static enum ext_lang_bt_status
extract_sym (PyObject *obj, gdb::unique_xmalloc_ptr<char> *name,
	     struct symbol **sym, struct block **sym_block,
	     const struct language_defn **language)
{
  PyObject *result = PyObject_CallMethod (obj, "symbol", NULL);

  if (result == NULL)
    return EXT_LANG_BT_ERROR;

  /* For 'symbol' callback, the function can return a symbol or a
     string.  */
  if (gdbpy_is_string (result))
    {
      *name = python_string_to_host_string (result);
      Py_DECREF (result);

      if (*name == NULL)
	return EXT_LANG_BT_ERROR;
      /* If the API returns a string (and not a symbol), then there is
	no symbol derived language available and the frame filter has
	either overridden the symbol with a string, or supplied a
	entirely synthetic symbol/value pairing.  In that case, use
	python_language.  */
      *language = python_language;
      *sym = NULL;
      *sym_block = NULL;
    }
  else
    {
      /* This type checks 'result' during the conversion so we
	 just call it unconditionally and check the return.  */
      *sym = symbol_object_to_symbol (result);
      /* TODO: currently, we have no way to recover the block in which SYMBOL
	 was found, so we have no block to return.  Trying to evaluate SYMBOL
	 will yield an incorrect value when it's located in a FRAME and
	 evaluated from another frame (as permitted in nested functions).  */
      *sym_block = NULL;

      Py_DECREF (result);

      if (*sym == NULL)
	{
	  PyErr_SetString (PyExc_RuntimeError,
			   _("Unexpected value.  Expecting a "
			     "gdb.Symbol or a Python string."));
	  return EXT_LANG_BT_ERROR;
	}

      /* Duplicate the symbol name, so the caller has consistency
	 in garbage collection.  */
      name->reset (xstrdup (SYMBOL_PRINT_NAME (*sym)));

      /* If a symbol is specified attempt to determine the language
	 from the symbol.  If mode is not "auto", then the language
	 has been explicitly set, use that.  */
      if (language_mode == language_mode_auto)
	*language = language_def (SYMBOL_LANGUAGE (*sym));
      else
	*language = current_language;
    }

  return EXT_LANG_BT_OK;
}

/* Helper function to extract a value from an object that conforms to
   the "Symbol Value" interface.  OBJ is the Python object to extract
   the value from.  VALUE is a pass-through argument where the value
   will be written.  If the object does not have the value attribute,
   or provides the Python None for a value, VALUE will be set to NULL
   and this function will return as successful.  Returns EXT_LANG_BT_ERROR
   on error with the appropriate Python exception set, and EXT_LANG_BT_OK on
   success.  */

static enum ext_lang_bt_status
extract_value (PyObject *obj, struct value **value)
{
  if (PyObject_HasAttrString (obj, "value"))
    {
      PyObject *vresult = PyObject_CallMethod (obj, "value", NULL);

      if (vresult == NULL)
	return EXT_LANG_BT_ERROR;

      /* The Python code has returned 'None' for a value, so we set
	 value to NULL.  This flags that GDB should read the
	 value.  */
      if (vresult == Py_None)
	{
	  Py_DECREF (vresult);
	  *value = NULL;
	  return EXT_LANG_BT_OK;
	}
      else
	{
	  *value = convert_value_from_python (vresult);
	  Py_DECREF (vresult);

	  if (*value == NULL)
	    return EXT_LANG_BT_ERROR;

	  return EXT_LANG_BT_OK;
	}
    }
  else
    *value = NULL;

  return EXT_LANG_BT_OK;
}

/* MI prints only certain values according to the type of symbol and
   also what the user has specified.  SYM is the symbol to check, and
   MI_PRINT_TYPES is an enum specifying what the user wants emitted
   for the MI command in question.  */
static int
mi_should_print (struct symbol *sym, enum mi_print_types type)
{
  int print_me = 0;

  switch (SYMBOL_CLASS (sym))
    {
    default:
    case LOC_UNDEF:	/* catches errors        */
    case LOC_CONST:	/* constant              */
    case LOC_TYPEDEF:	/* local typedef         */
    case LOC_LABEL:	/* local label           */
    case LOC_BLOCK:	/* local function        */
    case LOC_CONST_BYTES:	/* loc. byte seq.        */
    case LOC_UNRESOLVED:	/* unresolved static     */
    case LOC_OPTIMIZED_OUT:	/* optimized out         */
      print_me = 0;
      break;

    case LOC_ARG:	/* argument              */
    case LOC_REF_ARG:	/* reference arg         */
    case LOC_REGPARM_ADDR:	/* indirect register arg */
    case LOC_LOCAL:	/* stack local           */
    case LOC_STATIC:	/* static                */
    case LOC_REGISTER:	/* register              */
    case LOC_COMPUTED:	/* computed location     */
      if (type == MI_PRINT_LOCALS)
	print_me = ! SYMBOL_IS_ARGUMENT (sym);
      else
	print_me = SYMBOL_IS_ARGUMENT (sym);
    }
  return print_me;
}

/* Helper function which outputs a type name extracted from VAL to a
   "type" field in the output stream OUT.  OUT is the ui-out structure
   the type name will be output too, and VAL is the value that the
   type will be extracted from.  Returns EXT_LANG_BT_ERROR on error, with
   any GDB exceptions converted to a Python exception, or EXT_LANG_BT_OK on
   success.  */

static enum ext_lang_bt_status
py_print_type (struct ui_out *out, struct value *val)
{

  TRY
    {
      struct ui_file *stb;
      struct cleanup *cleanup;

      stb = mem_fileopen ();
      cleanup = make_cleanup_ui_file_delete (stb);
      check_typedef (value_type (val));
      type_print (value_type (val), "", stb, -1);
      ui_out_field_stream (out, "type", stb);
      do_cleanups (cleanup);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      gdbpy_convert_exception (except);
      return EXT_LANG_BT_ERROR;
    }
  END_CATCH

  return EXT_LANG_BT_OK;
}

/* Helper function which outputs a value to an output field in a
   stream.  OUT is the ui-out structure the value will be output to,
   VAL is the value that will be printed, OPTS contains the value
   printing options, ARGS_TYPE is an enumerator describing the
   argument format, and LANGUAGE is the language_defn that the value
   will be printed with.  Returns EXT_LANG_BT_ERROR on error, with any GDB
   exceptions converted to a Python exception, or EXT_LANG_BT_OK on
   success. */

static enum ext_lang_bt_status
py_print_value (struct ui_out *out, struct value *val,
		const struct value_print_options *opts,
		int indent,
		enum ext_lang_frame_args args_type,
		const struct language_defn *language)
{
  int should_print = 0;

  /* MI does not print certain values, differentiated by type,
     depending on what ARGS_TYPE indicates.  Test type against option.
     For CLI print all values.  */
  if (args_type == MI_PRINT_SIMPLE_VALUES
      || args_type == MI_PRINT_ALL_VALUES)
    {
      struct type *type = NULL;

      TRY
	{
	  type = check_typedef (value_type (val));
	}
      CATCH (except, RETURN_MASK_ALL)
	{
	  gdbpy_convert_exception (except);
	  return EXT_LANG_BT_ERROR;
	}
      END_CATCH

      if (args_type == MI_PRINT_ALL_VALUES)
	should_print = 1;
      else if (args_type == MI_PRINT_SIMPLE_VALUES
	       && TYPE_CODE (type) != TYPE_CODE_ARRAY
	       && TYPE_CODE (type) != TYPE_CODE_STRUCT
	       && TYPE_CODE (type) != TYPE_CODE_UNION)
	should_print = 1;
    }
  else if (args_type != NO_VALUES)
    should_print = 1;

  if (should_print)
    {
      TRY
	{
	  struct ui_file *stb;
	  struct cleanup *cleanup;

	  stb = mem_fileopen ();
	  cleanup = make_cleanup_ui_file_delete (stb);
	  common_val_print (val, stb, indent, opts, language);
	  ui_out_field_stream (out, "value", stb);
	  do_cleanups (cleanup);
	}
      CATCH (except, RETURN_MASK_ALL)
	{
	  gdbpy_convert_exception (except);
	  return EXT_LANG_BT_ERROR;
	}
      END_CATCH
    }

  return EXT_LANG_BT_OK;
}

/* Helper function to call a Python method and extract an iterator
   from the result.  If the function returns anything but an iterator
   the exception is preserved and NULL is returned.  FILTER is the
   Python object to call, and FUNC is the name of the method.  Returns
   a PyObject, or NULL on error with the appropriate exception set.
   This function can return an iterator, or NULL.  */

static PyObject *
get_py_iter_from_func (PyObject *filter, char *func)
{
  if (PyObject_HasAttrString (filter, func))
    {
      PyObject *result = PyObject_CallMethod (filter, func, NULL);

      if (result != NULL)
	{
	  if (result == Py_None)
	    {
	      return result;
	    }
	  else
	    {
	      PyObject *iterator = PyObject_GetIter (result);

	      Py_DECREF (result);
	      return iterator;
	    }
	}
    }
  else
    Py_RETURN_NONE;

  return NULL;
}

/*  Helper function to output a single frame argument and value to an
    output stream.  This function will account for entry values if the
    FV parameter is populated, the frame argument has entry values
    associated with them, and the appropriate "set entry-value"
    options are set.  Will output in CLI or MI like format depending
    on the type of output stream detected.  OUT is the output stream,
    SYM_NAME is the name of the symbol.  If SYM_NAME is populated then
    it must have an accompanying value in the parameter FV.  FA is a
    frame argument structure.  If FA is populated, both SYM_NAME and
    FV are ignored.  OPTS contains the value printing options,
    ARGS_TYPE is an enumerator describing the argument format,
    PRINT_ARGS_FIELD is a flag which indicates if we output "ARGS=1"
    in MI output in commands where both arguments and locals are
    printed.  Returns EXT_LANG_BT_ERROR on error, with any GDB exceptions
    converted to a Python exception, or EXT_LANG_BT_OK on success.  */

static enum ext_lang_bt_status
py_print_single_arg (struct ui_out *out,
		     const char *sym_name,
		     struct frame_arg *fa,
		     struct value *fv,
		     const struct value_print_options *opts,
		     enum ext_lang_frame_args args_type,
		     int print_args_field,
		     const struct language_defn *language)
{
  struct value *val;
  enum ext_lang_bt_status retval = EXT_LANG_BT_OK;

  if (fa != NULL)
    {
      if (fa->val == NULL && fa->error == NULL)
	return EXT_LANG_BT_OK;
      language = language_def (SYMBOL_LANGUAGE (fa->sym));
      val = fa->val;
    }
  else
    val = fv;

  TRY
    {
      struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);

      /*  MI has varying rules for tuples, but generally if there is only
      one element in each item in the list, do not start a tuple.  The
      exception is -stack-list-variables which emits an ARGS="1" field
      if the value is a frame argument.  This is denoted in this
      function with PRINT_ARGS_FIELD which is flag from the caller to
      emit the ARGS field.  */
      if (ui_out_is_mi_like_p (out))
	{
	  if (print_args_field || args_type != NO_VALUES)
	    make_cleanup_ui_out_tuple_begin_end (out, NULL);
	}

      annotate_arg_begin ();

      /* If frame argument is populated, check for entry-values and the
	 entry value options.  */
      if (fa != NULL)
	{
	  struct ui_file *stb;

	  stb = mem_fileopen ();
	  make_cleanup_ui_file_delete (stb);
	  fprintf_symbol_filtered (stb, SYMBOL_PRINT_NAME (fa->sym),
				   SYMBOL_LANGUAGE (fa->sym),
				   DMGL_PARAMS | DMGL_ANSI);
	  if (fa->entry_kind == print_entry_values_compact)
	    {
	      fputs_filtered ("=", stb);

	      fprintf_symbol_filtered (stb, SYMBOL_PRINT_NAME (fa->sym),
				       SYMBOL_LANGUAGE (fa->sym),
				       DMGL_PARAMS | DMGL_ANSI);
	    }
	  if (fa->entry_kind == print_entry_values_only
	      || fa->entry_kind == print_entry_values_compact)
	    {
	      fputs_filtered ("@entry", stb);
	    }
	  ui_out_field_stream (out, "name", stb);
	}
      else
	/* Otherwise, just output the name.  */
	ui_out_field_string (out, "name", sym_name);

      annotate_arg_name_end ();

      if (! ui_out_is_mi_like_p (out))
	ui_out_text (out, "=");

      if (print_args_field)
	ui_out_field_int (out, "arg", 1);

      /* For MI print the type, but only for simple values.  This seems
	 weird, but this is how MI choose to format the various output
	 types.  */
      if (args_type == MI_PRINT_SIMPLE_VALUES && val != NULL)
	{
	  if (py_print_type (out, val) == EXT_LANG_BT_ERROR)
	    {
	      retval = EXT_LANG_BT_ERROR;
	      do_cleanups (cleanups);
	    }
	}

      if (retval != EXT_LANG_BT_ERROR)
	{
	  if (val != NULL)
	    annotate_arg_value (value_type (val));

	  /* If the output is to the CLI, and the user option "set print
	     frame-arguments" is set to none, just output "...".  */
	  if (! ui_out_is_mi_like_p (out) && args_type == NO_VALUES)
	    ui_out_field_string (out, "value", "...");
	  else
	    {
	      /* Otherwise, print the value for both MI and the CLI, except
		 for the case of MI_PRINT_NO_VALUES.  */
	      if (args_type != NO_VALUES)
		{
		  if (val == NULL)
		    {
		      gdb_assert (fa != NULL && fa->error != NULL);
		      ui_out_field_fmt (out, "value",
					_("<error reading variable: %s>"),
					fa->error);
		    }
		  else if (py_print_value (out, val, opts, 0, args_type, language)
			   == EXT_LANG_BT_ERROR)
		    retval = EXT_LANG_BT_ERROR;
		}
	    }

	  do_cleanups (cleanups);
	}
    }
  CATCH (except, RETURN_MASK_ERROR)
    {
      gdbpy_convert_exception (except);
    }
  END_CATCH

  return retval;
}

/* Helper function to loop over frame arguments provided by the
   "frame_arguments" Python API.  Elements in the iterator must
   conform to the "Symbol Value" interface.  ITER is the Python
   iterable object, OUT is the output stream, ARGS_TYPE is an
   enumerator describing the argument format, PRINT_ARGS_FIELD is a
   flag which indicates if we output "ARGS=1" in MI output in commands
   where both arguments and locals are printed, and FRAME is the
   backing frame.  Returns EXT_LANG_BT_ERROR on error, with any GDB
   exceptions converted to a Python exception, or EXT_LANG_BT_OK on
   success.  */

static enum ext_lang_bt_status
enumerate_args (PyObject *iter,
		struct ui_out *out,
		enum ext_lang_frame_args args_type,
		int print_args_field,
		struct frame_info *frame)
{
  PyObject *item;
  struct value_print_options opts;

  get_user_print_options (&opts);

  if (args_type == CLI_SCALAR_VALUES)
    {
      /* True in "summary" mode, false otherwise.  */
      opts.summary = 1;
    }

  opts.deref_ref = 1;

  TRY
    {
      annotate_frame_args ();
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      gdbpy_convert_exception (except);
      goto error;
    }
  END_CATCH

  /*  Collect the first argument outside of the loop, so output of
      commas in the argument output is correct.  At the end of the
      loop block collect another item from the iterator, and, if it is
      not null emit a comma.  */
  item = PyIter_Next (iter);
  if (item == NULL && PyErr_Occurred ())
    goto error;

  while (item)
    {
      const struct language_defn *language;
      gdb::unique_xmalloc_ptr<char> sym_name;
      struct symbol *sym;
      struct block *sym_block;
      struct value *val;
      enum ext_lang_bt_status success = EXT_LANG_BT_ERROR;

      success = extract_sym (item, &sym_name, &sym, &sym_block, &language);
      if (success == EXT_LANG_BT_ERROR)
	{
	  Py_DECREF (item);
	  goto error;
	}

      success = extract_value (item, &val);
      if (success == EXT_LANG_BT_ERROR)
	{
	  Py_DECREF (item);
	  goto error;
	}

      Py_DECREF (item);
      item = NULL;

      if (sym && ui_out_is_mi_like_p (out)
	  && ! mi_should_print (sym, MI_PRINT_ARGS))
	continue;

      /* If the object did not provide a value, read it using
	 read_frame_args and account for entry values, if any.  */
      if (val == NULL)
	{
	  struct frame_arg arg, entryarg;

	  /* If there is no value, and also no symbol, set error and
	     exit.  */
	  if (sym == NULL)
	    {
	      PyErr_SetString (PyExc_RuntimeError,
			       _("No symbol or value provided."));
	      goto error;
	    }

	  TRY
	    {
	      read_frame_arg (sym, frame, &arg, &entryarg);
	    }
	  CATCH (except, RETURN_MASK_ALL)
	    {
	      gdbpy_convert_exception (except);
	      goto error;
	    }
	  END_CATCH

	  /* The object has not provided a value, so this is a frame
	     argument to be read by GDB.  In this case we have to
	     account for entry-values.  */

	  if (arg.entry_kind != print_entry_values_only)
	    {
	      if (py_print_single_arg (out, NULL, &arg,
				       NULL, &opts,
				       args_type,
				       print_args_field,
				       NULL) == EXT_LANG_BT_ERROR)
		{
		  xfree (arg.error);
		  xfree (entryarg.error);
		  goto error;
		}
	    }

	  if (entryarg.entry_kind != print_entry_values_no)
	    {
	      if (arg.entry_kind != print_entry_values_only)
		{
		  TRY
		    {
		      ui_out_text (out, ", ");
		      ui_out_wrap_hint (out, "    ");
		    }
		  CATCH (except, RETURN_MASK_ALL)
		    {
		      xfree (arg.error);
		      xfree (entryarg.error);
		      gdbpy_convert_exception (except);
		      goto error;
		    }
		  END_CATCH
		}

	      if (py_print_single_arg (out, NULL, &entryarg, NULL, &opts,
				       args_type, print_args_field, NULL)
		  == EXT_LANG_BT_ERROR)
		{
		      xfree (arg.error);
		      xfree (entryarg.error);
		      goto error;
		}
	    }

	  xfree (arg.error);
	  xfree (entryarg.error);
	}
      else
	{
	  /* If the object has provided a value, we just print that.  */
	  if (val != NULL)
	    {
	      if (py_print_single_arg (out, sym_name.get (), NULL, val, &opts,
				       args_type, print_args_field,
				       language) == EXT_LANG_BT_ERROR)
		goto error;
	    }
	}

      /* Collect the next item from the iterator.  If
	 this is the last item, do not print the
	 comma.  */
      item = PyIter_Next (iter);
      if (item != NULL)
	{
	  TRY
	    {
	      ui_out_text (out, ", ");
	    }
	  CATCH (except, RETURN_MASK_ALL)
	    {
	      Py_DECREF (item);
	      gdbpy_convert_exception (except);
	      goto error;
	    }
	  END_CATCH
	}
      else if (PyErr_Occurred ())
	goto error;

      TRY
	{
	  annotate_arg_end ();
	}
      CATCH (except, RETURN_MASK_ALL)
	{
	  Py_DECREF (item);
	  gdbpy_convert_exception (except);
	  goto error;
	}
      END_CATCH
    }

  return EXT_LANG_BT_OK;

 error:
  return EXT_LANG_BT_ERROR;
}


/* Helper function to loop over variables provided by the
   "frame_locals" Python API.  Elements in the iterable must conform
   to the "Symbol Value" interface.  ITER is the Python iterable
   object, OUT is the output stream, INDENT is whether we should
   indent the output (for CLI), ARGS_TYPE is an enumerator describing
   the argument format, PRINT_ARGS_FIELD is flag which indicates
   whether to output the ARGS field in the case of
   -stack-list-variables and FRAME is the backing frame.  Returns
   EXT_LANG_BT_ERROR on error, with any GDB exceptions converted to a Python
   exception, or EXT_LANG_BT_OK on success.  */

static enum ext_lang_bt_status
enumerate_locals (PyObject *iter,
		  struct ui_out *out,
		  int indent,
		  enum ext_lang_frame_args args_type,
		  int print_args_field,
		  struct frame_info *frame)
{
  PyObject *item;
  struct value_print_options opts;

  get_user_print_options (&opts);
  opts.deref_ref = 1;

  while ((item = PyIter_Next (iter)))
    {
      const struct language_defn *language;
      gdb::unique_xmalloc_ptr<char> sym_name;
      struct value *val;
      enum ext_lang_bt_status success = EXT_LANG_BT_ERROR;
      struct symbol *sym;
      struct block *sym_block;
      int local_indent = 8 + (8 * indent);
      struct cleanup *locals_cleanups;

      locals_cleanups = make_cleanup_py_decref (item);

      success = extract_sym (item, &sym_name, &sym, &sym_block, &language);
      if (success == EXT_LANG_BT_ERROR)
	{
	  do_cleanups (locals_cleanups);
	  goto error;
	}

      success = extract_value (item, &val);
      if (success == EXT_LANG_BT_ERROR)
	{
	  do_cleanups (locals_cleanups);
	  goto error;
	}

      if (sym != NULL && ui_out_is_mi_like_p (out)
	  && ! mi_should_print (sym, MI_PRINT_LOCALS))
	{
	  do_cleanups (locals_cleanups);
	  continue;
	}

      /* If the object did not provide a value, read it.  */
      if (val == NULL)
	{
	  TRY
	    {
	      val = read_var_value (sym, sym_block, frame);
	    }
	  CATCH (except, RETURN_MASK_ERROR)
	    {
	      gdbpy_convert_exception (except);
	      do_cleanups (locals_cleanups);
	      goto error;
	    }
	  END_CATCH
	}

      /* With PRINT_NO_VALUES, MI does not emit a tuple normally as
	 each output contains only one field.  The exception is
	 -stack-list-variables, which always provides a tuple.  */
      if (ui_out_is_mi_like_p (out))
	{
	  if (print_args_field || args_type != NO_VALUES)
	    make_cleanup_ui_out_tuple_begin_end (out, NULL);
	}
      TRY
	{
	  if (! ui_out_is_mi_like_p (out))
	    {
	      /* If the output is not MI we indent locals.  */
	      ui_out_spaces (out, local_indent);
	    }

	  ui_out_field_string (out, "name", sym_name.get ());

	  if (! ui_out_is_mi_like_p (out))
	    ui_out_text (out, " = ");
	}
      CATCH (except, RETURN_MASK_ERROR)
	{
	  gdbpy_convert_exception (except);
	  do_cleanups (locals_cleanups);
	  goto error;
	}
      END_CATCH

      if (args_type == MI_PRINT_SIMPLE_VALUES)
	{
	  if (py_print_type (out, val) == EXT_LANG_BT_ERROR)
	    {
	      do_cleanups (locals_cleanups);
	      goto error;
	    }
	}

      /* CLI always prints values for locals.  MI uses the
	 simple/no/all system.  */
      if (! ui_out_is_mi_like_p (out))
	{
	  int val_indent = (indent + 1) * 4;

	  if (py_print_value (out, val, &opts, val_indent, args_type,
			      language) == EXT_LANG_BT_ERROR)
	    {
	      do_cleanups (locals_cleanups);
	      goto error;
	    }
	}
      else
	{
	  if (args_type != NO_VALUES)
	    {
	      if (py_print_value (out, val, &opts, 0, args_type,
				  language) == EXT_LANG_BT_ERROR)
		{
		  do_cleanups (locals_cleanups);
		  goto error;
		}
	    }
	}

      do_cleanups (locals_cleanups);

      TRY
	{
	  ui_out_text (out, "\n");
	}
      CATCH (except, RETURN_MASK_ERROR)
	{
	  gdbpy_convert_exception (except);
	  goto error;
	}
      END_CATCH
    }

  if (item == NULL && PyErr_Occurred ())
    goto error;

  return EXT_LANG_BT_OK;

 error:
  return EXT_LANG_BT_ERROR;
}

/*  Helper function for -stack-list-variables.  Returns EXT_LANG_BT_ERROR on
    error, or EXT_LANG_BT_OK on success.  */

static enum ext_lang_bt_status
py_mi_print_variables (PyObject *filter, struct ui_out *out,
		       struct value_print_options *opts,
		       enum ext_lang_frame_args args_type,
		       struct frame_info *frame)
{
  struct cleanup *old_chain;
  PyObject *args_iter;
  PyObject *locals_iter;

  args_iter = get_py_iter_from_func (filter, "frame_args");
  old_chain = make_cleanup_py_xdecref (args_iter);
  if (args_iter == NULL)
    goto error;

  locals_iter = get_py_iter_from_func (filter, "frame_locals");
  if (locals_iter == NULL)
    goto error;

  make_cleanup_py_decref (locals_iter);
  make_cleanup_ui_out_list_begin_end (out, "variables");

  if (args_iter != Py_None)
    if (enumerate_args (args_iter, out, args_type, 1, frame)
	== EXT_LANG_BT_ERROR)
      goto error;

  if (locals_iter != Py_None)
    if (enumerate_locals (locals_iter, out, 1, args_type, 1, frame)
	== EXT_LANG_BT_ERROR)
      goto error;

  do_cleanups (old_chain);
  return EXT_LANG_BT_OK;

 error:
  do_cleanups (old_chain);
  return EXT_LANG_BT_ERROR;
}

/* Helper function for printing locals.  This function largely just
   creates the wrapping tuple, and calls enumerate_locals.  Returns
   EXT_LANG_BT_ERROR on error, or EXT_LANG_BT_OK on success.  */

static enum ext_lang_bt_status
py_print_locals (PyObject *filter,
		 struct ui_out *out,
		 enum ext_lang_frame_args args_type,
		 int indent,
		 struct frame_info *frame)
{
  PyObject *locals_iter = get_py_iter_from_func (filter,
						 "frame_locals");
  struct cleanup *old_chain = make_cleanup_py_xdecref (locals_iter);

  if (locals_iter == NULL)
    goto locals_error;

  make_cleanup_ui_out_list_begin_end (out, "locals");

  if (locals_iter != Py_None)
    if (enumerate_locals (locals_iter, out, indent, args_type,
			  0, frame) == EXT_LANG_BT_ERROR)
      goto locals_error;

  do_cleanups (old_chain);
  return EXT_LANG_BT_OK;

 locals_error:
  do_cleanups (old_chain);
  return EXT_LANG_BT_ERROR;
}

/* Helper function for printing frame arguments.  This function
   largely just creates the wrapping tuple, and calls enumerate_args.
   Returns EXT_LANG_BT_ERROR on error, with any GDB exceptions converted to
   a Python exception, or EXT_LANG_BT_OK on success.  */

static enum ext_lang_bt_status
py_print_args (PyObject *filter,
	       struct ui_out *out,
	       enum ext_lang_frame_args args_type,
	       struct frame_info *frame)
{
  PyObject *args_iter  = get_py_iter_from_func (filter, "frame_args");
  struct cleanup *old_chain = make_cleanup_py_xdecref (args_iter);

  if (args_iter == NULL)
    goto args_error;

  make_cleanup_ui_out_list_begin_end (out, "args");

  TRY
    {
      annotate_frame_args ();
      if (! ui_out_is_mi_like_p (out))
	ui_out_text (out, " (");
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      gdbpy_convert_exception (except);
      goto args_error;
    }
  END_CATCH

  if (args_iter != Py_None)
    if (enumerate_args (args_iter, out, args_type, 0, frame)
	== EXT_LANG_BT_ERROR)
      goto args_error;

  TRY
    {
      if (! ui_out_is_mi_like_p (out))
	ui_out_text (out, ")");
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      gdbpy_convert_exception (except);
      goto args_error;
    }
  END_CATCH

  do_cleanups (old_chain);
  return EXT_LANG_BT_OK;

 args_error:
  do_cleanups (old_chain);
  return EXT_LANG_BT_ERROR;
}

/*  Print a single frame to the designated output stream, detecting
    whether the output is MI or console, and formatting the output
    according to the conventions of that protocol.  FILTER is the
    frame-filter associated with this frame.  FLAGS is an integer
    describing the various print options.  The FLAGS variables is
    described in "apply_frame_filter" function.  ARGS_TYPE is an
    enumerator describing the argument format.  OUT is the output
    stream to print, INDENT is the level of indention for this frame
    (in the case of elided frames), and LEVELS_PRINTED is a hash-table
    containing all the frames level that have already been printed.
    If a frame level has been printed, do not print it again (in the
    case of elided frames).  Returns EXT_LANG_BT_ERROR on error, with any
    GDB exceptions converted to a Python exception, or EXT_LANG_BT_COMPLETED
    on success.  It can also throw an exception RETURN_QUIT.  */

static enum ext_lang_bt_status
py_print_frame (PyObject *filter, int flags,
		enum ext_lang_frame_args args_type,
		struct ui_out *out, int indent, htab_t levels_printed)
{
  int has_addr = 0;
  CORE_ADDR address = 0;
  struct gdbarch *gdbarch = NULL;
  struct frame_info *frame = NULL;
  struct cleanup *cleanup_stack;
  struct value_print_options opts;
  PyObject *py_inf_frame;
  int print_level, print_frame_info, print_args, print_locals;
  gdb::unique_xmalloc_ptr<char> function_to_free;

  /* Extract print settings from FLAGS.  */
  print_level = (flags & PRINT_LEVEL) ? 1 : 0;
  print_frame_info = (flags & PRINT_FRAME_INFO) ? 1 : 0;
  print_args = (flags & PRINT_ARGS) ? 1 : 0;
  print_locals = (flags & PRINT_LOCALS) ? 1 : 0;

  get_user_print_options (&opts);

  /* Get the underlying frame.  This is needed to determine GDB
  architecture, and also, in the cases of frame variables/arguments to
  read them if they returned filter object requires us to do so.  */
  py_inf_frame = PyObject_CallMethod (filter, "inferior_frame", NULL);
  if (py_inf_frame == NULL)
    return EXT_LANG_BT_ERROR;

  frame = frame_object_to_frame_info (py_inf_frame);;

  Py_DECREF (py_inf_frame);

  if (frame == NULL)
    return EXT_LANG_BT_ERROR;

  TRY
    {
      gdbarch = get_frame_arch (frame);
    }
  CATCH (except, RETURN_MASK_ERROR)
    {
      gdbpy_convert_exception (except);
      return EXT_LANG_BT_ERROR;
    }
  END_CATCH

  /* stack-list-variables.  */
  if (print_locals && print_args && ! print_frame_info)
    {
      if (py_mi_print_variables (filter, out, &opts,
				 args_type, frame) == EXT_LANG_BT_ERROR)
	return EXT_LANG_BT_ERROR;
      return EXT_LANG_BT_COMPLETED;
    }

  cleanup_stack = make_cleanup (null_cleanup, NULL);

  /* -stack-list-locals does not require a
     wrapping frame attribute.  */
  if (print_frame_info || (print_args && ! print_locals))
    make_cleanup_ui_out_tuple_begin_end (out, "frame");

  if (print_frame_info)
    {
      /* Elided frames are also printed with this function (recursively)
	 and are printed with indention.  */
      if (indent > 0)
	{
	  TRY
	    {
	      ui_out_spaces (out, indent*4);
	    }
	  CATCH (except, RETURN_MASK_ERROR)
	    {
	      gdbpy_convert_exception (except);
	      do_cleanups (cleanup_stack);
	      return EXT_LANG_BT_ERROR;
	    }
	  END_CATCH
	}

      /* The address is required for frame annotations, and also for
	 address printing.  */
      if (PyObject_HasAttrString (filter, "address"))
	{
	  PyObject *paddr = PyObject_CallMethod (filter, "address", NULL);

	  if (paddr == NULL)
	    {
	      do_cleanups (cleanup_stack);
	      return EXT_LANG_BT_ERROR;
	    }

	  if (paddr != Py_None)
	    {
	      if (get_addr_from_python (paddr, &address) < 0)
		{
		  Py_DECREF (paddr);
		  do_cleanups (cleanup_stack);
		  return EXT_LANG_BT_ERROR;
		}

	      has_addr = 1;
	    }
	  Py_DECREF (paddr);
	}
    }

  /* Print frame level.  MI does not require the level if
     locals/variables only are being printed.  */
  if ((print_frame_info || print_args) && print_level)
    {
      struct frame_info **slot;
      int level;

      slot = (struct frame_info **) htab_find_slot (levels_printed,
						    frame, INSERT);
      TRY
	{
	  level = frame_relative_level (frame);

	  /* Check if this frame has already been printed (there are cases
	     where elided synthetic dummy-frames have to 'borrow' the frame
	     architecture from the eliding frame.  If that is the case, do
	     not print 'level', but print spaces.  */
	  if (*slot == frame)
	    ui_out_field_skip (out, "level");
	  else
	    {
	      *slot = frame;
	      annotate_frame_begin (print_level ? level : 0,
				    gdbarch, address);
	      ui_out_text (out, "#");
	      ui_out_field_fmt_int (out, 2, ui_left, "level",
				    level);
	    }
	}
      CATCH (except, RETURN_MASK_ERROR)
	{
	  gdbpy_convert_exception (except);
	  do_cleanups (cleanup_stack);
	  return EXT_LANG_BT_ERROR;
	}
      END_CATCH
    }

  if (print_frame_info)
    {
      /* Print address to the address field.  If an address is not provided,
	 print nothing.  */
      if (opts.addressprint && has_addr)
	{
	  TRY
	    {
	      annotate_frame_address ();
	      ui_out_field_core_addr (out, "addr", gdbarch, address);
	      annotate_frame_address_end ();
	      ui_out_text (out, " in ");
	    }
	  CATCH (except, RETURN_MASK_ERROR)
	    {
	      gdbpy_convert_exception (except);
	      do_cleanups (cleanup_stack);
	      return EXT_LANG_BT_ERROR;
	    }
	  END_CATCH
	}

      /* Print frame function name.  */
      if (PyObject_HasAttrString (filter, "function"))
	{
	  PyObject *py_func = PyObject_CallMethod (filter, "function", NULL);
	  struct cleanup *py_func_cleanup;
	  const char *function = NULL;

	  if (py_func == NULL)
	    {
	      do_cleanups (cleanup_stack);
	      return EXT_LANG_BT_ERROR;
	    }
	  py_func_cleanup = make_cleanup_py_decref (py_func);

	  if (gdbpy_is_string (py_func))
	    {
	      function_to_free = python_string_to_host_string (py_func);

	      if (function_to_free == NULL)
		{
		  do_cleanups (cleanup_stack);
		  return EXT_LANG_BT_ERROR;
		}

	      function = function_to_free.get ();
	    }
	  else if (PyLong_Check (py_func))
	    {
	      CORE_ADDR addr;
	      struct bound_minimal_symbol msymbol;

	      if (get_addr_from_python (py_func, &addr) < 0)
		{
		  do_cleanups (cleanup_stack);
		  return EXT_LANG_BT_ERROR;
		}

	      msymbol = lookup_minimal_symbol_by_pc (addr);
	      if (msymbol.minsym != NULL)
		function = MSYMBOL_PRINT_NAME (msymbol.minsym);
	    }
	  else if (py_func != Py_None)
	    {
	      PyErr_SetString (PyExc_RuntimeError,
			       _("FrameDecorator.function: expecting a " \
				 "String, integer or None."));
	      do_cleanups (cleanup_stack);
	      return EXT_LANG_BT_ERROR;
	    }

	  TRY
	    {
	      annotate_frame_function_name ();
	      if (function == NULL)
		ui_out_field_skip (out, "func");
	      else
		ui_out_field_string (out, "func", function);
	    }
	  CATCH (except, RETURN_MASK_ERROR)
	    {
	      gdbpy_convert_exception (except);
	      do_cleanups (cleanup_stack);
	      return EXT_LANG_BT_ERROR;
	    }
	  END_CATCH

	  do_cleanups (py_func_cleanup);
	}
    }


  /* Frame arguments.  Check the result, and error if something went
     wrong.  */
  if (print_args)
    {
      if (py_print_args (filter, out, args_type, frame) == EXT_LANG_BT_ERROR)
	{
	  do_cleanups (cleanup_stack);
	  return EXT_LANG_BT_ERROR;
	}
    }

  /* File name/source/line number information.  */
  if (print_frame_info)
    {
      TRY
	{
	  annotate_frame_source_begin ();
	}
      CATCH (except, RETURN_MASK_ERROR)
	{
	  gdbpy_convert_exception (except);
	  do_cleanups (cleanup_stack);
	  return EXT_LANG_BT_ERROR;
	}
      END_CATCH

      if (PyObject_HasAttrString (filter, "filename"))
	{
	  PyObject *py_fn = PyObject_CallMethod (filter, "filename", NULL);
	  struct cleanup *py_fn_cleanup;

	  if (py_fn == NULL)
	    {
	      do_cleanups (cleanup_stack);
	      return EXT_LANG_BT_ERROR;
	    }
	  py_fn_cleanup = make_cleanup_py_decref (py_fn);

	  if (py_fn != Py_None)
	    {
	      gdb::unique_xmalloc_ptr<char>
		filename (python_string_to_host_string (py_fn));

	      if (filename == NULL)
		{
		  do_cleanups (cleanup_stack);
		  return EXT_LANG_BT_ERROR;
		}

	      TRY
		{
		  ui_out_wrap_hint (out, "   ");
		  ui_out_text (out, " at ");
		  annotate_frame_source_file ();
		  ui_out_field_string (out, "file", filename.get ());
		  annotate_frame_source_file_end ();
		}
	      CATCH (except, RETURN_MASK_ERROR)
		{
		  gdbpy_convert_exception (except);
		  do_cleanups (cleanup_stack);
		  return EXT_LANG_BT_ERROR;
		}
	      END_CATCH
	    }
	  do_cleanups (py_fn_cleanup);
	}

      if (PyObject_HasAttrString (filter, "line"))
	{
	  PyObject *py_line = PyObject_CallMethod (filter, "line", NULL);
	  struct cleanup *py_line_cleanup;
	  int line;

	  if (py_line == NULL)
	    {
	      do_cleanups (cleanup_stack);
	      return EXT_LANG_BT_ERROR;
	    }
	  py_line_cleanup = make_cleanup_py_decref (py_line);

	  if (py_line != Py_None)
	    {
	      line = PyLong_AsLong (py_line);
	      if (PyErr_Occurred ())
		{
		  do_cleanups (cleanup_stack);
		  return EXT_LANG_BT_ERROR;
		}

	      TRY
		{
		  ui_out_text (out, ":");
		  annotate_frame_source_line ();
		  ui_out_field_int (out, "line", line);
		}
	      CATCH (except, RETURN_MASK_ERROR)
		{
		  gdbpy_convert_exception (except);
		  do_cleanups (cleanup_stack);
		  return EXT_LANG_BT_ERROR;
		}
	      END_CATCH
	    }
	  do_cleanups (py_line_cleanup);
	}
    }

  /* For MI we need to deal with the "children" list population of
     elided frames, so if MI output detected do not send newline.  */
  if (! ui_out_is_mi_like_p (out))
    {
      TRY
	{
	  annotate_frame_end ();
	  ui_out_text (out, "\n");
	}
      CATCH (except, RETURN_MASK_ERROR)
	{
	  gdbpy_convert_exception (except);
	  do_cleanups (cleanup_stack);
	  return EXT_LANG_BT_ERROR;
	}
      END_CATCH
    }

  if (print_locals)
    {
      if (py_print_locals (filter, out, args_type, indent,
			   frame) == EXT_LANG_BT_ERROR)
	{
	  do_cleanups (cleanup_stack);
	  return EXT_LANG_BT_ERROR;
	}
    }

  {
    PyObject *elided;
    struct cleanup *elided_cleanup;

    /* Finally recursively print elided frames, if any.  */
    elided = get_py_iter_from_func (filter, "elided");
    if (elided == NULL)
      {
	do_cleanups (cleanup_stack);
	return EXT_LANG_BT_ERROR;
      }
    elided_cleanup = make_cleanup_py_decref (elided);

    if (elided != Py_None)
      {
	PyObject *item;

	make_cleanup_ui_out_list_begin_end (out, "children");

	if (! ui_out_is_mi_like_p (out))
	  indent++;

	while ((item = PyIter_Next (elided)))
	  {
	    struct cleanup *item_cleanup = make_cleanup_py_decref (item);

	    enum ext_lang_bt_status success = py_print_frame (item, flags,
							      args_type, out,
							      indent,
							      levels_printed);

	    do_cleanups (item_cleanup);

	    if (success == EXT_LANG_BT_ERROR)
	      {
		do_cleanups (cleanup_stack);
		return EXT_LANG_BT_ERROR;
	      }
	  }
	if (item == NULL && PyErr_Occurred ())
	  {
	    do_cleanups (cleanup_stack);
	    return EXT_LANG_BT_ERROR;
	  }
      }
    do_cleanups (elided_cleanup);
  }

  do_cleanups (cleanup_stack);
  return EXT_LANG_BT_COMPLETED;
}

/* Helper function to initiate frame filter invocation at starting
   frame FRAME.  */

static PyObject *
bootstrap_python_frame_filters (struct frame_info *frame,
				int frame_low, int frame_high)
{
  struct cleanup *cleanups =
    make_cleanup (null_cleanup, NULL);
  PyObject *module, *sort_func, *iterable, *frame_obj, *iterator;
  PyObject *py_frame_low, *py_frame_high;

  frame_obj = frame_info_to_frame_object (frame);
  if (frame_obj == NULL)
    goto error;
  make_cleanup_py_decref (frame_obj);

  module = PyImport_ImportModule ("gdb.frames");
  if (module == NULL)
    goto error;
  make_cleanup_py_decref (module);

  sort_func = PyObject_GetAttrString (module, "execute_frame_filters");
  if (sort_func == NULL)
    goto error;
  make_cleanup_py_decref (sort_func);

  py_frame_low = PyInt_FromLong (frame_low);
  if (py_frame_low == NULL)
    goto error;
  make_cleanup_py_decref (py_frame_low);

  py_frame_high = PyInt_FromLong (frame_high);
  if (py_frame_high == NULL)
    goto error;
  make_cleanup_py_decref (py_frame_high);

  iterable = PyObject_CallFunctionObjArgs (sort_func, frame_obj,
					   py_frame_low,
					   py_frame_high,
					   NULL);
  if (iterable == NULL)
    goto error;

  do_cleanups (cleanups);

  if (iterable != Py_None)
    {
      iterator = PyObject_GetIter (iterable);
      Py_DECREF (iterable);
    }
  else
    {
      return iterable;
    }

  return iterator;

 error:
  do_cleanups (cleanups);
  return NULL;
}

/*  This is the only publicly exported function in this file.  FRAME
    is the source frame to start frame-filter invocation.  FLAGS is an
    integer holding the flags for printing.  The following elements of
    the FRAME_FILTER_FLAGS enum denotes the make-up of FLAGS:
    PRINT_LEVEL is a flag indicating whether to print the frame's
    relative level in the output.  PRINT_FRAME_INFO is a flag that
    indicates whether this function should print the frame
    information, PRINT_ARGS is a flag that indicates whether to print
    frame arguments, and PRINT_LOCALS, likewise, with frame local
    variables.  ARGS_TYPE is an enumerator describing the argument
    format, OUT is the output stream to print.  FRAME_LOW is the
    beginning of the slice of frames to print, and FRAME_HIGH is the
    upper limit of the frames to count.  Returns EXT_LANG_BT_ERROR on error,
    or EXT_LANG_BT_COMPLETED on success.  */

enum ext_lang_bt_status
gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
			  struct frame_info *frame, int flags,
			  enum ext_lang_frame_args args_type,
			  struct ui_out *out, int frame_low, int frame_high)
{
  struct gdbarch *gdbarch = NULL;
  struct cleanup *cleanups;
  enum ext_lang_bt_status success = EXT_LANG_BT_ERROR;
  PyObject *iterable;
  PyObject *item;
  htab_t levels_printed;

  if (!gdb_python_initialized)
    return EXT_LANG_BT_NO_FILTERS;

  TRY
    {
      gdbarch = get_frame_arch (frame);
    }
  CATCH (except, RETURN_MASK_ALL)
    {
      /* Let gdb try to print the stack trace.  */
      return EXT_LANG_BT_NO_FILTERS;
    }
  END_CATCH

  cleanups = ensure_python_env (gdbarch, current_language);

  iterable = bootstrap_python_frame_filters (frame, frame_low, frame_high);

  if (iterable == NULL)
    {
      /* Normally if there is an error GDB prints the exception,
	 abandons the backtrace and exits.  The user can then call "bt
	 no-filters", and get a default backtrace (it would be
	 confusing to automatically start a standard backtrace halfway
	 through a Python filtered backtrace).  However in the case
	 where GDB cannot initialize the frame filters (most likely
	 due to incorrect auto-load paths), GDB has printed nothing.
	 In this case it is OK to print the default backtrace after
	 printing the error message.  GDB returns EXT_LANG_BT_NO_FILTERS
	 here to signify there are no filters after printing the
	 initialization error.  This return code will trigger a
	 default backtrace.  */

      gdbpy_print_stack ();
      do_cleanups (cleanups);
      return EXT_LANG_BT_NO_FILTERS;
    }

  /* If iterable is None, then there are no frame filters registered.
     If this is the case, defer to default GDB printing routines in MI
     and CLI.  */
  make_cleanup_py_decref (iterable);
  if (iterable == Py_None)
    {
      success = EXT_LANG_BT_NO_FILTERS;
      goto done;
    }

  levels_printed = htab_create (20,
				htab_hash_pointer,
				htab_eq_pointer,
				NULL);
  make_cleanup_htab_delete (levels_printed);

  while ((item = PyIter_Next (iterable)))
    {
      struct cleanup *item_cleanup = make_cleanup_py_decref (item);

      success = py_print_frame (item, flags, args_type, out, 0,
				levels_printed);

      do_cleanups (item_cleanup);

      /* Do not exit on error printing a single frame.  Print the
	 error and continue with other frames.  */
      if (success == EXT_LANG_BT_ERROR)
	gdbpy_print_stack ();
    }

  if (item == NULL && PyErr_Occurred ())
    goto error;

 done:
  do_cleanups (cleanups);
  return success;

  /* Exit and abandon backtrace on error, printing the exception that
     is set.  */
 error:
  gdbpy_print_stack ();
  do_cleanups (cleanups);
  return EXT_LANG_BT_ERROR;
}
