* Accessing multiple values from C @ 2011-11-01 15:34 Julian Graham 2011-11-01 22:57 ` Ludovic Courtès 2012-01-09 18:54 ` Andy Wingo 0 siblings, 2 replies; 15+ messages in thread From: Julian Graham @ 2011-11-01 15:34 UTC (permalink / raw) To: Guile Users Hey all, I was playing around with some C code that uses the new R6RS bytevector ports, and I noticed that there doesn't seem to be an easy way (a la `let-values' or `receive') to access multiple return values from C. I've resorted to doing: scm_struct_ref (foo, SCM_INUM0); ...which is almost certainly not future-proof. All I want to do is access these values as a pair or list. Is there a Right Way to do that? Thanks, Julian ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Accessing multiple values from C 2011-11-01 15:34 Accessing multiple values from C Julian Graham @ 2011-11-01 22:57 ` Ludovic Courtès 2012-01-09 18:54 ` Andy Wingo 1 sibling, 0 replies; 15+ messages in thread From: Ludovic Courtès @ 2011-11-01 22:57 UTC (permalink / raw) To: guile-user Hi, Julian Graham <joolean@gmail.com> skribis: > I was playing around with some C code that uses the new R6RS > bytevector ports, and I noticed that there doesn't seem to be an easy > way (a la `let-values' or `receive') to access multiple return values > from C. I've resorted to doing: > > scm_struct_ref (foo, SCM_INUM0); > > ...which is almost certainly not future-proof. All I want to do is > access these values as a pair or list. Values were already structs in 1.8, so that’s OK. Perhaps this should be documented though, and C accessors could be provided. > Is there a Right Way to do that? Yes: write Scheme code! :-) In 1.8 multiple-values were always a struct, which had to be allocated each time multiple values were returned. In 2.0 it’s a struct only if it has to cross the Scheme/C boundary–otherwise the values are stored on the VM stack. Thanks, Ludo’. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Accessing multiple values from C 2011-11-01 15:34 Accessing multiple values from C Julian Graham 2011-11-01 22:57 ` Ludovic Courtès @ 2012-01-09 18:54 ` Andy Wingo 2012-01-09 19:00 ` Julian Graham 1 sibling, 1 reply; 15+ messages in thread From: Andy Wingo @ 2012-01-09 18:54 UTC (permalink / raw) To: Julian Graham; +Cc: Guile Users Hi, On Tue 01 Nov 2011 16:34, Julian Graham <joolean@gmail.com> writes: > I was playing around with some C code that uses the new R6RS > bytevector ports, and I noticed that there doesn't seem to be an easy > way (a la `let-values' or `receive') to access multiple return values > from C. I've resorted to doing: > > scm_struct_ref (foo, SCM_INUM0); > > ...which is almost certainly not future-proof. All I want to do is > access these values as a pair or list. Is there a Right Way to do > that? Not yet. You interested in adding scm_c_value_ref (SCM, size_t) to the API, and documentation to api-control.texi? If you do it soon, it will make it into 2.0.4. Andy -- http://wingolog.org/ ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Accessing multiple values from C 2012-01-09 18:54 ` Andy Wingo @ 2012-01-09 19:00 ` Julian Graham 2012-01-12 4:50 ` Julian Graham 0 siblings, 1 reply; 15+ messages in thread From: Julian Graham @ 2012-01-09 19:00 UTC (permalink / raw) To: Andy Wingo; +Cc: Guile Users Hey Andy, > Not yet. You interested in adding scm_c_value_ref (SCM, size_t) to the > API, and documentation to api-control.texi? If you do it soon, it > will make it into 2.0.4. Sure. Gimme a day or so and I'll have something for review. Regards, Julian ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Accessing multiple values from C 2012-01-09 19:00 ` Julian Graham @ 2012-01-12 4:50 ` Julian Graham 2012-01-15 21:47 ` Ludovic Courtès 2012-01-18 3:15 ` Mark H Weaver 0 siblings, 2 replies; 15+ messages in thread From: Julian Graham @ 2012-01-12 4:50 UTC (permalink / raw) To: Andy Wingo; +Cc: Guile Users [-- Attachment #1: Type: text/plain, Size: 338 bytes --] Howdy, >> Not yet. You interested in adding scm_c_value_ref (SCM, size_t) to the >> API, and documentation to api-control.texi? If you do it soon, it >> will make it into 2.0.4. > > Sure. Gimme a day or so and I'll have something for review. Find attached a patch. Let me know if I missed anything. Regards, Julian [-- Attachment #2: 0001-Add-scm_c_value_ref-to-allow-access-to-multiple-retu.patch --] [-- Type: text/x-diff, Size: 5095 bytes --] From 8d1bf16a607c6e8a0913ef982df88286dd887d51 Mon Sep 17 00:00:00 2001 From: Julian Graham <julian@navigator.(none)> 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 <config.h> +#endif + +#include <assert.h> +#include <libguile.h> +#include <stdlib.h> +#include <string.h> + +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 ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: Accessing multiple values from C 2012-01-12 4:50 ` Julian Graham @ 2012-01-15 21:47 ` Ludovic Courtès 2012-01-16 9:05 ` Andy Wingo 2012-01-18 3:15 ` Mark H Weaver 1 sibling, 1 reply; 15+ messages in thread From: Ludovic Courtès @ 2012-01-15 21:47 UTC (permalink / raw) To: guile-user Hi Julian, Julian Graham <joolean@gmail.com> skribis: >>> Not yet. You interested in adding scm_c_value_ref (SCM, size_t) to the >>> API, and documentation to api-control.texi? If you do it soon, it >>> will make it into 2.0.4. >> >> Sure. Gimme a day or so and I'll have something for review. > > Find attached a patch. Let me know if I missed anything. Looks good to me, thanks! > +@deffn {C Function} scm_c_value_ref (values, idx) > +Returns the value at the position specified by @var{idx} in the Should be “Return” here. Andy: OK to apply? Ludo’. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Accessing multiple values from C 2012-01-15 21:47 ` Ludovic Courtès @ 2012-01-16 9:05 ` Andy Wingo 0 siblings, 0 replies; 15+ messages in thread From: Andy Wingo @ 2012-01-16 9:05 UTC (permalink / raw) To: Ludovic Courtès; +Cc: guile-user On Sun 15 Jan 2012 22:47, ludo@gnu.org (Ludovic Courtès) writes: >>>> Not yet. You interested in adding scm_c_value_ref (SCM, size_t) to the >>>> API, and documentation to api-control.texi? If you do it soon, it >>>> will make it into 2.0.4. >>> >>> Sure. Gimme a day or so and I'll have something for review. >> >> Find attached a patch. Let me know if I missed anything. > > Looks good to me, thanks! > > Andy: OK to apply? If it looks good to you, sure! I haven't had a chance to review anything besides local-eval in a few days :/ Happy hacking, Andy -- http://wingolog.org/ ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Accessing multiple values from C 2012-01-12 4:50 ` Julian Graham 2012-01-15 21:47 ` Ludovic Courtès @ 2012-01-18 3:15 ` Mark H Weaver 2012-01-18 16:20 ` Andy Wingo 2012-01-18 20:19 ` Ludovic Courtès 1 sibling, 2 replies; 15+ messages in thread From: Mark H Weaver @ 2012-01-18 3:15 UTC (permalink / raw) To: Julian Graham; +Cc: Andy Wingo, Ludovic Courtès, Guile Users Hi Julian, thanks for working on this! Julian Graham <joolean@gmail.com> writes: > +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)); > +} > + Should this verify that `obj' is a values object? Should it verify that `idx' can fit in an inum? Also, if `obj' is _not_ a values object and `idx' is 0, should this simply return `obj'? Since a single value is conceptually no different than multiple values (but is represented very differently within Guile), I'd think that this function should handle that case gracefully. What do other people think? Thanks, Mark ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Accessing multiple values from C 2012-01-18 3:15 ` Mark H Weaver @ 2012-01-18 16:20 ` Andy Wingo 2012-01-18 20:19 ` Ludovic Courtès 1 sibling, 0 replies; 15+ messages in thread From: Andy Wingo @ 2012-01-18 16:20 UTC (permalink / raw) To: Mark H Weaver; +Cc: Guile Users, Ludovic Courtès On Wed 18 Jan 2012 04:15, Mark H Weaver <mhw@netris.org> writes: > Should this verify that `obj' is a values object? > > Should it verify that `idx' can fit in an inum? Agreed! > Also, if `obj' is _not_ a values object and `idx' is 0, should this > simply return `obj'? Since a single value is conceptually no different > than multiple values (but is represented very differently within Guile), > I'd think that this function should handle that case gracefully. Hum, good question. I'm inclined to agree. Regards, Andy -- http://wingolog.org/ ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Accessing multiple values from C 2012-01-18 3:15 ` Mark H Weaver 2012-01-18 16:20 ` Andy Wingo @ 2012-01-18 20:19 ` Ludovic Courtès 2012-01-18 21:01 ` Mark H Weaver 2012-01-18 21:01 ` Julian Graham 1 sibling, 2 replies; 15+ messages in thread From: Ludovic Courtès @ 2012-01-18 20:19 UTC (permalink / raw) To: Mark H Weaver; +Cc: Andy Wingo, Guile Users Hi Mark, Mark H Weaver <mhw@netris.org> skribis: > Julian Graham <joolean@gmail.com> writes: >> +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)); >> +} >> + > > Should this verify that `obj' is a values object? > > Should it verify that `idx' can fit in an inum? Yes, good point. Using an ‘SCM_VALIDATE’, which will throw an exception upon error, right? > Also, if `obj' is _not_ a values object and `idx' is 0, should this > simply return `obj'? Yes, makes sense to me. Julian: could you change these bits and send an updated patch? Thanks, Ludo’. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Accessing multiple values from C 2012-01-18 20:19 ` Ludovic Courtès @ 2012-01-18 21:01 ` Mark H Weaver 2012-01-18 21:44 ` Ludovic Courtès 2012-01-18 21:47 ` Mark H Weaver 2012-01-18 21:01 ` Julian Graham 1 sibling, 2 replies; 15+ messages in thread From: Mark H Weaver @ 2012-01-18 21:01 UTC (permalink / raw) To: Ludovic Courtès; +Cc: Andy Wingo, Guile Users ludo@gnu.org (Ludovic Courtès) writes: > Mark H Weaver <mhw@netris.org> skribis: > >> Julian Graham <joolean@gmail.com> writes: >>> +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)); >>> +} >>> + >> >> Should this verify that `obj' is a values object? >> >> Should it verify that `idx' can fit in an inum? > > Yes, good point. Using an ‘SCM_VALIDATE’, which will throw an exception > upon error, right? Well, there's a complication with using an `SCM_VALIDATE' to check for values objects. If `idx' is 0 (make sure it's exact!), then we must _not_ throw an exception if `obj' is not a values object. However, in that case we still need to know whether `obj' is a values object or not. Also, a fine point about desirable error messages: asking for `idx' 5 of a values object with only 3 elements is, conceptually, the same kind of error as asking for `idx' 5 of something that is _not_ a values object. Therefore, I think in both cases the error should be something to the effect of "too few values". Thanks, Mark ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Accessing multiple values from C 2012-01-18 21:01 ` Mark H Weaver @ 2012-01-18 21:44 ` Ludovic Courtès 2012-01-18 21:47 ` Mark H Weaver 1 sibling, 0 replies; 15+ messages in thread From: Ludovic Courtès @ 2012-01-18 21:44 UTC (permalink / raw) To: Mark H Weaver; +Cc: Andy Wingo, Guile Users Hi! Mark H Weaver <mhw@netris.org> skribis: > ludo@gnu.org (Ludovic Courtès) writes: > >> Mark H Weaver <mhw@netris.org> skribis: >> >>> Julian Graham <joolean@gmail.com> writes: >>>> +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)); >>>> +} >>>> + >>> >>> Should this verify that `obj' is a values object? >>> >>> Should it verify that `idx' can fit in an inum? >> >> Yes, good point. Using an ‘SCM_VALIDATE’, which will throw an exception >> upon error, right? > > Well, there's a complication with using an `SCM_VALIDATE' to check for > values objects. If `idx' is 0 (make sure it's exact!), then we must > _not_ throw an exception if `obj' is not a values object. However, in > that case we still need to know whether `obj' is a values object or not. Yes, I already agreed on this one. ;-) > Also, a fine point about desirable error messages: asking for `idx' 5 of > a values object with only 3 elements is, conceptually, the same kind of > error as asking for `idx' 5 of something that is _not_ a values object. > > Therefore, I think in both cases the error should be something to the > effect of "too few values". Right. Ludo’. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Accessing multiple values from C 2012-01-18 21:01 ` Mark H Weaver 2012-01-18 21:44 ` Ludovic Courtès @ 2012-01-18 21:47 ` Mark H Weaver 2012-01-18 23:06 ` Mark H Weaver 1 sibling, 1 reply; 15+ messages in thread From: Mark H Weaver @ 2012-01-18 21:47 UTC (permalink / raw) To: Ludovic Courtès; +Cc: Andy Wingo, Guile Users I think something along these lines be ideal, though this code is UNTESTED. Mark SCM scm_c_value_ref (SCM obj, size_t idx) { if (SCM_VALUESP (obj)) { SCM values = scm_struct_ref (obj, SCM_INUM0); size_t i = idx; while (SCM_LIKELY (!scm_is_null (values))) { if (i == 0) return SCM_CAR (values); values = SCM_CDR (values); i--; } } else if (idx == 0) return obj; scm_error (scm_out_of_range_key, "scm_c_value_ref", "Too few values in ~S to access index ~S", scm_list_2 (obj, scm_from_unsigned_integer (idx)), scm_list_1 (scm_from_unsigned_integer (idx))); } ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Accessing multiple values from C 2012-01-18 21:47 ` Mark H Weaver @ 2012-01-18 23:06 ` Mark H Weaver 0 siblings, 0 replies; 15+ messages in thread From: Mark H Weaver @ 2012-01-18 23:06 UTC (permalink / raw) To: Guile Users At Julian's request, I went ahead and pushed my implementation of `scm_c_value_ref' to the stable-2.0 branch, so it will be in 2.0.4. Thanks, Mark ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: Accessing multiple values from C 2012-01-18 20:19 ` Ludovic Courtès 2012-01-18 21:01 ` Mark H Weaver @ 2012-01-18 21:01 ` Julian Graham 1 sibling, 0 replies; 15+ messages in thread From: Julian Graham @ 2012-01-18 21:01 UTC (permalink / raw) To: Ludovic Courtès; +Cc: Andy Wingo, Mark H Weaver, Guile Users Hi all, Thanks for the review! On Wed, Jan 18, 2012 at 3:19 PM, Ludovic Courtès <ludo@gnu.org> wrote: > Julian: could you change these bits and send an updated patch? Will do. Regards, Julian ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2012-01-18 23:06 UTC | newest] Thread overview: 15+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-11-01 15:34 Accessing multiple values from C Julian Graham 2011-11-01 22:57 ` Ludovic Courtès 2012-01-09 18:54 ` Andy Wingo 2012-01-09 19:00 ` Julian Graham 2012-01-12 4:50 ` Julian Graham 2012-01-15 21:47 ` Ludovic Courtès 2012-01-16 9:05 ` Andy Wingo 2012-01-18 3:15 ` Mark H Weaver 2012-01-18 16:20 ` Andy Wingo 2012-01-18 20:19 ` Ludovic Courtès 2012-01-18 21:01 ` Mark H Weaver 2012-01-18 21:44 ` Ludovic Courtès 2012-01-18 21:47 ` Mark H Weaver 2012-01-18 23:06 ` Mark H Weaver 2012-01-18 21:01 ` Julian Graham
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).