mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-24 20:30:28 +02:00
* box-dynamic-module: New directory, implements the box type in a
shared library and places the definitions in a C-only module. Thanks to Thomas Wawrzinek for this, too! * box-dynamic/box.c, box/box.c, box-dynamic-module/box.c, box-module/box.c (mark_box): Fixed typo in comment.
This commit is contained in:
parent
71c771efdf
commit
8779d59588
10 changed files with 259 additions and 10 deletions
|
@ -1,3 +1,13 @@
|
||||||
|
2001-06-05 Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
|
||||||
|
|
||||||
|
* box-dynamic-module: New directory, implements the box type in a
|
||||||
|
shared library and places the definitions in a C-only module.
|
||||||
|
|
||||||
|
Thanks to Thomas Wawrzinek for this, too!
|
||||||
|
|
||||||
|
* box-dynamic/box.c, box/box.c, box-dynamic-module/box.c,
|
||||||
|
box-module/box.c (mark_box): Fixed typo in comment.
|
||||||
|
|
||||||
2001-06-01 Rob Browning <rlb@cs.utexas.edu>
|
2001-06-01 Rob Browning <rlb@cs.utexas.edu>
|
||||||
|
|
||||||
* .cvsignore: here and in all subdirectories listing Makefile and
|
* .cvsignore: here and in all subdirectories listing Makefile and
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
## to the Free Software Foundation, Inc., 59 Temple Place, Suite
|
## to the Free Software Foundation, Inc., 59 Temple Place, Suite
|
||||||
## 330, Boston, MA 02111-1307 USA
|
## 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
SUBDIRS = scripts box box-module box-dynamic modules safe
|
SUBDIRS = scripts box box-module box-dynamic box-dynamic-module\
|
||||||
|
modules safe
|
||||||
|
|
||||||
EXTRA_DIST = README
|
EXTRA_DIST = README
|
||||||
|
|
|
@ -5,9 +5,15 @@ programming.
|
||||||
|
|
||||||
See the README files in the subdirectories for details.
|
See the README files in the subdirectories for details.
|
||||||
|
|
||||||
scripts Examples for writing simple scripts in Guile Scheme.
|
scripts Examples for writing simple scripts in Guile Scheme.
|
||||||
box Example for extending Guile with a new data type.
|
box Example for extending Guile with a new data type.
|
||||||
box-module Similar to `box', but define new procedures in a named module.
|
box-module Similar to `box', but defines new procedures in a
|
||||||
box-dynamic Implements the box type in a dynamically loadable library.
|
named module.
|
||||||
modules Examples for writing and using Guile modules.
|
box-dynamic Implements the box type in a dynamically loadable
|
||||||
safe Examples for creating and using safe environments.
|
library.
|
||||||
|
box-dynamic-module Combination of `box-module' and `box-dynamic':
|
||||||
|
Implements the `box' type in a shared library and
|
||||||
|
defines the procedures in a Guile module.
|
||||||
|
modules Examples for writing and using Guile modules.
|
||||||
|
safe Examples for creating and using safe environments.
|
||||||
|
|
||||||
|
|
2
examples/box-dynamic-module/.cvsignore
Normal file
2
examples/box-dynamic-module/.cvsignore
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Makefile
|
||||||
|
Makefile.in
|
31
examples/box-dynamic-module/Makefile.am
Normal file
31
examples/box-dynamic-module/Makefile.am
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
## Process this file with Automake to create Makefile.in
|
||||||
|
##
|
||||||
|
## Copyright (C) 2001 Free Software Foundation, Inc.
|
||||||
|
##
|
||||||
|
## This file is part of GUILE.
|
||||||
|
##
|
||||||
|
## GUILE is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as
|
||||||
|
## published by the Free Software Foundation; either version 2, or
|
||||||
|
## (at your option) any later version.
|
||||||
|
##
|
||||||
|
## GUILE 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 General Public License for more details.
|
||||||
|
##
|
||||||
|
## You should have received a copy of the GNU General Public
|
||||||
|
## License along with GUILE; see the file COPYING. If not, write
|
||||||
|
## to the Free Software Foundation, Inc., 59 Temple Place, Suite
|
||||||
|
## 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
EXTRA_DIST = README box.c
|
||||||
|
|
||||||
|
CFLAGS=`guile-config compile`
|
||||||
|
LIBS=`guile-config link`
|
||||||
|
|
||||||
|
libbox-module: box.lo
|
||||||
|
sh ../../libtool --mode=link $(CC) $< $(LIBS) -rpath $(prefix)/lib -o libbox-module.la
|
||||||
|
|
||||||
|
box.lo: box.c
|
||||||
|
sh ../../libtool --mode=compile $(CC) $(CFLAGS) -c $<
|
52
examples/box-dynamic-module/README
Normal file
52
examples/box-dynamic-module/README
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
-*- text -*-
|
||||||
|
|
||||||
|
This directory includes an example program for extending Guile with a
|
||||||
|
new (and even useful) data type, putting it into a shared library, so it
|
||||||
|
can be called from an unmodified guile interpreter. Further, the shared
|
||||||
|
library defines a new guile module.
|
||||||
|
|
||||||
|
To build the example, simply type
|
||||||
|
|
||||||
|
make libbox-module
|
||||||
|
|
||||||
|
in this directory.
|
||||||
|
|
||||||
|
A box is simply an object for storing one other object in. It can be
|
||||||
|
used for passing parameters by reference, for example. You simply
|
||||||
|
store an object into a box, pass it to another procedure which can
|
||||||
|
store a new object into it and thus return a value via the box.
|
||||||
|
|
||||||
|
Box objects are created with `make-box', set with `box-set!' and
|
||||||
|
examined with `box-ref'. Note that these procedures are placed in a
|
||||||
|
module called (box-module) and can thus only be accessed after using
|
||||||
|
this module. See the following example session for usage details:
|
||||||
|
|
||||||
|
Extend your LD_LIBRARY_PATH variable (or equivalent) to include . and
|
||||||
|
.libs
|
||||||
|
|
||||||
|
If you like this example so much that you want to have it available
|
||||||
|
for normal usage, install the dynamic libraries in the .libs directory
|
||||||
|
to the directory $(prefix)/lib
|
||||||
|
|
||||||
|
Note that after loading the extension, an explicit call to use-modules
|
||||||
|
is needed to make the exported procedures available.
|
||||||
|
|
||||||
|
$ guile
|
||||||
|
guile> (load-extension "libbox-module" "scm_init_box")
|
||||||
|
guile> make-box
|
||||||
|
<unnamed port>: In expression make-box:
|
||||||
|
<unnamed port>: Unbound variable: make-box
|
||||||
|
ABORT: (unbound-variable)
|
||||||
|
|
||||||
|
Type "(backtrace)" to get more information or "(debug)" to enter the debugger.
|
||||||
|
guile> (use-modules (box-module))
|
||||||
|
guile> (define b (make-box))
|
||||||
|
guile> b
|
||||||
|
#<box #f>
|
||||||
|
guile> (box-set! b '(list of values))
|
||||||
|
guile> b
|
||||||
|
#<box (list of values)>
|
||||||
|
guile> (box-ref b)
|
||||||
|
(list of values)
|
||||||
|
guile> (quit)
|
||||||
|
$
|
147
examples/box-dynamic-module/box.c
Normal file
147
examples/box-dynamic-module/box.c
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
/* examples/box-dynamic-module/box.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 1998,2001 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this software; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||||
|
* Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Include all needed declarations. */
|
||||||
|
#include <libguile.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* The type code for the newly created smob type will be stored into
|
||||||
|
this variable. It has the prefix `scm_tc16_' to make it usable
|
||||||
|
with the SCM_VALIDATE_SMOB macro below. */
|
||||||
|
static scm_bits_t scm_tc16_box;
|
||||||
|
|
||||||
|
|
||||||
|
/* This function is responsible for marking all SCM objects included
|
||||||
|
in the smob. */
|
||||||
|
static SCM
|
||||||
|
mark_box (SCM b)
|
||||||
|
{
|
||||||
|
/* Since we have only one SCM object to protect, we simply return it
|
||||||
|
and the caller will mark it. */
|
||||||
|
return SCM_CELL_OBJECT_1 (b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Print a textual represenation of the smob to a given port. */
|
||||||
|
static int
|
||||||
|
print_box (SCM b, SCM port, scm_print_state *pstate)
|
||||||
|
{
|
||||||
|
SCM value = SCM_CELL_OBJECT_1 (b);
|
||||||
|
|
||||||
|
scm_puts ("#<box ", port);
|
||||||
|
scm_write (value, port);
|
||||||
|
scm_puts (">", port);
|
||||||
|
|
||||||
|
/* Non-zero means success. */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This defines the primitve `make-box', which returns a new smob of
|
||||||
|
type `box', initialized to `#f'. */
|
||||||
|
static SCM
|
||||||
|
#define FUNC_NAME "make-box"
|
||||||
|
make_box (void)
|
||||||
|
{
|
||||||
|
/* This macro creates the new objects, stores the value `#f' into it
|
||||||
|
and returns it to the caller. */
|
||||||
|
SCM_RETURN_NEWSMOB (scm_tc16_box, SCM_BOOL_F);
|
||||||
|
}
|
||||||
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
|
||||||
|
/* This is the primitive `box-ref' which returns the object stored in
|
||||||
|
the box. */
|
||||||
|
static SCM
|
||||||
|
box_ref (SCM b)
|
||||||
|
#define FUNC_NAME "box-ref"
|
||||||
|
{
|
||||||
|
/* First, we have to ensure that the user really gave us a box
|
||||||
|
objects. The macro SCM_VALIDATE_SMOB will do all what is needed.
|
||||||
|
The parameters are interpreted as follows:
|
||||||
|
|
||||||
|
1: The position of the checked variable in the parameter list.
|
||||||
|
b: The passed parameter.
|
||||||
|
box: Concatenated with the fixed prefix scm_tc16_, names the type
|
||||||
|
code for the expected smob type. */
|
||||||
|
SCM_VALIDATE_SMOB (1, b, box);
|
||||||
|
|
||||||
|
/* Fetch the object from the box and return it. */
|
||||||
|
return SCM_CELL_OBJECT_1 (b);
|
||||||
|
}
|
||||||
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
|
||||||
|
/* Primitive which stores an arbitrary value into a box. */
|
||||||
|
static SCM
|
||||||
|
box_set_x (SCM b, SCM value)
|
||||||
|
#define FUNC_NAME "box-set!"
|
||||||
|
{
|
||||||
|
SCM_VALIDATE_SMOB (1, b, box);
|
||||||
|
|
||||||
|
/* Set the cell number 1 of the smob to the given value. */
|
||||||
|
SCM_SET_CELL_OBJECT_1 (b, value);
|
||||||
|
|
||||||
|
/* When this constant is returned, the REPL will not print the
|
||||||
|
returned value. All procedures in Guile which are documented as
|
||||||
|
returning `and unspecified value' actually return this value. */
|
||||||
|
return SCM_UNSPECIFIED;
|
||||||
|
}
|
||||||
|
#undef FUNC_NAME
|
||||||
|
|
||||||
|
|
||||||
|
/* Create and initialize the new smob type, and register the
|
||||||
|
primitives withe the interpreter library.
|
||||||
|
|
||||||
|
This function must be declared a bit different from the example in
|
||||||
|
the ../box directory, because it will be called by
|
||||||
|
`scm_c_define_module', called from below. */
|
||||||
|
static void
|
||||||
|
init_box_type (void * unused)
|
||||||
|
{
|
||||||
|
scm_tc16_box = scm_make_smob_type ("box", 0);
|
||||||
|
scm_set_smob_mark (scm_tc16_box, mark_box);
|
||||||
|
scm_set_smob_print (scm_tc16_box, print_box);
|
||||||
|
|
||||||
|
scm_c_define_gsubr ("make-box", 0, 0, 0, make_box);
|
||||||
|
scm_c_define_gsubr ("box-set!", 2, 0, 0, box_set_x);
|
||||||
|
scm_c_define_gsubr ("box-ref", 1, 0, 0, box_ref);
|
||||||
|
|
||||||
|
/* This is new too: Since the procedures are now in a module, we
|
||||||
|
have to explicitly export them before they can be used. */
|
||||||
|
scm_c_export ("make-box", "box-set!", "box-ref", NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is the function which must be given to `load-extension' as the
|
||||||
|
second argument. It will initialize the shared, library, but will
|
||||||
|
place the definitions in a module called (box-module), so that an
|
||||||
|
additional (use-modules (box-module)) is needed to make them
|
||||||
|
accessible. */
|
||||||
|
void
|
||||||
|
scm_init_box ()
|
||||||
|
{
|
||||||
|
/* Unlike the example in ../box, init_box_type is not called
|
||||||
|
directly, but by scm_c_define_module, which will create a module
|
||||||
|
named (box-module) and make this module current while called
|
||||||
|
init_box_type, thus placing the definitions into that module. */
|
||||||
|
scm_c_define_module ("box-module", init_box_type, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End of file. */
|
|
@ -34,7 +34,7 @@ static SCM
|
||||||
mark_box (SCM b)
|
mark_box (SCM b)
|
||||||
{
|
{
|
||||||
/* Since we have only one SCM object to protect, we simply return it
|
/* Since we have only one SCM object to protect, we simply return it
|
||||||
and the caller with mark it. */
|
and the caller will mark it. */
|
||||||
return SCM_CELL_OBJECT_1 (b);
|
return SCM_CELL_OBJECT_1 (b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ static SCM
|
||||||
mark_box (SCM b)
|
mark_box (SCM b)
|
||||||
{
|
{
|
||||||
/* Since we have only one SCM object to protect, we simply return it
|
/* Since we have only one SCM object to protect, we simply return it
|
||||||
and the caller with mark it. */
|
and the caller will mark it. */
|
||||||
return SCM_CELL_OBJECT_1 (b);
|
return SCM_CELL_OBJECT_1 (b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ static SCM
|
||||||
mark_box (SCM b)
|
mark_box (SCM b)
|
||||||
{
|
{
|
||||||
/* Since we have only one SCM object to protect, we simply return it
|
/* Since we have only one SCM object to protect, we simply return it
|
||||||
and the caller with mark it. */
|
and the caller will mark it. */
|
||||||
return SCM_CELL_OBJECT_1 (b);
|
return SCM_CELL_OBJECT_1 (b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue