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