Class-ify ui_out
[deliverable/binutils-gdb.git] / gdb / python / py-framefilter.c
index 9db83c702191d2febcfb27261d5eec9684b8101e..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,15 +43,17 @@ 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
-   EXT_LANG_BT_ERROR on error with the appropriate Python exception set, and
-   EXT_LANG_BT_OK on success.  */
+   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, char **name, struct symbol **sym,
+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);
@@ -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);
 
@@ -95,7 +102,7 @@ extract_sym (PyObject *obj, char **name, struct symbol **sym,
 
       /* 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
@@ -202,26 +209,25 @@ mi_should_print (struct symbol *sym, enum mi_print_types type)
 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 EXT_LANG_BT_ERROR;
     }
+  END_CATCH
 
   return EXT_LANG_BT_OK;
 }
@@ -243,12 +249,6 @@ py_print_value (struct ui_out *out, struct value *val,
                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 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,14 +290,15 @@ 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 EXT_LANG_BT_ERROR;
        }
+      END_CATCH
     }
 
   return EXT_LANG_BT_OK;
@@ -364,17 +366,19 @@ py_print_single_arg (struct ui_out *out,
                     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) == 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)
-                 == 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)
                {
-                 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 EXT_LANG_BT_OK;
-
- error:
-  return EXT_LANG_BT_ERROR;
+  return retval;
 }
 
 /* Helper function to loop over frame arguments provided by the
@@ -497,7 +506,6 @@ enumerate_args (PyObject *iter,
 {
   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,12 +539,13 @@ 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 ext_lang_bt_status success = EXT_LANG_BT_ERROR;
 
-      success = extract_sym (item, &sym_name, &sym, &language);
+      success = extract_sym (item, &sym_name, &sym, &sym_block, &language);
       if (success == EXT_LANG_BT_ERROR)
        {
          Py_DECREF (item);
@@ -545,7 +555,6 @@ enumerate_args (PyObject *iter,
       success = extract_value (item, &val);
       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
@@ -601,7 +606,6 @@ enumerate_args (PyObject *iter,
                {
                  xfree (arg.error);
                  xfree (entryarg.error);
-                 xfree (sym_name);
                  goto error;
                }
            }
@@ -610,19 +614,19 @@ 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,
@@ -631,7 +635,6 @@ enumerate_args (PyObject *iter,
                {
                      xfree (arg.error);
                      xfree (entryarg.error);
-                     xfree (sym_name);
                      goto error;
                }
            }
@@ -644,48 +647,45 @@ 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) == EXT_LANG_BT_ERROR)
-               {
-                 xfree (sym_name);
-                 goto 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 EXT_LANG_BT_OK;
@@ -723,25 +723,23 @@ 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 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);
+      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 == EXT_LANG_BT_ERROR)
        {
@@ -749,7 +747,7 @@ enumerate_locals (PyObject *iter,
          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,45 +757,47 @@ 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)
        {
@@ -810,7 +810,7 @@ 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;
 
@@ -836,15 +836,16 @@ 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 ())
@@ -945,40 +946,41 @@ py_print_args (PyObject *filter,
 {
   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)
        == 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 EXT_LANG_BT_OK;
@@ -1001,7 +1003,7 @@ py_print_args (PyObject *filter,
     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.  */
+    on success.  It can also throw an exception RETURN_QUIT.  */
 
 static enum ext_lang_bt_status
 py_print_frame (PyObject *filter, int flags,
@@ -1012,11 +1014,11 @@ py_print_frame (PyObject *filter, int flags,
   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;
@@ -1031,39 +1033,37 @@ py_print_frame (PyObject *filter, int flags,
   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) == EXT_LANG_BT_ERROR)
-       goto error;
-      else
-       {
-         do_cleanups (cleanup_stack);
-         return EXT_LANG_BT_COMPLETED;
-       }
+       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))
@@ -1075,15 +1075,17 @@ py_print_frame (PyObject *filter, int flags,
         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
@@ -1091,17 +1093,25 @@ py_print_frame (PyObject *filter, int flags,
       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);
        }
     }
 
@@ -1111,11 +1121,10 @@ py_print_frame (PyObject *filter, int flags,
     {
       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);
 
@@ -1124,22 +1133,24 @@ py_print_frame (PyObject *filter, int flags,
             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)
@@ -1148,83 +1159,89 @@ py_print_frame (PyObject *filter, int flags,
         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 = MSYMBOL_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;
-               }
-             Py_DECREF (py_func);
+         TRY
+           {
+             annotate_frame_function_name ();
+             if (function == NULL)
+               out->field_skip ("func");
+             else
+               out->field_string ("func", function);
            }
-         else
-           goto error;
+         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);
        }
     }
 
@@ -1234,154 +1251,187 @@ py_print_frame (PyObject *filter, int flags,
   if (print_args)
     {
       if (py_print_args (filter, out, args_type, frame) == EXT_LANG_BT_ERROR)
-       goto 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;
                }
-             Py_DECREF (py_fn);
+
+             TRY
+               {
+                 out->wrap_hint ("   ");
+                 out->text (" at ");
+                 annotate_frame_source_file ();
+                 out->field_string ("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
            }
-         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;
+               }
+
+             TRY
+               {
+                 out->text (":");
+                 annotate_frame_source_line ();
+                 out->field_int ("line", line);
                }
-             Py_DECREF (py_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) == EXT_LANG_BT_ERROR)
-       goto 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 ext_lang_bt_status success = py_print_frame (item, flags,
-                                                           args_type, out,
-                                                           indent,
-                                                           levels_printed);
+       if (! out->is_mi_like_p ())
+         indent++;
 
-         if (success == EXT_LANG_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 EXT_LANG_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 EXT_LANG_BT_ERROR;
+  return EXT_LANG_BT_COMPLETED;
 }
 
 /* Helper function to initiate frame filter invocation at starting
@@ -1472,22 +1522,22 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
   struct cleanup *cleanups;
   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 EXT_LANG_BT_NO_FILTERS;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       gdbarch = get_frame_arch (frame);
     }
-  if (except.reason < 0)
+  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);
 
@@ -1531,15 +1581,17 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
 
   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 ();
-
-      Py_DECREF (item);
     }
 
   if (item == NULL && PyErr_Occurred ())
This page took 0.041996 seconds and 4 git commands to generate.