Add translations for various sub-directories
[binutils-gdb.git] / gdb / python / py-lazy-string.c
blob1226c280174ac5c9c2c26f6bdf36508a5047a0ab
1 /* Python interface to lazy strings.
3 Copyright (C) 2010-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
20 #include "python-internal.h"
21 #include "charset.h"
22 #include "value.h"
23 #include "valprint.h"
24 #include "language.h"
26 struct lazy_string_object {
27 PyObject_HEAD
29 /* Holds the address of the lazy string. */
30 CORE_ADDR address;
32 /* Holds the encoding that will be applied to the string
33 when the string is printed by GDB. If the encoding is set
34 to None then GDB will select the most appropriate
35 encoding when the sting is printed. */
36 char *encoding;
38 /* If TYPE is an array: If the length is known, then this value is the
39 array's length, otherwise it is -1.
40 If TYPE is not an array: Then this value represents the string's length.
41 In either case, if the value is -1 then the string will be fetched and
42 encoded up to the first null of appropriate width. */
43 long length;
45 /* This attribute holds the type of the string.
46 For example if the lazy string was created from a C "char*" then TYPE
47 represents a C "char*".
48 To get the type of the character in the string call
49 stpy_lazy_string_elt_type.
50 This is recorded as a PyObject so that we take advantage of support for
51 preserving the type should its owning objfile go away. */
52 PyObject *type;
55 extern PyTypeObject lazy_string_object_type
56 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("lazy_string_object");
58 static PyObject *
59 stpy_get_address (PyObject *self, void *closure)
61 lazy_string_object *self_string = (lazy_string_object *) self;
63 return gdb_py_object_from_ulongest (self_string->address).release ();
66 static PyObject *
67 stpy_get_encoding (PyObject *self, void *closure)
69 lazy_string_object *self_string = (lazy_string_object *) self;
70 PyObject *result;
72 /* An encoding can be set to NULL by the user, so check before
73 attempting a Python FromString call. If NULL return Py_None. */
74 if (self_string->encoding)
75 result = PyUnicode_FromString (self_string->encoding);
76 else
78 result = Py_None;
79 Py_INCREF (result);
82 return result;
85 static PyObject *
86 stpy_get_length (PyObject *self, void *closure)
88 lazy_string_object *self_string = (lazy_string_object *) self;
90 return gdb_py_object_from_longest (self_string->length).release ();
93 static PyObject *
94 stpy_get_type (PyObject *self, void *closure)
96 lazy_string_object *str_obj = (lazy_string_object *) self;
98 Py_INCREF (str_obj->type);
99 return str_obj->type;
102 static PyObject *
103 stpy_convert_to_value (PyObject *self, PyObject *args)
105 lazy_string_object *self_string = (lazy_string_object *) self;
107 if (self_string->address == 0)
109 PyErr_SetString (gdbpy_gdb_memory_error,
110 _("Cannot create a value from NULL."));
111 return NULL;
114 PyObject *result = nullptr;
117 scoped_value_mark free_values;
119 struct type *type = type_object_to_type (self_string->type);
120 struct type *realtype;
121 struct value *val;
123 gdb_assert (type != NULL);
124 realtype = check_typedef (type);
125 switch (realtype->code ())
127 case TYPE_CODE_PTR:
128 /* If a length is specified we need to convert this to an array
129 of the specified size. */
130 if (self_string->length != -1)
132 /* PR 20786: There's no way to specify an array of length zero.
133 Record a length of [0,-1] which is how Ada does it. Anything
134 we do is broken, but this is one possible solution. */
135 type = lookup_array_range_type (realtype->target_type (),
136 0, self_string->length - 1);
137 val = value_at_lazy (type, self_string->address);
139 else
140 val = value_from_pointer (type, self_string->address);
141 break;
142 default:
143 val = value_at_lazy (type, self_string->address);
144 break;
147 result = value_to_value_object (val);
149 catch (const gdb_exception &except)
151 return gdbpy_handle_gdb_exception (nullptr, except);
154 return result;
157 static void
158 stpy_dealloc (PyObject *self)
160 lazy_string_object *self_string = (lazy_string_object *) self;
162 xfree (self_string->encoding);
163 Py_TYPE (self)->tp_free (self);
166 /* Low level routine to create a <gdb.LazyString> object.
168 Note: If TYPE is an array, LENGTH either must be -1 (meaning to use the
169 size of the array, which may itself be unknown in which case a length of
170 -1 is still used) or must be the length of the array. */
172 PyObject *
173 gdbpy_create_lazy_string_object (CORE_ADDR address, long length,
174 const char *encoding, struct type *type)
176 lazy_string_object *str_obj = NULL;
177 struct type *realtype;
179 if (length < -1)
181 PyErr_SetString (PyExc_ValueError, _("Invalid length."));
182 return NULL;
185 if (!type)
187 PyErr_SetString (PyExc_RuntimeError,
188 _("A lazy string's type cannot be NULL."));
189 return NULL;
192 realtype = check_typedef (type);
193 switch (realtype->code ())
195 case TYPE_CODE_ARRAY:
197 LONGEST array_length = -1;
198 LONGEST low_bound, high_bound;
200 if (get_array_bounds (realtype, &low_bound, &high_bound))
201 array_length = high_bound - low_bound + 1;
202 if (length == -1)
203 length = array_length;
204 else if (length != array_length)
206 PyErr_SetString (PyExc_ValueError, _("Invalid length."));
207 return NULL;
209 break;
212 case TYPE_CODE_PTR:
213 if (address == 0)
215 if (length > 0)
217 PyErr_SetString (gdbpy_gdb_memory_error,
218 _("Cannot create a lazy string with address 0x0, " \
219 "and a non-zero length."));
220 return nullptr;
222 length = 0;
224 break;
226 default:
227 gdb_assert_not_reached ("invalid type in gdbpy_create_lazy_string_object");
230 str_obj = PyObject_New (lazy_string_object, &lazy_string_object_type);
231 if (!str_obj)
232 return NULL;
234 str_obj->address = address;
235 str_obj->length = length;
236 if (encoding == NULL || !strcmp (encoding, ""))
237 str_obj->encoding = NULL;
238 else
239 str_obj->encoding = xstrdup (encoding);
240 str_obj->type = type_to_type_object (type);
242 return (PyObject *) str_obj;
245 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
246 gdbpy_initialize_lazy_string (void)
248 return gdbpy_type_ready (&lazy_string_object_type);
251 /* Determine whether the printer object pointed to by OBJ is a
252 Python lazy string. */
254 gdbpy_is_lazy_string (PyObject *result)
256 return PyObject_TypeCheck (result, &lazy_string_object_type);
259 /* Return the type of a character in lazy string LAZY. */
261 static struct type *
262 stpy_lazy_string_elt_type (lazy_string_object *lazy)
264 struct type *type = type_object_to_type (lazy->type);
265 struct type *realtype;
267 gdb_assert (type != NULL);
268 realtype = check_typedef (type);
270 switch (realtype->code ())
272 case TYPE_CODE_PTR:
273 case TYPE_CODE_ARRAY:
274 return check_typedef (realtype->target_type ());
275 default:
276 gdb_assert_not_reached ("invalid lazy string");
280 /* Extract the parameters from the lazy string object STRING.
281 ENCODING may be set to NULL, if no encoding is found. */
283 void
284 gdbpy_extract_lazy_string (PyObject *string, CORE_ADDR *addr,
285 struct type **str_elt_type,
286 long *length,
287 gdb::unique_xmalloc_ptr<char> *encoding)
289 lazy_string_object *lazy;
291 gdb_assert (gdbpy_is_lazy_string (string));
293 lazy = (lazy_string_object *) string;
295 *addr = lazy->address;
296 *str_elt_type = stpy_lazy_string_elt_type (lazy);
297 *length = lazy->length;
298 encoding->reset (lazy->encoding ? xstrdup (lazy->encoding) : NULL);
301 /* __str__ for LazyString. */
303 static PyObject *
304 stpy_str (PyObject *self)
306 lazy_string_object *str = (lazy_string_object *) self;
308 struct value_print_options opts;
309 get_user_print_options (&opts);
310 opts.addressprint = false;
312 string_file stream;
315 struct type *type = stpy_lazy_string_elt_type (str);
316 val_print_string (type, str->encoding, str->address, str->length,
317 &stream, &opts);
319 catch (const gdb_exception &exc)
321 return gdbpy_handle_gdb_exception (nullptr, exc);
324 return host_string_to_python_string (stream.c_str ()).release ();
327 GDBPY_INITIALIZE_FILE (gdbpy_initialize_lazy_string);
331 static PyMethodDef lazy_string_object_methods[] = {
332 { "value", stpy_convert_to_value, METH_NOARGS,
333 "Create a (lazy) value that contains a pointer to the string." },
334 {NULL} /* Sentinel */
338 static gdb_PyGetSetDef lazy_string_object_getset[] = {
339 { "address", stpy_get_address, NULL, "Address of the string.", NULL },
340 { "encoding", stpy_get_encoding, NULL, "Encoding of the string.", NULL },
341 { "length", stpy_get_length, NULL, "Length of the string.", NULL },
342 { "type", stpy_get_type, NULL, "Type associated with the string.", NULL },
343 { NULL } /* Sentinel */
346 PyTypeObject lazy_string_object_type = {
347 PyVarObject_HEAD_INIT (NULL, 0)
348 "gdb.LazyString", /*tp_name*/
349 sizeof (lazy_string_object), /*tp_basicsize*/
350 0, /*tp_itemsize*/
351 stpy_dealloc, /*tp_dealloc*/
352 0, /*tp_print*/
353 0, /*tp_getattr*/
354 0, /*tp_setattr*/
355 0, /*tp_compare*/
356 0, /*tp_repr*/
357 0, /*tp_as_number*/
358 0, /*tp_as_sequence*/
359 0, /*tp_as_mapping*/
360 0, /*tp_hash */
361 0, /*tp_call*/
362 stpy_str, /*tp_str*/
363 0, /*tp_getattro*/
364 0, /*tp_setattro*/
365 0, /*tp_as_buffer*/
366 Py_TPFLAGS_DEFAULT, /*tp_flags*/
367 "GDB lazy string object", /* tp_doc */
368 0, /* tp_traverse */
369 0, /* tp_clear */
370 0, /* tp_richcompare */
371 0, /* tp_weaklistoffset */
372 0, /* tp_iter */
373 0, /* tp_iternext */
374 lazy_string_object_methods, /* tp_methods */
375 0, /* tp_members */
376 lazy_string_object_getset /* tp_getset */