2010-06-04 Michael Snyder <msnyder@vmware.com>
[deliverable/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;
d59b6f6c 55
be759fcf
PM
56 return PyLong_FromUnsignedLongLong (self_string->address);
57}
58
59static PyObject *
60stpy_get_encoding (PyObject *self, void *closure)
61{
62 lazy_string_object *self_string = (lazy_string_object *) self;
63 PyObject *result;
64
65 /* An encoding can be set to NULL by the user, so check before
66 attempting a Python FromString call. If NULL return Py_None. */
67 if (self_string->encoding)
68 result = PyString_FromString (self_string->encoding);
69 else
70 {
71 result = Py_None;
72 Py_INCREF (result);
73 }
74
75 return result;
76}
77
78static PyObject *
79stpy_get_length (PyObject *self, void *closure)
80{
81 lazy_string_object *self_string = (lazy_string_object *) self;
d59b6f6c 82
be759fcf
PM
83 return PyLong_FromLong (self_string->length);
84}
85
86PyObject *
87stpy_get_type (PyObject *self, void *closure)
88{
89 lazy_string_object *str_obj = (lazy_string_object *) self;
d59b6f6c 90
be759fcf
PM
91 return type_to_type_object (str_obj->type);
92}
93
94static PyObject *
95stpy_convert_to_value (PyObject *self, PyObject *args)
96{
97 lazy_string_object *self_string = (lazy_string_object *) self;
98 struct value *val;
99
fff5cc64
PM
100 if (self_string->address == 0)
101 {
102 PyErr_SetString (PyExc_MemoryError,
044c0f87 103 _("Cannot create a value from NULL."));
fff5cc64
PM
104 return NULL;
105 }
106
be759fcf
PM
107 val = value_at_lazy (self_string->type, self_string->address);
108 return value_to_value_object (val);
109}
110
111static void
112stpy_dealloc (PyObject *self)
113{
114 lazy_string_object *self_string = (lazy_string_object *) self;
d59b6f6c 115
be759fcf
PM
116 xfree (self_string->encoding);
117}
118
119PyObject *
120gdbpy_create_lazy_string_object (CORE_ADDR address, long length,
121 const char *encoding, struct type *type)
122{
123 lazy_string_object *str_obj = NULL;
124
fff5cc64 125 if (address == 0 && length != 0)
be759fcf
PM
126 {
127 PyErr_SetString (PyExc_MemoryError,
fff5cc64
PM
128 _("Cannot create a lazy string with address 0x0, " \
129 "and a non-zero length."));
be759fcf
PM
130 return NULL;
131 }
132
133 if (!type)
134 {
135 PyErr_SetString (PyExc_RuntimeError,
044c0f87 136 _("A lazy string's type cannot be NULL."));
be759fcf
PM
137 return NULL;
138 }
139
140 str_obj = PyObject_New (lazy_string_object, &lazy_string_object_type);
141 if (!str_obj)
142 return NULL;
143
144 str_obj->address = address;
145 str_obj->length = length;
146 if (encoding == NULL || !strcmp (encoding, ""))
147 str_obj->encoding = NULL;
148 else
149 str_obj->encoding = xstrdup (encoding);
150 str_obj->type = type;
151
152 return (PyObject *) str_obj;
153}
154
155void
156gdbpy_initialize_lazy_string (void)
157{
158 if (PyType_Ready (&lazy_string_object_type) < 0)
159 return;
160
161 Py_INCREF (&lazy_string_object_type);
162}
163
164/* Determine whether the printer object pointed to by OBJ is a
165 Python lazy string. */
166int
167gdbpy_is_lazy_string (PyObject *result)
168{
169 return PyObject_TypeCheck (result, &lazy_string_object_type);
170}
171
172/* Extract and return the actual string from the lazy string object
173 STRING. Addtionally, the string type is written to *STR_TYPE, the
174 string length is written to *LENGTH, and the string encoding is
175 written to *ENCODING. On error, NULL is returned. The caller is
176 responsible for freeing the returned buffer. */
177gdb_byte *
178gdbpy_extract_lazy_string (PyObject *string, struct type **str_type,
179 long *length, char **encoding)
180{
181 int width;
182 int bytes_read;
183 gdb_byte *buffer = NULL;
184 int errcode = 0;
185 CORE_ADDR addr;
186 struct gdbarch *gdbarch;
187 enum bfd_endian byte_order;
188 PyObject *py_len = NULL, *py_encoding = NULL;
189 PyObject *py_addr = NULL, *py_type = NULL;
190 volatile struct gdb_exception except;
191
192 py_len = PyObject_GetAttrString (string, "length");
193 py_encoding = PyObject_GetAttrString (string, "encoding");
194 py_addr = PyObject_GetAttrString (string, "address");
195 py_type = PyObject_GetAttrString (string, "type");
196
197 /* A NULL encoding, length, address or type is not ok. */
198 if (!py_len || !py_encoding || !py_addr || !py_type)
199 goto error;
200
201 *length = PyLong_AsLong (py_len);
aab48ede 202 addr = PyLong_AsUnsignedLongLong (py_addr);
be759fcf
PM
203
204 /* If the user supplies Py_None an encoding, set encoding to NULL.
205 This will trigger the resulting LA_PRINT_CALL to automatically
206 select an encoding. */
207 if (py_encoding == Py_None)
208 *encoding = NULL;
209 else
210 *encoding = xstrdup (PyString_AsString (py_encoding));
211
212 *str_type = type_object_to_type (py_type);
213 gdbarch = get_type_arch (*str_type);
214 byte_order = gdbarch_byte_order (gdbarch);
215 width = TYPE_LENGTH (*str_type);
216
217 TRY_CATCH (except, RETURN_MASK_ALL)
218 {
219 errcode = read_string (addr, *length, width,
220 *length, byte_order, &buffer,
221 &bytes_read);
222 }
223 if (except.reason < 0)
224 {
225 PyErr_Format (except.reason == RETURN_QUIT \
226 ? PyExc_KeyboardInterrupt : PyExc_RuntimeError, \
227 "%s", except.message); \
228 goto error;
229
230 }
231
232 if (errcode)
233 goto error;
234
235 *length = bytes_read / width;
236
237 Py_DECREF (py_encoding);
238 Py_DECREF (py_len);
239 Py_DECREF (py_addr);
240 Py_DECREF (py_type);
241 return buffer;
242
243 error:
244 Py_XDECREF (py_encoding);
245 Py_XDECREF (py_len);
246 Py_XDECREF (py_addr);
247 Py_XDECREF (py_type);
248 xfree (buffer);
249 *length = 0;
250 *str_type = NULL;
251 return NULL;
252}
253
254\f
255
256static PyMethodDef lazy_string_object_methods[] = {
257 { "value", stpy_convert_to_value, METH_NOARGS,
258 "Create a (lazy) value that contains a pointer to the string." },
259 {NULL} /* Sentinel */
260};
261
262
263static PyGetSetDef lazy_string_object_getset[] = {
264 { "address", stpy_get_address, NULL, "Address of the string.", NULL },
265 { "encoding", stpy_get_encoding, NULL, "Encoding of the string.", NULL },
266 { "length", stpy_get_length, NULL, "Length of the string.", NULL },
267 { "type", stpy_get_type, NULL, "Type associated with the string.", NULL },
268 { NULL } /* Sentinel */
269};
270
271static PyTypeObject lazy_string_object_type = {
272 PyObject_HEAD_INIT (NULL)
273 0, /*ob_size*/
274 "gdb.LazyString", /*tp_name*/
275 sizeof (lazy_string_object), /*tp_basicsize*/
276 0, /*tp_itemsize*/
277 stpy_dealloc, /*tp_dealloc*/
278 0, /*tp_print*/
279 0, /*tp_getattr*/
280 0, /*tp_setattr*/
281 0, /*tp_compare*/
282 0, /*tp_repr*/
283 0, /*tp_as_number*/
284 0, /*tp_as_sequence*/
285 0, /*tp_as_mapping*/
286 0, /*tp_hash */
287 0, /*tp_call*/
288 0, /*tp_str*/
289 0, /*tp_getattro*/
290 0, /*tp_setattro*/
291 0, /*tp_as_buffer*/
292 Py_TPFLAGS_DEFAULT, /*tp_flags*/
293 "GDB lazy string object", /* tp_doc */
294 0, /* tp_traverse */
295 0, /* tp_clear */
296 0, /* tp_richcompare */
297 0, /* tp_weaklistoffset */
298 0, /* tp_iter */
299 0, /* tp_iternext */
300 lazy_string_object_methods, /* tp_methods */
301 0, /* tp_members */
302 lazy_string_object_getset /* tp_getset */
303};
This page took 0.273085 seconds and 4 git commands to generate.