* guile-snarf-docs.in, guile-snarf-docs-texi.in,
authorMichael Livshin <mlivshin@bigfoot.com>
Thu, 31 May 2001 13:15:54 +0000 (13:15 +0000)
committerMichael Livshin <mlivshin@bigfoot.com>
Thu, 31 May 2001 13:15:54 +0000 (13:15 +0000)
filter-doc-snarfage.c: new files.

* Makefile.am: add stuff to [build,] use and distribute
guile-snarf-docs, guile-snarf-docs-texi, guile_filter_doc_snarfage.

* guile-snarf.in: grok the new snarf output.

* snarf.h: make the output both texttools- and `read'-friendly.

* guile-doc-snarf.in (bindir): reimplement in terms of guile-snarf
and guile-snarf-docs.  (should also deprecate, I guess.  maybe
not).

libguile/ChangeLog
libguile/Makefile.am
libguile/filter-doc-snarfage.c [new file with mode: 0644]
libguile/guile-doc-snarf.in
libguile/guile-snarf-docs-texi.in [new file with mode: 0755]
libguile/guile-snarf-docs.in [new file with mode: 0755]
libguile/guile-snarf.in
libguile/snarf.h

index 10948b7..f24f54e 100644 (file)
@@ -1,3 +1,19 @@
+2001-05-31  Michael Livshin  <mlivshin@bigfoot.com>
+
+       * guile-snarf-docs.in, guile-snarf-docs-texi.in,
+       filter-doc-snarfage.c: new files.
+
+       * Makefile.am: add stuff to [build,] use and distribute
+       guile-snarf-docs, guile-snarf-docs-texi, guile_filter_doc_snarfage.
+
+       * guile-snarf.in: grok the new snarf output.
+
+       * snarf.h: make the output both texttools- and `read'-friendly.
+
+       * guile-doc-snarf.in (bindir): reimplement in terms of guile-snarf
+       and guile-snarf-docs.  (should also deprecate, I guess.  maybe
+       not).
+
 2001-05-31  Marius Vollmer  <mvo@zagadka.ping.de>
 
        * print.c (scm_simple_format): Support "~~" and "~%".  Signal
index 5a8cc58..baf34f5 100644 (file)
@@ -32,12 +32,14 @@ ETAGS_ARGS = --regex='/SCM_\(GLOBAL_\)?\(G?PROC\|G?PROC1\|SYMBOL\|VCELL\|CONST_L
    --regex='/[ \t]*SCM_[G]?DEFINE1?[ \t]*(\([^,]*\),[^,]*/\1/'
 
 lib_LTLIBRARIES = libguile.la
-bin_PROGRAMS = guile
+bin_PROGRAMS = guile guile_filter_doc_snarfage
 
 guile_SOURCES = guile.c
 guile_LDADD = libguile.la ${THREAD_LIBS_LOCAL}
 guile_LDFLAGS = @DLPREOPEN@
 
+guile_filter_doc_snarfage_SOURCES = filter-doc-snarfage.c
+
 libguile_la_SOURCES = alist.c arbiters.c async.c backtrace.c boolean.c     \
     chars.c continuations.c debug.c deprecation.c dynl.c dynwind.c         \
     environments.c eq.c error.c eval.c evalext.c extensions.c              \
@@ -87,7 +89,7 @@ DOT_DOC_FILES = alist.doc arbiters.doc async.doc backtrace.doc                    \
 EXTRA_DOT_DOC_FILES = @EXTRA_DOT_DOC_FILES@
 
 BUILT_SOURCES = cpp_err_symbols.c cpp_sig_symbols.c libpath.h scmconfig.h \
-    $(DOT_X_FILES) $(EXTRA_DOT_X_FILES) $(DOT_DOC_FILES)
+    $(DOT_X_FILES) $(EXTRA_DOT_X_FILES)
 
 EXTRA_libguile_la_SOURCES = _scm.h                     \
     alloca.c inet_aton.c memmove.c putenv.c strerror.c \
