ext/xml/ruby_xml_parser.c in libxml-ruby-0.3.6 vs ext/xml/ruby_xml_parser.c in libxml-ruby-0.3.8
- old
+ new
@@ -1,11 +1,14 @@
-/* $Id: ruby_xml_parser.c,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+/* $Id: ruby_xml_parser.c,v 1.3 2006/03/27 20:49:19 roscopeco Exp $ */
/* Please see the LICENSE file for copyright and distribution information */
#include "libxml.h"
+static VALUE libxml_xmlRubyErrorProc = Qnil;
+static int id_call;
+
int ruby_xml_parser_count = 0;
VALUE cXMLParser;
VALUE eXMLParserParseError;
static int
@@ -216,11 +219,11 @@
}
/*
* call-seq:
- * XML::Parser.enabled_catalog? => (true|false)
+ * XML::Parser.enabled_regexp? => (true|false)
*
* Determine whether libxml regular expression support is enabled.
*/
VALUE
ruby_xml_parser_enabled_regexp_q(VALUE class) {
@@ -265,11 +268,11 @@
}
/*
* call-seq:
- * XML::Parser.enabled_catalog? => (true|false)
+ * XML::Parser.enabled_unicode? => (true|false)
*
* Determine whether libxml unicode support is enabled.
*/
VALUE
ruby_xml_parser_enabled_unicode_q(VALUE class) {
@@ -281,11 +284,11 @@
}
/*
* call-seq:
- * XML::Parser.enabled_catalog? => (true|false)
+ * XML::Parser.enabled_xinclude? => (true|false)
*
* Determine whether libxml xinclude support is enabled.
*/
VALUE
ruby_xml_parser_enabled_xinclude_q(VALUE class) {
@@ -297,11 +300,11 @@
}
/*
* call-seq:
- * XML::Parser.enabled_catalog? => (true|false)
+ * XML::Parser.enabled_xpath? => (true|false)
*
* Determine whether libxml xpath support is enabled.
*/
VALUE
ruby_xml_parser_enabled_xpath_q(VALUE class) {
@@ -313,11 +316,11 @@
}
/*
* call-seq:
- * XML::Parser.enabled_catalog? => (true|false)
+ * XML::Parser.enabled_xpointer? => (true|false)
*
* Determine whether libxml xpointer support is enabled.
*/
VALUE
ruby_xml_parser_enabled_xpointer_q(VALUE class) {
@@ -329,11 +332,11 @@
}
/*
* call-seq:
- * XML::Parser.enabled_catalog? => (true|false)
+ * XML::Parser.enabled_zlib? => (true|false)
*
* Determine whether libxml zlib support is enabled.
*/
VALUE
ruby_xml_parser_enabled_zlib_q(VALUE class) {
@@ -1214,11 +1217,57 @@
rxpc->ctxt = xmlCreateMemoryParserCtxt(StringValuePtr(data->str), RSTRING(data->str)->len);
return(data->str);
}
+/*
+ * call-seq:
+ * XML::Parser.register_error_handler(lambda { |msg| ... }) => old_handler
+ * XML::Parser.register_error_handler(nil) => old_handler
+ *
+ * Register the attached block as the handler for parser errors.
+ * A message describing parse errors is passed to the block.
+ * Libxml passes error messages to the handler in parts, one per call.
+ * A typical error results in six calls to this proc, with arguments:
+ *
+ * "Entity: line 1: ",
+ * "parser ",
+ * "error : ",
+ * "Opening and ending tag mismatch: foo line 1 and foz\n",
+ * "<foo><bar/></foz>\n",
+ * " ^\n"
+ *
+ * Note that the error handler is shared by all threads.
+ */
+VALUE
+ruby_xml_parser_registerErrorHandler(VALUE self, VALUE proc) {
+ VALUE old_block = libxml_xmlRubyErrorProc;
+ libxml_xmlRubyErrorProc = proc;
+ return(old_block);
+}
+static void
+libxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg, ...)
+{
+ va_list ap;
+ char str[1000];
+ VALUE rstr;
+
+ if (libxml_xmlRubyErrorProc == Qnil) {
+ va_start(ap, msg);
+ vfprintf(stderr, msg, ap);
+ va_end(ap);
+ } else {
+ va_start(ap, msg);
+ if (vsnprintf(str, 999, msg, ap) >= 998) str[999] = 0;
+ va_end(ap);
+
+ rstr = rb_str_new2(str);
+ rb_funcall2(libxml_xmlRubyErrorProc, id_call, 1, &rstr);
+ }
+}
+
/* #define RUBY_XML_PARSER_ENABLED_INIT(func, method) \
rb_define_singleton_method(cXMLParser, method, \
ruby_xml_parser_enabled_##func##_q, 0); */
///#include "cbg.c"
@@ -1349,15 +1398,20 @@
ruby_xml_parser_memory_dump, 0);
rb_define_singleton_method(cXMLParser, "memory_used",
ruby_xml_parser_memory_used, 0);
rb_define_singleton_method(cXMLParser, "new", ruby_xml_parser_new, 0);
rb_define_singleton_method(cXMLParser, "string", ruby_xml_parser_new_string, 1);
-
+ rb_define_singleton_method(cXMLParser, "register_error_handler", ruby_xml_parser_registerErrorHandler, 1);
rb_define_method(cXMLParser, "filename", ruby_xml_parser_filename_get, 0);
rb_define_method(cXMLParser, "filename=", ruby_xml_parser_filename_set, 1);
rb_define_method(cXMLParser, "io", ruby_xml_parser_io_get, 0);
rb_define_method(cXMLParser, "io=", ruby_xml_parser_io_set, 1);
rb_define_method(cXMLParser, "parse", ruby_xml_parser_parse, 0);
rb_define_method(cXMLParser, "parser_context", ruby_xml_parser_parser_context_get, 0);
rb_define_method(cXMLParser, "string", ruby_xml_parser_str_get, 0);
rb_define_method(cXMLParser, "string=", ruby_xml_parser_str_set, 1);
+
+ // set up error handling
+ xmlSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
+ xmlThrDefSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
+ id_call = rb_intern("call");
}