/* General utility routines for GDB/Scheme code.
- Copyright (C) 2014 Free Software Foundation, Inc.
+ Copyright (C) 2014-2019 Free Software Foundation, Inc.
This file is part of GDB.
conventions, et.al. */
#include "defs.h"
-#include <stdint.h>
-#include "gdb_assert.h"
#include "guile-internal.h"
/* Define VARIABLES in the gdb module. */
void
-gdbscm_define_variables (const scheme_variable *variables, int public)
+gdbscm_define_variables (const scheme_variable *variables, int is_public)
{
const scheme_variable *sv;
for (sv = variables; sv->name != NULL; ++sv)
{
scm_c_define (sv->name, sv->value);
- if (public)
+ if (is_public)
scm_c_export (sv->name, NULL);
}
}
/* Define FUNCTIONS in the gdb module. */
void
-gdbscm_define_functions (const scheme_function *functions, int public)
+gdbscm_define_functions (const scheme_function *functions, int is_public)
{
const scheme_function *sf;
scm_set_procedure_property_x (proc, gdbscm_documentation_symbol,
gdbscm_scm_from_c_string (sf->doc_string));
- if (public)
+ if (is_public)
scm_c_export (sf->name, NULL);
}
}
void
gdbscm_define_integer_constants (const scheme_integer_constant *constants,
- int public)
+ int is_public)
{
const scheme_integer_constant *sc;
for (sc = constants; sc->name != NULL; ++sc)
{
scm_c_define (sc->name, scm_from_int (sc->value));
- if (public)
+ if (is_public)
scm_c_export (sc->name, NULL);
}
}
gdbscm_printf (SCM port, const char *format, ...)
{
va_list args;
- char *string;
va_start (args, format);
- string = xstrvprintf (format, args);
+ std::string string = string_vprintf (format, args);
va_end (args);
- scm_puts (string, port);
- xfree (string);
+ scm_puts (string.c_str (), port);
}
/* Utility for calling from gdb to "display" an SCM object. */
{
case 's':
{
- char **arg_ptr = argp;
+ char **arg_ptr = (char **) argp;
CHECK_TYPE (gdbscm_is_true (scm_string_p (arg)), arg, position,
func_name, _("string"));
- *arg_ptr = gdbscm_scm_to_c_string (arg);
+ *arg_ptr = gdbscm_scm_to_c_string (arg).release ();
break;
}
case 't':
{
- int *arg_ptr = argp;
+ int *arg_ptr = (int *) argp;
/* While in Scheme, anything non-#f is "true", we're strict. */
CHECK_TYPE (gdbscm_is_bool (arg), arg, position, func_name,
}
case 'i':
{
- int *arg_ptr = argp;
+ int *arg_ptr = (int *) argp;
CHECK_TYPE (scm_is_signed_integer (arg, INT_MIN, INT_MAX),
arg, position, func_name, _("int"));
}
case 'u':
{
- int *arg_ptr = argp;
+ int *arg_ptr = (int *) argp;
CHECK_TYPE (scm_is_unsigned_integer (arg, 0, UINT_MAX),
arg, position, func_name, _("unsigned int"));
}
case 'l':
{
- long *arg_ptr = argp;
+ long *arg_ptr = (long *) argp;
CHECK_TYPE (scm_is_signed_integer (arg, LONG_MIN, LONG_MAX),
arg, position, func_name, _("long"));
}
case 'n':
{
- unsigned long *arg_ptr = argp;
+ unsigned long *arg_ptr = (unsigned long *) argp;
CHECK_TYPE (scm_is_unsigned_integer (arg, 0, ULONG_MAX),
arg, position, func_name, _("unsigned long"));
}
case 'L':
{
- LONGEST *arg_ptr = argp;
+ LONGEST *arg_ptr = (LONGEST *) argp;
CHECK_TYPE (scm_is_signed_integer (arg, INT64_MIN, INT64_MAX),
arg, position, func_name, _("LONGEST"));
}
case 'U':
{
- ULONGEST *arg_ptr = argp;
+ ULONGEST *arg_ptr = (ULONGEST *) argp;
CHECK_TYPE (scm_is_unsigned_integer (arg, 0, UINT64_MAX),
arg, position, func_name, _("ULONGEST"));
}
case 'O':
{
- SCM *arg_ptr = argp;
+ SCM *arg_ptr = (SCM *) argp;
*arg_ptr = arg;
break;
return -1;
}
-/* Utility to parse required, optional, and keyword arguments to Scheme
- functions. Modelled on PyArg_ParseTupleAndKeywords, but no attempt is made
- at similarity or functionality.
- There is no result, if there's an error a Scheme exception is thrown.
-
- Guile provides scm_c_bind_keyword_arguments, and feel free to use it.
- This is for times when we want a bit more parsing.
-
- BEGINNING_ARG_POS is the position of the first argument passed to this
- routine. It should be one of the SCM_ARGn values. It could be > SCM_ARG1
- if the caller chooses not to parse one or more required arguments.
-
- KEYWORDS may be NULL if there are no keywords.
-
- FORMAT:
- s - string -> char *, malloc'd
- t - boolean (gdb uses "t", for biT?) -> int
- i - int
- u - unsigned int
- l - long
- n - unsigned long
- L - longest
- U - unsigned longest
- O - random scheme object
- | - indicates the next set is for optional arguments
- # - indicates the next set is for keyword arguments (must follow |)
- . - indicates "rest" arguments are present, this character must appear last
-
- FORMAT must match the definition from scm_c_{make,define}_gsubr.
- Required and optional arguments appear in order in the format string.
- Afterwards, keyword-based arguments are processed. There must be as many
- remaining characters in the format string as their are keywords.
- Except for "|#.", the number of characters in the format string must match
- #required + #optional + #keywords.
-
- The function is required to be defined in a compatible manner:
- #required-args and #optional-arguments must match, and rest-arguments
- must be specified if keyword args are desired, and/or regular "rest" args.
-
- Example: For this function,
- scm_c_define_gsubr ("execute", 2, 3, 1, foo);
- the format string + keyword list could be any of:
- 1) "ss|ttt#tt", { "key1", "key2", NULL }
- 2) "ss|ttt.", { NULL }
- 3) "ss|ttt#t.", { "key1", NULL }
-
- For required and optional args pass the SCM of the argument, and a
- pointer to the value to hold the parsed result (type depends on format
- char). After that pass the SCM containing the "rest" arguments followed
- by pointers to values to hold parsed keyword arguments, and if specified
- a pointer to hold the remaining contents of "rest".
-
- For keyword arguments pass two pointers: the first is a pointer to an int
- that will contain the position of the argument in the arg list, and the
- second will contain result of processing the argument. The int pointed
- to by the first value should be initialized to -1. It can then be used
- to tell whether the keyword was present.
-
- If both keyword and rest arguments are present, the caller must pass a
- pointer to contain the new value of rest (after keyword args have been
- removed).
- There's currently no way, that I know of, to specify default values for
- optional arguments in C-provided functions. At the moment they're a
- work-in-progress. The caller should test SCM_UNBNDP for each optional
- argument. Unbound optional arguments are ignored. */
+/* Helper for gdbscm_parse_function_args that does most of the work,
+ in a separate function wrapped with gdbscm_wrap so that we can use
+ non-trivial-dtor objects here. The result is #f upon success or a
+ <gdb:exception> object otherwise. */
-void
-gdbscm_parse_function_args (const char *func_name,
- int beginning_arg_pos,
- const SCM *keywords,
- const char *format, ...)
+static SCM
+gdbscm_parse_function_args_1 (const char *func_name,
+ int beginning_arg_pos,
+ const SCM *keywords,
+ const char *format, va_list args)
{
- va_list args;
const char *p;
- int i, have_rest, num_keywords, length, position;
+ int i, have_rest, num_keywords, position;
int have_optional = 0;
SCM status;
SCM rest = SCM_EOL;
/* Keep track of malloc'd strings. We need to free them upon error. */
- VEC (char_ptr) *allocated_strings = NULL;
- char *ptr;
+ std::vector<char *> allocated_strings;
have_rest = validate_arg_format (format);
num_keywords = count_keywords (keywords);
- va_start (args, format);
-
p = format;
position = beginning_arg_pos;
if (!gdbscm_is_false (status))
goto fail;
if (*p == 's')
- VEC_safe_push (char_ptr, allocated_strings, *(char **) arg_ptr);
+ allocated_strings.push_back (*(char **) arg_ptr);
}
++p;
++position;
if (num_keywords > 0)
{
- SCM *keyword_args = (SCM *) alloca (num_keywords * sizeof (SCM));
- int *keyword_positions = (int *) alloca (num_keywords * sizeof (int));
+ SCM *keyword_args = XALLOCAVEC (SCM, num_keywords);
+ int *keyword_positions = XALLOCAVEC (int, num_keywords);
gdb_assert (*p == '#');
++p;
if (!gdbscm_is_false (status))
goto fail;
if (p[i] == 's')
- {
- VEC_safe_push (char_ptr, allocated_strings,
- *(char **) arg_ptr);
- }
+ allocated_strings.push_back (*(char **) arg_ptr);
}
}
}
}
}
- va_end (args);
- VEC_free (char_ptr, allocated_strings);
- return;
+ /* Return anything not-an-exception. */
+ return SCM_BOOL_F;
fail:
- va_end (args);
- for (i = 0; VEC_iterate (char_ptr, allocated_strings, i, ptr); ++i)
+ for (char *ptr : allocated_strings)
xfree (ptr);
- VEC_free (char_ptr, allocated_strings);
- gdbscm_throw (status);
+
+ /* Return the exception, which gdbscm_wrap takes care of
+ throwing. */
+ return status;
}
+
+/* Utility to parse required, optional, and keyword arguments to Scheme
+ functions. Modelled on PyArg_ParseTupleAndKeywords, but no attempt is made
+ at similarity or functionality.
+ There is no result, if there's an error a Scheme exception is thrown.
+
+ Guile provides scm_c_bind_keyword_arguments, and feel free to use it.
+ This is for times when we want a bit more parsing.
+
+ BEGINNING_ARG_POS is the position of the first argument passed to this
+ routine. It should be one of the SCM_ARGn values. It could be > SCM_ARG1
+ if the caller chooses not to parse one or more required arguments.
+
+ KEYWORDS may be NULL if there are no keywords.
+
+ FORMAT:
+ s - string -> char *, malloc'd
+ t - boolean (gdb uses "t", for biT?) -> int
+ i - int
+ u - unsigned int
+ l - long
+ n - unsigned long
+ L - longest
+ U - unsigned longest
+ O - random scheme object
+ | - indicates the next set is for optional arguments
+ # - indicates the next set is for keyword arguments (must follow |)
+ . - indicates "rest" arguments are present, this character must appear last
+
+ FORMAT must match the definition from scm_c_{make,define}_gsubr.
+ Required and optional arguments appear in order in the format string.
+ Afterwards, keyword-based arguments are processed. There must be as many
+ remaining characters in the format string as their are keywords.
+ Except for "|#.", the number of characters in the format string must match
+ #required + #optional + #keywords.
+
+ The function is required to be defined in a compatible manner:
+ #required-args and #optional-arguments must match, and rest-arguments
+ must be specified if keyword args are desired, and/or regular "rest" args.
+
+ Example: For this function,
+ scm_c_define_gsubr ("execute", 2, 3, 1, foo);
+ the format string + keyword list could be any of:
+ 1) "ss|ttt#tt", { "key1", "key2", NULL }
+ 2) "ss|ttt.", { NULL }
+ 3) "ss|ttt#t.", { "key1", NULL }
+
+ For required and optional args pass the SCM of the argument, and a
+ pointer to the value to hold the parsed result (type depends on format
+ char). After that pass the SCM containing the "rest" arguments followed
+ by pointers to values to hold parsed keyword arguments, and if specified
+ a pointer to hold the remaining contents of "rest".
+
+ For keyword arguments pass two pointers: the first is a pointer to an int
+ that will contain the position of the argument in the arg list, and the
+ second will contain result of processing the argument. The int pointed
+ to by the first value should be initialized to -1. It can then be used
+ to tell whether the keyword was present.
+
+ If both keyword and rest arguments are present, the caller must pass a
+ pointer to contain the new value of rest (after keyword args have been
+ removed).
+
+ There's currently no way, that I know of, to specify default values for
+ optional arguments in C-provided functions. At the moment they're a
+ work-in-progress. The caller should test SCM_UNBNDP for each optional
+ argument. Unbound optional arguments are ignored. */
+
+void
+gdbscm_parse_function_args (const char *func_name,
+ int beginning_arg_pos,
+ const SCM *keywords,
+ const char *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+
+ gdbscm_wrap (gdbscm_parse_function_args_1, func_name,
+ beginning_arg_pos, keywords, format, args);
+
+ va_end (args);
+}
+
\f
/* Return longest L as a scheme object. */
gdbscm_gc_xstrdup (const char *str)
{
size_t len = strlen (str);
- char *result = scm_gc_malloc_pointerless (len + 1, "gdbscm_gc_xstrdup");
+ char *result
+ = (char *) scm_gc_malloc_pointerless (len + 1, "gdbscm_gc_xstrdup");
strcpy (result, str);
return result;
/* Allocating "pointerless" works because the pointers are all
self-contained within the object. */
- result = scm_gc_malloc_pointerless (((len + 1) * sizeof (char *))
- + string_space, "parameter enum list");
+ result = (char **) scm_gc_malloc_pointerless (((len + 1) * sizeof (char *))
+ + string_space,
+ "parameter enum list");
p = (char *) &result[len + 1];
for (i = 0; i < len; ++i)