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