1 /* Scheme interface to lazy strings.
3 Copyright (C) 2010-2020 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 /* See README file in this directory for implementation notes, coding
21 conventions, et.al. */
28 #include "guile-internal.h"
30 /* The <gdb:lazy-string> smob. */
34 /* This always appears first. */
37 /* Holds the address of the lazy string. */
40 /* Holds the encoding that will be applied to the string when the string
41 is printed by GDB. If the encoding is set to NULL then GDB will select
42 the most appropriate encoding when the sting is printed.
43 Space for this is malloc'd and will be freed when the object is
47 /* If TYPE is an array: If the length is known, then this value is the
48 array's length, otherwise it is -1.
49 If TYPE is not an array: Then this value represents the string's length.
50 In either case, if the value is -1 then the string will be fetched and
51 encoded up to the first null of appropriate width. */
54 /* The type of the string.
55 For example if the lazy string was created from a C "char*" then TYPE
56 represents a C "char*". To get the type of the character in the string
57 call lsscm_elt_type which handles the different kinds of values for TYPE.
58 This is recorded as an SCM object so that we take advantage of support for
59 preserving the type should its owning objfile go away. */
63 static const char lazy_string_smob_name
[] = "gdb:lazy-string";
65 /* The tag Guile knows the lazy string smob by. */
66 static scm_t_bits lazy_string_smob_tag
;
68 /* Administrivia for lazy string smobs. */
70 /* The smob "free" function for <gdb:lazy-string>. */
73 lsscm_free_lazy_string_smob (SCM self
)
75 lazy_string_smob
*v_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (self
);
77 xfree (v_smob
->encoding
);
82 /* The smob "print" function for <gdb:lazy-string>. */
85 lsscm_print_lazy_string_smob (SCM self
, SCM port
, scm_print_state
*pstate
)
87 lazy_string_smob
*ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (self
);
89 gdbscm_printf (port
, "#<%s", lazy_string_smob_name
);
90 gdbscm_printf (port
, " @%s", hex_string (ls_smob
->address
));
91 if (ls_smob
->length
>= 0)
92 gdbscm_printf (port
, " length %d", ls_smob
->length
);
93 if (ls_smob
->encoding
!= NULL
)
94 gdbscm_printf (port
, " encoding %s", ls_smob
->encoding
);
97 scm_remember_upto_here_1 (self
);
99 /* Non-zero means success. */
103 /* Low level routine to create a <gdb:lazy-string> object.
104 The caller must verify:
106 - !(address == 0 && length != 0)
110 lsscm_make_lazy_string_smob (CORE_ADDR address
, int length
,
111 const char *encoding
, struct type
*type
)
113 lazy_string_smob
*ls_smob
= (lazy_string_smob
*)
114 scm_gc_malloc (sizeof (lazy_string_smob
), lazy_string_smob_name
);
117 gdb_assert (length
>= -1);
118 gdb_assert (!(address
== 0 && length
!= 0));
119 gdb_assert (type
!= NULL
);
121 ls_smob
->address
= address
;
122 ls_smob
->length
= length
;
123 if (encoding
== NULL
|| strcmp (encoding
, "") == 0)
124 ls_smob
->encoding
= NULL
;
126 ls_smob
->encoding
= xstrdup (encoding
);
127 ls_smob
->type
= tyscm_scm_from_type (type
);
129 ls_scm
= scm_new_smob (lazy_string_smob_tag
, (scm_t_bits
) ls_smob
);
130 gdbscm_init_gsmob (&ls_smob
->base
);
135 /* Return non-zero if SCM is a <gdb:lazy-string> object. */
138 lsscm_is_lazy_string (SCM scm
)
140 return SCM_SMOB_PREDICATE (lazy_string_smob_tag
, scm
);
143 /* (lazy-string? object) -> boolean */
146 gdbscm_lazy_string_p (SCM scm
)
148 return scm_from_bool (lsscm_is_lazy_string (scm
));
151 /* Main entry point to create a <gdb:lazy-string> object.
152 If there's an error a <gdb:exception> object is returned. */
155 lsscm_make_lazy_string (CORE_ADDR address
, int length
,
156 const char *encoding
, struct type
*type
)
160 return gdbscm_make_out_of_range_error (NULL
, 0,
161 scm_from_int (length
),
162 _("invalid length"));
165 if (address
== 0 && length
!= 0)
167 return gdbscm_make_out_of_range_error
168 (NULL
, 0, scm_from_int (length
),
169 _("cannot create a lazy string with address 0x0,"
170 " and a non-zero length"));
175 return gdbscm_make_out_of_range_error
176 (NULL
, 0, scm_from_int (0), _("a lazy string's type cannot be NULL"));
179 return lsscm_make_lazy_string_smob (address
, length
, encoding
, type
);
182 /* Returns the <gdb:lazy-string> smob in SELF.
183 Throws an exception if SELF is not a <gdb:lazy-string> object. */
186 lsscm_get_lazy_string_arg_unsafe (SCM self
, int arg_pos
, const char *func_name
)
188 SCM_ASSERT_TYPE (lsscm_is_lazy_string (self
), self
, arg_pos
, func_name
,
189 lazy_string_smob_name
);
194 /* Return the type of a character in lazy string LS_SMOB. */
197 lsscm_elt_type (lazy_string_smob
*ls_smob
)
199 struct type
*type
= tyscm_scm_to_type (ls_smob
->type
);
200 struct type
*realtype
;
202 realtype
= check_typedef (type
);
204 switch (TYPE_CODE (realtype
))
207 case TYPE_CODE_ARRAY
:
208 return TYPE_TARGET_TYPE (realtype
);
210 /* This is done to preserve existing behaviour. PR 20769.
211 E.g., gdb.parse_and_eval("my_int_variable").lazy_string().type. */
216 /* Lazy string methods. */
218 /* (lazy-string-address <gdb:lazy-string>) -> address */
221 gdbscm_lazy_string_address (SCM self
)
223 SCM ls_scm
= lsscm_get_lazy_string_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
224 lazy_string_smob
*ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (ls_scm
);
226 return gdbscm_scm_from_ulongest (ls_smob
->address
);
229 /* (lazy-string-length <gdb:lazy-string>) -> integer */
232 gdbscm_lazy_string_length (SCM self
)
234 SCM ls_scm
= lsscm_get_lazy_string_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
235 lazy_string_smob
*ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (ls_scm
);
237 return scm_from_int (ls_smob
->length
);
240 /* (lazy-string-encoding <gdb:lazy-string>) -> string */
243 gdbscm_lazy_string_encoding (SCM self
)
245 SCM ls_scm
= lsscm_get_lazy_string_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
246 lazy_string_smob
*ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (ls_scm
);
248 /* An encoding can be set to NULL by the user, so check first.
249 If NULL return #f. */
251 return gdbscm_scm_from_c_string (ls_smob
->encoding
);
255 /* (lazy-string-type <gdb:lazy-string>) -> <gdb:type> */
258 gdbscm_lazy_string_type (SCM self
)
260 SCM ls_scm
= lsscm_get_lazy_string_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
261 lazy_string_smob
*ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (ls_scm
);
263 return ls_smob
->type
;
266 /* (lazy-string->value <gdb:lazy-string>) -> <gdb:value> */
269 gdbscm_lazy_string_to_value (SCM self
)
271 SCM ls_scm
= lsscm_get_lazy_string_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
275 value
= lsscm_safe_lazy_string_to_value (ls_scm
, SCM_ARG1
, FUNC_NAME
,
278 gdbscm_throw (except_scm
);
279 return vlscm_scm_from_value (value
);
282 /* A "safe" version of gdbscm_lazy_string_to_value for use by
283 vlscm_convert_typed_value_from_scheme.
284 The result, upon success, is the value of <gdb:lazy-string> STRING.
285 ARG_POS is the argument position of STRING in the original Scheme
286 function call, used in exception text.
287 If there's an error, NULL is returned and a <gdb:exception> object
288 is stored in *except_scmp.
290 Note: The result is still "lazy". The caller must call value_fetch_lazy
291 to actually fetch the value. */
294 lsscm_safe_lazy_string_to_value (SCM string
, int arg_pos
,
295 const char *func_name
, SCM
*except_scmp
)
297 lazy_string_smob
*ls_smob
;
298 struct value
*value
= NULL
;
300 gdb_assert (lsscm_is_lazy_string (string
));
302 ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (string
);
304 if (ls_smob
->address
== 0)
307 = gdbscm_make_out_of_range_error (func_name
, arg_pos
, string
,
308 _("cannot create a value from NULL"));
314 struct type
*type
= tyscm_scm_to_type (ls_smob
->type
);
315 struct type
*realtype
= check_typedef (type
);
317 switch (TYPE_CODE (realtype
))
320 /* If a length is specified we need to convert this to an array
321 of the specified size. */
322 if (ls_smob
->length
!= -1)
324 /* PR 20786: There's no way to specify an array of length zero.
325 Record a length of [0,-1] which is how Ada does it. Anything
326 we do is broken, but this one possible solution. */
327 type
= lookup_array_range_type (TYPE_TARGET_TYPE (realtype
),
328 0, ls_smob
->length
- 1);
329 value
= value_at_lazy (type
, ls_smob
->address
);
332 value
= value_from_pointer (type
, ls_smob
->address
);
335 value
= value_at_lazy (type
, ls_smob
->address
);
339 catch (const gdb_exception
&except
)
341 *except_scmp
= gdbscm_scm_from_gdb_exception (unpack (except
));
348 /* Print a lazy string to STREAM using val_print_string.
349 STRING must be a <gdb:lazy-string> object. */
352 lsscm_val_print_lazy_string (SCM string
, struct ui_file
*stream
,
353 const struct value_print_options
*options
)
355 lazy_string_smob
*ls_smob
;
356 struct type
*elt_type
;
358 gdb_assert (lsscm_is_lazy_string (string
));
360 ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (string
);
361 elt_type
= lsscm_elt_type (ls_smob
);
363 val_print_string (elt_type
, ls_smob
->encoding
,
364 ls_smob
->address
, ls_smob
->length
,
368 /* Initialize the Scheme lazy-strings code. */
370 static const scheme_function lazy_string_functions
[] =
372 { "lazy-string?", 1, 0, 0, as_a_scm_t_subr (gdbscm_lazy_string_p
),
374 Return #t if the object is a <gdb:lazy-string> object." },
376 { "lazy-string-address", 1, 0, 0,
377 as_a_scm_t_subr (gdbscm_lazy_string_address
),
379 Return the address of the lazy-string." },
381 { "lazy-string-length", 1, 0, 0, as_a_scm_t_subr (gdbscm_lazy_string_length
),
383 Return the length of the lazy-string.\n\
384 If the length is -1 then the length is determined by the first null\n\
385 of appropriate width." },
387 { "lazy-string-encoding", 1, 0, 0,
388 as_a_scm_t_subr (gdbscm_lazy_string_encoding
),
390 Return the encoding of the lazy-string." },
392 { "lazy-string-type", 1, 0, 0, as_a_scm_t_subr (gdbscm_lazy_string_type
),
394 Return the <gdb:type> of the lazy-string." },
396 { "lazy-string->value", 1, 0, 0,
397 as_a_scm_t_subr (gdbscm_lazy_string_to_value
),
399 Return the <gdb:value> representation of the lazy-string." },
405 gdbscm_initialize_lazy_strings (void)
407 lazy_string_smob_tag
= gdbscm_make_smob_type (lazy_string_smob_name
,
408 sizeof (lazy_string_smob
));
409 scm_set_smob_free (lazy_string_smob_tag
, lsscm_free_lazy_string_smob
);
410 scm_set_smob_print (lazy_string_smob_tag
, lsscm_print_lazy_string_smob
);
412 gdbscm_define_functions (lazy_string_functions
, 1);