@@ -95,6 +97,8 @@ EXTRA_libguile_la_SOURCES = _scm.h                    \
     filesys.c posix.c net_db.c socket.c                        \
     ramap.c unif.c debug-malloc.c
 
+Makefile: $(DOT_X_FILES)
+
 ## In next release, threads will be factored out of libguile.
 ## Until then, the machine specific headers is a temporary kludge.
 OMIT_DEPENDENCIES = libguile.h ltdl.h \
@@ -133,10 +137,13 @@ modinclude_HEADERS = __scm.h alist.h arbiters.h async.h backtrace.h boolean.h \
 ## and not a header -- headers are included in the distribution.
 modinclude_DATA = scmconfig.h
 
-bin_SCRIPTS = guile-snarf guile-doc-snarf guile-snarf.awk guile-func-name-check
+bin_SCRIPTS = guile-snarf guile-doc-snarf guile-snarf-docs \
+    guile-snarf-docs-texi guile-func-name-check
 
 EXTRA_DIST = ChangeLog-gh ChangeLog-scm ChangeLog-threads cpp_signal.c \
     cpp_errno.c cpp_err_symbols.in cpp_sig_symbols.in cpp_cnvt.awk
+#    $(DOT_DOC_FILES) $(EXTRA_DOT_DOC_FILES) \
+#    guile-procedures.txt guile.texi
 
 ## FIXME: Consider using timestamp file, to avoid unnecessary rebuilds.
 libpath.h: $(srcdir)/Makefile.in  $(top_builddir)/config.status
@@ -178,22 +185,24 @@ libpath.h: $(srcdir)/Makefile.in  $(top_builddir)/config.status
 
 SUFFIXES = .x .doc
 .c.x:
-       ./guile-doc-snarf $< $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $< > $@ \
+       ./guile-snarf $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $< > $@ \
        || { rm $@; false; }
-.x.doc:
-       ./guile-doc-snarf $(srcdir)/$*.c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(srcdir)/$*.c > /dev/null \
+.c.doc:
+       -(test -n "${AWK+set}" || AWK="@AWK@"; ${AWK} -f ./guile-func-name-check $<)
+       ./guile-snarf-docs $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $< > $@ \
         || { rm $@; false; }
 
-*.x: snarf.h guile-doc-snarf.in
-*.doc: guile-snarf.awk.in
+$(DOT_X_FILES) $(EXTRA_DOT_DOC_FILES): snarf.h guile-snarf.in
+
+$(DOT_DOC_FILES) $(EXTRA_DOT_DOC_FILES): snarf.h guile-snarf-docs.in guile_filter_doc_snarfage
 
 error.x: cpp_err_symbols.c
 posix.x: cpp_sig_symbols.c
 load.x: libpath.h
 
-guile.texi: $(DOT_DOC_FILES) $(EXTRA_DOT_DOC_FILES)
-       echo "@paragraphindent 0" > $@
-       cat *.doc >> $@
+guile.texi: $(DOT_DOC_FILES) $(EXTRA_DOT_DOC_FILES) guile-snarf-docs-texi.in guile
+       ./guile-snarf-docs-texi $(DOT_DOC_FILES) $(EXTRA_DOT_DOC_FILES) > $@ \
+       || { rm $@; false; }
 
 guile-procedures.txt: guile.texi
        rm -f $@
@@ -250,4 +259,4 @@ MOSTLYCLEANFILES = \
        cpp_err_symbols_here cpp_err_symbols_diff cpp_err_symbols_new \
        cpp_sig_symbols_here cpp_sig_symbols_diff cpp_sig_symbols_new
 
