Home | History | Annotate | Line # | Download | only in guile
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