1 /* Scheme 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 /* See README file in this directory for implementation notes, coding
21 conventions, et.al. */
27 #include "guile-internal.h"
29 /* The <gdb:lazy-string> smob. */
31 struct lazy_string_smob
33 /* This always appears first. */
36 /* Holds the address of the lazy string. */
39 /* Holds the encoding that will be applied to the string when the string
40 is printed by GDB. If the encoding is set to NULL then GDB will select
41 the most appropriate encoding when the sting is printed.
42 Space for this is malloc'd and will be freed when the object is
46 /* If TYPE is an array: If the length is known, then this value is the
47 array's length, otherwise it is -1.
48 If TYPE is not an array: Then this value represents the string's length.
49 In either case, if the value is -1 then the string will be fetched and
50 encoded up to the first null of appropriate width. */
53 /* The type of the string.
54 For example if the lazy string was created from a C "char*" then TYPE
55 represents a C "char*". To get the type of the character in the string
56 call lsscm_elt_type which handles the different kinds of values for TYPE.
57 This is recorded as an SCM object so that we take advantage of support for
58 preserving the type should its owning objfile go away. */
62 static const char lazy_string_smob_name
[] = "gdb:lazy-string";
64 /* The tag Guile knows the lazy string smob by. */
65 static scm_t_bits lazy_string_smob_tag
;
67 /* Administrivia for lazy string smobs. */
69 /* The smob "free" function for <gdb:lazy-string>. */
72 lsscm_free_lazy_string_smob (SCM self
)
74 lazy_string_smob
*v_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (self
);
76 xfree (v_smob
->encoding
);
81 /* The smob "print" function for <gdb:lazy-string>. */
84 lsscm_print_lazy_string_smob (SCM self
, SCM port
, scm_print_state
*pstate
)
86 lazy_string_smob
*ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (self
);
88 gdbscm_printf (port
, "#<%s", lazy_string_smob_name
);
89 gdbscm_printf (port
, " @%s", hex_string (ls_smob
->address
));
90 if (ls_smob
->length
>= 0)
91 gdbscm_printf (port
, " length %d", ls_smob
->length
);
92 if (ls_smob
->encoding
!= NULL
)
93 gdbscm_printf (port
, " encoding %s", ls_smob
->encoding
);
96 scm_remember_upto_here_1 (self
);
98 /* Non-zero means success. */
102 /* Low level routine to create a <gdb:lazy-string> object.
103 The caller must verify:
105 - !(address == 0 && length != 0)
109 lsscm_make_lazy_string_smob (CORE_ADDR address
, int length
,
110 const char *encoding
, struct type
*type
)
112 lazy_string_smob
*ls_smob
= (lazy_string_smob
*)
113 scm_gc_malloc (sizeof (lazy_string_smob
), lazy_string_smob_name
);
116 gdb_assert (length
>= -1);
117 gdb_assert (!(address
== 0 && length
!= 0));
118 gdb_assert (type
!= NULL
);
120 ls_smob
->address
= address
;
121 ls_smob
->length
= length
;
122 if (encoding
== NULL
|| strcmp (encoding
, "") == 0)
123 ls_smob
->encoding
= NULL
;
125 ls_smob
->encoding
= xstrdup (encoding
);
126 ls_smob
->type
= tyscm_scm_from_type (type
);
128 ls_scm
= scm_new_smob (lazy_string_smob_tag
, (scm_t_bits
) ls_smob
);
129 gdbscm_init_gsmob (&ls_smob
->base
);
134 /* Return non-zero if SCM is a <gdb:lazy-string> object. */
137 lsscm_is_lazy_string (SCM scm
)
139 return SCM_SMOB_PREDICATE (lazy_string_smob_tag
, scm
);
142 /* (lazy-string? object) -> boolean */
145 gdbscm_lazy_string_p (SCM scm
)
147 return scm_from_bool (lsscm_is_lazy_string (scm
));
150 /* Main entry point to create a <gdb:lazy-string> object.
151 If there's an error a <gdb:exception> object is returned. */
154 lsscm_make_lazy_string (CORE_ADDR address
, int length
,
155 const char *encoding
, struct type
*type
)
159 return gdbscm_make_out_of_range_error (NULL
, 0,
160 scm_from_int (length
),
161 _("invalid length"));
164 if (address
== 0 && length
!= 0)
166 return gdbscm_make_out_of_range_error
167 (NULL
, 0, scm_from_int (length
),
168 _("cannot create a lazy string with address 0x0,"
169 " and a non-zero length"));
174 return gdbscm_make_out_of_range_error
175 (NULL
, 0, scm_from_int (0), _("a lazy string's type cannot be NULL"));
178 return lsscm_make_lazy_string_smob (address
, length
, encoding
, type
);
181 /* Returns the <gdb:lazy-string> smob in SELF.
182 Throws an exception if SELF is not a <gdb:lazy-string> object. */
185 lsscm_get_lazy_string_arg_unsafe (SCM self
, int arg_pos
, const char *func_name
)
187 SCM_ASSERT_TYPE (lsscm_is_lazy_string (self
), self
, arg_pos
, func_name
,
188 lazy_string_smob_name
);
193 /* Return the type of a character in lazy string LS_SMOB. */
196 lsscm_elt_type (lazy_string_smob
*ls_smob
)
198 struct type
*type
= tyscm_scm_to_type (ls_smob
->type
);
199 struct type
*realtype
;
201 realtype
= check_typedef (type
);
203 switch (realtype
->code ())
206 case TYPE_CODE_ARRAY
:
207 return realtype
->target_type ();
209 /* This is done to preserve existing behavior. PR 20769.
210 E.g., gdb.parse_and_eval("my_int_variable").lazy_string().type. */
215 /* Lazy string methods. */
217 /* (lazy-string-address <gdb:lazy-string>) -> address */
220 gdbscm_lazy_string_address (SCM self
)
222 SCM ls_scm
= lsscm_get_lazy_string_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
223 lazy_string_smob
*ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (ls_scm
);
225 return gdbscm_scm_from_ulongest (ls_smob
->address
);
228 /* (lazy-string-length <gdb:lazy-string>) -> integer */
231 gdbscm_lazy_string_length (SCM self
)
233 SCM ls_scm
= lsscm_get_lazy_string_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
234 lazy_string_smob
*ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (ls_scm
);
236 return scm_from_int (ls_smob
->length
);
239 /* (lazy-string-encoding <gdb:lazy-string>) -> string */
242 gdbscm_lazy_string_encoding (SCM self
)
244 SCM ls_scm
= lsscm_get_lazy_string_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
245 lazy_string_smob
*ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (ls_scm
);
247 /* An encoding can be set to NULL by the user, so check first.
248 If NULL return #f. */
250 return gdbscm_scm_from_c_string (ls_smob
->encoding
);
254 /* (lazy-string-type <gdb:lazy-string>) -> <gdb:type> */
257 gdbscm_lazy_string_type (SCM self
)
259 SCM ls_scm
= lsscm_get_lazy_string_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
260 lazy_string_smob
*ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (ls_scm
);
262 return ls_smob
->type
;
265 /* (lazy-string->value <gdb:lazy-string>) -> <gdb:value> */
268 gdbscm_lazy_string_to_value (SCM self
)
270 SCM ls_scm
= lsscm_get_lazy_string_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
274 value
= lsscm_safe_lazy_string_to_value (ls_scm
, SCM_ARG1
, FUNC_NAME
,
277 gdbscm_throw (except_scm
);
278 return vlscm_scm_from_value (value
);
281 /* A "safe" version of gdbscm_lazy_string_to_value for use by
282 vlscm_convert_typed_value_from_scheme.
283 The result, upon success, is the value of <gdb:lazy-string> STRING.
284 ARG_POS is the argument position of STRING in the original Scheme
285 function call, used in exception text.
286 If there's an error, NULL is returned and a <gdb:exception> object
287 is stored in *except_scmp.
289 Note: The result is still "lazy". The caller must call value_fetch_lazy
290 to actually fetch the value. */
293 lsscm_safe_lazy_string_to_value (SCM string
, int arg_pos
,
294 const char *func_name
, SCM
*except_scmp
)
296 lazy_string_smob
*ls_smob
;
297 struct value
*value
= NULL
;
299 gdb_assert (lsscm_is_lazy_string (string
));
301 ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (string
);
303 if (ls_smob
->address
== 0)
306 = gdbscm_make_out_of_range_error (func_name
, arg_pos
, string
,
307 _("cannot create a value from NULL"));
313 struct type
*type
= tyscm_scm_to_type (ls_smob
->type
);
314 struct type
*realtype
= check_typedef (type
);
316 switch (realtype
->code ())
319 /* If a length is specified we need to convert this to an array
320 of the specified size. */
321 if (ls_smob
->length
!= -1)
323 /* PR 20786: There's no way to specify an array of length zero.
324 Record a length of [0,-1] which is how Ada does it. Anything
325 we do is broken, but this one possible solution. */
326 type
= lookup_array_range_type (realtype
->target_type (),
327 0, ls_smob
->length
- 1);
328 value
= value_at_lazy (type
, ls_smob
->address
);
331 value
= value_from_pointer (type
, ls_smob
->address
);
334 value
= value_at_lazy (type
, ls_smob
->address
);
338 catch (const gdb_exception
&except
)
340 *except_scmp
= gdbscm_scm_from_gdb_exception (unpack (except
));
347 /* Print a lazy string to STREAM using val_print_string.
348 STRING must be a <gdb:lazy-string> object. */
351 lsscm_val_print_lazy_string (SCM string
, struct ui_file
*stream
,
352 const struct value_print_options
*options
)
354 lazy_string_smob
*ls_smob
;
355 struct type
*elt_type
;
357 gdb_assert (lsscm_is_lazy_string (string
));
359 ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (string
);
360 elt_type
= lsscm_elt_type (ls_smob
);
362 val_print_string (elt_type
, ls_smob
->encoding
,
363 ls_smob
->address
, ls_smob
->length
,
367 /* Initialize the Scheme lazy-strings code. */
369 static const scheme_function lazy_string_functions
[] =
371 { "lazy-string?", 1, 0, 0, as_a_scm_t_subr (gdbscm_lazy_string_p
),
373 Return #t if the object is a <gdb:lazy-string> object." },
375 { "lazy-string-address", 1, 0, 0,
376 as_a_scm_t_subr (gdbscm_lazy_string_address
),
378 Return the address of the lazy-string." },
380 { "lazy-string-length", 1, 0, 0, as_a_scm_t_subr (gdbscm_lazy_string_length
),
382 Return the length of the lazy-string.\n\
383 If the length is -1 then the length is determined by the first null\n\
384 of appropriate width." },
386 { "lazy-string-encoding", 1, 0, 0,
387 as_a_scm_t_subr (gdbscm_lazy_string_encoding
),
389 Return the encoding of the lazy-string." },
391 { "lazy-string-type", 1, 0, 0, as_a_scm_t_subr (gdbscm_lazy_string_type
),
393 Return the <gdb:type> of the lazy-string." },
395 { "lazy-string->value", 1, 0, 0,
396 as_a_scm_t_subr (gdbscm_lazy_string_to_value
),
398 Return the <gdb:value> representation of the lazy-string." },
404 gdbscm_initialize_lazy_strings (void)
406 lazy_string_smob_tag
= gdbscm_make_smob_type (lazy_string_smob_name
,
407 sizeof (lazy_string_smob
));
408 scm_set_smob_free (lazy_string_smob_tag
, lsscm_free_lazy_string_smob
);
409 scm_set_smob_print (lazy_string_smob_tag
, lsscm_print_lazy_string_smob
);
411 gdbscm_define_functions (lazy_string_functions
, 1);