scm-utils.c revision 1.1.1.2 1 1.1 christos /* General utility routines for GDB/Scheme code.
2 1.1 christos
3 1.1 christos Copyright (C) 2014-2015 Free Software Foundation, Inc.
4 1.1 christos
5 1.1 christos This file is part of GDB.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos /* See README file in this directory for implementation notes, coding
21 1.1 christos conventions, et.al. */
22 1.1 christos
23 1.1 christos #include "defs.h"
24 1.1 christos #include "guile-internal.h"
25 1.1 christos
26 1.1 christos /* Define VARIABLES in the gdb module. */
27 1.1 christos
28 1.1 christos void
29 1.1.1.2 christos gdbscm_define_variables (const scheme_variable *variables, int is_public)
30 1.1 christos {
31 1.1 christos const scheme_variable *sv;
32 1.1 christos
33 1.1 christos for (sv = variables; sv->name != NULL; ++sv)
34 1.1 christos {
35 1.1 christos scm_c_define (sv->name, sv->value);
36 1.1.1.2 christos if (is_public)
37 1.1 christos scm_c_export (sv->name, NULL);
38 1.1 christos }
39 1.1 christos }
40 1.1 christos
41 1.1 christos /* Define FUNCTIONS in the gdb module. */
42 1.1 christos
43 1.1 christos void
44 1.1.1.2 christos gdbscm_define_functions (const scheme_function *functions, int is_public)
45 1.1 christos {
46 1.1 christos const scheme_function *sf;
47 1.1 christos
48 1.1 christos for (sf = functions; sf->name != NULL; ++sf)
49 1.1 christos {
50 1.1 christos SCM proc = scm_c_define_gsubr (sf->name, sf->required, sf->optional,
51 1.1 christos sf->rest, sf->func);
52 1.1 christos
53 1.1 christos scm_set_procedure_property_x (proc, gdbscm_documentation_symbol,
54 1.1 christos gdbscm_scm_from_c_string (sf->doc_string));
55 1.1.1.2 christos if (is_public)
56 1.1 christos scm_c_export (sf->name, NULL);
57 1.1 christos }
58 1.1 christos }
59 1.1 christos
60 1.1 christos /* Define CONSTANTS in the gdb module. */
61 1.1 christos
62 1.1 christos void
63 1.1 christos gdbscm_define_integer_constants (const scheme_integer_constant *constants,
64 1.1.1.2 christos int is_public)
65 1.1 christos {
66 1.1 christos const scheme_integer_constant *sc;
67 1.1 christos
68 1.1 christos for (sc = constants; sc->name != NULL; ++sc)
69 1.1 christos {
70 1.1 christos scm_c_define (sc->name, scm_from_int (sc->value));
71 1.1.1.2 christos if (is_public)
72 1.1 christos scm_c_export (sc->name, NULL);
73 1.1 christos }
74 1.1 christos }
75 1.1 christos
76 1.1 christos /* scm_printf, alas it doesn't exist. */
78 1.1 christos
79 1.1 christos void
80 1.1 christos gdbscm_printf (SCM port, const char *format, ...)
81 1.1 christos {
82 1.1 christos va_list args;
83 1.1 christos char *string;
84 1.1 christos
85 1.1 christos va_start (args, format);
86 1.1 christos string = xstrvprintf (format, args);
87 1.1 christos va_end (args);
88 1.1 christos scm_puts (string, port);
89 1.1 christos xfree (string);
90 1.1 christos }
91 1.1 christos
92 1.1 christos /* Utility for calling from gdb to "display" an SCM object. */
93 1.1 christos
94 1.1 christos void
95 1.1 christos gdbscm_debug_display (SCM obj)
96 1.1 christos {
97 1.1 christos SCM port = scm_current_output_port ();
98 1.1 christos
99 1.1 christos scm_display (obj, port);
100 1.1 christos scm_newline (port);
101 1.1 christos scm_force_output (port);
102 1.1 christos }
103 1.1 christos
104 1.1 christos /* Utility for calling from gdb to "write" an SCM object. */
105 1.1 christos
106 1.1 christos void
107 1.1 christos gdbscm_debug_write (SCM obj)
108 1.1 christos {
109 1.1 christos SCM port = scm_current_output_port ();
110 1.1 christos
111 1.1 christos scm_write (obj, port);
112 1.1 christos scm_newline (port);
113 1.1 christos scm_force_output (port);
114 1.1 christos }
115 1.1 christos
116 1.1 christos /* Subroutine of gdbscm_parse_function_args to simplify it.
118 1.1 christos Return the number of keyword arguments. */
119 1.1 christos
120 1.1 christos static int
121 1.1 christos count_keywords (const SCM *keywords)
122 1.1 christos {
123 1.1 christos int i;
124 1.1 christos
125 1.1 christos if (keywords == NULL)
126 1.1 christos return 0;
127 1.1 christos for (i = 0; keywords[i] != SCM_BOOL_F; ++i)
128 1.1 christos continue;
129 1.1 christos
130 1.1 christos return i;
131 1.1 christos }
132 1.1 christos
133 1.1 christos /* Subroutine of gdbscm_parse_function_args to simplify it.
134 1.1 christos Validate an argument format string.
135 1.1 christos The result is a boolean indicating if "." was seen. */
136 1.1 christos
137 1.1 christos static int
138 1.1 christos validate_arg_format (const char *format)
139 1.1 christos {
140 1.1 christos const char *p;
141 1.1 christos int length = strlen (format);
142 1.1 christos int optional_position = -1;
143 1.1 christos int keyword_position = -1;
144 1.1 christos int dot_seen = 0;
145 1.1 christos
146 1.1 christos gdb_assert (length > 0);
147 1.1 christos
148 1.1 christos for (p = format; *p != '\0'; ++p)
149 1.1 christos {
150 1.1 christos switch (*p)
151 1.1 christos {
152 1.1 christos case 's':
153 1.1 christos case 't':
154 1.1 christos case 'i':
155 1.1 christos case 'u':
156 1.1 christos case 'l':
157 1.1 christos case 'n':
158 1.1 christos case 'L':
159 1.1 christos case 'U':
160 1.1 christos case 'O':
161 1.1 christos break;
162 1.1 christos case '|':
163 1.1 christos gdb_assert (keyword_position < 0);
164 1.1 christos gdb_assert (optional_position < 0);
165 1.1 christos optional_position = p - format;
166 1.1 christos break;
167 1.1 christos case '#':
168 1.1 christos gdb_assert (keyword_position < 0);
169 1.1 christos keyword_position = p - format;
170 1.1 christos break;
171 1.1 christos case '.':
172 1.1 christos gdb_assert (p[1] == '\0');
173 1.1 christos dot_seen = 1;
174 1.1 christos break;
175 1.1 christos default:
176 1.1 christos gdb_assert_not_reached ("invalid argument format character");
177 1.1 christos }
178 1.1 christos }
179 1.1 christos
180 1.1 christos return dot_seen;
181 1.1 christos }
182 1.1 christos
183 1.1 christos /* Our version of SCM_ASSERT_TYPE that calls gdbscm_make_type_error. */
184 1.1 christos #define CHECK_TYPE(ok, arg, position, func_name, expected_type) \
185 1.1 christos do { \
186 1.1 christos if (!(ok)) \
187 1.1 christos { \
188 1.1 christos return gdbscm_make_type_error ((func_name), (position), (arg), \
189 1.1 christos (expected_type)); \
190 1.1 christos } \
191 1.1 christos } while (0)
192 1.1 christos
193 1.1 christos /* Subroutine of gdbscm_parse_function_args to simplify it.
194 1.1 christos Check the type of ARG against FORMAT_CHAR and extract the value.
195 1.1 christos POSITION is the position of ARG in the argument list.
196 1.1 christos The result is #f upon success or a <gdb:exception> object. */
197 1.1 christos
198 1.1 christos static SCM
199 1.1 christos extract_arg (char format_char, SCM arg, void *argp,
200 1.1 christos const char *func_name, int position)
201 1.1 christos {
202 1.1 christos switch (format_char)
203 1.1 christos {
204 1.1 christos case 's':
205 1.1 christos {
206 1.1 christos char **arg_ptr = argp;
207 1.1 christos
208 1.1 christos CHECK_TYPE (gdbscm_is_true (scm_string_p (arg)), arg, position,
209 1.1 christos func_name, _("string"));
210 1.1 christos *arg_ptr = gdbscm_scm_to_c_string (arg);
211 1.1 christos break;
212 1.1 christos }
213 1.1 christos case 't':
214 1.1 christos {
215 1.1 christos int *arg_ptr = argp;
216 1.1 christos
217 1.1 christos /* While in Scheme, anything non-#f is "true", we're strict. */
218 1.1 christos CHECK_TYPE (gdbscm_is_bool (arg), arg, position, func_name,
219 1.1 christos _("boolean"));
220 1.1 christos *arg_ptr = gdbscm_is_true (arg);
221 1.1 christos break;
222 1.1 christos }
223 1.1 christos case 'i':
224 1.1 christos {
225 1.1 christos int *arg_ptr = argp;
226 1.1 christos
227 1.1 christos CHECK_TYPE (scm_is_signed_integer (arg, INT_MIN, INT_MAX),
228 1.1 christos arg, position, func_name, _("int"));
229 1.1 christos *arg_ptr = scm_to_int (arg);
230 1.1 christos break;
231 1.1 christos }
232 1.1 christos case 'u':
233 1.1 christos {
234 1.1 christos int *arg_ptr = argp;
235 1.1 christos
236 1.1 christos CHECK_TYPE (scm_is_unsigned_integer (arg, 0, UINT_MAX),
237 1.1 christos arg, position, func_name, _("unsigned int"));
238 1.1 christos *arg_ptr = scm_to_uint (arg);
239 1.1 christos break;
240 1.1 christos }
241 1.1 christos case 'l':
242 1.1 christos {
243 1.1 christos long *arg_ptr = argp;
244 1.1 christos
245 1.1 christos CHECK_TYPE (scm_is_signed_integer (arg, LONG_MIN, LONG_MAX),
246 1.1 christos arg, position, func_name, _("long"));
247 1.1 christos *arg_ptr = scm_to_long (arg);
248 1.1 christos break;
249 1.1 christos }
250 1.1 christos case 'n':
251 1.1 christos {
252 1.1 christos unsigned long *arg_ptr = argp;
253 1.1 christos
254 1.1 christos CHECK_TYPE (scm_is_unsigned_integer (arg, 0, ULONG_MAX),
255 1.1 christos arg, position, func_name, _("unsigned long"));
256 1.1 christos *arg_ptr = scm_to_ulong (arg);
257 1.1 christos break;
258 1.1 christos }
259 1.1 christos case 'L':
260 1.1 christos {
261 1.1 christos LONGEST *arg_ptr = argp;
262 1.1 christos
263 1.1 christos CHECK_TYPE (scm_is_signed_integer (arg, INT64_MIN, INT64_MAX),
264 1.1 christos arg, position, func_name, _("LONGEST"));
265 1.1 christos *arg_ptr = gdbscm_scm_to_longest (arg);
266 1.1 christos break;
267 1.1 christos }
268 1.1 christos case 'U':
269 1.1 christos {
270 1.1 christos ULONGEST *arg_ptr = argp;
271 1.1 christos
272 1.1 christos CHECK_TYPE (scm_is_unsigned_integer (arg, 0, UINT64_MAX),
273 1.1 christos arg, position, func_name, _("ULONGEST"));
274 1.1 christos *arg_ptr = gdbscm_scm_to_ulongest (arg);
275 1.1 christos break;
276 1.1 christos }
277 1.1 christos case 'O':
278 1.1 christos {
279 1.1 christos SCM *arg_ptr = argp;
280 1.1 christos
281 1.1 christos *arg_ptr = arg;
282 1.1 christos break;
283 1.1 christos }
284 1.1 christos default:
285 1.1 christos gdb_assert_not_reached ("invalid argument format character");
286 1.1 christos }
287 1.1 christos
288 1.1 christos return SCM_BOOL_F;
289 1.1 christos }
290 1.1 christos
291 1.1 christos #undef CHECK_TYPE
292 1.1 christos
293 1.1 christos /* Look up KEYWORD in KEYWORD_LIST.
294 1.1 christos The result is the index of the keyword in the list or -1 if not found. */
295 1.1 christos
296 1.1 christos static int
297 1.1 christos lookup_keyword (const SCM *keyword_list, SCM keyword)
298 1.1 christos {
299 1.1 christos int i = 0;
300 1.1 christos
301 1.1 christos while (keyword_list[i] != SCM_BOOL_F)
302 1.1 christos {
303 1.1 christos if (scm_is_eq (keyword_list[i], keyword))
304 1.1 christos return i;
305 1.1 christos ++i;
306 1.1 christos }
307 1.1 christos
308 1.1 christos return -1;
309 1.1 christos }
310 1.1 christos
311 1.1 christos /* Utility to parse required, optional, and keyword arguments to Scheme
312 1.1 christos functions. Modelled on PyArg_ParseTupleAndKeywords, but no attempt is made
313 1.1 christos at similarity or functionality.
314 1.1 christos There is no result, if there's an error a Scheme exception is thrown.
315 1.1 christos
316 1.1 christos Guile provides scm_c_bind_keyword_arguments, and feel free to use it.
317 1.1 christos This is for times when we want a bit more parsing.
318 1.1 christos
319 1.1 christos BEGINNING_ARG_POS is the position of the first argument passed to this
320 1.1 christos routine. It should be one of the SCM_ARGn values. It could be > SCM_ARG1
321 1.1 christos if the caller chooses not to parse one or more required arguments.
322 1.1 christos
323 1.1 christos KEYWORDS may be NULL if there are no keywords.
324 1.1 christos
325 1.1 christos FORMAT:
326 1.1 christos s - string -> char *, malloc'd
327 1.1 christos t - boolean (gdb uses "t", for biT?) -> int
328 1.1 christos i - int
329 1.1 christos u - unsigned int
330 1.1 christos l - long
331 1.1 christos n - unsigned long
332 1.1 christos L - longest
333 1.1 christos U - unsigned longest
334 1.1 christos O - random scheme object
335 1.1 christos | - indicates the next set is for optional arguments
336 1.1 christos # - indicates the next set is for keyword arguments (must follow |)
337 1.1 christos . - indicates "rest" arguments are present, this character must appear last
338 1.1 christos
339 1.1 christos FORMAT must match the definition from scm_c_{make,define}_gsubr.
340 1.1 christos Required and optional arguments appear in order in the format string.
341 1.1 christos Afterwards, keyword-based arguments are processed. There must be as many
342 1.1 christos remaining characters in the format string as their are keywords.
343 1.1 christos Except for "|#.", the number of characters in the format string must match
344 1.1 christos #required + #optional + #keywords.
345 1.1 christos
346 1.1 christos The function is required to be defined in a compatible manner:
347 1.1 christos #required-args and #optional-arguments must match, and rest-arguments
348 1.1 christos must be specified if keyword args are desired, and/or regular "rest" args.
349 1.1 christos
350 1.1 christos Example: For this function,
351 1.1 christos scm_c_define_gsubr ("execute", 2, 3, 1, foo);
352 1.1 christos the format string + keyword list could be any of:
353 1.1 christos 1) "ss|ttt#tt", { "key1", "key2", NULL }
354 1.1 christos 2) "ss|ttt.", { NULL }
355 1.1 christos 3) "ss|ttt#t.", { "key1", NULL }
356 1.1 christos
357 1.1 christos For required and optional args pass the SCM of the argument, and a
358 1.1 christos pointer to the value to hold the parsed result (type depends on format
359 1.1 christos char). After that pass the SCM containing the "rest" arguments followed
360 1.1 christos by pointers to values to hold parsed keyword arguments, and if specified
361 1.1 christos a pointer to hold the remaining contents of "rest".
362 1.1 christos
363 1.1 christos For keyword arguments pass two pointers: the first is a pointer to an int
364 1.1 christos that will contain the position of the argument in the arg list, and the
365 1.1 christos second will contain result of processing the argument. The int pointed
366 1.1 christos to by the first value should be initialized to -1. It can then be used
367 1.1 christos to tell whether the keyword was present.
368 1.1 christos
369 1.1 christos If both keyword and rest arguments are present, the caller must pass a
370 1.1 christos pointer to contain the new value of rest (after keyword args have been
371 1.1 christos removed).
372 1.1 christos
373 1.1 christos There's currently no way, that I know of, to specify default values for
374 1.1 christos optional arguments in C-provided functions. At the moment they're a
375 1.1 christos work-in-progress. The caller should test SCM_UNBNDP for each optional
376 1.1 christos argument. Unbound optional arguments are ignored. */
377 1.1 christos
378 1.1 christos void
379 1.1 christos gdbscm_parse_function_args (const char *func_name,
380 1.1 christos int beginning_arg_pos,
381 1.1 christos const SCM *keywords,
382 1.1 christos const char *format, ...)
383 1.1 christos {
384 1.1 christos va_list args;
385 1.1 christos const char *p;
386 1.1 christos int i, have_rest, num_keywords, length, position;
387 1.1 christos int have_optional = 0;
388 1.1 christos SCM status;
389 1.1 christos SCM rest = SCM_EOL;
390 1.1 christos /* Keep track of malloc'd strings. We need to free them upon error. */
391 1.1 christos VEC (char_ptr) *allocated_strings = NULL;
392 1.1 christos char *ptr;
393 1.1 christos
394 1.1 christos have_rest = validate_arg_format (format);
395 1.1 christos num_keywords = count_keywords (keywords);
396 1.1 christos
397 1.1 christos va_start (args, format);
398 1.1 christos
399 1.1 christos p = format;
400 1.1 christos position = beginning_arg_pos;
401 1.1 christos
402 1.1 christos /* Process required, optional arguments. */
403 1.1 christos
404 1.1 christos while (*p && *p != '#' && *p != '.')
405 1.1 christos {
406 1.1 christos SCM arg;
407 1.1 christos void *arg_ptr;
408 1.1 christos
409 1.1 christos if (*p == '|')
410 1.1 christos {
411 1.1 christos have_optional = 1;
412 1.1 christos ++p;
413 1.1 christos continue;
414 1.1 christos }
415 1.1 christos
416 1.1 christos arg = va_arg (args, SCM);
417 1.1 christos if (!have_optional || !SCM_UNBNDP (arg))
418 1.1 christos {
419 1.1 christos arg_ptr = va_arg (args, void *);
420 1.1 christos status = extract_arg (*p, arg, arg_ptr, func_name, position);
421 1.1 christos if (!gdbscm_is_false (status))
422 1.1 christos goto fail;
423 1.1 christos if (*p == 's')
424 1.1 christos VEC_safe_push (char_ptr, allocated_strings, *(char **) arg_ptr);
425 1.1 christos }
426 1.1 christos ++p;
427 1.1 christos ++position;
428 1.1 christos }
429 1.1 christos
430 1.1 christos /* Process keyword arguments. */
431 1.1 christos
432 1.1 christos if (have_rest || num_keywords > 0)
433 1.1 christos rest = va_arg (args, SCM);
434 1.1 christos
435 1.1 christos if (num_keywords > 0)
436 1.1 christos {
437 1.1 christos SCM *keyword_args = (SCM *) alloca (num_keywords * sizeof (SCM));
438 1.1 christos int *keyword_positions = (int *) alloca (num_keywords * sizeof (int));
439 1.1 christos
440 1.1 christos gdb_assert (*p == '#');
441 1.1 christos ++p;
442 1.1 christos
443 1.1 christos for (i = 0; i < num_keywords; ++i)
444 1.1 christos {
445 1.1 christos keyword_args[i] = SCM_UNSPECIFIED;
446 1.1 christos keyword_positions[i] = -1;
447 1.1 christos }
448 1.1 christos
449 1.1 christos while (scm_is_pair (rest)
450 1.1 christos && scm_is_keyword (scm_car (rest)))
451 1.1 christos {
452 1.1 christos SCM keyword = scm_car (rest);
453 1.1 christos
454 1.1 christos i = lookup_keyword (keywords, keyword);
455 1.1 christos if (i < 0)
456 1.1 christos {
457 1.1 christos status = gdbscm_make_error (scm_arg_type_key, func_name,
458 1.1 christos _("Unrecognized keyword: ~a"),
459 1.1 christos scm_list_1 (keyword), keyword);
460 1.1 christos goto fail;
461 1.1 christos }
462 1.1 christos if (!scm_is_pair (scm_cdr (rest)))
463 1.1 christos {
464 1.1 christos status = gdbscm_make_error
465 1.1 christos (scm_arg_type_key, func_name,
466 1.1 christos _("Missing value for keyword argument"),
467 1.1 christos scm_list_1 (keyword), keyword);
468 1.1 christos goto fail;
469 1.1 christos }
470 1.1 christos keyword_args[i] = scm_cadr (rest);
471 1.1 christos keyword_positions[i] = position + 1;
472 1.1 christos rest = scm_cddr (rest);
473 1.1 christos position += 2;
474 1.1 christos }
475 1.1 christos
476 1.1 christos for (i = 0; i < num_keywords; ++i)
477 1.1 christos {
478 1.1 christos int *arg_pos_ptr = va_arg (args, int *);
479 1.1 christos void *arg_ptr = va_arg (args, void *);
480 1.1 christos SCM arg = keyword_args[i];
481 1.1 christos
482 1.1 christos if (! scm_is_eq (arg, SCM_UNSPECIFIED))
483 1.1 christos {
484 1.1 christos *arg_pos_ptr = keyword_positions[i];
485 1.1 christos status = extract_arg (p[i], arg, arg_ptr, func_name,
486 1.1 christos keyword_positions[i]);
487 1.1 christos if (!gdbscm_is_false (status))
488 1.1 christos goto fail;
489 1.1 christos if (p[i] == 's')
490 1.1 christos {
491 1.1 christos VEC_safe_push (char_ptr, allocated_strings,
492 1.1 christos *(char **) arg_ptr);
493 1.1 christos }
494 1.1 christos }
495 1.1 christos }
496 1.1 christos }
497 1.1 christos
498 1.1 christos /* Process "rest" arguments. */
499 1.1 christos
500 1.1 christos if (have_rest)
501 1.1 christos {
502 1.1 christos if (num_keywords > 0)
503 1.1 christos {
504 1.1 christos SCM *rest_ptr = va_arg (args, SCM *);
505 1.1 christos
506 1.1 christos *rest_ptr = rest;
507 1.1 christos }
508 1.1 christos }
509 1.1 christos else
510 1.1 christos {
511 1.1 christos if (! scm_is_null (rest))
512 1.1 christos {
513 1.1 christos status = gdbscm_make_error (scm_args_number_key, func_name,
514 1.1 christos _("Too many arguments"),
515 1.1 christos SCM_EOL, SCM_BOOL_F);
516 1.1 christos goto fail;
517 1.1 christos }
518 1.1 christos }
519 1.1 christos
520 1.1 christos va_end (args);
521 1.1 christos VEC_free (char_ptr, allocated_strings);
522 1.1 christos return;
523 1.1 christos
524 1.1 christos fail:
525 1.1 christos va_end (args);
526 1.1 christos for (i = 0; VEC_iterate (char_ptr, allocated_strings, i, ptr); ++i)
527 1.1 christos xfree (ptr);
528 1.1 christos VEC_free (char_ptr, allocated_strings);
529 1.1 christos gdbscm_throw (status);
530 1.1 christos }
531 1.1 christos
532 1.1 christos /* Return longest L as a scheme object. */
534 1.1 christos
535 1.1 christos SCM
536 1.1 christos gdbscm_scm_from_longest (LONGEST l)
537 1.1 christos {
538 1.1 christos return scm_from_int64 (l);
539 1.1 christos }
540 1.1 christos
541 1.1 christos /* Convert scheme object L to LONGEST.
542 1.1 christos It is an error to call this if L is not an integer in range of LONGEST.
543 1.1 christos (because the underlying Scheme function will thrown an exception,
544 1.1 christos which is not part of our contract with the caller). */
545 1.1 christos
546 1.1 christos LONGEST
547 1.1 christos gdbscm_scm_to_longest (SCM l)
548 1.1 christos {
549 1.1 christos return scm_to_int64 (l);
550 1.1 christos }
551 1.1 christos
552 1.1 christos /* Return unsigned longest L as a scheme object. */
553 1.1 christos
554 1.1 christos SCM
555 1.1 christos gdbscm_scm_from_ulongest (ULONGEST l)
556 1.1 christos {
557 1.1 christos return scm_from_uint64 (l);
558 1.1 christos }
559 1.1 christos
560 1.1 christos /* Convert scheme object U to ULONGEST.
561 1.1 christos It is an error to call this if U is not an integer in range of ULONGEST
562 1.1 christos (because the underlying Scheme function will thrown an exception,
563 1.1 christos which is not part of our contract with the caller). */
564 1.1 christos
565 1.1 christos ULONGEST
566 1.1 christos gdbscm_scm_to_ulongest (SCM u)
567 1.1 christos {
568 1.1 christos return scm_to_uint64 (u);
569 1.1 christos }
570 1.1 christos
571 1.1 christos /* Same as scm_dynwind_free, but uses xfree. */
572 1.1 christos
573 1.1 christos void
574 1.1 christos gdbscm_dynwind_xfree (void *ptr)
575 1.1 christos {
576 1.1 christos scm_dynwind_unwind_handler (xfree, ptr, SCM_F_WIND_EXPLICITLY);
577 1.1 christos }
578 1.1 christos
579 1.1 christos /* Return non-zero if PROC is a procedure. */
580 1.1 christos
581 1.1 christos int
582 1.1 christos gdbscm_is_procedure (SCM proc)
583 1.1 christos {
584 1.1 christos return gdbscm_is_true (scm_procedure_p (proc));
585 1.1 christos }
586 1.1 christos
587 1.1 christos /* Same as xstrdup, but the string is allocated on the GC heap. */
588 1.1 christos
589 1.1 christos char *
590 1.1 christos gdbscm_gc_xstrdup (const char *str)
591 1.1 christos {
592 1.1 christos size_t len = strlen (str);
593 1.1 christos char *result = scm_gc_malloc_pointerless (len + 1, "gdbscm_gc_xstrdup");
594 1.1 christos
595 1.1 christos strcpy (result, str);
596 1.1 christos return result;
597 1.1 christos }
598 1.1 christos
599 1.1 christos /* Return a duplicate of ARGV living on the GC heap. */
600 1.1 christos
601 1.1 christos const char * const *
602 1.1 christos gdbscm_gc_dup_argv (char **argv)
603 1.1 christos {
604 1.1 christos int i, len;
605 1.1 christos size_t string_space;
606 1.1 christos char *p, **result;
607 1.1 christos
608 1.1 christos for (len = 0, string_space = 0; argv[len] != NULL; ++len)
609 1.1 christos string_space += strlen (argv[len]) + 1;
610 1.1 christos
611 1.1 christos /* Allocating "pointerless" works because the pointers are all
612 1.1 christos self-contained within the object. */
613 1.1 christos result = scm_gc_malloc_pointerless (((len + 1) * sizeof (char *))
614 1.1 christos + string_space, "parameter enum list");
615 1.1 christos p = (char *) &result[len + 1];
616 1.1 christos
617 1.1 christos for (i = 0; i < len; ++i)
618 1.1 christos {
619 1.1 christos result[i] = p;
620 1.1 christos strcpy (p, argv[i]);
621 1.1 christos p += strlen (p) + 1;
622 1.1 christos }
623 1.1 christos result[i] = NULL;
624 1.1 christos
625 1.1 christos return (const char * const *) result;
626 1.1 christos }
627 1.1 christos
628 1.1 christos /* Return non-zero if the version of Guile being used it at least
629 1.1 christos MAJOR.MINOR.MICRO. */
630 1.1 christos
631 1.1 christos int
632 1.1 christos gdbscm_guile_version_is_at_least (int major, int minor, int micro)
633 1.1 christos {
634 1.1 christos if (major > gdbscm_guile_major_version)
635 1.1 christos return 0;
636 1.1 christos if (major < gdbscm_guile_major_version)
637 1.1 christos return 1;
638 1.1 christos if (minor > gdbscm_guile_minor_version)
639 1.1 christos return 0;
640 1.1 christos if (minor < gdbscm_guile_minor_version)
641 1.1 christos return 1;
642 1.1 christos if (micro > gdbscm_guile_micro_version)
643 return 0;
644 return 1;
645 }
646