1 /* Scheme interface to lazy strings.
3 Copyright (C) 2010-2014 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. */
26 #include "exceptions.h"
29 #include "guile-internal.h"
31 /* The <gdb:lazy-string> smob. */
35 /* This always appears first. */
38 /* Holds the address of the lazy string. */
41 /* Holds the encoding that will be applied to the string when the string
42 is printed by GDB. If the encoding is set to NULL then GDB will select
43 the most appropriate encoding when the sting is printed.
44 Space for this is malloc'd and will be freed when the object is
48 /* Holds the length of the string in characters. If the length is -1,
49 then the string will be fetched and encoded up to the first null of
53 /* This attribute holds the type that is represented by the lazy
58 static const char lazy_string_smob_name
[] = "gdb:lazy-string";
60 /* The tag Guile knows the lazy string smob by. */
61 static scm_t_bits lazy_string_smob_tag
;
63 /* Administrivia for lazy string smobs. */
65 /* The smob "free" function for <gdb:lazy-string>. */
68 lsscm_free_lazy_string_smob (SCM self
)
70 lazy_string_smob
*v_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (self
);
72 xfree (v_smob
->encoding
);
77 /* The smob "print" function for <gdb:lazy-string>. */
80 lsscm_print_lazy_string_smob (SCM self
, SCM port
, scm_print_state
*pstate
)
82 lazy_string_smob
*ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (self
);
84 gdbscm_printf (port
, "#<%s", lazy_string_smob_name
);
85 gdbscm_printf (port
, " @%s", hex_string (ls_smob
->address
));
86 if (ls_smob
->length
>= 0)
87 gdbscm_printf (port
, " length %d", ls_smob
->length
);
88 if (ls_smob
->encoding
!= NULL
)
89 gdbscm_printf (port
, " encoding %s", ls_smob
->encoding
);
92 scm_remember_upto_here_1 (self
);
94 /* Non-zero means success. */
98 /* Low level routine to create a <gdb:lazy-string> object.
99 The caller must verify !(address == 0 && length != 0). */
102 lsscm_make_lazy_string_smob (CORE_ADDR address
, int length
,
103 const char *encoding
, struct type
*type
)
105 lazy_string_smob
*ls_smob
= (lazy_string_smob
*)
106 scm_gc_malloc (sizeof (lazy_string_smob
), lazy_string_smob_name
);
109 /* Caller must verify this. */
110 gdb_assert (!(address
== 0 && length
!= 0));
111 gdb_assert (type
!= NULL
);
113 ls_smob
->address
= address
;
114 /* Coerce all values < 0 to -1. */
115 ls_smob
->length
= length
< 0 ? -1 : length
;
116 if (encoding
== NULL
|| strcmp (encoding
, "") == 0)
117 ls_smob
->encoding
= NULL
;
119 ls_smob
->encoding
= xstrdup (encoding
);
120 ls_smob
->type
= type
;
122 ls_scm
= scm_new_smob (lazy_string_smob_tag
, (scm_t_bits
) ls_smob
);
123 gdbscm_init_gsmob (&ls_smob
->base
);
128 /* Return non-zero if SCM is a <gdb:lazy-string> object. */
131 lsscm_is_lazy_string (SCM scm
)
133 return SCM_SMOB_PREDICATE (lazy_string_smob_tag
, scm
);
136 /* (lazy-string? object) -> boolean */
139 gdbscm_lazy_string_p (SCM scm
)
141 return scm_from_bool (lsscm_is_lazy_string (scm
));
144 /* Main entry point to create a <gdb:lazy-string> object.
145 If there's an error a <gdb:exception> object is returned. */
148 lsscm_make_lazy_string (CORE_ADDR address
, int length
,
149 const char *encoding
, struct type
*type
)
151 if (address
== 0 && length
!= 0)
153 return gdbscm_make_out_of_range_error
154 (NULL
, 0, scm_from_int (length
),
155 _("cannot create a lazy string with address 0x0"
156 " and a non-zero length"));
161 return gdbscm_make_out_of_range_error
162 (NULL
, 0, scm_from_int (0), _("a lazy string's type cannot be NULL"));
165 return lsscm_make_lazy_string_smob (address
, length
, encoding
, type
);
168 /* Returns the <gdb:lazy-string> smob in SELF.
169 Throws an exception if SELF is not a <gdb:lazy-string> object. */
172 lsscm_get_lazy_string_arg_unsafe (SCM self
, int arg_pos
, const char *func_name
)
174 SCM_ASSERT_TYPE (lsscm_is_lazy_string (self
), self
, arg_pos
, func_name
,
175 lazy_string_smob_name
);
180 /* Lazy string methods. */
182 /* (lazy-string-address <gdb:lazy-string>) -> address */
185 gdbscm_lazy_string_address (SCM self
)
187 SCM ls_scm
= lsscm_get_lazy_string_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
188 lazy_string_smob
*ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (ls_scm
);
190 return gdbscm_scm_from_ulongest (ls_smob
->address
);
193 /* (lazy-string-length <gdb:lazy-string>) -> integer */
196 gdbscm_lazy_string_length (SCM self
)
198 SCM ls_scm
= lsscm_get_lazy_string_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
199 lazy_string_smob
*ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (ls_scm
);
201 return scm_from_int (ls_smob
->length
);
204 /* (lazy-string-encoding <gdb:lazy-string>) -> string */
207 gdbscm_lazy_string_encoding (SCM self
)
209 SCM ls_scm
= lsscm_get_lazy_string_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
210 lazy_string_smob
*ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (ls_scm
);
212 /* An encoding can be set to NULL by the user, so check first.
213 If NULL return #f. */
215 return gdbscm_scm_from_c_string (ls_smob
->encoding
);
219 /* (lazy-string-type <gdb:lazy-string>) -> <gdb:type> */
222 gdbscm_lazy_string_type (SCM self
)
224 SCM ls_scm
= lsscm_get_lazy_string_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
225 lazy_string_smob
*ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (ls_scm
);
227 return tyscm_scm_from_type (ls_smob
->type
);
230 /* (lazy-string->value <gdb:lazy-string>) -> <gdb:value> */
233 gdbscm_lazy_string_to_value (SCM self
)
235 SCM ls_scm
= lsscm_get_lazy_string_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
236 lazy_string_smob
*ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (ls_scm
);
237 struct value
*value
= NULL
;
238 volatile struct gdb_exception except
;
240 if (ls_smob
->address
== 0)
242 gdbscm_throw (gdbscm_make_out_of_range_error (FUNC_NAME
, SCM_ARG1
, self
,
243 _("cannot create a value from NULL")));
246 TRY_CATCH (except
, RETURN_MASK_ALL
)
248 value
= value_at_lazy (ls_smob
->type
, ls_smob
->address
);
250 GDBSCM_HANDLE_GDB_EXCEPTION (except
);
252 return vlscm_scm_from_value (value
);
255 /* A "safe" version of gdbscm_lazy_string_to_value for use by
256 vlscm_convert_typed_value_from_scheme.
257 The result, upon success, is the value of <gdb:lazy-string> STRING.
258 ARG_POS is the argument position of STRING in the original Scheme
259 function call, used in exception text.
260 If there's an error, NULL is returned and a <gdb:exception> object
261 is stored in *except_scmp.
263 Note: The result is still "lazy". The caller must call value_fetch_lazy
264 to actually fetch the value. */
267 lsscm_safe_lazy_string_to_value (SCM string
, int arg_pos
,
268 const char *func_name
, SCM
*except_scmp
)
270 lazy_string_smob
*ls_smob
;
271 struct value
*value
= NULL
;
272 volatile struct gdb_exception except
;
274 gdb_assert (lsscm_is_lazy_string (string
));
276 ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (string
);
277 *except_scmp
= SCM_BOOL_F
;
279 if (ls_smob
->address
== 0)
282 = gdbscm_make_out_of_range_error (FUNC_NAME
, SCM_ARG1
, string
,
283 _("cannot create a value from NULL"));
287 TRY_CATCH (except
, RETURN_MASK_ALL
)
289 value
= value_at_lazy (ls_smob
->type
, ls_smob
->address
);
291 if (except
.reason
< 0)
293 *except_scmp
= gdbscm_scm_from_gdb_exception (except
);
300 /* Print a lazy string to STREAM using val_print_string.
301 STRING must be a <gdb:lazy-string> object. */
304 lsscm_val_print_lazy_string (SCM string
, struct ui_file
*stream
,
305 const struct value_print_options
*options
)
307 lazy_string_smob
*ls_smob
;
309 gdb_assert (lsscm_is_lazy_string (string
));
311 ls_smob
= (lazy_string_smob
*) SCM_SMOB_DATA (string
);
313 val_print_string (ls_smob
->type
, ls_smob
->encoding
,
314 ls_smob
->address
, ls_smob
->length
,
318 /* Initialize the Scheme lazy-strings code. */
320 static const scheme_function lazy_string_functions
[] =
322 { "lazy-string?", 1, 0, 0, gdbscm_lazy_string_p
,
324 Return #t if the object is a <gdb:lazy-string> object." },
326 { "lazy-string-address", 1, 0, 0, gdbscm_lazy_string_address
,
328 Return the address of the lazy-string." },
330 { "lazy-string-length", 1, 0, 0, gdbscm_lazy_string_length
,
332 Return the length of the lazy-string.\n\
333 If the length is -1 then the length is determined by the first null\n\
334 of appropriate width." },
336 { "lazy-string-encoding", 1, 0, 0, gdbscm_lazy_string_encoding
,
338 Return the encoding of the lazy-string." },
340 { "lazy-string-type", 1, 0, 0, gdbscm_lazy_string_type
,
342 Return the <gdb:type> of the lazy-string." },
344 { "lazy-string->value", 1, 0, 0, gdbscm_lazy_string_to_value
,
346 Return the <gdb:value> representation of the lazy-string." },
352 gdbscm_initialize_lazy_strings (void)
354 lazy_string_smob_tag
= gdbscm_make_smob_type (lazy_string_smob_name
,
355 sizeof (lazy_string_smob
));
356 scm_set_smob_free (lazy_string_smob_tag
, lsscm_free_lazy_string_smob
);
357 scm_set_smob_print (lazy_string_smob_tag
, lsscm_print_lazy_string_smob
);
359 gdbscm_define_functions (lazy_string_functions
, 1);