* box-dynamic: New directory, implements the box type in a shared
authorMartin Grabmüller <mgrabmue@cs.tu-berlin.de>
Thu, 31 May 2001 18:24:11 +0000 (18:24 +0000)
committerMartin Grabmüller <mgrabmue@cs.tu-berlin.de>
Thu, 31 May 2001 18:24:11 +0000 (18:24 +0000)
library (aka extension)

Thanks to Thomas Wawrzinek for patching box.c into an extension!

examples/ChangeLog
examples/Makefile.am
examples/README
examples/box-dynamic/Makefile.am [new file with mode: 0644]
examples/box-dynamic/README [new file with mode: 0644]
examples/box-dynamic/box.c [new file with mode: 0644]

index 64a1976..5549fa5 100644 (file)
@@ -1,3 +1,10 @@
+2001-05-31  Martin Grabmueller  <mgrabmue@cs.tu-berlin.de>
+
+       * box-dynamic: New directory, implements the box type in a shared
+       library (aka extension)
+
+       Thanks to Thomas Wawrzinek for patching box.c into an extension!
+       
 2001-05-30  Martin Grabmueller  <mgrabmue@cs.tu-berlin.de>
 
        * box-module: New directory, similar to box, but defines the
index c0955a1..1b5d385 100644 (file)
@@ -19,6 +19,6 @@
 ##   to the Free Software Foundation, Inc., 59 Temple Place, Suite
 ##   330, Boston, MA 02111-1307 USA
 
-SUBDIRS = scripts box box-module modules safe
+SUBDIRS = scripts box box-module box-dynamic modules safe
 
 EXTRA_DIST = README
index ff9f3b2..0c2c706 100644 (file)
@@ -1,6 +1,6 @@
                                                               -*- text -*-
 
-This directory includes examples illustrating various aspects of Guile
+This directory contains examples illustrating various aspects of Guile
 programming.
 
 See the README files in the subdirectories for details.
@@ -8,5 +8,6 @@ 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.
diff --git a/examples/box-dynamic/Makefile.am b/examples/box-dynamic/Makefile.am
new file mode 100644 (file)
index 0000000..7bb9f46
--- /dev/null
@@ -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: box.lo
+       sh ../../libtool --mode=link $(CC) $< $(LIBS) -rpath $(prefix)/lib -o libbox.la
+
+box.lo: box.c
+       sh ../../libtool --mode=compile $(CC) $(CFLAGS) -c $< 
\ No newline at end of file
diff --git a/examples/box-dynamic/README b/examples/box-dynamic/README
new file mode 100644 (file)
index 0000000..561e484
--- /dev/null
@@ -0,0 +1,41 @@
+                                                              -*- 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.
+
+To build the example, simply type
+
+  make libbox
+
+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
+
+$ ./guile
+guile> (load-extension "libbox" "scm_init_box")
+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/box.c b/examples/box-dynamic/box.c
new file mode 100644 (file)
index 0000000..6c6151c
--- /dev/null
@@ -0,0 +1,128 @@
+/* examples/box-dynamic/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 with 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 with the interpreter library.
+   
+   To be called with (load-extension "libbox" "scm_init_box")
+   from a script.
+*/
+void
+scm_init_box ()
+{
+  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);
+}
+
+/* End of file.  */