From 8d1bf16a607c6e8a0913ef982df88286dd887d51 Mon Sep 17 00:00:00 2001 From: Julian Graham Date: Wed, 11 Jan 2012 22:08:51 -0500 Subject: [PATCH] Add `scm_c_value_ref' to allow access to multiple returned values from C. * libguile/values.c, libguile/values.h (scm_c_value_ref): New function. * doc/ref/api-control.texi (Multiple Values): Add documentation for `scm_c_value_ref'. * test-suite/standalone/test-scm-values.c: New file. * test-suite/standalone/Makefile.am: Ensure that test-scm-values.c gets built and executed as part of `make check'. --- doc/ref/api-control.texi | 5 +++ libguile/values.c | 7 ++++ libguile/values.h | 1 + test-suite/standalone/Makefile.am | 7 ++++ test-suite/standalone/test-scm-values.c | 60 +++++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 0 deletions(-) create mode 100644 test-suite/standalone/test-scm-values.c diff --git a/doc/ref/api-control.texi b/doc/ref/api-control.texi index c1502b0..4077bd9 100644 --- a/doc/ref/api-control.texi +++ b/doc/ref/api-control.texi @@ -785,6 +785,11 @@ the current implementation that object shares structure with @var{args}, so @var{args} should not be modified subsequently. @end deffn +@deffn {C Function} scm_c_value_ref (values, idx) +Returns the value at the position specified by @var{idx} in the +multiple-values object @var{values}. +@end deffn + @rnindex call-with-values @deffn {Scheme Procedure} call-with-values producer consumer Calls its @var{producer} argument with no values and a diff --git a/libguile/values.c b/libguile/values.c index ab77731..3a213fa 100644 --- a/libguile/values.c +++ b/libguile/values.c @@ -67,6 +67,13 @@ print_values (SCM obj, SCM pwps) return SCM_UNSPECIFIED; } +SCM +scm_c_value_ref (SCM obj, size_t idx) +{ + SCM values = scm_struct_ref (obj, SCM_INUM0); + return scm_list_ref (values, SCM_I_MAKINUM (idx)); +} + SCM_DEFINE (scm_values, "values", 0, 0, 1, (SCM args), "Delivers all of its arguments to its continuation. Except for\n" diff --git a/libguile/values.h b/libguile/values.h index 65ad8a1..5f79855 100644 --- a/libguile/values.h +++ b/libguile/values.h @@ -33,6 +33,7 @@ SCM_API SCM scm_values_vtable; SCM_INTERNAL void scm_i_extract_values_2 (SCM obj, SCM *p1, SCM *p2); SCM_API SCM scm_values (SCM args); +SCM_API SCM scm_c_value_ref (SCM values, size_t idx); SCM_INTERNAL void scm_init_values (void); #endif /* SCM_VALUES_H */ diff --git a/test-suite/standalone/Makefile.am b/test-suite/standalone/Makefile.am index 08d249c..7b96785 100644 --- a/test-suite/standalone/Makefile.am +++ b/test-suite/standalone/Makefile.am @@ -189,6 +189,13 @@ test_scm_to_latin1_string_LDADD = $(LIBGUILE_LDADD) check_PROGRAMS += test-scm-to-latin1-string TESTS += test-scm-to-latin1-string +# test-values +test_scm_values_SOURCES = test-scm-values.c +test_scm_values_CFLAGS = ${test_cflags} +test_scm_values_LDADD = $(LIBGUILE_LDADD) +check_PROGRAMS += test-scm-values +TESTS += test-scm-values + if HAVE_SHARED_LIBRARIES # test-extensions diff --git a/test-suite/standalone/test-scm-values.c b/test-suite/standalone/test-scm-values.c new file mode 100644 index 0000000..25acd2e --- /dev/null +++ b/test-suite/standalone/test-scm-values.c @@ -0,0 +1,60 @@ +/* Copyright (C) 2012 Free Software Foundation, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 3 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +static void +test_scm_c_value_ref () +{ + SCM values = scm_values (scm_list_3 (scm_from_locale_string ("foo"), + scm_from_locale_string ("bar"), + scm_from_locale_string ("baz"))); + + + char *foo = scm_to_locale_string (scm_c_value_ref (values, 0)); + char *bar = scm_to_locale_string (scm_c_value_ref (values, 1)); + char *baz = scm_to_locale_string (scm_c_value_ref (values, 2)); + + assert (strcmp (foo, "foo") == 0); + assert (strcmp (bar, "bar") == 0); + assert (strcmp (baz, "baz") == 0); + + free (foo); + free (bar); + free (baz); +} + +static void +tests (void *data, int argc, char **argv) +{ + test_scm_c_value_ref (); +} + +int +main (int argc, char *argv[]) +{ + scm_boot_guile (argc, argv, tests, NULL); + return 0; +} -- 1.7.5.4