diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-03-13 21:05:20 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-03-13 21:05:20 +0200 |
commit | c6229965bc51a2bcb1460a9dcc28bed4a0092678 (patch) | |
tree | 29e9a9b1b999a65642147beaf6831d7211881121 | |
parent | 181a4133f334e38966b58afa5c79f2840637c98f (diff) | |
download | gamma-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.am | 3 | ||||
-rw-r--r-- | NEWS | 7 | ||||
-rw-r--r-- | README | 1 | ||||
-rw-r--r-- | modules/MODLIST | 1 | ||||
-rw-r--r-- | modules/expat | 47 | ||||
-rw-r--r-- | modules/sql | 8 | ||||
-rwxr-xr-x | scripts/bootstrap | 6 | ||||
-rw-r--r-- | src/.gitignore | 3 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/eval.c | 72 | ||||
-rw-r--r-- | src/expat.sci | 87 | ||||
-rw-r--r-- | src/gamma-expat.c | 885 | ||||
-rw-r--r-- | src/gamma-expat.h | 64 | ||||
-rw-r--r-- | src/syslog.c | 47 | ||||
-rw-r--r-- | src/syslog.sci | 23 |
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 @@ -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. @@ -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 |