Moving towards snow-fort packaging

This commit is contained in:
retropikzel 2025-06-20 09:37:51 +03:00
parent 1bcba42096
commit f037d22c40
6 changed files with 68 additions and 855 deletions

3
.gitignore vendored
View File

@ -47,3 +47,6 @@ snow
foreign/c/lib
!foreign/c/primitives/gauche/*.c
!foreign/c/primitives/include/*.h
README.html
*.tgz
*.tar.gz

View File

@ -2,10 +2,30 @@
CC=gcc
DOCKER=docker run -it -v ${PWD}:/workdir
DOCKER_INIT=cd /workdir && make clean &&
VERSION=$(shell grep "version:" README.md | awk '{split\($0,a\); print a[2];}')
VERSION=$(shell awk '/version:/{ print $$2 }' README.md )
TESTNAME=primitives
all: chibi chicken cyclone gambit gauche gerbil guile kawa larceny mosh racket sagittarius skint stklos tr7 ypsilon
chibi: foreign/c/primitives/chibi/foreign-c.stub
chibi-ffi foreign/c/primitives/chibi/foreign-c.stub
${CC} \
-g3 \
-o foreign/c/primitives/chibi/foreign-c.so \
foreign/c/primitives/chibi/foreign-c.c \
-fPIC \
-lffi \
-shared
package:
markdown README.md > README.html
snow-chibi package \
--version=${VERSION} \
--authors="Retropikzel" \
--doc=README.html \
--description="Portable foreign function interface for R7RS Schemes" \
foreign/c.sld
clean-package:
rm -rf *.tgz
test-compile-r7rs: tmp/test/libtest.o tmp/test/libtest.so tmp/test/libtest.a
make ${COMPILE_R7RS}
@ -46,6 +66,7 @@ tmp/test/libtest.so: tests/c-src/libtest.c
tmp/test/libtest.a: tmp/test/libtest.o tests/c-src/libtest.c
ar rcs tmp/test/libtest.a tmp/test/libtest.o
documentation/foreign-c.html:
# apt-get install pandoc weasyprint
docs:
@ -59,54 +80,6 @@ docs:
-o documentation/foreign-c.pdf \
README.md
chibi:
make -C foreign/c chibi
chicken:
make -C foreign/c chicken
cyclone:
make -C foreign/c cyclone
gambit:
make -C foreign/c gambit
gauche:
make -C foreign/c gauche
gerbil:
make -C foreign/c gerbil
guile:
make -C foreign/c guile
kawa:
make -C foreign/c kawa
larceny:
make -C foreign/c larceny
mosh:
make -C foreign/c mosh
racket:
make -C foreign/c racket
sagittarius:
make -C foreign/c sagittarius
skint:
make -C foreign/c skint
stklos:
make -C foreign/c stklos
tr7:
make -C foreign/c tr7
ypsilon:
make -C foreign/c tr7
clean:
find . -name "*.meta" -delete
find . -name "*.link" -delete

View File

@ -1,800 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>foreign-c a portable foreign function interface for R7RS
Schemes - 0.10.0</title>
<style>
table { width: 250%; }
nav { float: left; width: 20%;}
main { float: right; width: 80%; }
pre { background-color: lightgrey; }
</style>
</head>
<body>
<h1 id="foreign-c">foreign-c</h1>
<p>foreign-c is a C foreign function interface (FFI) library for
R7RS Schemes. It is portable in the sense that it supports
multiple implementations, as opposed to being portable by
conforming to some specification.</p>
<p><a href="https://sr.ht/~retropikzel/foreign-c/trackers">Issue
tracker</a></p>
<p><a href="https://sr.ht/~retropikzel/foreign-c/lists">Maling
lists</a></p>
<p><a
href="https://jenkins.scheme.org/job/foreign_c/job/foreign-c/">Jenkins</a></p>
<ul>
<li><a href="#installation">Installation</a></li>
<li><a href="#documentation">Documentation</a>
<ul>
<li><a href="#types">Types</a></li>
<li><a href="#primitives-1">Primitives 1</a>
<ul>
<li>c-type-size</li>
<li>define-c-library</li>
<li>define-c-procedure</li>
<li>c-bytevector?</li>
<li>c-bytevector-u8-set!</li>
<li>c-bytevector-u8-ref</li>
<li>c-bytevector-pointer-set!</li>
<li>c-bytevector-pointer-ref</li>
</ul></li>
<li><a href="#primitives-2">Primitives 2</a>
<ul>
<li>define-c-callback</li>
</ul></li>
<li><a href="#c-bytevector">c-bytevector</a>
<ul>
<li>make-c-null</li>
<li>c-null?</li>
<li>c-free</li>
<li>make-c-bytevector</li>
<li>call-with-address-of</li>
<li>native-endianness</li>
<li>c-bytevector-s8-set!</li>
<li>c-bytevector-s8-ref</li>
<li>c-bytevector-s16-set!</li>
<li>c-bytevector-s16-ref</li>
<li>c-bytevector-s16-native-set!</li>
<li>c-bytevector-s16-native-ref</li>
<li>c-bytevector-u16-set!</li>
<li>c-bytevector-u16-ref</li>
<li>c-bytevector-u16-native-set!</li>
<li>c-bytevector-u16-native-ref</li>
<li>c-bytevector-s32-set!</li>
<li>c-bytevector-s32-ref</li>
<li>c-bytevector-s32-native-set!</li>
<li>c-bytevector-s32-native-ref</li>
<li>c-bytevector-u32-set!</li>
<li>c-bytevector-u32-ref</li>
<li>c-bytevector-u32-native-set!</li>
<li>c-bytevector-u32-native-ref</li>
<li>c-bytevector-s64-set!</li>
<li>c-bytevector-s64-ref</li>
<li>c-bytevector-s64-native-set!</li>
<li>c-bytevector-s64-native-ref</li>
<li>c-bytevector-u64-set!</li>
<li>c-bytevector-u64-ref</li>
<li>c-bytevector-u64-native-set!</li>
<li>c-bytevector-u64-native-ref</li>
<li>c-bytevector-sint-set!</li>
<li>c-bytevector-sint-ref</li>
<li>c-bytevector-uint-set!</li>
<li>c-bytevector-uint-ref</li>
<li>c-bytevector-ieee-single-set!</li>
<li>c-bytevector-ieee-single-native-set!</li>
<li>c-bytevector-ieee-single-ref</li>
<li>c-bytevector-ieee-single-native-ref</li>
<li>c-bytevector-ieee-double-set!</li>
<li>c-bytevector-ieee-double-native-set!</li>
<li>c-bytevector-ieee-double-ref</li>
<li>c-bytevector-ieee-double-native-ref</li>
<li>bytevector-&gt;c-bytevector</li>
<li>c-bytevector-&gt;bytevector</li>
<li>string-&gt;c-utf8</li>
<li>c-utf8-&gt;string</li>
</ul></li>
<li><a href="#environment-variables">Environment
variables</a></li>
</ul></li>
</ul>
<h2 id="implementation-support-tables">Implementation support
tables</h2>
<h3 id="primitives-1-table">Primitives 1 table</h3>
<table>
<colgroup>
<col style="width: 13%" />
<col style="width: 10%" />
<col style="width: 16%" />
<col style="width: 15%" />
<col style="width: 16%" />
<col style="width: 11%" />
<col style="width: 16%" />
</colgroup>
<thead>
<tr class="header">
<th></th>
<th style="text-align: center;">c-type-size</th>
<th style="text-align: center;">c-bytevector-u8-set!</th>
<th style="text-align: center;">c-bytevector-u8-ref</th>
<th style="text-align: center;">define-c-library</th>
<th style="text-align: center;">c-bytevector?</th>
<th style="text-align: center;">define-c-procedure</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><strong>Chibi</strong></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
</tr>
<tr class="even">
<td><strong>Chicken</strong></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
</tr>
<tr class="odd">
<td><strong>Gauche</strong></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
</tr>
<tr class="even">
<td><strong>Guile</strong></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
</tr>
<tr class="odd">
<td><strong>Kawa</strong></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
</tr>
<tr class="even">
<td><strong>Mosh</strong></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
</tr>
<tr class="odd">
<td><strong>Racket</strong></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
</tr>
<tr class="even">
<td><strong>Saggittarius</strong></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
</tr>
<tr class="odd">
<td><strong>Stklos</strong></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
</tr>
<tr class="even">
<td><strong>Ypsilon</strong></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
</tr>
</tbody>
</table>
<h3 id="primitives-2-table">Primitives 2 table</h3>
<table>
<thead>
<tr class="header">
<th></th>
<th style="text-align: center;">define-c-callback</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Chibi</td>
<td style="text-align: center;"></td>
</tr>
<tr class="even">
<td><strong>Chicken</strong></td>
<td style="text-align: center;">X</td>
</tr>
<tr class="odd">
<td>Gauche</td>
<td style="text-align: center;"></td>
</tr>
<tr class="even">
<td><strong>Guile</strong></td>
<td style="text-align: center;">X</td>
</tr>
<tr class="odd">
<td>Kawa</td>
<td style="text-align: center;"></td>
</tr>
<tr class="even">
<td><strong>Mosh</strong></td>
<td style="text-align: center;">X</td>
</tr>
<tr class="odd">
<td><strong>Racket</strong></td>
<td style="text-align: center;">X</td>
</tr>
<tr class="even">
<td><strong>Saggittarius</strong></td>
<td style="text-align: center;">X</td>
</tr>
<tr class="odd">
<td>Stklos</td>
<td style="text-align: center;"></td>
</tr>
<tr class="even">
<td><strong>Ypsilon</strong></td>
<td style="text-align: center;">X</td>
</tr>
</tbody>
</table>
<h3 id="test-files-pass">Test files pass</h3>
<table>
<thead>
<tr class="header">
<th></th>
<th style="text-align: center;">primitives.scm</th>
<th style="text-align: center;">addressof.scm</th>
<th style="text-align: right;">callback.scm</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Chibi</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td><strong>Chicken</strong></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: right;">X</td>
</tr>
<tr class="odd">
<td>Gauche</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td><strong>Guile</strong></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: right;">X</td>
</tr>
<tr class="odd">
<td>Kawa</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td>Mosh</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: right;"></td>
</tr>
<tr class="odd">
<td>Racket</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;"></td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td><strong>Saggittarius</strong></td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: right;">X</td>
</tr>
<tr class="odd">
<td>Stklos</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: right;"></td>
</tr>
<tr class="even">
<td>Ypsilon</td>
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td style="text-align: right;"></td>
</tr>
</tbody>
</table>
<h2 id="installation">Installation</h2>
<p>Eithe download the latest release from <a
href="https://git.sr.ht/~retropikzel/foreign-c/refs">https://git.sr.ht/~retropikzel/foreign-c/refs</a>
or git clone, preferably with a tag, and copy the
<em>foreign</em> directory to your library directory.</p>
<p>Example assuming libraries in directory <em>snow</em>:</p>
<pre><code>git clone https://git.sr.ht/~retropikzel/foreign-c --branch LATEST_VERSION
mkdir -p snow
cp -r foreign-c/foreign snow/
make -C snow/foreign/c SCHEME_IMPLEMENTATION_NAME</code></pre>
<p>With most implementations the make command does not compile
anything. When that is the case it will say “Nothing to build on
SCHEME_IMPLEMENTATION_NAME.”</p>
<h2 id="documentation">Documentation</h2>
<h3 id="types">Types</h3>
<p>Types are given as symbols, for example int8 or
pointer.</p>
<ul>
<li>int8</li>
<li>uint8</li>
<li>int16</li>
<li>uint16</li>
<li>int32</li>
<li>uint32</li>
<li>int64</li>
<li>uint64</li>
<li>char</li>
<li>unsigned-char</li>
<li>short</li>
<li>unsigned-short</li>
<li>int</li>
<li>unsigned-int</li>
<li>long</li>
<li>unsigned-long</li>
<li>float</li>
<li>double</li>
<li>pointer
<ul>
<li>c-bytevector on Scheme side</li>
</ul></li>
<li>callback
<ul>
<li>Callback function</li>
</ul></li>
<li>void
<ul>
<li>Can not be argument type, only return type</li>
</ul></li>
</ul>
<h3 id="primitives-1">Primitives 1</h3>
<p>(<strong>c-type-size</strong> <em>type</em>)</p>
<p>Returns the size of given C type.</p>
<p>(<strong>define-c-library</strong> <em>scheme-name</em>
<em>headers</em> <em>object-name</em> <em>options</em>)</p>
<p>Takes a scheme-name to bind the library to, list of C headers
as strings, shared-object name and options.</p>
<p>The C header strings should not contain “&lt;” or “&gt;”,
they are added automatically.</p>
<p>The name of the shared object should not contain suffix like
.so or .dll. Nor should it contain any prefix like “lib”.</p>
<p>Options:</p>
<ul>
<li>additional-versions
<ul>
<li>Search for additional versions of shared object, given
shared object “c” and additional versions “6” “7” on linux the
files “libc”, “libc.6”, “libc.7” are searched for.</li>
<li>Can be either numbers or strings</li>
</ul></li>
<li>additional-paths
<ul>
<li>Give additional paths to search shared objects from</li>
</ul></li>
</ul>
<p>Example:</p>
<pre><code>(cond-expand
(windows (define-c-library libc-stdlib
&#39;(&quot;stdlib.h&quot;)
&quot;ucrtbase&quot;
&#39;((additional-versions (&quot;0&quot; &quot;6&quot;))
(additiona-paths (&quot;.&quot;)))))
(else (define-c-library libc-stdlib
(list &quot;stdlib.h&quot;)
&quot;c&quot;
&#39;((additional-versions (&quot;0&quot; &quot;6&quot;))
(additiona-paths (&quot;.&quot;))))))</code></pre>
<h4 id="notes">Notes</h4>
<ul>
<li>Do not cond-expand inside the arguments, that might lead to
problems on some implementations.</li>
<li>Do not store options in variables, that might lead to
problems on some implementations.</li>
<li>Pass the headers using quote
<ul>
<li>As (…) and not (list…)</li>
</ul></li>
<li>Pass the options using quote
<ul>
<li>As (…) and not (list…)</li>
</ul></li>
</ul>
<p>(<strong>define-c-procedure</strong> <em>scheme-name</em>
<em>shared-object</em> <em>c-name</em> <em>return-type</em>
<em>argument-type</em>)</p>
<p>Takes a scheme-name to bind the C procedure to, shared-object
where the function is looked from, c-name of the function as
symbol, return-type and argument-types.</p>
<p>Defines a new foreign function to be used from Scheme
code.</p>
<p>Example:</p>
<pre><code>(cond-expand
(windows (define-c-library libc-stdlib &#39;(&quot;stdlib.h&quot;) &quot;ucrtbase&quot; &#39;()))
(else (define-c-library libc-stdlib &#39;(&quot;stdlib.h&quot;) &quot;c&quot; &#39;(&quot;6&quot;))))
(define-c-procedure c-puts libc-stdlib &#39;puts &#39;int &#39;(pointer))
(c-puts &quot;Message brought to you by foreign-c!&quot;)</code></pre>
<h4 id="notes-1">Notes</h4>
<ul>
<li>Pass the return-types using quote
<ul>
<li>As (…) and not (list…)</li>
</ul></li>
</ul>
<p>(<strong>c-bytevector?</strong> <em>obj</em>)</p>
<p>Returns <strong>#t</strong> if <em>obj</em> is c-bytevector,
otherwise returns <strong>#f</strong>.</p>
<p>(<strong>c-bytevector-u8-set!</strong> <em>c-bytevector</em>
<em>k</em> <em>byte</em>)</p>
<p>If K is not a valid index of c-bytevector the behaviour is
undefined.</p>
<p>Stores the byte in element k of c-bytevector.</p>
<p>(<strong>c-bytevector-u8-ref</strong> <em>c-bytevector</em>
<em>k</em>)</p>
<p>If K is not a valid index of c-bytevector the behaviour is
undefined.</p>
<p>Returns the byte at index k of c-bytevector.</p>
<p>(<strong>c-bytevector-pointer-set!</strong>
<em>c-bytevector</em> <em>k</em> <em>pointer</em>)</p>
<p>If K is not a valid index of c-bytevector the behaviour is
undefined.</p>
<p>Stores the pointer(which is also c-bytevector) in element k
of c-bytevector.</p>
<p>(<strong>c-bytevector-pointer-ref</strong>
<em>c-bytevector</em> <em>k</em> <em>pointer</em>)</p>
<p>If K is not a valid index of c-bytevector the behaviour is
undefined.</p>
<p>Returns the pointer(which is also c-bytevector) at index k of
c-bytevector.</p>
<h3 id="primitives-2">Primitives 2</h3>
<p>(<strong>define-c-callback</strong> <em>scheme-name</em>
<em>return-type</em> <em>argument-types</em>
<em>procedure</em>)</p>
<p>Takes scheme-name to bind the Scheme procedure to,
return-type, argument-types and procedure as in place
lambda.</p>
<p>Defines a new Sceme function to be used as callback to C
code.</p>
<p>Example:</p>
<pre><code>; Load the shared library
(cond-expand
(windows (define-c-library libc-stdlib &#39;(&quot;stdlib.h&quot;) &quot;ucrtbase&quot; &#39;()))
(else (define-c-library &#39;(&quot;stdlib.h&quot;) &quot;c&quot; &#39;(&quot;&quot; &quot;6&quot;))))
; Define C function that takes a callback
(define-c-procedure qsort libc-stdlib &#39;qsort &#39;void &#39;(pointer int int callback))
; Define our callback
(define-c-callback compare
&#39;int
&#39;(pointer pointer)
(lambda (pointer-a pointer-b)
(let ((a (c-bytevector-sint-get pointer-a (native-endianness) 0))
(b (c-bytevector-sint-get pointer-b (native-endianness) 0)))
(cond ((&gt; a b) 1)
((= a b) 0)
((&lt; a b) -1)))))
; Create new array of ints to be sorted
(define array (make-c-bytevector (* (c-type-size &#39;int) 3)))
(c-bytevector-s32-native-set! array (* (c-type-size &#39;int) 0) 3)
(c-bytevector-s32-native-set! array (* (c-type-size &#39;int) 1) 2)
(c-bytevector-s32-native-set! array (* (c-type-size &#39;int) 2) 1)
(display array)
(newline)
;&gt; (3 2 1)
; Sort the array
(qsort array 3 (c-type-size &#39;int) compare)
(display array)
(newline)
;&gt; (1 2 3)</code></pre>
<h3 id="c-bytevector">c-bytevector</h3>
<p>Foreign-c c-bytevector interface is copied from R6RS
bytevectors, with some added functionality for C null pointers
and manual memory management.</p>
<p>(<strong>make-c-null</strong>)</p>
<p>Returns a null C pointer.</p>
<p>(<strong>c-null?</strong> <em>obj</em>)</p>
<p>Returns <strong>#t</strong> if <em>obj</em> is a null C
pointer, otherwise returns <strong>#f</strong>.</p>
<p>(<strong>c-free</strong> <em>c-bytevector</em>)</p>
<p>Frees <em>c-bytevector</em> from memory.</p>
<p>(<strong>call-with-address-of</strong> <em>c-bytevector</em>
<em>thunk</em>)</p>
<p>Calls <em>thunk</em> with address pointer of
<em>c-bytevector</em>.</p>
<p>Since the support for calling C functions taking pointer
address arguments, ones prefixrd with &amp; in C, varies, some
additional ceremony is needed on the Scheme side.</p>
<p>Example:</p>
<p>Calling from C:</p>
<pre><code>//void func(int** i);
func(&amp;i);</code></pre>
<p>Calling from Scheme:</p>
<pre><code>(define cbv (make-bytevector (c-type-size &#39;int)))
(call-with-address-of
cbv
(lambda (address)
(func address)))
; Use cbv here</code></pre>
<p>The passed c-bytevector, in example named cbv, should only be
used <strong>after</strong> call to call-with-addres-of
ends.</p>
<p>(<strong>bytevector-&gt;c-bytevector</strong>
<em>bytevector</em>)</p>
<p>Returns a newly allocated c-bytevector of the bytes of
<em>bytevector</em>.</p>
<p>(<strong>c-bytevector-&gt;bytevector</strong>)</p>
<p>Returns a newly allocated bytevector of the bytes of
<em>c-bytevector</em>.</p>
<p>(<strong>native-endianness</strong>)</p>
<p>Returns the endianness symbol associated implementations
preferred endianness (usually that of the underlying machine
architecture). This may be any &lt;endianness symbol&gt;,
including a symbol other than big and little.</p>
<p>(<strong>make-c-bytevector</strong> <em>k</em>)</br>
(<strong>make-c-bytevector</strong> <em>k</em>
<em>fill</em>)</p>
<p>Returns a newly allocated c-bytevector of <em>k</em>
bytes.</p>
<p>If the <em>fill</em> argument is missing, the initial
contents of the returned c-bytevector are unspecified.</p>
<p>If the <em>fill</em> argument is present, its value must
confine to C uint8_t values , it specifies the initial value for
the bytes of the c-bytevector</p>
<p>(<strong>c-bytevector-s8-set!</strong> <em>c-bytevector</em>
<em>k</em> <em>byte</em>)</p>
<p>If <em>k</em> is not a valid index of c-bytevector the
behaviour is undefined.</p>
<p>Stores the <em>byte</em> in element <em>k</em> of
<em>c-bytevector</em>.</p>
<p>(<strong>c-bytevector-s8-ref</strong> <em>c-bytevector</em>
<em>k</em>)</p>
<p>If <em>k</em> is not a valid index of c-bytevector the
behaviour is undefined.</p>
<p>Returns the byte at index <em>k</em> of
<em>c-bytevector</em>.</p>
<p>(<strong>c-bytevector-char-set!</strong>
<em>c-bytevector</em> <em>k</em> <em>char</em>)</p>
<p>If <em>k</em> is not a valid index of c-bytevector the
behaviour is undefined.</p>
<p>Stores the <em>char</em> in element <em>k</em> of
<em>c-bytevector</em>.</p>
<p>(<strong>c-bytevector-char-ref</strong> <em>c-bytevector</em>
<em>k</em>)</p>
<p>If <em>k</em> is not a valid index of c-bytevector the
behaviour is undefined.</p>
<p>Returns the char at index <em>k</em> of
<em>c-bytevector</em>.</p>
<p>(<strong>c-bytevector-uchar-set!</strong>
<em>c-bytevector</em> <em>k</em> <em>char</em>)</p>
<p>If <em>k</em> is not a valid index of c-bytevector the
behaviour is undefined.</p>
<p>Stores the unsigned <em>char</em> in element <em>k</em> of
<em>c-bytevector</em>.</p>
<p>(<strong>c-bytevector-uchar-ref</strong>
<em>c-bytevector</em> <em>k</em>)</p>
<p>If <em>k</em> is not a valid index of c-bytevector the
behaviour is undefined.</p>
<p>Returns the unsigned char at index <em>k</em> of
<em>c-bytevector</em>.</p>
<p>(<strong>c-bytevector-uint-ref</strong> <em>c-bytevector</em>
<em>k</em> <em>endianness</em> <em>size</em>)</br>
(<strong>c-bytevector-sint-ref</strong> <em>c-bytevector</em>
<em>k</em> <em>endianness</em> <em>size</em>)</br>
(<strong>c-bytevector-uint-set!</strong> <em>c-bytevector</em>
<em>k</em> <em>n</em> <em>endianness</em> <em>size</em>)</br>
(<strong>c-bytevector-sint-set!</strong> <em>c-bytevector</em>
<em>k</em> <em>n</em> <em>endianness</em> <em>size</em>)</p>
<p>Size must be a positive exact integer object. If
<em>k</em>,…,<em>k</em> + <em>size</em> 1 is not valid indices
of c-bytevector the behavior is unspecified.</p>
<p>The c-bytevector-uint-ref procedure retrieves the exact
integer object corresponding to the unsigned representation of
size <em>size</em> and specified by <em>endianness</em> at
indices <em>k</em>,…,<em>k</em> + <em>size</em> 1.</p>
<p>The c-bytevector-sint-ref procedure retrieves the exact
integer object corresponding to the twos-complement
representation of size <em>size</em> and specified by
<em>endianness</em> at indices <em>k</em>,…,<em>k</em> +
<em>size</em> 1. For c-bytevector-uint-set!, <em>n</em> must
be an exact integer object in the interval
{0,…,256^<em>size</em> 1}.</p>
<p>The c-bytevector-uint-set! procedure stores the unsigned
representation of size <em>size</em> and specified by
<em>endianness</em> into c-bytevector at indices
<em>k</em>,…,<em>k</em> + size 1.</p>
<p>The . . . -set! procedures return unspecified values.</p>
<p>Examples:</p>
<pre><code>(define cbv (make-c-bytevector (c-type-size &#39;int)))
(c-bytevector-sint-set! cbv 0 100 (native-endianness) (c-type-size &#39;int))
(c-bytevector-sint-ref cbv 0 (native-endianness) (c-type-size &#39;int))
&gt; 100</code></pre>
<p>(<strong>c-bytevector-u16-ref</strong> <em>c-bytevector</em>
<em>k</em> <em>endianness</em>)</br>
(<strong>c-bytevector-s16-ref</strong> <em>c-bytevector</em>
<em>k</em> <em>endianness</em>)</br>
(<strong>c-bytevector-u16-native-ref</strong>
<em>c-bytevector</em> <em>k</em>)</br>
(<strong>c-bytevector-s16-native-ref</strong>
<em>c-bytevector</em> <em>k</em>)</br>
(<strong>c-bytevector-u16-set!</strong> <em>c-bytevector</em>
<em>k</em> <em>n</em> <em>endianness</em>)</br>
(<strong>c-bytevector-s16-set!</strong> <em>c-bytevector</em>
<em>k</em> <em>n</em> <em>endianness</em>)</br>
(<strong>c-bytevector-u16-native-set!</strong>
<em>c-bytevector</em> <em>k</em> <em>n</em>)</br>
(<strong>c-bytevector-s16-native-set!</strong>
<em>c-bytevector</em> <em>k</em> <em>n</em>)</p>
<p><em>K</em> must be a valid index of <em>c-bytevector</em> ;
so must <em>k</em> + 1. For c-bytevector-u16-set! and
c-bytevector-u16-native-set!, <em>n</em> must be an exact
integer object in the interval {0,…,216 1}. For
c-bytevector-s16-set! and c-bytevector-s16-native-set!,
<em>n</em> must be an exact integer object in the interval
{215,…,215 1}.</p>
<p>These retrieve and set two-byte representations of numbers at
indices <em>k</em> and <em>k</em> + 1, according to the
endianness specified by <em>endianness</em>. The procedures with
u16 in their names deal with the unsigned representation; those
with s16 in their names deal with the twos-complement
representation.</p>
<p>The procedures with native in their names employ the native
endianness, and work only at aligned indices: <em>k</em> must be
a multiple of 2.</p>
<p>The …-set! procedures return unspecified values.</p>
<p>(<strong>c-bytevector-u32-ref</strong> <em>c-bytevector</em>
<em>k</em> <em>endianness</em>)</br>
(<strong>c-bytevector-s32-ref</strong> <em>c-bytevector</em>
<em>k</em> <em>endianness</em>)</br>
(<strong>c-bytevector-u32-native-ref</strong>
<em>c-bytevector</em> <em>k</em>)</br>
(<strong>c-bytevector-s32-native-ref</strong>
<em>c-bytevector</em> <em>k</em>)</br>
(<strong>c-bytevector-u32-set!</strong> <em>c-bytevector</em>
<em>k</em> <em>n</em> <em>endianness</em>)</br>
(<strong>c-bytevector-s32-set!</strong> <em>c-bytevector</em>
<em>k</em> <em>n</em> <em>endianness</em>)</br>
(<strong>c-bytevector-u32-native-set!</strong>
<em>c-bytevector</em> <em>k</em> <em>n</em>)</br>
(<strong>c-bytevector-s32-native-set!</strong>
<em>c-bytevector</em> <em>k</em> <em>n</em>)</p>
<p><em>K</em>,…,<em>k</em> + 3 must be valid indices of
bytevector. For c-bytevector-u32-set! and
bytevector-u32-native-set!, <em>n</em> must be an exact integer
object in the interval {0,…,232 1}. For bytevector-s32-set!
and bytevector-s32-native-set!, <em>n</em> must be an exact
integer object in the interval {231,…,232 1}.</p>
<p>These retrieve and set four-byte representations of numbers
at indices <em>k</em>,…,<em>k</em> + 3, according to the
endianness specified by <em>endianness</em>. The procedures with
u32 in their names deal with the unsigned representation; those
with s32 with the twos-complement representation.</p>
<p>The procedures with native in their names employ the native
endianness, and work only at aligned indices: <em>k</em> must be
a multiple of 4.</p>
<p>The …-set! procedures return unspecified values.</p>
<p>(<strong>c-bytevector-u64-ref</strong> <em>c-bytevector</em>
<em>k</em> <em>endianness</em>)</br>
(<strong>c-bytevector-s64-ref</strong> <em>c-bytevector</em>
<em>k</em> <em>endianness</em>)</br>
(<strong>c-bytevector-u64-native-ref</strong>
<em>c-bytevector</em> <em>k</em>)</br>
(<strong>c-bytevector-s64-native-ref</strong>
<em>c-bytevector</em> <em>k</em>)</br>
(<strong>c-bytevector-u64-set!</strong> <em>c-bytevector</em>
<em>k</em> <em>n</em> <em>endianness</em>)</br>
(<strong>c-bytevector-s64-set!</strong> <em>c-bytevector</em>
<em>k</em> <em>n</em> <em>endianness</em>)</br>
(<strong>c-bytevector-u64-native-set!</strong>
<em>c-bytevector</em> <em>k</em> <em>n</em>)</br>
(<strong>c-bytevector-s64-native-set!</strong>
<em>c-bytevector</em> <em>k</em> <em>n</em>)</p>
<p><em>K</em>,…,<em>k</em> + 7 must be valid indices of
<em>c-bytevector</em>. For c-bytevector-u64-set! and
c-bytevector-u64-native-set!, <em>n</em> must be an exact
integer object in the interval {0,…,264 1}. For
c-bytevector-s64-set! and c-bytevector-s64-native-set!,
<em>n</em> must be an exact integer object in the interval
{263,…,264 1}.</p>
<p>These retrieve and set eight-byte representations of numbers
at indices <em>k</em>,…,<em>k</em> + 7, according to the
endianness specified by <em>endianness</em>. The procedures with
u64 in their names deal with the unsigned representation; those
with s64 with the twos-complement representation.</p>
<p>The procedures with native in their names employ the native
endianness, and work only at aligned indices: <em>k</em> must be
a multiple of 8.</p>
<p>The …-set! procedures return unspecified values.</p>
<p>(<strong>c-bytevector-ieee-single-native-ref</strong>)</br>
(<strong>c-bytevector-ieee-single-ref</strong>)</br></p>
<p><em>K</em>,…,<em>k</em> + 3 must be valid indices of
<em>c-bytevector</em>. For c-bytevector-ieee-single-native-ref,
<em>k</em> must be a multiple of 4.</p>
<p>These procedures return the inexact real number object that
best represents the IEEE-754 single-precision number represented
by the four bytes beginning at index <em>k</em>.</p>
<p>(<strong>c-bytevector-ieee-double-native-ref</strong>)</br>
(<strong>c-bytevector-ieee-double-ref</strong>)</p>
<p><em>K</em>,…,<em>k</em> + 7 must be valid indices of
<em>c-bytevector</em>. For c-bytevector-ieee-double-native-ref,
<em>k</em> must be a multiple of 8.</p>
<p>These procedures return the inexact real number object that
best represents the IEEE-754 double-precision number represented
by the eight bytes beginning at index <em>k</em>.</p>
<p>(<strong>c-bytevector-ieee-single-native-set!</strong>)</br>
(<strong>c-bytevector-ieee-single-set!</strong>)</p>
<p><em>K</em>,…,<em>k</em> + 3 must be valid indices of
<em>c-bytevector</em>. For c-bytevector-ieee-single-native-set!,
<em>k</em> must be a multiple of 4.</p>
<p>These procedures store an IEEE-754 single-precision
representation of x into elements <em>k</em> through <em>k</em>
+ 3 of bytevector, and return unspecified values.</p>
<p>(<strong>c-bytevector-ieee-double-native-set!</strong>)</br>
(<strong>c-bytevector-ieee-double-set!</strong>)</p>
<p><em>K</em>,…,<em>k</em> + 7 must be valid indices of
bytevector. For c-bytevector-ieee-double-native-set!, <em>k</em>
must be a multiple of 8.</p>
<p>These procedures store an IEEE-754 double-precision
representation of x into elements <em>k</em> through <em>k</em>
+ 7 of bytevector, andreturn unspecified values.</p>
<p>(<strong>string-&gt;c-utf8</strong> <em>string</em>)</p>
<p>Returns a newly allocated (unless empty) c-bytevector that
contains the UTF-8 encoding of the given string.</p>
<p>(<strong>c-utf8-&gt;string</strong>
<em>c-bytevector</em>)</p>
<p>Returns a newly allocated (unless empty) string whose
character sequence is encoded by the given c-bytevector.</p>
<h3 id="environment-variables">Environment variables</h3>
<p>Setting environment variables like this on Windows works for
this library:</p>
<pre><code>set &quot;FOREIGN_C_LOAD_PATH=C:\Program Files (x86)/foo/bar&quot;</code></pre>
<h4 id="foreign_c__load_path">FOREIGN_C__LOAD_PATH</h4>
<p>To add more paths to where foreign c looks for libraries set
FOREIGN_C_LOAD_PATH to paths separated by ; on windows, and : on
other operating systems.</p>
</body>
</html>

View File

@ -10,7 +10,7 @@
(chibi ast)
(scheme inexact)
(chibi))
(include-shared "c/lib/chibi"))
(include-shared "c/primitives/chibi/foreign-c"))
(chicken
(import (scheme base)
(scheme write)

View File

@ -1,9 +1,14 @@
CC=gcc
chibi: primitives/chibi/foreign-c.stub
chibi-ffi primitives/chibi/foreign-c.stub
mkdir -p lib
${CC} -g3 -o lib/chibi.so primitives/chibi/foreign-c.c -fPIC -lffi -shared
chibi: foreign/c/primitives/chibi/foreign-c.stub
chibi-ffi foreign/c/primitives/chibi/foreign-c.stub
${CC} \
-g3 \
-o foreign/c/primitives/chibi/foreign-c.so \
foreign/c/primitives/chibi/foreign-c.c \
-fPIC \
-lffi \
-shared
chicken:
@echo "Nothing to build for Chicken"

32
tests/hello.scm Normal file
View File

@ -0,0 +1,32 @@
(import (scheme base)
(scheme write)
(foreign c))
(cond-expand
(windows (define-c-library c-stdlib
'("stdlib.h")
"ucrtbase"
'()))
(else (define-c-library c-stdlib
'("stdlib.h")
"c"
'((additional-versions ("6"))))))
(define-c-procedure c-system c-stdlib 'system 'int '(pointer))
(define (anything->string item)
(parameterize
((current-output-port (open-output-string)))
(display item)
(get-output-string (current-output-port))))
(define (system command)
(c-system (string->c-utf8
(apply string-append
(map (lambda (item)
(string-append (anything->string item) " "))
command)))))
(system '(ls))