-/* 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
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
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)
{
/* 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 ();
}
}
+ 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. */
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
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;
}
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;
}