-CLEANFILES = libpath.h *.x *.doc
+CLEANFILES = libpath.h *.x *.doc guile-procedures.txt guile.texi
diff --git a/libguile/filter-doc-snarfage.c b/libguile/filter-doc-snarfage.c
new file mode 100644 (file)
index 0000000..c403b0e
--- /dev/null
@@ -0,0 +1,234 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+static void init_state_machine (void);
+
+static void process (void);
+
+static void check_end_conditions (void);
+
+int
+main (int argc, char *argv[])
+{
+  init_state_machine ();
+  process ();
+  check_end_conditions ();
+    
+  return EXIT_SUCCESS;
+}
+
+typedef enum state_t
+  {
+    SKIP,
+    SKIP_COOKIE,
+        
+    MULTILINE,
+
+    MULTILINE_COOKIE,
+    STRINGS,
+
+    SINGLELINE,
+
+  } state_t;
+
+state_t state = SKIP;
+
+static void die (const char *msg);
+static void process_strings (void);
+static void process_single_line (void);
+
+void
+process ()
+{
+  int want_cookie = 0;
+  int ch;
+  
+  while ((ch = getc (stdin)) != EOF) {
+    char c = (char)ch;
+
+    switch (state) {
+    case SKIP:
+      if (c == '^') {
+        if (want_cookie) {
+          state = SKIP_COOKIE;
+          want_cookie = 0;
+        } else
+          want_cookie = 1;
+      } else
+        want_cookie = 0;
+      break;
+    case SKIP_COOKIE:
+      switch (c) {
+      case '[':
+        fputs ("(doc-check\n", stdout);
+        state = SINGLELINE;
+        break;
+      case '{':
+        fputs ("(doc-block (\n", stdout);
+        state = MULTILINE;
+        break;
+      default:
+        die ("bad snarf cookie");
+        break;
+      }
+      break;
+    case MULTILINE:
+      if (c == '^') {
+        if (want_cookie) {
+          fputs ("\n)\n(\n", stdout);
+          state = MULTILINE_COOKIE;
+          want_cookie = 0;
+        } else
+          want_cookie = 1;
+      } else {
+        want_cookie = 0;
+        putc (c, stdout);
+      }
+      break;
+    case MULTILINE_COOKIE:
+      switch (c) {
+      case '(':
+        state = STRINGS;
+        break;
+      case ' ':
+        state = MULTILINE;
+        break;
+      case '}':
+        fputs ("))\n", stdout);
+        state = SKIP;
+        break;
+      default:
+        die ("bad snarf cookie in multiline context");
+        break;
+      }
+      break;
+    case STRINGS:
+      process_strings ();
+      state = MULTILINE;
+      break;
+    case SINGLELINE:
+      process_single_line ();
+      fputs ("\n)\n", stdout);
+      state = SKIP;
+      break;
+    default:
+      abort ();
+      break;
+    }
+  }
+}
+
+void
+init_state_machine ()
+{}
+
+void
+die (const char *msg)
+{
+  fprintf (stderr, "%s\n", msg);
+  exit (EXIT_FAILURE);
+}
+
+void
+check_end_conditions ()
+{
+  if (state != SKIP)
+    die ("something is unterminated");
+}
+
+typedef enum str_state_t
+  {
+    STR_SKIP,
+    STR_INSIDE,
+    STR_HAD_ESCAPE,
+    STR_EXIT
+  } str_state_t;
+
+void
+process_strings ()
+{
+  /* read well-formed strings up to a ')', and break them up in the
+     process if they are too long */
+  int count = 0;
+  int ch;
+  str_state_t state = STR_SKIP;
+
+  fputs ("docstring\n", stdout);
+
+#define PUTC(c) putc (c, stdout); if (++count >= 512) { fputs ("\"\nstring \"", stdout); count = 0; }
+
+  while (!(((ch = getc (stdin)) == EOF)
+           || (state == STR_EXIT))) {
+    char c = (char) ch;
+
+    switch (state) {
+    case STR_SKIP:
+      switch (c) {
+      case '"':
+        fputs ("\nstring ", stdout);
+        count = 0;
+        PUTC (c);
+        state = STR_INSIDE;
+        break;
+      case ')':
+        state = STR_EXIT;
+        break;
+      default:
+        if (!isspace (c))
+          die ("stray stuff where should be only strings");
+        break;
+      }
+      break;
+    case STR_INSIDE:
+      switch (c) {
+      case '\\':
+        putc (c, stdout);
+        ++count;
+        state = STR_HAD_ESCAPE;
+        break;
+      case '"':
+        putc (c, stdout);
+        state = STR_SKIP;
+        break;
+      default:
+        PUTC (c);
+        break;
+      }
+      break;
+    case STR_HAD_ESCAPE:
+      PUTC (c);
+      state = STR_INSIDE;
+      break;
+    default:
+      abort ();
+      break;
+    }
+  }
+
+  if (state != STR_EXIT)
+    die ("docstrings don't terminate");
+}
+
+void
+process_single_line ()
+{
+  /* read up to a ']' */
+  int ch;
+  while (!(((ch = getc (stdin)) == EOF)
+           || ((char) ch == ']'))) {
+    char c = (char) ch;
+
+    putc (c, stdout);
+  }
+
+  if ((char) ch != ']')
+    die ("bad checking snarfage");
+}
+
+
+/*
+  Local Variables:
+  c-file-style: "gnu"
+  End:
+*/
index 9540755..36e1a94 100755 (executable)
 # the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 # Boston, MA 02111-1307 USA
 
