X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fguile%2Fscm-utils.c;h=2710b110c08662132759445ea05b2bbfc1fa2441;hb=7d10623d3b153d6c15406b203fb1cf111c53f1dd;hp=023097f2ae071c267c3ec8b6c756141203891cbe;hpb=32d0add0a654c1204ab71dc8a55d9374538c4b33;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/guile/scm-utils.c b/gdb/guile/scm-utils.c index 023097f2ae..2710b110c0 100644 --- a/gdb/guile/scm-utils.c +++ b/gdb/guile/scm-utils.c @@ -1,6 +1,6 @@ /* General utility routines for GDB/Scheme code. - Copyright (C) 2014-2015 Free Software Foundation, Inc. + Copyright (C) 2014-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -21,20 +21,19 @@ conventions, et.al. */ #include "defs.h" -#include #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); } } @@ -42,7 +41,7 @@ gdbscm_define_variables (const scheme_variable *variables, int public) /* 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; @@ -53,7 +52,7 @@ gdbscm_define_functions (const scheme_function *functions, int public) 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); } } @@ -62,14 +61,14 @@ gdbscm_define_functions (const scheme_function *functions, int public) 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); } } @@ -80,13 +79,11 @@ void 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. */ @@ -202,16 +199,16 @@ extract_arg (char format_char, SCM arg, void *argp, { 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, @@ -221,7 +218,7 @@ extract_arg (char format_char, SCM arg, void *argp, } 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")); @@ -230,7 +227,7 @@ extract_arg (char format_char, SCM arg, void *argp, } 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")); @@ -239,7 +236,7 @@ extract_arg (char format_char, SCM arg, void *argp, } 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")); @@ -248,7 +245,7 @@ extract_arg (char format_char, SCM arg, void *argp, } 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")); @@ -257,7 +254,7 @@ extract_arg (char format_char, SCM arg, void *argp, } 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")); @@ -266,7 +263,7 @@ extract_arg (char format_char, SCM arg, void *argp, } 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")); @@ -275,7 +272,7 @@ extract_arg (char format_char, SCM arg, void *argp, } case 'O': { - SCM *arg_ptr = argp; + SCM *arg_ptr = (SCM *) argp; *arg_ptr = arg; break; @@ -307,94 +304,29 @@ lookup_keyword (const SCM *keyword_list, SCM keyword) 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 + 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 allocated_strings; have_rest = validate_arg_format (format); num_keywords = count_keywords (keywords); - va_start (args, format); - p = format; position = beginning_arg_pos; @@ -420,7 +352,7 @@ gdbscm_parse_function_args (const char *func_name, 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; @@ -433,8 +365,8 @@ gdbscm_parse_function_args (const char *func_name, 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; @@ -486,10 +418,7 @@ gdbscm_parse_function_args (const char *func_name, 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); } } } @@ -516,17 +445,100 @@ gdbscm_parse_function_args (const char *func_name, } } - 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); +} + /* Return longest L as a scheme object. */ @@ -588,7 +600,8 @@ char * 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; @@ -608,8 +621,9 @@ gdbscm_gc_dup_argv (char **argv) /* 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)