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