-fullfilename=$1; shift
+fullfilename=$1
 
 # strip path to source directory
 filename=`basename $fullfilename`
 
-# we need to be sure that the .x file exists
-# since the .c/.cc file may include it
-# (the old guile-snarf did not have this problem
-#  because the makefile redirects output to the .x file
-#  which creates the file before the inclusion occurs)
-# --12/12/99 gjb
 no_ext=`echo $filename | sed 's/\.[^.]*$//g'`
 dot_doc=${no_ext}.doc
 
-temp="/tmp/snarf.$$"
-trap "rm -f $temp" 0 1 2 15
+bindir=`dirname $0`
 
-## Let the user override the preprocessor & awk autoconf found.
-test -n "${CPP+set}" || CPP="@CPP@"
-test -n "${AWK+set}" || AWK="@AWK@"
+${bindir}/guile-snarf-docs "$@" > $dot_doc
 
-## Must run guile-func-name-check on the unpreprocessed source
-${AWK} -f `dirname $0`/guile-func-name-check "$fullfilename"
-
-## We must use a temporary file here, instead of a pipe, because we
-## need to know if CPP exits with a non-zero status.
-${CPP} -DSCM_MAGIC_SNARFER "$@" > ${temp} || exit $?
-cut -c1-1023 ${temp} | ${AWK} -f `dirname $0`/guile-snarf.awk ${dot_doc}
+${bindir}/guile-snarf "$@"
 
 # guile-doc-snarf ends here
