Class-ify ui_out
[deliverable/binutils-gdb.git] / gdb / python / py-framefilter.c
index 76ce4e56670652687386409f199ccca06192b134..67ad65a7cf441e2b7fb4f747e73f7ee0d950ada7 100644 (file)
@@ -1,6 +1,6 @@
 /* Python frame filters
 
-   Copyright (C) 2013-2014 Free Software Foundation, Inc.
+   Copyright (C) 2013-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -21,7 +21,6 @@
 #include "objfiles.h"
 #include "symtab.h"
 #include "language.h"
-#include "exceptions.h"
 #include "arch-utils.h"
 #include "python.h"
 #include "ui-out.h"
@@ -44,21 +43,23 @@ enum mi_print_types
    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.  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
-   PY_BT_ERROR on error with the appropriate Python exception set, and
-   PY_BT_OK on success.  */
-
-static enum py_bt_status
-extract_sym (PyObject *obj, char **name, struct symbol **sym,
+   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 PY_BT_ERROR;
+    return EXT_LANG_BT_ERROR;
 
   /* For 'symbol' callback, the function can return a symbol or a
      string.  */
@@ -68,7 +69,7 @@ extract_sym (PyObject *obj, char **name, struct symbol **sym,
       Py_DECREF (result);
 
       if (*name == NULL)
-       return PY_BT_ERROR;
+       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
@@ -76,12 +77,18 @@ extract_sym (PyObject *obj, char **name, struct symbol **sym,
        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);
 
@@ -90,12 +97,12 @@ extract_sym (PyObject *obj, char **name, struct symbol **sym,
          PyErr_SetString (PyExc_RuntimeError,
                           _("Unexpected value.  Expecting a "
                             "gdb.Symbol or a Python string."));
-         return PY_BT_ERROR;
+         return EXT_LANG_BT_ERROR;
        }
 
       /* Duplicate the symbol name, so the caller has consistency
         in garbage collection.  */
-      *name = xstrdup (SYMBOL_PRINT_NAME (*sym));
+      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
@@ -106,7 +113,7 @@ extract_sym (PyObject *obj, char **name, struct symbol **sym,
        *language = current_language;
     }
 
-  return PY_BT_OK;
+  return EXT_LANG_BT_OK;
 }
 
 /* Helper function to extract a value from an object that conforms to
@@ -114,11 +121,11 @@ extract_sym (PyObject *obj, char **name, struct symbol **sym,
    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 PY_BT_ERROR
-   on error with the appropriate Python exception set, and PY_BT_OK on
+   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 py_bt_status
+static enum ext_lang_bt_status
 extract_value (PyObject *obj, struct value **value)
 {
   if (PyObject_HasAttrString (obj, "value"))
@@ -126,7 +133,7 @@ extract_value (PyObject *obj, struct value **value)
       PyObject *vresult = PyObject_CallMethod (obj, "value", NULL);
 
       if (vresult == NULL)
-       return PY_BT_ERROR;
+       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
@@ -135,7 +142,7 @@ extract_value (PyObject *obj, struct value **value)
        {
          Py_DECREF (vresult);
          *value = NULL;
-         return PY_BT_OK;
+         return EXT_LANG_BT_OK;
        }
       else
        {
@@ -143,15 +150,15 @@ extract_value (PyObject *obj, struct value **value)
          Py_DECREF (vresult);
 
          if (*value == NULL)
-           return PY_BT_ERROR;
+           return EXT_LANG_BT_ERROR;
 
-         return PY_BT_OK;
+         return EXT_LANG_BT_OK;
        }
     }
   else
     *value = NULL;
 
-  return PY_BT_OK;
+  return EXT_LANG_BT_OK;
 }
 
 /* MI prints only certain values according to the type of symbol and
@@ -195,35 +202,34 @@ mi_should_print (struct symbol *sym, enum mi_print_types type)
 /* 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 PY_BT_ERROR on error, with
-   any GDB exceptions converted to a Python exception, or PY_BT_OK on
+   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 py_bt_status
+static enum ext_lang_bt_status
 py_print_type (struct ui_out *out, struct value *val)
 {
-  volatile struct gdb_exception except;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
-      struct type *type;
       struct ui_file *stb;
       struct cleanup *cleanup;
 
       stb = mem_fileopen ();
       cleanup = make_cleanup_ui_file_delete (stb);
-      type = check_typedef (value_type (val));
+      check_typedef (value_type (val));
       type_print (value_type (val), "", stb, -1);
-      ui_out_field_stream (out, "type", stb);
+      out->field_stream ("type", stb);
       do_cleanups (cleanup);
     }
-  if (except.reason < 0)
+  CATCH (except, RETURN_MASK_ALL)
     {
       gdbpy_convert_exception (except);
-      return PY_BT_ERROR;
+      return EXT_LANG_BT_ERROR;
     }
+  END_CATCH
 
-  return PY_BT_OK;
+  return EXT_LANG_BT_OK;
 }
 
 /* Helper function which outputs a value to an output field in a
@@ -231,24 +237,18 @@ py_print_type (struct ui_out *out, struct value *val)
    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 PY_BT_ERROR on error, with any GDB
-   exceptions converted to a Python exception, or PY_BT_OK on
+   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 py_bt_status
+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 py_frame_args args_type,
+               enum ext_lang_frame_args args_type,
                const struct language_defn *language)
 {
   int should_print = 0;
-  volatile struct gdb_exception except;
-  int local_indent = (4 * indent);
-
-  /* Never set an indent level for common_val_print if MI.  */
-  if (ui_out_is_mi_like_p (out))
-    local_indent = 0;
 
   /* MI does not print certain values, differentiated by type,
      depending on what ARGS_TYPE indicates.  Test type against option.
@@ -258,15 +258,16 @@ py_print_value (struct ui_out *out, struct value *val,
     {
       struct type *type = NULL;
 
-      TRY_CATCH (except, RETURN_MASK_ALL)
+      TRY
        {
          type = check_typedef (value_type (val));
        }
-      if (except.reason < 0)
+      CATCH (except, RETURN_MASK_ALL)
        {
          gdbpy_convert_exception (except);
-         return PY_BT_ERROR;
+         return EXT_LANG_BT_ERROR;
        }
+      END_CATCH
 
       if (args_type == MI_PRINT_ALL_VALUES)
        should_print = 1;
@@ -281,7 +282,7 @@ py_print_value (struct ui_out *out, struct value *val,
 
   if (should_print)
     {
-      TRY_CATCH (except, RETURN_MASK_ALL)
+      TRY
        {
          struct ui_file *stb;
          struct cleanup *cleanup;
@@ -289,17 +290,18 @@ py_print_value (struct ui_out *out, struct value *val,
          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);
+         out->field_stream ("value", stb);
          do_cleanups (cleanup);
        }
-      if (except.reason < 0)
+      CATCH (except, RETURN_MASK_ALL)
        {
          gdbpy_convert_exception (except);
-         return PY_BT_ERROR;
+         return EXT_LANG_BT_ERROR;
        }
+      END_CATCH
     }
 
-  return PY_BT_OK;
+  return EXT_LANG_BT_OK;
 }
 
 /* Helper function to call a Python method and extract an iterator
@@ -350,31 +352,33 @@ get_py_iter_from_func (PyObject *filter, char *func)
     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 PY_BT_ERROR on error, with any GDB exceptions
-    converted to a Python exception, or PY_BT_OK on success.  */
+    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 py_bt_status
+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 py_frame_args args_type,
+                    enum ext_lang_frame_args args_type,
                     int print_args_field,
                     const struct language_defn *language)
 {
   struct value *val;
-  volatile struct gdb_exception except;
+  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_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
 
@@ -384,7 +388,7 @@ py_print_single_arg (struct ui_out *out,
       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 (out->is_mi_like_p ())
        {
          if (print_args_field || args_type != NO_VALUES)
            make_cleanup_ui_out_tuple_begin_end (out, NULL);
@@ -416,65 +420,70 @@ py_print_single_arg (struct ui_out *out,
            {
              fputs_filtered ("@entry", stb);
            }
-         ui_out_field_stream (out, "name", stb);
+         out->field_stream ("name", stb);
        }
       else
        /* Otherwise, just output the name.  */
-       ui_out_field_string (out, "name", sym_name);
+       out->field_string ("name", sym_name);
 
       annotate_arg_name_end ();
 
-      if (! ui_out_is_mi_like_p (out))
-       ui_out_text (out, "=");
+      if (! out->is_mi_like_p ())
+       out->text ("=");
 
       if (print_args_field)
-       ui_out_field_int (out, "arg", 1);
+       out->field_int ("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)
+      if (args_type == MI_PRINT_SIMPLE_VALUES && val != NULL)
        {
-         if (py_print_type (out, val) == PY_BT_ERROR)
+         if (py_print_type (out, val) == EXT_LANG_BT_ERROR)
            {
+             retval = EXT_LANG_BT_ERROR;
              do_cleanups (cleanups);
-             goto error;
            }
        }
 
-      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
+      if (retval != EXT_LANG_BT_ERROR)
        {
-         /* 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)
+           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 (! out->is_mi_like_p () && args_type == NO_VALUES)
+           out->field_string ("value", "...");
+         else
            {
-             if (py_print_value (out, val, opts, 0, args_type, language)
-                 == PY_BT_ERROR)
+             /* Otherwise, print the value for both MI and the CLI, except
+                for the case of MI_PRINT_NO_VALUES.  */
+             if (args_type != NO_VALUES)
                {
-                 do_cleanups (cleanups);
-                 goto error;
+                 if (val == NULL)
+                   {
+                     gdb_assert (fa != NULL && fa->error != NULL);
+                     out->field_fmt ("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);
+         do_cleanups (cleanups);
+       }
     }
-  if (except.reason < 0)
+  CATCH (except, RETURN_MASK_ERROR)
     {
       gdbpy_convert_exception (except);
-      goto error;
     }
+  END_CATCH
 
-  return PY_BT_OK;
-
- error:
-  return PY_BT_ERROR;
+  return retval;
 }
 
 /* Helper function to loop over frame arguments provided by the
@@ -484,20 +493,19 @@ py_print_single_arg (struct ui_out *out,
    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 PY_BT_ERROR on error, with any GDB
-   exceptions converted to a Python exception, or PY_BT_OK on
+   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 py_bt_status
+static enum ext_lang_bt_status
 enumerate_args (PyObject *iter,
                struct ui_out *out,
-               enum py_frame_args args_type,
+               enum ext_lang_frame_args args_type,
                int print_args_field,
                struct frame_info *frame)
 {
   PyObject *item;
   struct value_print_options opts;
-  volatile struct gdb_exception except;
 
   get_user_print_options (&opts);
 
@@ -509,15 +517,16 @@ enumerate_args (PyObject *iter,
 
   opts.deref_ref = 1;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       annotate_frame_args ();
     }
-  if (except.reason < 0)
+  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
@@ -530,22 +539,22 @@ enumerate_args (PyObject *iter,
   while (item)
     {
       const struct language_defn *language;
-      char *sym_name;
+      gdb::unique_xmalloc_ptr<char> sym_name;
       struct symbol *sym;
+      struct block *sym_block;
       struct value *val;
-      enum py_bt_status success = PY_BT_ERROR;
+      enum ext_lang_bt_status success = EXT_LANG_BT_ERROR;
 
-      success = extract_sym (item, &sym_name, &sym, &language);
-      if (success == PY_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 == PY_BT_ERROR)
+      if (success == EXT_LANG_BT_ERROR)
        {
-         xfree (sym_name);
          Py_DECREF (item);
          goto error;
        }
@@ -553,12 +562,9 @@ enumerate_args (PyObject *iter,
       Py_DECREF (item);
       item = NULL;
 
-      if (sym && ui_out_is_mi_like_p (out)
+      if (sym && out->is_mi_like_p ()
          && ! mi_should_print (sym, MI_PRINT_ARGS))
-       {
-         xfree (sym_name);
-         continue;
-       }
+       continue;
 
       /* If the object did not provide a value, read it using
         read_frame_args and account for entry values, if any.  */
@@ -572,20 +578,19 @@ enumerate_args (PyObject *iter,
            {
              PyErr_SetString (PyExc_RuntimeError,
                               _("No symbol or value provided."));
-             xfree (sym_name);
              goto error;
            }
 
-         TRY_CATCH (except, RETURN_MASK_ALL)
+         TRY
            {
              read_frame_arg (sym, frame, &arg, &entryarg);
            }
-         if (except.reason < 0)
+         CATCH (except, RETURN_MASK_ALL)
            {
-             xfree (sym_name);
              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
@@ -597,11 +602,10 @@ enumerate_args (PyObject *iter,
                                       NULL, &opts,
                                       args_type,
                                       print_args_field,
-                                      NULL) == PY_BT_ERROR)
+                                      NULL) == EXT_LANG_BT_ERROR)
                {
                  xfree (arg.error);
                  xfree (entryarg.error);
-                 xfree (sym_name);
                  goto error;
                }
            }
@@ -610,28 +614,27 @@ enumerate_args (PyObject *iter,
            {
              if (arg.entry_kind != print_entry_values_only)
                {
-                 TRY_CATCH (except, RETURN_MASK_ALL)
+                 TRY
                    {
-                     ui_out_text (out, ", ");
-                     ui_out_wrap_hint (out, "    ");
+                     out->text (", ");
+                     out->wrap_hint ("    ");
                    }
-                 if (except.reason < 0)
+                 CATCH (except, RETURN_MASK_ALL)
                    {
                      xfree (arg.error);
                      xfree (entryarg.error);
-                     xfree (sym_name);
                      gdbpy_convert_exception (except);
                      goto error;
                    }
+                 END_CATCH
                }
 
-             if (py_print_single_arg (out, NULL, &entryarg, NULL,
-                                     &opts, args_type,
-                                     print_args_field, NULL) == PY_BT_ERROR)
+             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);
-                     xfree (sym_name);
                      goto error;
                }
            }
@@ -644,54 +647,51 @@ enumerate_args (PyObject *iter,
          /* If the object has provided a value, we just print that.  */
          if (val != NULL)
            {
-             if (py_print_single_arg (out, sym_name, NULL, val, &opts,
+             if (py_print_single_arg (out, sym_name.get (), NULL, val, &opts,
                                       args_type, print_args_field,
-                                      language) == PY_BT_ERROR)
-               {
-                 xfree (sym_name);
-                 goto error;
-               }
+                                      language) == EXT_LANG_BT_ERROR)
+               goto error;
            }
        }
 
-      xfree (sym_name);
-
       /* 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_CATCH (except, RETURN_MASK_ALL)
+         TRY
            {
-             ui_out_text (out, ", ");
+             out->text (", ");
            }
-         if (except.reason < 0)
+         CATCH (except, RETURN_MASK_ALL)
            {
              Py_DECREF (item);
              gdbpy_convert_exception (except);
              goto error;
            }
+         END_CATCH
        }
       else if (PyErr_Occurred ())
        goto error;
 
-      TRY_CATCH (except, RETURN_MASK_ALL)
+      TRY
        {
          annotate_arg_end ();
        }
-      if (except.reason < 0)
+      CATCH (except, RETURN_MASK_ALL)
        {
          Py_DECREF (item);
          gdbpy_convert_exception (except);
          goto error;
        }
+      END_CATCH
     }
 
-  return PY_BT_OK;
+  return EXT_LANG_BT_OK;
 
  error:
-  return PY_BT_ERROR;
+  return EXT_LANG_BT_ERROR;
 }
 
 
@@ -703,14 +703,14 @@ enumerate_args (PyObject *iter,
    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
-   PY_BT_ERROR on error, with any GDB exceptions converted to a Python
-   exception, or PY_BT_OK on success.  */
+   EXT_LANG_BT_ERROR on error, with any GDB exceptions converted to a Python
+   exception, or EXT_LANG_BT_OK on success.  */
 
-static enum py_bt_status
+static enum ext_lang_bt_status
 enumerate_locals (PyObject *iter,
                  struct ui_out *out,
                  int indent,
-                 enum py_frame_args args_type,
+                 enum ext_lang_frame_args args_type,
                  int print_args_field,
                  struct frame_info *frame)
 {
@@ -723,33 +723,31 @@ enumerate_locals (PyObject *iter,
   while ((item = PyIter_Next (iter)))
     {
       const struct language_defn *language;
-      char *sym_name;
+      gdb::unique_xmalloc_ptr<char> sym_name;
       struct value *val;
-      enum py_bt_status  success = PY_BT_ERROR;
+      enum ext_lang_bt_status success = EXT_LANG_BT_ERROR;
       struct symbol *sym;
-      volatile struct gdb_exception except;
+      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, &language);
-      if (success == PY_BT_ERROR)
+      success = extract_sym (item, &sym_name, &sym, &sym_block, &language);
+      if (success == EXT_LANG_BT_ERROR)
        {
          do_cleanups (locals_cleanups);
          goto error;
        }
 
-      make_cleanup (xfree, sym_name);
-
       success = extract_value (item, &val);
-      if (success == PY_BT_ERROR)
+      if (success == EXT_LANG_BT_ERROR)
        {
          do_cleanups (locals_cleanups);
          goto error;
        }
 
-      if (sym != NULL && ui_out_is_mi_like_p (out)
+      if (sym != NULL && out->is_mi_like_p ()
          && ! mi_should_print (sym, MI_PRINT_LOCALS))
        {
          do_cleanups (locals_cleanups);
@@ -759,49 +757,51 @@ enumerate_locals (PyObject *iter,
       /* If the object did not provide a value, read it.  */
       if (val == NULL)
        {
-         TRY_CATCH (except, RETURN_MASK_ALL)
+         TRY
            {
-             val = read_var_value (sym, frame);
+             val = read_var_value (sym, sym_block, frame);
            }
-         if (except.reason < 0)
+         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 (out->is_mi_like_p ())
        {
          if (print_args_field || args_type != NO_VALUES)
            make_cleanup_ui_out_tuple_begin_end (out, NULL);
        }
-      TRY_CATCH (except, RETURN_MASK_ALL)
+      TRY
        {
-         if (! ui_out_is_mi_like_p (out))
+         if (! out->is_mi_like_p ())
            {
              /* If the output is not MI we indent locals.  */
-             ui_out_spaces (out, local_indent);
+             out->spaces (local_indent);
            }
 
-         ui_out_field_string (out, "name", sym_name);
+         out->field_string ("name", sym_name.get ());
 
-         if (! ui_out_is_mi_like_p (out))
-           ui_out_text (out, " = ");
+         if (! out->is_mi_like_p ())
+           out->text (" = ");
        }
-      if (except.reason < 0)
+      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) == PY_BT_ERROR)
+         if (py_print_type (out, val) == EXT_LANG_BT_ERROR)
            {
              do_cleanups (locals_cleanups);
              goto error;
@@ -810,12 +810,12 @@ enumerate_locals (PyObject *iter,
 
       /* CLI always prints values for locals.  MI uses the
         simple/no/all system.  */
-      if (! ui_out_is_mi_like_p (out))
+      if (! out->is_mi_like_p ())
        {
          int val_indent = (indent + 1) * 4;
 
          if (py_print_value (out, val, &opts, val_indent, args_type,
-                             language) ==  PY_BT_ERROR)
+                             language) == EXT_LANG_BT_ERROR)
            {
              do_cleanups (locals_cleanups);
              goto error;
@@ -826,7 +826,7 @@ enumerate_locals (PyObject *iter,
          if (args_type != NO_VALUES)
            {
              if (py_print_value (out, val, &opts, 0, args_type,
-                                 language) ==  PY_BT_ERROR)
+                                 language) == EXT_LANG_BT_ERROR)
                {
                  do_cleanups (locals_cleanups);
                  goto error;
@@ -836,33 +836,34 @@ enumerate_locals (PyObject *iter,
 
       do_cleanups (locals_cleanups);
 
-      TRY_CATCH (except, RETURN_MASK_ALL)
+      TRY
        {
-         ui_out_text (out, "\n");
+         out->text ("\n");
        }
-      if (except.reason < 0)
+      CATCH (except, RETURN_MASK_ERROR)
        {
          gdbpy_convert_exception (except);
          goto error;
        }
+      END_CATCH
     }
 
   if (item == NULL && PyErr_Occurred ())
     goto error;
 
-  return PY_BT_OK;
+  return EXT_LANG_BT_OK;
 
  error:
-  return PY_BT_ERROR;
+  return EXT_LANG_BT_ERROR;
 }
 
-/*  Helper function for -stack-list-variables.  Returns PY_BT_ERROR on
-    error, or PY_BT_OK on success.  */
+/*  Helper function for -stack-list-variables.  Returns EXT_LANG_BT_ERROR on
+    error, or EXT_LANG_BT_OK on success.  */
 
-static enum py_bt_status
+static enum ext_lang_bt_status
 py_mi_print_variables (PyObject *filter, struct ui_out *out,
                       struct value_print_options *opts,
-                      enum py_frame_args args_type,
+                      enum ext_lang_frame_args args_type,
                       struct frame_info *frame)
 {
   struct cleanup *old_chain;
@@ -882,30 +883,31 @@ py_mi_print_variables (PyObject *filter, struct ui_out *out,
   make_cleanup_ui_out_list_begin_end (out, "variables");
 
   if (args_iter != Py_None)
-    if (enumerate_args (args_iter, out, args_type, 1, frame) == PY_BT_ERROR)
+    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)
-       == PY_BT_ERROR)
+       == EXT_LANG_BT_ERROR)
       goto error;
 
   do_cleanups (old_chain);
-  return PY_BT_OK;
+  return EXT_LANG_BT_OK;
 
  error:
   do_cleanups (old_chain);
-  return PY_BT_ERROR;
+  return EXT_LANG_BT_ERROR;
 }
 
 /* Helper function for printing locals.  This function largely just
    creates the wrapping tuple, and calls enumerate_locals.  Returns
-   PY_BT_ERROR on error, or PY_BT_OK on success.*/
+   EXT_LANG_BT_ERROR on error, or EXT_LANG_BT_OK on success.  */
 
-static enum py_bt_status
+static enum ext_lang_bt_status
 py_print_locals (PyObject *filter,
                 struct ui_out *out,
-                enum py_frame_args args_type,
+                enum ext_lang_frame_args args_type,
                 int indent,
                 struct frame_info *frame)
 {
@@ -920,70 +922,72 @@ py_print_locals (PyObject *filter,
 
   if (locals_iter != Py_None)
     if (enumerate_locals (locals_iter, out, indent, args_type,
-                         0, frame) == PY_BT_ERROR)
+                         0, frame) == EXT_LANG_BT_ERROR)
       goto locals_error;
 
   do_cleanups (old_chain);
-  return PY_BT_OK;;
+  return EXT_LANG_BT_OK;
 
  locals_error:
   do_cleanups (old_chain);
-  return PY_BT_ERROR;
+  return EXT_LANG_BT_ERROR;
 }
 
 /* Helper function for printing frame arguments.  This function
    largely just creates the wrapping tuple, and calls enumerate_args.
-   Returns PY_BT_ERROR on error, with any GDB exceptions converted to
-   a Python exception, or PY_BT_OK on success.  */
+   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 py_bt_status
+static enum ext_lang_bt_status
 py_print_args (PyObject *filter,
               struct ui_out *out,
-              enum py_frame_args args_type,
+              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);
-  volatile struct gdb_exception except;
 
   if (args_iter == NULL)
     goto args_error;
 
   make_cleanup_ui_out_list_begin_end (out, "args");
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       annotate_frame_args ();
-      if (! ui_out_is_mi_like_p (out))
-       ui_out_text (out, " (");
+      if (! out->is_mi_like_p ())
+       out->text (" (");
     }
-  if (except.reason < 0)
+  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) == PY_BT_ERROR)
+    if (enumerate_args (args_iter, out, args_type, 0, frame)
+       == EXT_LANG_BT_ERROR)
       goto args_error;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
-      if (! ui_out_is_mi_like_p (out))
-       ui_out_text (out, ")");
+      if (! out->is_mi_like_p ())
+       out->text (")");
     }
-  if (except.reason < 0)
+  CATCH (except, RETURN_MASK_ALL)
     {
       gdbpy_convert_exception (except);
       goto args_error;
     }
+  END_CATCH
 
   do_cleanups (old_chain);
-  return PY_BT_OK;
+  return EXT_LANG_BT_OK;
 
  args_error:
   do_cleanups (old_chain);
-  return PY_BT_ERROR;
+  return EXT_LANG_BT_ERROR;
 }
 
 /*  Print a single frame to the designated output stream, detecting
@@ -997,23 +1001,24 @@ py_print_args (PyObject *filter,
     (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 PY_BT_ERROR on error, with any
-    GDB exceptions converted to a Python exception, or PY_BT_COMPLETED
-    on success.  */
+    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 py_bt_status
-py_print_frame (PyObject *filter, int flags, enum py_frame_args args_type,
+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 = make_cleanup (null_cleanup, NULL);
+  struct cleanup *cleanup_stack;
   struct value_print_options opts;
-  PyObject *py_inf_frame, *elided;
+  PyObject *py_inf_frame;
   int print_level, print_frame_info, print_args, print_locals;
-  volatile struct gdb_exception except;
+  gdb::unique_xmalloc_ptr<char> function_to_free;
 
   /* Extract print settings from FLAGS.  */
   print_level = (flags & PRINT_LEVEL) ? 1 : 0;
@@ -1028,39 +1033,37 @@ py_print_frame (PyObject *filter, int flags, enum py_frame_args args_type,
   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)
-    goto error;
+    return EXT_LANG_BT_ERROR;
 
   frame = frame_object_to_frame_info (py_inf_frame);;
 
   Py_DECREF (py_inf_frame);
 
   if (frame == NULL)
-    goto error;
+    return EXT_LANG_BT_ERROR;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       gdbarch = get_frame_arch (frame);
     }
