unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* 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 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

* 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

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).