diff --git a/libguile/guile-snarf-docs-texi.in b/libguile/guile-snarf-docs-texi.in
new file mode 100755 (executable)
index 0000000..2dbc4ae
--- /dev/null
@@ -0,0 +1,60 @@
+#!/bin/sh
+# Massage the snarfed docs to texinfo.
+#
+#  Copyright (C) 1996, 1997, 1998, 1999, 2000 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
+
+srcdir=@srcdir@
+bindir=`dirname $0`
+
+bindir=`(cd $bindir; pwd)`
+srcdir=`(cd $srcdir; pwd)`
+
+temp0="/tmp/snarf.0.$$"
+temp1="/tmp/snarf.1.$$"
+trap "rm -f $temp0 $temp1" 0 1 2 15
+
+# cat all the small files together:
+cat "$@" > ${temp1}
+
+## massage the arglists
+
+# lose the SCM types and commas, and texi-quote @'s in names and args
+< ${temp1} sed -e '/^arglist/s/[       ]*SCM[  ]*//g' \
+               -e '/^arglist/s/,/ /g' \
+               -e '/^arglist/s/([      ]*void[         ]*)/()/g' \
+               -e '/^fname/s/@/@@/g' \
+               -e '/^arglist/s/@/@@/g' \
+           > ${temp0}
+
+# nothing to do with the docstrings
+< ${temp0} sed -e 's/^string //' > ${temp1}
+
+# we're too lame to check argpos assertions other then for straight names, so...
+< ${temp1} sed -e 's/^argpos.*[(\[].*//' > ${temp0}
+
+echo "@paragraphindent 0"
+
+# now run the script that will generate texinfo
+main='(module-ref (resolve-module '\''(scripts snarf-check-and-output-texi)) '\''main)'
+apply_main="(apply $main (cdr (command-line)))"
+
+if [ `basename ${bindir}` = libguile ]; then
+   GUILE_LOAD_PATH=${srcdir}/.. ${bindir}/guile -c "${apply_main}" < ${temp0}
+else
+   ${bindir}/guile -c "${apply_main}" < ${temp0}
+fi
diff --git a/libguile/guile-snarf-docs.in b/libguile/guile-snarf-docs.in
new file mode 100755 (executable)
index 0000000..338b710
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/sh
+# Extract the doc stuff for builtin things.
+#
+#  Copyright (C) 1996, 1997, 1998, 1999, 2000 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
+
+bindir=`dirname $0`
+
+temp="/tmp/snarf.$$"
+trap "rm -f $temp" 0 1 2 15
+
+## Let the user override the preprocessor autoconf found.
+test -n "${CPP+set}" || CPP="@CPP@"
+
+## We must use a temporary file here, instead of a pipe, because we
+## need to know if CPP exits with a non-zero status.
+${CPP} -DSCM_MAGIC_SNARF_DOCS "$@" > ${temp} || exit $?
+< ${temp} ${bindir}/guile_filter_doc_snarfage
index d41f34c..41542dc 100644 (file)
@@ -26,8 +26,8 @@ test -n "${CPP+set}" || CPP="@CPP@"
 
 ## We must use a temporary file here, instead of a pipe, because we
 ## need to know if CPP exits with a non-zero status.
-${CPP} -DSCM_MAGIC_SNARFER "$@" > ${temp} || exit $?
-< ${temp} grep "^ *SCM_SNARF_INIT_START" | sed -e "s/^ *SCM_SNARF_INIT_START//" -e 's/SCM_SNARF_DOC_START.*$//g'
+${CPP} -DSCM_MAGIC_SNARF_INITS "$@" > ${temp} || exit $?
+< ${temp} grep "^ *\^\^" | sed -e "s/^ *\^\^//"
 
 ## Apparently, AIX's preprocessor is unhappy if you try to #include an
 ## empty file.
index ac7a59b..045e634 100644 (file)
  * line, if any.
  */
 
-#ifndef SCM_MAGIC_SNARFER
-#  define SCM_SNARF_HERE(X) X
-#  define SCM_SNARF_INIT(X)
-#  define SCM_SNARF_DOCS(X)
+#ifdef SCM_MAGIC_SNARF_INITS
+# define SCM_SNARF_HERE(X)
+# define SCM_SNARF_INIT(X) ^^ X
+# define SCM_SNARF_DOCS(TYPE, FNAME, ARGLIST, REQ, OPT, VAR, DOCSTRING)
 #else
+# ifdef SCM_MAGIC_SNARF_DOCS
 #  define SCM_SNARF_HERE(X)
-#  define SCM_SNARF_INIT(X) SCM_SNARF_INIT_START X
-#  define SCM_SNARF_DOCS(X) X
+#  define SCM_SNARF_INIT(X)
+#  define SCM_SNARF_DOCS(TYPE, FNAME, ARGLIST, REQ, OPT, VAR, DOCSTRING) \
+^^{ \
+^^ fname . FNAME \
+^^ type . TYPE \
+^^ location __FILE__ . __LINE__ \
+^^ arglist . ARGLIST \
+^^ argsig REQ OPT VAR \
+^^(DOCSTRING) \
+^^}
+# else
+#  define SCM_SNARF_HERE(X) X
+#  define SCM_SNARF_INIT(X)
+#  define SCM_SNARF_DOCS(TYPE, FNAME, ARGLIST, REQ, OPT, VAR, DOCSTRING)
+# endif
 #endif
 
 #define SCM_DEFINE(FNAME, PRIMNAME, REQ, OPT, VAR, ARGLIST, DOCSTRING) \
