]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/python/py-lazy-string.c
2010-04-14 Phil Muldoon <pmuldoon@redhat.com>
[thirdparty/binutils-gdb.git] / gdb / python / py-lazy-string.c
CommitLineData
be759fcf
PM
1/* Python interface to lazy strings.
2
3 Copyright (C) 2010 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20#include "defs.h"
21#include "python-internal.h"
22#include "charset.h"
23#include "value.h"
24#include "exceptions.h"
25#include "valprint.h"
26#include "language.h"
27
28typedef struct {
29 PyObject_HEAD
30 /* Holds the address of the lazy string. */
31 CORE_ADDR address;
32
33 /* Holds the encoding that will be applied to the string
34 when the string is printed by GDB. If the encoding is set
35 to None then GDB will select the most appropriate
36 encoding when the sting is printed. */
37 char *encoding;
38
39 /* Holds the length of the string in characters. If the
40 length is -1, then the string will be fetched and encoded up to
41 the first null of appropriate width. */
42 long length;
43
44 /* This attribute holds the type that is represented by the lazy
45 string's type. */
46 struct type *type;
47} lazy_string_object;
48
49static PyTypeObject lazy_string_object_type;
50
51static PyObject *
52stpy_get_address (PyObject *self, void *closure)
53{
54 lazy_string_object *self_string = (lazy_string_object *) self;
55 return PyLong_FromUnsignedLongLong (self_string->address);
56}
57
58static PyObject *
59stpy_get_encoding (PyObject *self, void *closure)
60{
61 lazy_string_object *self_string = (lazy_string_object *) self;
62 PyObject *result;
63
64 /* An encoding can be set to NULL by the user, so check before
65 attempting a Python FromString call. If NULL return Py_None. */
66 if (self_string->encoding)
67 result = PyString_FromString (self_string->encoding);
68 else
69 {
70 result = Py_None;
71 Py_INCREF (result);
72 }
73
74 return result;
75}
76
77static PyObject *
78stpy_get_length (PyObject *self, void *closure)
79{
80 lazy_string_object *self_string = (lazy_string_object *) self;
81 return PyLong_FromLong (self_string->length);
82}
83
84PyObject *
85stpy_get_type (PyObject *self, void *closure)
86{
87 lazy_string_object *str_obj = (lazy_string_object *) self;
88 return type_to_type_object (str_obj->type);
89}
90
91static PyObject *
92stpy_convert_to_value (PyObject *self, PyObject *args)
93{
94 lazy_string_object *self_string = (lazy_string_object *) self;
95 struct value *val;
96
fff5cc64
PM
97 if (self_string->address == 0)
98 {
99 PyErr_SetString (PyExc_MemoryError,
f5f8b5ba 100 _("Cannot create a value from NULL"));
fff5cc64
PM
101 return NULL;
102 }
103
be759fcf
PM
104 val = value_at_lazy (self_string->type, self_string->address);
105 return value_to_value_object (val);
106}
107
108static void
109stpy_dealloc (PyObject *self)
110{
111 lazy_string_object *self_string = (lazy_string_object *) self;
112 xfree (self_string->encoding);
113}
114
115PyObject *
116gdbpy_create_lazy_string_object (CORE_ADDR address, long length,
117 const char *encoding, struct type *type)
118{
119 lazy_string_object *str_obj = NULL;
120
fff5cc64 121 if (address == 0 && length != 0)
be759fcf
PM
122 {
123 PyErr_SetString (PyExc_MemoryError,
fff5cc64
PM
124 _("Cannot create a lazy string with address 0x0, " \
125 "and a non-zero length."));
be759fcf
PM
126 return NULL;
127 }
128
129 if (!type)
130 {
131 PyErr_SetString (PyExc_RuntimeError,
132 "A lazy string's type cannot be NULL.");
133 return NULL;
134 }
135
136 str_obj = PyObject_New (lazy_string_object, &lazy_string_object_type);
137 if (!str_obj)
138 return NULL;
139
140 str_obj->address = address;
141 str_obj->length = length;
142 if (encoding == NULL || !strcmp (encoding, ""))
143 str_obj->encoding = NULL;
144 else
145 str_obj->encoding = xstrdup (encoding);
146 str_obj->type = type;
147
148 return (PyObject *) str_obj;
149}
150
151void
152gdbpy_initialize_lazy_string (void)
153{
154 if (PyType_Ready (&lazy_string_object_type) < 0)
155 return;
156
157 Py_INCREF (&lazy_string_object_type);
158}
159
160/* Determine whether the printer object pointed to by OBJ is a
161 Python lazy string. */
162int
163gdbpy_is_lazy_string (PyObject *result)
164{
165 return PyObject_TypeCheck (result, &lazy_string_object_type);
166}
167
168/* Extract and return the actual string from the lazy string object
169 STRING. Addtionally, the string type is written to *STR_TYPE, the
170 string length is written to *LENGTH, and the string encoding is
171 written to *ENCODING. On error, NULL is returned. The caller is
172 responsible for freeing the returned buffer. */
173gdb_byte *
174gdbpy_extract_lazy_string (PyObject *string, struct type **str_type,
175 long *length, char **encoding)
176{
177 int width;
178 int bytes_read;
179 gdb_byte *buffer = NULL;
180 int errcode = 0;
181 CORE_ADDR addr;
182 struct gdbarch *gdbarch;
183 enum bfd_endian byte_order;
184 PyObject *py_len = NULL, *py_encoding = NULL;
185 PyObject *py_addr = NULL, *py_type = NULL;
186 volatile struct gdb_exception except;
187
188 py_len = PyObject_GetAttrString (string, "length");
189 py_encoding = PyObject_GetAttrString (string, "encoding");
190 py_addr = PyObject_GetAttrString (string, "address");
191 py_type = PyObject_GetAttrString (string, "type");
192
193 /* A NULL encoding, length, address or type is not ok. */
194 if (!py_len || !py_encoding || !py_addr || !py_type)
195 goto error;
196
197 *length = PyLong_AsLong (py_len);
aab48ede 198 addr = PyLong_AsUnsignedLongLong (py_addr);
be759fcf
PM
199
200 /* If the user supplies Py_None an encoding, set encoding to NULL.
201 This will trigger the resulting LA_PRINT_CALL to automatically
202 select an encoding. */
203 if (py_encoding == Py_None)
204 *encoding = NULL;
205 else
206 *encoding = xstrdup (PyString_AsString (py_encoding));
207
208 *str_type = type_object_to_type (py_type);
209 gdbarch = get_type_arch (*str_type);
210 byte_order = gdbarch_byte_order (gdbarch);
211 width = TYPE_LENGTH (*str_type);
212
213 TRY_CATCH (except, RETURN_MASK_ALL)
214 {
215 errcode = read_string (addr, *length, width,
216 *length, byte_order, &buffer,
217 &bytes_read);
218 }
219 if (except.reason < 0)
220 {
221 PyErr_Format (except.reason == RETURN_QUIT \
222 ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, \
223 "%s", except.message); \
224 goto error;
225
226 }
227
228 if (errcode)
229 goto error;
230
231 *length = bytes_read / width;
232
233 Py_DECREF (py_encoding);
234 Py_DECREF (py_len);
235 Py_DECREF (py_addr);
236 Py_DECREF (py_type);
237 return buffer;
238
239 error:
240 Py_XDECREF (py_encoding);
241 Py_XDECREF (py_len);
242 Py_XDECREF (py_addr);
243 Py_XDECREF (py_type);
244 xfree (buffer);
245 *length = 0;
246 *str_type = NULL;
247 return NULL;
248}
249
250\f
251
252static PyMethodDef lazy_string_object_methods[] = {
253 { "value", stpy_convert_to_value, METH_NOARGS,
254 "Create a (lazy) value that contains a pointer to the string." },
255 {NULL} /* Sentinel */
256};
257
258
259static PyGetSetDef lazy_string_object_getset[] = {
260 { "address", stpy_get_address, NULL, "Address of the string.", NULL },
261 { "encoding", stpy_get_encoding, NULL, "Encoding of the string.", NULL },
262 { "length", stpy_get_length, NULL, "Length of the string.", NULL },
263 { "type", stpy_get_type, NULL, "Type associated with the string.", NULL },
264 { NULL } /* Sentinel */
265};
266
267static PyTypeObject lazy_string_object_type = {
268 PyObject_HEAD_INIT (NULL)
269 0, /*ob_size*/
270 "gdb.LazyString", /*tp_name*/
271 sizeof (lazy_string_object), /*tp_basicsize*/
272 0, /*tp_itemsize*/
273 stpy_dealloc, /*tp_dealloc*/
274 0, /*tp_print*/
275 0, /*tp_getattr*/
276 0, /*tp_setattr*/
277 0, /*tp_compare*/
278 0, /*tp_repr*/
279 0, /*tp_as_number*/
280 0, /*tp_as_sequence*/
281 0, /*tp_as_mapping*/
282 0, /*tp_hash */
283 0, /*tp_call*/
284 0, /*tp_str*/
285 0, /*tp_getattro*/
286 0, /*tp_setattro*/
287 0, /*tp_as_buffer*/
288 Py_TPFLAGS_DEFAULT, /*tp_flags*/
289 "GDB lazy string object", /* tp_doc */
290 0, /* tp_traverse */
291 0, /* tp_clear */
292 0, /* tp_richcompare */
293 0, /* tp_weaklistoffset */
294 0, /* tp_iter */
295 0, /* tp_iternext */
296 lazy_string_object_methods, /* tp_methods */
297 0, /* tp_members */
298 lazy_string_object_getset /* tp_getset */
299};