]> Git Repo - binutils.git/blob - gdb/python/py-lazy-string.c
Allow python to find its files if moved from original location.
[binutils.git] / gdb / python / py-lazy-string.c
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
28 typedef 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
49 static PyTypeObject lazy_string_object_type;
50
51 static PyObject *
52 stpy_get_address (PyObject *self, void *closure)
53 {
54   lazy_string_object *self_string = (lazy_string_object *) self;
55
56   return PyLong_FromUnsignedLongLong (self_string->address);
57 }
58
59 static PyObject *
60 stpy_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
78 static PyObject *
79 stpy_get_length (PyObject *self, void *closure)
80 {
81   lazy_string_object *self_string = (lazy_string_object *) self;
82
83   return PyLong_FromLong (self_string->length);
84 }
85
86 PyObject *
87 stpy_get_type (PyObject *self, void *closure)
88 {
89   lazy_string_object *str_obj = (lazy_string_object *) self;
90
91   return type_to_type_object (str_obj->type);
92 }
93
94 static PyObject *
95 stpy_convert_to_value  (PyObject *self, PyObject *args)
96 {
97   lazy_string_object *self_string = (lazy_string_object *) self;
98   struct value *val;
99
100   if (self_string->address == 0)
101     {
102       PyErr_SetString (PyExc_MemoryError,
103                        _("Cannot create a value from NULL."));
104       return NULL;
105     }
106
107   val = value_at_lazy (self_string->type, self_string->address);
108   return value_to_value_object (val);
109 }
110
111 static void
112 stpy_dealloc (PyObject *self)
113 {
114   lazy_string_object *self_string = (lazy_string_object *) self;
115
116   xfree (self_string->encoding);
117 }
118
119 PyObject *
120 gdbpy_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
125   if (address == 0 && length != 0)
126     {
127       PyErr_SetString (PyExc_MemoryError,
128                        _("Cannot create a lazy string with address 0x0, " \
129                          "and a non-zero length."));
130       return NULL;
131     }
132
133   if (!type)
134     {
135       PyErr_SetString (PyExc_RuntimeError,
136                        _("A lazy string's type cannot be NULL."));
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
155 void
156 gdbpy_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.  */
166 int
167 gdbpy_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.  */
177 gdb_byte *
178 gdbpy_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);
202   addr = PyLong_AsUnsignedLongLong (py_addr);
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
256 static 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
263 static 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
271 static 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.048596 seconds and 4 git commands to generate.