@@ -95,10 +109,7 @@ SCM_SNARF_INIT(\
 scm_c_define_gsubr (s_ ## FNAME, REQ, OPT, VAR, \
                     (SCM_FUNC_CAST_ARBITRARY_ARGS) FNAME); \
 )\
-SCM_SNARF_DOCS(\
-SCM_SNARF_DOC_STARTP PRIMNAME #ARGLIST | REQ | OPT | VAR | __FILE__:__LINE__ | \
- SCM_SNARF_DOCSTRING_START DOCSTRING SCM_SNARF_DOCSTRING_END \
-)
+SCM_SNARF_DOCS(primitive, PRIMNAME, ARGLIST, REQ, OPT, VAR, DOCSTRING)
 
 #define SCM_DEFINE1(FNAME, PRIMNAME, TYPE, ARGLIST, DOCSTRING) \
 SCM_SNARF_HERE(\
@@ -106,10 +117,7 @@ static const char s_ ## FNAME [] = PRIMNAME; \
 SCM FNAME ARGLIST\
 )\
 SCM_SNARF_INIT(scm_c_define_subr (s_ ## FNAME, TYPE, FNAME); ) \
-SCM_SNARF_DOCS(\
-SCM_SNARF_DOC_START1 PRIMNAME #ARGLIST | 2 | 0 | 0 | __FILE__:__LINE__ | \
- SCM_SNARF_DOCSTRING_START DOCSTRING SCM_SNARF_DOCSTRING_END \
-)
+SCM_SNARF_DOCS(1, PRIMNAME, ARGLIST, 2, 0, 0, DOCSTRING)
 
 #define SCM_PROC(RANAME, STR, REQ, OPT, VAR, CFN)  \
 SCM_SNARF_HERE(static const char RANAME[]=STR) \
@@ -120,10 +128,8 @@ SCM_SNARF_INIT(scm_c_define_gsubr (RANAME, REQ, OPT, VAR, \
 SCM_SNARF_HERE(static const char RANAME[]=STR) \
 SCM_SNARF_INIT(scm_c_define_gsubr (RANAME, REQ, OPT, VAR, \
                                    (SCM_FUNC_CAST_ARBITRARY_ARGS) CFN);) \
-SCM_SNARF_DOCS(\
-SCM_SNARF_DOC_STARTR STR | REQ | OPT | VAR | __FILE__:__LINE__ | \
- SCM_SNARF_DOCSTRING_START CFN SCM_SNARF_DOCSTRING_END \
-)
+SCM_SNARF_DOCS(register, STR, (), REQ, OPT, VAR, \
+               "implemented by the C function \"" #CFN "\"")
 
 #define SCM_GPROC(RANAME, STR, REQ, OPT, VAR, CFN, GF)  \
 SCM_SNARF_HERE(\
@@ -211,10 +217,10 @@ SCM_SNARF_INIT(c_name = scm_permanent_object (scm_sysintern (scheme_name, init_v
 
 #endif /* (SCM_DEBUG_DEPRECATED == 0) */
 
-#ifdef SCM_MAGIC_SNARFER
+#ifdef SCM_MAGIC_SNARF_DOCS
 #undef SCM_ASSERT
-#define SCM_ASSERT(_cond, _arg, _pos, _subr) *&*&*&*SCM_ARG_BETTER_BE_IN_POSITION(_arg,_pos,__LINE__)
-#endif /* SCM_MAGIC_SNARFER */
+#define SCM_ASSERT(_cond, _arg, _pos, _subr) ^^[ argpos _arg _pos __LINE__ ]
+#endif /* SCM_MAGIC_SNARF_DOCS */
 
 #endif /* LIBGUILE_SNARF_H */