-  if (except.reason < 0)
+  CATCH (except, RETURN_MASK_ERROR)
     {
       gdbpy_convert_exception (except);
-      goto error;
+      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) == PY_BT_ERROR)
-       goto error;
-      else
-       {
-         do_cleanups (cleanup_stack);
-         return PY_BT_COMPLETED;
-       }
+                                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))
@@ -1072,15 +1075,17 @@ py_print_frame (PyObject *filter, int flags, enum py_frame_args args_type,
         and are printed with indention.  */
       if (indent > 0)
        {
-       TRY_CATCH (except, RETURN_MASK_ALL)
-         {
-           ui_out_spaces (out, indent*4);
-         }
-       if (except.reason < 0)
-         {
-           gdbpy_convert_exception (except);
-           goto error;
-         }
+         TRY
+           {
+             out->spaces (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
@@ -1088,17 +1093,25 @@ py_print_frame (PyObject *filter, int flags, enum py_frame_args args_type,
       if (PyObject_HasAttrString (filter, "address"))
        {
          PyObject *paddr = PyObject_CallMethod (filter, "address", NULL);
-         if (paddr != NULL)
+
+         if (paddr == NULL)
            {
-             if (paddr != Py_None)
+             do_cleanups (cleanup_stack);
+             return EXT_LANG_BT_ERROR;
+           }
+
+         if (paddr != Py_None)
+           {
+             if (get_addr_from_python (paddr, &address) < 0)
                {
-                 address = PyLong_AsLong (paddr);
-                 has_addr = 1;
+                 Py_DECREF (paddr);
+                 do_cleanups (cleanup_stack);
+                 return EXT_LANG_BT_ERROR;
                }
-             Py_DECREF (paddr);
+
+             has_addr = 1;
            }
-         else
-           goto error;
+         Py_DECREF (paddr);
        }
     }
 
@@ -1108,11 +1121,10 @@ py_print_frame (PyObject *filter, int flags, enum py_frame_args args_type,
     {
       struct frame_info **slot;
       int level;
-      volatile struct gdb_exception except;
 
       slot = (struct frame_info **) htab_find_slot (levels_printed,
                                                    frame, INSERT);
-      TRY_CATCH (except, RETURN_MASK_ALL)
+      TRY
        {
          level = frame_relative_level (frame);
 
@@ -1121,22 +1133,24 @@ py_print_frame (PyObject *filter, int flags, enum py_frame_args args_type,
             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");
+           out->field_skip ("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",
+             out->text ("#");
+             out->field_fmt_int (2, ui_left, "level",
                                    level);
            }
        }
-      if (except.reason < 0)
+      CATCH (except, RETURN_MASK_ERROR)
        {
          gdbpy_convert_exception (except);
-         goto error;
+         do_cleanups (cleanup_stack);
+         return EXT_LANG_BT_ERROR;
        }
+      END_CATCH
     }
 
   if (print_frame_info)
@@ -1145,84 +1159,90 @@ py_print_frame (PyObject *filter, int flags, enum py_frame_args args_type,
         print nothing.  */
       if (opts.addressprint && has_addr)
        {
-         TRY_CATCH (except, RETURN_MASK_ALL)
+         TRY
            {
              annotate_frame_address ();
-             ui_out_field_core_addr (out, "addr", gdbarch, address);
+             out->field_core_addr ("addr", gdbarch, address);
              annotate_frame_address_end ();
-             ui_out_text (out, " in ");
+             out->text (" in ");
            }
-         if (except.reason < 0)
+         CATCH (except, RETURN_MASK_ERROR)
            {
              gdbpy_convert_exception (except);
-             goto error;
+             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)
+         if (py_func == NULL)
            {
-             const char *function = NULL;
-
-             if (gdbpy_is_string (py_func))
-               {
-                 char *function_to_free = NULL;
+             do_cleanups (cleanup_stack);
+             return EXT_LANG_BT_ERROR;
+           }
+         py_func_cleanup = make_cleanup_py_decref (py_func);
 
-                 function = function_to_free =
-                   python_string_to_host_string (py_func);
+         if (gdbpy_is_string (py_func))
+           {
+             function_to_free = python_string_to_host_string (py_func);
 
-                 if (function == NULL)
-                   {
-                     Py_DECREF (py_func);
-                     goto error;
-                   }
-                 make_cleanup (xfree, function_to_free);
-               }
-             else if (PyLong_Check (py_func))
+             if (function_to_free == NULL)
                {
-                 CORE_ADDR addr = PyLong_AsUnsignedLongLong (py_func);
-                 struct bound_minimal_symbol msymbol;
+                 do_cleanups (cleanup_stack);
+                 return EXT_LANG_BT_ERROR;
+               }
 
-                 if (PyErr_Occurred ())
-                   goto error;
+             function = function_to_free.get ();
+           }
+         else if (PyLong_Check (py_func))
+           {
+             CORE_ADDR addr;
+             struct bound_minimal_symbol msymbol;
 
-                 msymbol = lookup_minimal_symbol_by_pc (addr);
-                 if (msymbol.minsym != NULL)
-                   function = SYMBOL_PRINT_NAME (msymbol.minsym);
-               }
-             else if (py_func != Py_None)
+             if (get_addr_from_python (py_func, &addr) < 0)
                {
-                 PyErr_SetString (PyExc_RuntimeError,
-                                  _("FrameDecorator.function: expecting a " \
-                                    "String, integer or None."));
-                 Py_DECREF (py_func);
-                 goto error;
+                 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_CATCH (except, RETURN_MASK_ALL)
-               {
-                 annotate_frame_function_name ();
-                 if (function == NULL)
-                   ui_out_field_skip (out, "func");
-                 else
-                   ui_out_field_string (out, "func", function);
-               }
-             if (except.reason < 0)
-               {
-                 Py_DECREF (py_func);
-                 gdbpy_convert_exception (except);
-                 goto error;
-               }
+         TRY
+           {
+             annotate_frame_function_name ();
+             if (function == NULL)
+               out->field_skip ("func");
+             else
+               out->field_string ("func", function);
+           }
+         CATCH (except, RETURN_MASK_ERROR)
+           {
+             gdbpy_convert_exception (except);
+             do_cleanups (cleanup_stack);
+             return EXT_LANG_BT_ERROR;
            }
-         Py_DECREF (py_func);
+         END_CATCH
+
+         do_cleanups (py_func_cleanup);
        }
-      else
-       goto error;
     }
 
 
@@ -1230,155 +1250,188 @@ py_print_frame (PyObject *filter, int flags, enum py_frame_args args_type,
      wrong.  */
   if (print_args)
     {
-      if (py_print_args (filter, out, args_type, frame) == PY_BT_ERROR)
-       goto error;
+      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_CATCH (except, RETURN_MASK_ALL)
+      TRY
        {
          annotate_frame_source_begin ();
        }
-      if (except.reason < 0)
+      CATCH (except, RETURN_MASK_ERROR)
        {
          gdbpy_convert_exception (except);
-         goto error;
+         do_cleanups (cleanup_stack);
+         return EXT_LANG_BT_ERROR;
        }
+      END_CATCH
 
       if (PyObject_HasAttrString (filter, "filename"))
        {
-         PyObject *py_fn = PyObject_CallMethod (filter, "filename",
-                                                NULL);
-         if (py_fn != NULL)
+         PyObject *py_fn = PyObject_CallMethod (filter, "filename", NULL);
+         struct cleanup *py_fn_cleanup;
+
+         if (py_fn == NULL)
            {
-             if (py_fn != Py_None)
-               {
-                 char *filename = python_string_to_host_string (py_fn);
+             do_cleanups (cleanup_stack);
+             return EXT_LANG_BT_ERROR;
+           }
+         py_fn_cleanup = make_cleanup_py_decref (py_fn);
 
-                 if (filename == NULL)
-                   {
-                     Py_DECREF (py_fn);
-                     goto error;
-                   }
+         if (py_fn != Py_None)
+           {
+             gdb::unique_xmalloc_ptr<char>
+               filename (python_string_to_host_string (py_fn));
 
-                 make_cleanup (xfree, filename);
-                 TRY_CATCH (except, RETURN_MASK_ALL)
-                   {
-                     ui_out_wrap_hint (out, "   ");
-                     ui_out_text (out, " at ");
-                     annotate_frame_source_file ();
-                     ui_out_field_string (out, "file", filename);
-                     annotate_frame_source_file_end ();
-                   }
-                 if (except.reason < 0)
-                   {
-                     Py_DECREF (py_fn);
-                     gdbpy_convert_exception (except);
-                     goto error;
-                   }
+             if (filename == NULL)
+               {
+                 do_cleanups (cleanup_stack);
+                 return EXT_LANG_BT_ERROR;
+               }
+
+             TRY
+               {
+                 out->wrap_hint ("   ");
+                 out->text (" at ");
+                 annotate_frame_source_file ();
+                 out->field_string ("file", filename.get ());
+                 annotate_frame_source_file_end ();
                }
-             Py_DECREF (py_fn);
+             CATCH (except, RETURN_MASK_ERROR)
+               {
+                 gdbpy_convert_exception (except);
+                 do_cleanups (cleanup_stack);
+                 return EXT_LANG_BT_ERROR;
+               }
+             END_CATCH
            }
-         else
-           goto error;
+         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)
+         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)
            {
-             if (py_line != Py_None)
+             line = PyLong_AsLong (py_line);
+             if (PyErr_Occurred ())
                {
-                 line = PyLong_AsLong (py_line);
-                 TRY_CATCH (except, RETURN_MASK_ALL)
-                   {
-                     ui_out_text (out, ":");
-                     annotate_frame_source_line ();
-                     ui_out_field_int (out, "line", line);
-                   }
-                 if (except.reason < 0)
-                   {
-                     Py_DECREF (py_line);
-                     gdbpy_convert_exception (except);
-                     goto error;
-                   }
+                 do_cleanups (cleanup_stack);
+                 return EXT_LANG_BT_ERROR;
                }
-             Py_DECREF (py_line);
+
+             TRY
+               {
+                 out->text (":");
+                 annotate_frame_source_line ();
+                 out->field_int ("line", line);
+               }
+             CATCH (except, RETURN_MASK_ERROR)
+               {
+                 gdbpy_convert_exception (except);
+                 do_cleanups (cleanup_stack);
+                 return EXT_LANG_BT_ERROR;
+               }
+             END_CATCH
            }
-         else
-           goto error;
+         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))
+  if (! out->is_mi_like_p ())
     {
-      TRY_CATCH (except, RETURN_MASK_ALL)
+      TRY
        {
          annotate_frame_end ();
-         ui_out_text (out, "\n");
+         out->text ("\n");
        }
-      if (except.reason < 0)
+      CATCH (except, RETURN_MASK_ERROR)
        {
          gdbpy_convert_exception (except);
-         goto error;
+         do_cleanups (cleanup_stack);
+         return EXT_LANG_BT_ERROR;
        }
+      END_CATCH
     }
 
   if (print_locals)
     {
       if (py_print_locals (filter, out, args_type, indent,
-                          frame) == PY_BT_ERROR)
-       goto error;
+                          frame) == EXT_LANG_BT_ERROR)
+       {
+         do_cleanups (cleanup_stack);
+         return EXT_LANG_BT_ERROR;
+       }
     }
 
-  /* Finally recursively print elided frames, if any.  */
-  elided  = get_py_iter_from_func (filter, "elided");
-  if (elided == NULL)
-    goto error;
+  {
+    PyObject *elided;
+    struct cleanup *elided_cleanup;
 
-  make_cleanup_py_decref (elided);
-  if (elided != Py_None)
-    {
-      PyObject *item;
+    /* 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);
 
-      make_cleanup_ui_out_list_begin_end (out, "children");
+    if (elided != Py_None)
+      {
+       PyObject *item;
 
-      if (! ui_out_is_mi_like_p (out))
-       indent++;
+       make_cleanup_ui_out_list_begin_end (out, "children");
 
-      while ((item = PyIter_Next (elided)))
-       {
-         enum py_bt_status success = py_print_frame (item, flags,
-                                                     args_type, out,
-                                                     indent,
-                                                     levels_printed);
+       if (! out->is_mi_like_p ())
+         indent++;
 
-         if (success == PY_BT_ERROR)
-           {
-             Py_DECREF (item);
-             goto error;
-           }
+       while ((item = PyIter_Next (elided)))
+         {
+           struct cleanup *item_cleanup = make_cleanup_py_decref (item);
 
-         Py_DECREF (item);
-       }
-      if (item == NULL && PyErr_Occurred ())
-       goto error;
-    }
+           enum ext_lang_bt_status success = py_print_frame (item, flags,
+                                                             args_type, out,
+                                                             indent,
+                                                             levels_printed);
 
+           do_cleanups (item_cleanup);
 
-  do_cleanups (cleanup_stack);
-  return PY_BT_COMPLETED;
+           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);
+  }
 
- error:
   do_cleanups (cleanup_stack);
-  return PY_BT_ERROR;
+  return EXT_LANG_BT_COMPLETED;
 }
 
 /* Helper function to initiate frame filter invocation at starting
@@ -1456,38 +1509,37 @@ bootstrap_python_frame_filters (struct frame_info *frame,
     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 PY_BT_ERROR on error,
-    or PY_BT_COMPLETED on success.*/
-
-enum py_bt_status
-apply_frame_filter (struct frame_info *frame, int flags,
-                   enum py_frame_args args_type,
-                   struct ui_out *out, int frame_low,
-                   int frame_high)
-
+    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 py_bt_status success = PY_BT_ERROR;
+  enum ext_lang_bt_status success = EXT_LANG_BT_ERROR;
   PyObject *iterable;
-  volatile struct gdb_exception except;
   PyObject *item;
   htab_t levels_printed;
 
   if (!gdb_python_initialized)
-    return PY_BT_NO_FILTERS;
+    return EXT_LANG_BT_NO_FILTERS;
 
-  cleanups = ensure_python_env (gdbarch, current_language);
-
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       gdbarch = get_frame_arch (frame);
     }
-  if (except.reason < 0)
+  CATCH (except, RETURN_MASK_ALL)
     {
-      gdbpy_convert_exception (except);
-      goto error;
+      /* 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);
 
@@ -1501,14 +1553,14 @@ apply_frame_filter (struct frame_info *frame, int flags,
         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 PY_BT_NO_FILTERS
+        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 PY_BT_NO_FILTERS;
+      return EXT_LANG_BT_NO_FILTERS;
     }
 
   /* If iterable is None, then there are no frame filters registered.
@@ -1517,7 +1569,7 @@ apply_frame_filter (struct frame_info *frame, int flags,
   make_cleanup_py_decref (iterable);
   if (iterable == Py_None)
     {
-      success = PY_BT_NO_FILTERS;
+      success = EXT_LANG_BT_NO_FILTERS;
       goto done;
     }
 
@@ -1529,15 +1581,17 @@ apply_frame_filter (struct frame_info *frame, int flags,
 
   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 == PY_BT_ERROR)
+      if (success == EXT_LANG_BT_ERROR)
        gdbpy_print_stack ();
-
-      Py_DECREF (item);
     }
 
   if (item == NULL && PyErr_Occurred ())
@@ -1552,5 +1606,5 @@ apply_frame_filter (struct frame_info *frame, int flags,
  error:
   gdbpy_print_stack ();
   do_cleanups (cleanups);
-  return PY_BT_ERROR;
+  return EXT_LANG_BT_ERROR;
 }
This page took 0.058622 seconds and 4 git commands to generate.