1c50c785cSJohn Marino /* Python interface to lazy strings.
2c50c785cSJohn Marino
3*ef5ccd6cSJohn Marino Copyright (C) 2010-2013 Free Software Foundation, Inc.
4c50c785cSJohn Marino
5c50c785cSJohn Marino This file is part of GDB.
6c50c785cSJohn Marino
7c50c785cSJohn Marino This program is free software; you can redistribute it and/or modify
8c50c785cSJohn Marino it under the terms of the GNU General Public License as published by
9c50c785cSJohn Marino the Free Software Foundation; either version 3 of the License, or
10c50c785cSJohn Marino (at your option) any later version.
11c50c785cSJohn Marino
12c50c785cSJohn Marino This program is distributed in the hope that it will be useful,
13c50c785cSJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
14c50c785cSJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15c50c785cSJohn Marino GNU General Public License for more details.
16c50c785cSJohn Marino
17c50c785cSJohn Marino You should have received a copy of the GNU General Public License
18c50c785cSJohn Marino along with this program. If not, see <http://www.gnu.org/licenses/>. */
19c50c785cSJohn Marino
20c50c785cSJohn Marino #include "defs.h"
21c50c785cSJohn Marino #include "python-internal.h"
22c50c785cSJohn Marino #include "charset.h"
23c50c785cSJohn Marino #include "value.h"
24c50c785cSJohn Marino #include "exceptions.h"
25c50c785cSJohn Marino #include "valprint.h"
26c50c785cSJohn Marino #include "language.h"
27c50c785cSJohn Marino #include "gdb_assert.h"
28c50c785cSJohn Marino
29c50c785cSJohn Marino typedef struct {
30c50c785cSJohn Marino PyObject_HEAD
31c50c785cSJohn Marino /* Holds the address of the lazy string. */
32c50c785cSJohn Marino CORE_ADDR address;
33c50c785cSJohn Marino
34c50c785cSJohn Marino /* Holds the encoding that will be applied to the string
35c50c785cSJohn Marino when the string is printed by GDB. If the encoding is set
36c50c785cSJohn Marino to None then GDB will select the most appropriate
37c50c785cSJohn Marino encoding when the sting is printed. */
38c50c785cSJohn Marino char *encoding;
39c50c785cSJohn Marino
40c50c785cSJohn Marino /* Holds the length of the string in characters. If the
41c50c785cSJohn Marino length is -1, then the string will be fetched and encoded up to
42c50c785cSJohn Marino the first null of appropriate width. */
43c50c785cSJohn Marino long length;
44c50c785cSJohn Marino
45c50c785cSJohn Marino /* This attribute holds the type that is represented by the lazy
46c50c785cSJohn Marino string's type. */
47c50c785cSJohn Marino struct type *type;
48c50c785cSJohn Marino } lazy_string_object;
49c50c785cSJohn Marino
50c50c785cSJohn Marino static PyTypeObject lazy_string_object_type;
51c50c785cSJohn Marino
52c50c785cSJohn Marino static PyObject *
stpy_get_address(PyObject * self,void * closure)53c50c785cSJohn Marino stpy_get_address (PyObject *self, void *closure)
54c50c785cSJohn Marino {
55c50c785cSJohn Marino lazy_string_object *self_string = (lazy_string_object *) self;
56c50c785cSJohn Marino
57c50c785cSJohn Marino return gdb_py_long_from_ulongest (self_string->address);
58c50c785cSJohn Marino }
59c50c785cSJohn Marino
60c50c785cSJohn Marino static PyObject *
stpy_get_encoding(PyObject * self,void * closure)61c50c785cSJohn Marino stpy_get_encoding (PyObject *self, void *closure)
62c50c785cSJohn Marino {
63c50c785cSJohn Marino lazy_string_object *self_string = (lazy_string_object *) self;
64c50c785cSJohn Marino PyObject *result;
65c50c785cSJohn Marino
66c50c785cSJohn Marino /* An encoding can be set to NULL by the user, so check before
67c50c785cSJohn Marino attempting a Python FromString call. If NULL return Py_None. */
68c50c785cSJohn Marino if (self_string->encoding)
69c50c785cSJohn Marino result = PyString_FromString (self_string->encoding);
70c50c785cSJohn Marino else
71c50c785cSJohn Marino {
72c50c785cSJohn Marino result = Py_None;
73c50c785cSJohn Marino Py_INCREF (result);
74c50c785cSJohn Marino }
75c50c785cSJohn Marino
76c50c785cSJohn Marino return result;
77c50c785cSJohn Marino }
78c50c785cSJohn Marino
79c50c785cSJohn Marino static PyObject *
stpy_get_length(PyObject * self,void * closure)80c50c785cSJohn Marino stpy_get_length (PyObject *self, void *closure)
81c50c785cSJohn Marino {
82c50c785cSJohn Marino lazy_string_object *self_string = (lazy_string_object *) self;
83c50c785cSJohn Marino
84c50c785cSJohn Marino return PyLong_FromLong (self_string->length);
85c50c785cSJohn Marino }
86c50c785cSJohn Marino
87*ef5ccd6cSJohn Marino static PyObject *
stpy_get_type(PyObject * self,void * closure)88c50c785cSJohn Marino stpy_get_type (PyObject *self, void *closure)
89c50c785cSJohn Marino {
90c50c785cSJohn Marino lazy_string_object *str_obj = (lazy_string_object *) self;
91c50c785cSJohn Marino
92c50c785cSJohn Marino return type_to_type_object (str_obj->type);
93c50c785cSJohn Marino }
94c50c785cSJohn Marino
95c50c785cSJohn Marino static PyObject *
stpy_convert_to_value(PyObject * self,PyObject * args)96c50c785cSJohn Marino stpy_convert_to_value (PyObject *self, PyObject *args)
97c50c785cSJohn Marino {
98c50c785cSJohn Marino lazy_string_object *self_string = (lazy_string_object *) self;
99a45ae5f8SJohn Marino struct value *val = NULL;
100a45ae5f8SJohn Marino volatile struct gdb_exception except;
101c50c785cSJohn Marino
102c50c785cSJohn Marino if (self_string->address == 0)
103c50c785cSJohn Marino {
104c50c785cSJohn Marino PyErr_SetString (PyExc_MemoryError,
105c50c785cSJohn Marino _("Cannot create a value from NULL."));
106c50c785cSJohn Marino return NULL;
107c50c785cSJohn Marino }
108c50c785cSJohn Marino
109a45ae5f8SJohn Marino TRY_CATCH (except, RETURN_MASK_ALL)
110a45ae5f8SJohn Marino {
111c50c785cSJohn Marino val = value_at_lazy (self_string->type, self_string->address);
112a45ae5f8SJohn Marino }
113a45ae5f8SJohn Marino GDB_PY_HANDLE_EXCEPTION (except);
114a45ae5f8SJohn Marino
115c50c785cSJohn Marino return value_to_value_object (val);
116c50c785cSJohn Marino }
117c50c785cSJohn Marino
118c50c785cSJohn Marino static void
stpy_dealloc(PyObject * self)119c50c785cSJohn Marino stpy_dealloc (PyObject *self)
120c50c785cSJohn Marino {
121c50c785cSJohn Marino lazy_string_object *self_string = (lazy_string_object *) self;
122c50c785cSJohn Marino
123c50c785cSJohn Marino xfree (self_string->encoding);
124c50c785cSJohn Marino }
125c50c785cSJohn Marino
126c50c785cSJohn Marino PyObject *
gdbpy_create_lazy_string_object(CORE_ADDR address,long length,const char * encoding,struct type * type)127c50c785cSJohn Marino gdbpy_create_lazy_string_object (CORE_ADDR address, long length,
128c50c785cSJohn Marino const char *encoding, struct type *type)
129c50c785cSJohn Marino {
130c50c785cSJohn Marino lazy_string_object *str_obj = NULL;
131c50c785cSJohn Marino
132c50c785cSJohn Marino if (address == 0 && length != 0)
133c50c785cSJohn Marino {
134c50c785cSJohn Marino PyErr_SetString (PyExc_MemoryError,
135c50c785cSJohn Marino _("Cannot create a lazy string with address 0x0, " \
136c50c785cSJohn Marino "and a non-zero length."));
137c50c785cSJohn Marino return NULL;
138c50c785cSJohn Marino }
139c50c785cSJohn Marino
140c50c785cSJohn Marino if (!type)
141c50c785cSJohn Marino {
142c50c785cSJohn Marino PyErr_SetString (PyExc_RuntimeError,
143c50c785cSJohn Marino _("A lazy string's type cannot be NULL."));
144c50c785cSJohn Marino return NULL;
145c50c785cSJohn Marino }
146c50c785cSJohn Marino
147c50c785cSJohn Marino str_obj = PyObject_New (lazy_string_object, &lazy_string_object_type);
148c50c785cSJohn Marino if (!str_obj)
149c50c785cSJohn Marino return NULL;
150c50c785cSJohn Marino
151c50c785cSJohn Marino str_obj->address = address;
152c50c785cSJohn Marino str_obj->length = length;
153c50c785cSJohn Marino if (encoding == NULL || !strcmp (encoding, ""))
154c50c785cSJohn Marino str_obj->encoding = NULL;
155c50c785cSJohn Marino else
156c50c785cSJohn Marino str_obj->encoding = xstrdup (encoding);
157c50c785cSJohn Marino str_obj->type = type;
158c50c785cSJohn Marino
159c50c785cSJohn Marino return (PyObject *) str_obj;
160c50c785cSJohn Marino }
161c50c785cSJohn Marino
162c50c785cSJohn Marino void
gdbpy_initialize_lazy_string(void)163c50c785cSJohn Marino gdbpy_initialize_lazy_string (void)
164c50c785cSJohn Marino {
165c50c785cSJohn Marino if (PyType_Ready (&lazy_string_object_type) < 0)
166c50c785cSJohn Marino return;
167c50c785cSJohn Marino
168c50c785cSJohn Marino Py_INCREF (&lazy_string_object_type);
169c50c785cSJohn Marino }
170c50c785cSJohn Marino
171c50c785cSJohn Marino /* Determine whether the printer object pointed to by OBJ is a
172c50c785cSJohn Marino Python lazy string. */
173c50c785cSJohn Marino int
gdbpy_is_lazy_string(PyObject * result)174c50c785cSJohn Marino gdbpy_is_lazy_string (PyObject *result)
175c50c785cSJohn Marino {
176c50c785cSJohn Marino return PyObject_TypeCheck (result, &lazy_string_object_type);
177c50c785cSJohn Marino }
178c50c785cSJohn Marino
179c50c785cSJohn Marino /* Extract the parameters from the lazy string object STRING.
180c50c785cSJohn Marino ENCODING will either be set to NULL, or will be allocated with
181c50c785cSJohn Marino xmalloc, in which case the callers is responsible for freeing
182c50c785cSJohn Marino it. */
183c50c785cSJohn Marino
184c50c785cSJohn Marino void
gdbpy_extract_lazy_string(PyObject * string,CORE_ADDR * addr,struct type ** str_type,long * length,char ** encoding)185c50c785cSJohn Marino gdbpy_extract_lazy_string (PyObject *string, CORE_ADDR *addr,
186c50c785cSJohn Marino struct type **str_type,
187c50c785cSJohn Marino long *length, char **encoding)
188c50c785cSJohn Marino {
189c50c785cSJohn Marino lazy_string_object *lazy;
190c50c785cSJohn Marino
191c50c785cSJohn Marino gdb_assert (gdbpy_is_lazy_string (string));
192c50c785cSJohn Marino
193c50c785cSJohn Marino lazy = (lazy_string_object *) string;
194c50c785cSJohn Marino
195c50c785cSJohn Marino *addr = lazy->address;
196c50c785cSJohn Marino *str_type = lazy->type;
197c50c785cSJohn Marino *length = lazy->length;
198c50c785cSJohn Marino *encoding = lazy->encoding ? xstrdup (lazy->encoding) : NULL;
199c50c785cSJohn Marino }
200c50c785cSJohn Marino
201c50c785cSJohn Marino
202c50c785cSJohn Marino
203c50c785cSJohn Marino static PyMethodDef lazy_string_object_methods[] = {
204c50c785cSJohn Marino { "value", stpy_convert_to_value, METH_NOARGS,
205c50c785cSJohn Marino "Create a (lazy) value that contains a pointer to the string." },
206c50c785cSJohn Marino {NULL} /* Sentinel */
207c50c785cSJohn Marino };
208c50c785cSJohn Marino
209c50c785cSJohn Marino
210c50c785cSJohn Marino static PyGetSetDef lazy_string_object_getset[] = {
211c50c785cSJohn Marino { "address", stpy_get_address, NULL, "Address of the string.", NULL },
212c50c785cSJohn Marino { "encoding", stpy_get_encoding, NULL, "Encoding of the string.", NULL },
213c50c785cSJohn Marino { "length", stpy_get_length, NULL, "Length of the string.", NULL },
214c50c785cSJohn Marino { "type", stpy_get_type, NULL, "Type associated with the string.", NULL },
215c50c785cSJohn Marino { NULL } /* Sentinel */
216c50c785cSJohn Marino };
217c50c785cSJohn Marino
218c50c785cSJohn Marino static PyTypeObject lazy_string_object_type = {
219*ef5ccd6cSJohn Marino PyVarObject_HEAD_INIT (NULL, 0)
220c50c785cSJohn Marino "gdb.LazyString", /*tp_name*/
221c50c785cSJohn Marino sizeof (lazy_string_object), /*tp_basicsize*/
222c50c785cSJohn Marino 0, /*tp_itemsize*/
223c50c785cSJohn Marino stpy_dealloc, /*tp_dealloc*/
224c50c785cSJohn Marino 0, /*tp_print*/
225c50c785cSJohn Marino 0, /*tp_getattr*/
226c50c785cSJohn Marino 0, /*tp_setattr*/
227c50c785cSJohn Marino 0, /*tp_compare*/
228c50c785cSJohn Marino 0, /*tp_repr*/
229c50c785cSJohn Marino 0, /*tp_as_number*/
230c50c785cSJohn Marino 0, /*tp_as_sequence*/
231c50c785cSJohn Marino 0, /*tp_as_mapping*/
232c50c785cSJohn Marino 0, /*tp_hash */
233c50c785cSJohn Marino 0, /*tp_call*/
234c50c785cSJohn Marino 0, /*tp_str*/
235c50c785cSJohn Marino 0, /*tp_getattro*/
236c50c785cSJohn Marino 0, /*tp_setattro*/
237c50c785cSJohn Marino 0, /*tp_as_buffer*/
238c50c785cSJohn Marino Py_TPFLAGS_DEFAULT, /*tp_flags*/
239c50c785cSJohn Marino "GDB lazy string object", /* tp_doc */
240c50c785cSJohn Marino 0, /* tp_traverse */
241c50c785cSJohn Marino 0, /* tp_clear */
242c50c785cSJohn Marino 0, /* tp_richcompare */
243c50c785cSJohn Marino 0, /* tp_weaklistoffset */
244c50c785cSJohn Marino 0, /* tp_iter */
245c50c785cSJohn Marino 0, /* tp_iternext */
246c50c785cSJohn Marino lazy_string_object_methods, /* tp_methods */
247c50c785cSJohn Marino 0, /* tp_members */
248c50c785cSJohn Marino lazy_string_object_getset /* tp_getset */
249c50c785cSJohn Marino };
250