1/* Copyright (C) 2013-2020 Free Software Foundation, Inc.
2
3   This program is free software; you can redistribute it and/or modify
4   it under the terms of the GNU General Public License as published by
5   the Free Software Foundation; either version 3 of the License, or
6   (at your option) any later version.
7
8   This program is distributed in the hope that it will be useful,
9   but WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   GNU General Public License for more details.
12
13   You should have received a copy of the GNU General Public License
14   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
15
16#include "defs.h"
17#include "python-internal.h"
18#include "varobj.h"
19#include "varobj-iter.h"
20
21/* A dynamic varobj iterator "class" for python pretty-printed
22   varobjs.  This inherits struct varobj_iter.  */
23
24struct py_varobj_iter
25{
26  /* The 'base class'.  */
27  struct varobj_iter base;
28
29  /* The python iterator returned by the printer's 'children' method,
30     or NULL if not available.  */
31  PyObject *iter;
32};
33
34/* Implementation of the 'dtor' method of pretty-printed varobj
35   iterators.  */
36
37static void
38py_varobj_iter_dtor (struct varobj_iter *self)
39{
40  struct py_varobj_iter *dis = (struct py_varobj_iter *) self;
41  gdbpy_enter_varobj enter_py (self->var);
42  Py_XDECREF (dis->iter);
43}
44
45/* Implementation of the 'next' method of pretty-printed varobj
46   iterators.  */
47
48static varobj_item *
49py_varobj_iter_next (struct varobj_iter *self)
50{
51  struct py_varobj_iter *t = (struct py_varobj_iter *) self;
52  PyObject *py_v;
53  varobj_item *vitem;
54  const char *name = NULL;
55
56  if (!gdb_python_initialized)
57    return NULL;
58
59  gdbpy_enter_varobj enter_py (self->var);
60
61  gdbpy_ref<> item (PyIter_Next (t->iter));
62
63  if (item == NULL)
64    {
65      /* Normal end of iteration.  */
66      if (!PyErr_Occurred ())
67	return NULL;
68
69      /* If we got a memory error, just use the text as the item.  */
70      if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error))
71	{
72	  gdbpy_err_fetch fetched_error;
73	  gdb::unique_xmalloc_ptr<char> value_str = fetched_error.to_string ();
74	  if (value_str == NULL)
75	    {
76	      gdbpy_print_stack ();
77	      return NULL;
78	    }
79
80	  std::string name_str = string_printf ("<error at %d>",
81						self->next_raw_index++);
82	  item.reset (Py_BuildValue ("(ss)", name_str.c_str (),
83				     value_str.get ()));
84	  if (item == NULL)
85	    {
86	      gdbpy_print_stack ();
87	      return NULL;
88	    }
89	}
90      else
91	{
92	  /* Any other kind of error.  */
93	  gdbpy_print_stack ();
94	  return NULL;
95	}
96    }
97
98  if (!PyArg_ParseTuple (item.get (), "sO", &name, &py_v))
99    {
100      gdbpy_print_stack ();
101      error (_("Invalid item from the child list"));
102    }
103
104  vitem = new varobj_item ();
105  vitem->value = convert_value_from_python (py_v);
106  if (vitem->value == NULL)
107    gdbpy_print_stack ();
108  vitem->name = name;
109
110  self->next_raw_index++;
111  return vitem;
112}
113
114/* The 'vtable' of pretty-printed python varobj iterators.  */
115
116static const struct varobj_iter_ops py_varobj_iter_ops =
117{
118  py_varobj_iter_dtor,
119  py_varobj_iter_next
120};
121
122/* Constructor of pretty-printed varobj iterators.  VAR is the varobj
123   whose children the iterator will be iterating over.  PYITER is the
124   python iterator actually responsible for the iteration.  */
125
126static void
127py_varobj_iter_ctor (struct py_varobj_iter *self,
128		     struct varobj *var, gdbpy_ref<> &&pyiter)
129{
130  self->base.var = var;
131  self->base.ops = &py_varobj_iter_ops;
132  self->base.next_raw_index = 0;
133  self->iter = pyiter.release ();
134}
135
136/* Allocate and construct a pretty-printed varobj iterator.  VAR is
137   the varobj whose children the iterator will be iterating over.
138   PYITER is the python iterator actually responsible for the
139   iteration.  */
140
141static struct py_varobj_iter *
142py_varobj_iter_new (struct varobj *var, gdbpy_ref<> &&pyiter)
143{
144  struct py_varobj_iter *self;
145
146  self = XNEW (struct py_varobj_iter);
147  py_varobj_iter_ctor (self, var, std::move (pyiter));
148  return self;
149}
150
151/* Return a new pretty-printed varobj iterator suitable to iterate
152   over VAR's children.  */
153
154struct varobj_iter *
155py_varobj_get_iterator (struct varobj *var, PyObject *printer)
156{
157  struct py_varobj_iter *py_iter;
158
159  gdbpy_enter_varobj enter_py (var);
160
161  if (!PyObject_HasAttr (printer, gdbpy_children_cst))
162    return NULL;
163
164  gdbpy_ref<> children (PyObject_CallMethodObjArgs (printer, gdbpy_children_cst,
165						    NULL));
166  if (children == NULL)
167    {
168      gdbpy_print_stack ();
169      error (_("Null value returned for children"));
170    }
171
172  gdbpy_ref<> iter (PyObject_GetIter (children.get ()));
173  if (iter == NULL)
174    {
175      gdbpy_print_stack ();
176      error (_("Could not get children iterator"));
177    }
178
179  py_iter = py_varobj_iter_new (var, std::move (iter));
180
181  return &py_iter->base;
182}
183