Rename field_int to field_signed
[deliverable/binutils-gdb.git] / gdb / python / py-varobj.c
index 2b9534863907043fb9e146628b8b245ae1e2dcaa..611c4ca76f2a1b0206d0ef78dfb07ee51346c8e0 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2013-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2013-2019 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -38,11 +38,8 @@ static void
 py_varobj_iter_dtor (struct varobj_iter *self)
 {
   struct py_varobj_iter *dis = (struct py_varobj_iter *) self;
-  struct cleanup *back_to = varobj_ensure_python_env (self->var);
-
+  gdbpy_enter_varobj enter_py (self->var);
   Py_XDECREF (dis->iter);
-
-  do_cleanups (back_to);
 }
 
 /* Implementation of the 'next' method of pretty-printed varobj
@@ -52,12 +49,16 @@ static varobj_item *
 py_varobj_iter_next (struct varobj_iter *self)
 {
   struct py_varobj_iter *t = (struct py_varobj_iter *) self;
-  struct cleanup *back_to;
-  PyObject *item;
+  PyObject *py_v;
+  varobj_item *vitem;
+  const char *name = NULL;
 
-  back_to = varobj_ensure_python_env (self->var);
+  if (!gdb_python_initialized)
+    return NULL;
 
-  item = PyIter_Next (t->iter);
+  gdbpy_enter_varobj enter_py (self->var);
+
+  gdbpy_ref<> item (PyIter_Next (t->iter));
 
   if (item == NULL)
     {
@@ -68,25 +69,18 @@ py_varobj_iter_next (struct varobj_iter *self)
       /* If we got a memory error, just use the text as the item.  */
       if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error))
        {
-         PyObject *type, *value, *trace;
-         char *name_str, *value_str;
-
-         PyErr_Fetch (&type, &value, &trace);
-         value_str = gdbpy_exception_to_string (type, value);
-         Py_XDECREF (type);
-         Py_XDECREF (value);
-         Py_XDECREF (trace);
+         gdbpy_err_fetch fetched_error;
+         gdb::unique_xmalloc_ptr<char> value_str = fetched_error.to_string ();
          if (value_str == NULL)
            {
              gdbpy_print_stack ();
              return NULL;
            }
 
-         name_str = xstrprintf ("<error at %d>",
-                                self->next_raw_index++);
-         item = Py_BuildValue ("(ss)", name_str, value_str);
-         xfree (name_str);
-         xfree (value_str);
+         std::string name_str = string_printf ("<error at %d>",
+                                               self->next_raw_index++);
+         item.reset (Py_BuildValue ("(ss)", name_str.c_str (),
+                                    value_str.get ()));
          if (item == NULL)
            {
              gdbpy_print_stack ();
@@ -101,9 +95,20 @@ py_varobj_iter_next (struct varobj_iter *self)
        }
     }
 
+  if (!PyArg_ParseTuple (item.get (), "sO", &name, &py_v))
+    {
+      gdbpy_print_stack ();
+      error (_("Invalid item from the child list"));
+    }
+
+  vitem = new varobj_item ();
+  vitem->value = convert_value_from_python (py_v);
+  if (vitem->value == NULL)
+    gdbpy_print_stack ();
+  vitem->name = name;
+
   self->next_raw_index++;
-  do_cleanups (back_to);
-  return item;
+  return vitem;
 }
 
 /* The 'vtable' of pretty-printed python varobj iterators.  */
@@ -118,14 +123,14 @@ static const struct varobj_iter_ops py_varobj_iter_ops =
    whose children the iterator will be iterating over.  PYITER is the
    python iterator actually responsible for the iteration.  */
 
-static void CPYCHECKER_STEALS_REFERENCE_TO_ARG (3)
+static void
 py_varobj_iter_ctor (struct py_varobj_iter *self,
-                     struct varobj *var, PyObject *pyiter)
+                    struct varobj *var, gdbpy_ref<> &&pyiter)
 {
   self->base.var = var;
   self->base.ops = &py_varobj_iter_ops;
   self->base.next_raw_index = 0;
-  self->iter = pyiter;
+  self->iter = pyiter.release ();
 }
 
 /* Allocate and construct a pretty-printed varobj iterator.  VAR is
@@ -133,13 +138,13 @@ py_varobj_iter_ctor (struct py_varobj_iter *self,
    PYITER is the python iterator actually responsible for the
    iteration.  */
 
-static struct py_varobj_iter * CPYCHECKER_STEALS_REFERENCE_TO_ARG (2)
-py_varobj_iter_new (struct varobj *var, PyObject *pyiter)
+static struct py_varobj_iter *
+py_varobj_iter_new (struct varobj *var, gdbpy_ref<> &&pyiter)
 {
   struct py_varobj_iter *self;
 
   self = XNEW (struct py_varobj_iter);
-  py_varobj_iter_ctor (self, var, pyiter);
+  py_varobj_iter_ctor (self, var, std::move (pyiter));
   return self;
 }
 
@@ -149,38 +154,29 @@ py_varobj_iter_new (struct varobj *var, PyObject *pyiter)
 struct varobj_iter *
 py_varobj_get_iterator (struct varobj *var, PyObject *printer)
 {
-  PyObject *children;
-  int i;
-  PyObject *iter;
   struct py_varobj_iter *py_iter;
-  struct cleanup *back_to = varobj_ensure_python_env (var);
+
+  gdbpy_enter_varobj enter_py (var);
 
   if (!PyObject_HasAttr (printer, gdbpy_children_cst))
-    {
-      do_cleanups (back_to);
-      return NULL;
-    }
+    return NULL;
 
-  children = PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
-                                        NULL);
+  gdbpy_ref<> children (PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
+                                                   NULL));
   if (children == NULL)
     {
       gdbpy_print_stack ();
       error (_("Null value returned for children"));
     }
 
-  make_cleanup_py_decref (children);
-
-  iter = PyObject_GetIter (children);
+  gdbpy_ref<> iter (PyObject_GetIter (children.get ()));
   if (iter == NULL)
     {
       gdbpy_print_stack ();
       error (_("Could not get children iterator"));
     }
 
-  py_iter = py_varobj_iter_new (var, iter);
-
-  do_cleanups (back_to);
+  py_iter = py_varobj_iter_new (var, std::move (iter));
 
   return &py_iter->base;
 }
This page took 0.027361 seconds and 4 git commands to generate.