diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/ChangeLog | 10 | ||||
-rw-r--r-- | examples/Makefile.am | 3 | ||||
-rw-r--r-- | examples/README | 18 | ||||
-rw-r--r-- | examples/box-dynamic-module/.cvsignore | 2 | ||||
-rw-r--r-- | examples/box-dynamic-module/Makefile.am | 31 | ||||
-rw-r--r-- | examples/box-dynamic-module/README | 52 | ||||
-rw-r--r-- | examples/box-dynamic-module/box.c | 147 | ||||
-rw-r--r-- | examples/box-dynamic/box.c | 2 | ||||
-rw-r--r-- | examples/box-module/box.c | 2 | ||||
-rw-r--r-- | examples/box/box.c | 2 |
10 files changed, 259 insertions, 10 deletions
diff --git a/examples/ChangeLog b/examples/ChangeLog index fac04cd1b..da7797723 100644 --- a/examples/ChangeLog +++ b/examples/ChangeLog @@ -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> * .cvsignore: here and in all subdirectories listing Makefile and diff --git a/examples/Makefile.am b/examples/Makefile.am index 1b5d3852a..504ba06ff 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -19,6 +19,7 @@ ## to the Free Software Foundation, Inc., 59 Temple Place, Suite ## 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 diff --git a/examples/README b/examples/README index 0c2c7063a..2a362f2cd 100644 --- a/examples/README +++ b/examples/README @@ -5,9 +5,15 @@ programming. See the README files in the subdirectories for details. -scripts Examples for writing simple scripts in Guile Scheme. -box Example for extending Guile with a new data type. -box-module Similar to `box', but define new procedures in a named module. -box-dynamic Implements the box type in a dynamically loadable library. -modules Examples for writing and using Guile modules. -safe Examples for creating and using safe environments. +scripts Examples for writing simple scripts in Guile Scheme. +box Example for extending Guile with a new data type. +box-module Similar to `box', but defines new procedures in a + named module. +box-dynamic Implements the box type in a dynamically loadable + 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. + diff --git a/examples/box-dynamic-module/.cvsignore b/examples/box-dynamic-module/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/examples/box-dynamic-module/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/examples/box-dynamic-module/Makefile.am b/examples/box-dynamic-module/Makefile.am new file mode 100644 index 000000000..16465c814 --- /dev/null +++ b/examples/box-dynamic-module/Makefile.am @@ -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 $<
\ No newline at end of file diff --git a/examples/box-dynamic-module/README b/examples/box-dynamic-module/README new file mode 100644 index 000000000..a3cb32496 --- /dev/null +++ b/examples/box-dynamic-module/README @@ -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) +$ diff --git a/examples/box-dynamic-module/box.c b/examples/box-dynamic-module/box.c new file mode 100644 index 000000000..166610248 --- /dev/null +++ b/examples/box-dynamic-module/box.c @@ -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. */ diff --git a/examples/box-dynamic/box.c b/examples/box-dynamic/box.c index 6c6151cee..8872a6163 100644 --- a/examples/box-dynamic/box.c +++ b/examples/box-dynamic/box.c @@ -34,7 +34,7 @@ static SCM mark_box (SCM b) { /* 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); } diff --git a/examples/box-module/box.c b/examples/box-module/box.c index 2065466fc..cf6542593 100644 --- a/examples/box-module/box.c +++ b/examples/box-module/box.c @@ -34,7 +34,7 @@ static SCM mark_box (SCM b) { /* 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); } diff --git a/examples/box/box.c b/examples/box/box.c index a928c0ef3..6c972b86b 100644 --- a/examples/box/box.c +++ b/examples/box/box.c @@ -34,7 +34,7 @@ static SCM mark_box (SCM b) { /* 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); } |