]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/guile/scm-string.c
Update copyright year range in all GDB files
[thirdparty/binutils-gdb.git] / gdb / guile / scm-string.c
1 /* GDB/Scheme charset interface.
2
3 Copyright (C) 2014-2018 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 /* See README file in this directory for implementation notes, coding
21 conventions, et.al. */
22
23 #include "defs.h"
24 #include "charset.h"
25 #include "guile-internal.h"
26
27 /* Convert STRING to an int.
28 STRING must be a valid integer. */
29
30 int
31 gdbscm_scm_string_to_int (SCM string)
32 {
33 char *s = scm_to_latin1_string (string);
34 int r = atoi (s);
35
36 free (s);
37 return r;
38 }
39
40 /* Convert a C (latin1) string to an SCM string.
41 "latin1" is chosen because Guile won't throw an exception. */
42
43 SCM
44 gdbscm_scm_from_c_string (const char *string)
45 {
46 return scm_from_latin1_string (string);
47 }
48
49 /* Convert an SCM string to a C (latin1) string.
50 "latin1" is chosen because Guile won't throw an exception.
51 Space for the result is allocated with malloc, caller must free.
52 It is an error to call this if STRING is not a string. */
53
54 char *
55 gdbscm_scm_to_c_string (SCM string)
56 {
57 return scm_to_latin1_string (string);
58 }
59
60 /* Use printf to construct a Scheme string. */
61
62 SCM
63 gdbscm_scm_from_printf (const char *format, ...)
64 {
65 va_list args;
66 char *string;
67 SCM result;
68
69 va_start (args, format);
70 string = xstrvprintf (format, args);
71 va_end (args);
72 result = scm_from_latin1_string (string);
73 xfree (string);
74
75 return result;
76 }
77
78 /* Struct to pass data from gdbscm_scm_to_string to
79 gdbscm_call_scm_to_stringn. */
80
81 struct scm_to_stringn_data
82 {
83 SCM string;
84 size_t *lenp;
85 const char *charset;
86 scm_t_string_failed_conversion_handler conversion_kind;
87 char *result;
88 };
89
90 /* Helper for gdbscm_scm_to_string to call scm_to_stringn
91 from within scm_c_catch. */
92
93 static SCM
94 gdbscm_call_scm_to_stringn (void *datap)
95 {
96 struct scm_to_stringn_data *data = (struct scm_to_stringn_data *) datap;
97
98 data->result = scm_to_stringn (data->string, data->lenp, data->charset,
99 data->conversion_kind);
100 return SCM_BOOL_F;
101 }
102
103 /* Convert an SCM string to a string in charset CHARSET.
104 This function is guaranteed to not throw an exception.
105
106 If LENP is NULL then the returned string is NUL-terminated,
107 and an exception is thrown if the string contains embedded NULs.
108 Otherwise the string is not guaranteed to be NUL-terminated, but worse
109 there's no space to put a NUL if we wanted to (scm_to_stringn limitation).
110
111 If STRICT is non-zero, and there's a conversion error, then a
112 <gdb:exception> object is stored in *EXCEPT_SCMP, and NULL is returned.
113 If STRICT is zero, then escape sequences are used for characters that
114 can't be converted, and EXCEPT_SCMP may be passed as NULL.
115
116 Space for the result is allocated with malloc, caller must free.
117 It is an error to call this if STRING is not a string. */
118
119 char *
120 gdbscm_scm_to_string (SCM string, size_t *lenp,
121 const char *charset, int strict, SCM *except_scmp)
122 {
123 struct scm_to_stringn_data data;
124 SCM scm_result;
125
126 data.string = string;
127 data.lenp = lenp;
128 data.charset = charset;
129 data.conversion_kind = (strict
130 ? SCM_FAILED_CONVERSION_ERROR
131 : SCM_FAILED_CONVERSION_ESCAPE_SEQUENCE);
132 data.result = NULL;
133
134 scm_result = gdbscm_call_guile (gdbscm_call_scm_to_stringn, &data, NULL);
135
136 if (gdbscm_is_false (scm_result))
137 {
138 gdb_assert (data.result != NULL);
139 return data.result;
140 }
141 gdb_assert (gdbscm_is_exception (scm_result));
142 *except_scmp = scm_result;
143 return NULL;
144 }
145
146 /* Struct to pass data from gdbscm_scm_from_string to
147 gdbscm_call_scm_from_stringn. */
148
149 struct scm_from_stringn_data
150 {
151 const char *string;
152 size_t len;
153 const char *charset;
154 scm_t_string_failed_conversion_handler conversion_kind;
155 SCM result;
156 };
157
158 /* Helper for gdbscm_scm_from_string to call scm_from_stringn
159 from within scm_c_catch. */
160
161 static SCM
162 gdbscm_call_scm_from_stringn (void *datap)
163 {
164 struct scm_from_stringn_data *data = (struct scm_from_stringn_data *) datap;
165
166 data->result = scm_from_stringn (data->string, data->len, data->charset,
167 data->conversion_kind);
168 return SCM_BOOL_F;
169 }
170
171 /* Convert STRING to a Scheme string in charset CHARSET.
172 This function is guaranteed to not throw an exception.
173
174 If STRICT is non-zero, and there's a conversion error, then a
175 <gdb:exception> object is returned.
176 If STRICT is zero, then question marks are used for characters that
177 can't be converted (limitation of underlying Guile conversion support). */
178
179 SCM
180 gdbscm_scm_from_string (const char *string, size_t len,
181 const char *charset, int strict)
182 {
183 struct scm_from_stringn_data data;
184 SCM scm_result;
185
186 data.string = string;
187 data.len = len;
188 data.charset = charset;
189 /* The use of SCM_FAILED_CONVERSION_QUESTION_MARK is specified by Guile. */
190 data.conversion_kind = (strict
191 ? SCM_FAILED_CONVERSION_ERROR
192 : SCM_FAILED_CONVERSION_QUESTION_MARK);
193 data.result = SCM_UNDEFINED;
194
195 scm_result = gdbscm_call_guile (gdbscm_call_scm_from_stringn, &data, NULL);
196
197 if (gdbscm_is_false (scm_result))
198 {
199 gdb_assert (!SCM_UNBNDP (data.result));
200 return data.result;
201 }
202 gdb_assert (gdbscm_is_exception (scm_result));
203 return scm_result;
204 }
205
206 /* Convert an SCM string to a host string.
207 This function is guaranteed to not throw an exception.
208
209 If LENP is NULL then the returned string is NUL-terminated,
210 and if the string contains embedded NULs then NULL is returned with
211 an exception object stored in *EXCEPT_SCMP.
212 Otherwise the string is not guaranteed to be NUL-terminated, but worse
213 there's no space to put a NUL if we wanted to (scm_to_stringn limitation).
214
215 Returns NULL if there is a conversion error, with the exception object
216 stored in *EXCEPT_SCMP.
217 Space for the result is allocated with malloc, caller must free.
218 It is an error to call this if STRING is not a string. */
219
220 char *
221 gdbscm_scm_to_host_string (SCM string, size_t *lenp, SCM *except_scmp)
222 {
223 return gdbscm_scm_to_string (string, lenp, host_charset (), 1, except_scmp);
224 }
225
226 /* Convert a host string to an SCM string.
227 This function is guaranteed to not throw an exception.
228 Returns a <gdb:exception> object if there's a conversion error. */
229
230 SCM
231 gdbscm_scm_from_host_string (const char *string, size_t len)
232 {
233 return gdbscm_scm_from_string (string, len, host_charset (), 1);
234 }
235
236 /* (string->argv string) -> list
237 Return list of strings split up according to GDB's argv parsing rules.
238 This is useful when writing GDB commands in Scheme. */
239
240 static SCM
241 gdbscm_string_to_argv (SCM string_scm)
242 {
243 char *string;
244 SCM result = SCM_EOL;
245
246 gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, NULL, "s",
247 string_scm, &string);
248
249 if (string == NULL || *string == '\0')
250 {
251 xfree (string);
252 return SCM_EOL;
253 }
254
255 gdb_argv c_argv (string);
256 for (char *arg : c_argv)
257 result = scm_cons (gdbscm_scm_from_c_string (arg), result);
258
259 xfree (string);
260
261 return scm_reverse_x (result, SCM_EOL);
262 }
263 \f
264 /* Initialize the Scheme charset interface to GDB. */
265
266 static const scheme_function string_functions[] =
267 {
268 { "string->argv", 1, 0, 0, as_a_scm_t_subr (gdbscm_string_to_argv),
269 "\
270 Convert a string to a list of strings split up according to\n\
271 gdb's argv parsing rules." },
272
273 END_FUNCTIONS
274 };
275
276 void
277 gdbscm_initialize_strings (void)
278 {
279 gdbscm_define_functions (string_functions, 1);
280 }