aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-03-13 21:05:20 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2010-03-13 21:05:20 +0200
commitc6229965bc51a2bcb1460a9dcc28bed4a0092678 (patch)
tree29e9a9b1b999a65642147beaf6831d7211881121
parent181a4133f334e38966b58afa5c79f2840637c98f (diff)
downloadgamma-c6229965bc51a2bcb1460a9dcc28bed4a0092678.tar.gz
gamma-c6229965bc51a2bcb1460a9dcc28bed4a0092678.tar.bz2
Implement Expat bindings.
* modules/expat: New module. * modules/MODLIST: Add expat. * src/eval.c: New file. * src/expat.sci: New file. * src/gamma-expat.c: New file. * src/gamma-expat.h: New file. * src/.gitignore: Update. * src/Makefile.am (.c.inc): Handle GAMMA_CONST and GAMMA_EXPORT markers. * src/syslog.c (syslog_kw): Use GAMMA_CONST marker. * src/syslog.sci: Remove explicit exports. * modules/sql: Do not use AC_LIBOBJ. * scripts/bootstrap: Minor improvement. * NEWS, README: Update.
-rw-r--r--Makefile.am3
-rw-r--r--NEWS7
-rw-r--r--README1
-rw-r--r--modules/MODLIST1
-rw-r--r--modules/expat47
-rw-r--r--modules/sql8
-rwxr-xr-xscripts/bootstrap6
-rw-r--r--src/.gitignore3
-rw-r--r--src/Makefile.am2
-rw-r--r--src/eval.c72
-rw-r--r--src/expat.sci87
-rw-r--r--src/gamma-expat.c885
-rw-r--r--src/gamma-expat.h64
-rw-r--r--src/syslog.c47
-rw-r--r--src/syslog.sci23
15 files changed, 1201 insertions, 55 deletions
diff --git a/Makefile.am b/Makefile.am
index 6a153f7..5419ad7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -62,3 +62,6 @@ dist-hook:
done; \
cp MODLIST $$distdir/modules; \
cd $$here
+
+#Makefile.am: $(top_srcdir)/modules/MODLIST
+# scripts/bootstrap -C $(top_srcdir) --moddir modules --parents
diff --git a/NEWS b/NEWS
index cbdc3f3..d0cb342 100644
--- a/NEWS
+++ b/NEWS
@@ -1,10 +1,13 @@
-Gamma NEWS -- history of user-visible changes. 2007-12-26
-Copyright (C) 2004, 2007 Sergey Poznyakoff
+Gamma NEWS -- history of user-visible changes. 2010-03-13
+Copyright (C) 2004, 2007, 2010 Sergey Poznyakoff
See the end of file for copying conditions.
Please send radius bug reports to <gray@gnu.org.ua>
+* New modules: expat and syslog
+
+
Version 1.1 (CVS)
* Licensed under GPLv3.
diff --git a/README b/README
index 675f28c..4f2b6f1 100644
--- a/README
+++ b/README
@@ -5,6 +5,7 @@ GAMMA = Guile Archive of Multiple Modules with 'A' just for the 'A' of it.
It is a set of possibly useful modules. Currently it includes
** interfaces for two SQL DBMS: MySQL and PostgreSQL
+** interfaces to Expat
** interfaces to syslog
Both are extensively used by Ellinika (http://ellinika.farlep.net)
diff --git a/modules/MODLIST b/modules/MODLIST
index a6d2fb9..a1e2616 100644
--- a/modules/MODLIST
+++ b/modules/MODLIST
@@ -2,5 +2,6 @@
# Empty lines and comments (lines starting with #) are ignored.
# Each line is treated as a name of module definition file.
+expat
sql
syslog
diff --git a/modules/expat b/modules/expat
new file mode 100644
index 0000000..5e98150
--- /dev/null
+++ b/modules/expat
@@ -0,0 +1,47 @@
+# eXpat interface
+
+configure:
+
+AC_SUBST([EXPAT_LIBS])
+AC_SUBST([EXPAT_INCS])
+AC_ARG_WITH(expat,
+ AC_HELP_STRING([--with-expat=PATH],
+ [set path to the expat installation root directory]),
+ [case $withval in
+ /*) if test -d $withval; then
+ if test -d $withval/lib; then
+ EXPAT_LIBS="-L$withval/lib"
+ else
+ AC_MSG_ERROR([directory $withval/lib does not exist])
+ fi
+ if test -d $withval/include; then
+ EXPAT_INCS="-I$withval/includes"
+ else
+ AC_MSG_ERROR([directory $withval/includes does not exist])
+ fi
+ else
+ AC_MSG_ERROR([directory $withval does not exist])
+ fi
+ ;;
+ *) AC_MSG_ERROR([--with-expat argument must be a pathname to the expat installation root directory]);;
+ esac])
+
+MU_CHECK_LIB([expat], [XML_ParserCreate], [$EXPAT_LIBS],
+ [ EXPAT_LIBS="$EXPAT_LIBS -lexpat" ],
+ [ gamma_expat=no ])
+
+libraries:
+expat
+
+sources:
+gamma-expat.c
+gamma-expat.h
+eval.c
+
+scm:
+expat.sci
+
+makefile:
+expat.scm: Makefile $(libgamma_expat_la_SOURCES:.c=.inc)
+libgamma_expat_la_LIBADD = @LTLIBOBJS@ @GUILE_LIBS@ $(EXPAT_LIBS)
+libgamma_expat_la_CPPFLAGS = $(EXPAT_INCS)
diff --git a/modules/sql b/modules/sql
index 0026d9f..f01b695 100644
--- a/modules/sql
+++ b/modules/sql
@@ -15,6 +15,7 @@ AC_ARG_WITH([postgres],
[PGSQL=$withval])
AC_SUBST([SQLLIBS])
+AC_SUBST([SQLOBJS])
# Check individual libraries
if test $MYSQL = yes; then
MU_CHECK_LIB([mysqlclient], [mysql_real_connect], [-lm],
@@ -22,7 +23,7 @@ if test $MYSQL = yes; then
[Define this if you are going to use MySQL])
AC_DEFINE([HAVE_LIBMYSQL],1,
[Define this if you have mysqlclient library])
- AC_LIBOBJ([mysql])
+ SQLOBJS="$SQLOBJS mysql$U.lo"
SQLLIBS="$SQLLIBS $mu_cv_lib_mysqlclient" ],
[ MYSQL=no ],
[/usr/local/lib/mysql /usr/lib/mysql])
@@ -33,7 +34,7 @@ if test $PGSQL = yes; then
[Define this if you are going to use PostgreSQL])
AC_DEFINE([HAVE_LIBPQ],1,
[Define this if you have libp])
- AC_LIBOBJ([pgsql])
+ SQLOBJS="$SQLOBJS pgsql$U.lo"
SQLLIBS="$SQLLIBS $mu_cv_lib_pq" ],
[ PGSQL=no ],
[/usr/local/pgsql/lib /usr/pgsql/lib])
@@ -56,7 +57,8 @@ makefile:
sql.scm: Makefile $(libgamma_sql_la_SOURCES:.c=.inc)
EXTRA_DIST += mysql.c pgsql.c
-libgamma_sql_la_LIBADD = @LTLIBOBJS@ @GUILE_LIBS@ $(SQLLIBS)
+libgamma_sql_la_LIBADD = @SQLOBJS@ @LTLIBOBJS@ @GUILE_LIBS@ @SQLLIBS@
+libgamma_sql_la_DEPENDENCIES = @SQLOBJS@
scm:
sql.sci
diff --git a/scripts/bootstrap b/scripts/bootstrap
index 23fe96c..288f0e9 100755
--- a/scripts/bootstrap
+++ b/scripts/bootstrap
@@ -294,10 +294,10 @@ exec ${GUILE-guile} -l $0 -c "(apply $main (cons \"$0\" (cdr (command-line))))"
(format #t "if test $~A = yes; then~%" var-name)
(thunk)
(display "fi\n")))
- (format #t "if test $~A = yes; then~%" var-name)
(let ((libraries (assoc-ref moddef 'libraries)))
(cond
((and libraries (not (null? libraries)))
+ (format #t "if test $~A = yes; then~%" var-name)
(display " GAMMA_LIB_LIST=\"$GAMMA_LIB_LIST")
(for-each
(lambda (root)
@@ -312,8 +312,8 @@ exec ${GUILE-guile} -l $0 -c "(apply $main (cons \"$0\" (cdr (command-line))))"
(format #t " install-~A-hook" root))
libraries)
(display #\")
- (newline))))
- (display "fi\n")))
+ (newline)
+ (display "fi\n"))))))
(define (empty-string-list? lst)
(cond
diff --git a/src/.gitignore b/src/.gitignore
index 2af40d6..adcd510 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -10,3 +10,6 @@ sql.scm
syslog.inc
syslog.scm
modules.mk
+eval.inc
+expat.scm
+gamma-expat.inc
diff --git a/src/Makefile.am b/src/Makefile.am
index b7bca34..bfb82de 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -56,7 +56,7 @@ SUFFIXES=.x .doc .inc .sci .scm
$< $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
.c.inc:
- $(AM_V_GEN)sed -n 's/SCM_DEFINE *(.[^,]*, *\"\([^"][^"]*\)\".*/[(export \1)]/p' $< > $@
+ $(AM_V_GEN)sed -n 's/SCM_DEFINE *(.[^,]*, *\"\([^"][^"]*\)\".*/[(export \1)]/p;s/^[ ]*GAMMA_CONST *(\(.[^)]*\)).*/[(export \1])/p;s/.*GAMMA_EXPORT *("\(.*\)").*/[(export \1)]/p' $< > $@
guile-procedures.txt: $(DOT_DOC_FILES)
$(AM_V_GEN)cat $(DOT_DOC_FILES) > $@
diff --git a/src/eval.c b/src/eval.c
new file mode 100644
index 0000000..407b164
--- /dev/null
+++ b/src/eval.c
@@ -0,0 +1,72 @@
+/* This file is part of Gamma.
+ Copyright (C) 2010 Sergey Poznyakoff
+
+ Gamma 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 3, or (at your option)
+ any later version.
+
+ Gamma 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 Gamma. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "gamma-expat.h"
+
+
+/* General-purpose eval handlers */
+
+SCM
+gamma_eval_catch_body(void *list)
+{
+ return scm_primitive_eval((SCM)list);
+}
+
+static SCM
+eval_catch_handler (void *data, SCM tag, SCM throw_args)
+{
+ scm_handle_by_message_noexit("gamma", tag, throw_args);
+ longjmp(*(jmp_buf*)data, 1);
+}
+
+struct scheme_exec_data {
+ SCM (*handler) (void *data);
+ void *data;
+ SCM result;
+};
+
+static SCM
+scheme_safe_exec_body (void *data)
+{
+ struct scheme_exec_data *ed = data;
+ ed->result = ed->handler(ed->data);
+ return SCM_BOOL_F;
+}
+
+int
+gamma_safe_exec(SCM (*handler) (void *data), void *data, SCM *result)
+{
+ jmp_buf jmp_env;
+ struct scheme_exec_data ed;
+
+ if (setjmp(jmp_env))
+ return 1;
+ ed.handler = handler;
+ ed.data = data;
+ scm_internal_lazy_catch(SCM_BOOL_T,
+ scheme_safe_exec_body, (void*)&ed,
+ eval_catch_handler, &jmp_env);
+ if (result)
+ *result = ed.result;
+ return 0;
+}
+
+char *
+gamma_proc_name(SCM proc)
+{
+ return scm_to_locale_string(
+ scm_symbol_to_string(scm_procedure_name(proc)));
+}
diff --git a/src/expat.sci b/src/expat.sci
new file mode 100644
index 0000000..258e387
--- /dev/null
+++ b/src/expat.sci
@@ -0,0 +1,87 @@
+;;;; This file is part of Gamma. -*- scheme -*-
+;;;; Copyright (C) 2010 Sergey Poznyakoff
+;;;;
+;;;; Gamma 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 3, or (at your option)
+;;;; any later version.
+;;;;
+;;;; Gamma 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 Gamma. If not, see <http://www.gnu.org/licenses/>.
+
+changequote([,])dnl
+
+(define-module (gamma expat)
+ :use-module (ice-9 rdelim)
+ :use-module (srfi srfi-1))
+
+(let ((lib-path "LIBDIR/"))
+ (load-extension (string-append
+ lib-path "libgamma-expat-v-VERSION") "gamma_expat_init"))
+
+include(BUILDDIR/gamma-expat.inc)
+
+(define-public (xml-make-parser . rest)
+ (if (null? rest)
+ (xml-primitive-make-parser)
+ (letrec ((parser-setup (lambda (setup handler-args)
+ (let ((p
+ (apply xml-primitive-make-parser setup)))
+ (if (not (null? handler-args))
+ (apply xml-set-handler p handler-args))
+ p))))
+ (if (string? (car rest))
+ (let ((encoding (car rest))
+ (rest (cdr rest)))
+ (if (char? (car rest))
+ (parser-setup (list encoding (car rest))
+ (cdr rest))
+ (parser-setup (list encoding) rest)))
+ (parser-setup '() rest)))))
+
+(define-public (xml-parse-more parser input)
+ (cond
+ ((eof-object? input)
+ (xml-primitive-parse parser "" #t))
+ (else
+ (xml-primitive-parse parser input #f))))
+
+(define-public (xml-parse parser)
+ (let loop ((line (read-line)))
+ (xml-parse-more parser line)
+ (if (not (eof-object? line))
+ (loop (read-line)))))
+
+(define-public (xml-set-handler parser . rest)
+ (if (odd? (length rest))
+ (scm-error 'wrong-number-of-args
+ "xml-set-handler"
+ "Wrong number of arguments to ~A"
+ (list "xml-set-handler")
+ #f))
+
+ (for-each
+ (lambda (elt)
+ (xml-primitive-set-handler parser (car elt) (cdr elt)))
+
+ (let ((prev-elem #f))
+ (fold-right
+ (lambda (elem prev)
+ (cond
+ (prev-elem
+ (let ((ret (cons (cons elem prev-elem) prev)))
+ (set! prev-elem #f)
+ ret))
+ (else
+ (set! prev-elem elem)
+ prev)))
+ '()
+ rest))))
+
+
+;;;; End of expat.scm
diff --git a/src/gamma-expat.c b/src/gamma-expat.c
new file mode 100644
index 0000000..3348d65
--- /dev/null
+++ b/src/gamma-expat.c
@@ -0,0 +1,885 @@
+/* This file is part of Gamma.
+ Copyright (C) 2010 Sergey Poznyakoff
+
+ Gamma 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 3, or (at your option)
+ any later version.
+
+ Gamma 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 Gamma. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "gamma-expat.h"
+
+
+static long gamma_xml_parser_tag;
+
+struct gamma_xml_parser
+{
+ XML_Parser parser;
+};
+
+#define gamma_scm_is_xml_parser(s) \
+ (!SCM_IMP(s) && SCM_CELL_TYPE(s) == gamma_xml_parser_tag)
+
+static SCM
+gamma_xml_parser_create(XML_Parser parser)
+{
+ struct gamma_xml_parser *gp;
+
+ gp = scm_gc_malloc(sizeof (*gp), "XML_Parser");
+ gp->parser = parser;
+ SCM_RETURN_NEWSMOB(gamma_xml_parser_tag, gp);
+}
+
+#define GAMMA_XML_PARSER_PTR(smob) \
+ ((struct gamma_xml_parser *)SCM_CDR(smob))
+
+static scm_sizet
+gamma_xml_parser_free(SCM smob)
+{
+ struct gamma_xml_parser *gp = GAMMA_XML_PARSER_PTR(smob);
+ if (gp->parser) {
+ struct gamma_expat_user_data *udata =
+ XML_GetUserData(gp->parser);
+ free(udata);
+ XML_ParserFree(gp->parser);
+ }
+ free(gp);
+ return 0;
+}
+
+static SCM
+gamma_xml_parser_mark(SCM smob)
+{
+ struct gamma_xml_parser *gp = GAMMA_XML_PARSER_PTR(smob);
+ struct gamma_expat_user_data *udata;
+ int i;
+
+ if (!gp->parser)
+ return SCM_BOOL_F;
+ udata = XML_GetUserData(gp->parser);
+ for (i = 0; i < gamma_expat_handler_count; i++) {
+ if (!SCM_UNBNDP(udata->handler[i]))
+ scm_gc_mark(udata->handler[i]);
+ }
+ if (!SCM_UNBNDP(udata->external_entity_ref_handler_arg))
+ scm_gc_mark(udata->external_entity_ref_handler_arg);
+ return SCM_BOOL_F;
+}
+
+static int
+gamma_xml_parser_print(SCM smob, SCM port, scm_print_state *pstate)
+{
+/* struct gamma_xml_parser *gp = GAMMA_XML_PARSER_PTR(smob);*/
+
+ scm_puts("#<XML_Parser>", port);
+ /* FIXME: show more details */
+ return 1;
+}
+
+static void
+gamma_xml_parser_init()
+{
+ gamma_xml_parser_tag =
+ scm_make_smob_type("XML_Parser",
+ sizeof(struct gamma_xml_parser));
+ scm_set_smob_mark(gamma_xml_parser_tag, gamma_xml_parser_mark);
+ scm_set_smob_free(gamma_xml_parser_tag, gamma_xml_parser_free);
+ scm_set_smob_print(gamma_xml_parser_tag, gamma_xml_parser_print);
+}
+
+
+static struct gamma_expat_user_data *
+make_user_data ()
+{
+ int i;
+
+ struct gamma_expat_user_data *p = scm_gc_malloc(sizeof (*p),
+ "make_user_data");
+ for (i = 0; i < gamma_expat_handler_count; i++)
+ p->handler[i] = SCM_UNSPECIFIED;
+ p->external_entity_ref_handler_arg = SCM_UNSPECIFIED;
+ return p;
+}
+
+SCM_GLOBAL_SYMBOL(gamma_xml_error, "gamma-xml-error");
+
+SCM_DEFINE(scm_xml_primitive_make_parser, "xml-primitive-make-parser", 0, 2, 0,
+ (SCM enc, SCM sep),
+ "Return a new parser. If @var{enc} is given, it must be one of:"
+ " \"US-ASCII\", \"UTF-8\", \"UTF-16\", \"ISO-8859-1\". If @var{sep}"
+ "is given, the returned parser has namespace processing in effect. "
+ "In that case, @var{sep} is a character which is used as a "
+ "separator between the namespace @acronym{URI} and the local part "
+ "of the name in returned namespace element and attribute names.")
+#define FUNC_NAME s_scm_xml_primitive_make_parser
+{
+ XML_Char *encoding = NULL;
+ XML_Char separator = 0;
+ XML_Parser parser;
+
+ if (!SCM_UNBNDP(enc)) {
+ SCM_VALIDATE_STRING(1, enc);
+ encoding = scm_to_locale_string(enc);
+ }
+ if (!SCM_UNBNDP(sep)) {
+ SCM_VALIDATE_CHAR(2, sep);
+ separator = SCM_CHAR(sep);
+ parser = XML_ParserCreateNS(encoding, separator);
+ } else
+ parser = XML_ParserCreate(encoding);
+ if (!parser)
+ scm_memory_error(FUNC_NAME);
+ XML_SetUserData(parser, make_user_data());
+ free(encoding);
+ return gamma_xml_parser_create(parser);
+}
+#undef FUNC_NAME
+
+SCM_DEFINE(scm_xml_set_encoding, "xml-set-encoding", 2, 0, 0,
+ (SCM parser, SCM enc),
+ "Set the encoding to be used by the @var{parser}.")
+#define FUNC_NAME s_scm_xml_set_encoding
+{
+ struct gamma_xml_parser *gp;
+ char *encoding;
+ enum XML_Status status;
+
+ SCM_ASSERT(gamma_scm_is_xml_parser(parser), parser,
+ SCM_ARG1, FUNC_NAME);
+ SCM_VALIDATE_STRING(2, enc);
+
+ gp = GAMMA_XML_PARSER_PTR(parser);
+ encoding = scm_to_locale_string(enc);
+ status = XML_SetEncoding(gp->parser, encoding);
+ free(encoding);
+ if (status == XML_STATUS_ERROR) {
+ enum XML_Error error = XML_GetErrorCode(gp->parser);
+ scm_error(gamma_xml_error, FUNC_NAME,
+ "~A",
+ scm_list_1(scm_makfrom0str(XML_ErrorString(error))),
+ SCM_BOOL_F);
+ }
+ return SCM_UNSPECIFIED;
+}
+#undef FUNC_NAME
+
+SCM_DEFINE(scm_xml_primitive_parse, "xml-primitive-parse", 3, 0, 0,
+ (SCM parser, SCM input, SCM isfinal),
+ "Parse next piece of input")
+#define FUNC_NAME s_scm_xml_primitive_parse
+{
+ struct gamma_xml_parser *gp;
+ char *str;
+ enum XML_Status status;
+
+ SCM_ASSERT(gamma_scm_is_xml_parser(parser), parser,
+ SCM_ARG1, FUNC_NAME);
+ SCM_VALIDATE_STRING(2, input);
+ SCM_VALIDATE_BOOL(3, isfinal);
+
+ gp = GAMMA_XML_PARSER_PTR(parser);
+ str = scm_to_locale_string(input);
+ status = XML_Parse(gp->parser, str, strlen(str),
+ isfinal == SCM_BOOL_T);
+ free(str);
+ if (status == XML_STATUS_ERROR) {
+ enum XML_Error error = XML_GetErrorCode(gp->parser);
+ scm_error(gamma_xml_error, FUNC_NAME,
+ "~A",
+ scm_list_1(scm_makfrom0str(XML_ErrorString(error))),
+ scm_list_2(scm_from_int(error), input));
+ }
+ return SCM_UNSPECIFIED;
+
+}
+#undef FUNC_NAME
+
+
+static SCM
+attrs_to_scm(const XML_Char **attr)
+{
+ int i;
+ SCM scm_first = SCM_EOL, scm_last = SCM_EOL;
+
+ for (i = 0; attr[i]; i += 2) {
+ SCM new = scm_cons(scm_cons(scm_makfrom0str(attr[i]),
+ scm_makfrom0str(attr[i + 1])),
+ SCM_EOL);
+ if (scm_first == SCM_EOL)
+ scm_last = scm_first = new;
+ else {
+ SCM_SETCDR(scm_last, new);
+ scm_last = new;
+ }
+ }
+ return scm_first;
+}
+
+struct apply_data {
+ SCM proc;
+ SCM arg;
+};
+
+SCM
+gamma_apply_catch_body(void *data)
+{
+ struct apply_data *xp = data;
+ return scm_apply_0(xp->proc, xp->arg);
+}
+
+typedef void (*generic_handler_setter_t) (XML_Parser);
+
+
+static void XMLCALL
+generic_start_handler(void *user_data, const XML_Char *name,
+ const XML_Char **attrs)
+{
+ struct apply_data xdata;
+ struct gamma_expat_user_data *udata = user_data;
+
+ xdata.proc = udata->handler[start_element_handler];
+ xdata.arg = scm_list_2(scm_makfrom0str(name),
+ attrs_to_scm(attrs));
+ gamma_safe_exec(gamma_apply_catch_body, &xdata, NULL);
+}
+
+static void
+set_generic_start_element_handler(XML_Parser parser)
+{
+ XML_SetStartElementHandler(parser, generic_start_handler);
+}
+
+static void XMLCALL
+generic_end_handler(void *user_data, const XML_Char *name)
+{
+ struct apply_data xdata;
+ struct gamma_expat_user_data *udata = user_data;
+
+ xdata.proc = udata->handler[end_element_handler];
+ xdata.arg = scm_list_1(scm_makfrom0str(name));
+ gamma_safe_exec(gamma_apply_catch_body, &xdata, NULL);
+}
+
+static void
+set_generic_end_element_handler(XML_Parser parser)
+{
+ XML_SetEndElementHandler(parser, generic_end_handler);
+}
+
+static void XMLCALL
+data_chunk_handler(SCM proc, const XML_Char *chunk, int len)
+{
+ struct apply_data xdata;
+ xdata.proc = proc;
+ xdata.arg = scm_list_1(scm_from_locale_stringn(chunk, len));
+ gamma_safe_exec(gamma_apply_catch_body, &xdata, NULL);
+}
+
+static void XMLCALL
+generic_character_data_handler(void *user_data, const XML_Char *chunk,
+ int len)
+{
+ struct gamma_expat_user_data *udata = user_data;
+ data_chunk_handler(udata->handler[character_data_handler],
+ chunk, len);
+}
+
+static void
+set_generic_character_data_handler(XML_Parser parser)
+{
+ XML_SetCharacterDataHandler(parser, generic_character_data_handler);
+}
+
+static void XMLCALL
+generic_processing_instruction_handler(void *user_data,
+ const XML_Char *target,
+ const XML_Char *data)
+{
+ struct apply_data xdata;
+ struct gamma_expat_user_data *udata = user_data;
+
+ xdata.proc = udata->handler[processing_instruction_handler];
+ xdata.arg = scm_list_2(scm_from_locale_string(target),
+ scm_from_locale_string(data));
+ gamma_safe_exec(gamma_apply_catch_body, &xdata, NULL);
+}
+
+static void
+set_generic_processing_instruction_handler(XML_Parser parser)
+{
+ XML_SetProcessingInstructionHandler(parser,
+ generic_processing_instruction_handler);
+}
+
+static void XMLCALL
+generic_comment_handler(void *user_data, const XML_Char *data)
+{
+ struct apply_data xdata;
+ struct gamma_expat_user_data *udata = user_data;
+
+ xdata.proc = udata->handler[comment_handler];
+ xdata.arg = scm_list_1(scm_from_locale_string(data));
+ gamma_safe_exec(gamma_apply_catch_body, &xdata, NULL);
+}
+
+static void
+set_generic_comment_handler(XML_Parser parser)
+{
+ XML_SetCommentHandler(parser, generic_comment_handler);
+}
+
+static void XMLCALL
+generic_start_cdata_section_handler(void *user_data)
+{
+ struct apply_data xdata;
+ struct gamma_expat_user_data *udata = user_data;
+
+ xdata.proc = udata->handler[start_cdata_section_handler];
+ xdata.arg = SCM_EOL;
+ gamma_safe_exec(gamma_apply_catch_body, &xdata, NULL);
+}
+
+static void
+set_generic_start_cdata_section_handler(XML_Parser parser)
+{
+ XML_SetStartCdataSectionHandler(parser,
+ generic_start_cdata_section_handler);
+}
+
+static void XMLCALL
+generic_end_cdata_section_handler(void *user_data)
+{
+ struct apply_data xdata;
+ struct gamma_expat_user_data *udata = user_data;
+
+ xdata.proc = udata->handler[end_cdata_section_handler];
+ xdata.arg = SCM_EOL;
+ gamma_safe_exec(gamma_apply_catch_body, &xdata, NULL);
+}
+
+static void
+set_generic_end_cdata_section_handler(XML_Parser parser)
+{
+ XML_SetEndCdataSectionHandler(parser,
+ generic_end_cdata_section_handler);
+}
+
+static void XMLCALL
+generic_default_handler(void *user_data, const XML_Char *chunk,
+ int len)
+{
+ struct gamma_expat_user_data *udata = user_data;
+ data_chunk_handler(udata->handler[default_handler], chunk, len);
+}
+
+static void
+set_generic_default_handler(XML_Parser parser)
+{
+ XML_SetDefaultHandler(parser, generic_default_handler);
+}
+
+static void XMLCALL
+generic_default_handler_expand(void *user_data, const XML_Char *chunk,
+ int len)
+{
+ struct gamma_expat_user_data *udata = user_data;
+ data_chunk_handler(udata->handler[default_handler_expand], chunk, len);
+}
+
+static void
+set_generic_default_handler_expand(XML_Parser parser)
+{
+ XML_SetDefaultHandlerExpand(parser, generic_default_handler_expand);
+}
+
+static void XMLCALL
+generic_unparsed_entity_decl_handler(void *user_data,
+ const XML_Char *entity_name,
+ const XML_Char *base,
+ const XML_Char *system_id,
+ const XML_Char *public_id,
+ const XML_Char *notation_name)
+{
+ struct apply_data xdata;
+ struct gamma_expat_user_data *udata = user_data;
+
+ xdata.proc = udata->handler[unparsed_entity_decl_handler];
+ xdata.arg = scm_list_5(scm_from_locale_string(entity_name),
+ scm_from_locale_string(base),
+ scm_from_locale_string(system_id),
+ scm_from_locale_string(public_id),
+ scm_from_locale_string(notation_name));
+ gamma_safe_exec(gamma_apply_catch_body, &xdata, NULL);
+}
+
+static void
+set_generic_unparsed_entity_decl_handler(XML_Parser parser)
+{
+ XML_SetUnparsedEntityDeclHandler(parser,
+ generic_unparsed_entity_decl_handler);
+}
+
+static void XMLCALL
+generic_notation_decl_handler(void *user_data,
+ const XML_Char *notation_name,
+ const XML_Char *base,
+ const XML_Char *system_id,
+ const XML_Char *public_id)
+{
+ struct apply_data xdata;
+ struct gamma_expat_user_data *udata = user_data;
+
+ xdata.proc = udata->handler[notation_decl_handler];
+ xdata.arg = scm_list_4(scm_from_locale_string(notation_name),
+ scm_from_locale_string(base),
+ scm_from_locale_string(system_id),
+ scm_from_locale_string(public_id));
+ gamma_safe_exec(gamma_apply_catch_body, &xdata, NULL);
+}
+
+static void
+set_generic_notation_decl_handler(XML_Parser parser)
+{
+ XML_SetNotationDeclHandler(parser,
+ generic_notation_decl_handler);
+}
+
+static void XMLCALL
+generic_start_namespace_decl_handler(void *user_data,
+ const XML_Char *prefix,
+ const XML_Char *uri)
+{
+ struct apply_data xdata;
+ struct gamma_expat_user_data *udata = user_data;
+
+ xdata.proc = udata->handler[start_namespace_decl_handler];
+ xdata.arg = scm_list_2(scm_from_locale_string(prefix),
+ scm_from_locale_string(uri));
+ gamma_safe_exec(gamma_apply_catch_body, &xdata, NULL);
+}
+
+static void
+set_generic_start_namespace_decl_handler(XML_Parser parser)
+{
+ XML_SetStartNamespaceDeclHandler(parser,
+ generic_start_namespace_decl_handler);
+}
+
+static void XMLCALL
+generic_end_namespace_decl_handler(void *user_data,
+ const XML_Char *prefix)
+{
+ struct apply_data xdata;
+ struct gamma_expat_user_data *udata = user_data;
+
+ xdata.proc = udata->handler[end_namespace_decl_handler];
+ xdata.arg = scm_list_1(scm_from_locale_string(prefix));
+ gamma_safe_exec(gamma_apply_catch_body, &xdata, NULL);
+}
+
+static void
+set_generic_end_namespace_decl_handler(XML_Parser parser)
+{
+ XML_SetEndNamespaceDeclHandler(parser,
+ generic_end_namespace_decl_handler);
+}
+
+
+static void XMLCALL
+generic_skipped_entity_handler(void *user_data,
+ const XML_Char *entity_name,
+ int is_parameter_entity)
+{
+ struct apply_data xdata;
+ struct gamma_expat_user_data *udata = user_data;
+
+ xdata.proc = udata->handler[skipped_entity_handler];
+ xdata.arg = scm_list_2(scm_from_locale_string(entity_name),
+ is_parameter_entity ? SCM_BOOL_T : SCM_BOOL_F);
+ gamma_safe_exec(gamma_apply_catch_body, &xdata, NULL);
+}
+
+static void
+set_generic_skipped_entity_handler(XML_Parser parser)
+{
+ XML_SetSkippedEntityHandler(parser, generic_skipped_entity_handler);
+}
+
+
+static int XMLCALL
+generic_not_standalone_handler(void *user_data)
+{
+ struct apply_data xdata;
+ struct gamma_expat_user_data *udata = user_data;
+
+ xdata.proc = udata->handler[not_standalone_handler];
+ xdata.arg = SCM_EOL;
+ /* FIXME: Result? */
+ gamma_safe_exec(gamma_apply_catch_body, &xdata, NULL);
+ return 0;
+}
+
+static void
+set_generic_not_standalone_handler(XML_Parser parser)
+{
+ XML_SetNotStandaloneHandler(parser,
+ generic_not_standalone_handler);
+}
+
+static void XMLCALL
+generic_xml_decl_handler(void *user_data,
+ const XML_Char *version,
+ const XML_Char *encoding,
+ int standalone)
+{
+ struct apply_data xdata;
+ struct gamma_expat_user_data *udata = user_data;
+
+ xdata.proc = udata->handler[xml_decl_handler];
+ xdata.arg = scm_list_3(scm_from_locale_string(version),
+ scm_from_locale_string(encoding),
+ standalone == -1 ?
+ SCM_UNSPECIFIED :
+ (standalone ? SCM_BOOL_T : SCM_BOOL_F));
+ gamma_safe_exec(gamma_apply_catch_body, &xdata, NULL);
+}
+
+static void
+set_generic_xml_decl_handler(XML_Parser parser)
+{
+ XML_SetXmlDeclHandler(parser, generic_xml_decl_handler);
+}
+
+static void XMLCALL
+generic_start_doctype_decl_handler(void *user_data,
+ const XML_Char *doctype_name,
+ const XML_Char *sysid,
+ const XML_Char *pubid,
+ int has_internal_subset)
+{
+ struct apply_data xdata;
+ struct gamma_expat_user_data *udata = user_data;
+
+ xdata.proc = udata->handler[start_doctype_decl_handler];
+ xdata.arg = scm_list_4(scm_from_locale_string(doctype_name),
+ sysid ? scm_from_locale_string(sysid) :
+ SCM_BOOL_F,
+ pubid ? scm_from_locale_string(pubid) :
+ SCM_BOOL_F,
+ (has_internal_subset ? SCM_BOOL_T : SCM_BOOL_F));
+ gamma_safe_exec(gamma_apply_catch_body, &xdata, NULL);
+}
+
+static void
+set_generic_start_doctype_decl_handler(XML_Parser parser)
+{
+ XML_SetStartDoctypeDeclHandler(parser,
+ generic_start_doctype_decl_handler);
+}
+
+static void XMLCALL
+generic_end_doctype_decl_handler(void *user_data)
+{
+ struct apply_data xdata;
+ struct gamma_expat_user_data *udata = user_data;
+
+ xdata.proc = udata->handler[end_doctype_decl_handler];
+ xdata.arg = SCM_EOL;
+ gamma_safe_exec(gamma_apply_catch_body, &xdata, NULL);
+}
+
+static void
+set_generic_end_doctype_decl_handler(XML_Parser parser)
+{
+ XML_SetEndDoctypeDeclHandler(parser,
+ generic_end_doctype_decl_handler);
+}
+
+static void XMLCALL
+generic_attlist_decl_handler(void *user_data,
+ const XML_Char *elname,
+ const XML_Char *attname,
+ const XML_Char *att_type,
+ const XML_Char *dflt,
+ int isrequired)
+{
+ struct apply_data xdata;
+ struct gamma_expat_user_data *udata = user_data;
+
+ xdata.proc = udata->handler[attlist_decl_handler];
+ xdata.arg = scm_list_4(scm_from_locale_string(elname),
+ scm_from_locale_string(attname),
+ scm_from_locale_string(att_type),
+ dflt ? scm_from_locale_string(dflt) :
+ (isrequired ? SCM_BOOL_T : SCM_BOOL_F));
+ gamma_safe_exec(gamma_apply_catch_body, &xdata, NULL);
+}
+
+static void
+set_generic_attlist_decl_handler(XML_Parser parser)
+{
+ XML_SetAttlistDeclHandler(parser,
+ generic_attlist_decl_handler);
+}
+
+static void XMLCALL
+generic_entity_decl_handler(void *user_data,
+ const XML_Char *entity_name,
+ int is_parameter_entity,
+ const XML_Char *value,
+ int value_length,
+ const XML_Char *base,
+ const XML_Char *system_id,
+ const XML_Char *public_i