[Pkg-ruby-extras-maintainers] r964 - in
packages-wip/libxml-ruby/trunk: . debian
Filipe Lautert
filipe-guest at alioth.debian.org
Fri Nov 3 22:04:09 CET 2006
Author: filipe-guest
Date: 2006-11-03 22:04:08 +0100 (Fri, 03 Nov 2006)
New Revision: 964
Added:
packages-wip/libxml-ruby/trunk/cbg.c
packages-wip/libxml-ruby/trunk/debian/
packages-wip/libxml-ruby/trunk/debian/changelog
packages-wip/libxml-ruby/trunk/debian/compat
packages-wip/libxml-ruby/trunk/debian/control
packages-wip/libxml-ruby/trunk/debian/control.in
packages-wip/libxml-ruby/trunk/debian/copyright
packages-wip/libxml-ruby/trunk/debian/docs
packages-wip/libxml-ruby/trunk/debian/rules
packages-wip/libxml-ruby/trunk/debian/watch
packages-wip/libxml-ruby/trunk/extconf.rb
packages-wip/libxml-ruby/trunk/libxml.c
packages-wip/libxml-ruby/trunk/libxml.h
packages-wip/libxml-ruby/trunk/libxml.rb
packages-wip/libxml-ruby/trunk/ruby_xml_attr.c
packages-wip/libxml-ruby/trunk/ruby_xml_attr.h
packages-wip/libxml-ruby/trunk/ruby_xml_attribute.c
packages-wip/libxml-ruby/trunk/ruby_xml_attribute.h
packages-wip/libxml-ruby/trunk/ruby_xml_document.c
packages-wip/libxml-ruby/trunk/ruby_xml_document.h
packages-wip/libxml-ruby/trunk/ruby_xml_dtd.c
packages-wip/libxml-ruby/trunk/ruby_xml_dtd.h
packages-wip/libxml-ruby/trunk/ruby_xml_input_cbg.c
packages-wip/libxml-ruby/trunk/ruby_xml_input_cbg.h
packages-wip/libxml-ruby/trunk/ruby_xml_node.c
packages-wip/libxml-ruby/trunk/ruby_xml_node.h
packages-wip/libxml-ruby/trunk/ruby_xml_node_set.c
packages-wip/libxml-ruby/trunk/ruby_xml_node_set.h
packages-wip/libxml-ruby/trunk/ruby_xml_ns.c
packages-wip/libxml-ruby/trunk/ruby_xml_ns.h
packages-wip/libxml-ruby/trunk/ruby_xml_parser.c
packages-wip/libxml-ruby/trunk/ruby_xml_parser.h
packages-wip/libxml-ruby/trunk/ruby_xml_parser_context.c
packages-wip/libxml-ruby/trunk/ruby_xml_parser_context.h
packages-wip/libxml-ruby/trunk/ruby_xml_sax_parser.c
packages-wip/libxml-ruby/trunk/ruby_xml_sax_parser.h
packages-wip/libxml-ruby/trunk/ruby_xml_schema.c
packages-wip/libxml-ruby/trunk/ruby_xml_schema.h
packages-wip/libxml-ruby/trunk/ruby_xml_tree.c
packages-wip/libxml-ruby/trunk/ruby_xml_tree.h
packages-wip/libxml-ruby/trunk/ruby_xml_xinclude.c
packages-wip/libxml-ruby/trunk/ruby_xml_xinclude.h
packages-wip/libxml-ruby/trunk/ruby_xml_xpath.c
packages-wip/libxml-ruby/trunk/ruby_xml_xpath.h
packages-wip/libxml-ruby/trunk/ruby_xml_xpath_context.c
packages-wip/libxml-ruby/trunk/ruby_xml_xpath_context.h
packages-wip/libxml-ruby/trunk/ruby_xml_xpointer.c
packages-wip/libxml-ruby/trunk/ruby_xml_xpointer.h
packages-wip/libxml-ruby/trunk/ruby_xml_xpointer_context.c
packages-wip/libxml-ruby/trunk/ruby_xml_xpointer_context.h
packages-wip/libxml-ruby/trunk/sax_parser_callbacks.inc
Log:
Load newtrunk into packages-wip/libxml-ruby/trunk.
Added: packages-wip/libxml-ruby/trunk/cbg.c
===================================================================
--- packages-wip/libxml-ruby/trunk/cbg.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/cbg.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,76 @@
+#include <string.h>
+#include <libxml/xmlIO.h>
+#include "ruby.h"
+
+/*
+int xmlRegisterInputCallbacks (xmlInputMatchCallback matchFunc,
+ xmlInputOpenCallback openFunc,
+ xmlInputReadCallback readFunc,
+ xmlInputCloseCallback closeFunc);
+
+
+int (*xmlInputMatchCallback) (char const *filename);
+void* (*xmlInputOpenCallback) (char const *filename);
+int (*xmlInputReadCallback) (void *context,
+ char *buffer,
+ int len);
+int (*xmlInputCloseCallback) (void *context);
+*/
+
+typedef struct deb_doc_context {
+ char *buffer;
+ char *bpos;
+ int remaining;
+} deb_doc_context;
+
+int deb_Match (char const *filename) {
+ fprintf( stderr, "deb_Match: %s\n", filename );
+ if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "deb://", 6)) {
+ return(1);
+ }
+ return(0);
+}
+
+void* deb_Open (char const *filename) {
+ deb_doc_context *deb_doc;
+ VALUE res;
+
+ deb_doc = (deb_doc_context*)malloc( sizeof(deb_doc_context) );
+
+ res = rb_funcall( rb_funcall( rb_mKernel, rb_intern("const_get"), 1, rb_str_new2("DEBSystem") ),
+ rb_intern("document_query"), 1, rb_str_new2(filename));
+ deb_doc->buffer = strdup( StringValuePtr(res) );
+ //deb_doc->buffer = strdup("<serepes>serepes</serepes>");
+
+ deb_doc->bpos = deb_doc->buffer;
+ deb_doc->remaining = strlen(deb_doc->buffer);
+ return deb_doc;
+}
+
+int deb_Read (void *context, char *buffer, int len) {
+ deb_doc_context *deb_doc;
+ int ret_len;
+ deb_doc = (deb_doc_context*)context;
+
+ if (len >= deb_doc->remaining) {
+ ret_len = deb_doc->remaining;
+ } else {
+ ret_len = len;
+ }
+ deb_doc->remaining -= ret_len;
+ strncpy( buffer, deb_doc->bpos, ret_len );
+ deb_doc->bpos += ret_len;
+
+ return ret_len;
+}
+
+int deb_Close (void *context) {
+ free( ((deb_doc_context*)context)->buffer );
+ free( context );
+ return 1;
+}
+
+
+void deb_register_cbg() {
+ xmlRegisterInputCallbacks( deb_Match, deb_Open, deb_Read, deb_Close );
+}
Added: packages-wip/libxml-ruby/trunk/debian/changelog
===================================================================
--- packages-wip/libxml-ruby/trunk/debian/changelog 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/debian/changelog 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,41 @@
+libxml-ruby (0.3.8-1) unstable; urgency=low
+
+ * Package adopted. Closes: #335698.
+
+ -- Filipe Lautert <filipelautert at celepar.pr.gov.br> Wed, 1 Nov 2006 15:35:12 -0300
+
+libxml-ruby (0.3.4-4) unstable; urgency=low
+
+ * QA upload.
+ * Add a libxml-ruby metapackage as recommended by Debian Ruby Policy.
+ Closes: #282759.
+ * Change section to interpreters. Closes: #260944.
+ * debian/copyright: Update upstream URL.
+ * debian/dirs: $(sitedir) already handled by the Makefile; remove.
+ * debian/docs: README and TODO already handled by cdbs; remove.
+ * debian/watch: Add.
+ * Conforms to Standards version 3.6.2.
+
+ -- Matej Vela <vela at debian.org> Sun, 13 Nov 2005 17:38:06 +0100
+
+libxml-ruby (0.3.4-3) unstable; urgency=low
+
+ * Orphaning package, setting maintainer to QA.
+
+ -- Andres Salomon <dilinger at voxel.net> Tue, 25 Oct 2005 01:44:32 -0400
+
+libxml-ruby (0.3.4-2) unstable; urgency=low
+
+ * Fix FTBFS due to unnecessary libm/atan check; thanks to
+ Andreas Jochens (closes: #265475).
+ * Fix gcc-4.0 FTBFS due to lvalue casts; thanks to
+ Andreas Jochens (closes: #287452).
+
+ -- Andres Salomon <dilinger at voxel.net> Wed, 29 Dec 2004 07:37:28 -0500
+
+libxml-ruby (0.3.4-1) unstable; urgency=low
+
+ * Initial release (closes: #228534).
+
+ -- Andres Salomon <dilinger at voxel.net> Fri, 16 Jul 2004 22:12:41 -0400
+
Added: packages-wip/libxml-ruby/trunk/debian/compat
===================================================================
--- packages-wip/libxml-ruby/trunk/debian/compat 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/debian/compat 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1 @@
+4
Added: packages-wip/libxml-ruby/trunk/debian/control
===================================================================
--- packages-wip/libxml-ruby/trunk/debian/control 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/debian/control 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,23 @@
+Source: libxml-ruby
+Section: interpreters
+Priority: optional
+Maintainer: Filipe Lautert <filipelautert at celepar.pr.gov.br>
+Uploaders: Debian Ruby Extras Maintainers <pkg-ruby-extras-maintainers at lists.alioth.debian.org>, Antonio S. de A. Terceiro <asaterceiro at inf.ufrgs.br>, David Moreno Garza <damog at debian.org>, David Nusinow <dnusinow at debian.org>, Paul van Tilburg <paulvt at debian.org>, Esteban Manchado Velázquez <zoso at debian.org>, Arnaud Cornet <arnaud.cornet at gmail.com>, Lucas Nussbaum <lucas at lucas-nussbaum.net>, Thierry Reding <thierry at doppeltgemoppelt.de>, Marc Dequènes (Duck) <Duck at DuckCorp.org>, Ari Pollak <ari at debian.org>, Daigo Moriwaki <daigo at debian.org>, Vincent Fourmond <vincent.fourmond at 9online.fr>, Rudi Cilibrasi <cilibrar at cilibrar.com>, Patrick Ringl <patrick_ at freenet.de>
+Build-Depends: debhelper (>> 4.1.0), cdbs, ruby-pkg-tools (>= 0.8), ruby, ruby1.8-dev, libxml2-dev, libxslt1-dev, zlib1g-dev
+Standards-Version: 3.7.2
+
+Package: libxml-ruby
+Architecture: all
+Depends: libxml-ruby1.8
+Description: Ruby interface to libxml
+ libxml-ruby is a Ruby interface for processing XML. It supports
+ XPath, XPointer, and other features. Internally, it uses libxml
+ and libxslt.
+
+Package: libxml-ruby1.8
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: Ruby interface to libxml
+ libxml-ruby is a Ruby interface for processing XML. It supports
+ XPath, XPointer, and other features. Internally, it uses libxml
+ and libxslt.
Added: packages-wip/libxml-ruby/trunk/debian/control.in
===================================================================
--- packages-wip/libxml-ruby/trunk/debian/control.in 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/debian/control.in 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,23 @@
+Source: libxml-ruby
+Section: interpreters
+Priority: optional
+Maintainer: Filipe Lautert <filipelautert at celepar.pr.gov.br>
+Uploaders: @RUBY_EXTRAS_TEAM@
+Build-Depends: debhelper (>> 4.1.0), cdbs, ruby-pkg-tools (>= 0.8), ruby, ruby1.8-dev, libxml2-dev, libxslt1-dev, zlib1g-dev
+Standards-Version: 3.7.2
+
+Package: libxml-ruby
+Architecture: all
+Depends: libxml-ruby1.8
+Description: Ruby interface to libxml
+ libxml-ruby is a Ruby interface for processing XML. It supports
+ XPath, XPointer, and other features. Internally, it uses libxml
+ and libxslt.
+
+Package: libxml-ruby1.8
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: Ruby interface to libxml
+ libxml-ruby is a Ruby interface for processing XML. It supports
+ XPath, XPointer, and other features. Internally, it uses libxml
+ and libxslt.
Added: packages-wip/libxml-ruby/trunk/debian/copyright
===================================================================
--- packages-wip/libxml-ruby/trunk/debian/copyright 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/debian/copyright 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,22 @@
+# $Id: LICENSE,v 1.3 2006/02/28 09:57:52 roscopeco Exp $
+
+ Copyright (c) 2002-2006 Sean Chittenden <sean at chittenden.org> and contributors
+ Copyright (c) 2001 Wai-Sun "Squidster" Chia <waisun.chia at compaq.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
Added: packages-wip/libxml-ruby/trunk/debian/docs
===================================================================
--- packages-wip/libxml-ruby/trunk/debian/docs 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/debian/docs 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,3 @@
+README
+tests
+TODO
Added: packages-wip/libxml-ruby/trunk/debian/rules
===================================================================
--- packages-wip/libxml-ruby/trunk/debian/rules 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/debian/rules 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,9 @@
+#!/usr/bin/make -f
+#
+# CDBS file to build the Foo Ruby package.
+
+include /usr/share/cdbs/1/rules/debhelper.mk
+include /usr/share/ruby-pkg-tools/1/class/ruby-extconf-rb.mk
+include /usr/share/ruby-pkg-tools/1/rules/uploaders.mk
+
+DEB_COMPRESS_EXCLUDE := .xml
Property changes on: packages-wip/libxml-ruby/trunk/debian/rules
___________________________________________________________________
Name: svn:executable
+ *
Added: packages-wip/libxml-ruby/trunk/debian/watch
===================================================================
--- packages-wip/libxml-ruby/trunk/debian/watch 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/debian/watch 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,2 @@
+version=3
+http://rubyforge.org/frs/?group_id=494 .*/libxml-ruby-(.*)\.tar\.gz
Added: packages-wip/libxml-ruby/trunk/extconf.rb
===================================================================
--- packages-wip/libxml-ruby/trunk/extconf.rb 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/extconf.rb 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,95 @@
+#!/usr/bin/env ruby
+
+require 'mkmf'
+
+if defined?(CFLAGS)
+ if CFLAGS.index(CONFIG['CCDLFLAGS'])
+ $CFLAGS = CFLAGS
+ else
+ $CFLAGS = CFLAGS + ' ' + CONFIG['CCDLFLAGS']
+ end
+else
+ $CFLAGS = CONFIG['CFLAGS']
+end
+$LDFLAGS = CONFIG['LDFLAGS']
+$LIBPATH.push(Config::CONFIG['libdir'])
+
+def crash(str)
+ printf(" extconf failure: %s\n", str)
+ exit 1
+end
+
+dir_config('iconv')
+dir_config('xml2')
+dir_config('zlib')
+
+have_library('socket','socket')
+have_library('nsl','gethostbyname')
+
+unless have_library('m', 'atan')
+ # try again for gcc 4.0
+ saveflags = $CFLAGS
+ $CFLAGS += ' -fno-builtin'
+ unless have_library('m', 'atan')
+ crash('need libm')
+ end
+ $CFLAGS = saveflags
+end
+
+unless have_library('z', 'inflate')
+ crash('need zlib')
+else
+ $defs.push('-DHAVE_ZLIB_H')
+end
+
+unless have_library('iconv','iconv_open') or
+ have_library('c','iconv_open') or
+ have_library('recode','iconv_open') or
+ have_library('iconv')
+ crash(<<EOL)
+need libiconv.
+
+ Install the libiconv or try passing one of the following options
+ to extconf.rb:
+
+ --with-iconv-dir=/path/to/iconv
+ --with-iconv-lib=/path/to/iconv/lib
+ --with-iconv-include=/path/to/iconv/include
+EOL
+end
+
+unless (have_library('xml2', 'xmlParseDoc') or
+ find_library('xml2', '/opt/lib', '/usr/local/lib', '/usr/lib')) and
+ (have_header('libxml/xmlversion.h') or
+ find_header('libxml/xmlversion.h',
+ '/opt/include/libxml2',
+ '/usr/local/include/libxml2',
+ '/usr/include/libxml2'))
+ crash(<<EOL)
+need libxml2.
+
+ Install the library or try one of the following options to extconf.rb:
+
+ --with-xml2-dir=/path/to/libxml2
+ --with-xml2-lib=/path/to/libxml2/lib
+ --with-xml2-include=/path/to/libxml2/include
+EOL
+end
+
+unless have_library('xml2', 'xmlDocFormatDump')
+ crash('Your version of libxml2 is too old. Please upgrade.')
+end
+
+unless have_func('docbCreateFileParserCtxt')
+ crash('Need docbCreateFileParserCtxt')
+end
+
+if try_compile('int main() { return 0; }','-Wall')
+ $CFLAGS << ' -Wall'
+end
+
+$CFLAGS << ' ' << $INCFLAGS
+$INSTALLFILES = [["../xml/libxml.rb", "$(RUBYLIBDIR)", "../xml"]]
+
+create_header()
+create_makefile('xml/libxml_so')
Added: packages-wip/libxml-ruby/trunk/libxml.c
===================================================================
--- packages-wip/libxml-ruby/trunk/libxml.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/libxml.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,86 @@
+/* $Id: libxml.c,v 1.2 2006/04/17 13:30:22 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#include "libxml.h"
+
+/* Ruby's util.h has ruby_strdup */
+#include "util.h"
+
+#ifdef xmlMalloc
+#undef xmlMalloc
+#endif
+#ifdef xmlRealloc
+#undef xmlRealloc
+#endif
+#ifdef xmlMemStrdup
+#undef xmlMemStrdup
+#endif
+#ifdef xmlMemFree
+#undef xmlMemFree
+#endif
+
+#ifdef RubyMemMalloc
+#undef RubyMemMalloc
+#endif
+#ifdef RubyMemRealloc
+#undef RubyMemRealloc
+#endif
+#ifdef RubyMemStrdup
+#undef RubyMemStrdup
+#endif
+#ifdef RubyMemFree
+#undef RubyMemFree
+#endif
+
+#define RubyMemFree ruby_xfree
+#define RubyMemRealloc ruby_xrealloc
+#define RubyMemMalloc ruby_xmalloc
+#define RubyMemStrdup ruby_strdup
+
+VALUE mXML;
+
+static xmlFreeFunc freeFunc = NULL;
+static xmlMallocFunc mallocFunc = NULL;
+static xmlReallocFunc reallocFunc = NULL;
+static xmlStrdupFunc strdupFunc = NULL;
+
+void
+Init_libxml_so(void) {
+ /* Some libxml memory goo that should be done before anything else */
+ xmlMemGet((xmlFreeFunc *) & freeFunc,
+ (xmlMallocFunc *) & mallocFunc,
+ (xmlReallocFunc *) & reallocFunc,
+ (xmlStrdupFunc *) & strdupFunc);
+
+ if (xmlMemSetup((xmlFreeFunc)RubyMemFree, (xmlMallocFunc)RubyMemMalloc,
+ (xmlReallocFunc)RubyMemRealloc, (xmlStrdupFunc)RubyMemStrdup) != 0)
+ rb_fatal("could not install the memory handlers for libxml");
+ xmlInitParser();
+
+ mXML = rb_define_module("XML");
+
+ rb_define_const(mXML, "XML_NAMESPACE", rb_str_new2((const char*)XML_XML_NAMESPACE));
+
+ ruby_init_parser();
+ ruby_init_xml_parser_context();
+ ruby_init_xml_attr();
+ ruby_init_xml_attribute();
+ ruby_init_xml_document();
+ ruby_init_xml_node();
+ ruby_init_xml_node_set();
+ ruby_init_xml_ns();
+ ruby_init_xml_sax_parser();
+ ruby_init_xml_tree();
+ ruby_init_xml_xinclude();
+ ruby_init_xml_xpath();
+ ruby_init_xml_xpath_context();
+ ruby_init_xml_xpointer();
+ ruby_init_xml_xpointer_context();
+ ruby_init_input_callbacks(); /* MUFF */
+ ruby_init_xml_dtd(); /* MUFF */
+ ruby_init_xml_schema(); /* MUFF */
+
+ ruby_xml_parser_default_substitute_entities_set(cXMLParser, Qtrue);
+ ruby_xml_parser_default_load_external_dtd_set(cXMLParser, Qtrue);
+}
Added: packages-wip/libxml-ruby/trunk/libxml.h
===================================================================
--- packages-wip/libxml-ruby/trunk/libxml.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/libxml.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,82 @@
+/* Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RUBY_LIBXML_H__
+#define __RUBY_LIBXML_H__
+
+/* Don't nuke this block! It is used for automatically updating the
+ * versions below. VERSION = string formatting, VERNUM = numbered
+ * version for inline testing: increment both or none at all. */
+#define RUBY_LIBXML_VERSION "0.3.8"
+#define RUBY_LIBXML_VERNUM 38
+#define RUBY_LIBXML_VER_MAJ 0
+#define RUBY_LIBXML_VER_MIN 3
+#define RUBY_LIBXML_VER_MIC 8
+
+#include <ruby.h>
+#include <rubyio.h>
+#include <util.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/debugXML.h>
+#include <libxml/xmlversion.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/xpath.h>
+#include <libxml/valid.h>
+#include <libxml/catalog.h>
+#ifdef LIBXML_DEBUG_ENABLED
+#include <libxml/xpathInternals.h>
+#endif
+#ifdef LIBXML_XINCLUDE_ENABLED
+#include <libxml/xinclude.h>
+#endif
+#ifdef LIBXML_XPTR_ENABLED
+#include <libxml/xpointer.h>
+#endif
+
+#define RUBY_LIBXML_SRC_TYPE_NULL 0
+#define RUBY_LIBXML_SRC_TYPE_FILE 1
+#define RUBY_LIBXML_SRC_TYPE_STRING 2
+#define RUBY_LIBXML_SRC_TYPE_IO 3
+#define RUBY_LIBXML_SRC_TYPE_XPATH 4
+
+typedef struct rx_file_data {
+ VALUE filename; /* Filename/path to self */
+} rx_file_data;
+
+typedef struct rx_io_data {
+ VALUE io;
+} rx_io_data;
+
+typedef struct rx_string_data {
+ VALUE str;
+} rx_string_data;
+
+typedef struct rx_xpath_data {
+ VALUE ctxt;
+} rx_xpath_data;
+
+#include "ruby_xml_attr.h"
+#include "ruby_xml_attribute.h"
+#include "ruby_xml_document.h"
+#include "ruby_xml_node.h"
+#include "ruby_xml_node_set.h"
+#include "ruby_xml_ns.h"
+#include "ruby_xml_parser.h"
+#include "ruby_xml_parser_context.h"
+#include "ruby_xml_sax_parser.h"
+#include "ruby_xml_tree.h"
+#include "ruby_xml_xinclude.h"
+#include "ruby_xml_xpath.h"
+#include "ruby_xml_xpath_context.h"
+#include "ruby_xml_xpointer.h"
+#include "ruby_xml_xpointer_context.h"
+#include "ruby_xml_input_cbg.h"
+#include "ruby_xml_dtd.h"
+#include "ruby_xml_schema.h"
+
+extern VALUE mXML;
+
+void ruby_init_parser(void);
+void ruby_xml_parser_free(ruby_xml_parser *rxp);
+
+#endif
Added: packages-wip/libxml-ruby/trunk/libxml.rb
===================================================================
--- packages-wip/libxml-ruby/trunk/libxml.rb 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/libxml.rb 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,107 @@
+# $Id: libxml.rb,v 1.1 2006/04/17 13:30:22 roscopeco Exp $
+# Please see the LICENSE file for copyright and distribution information
+require 'xml/libxml_so'
+
+class XML::Node::Set
+ def empty? #:nodoc:
+ self.length <= 0
+ end
+
+ def first #:nodoc:
+ self.each { |n| return n }
+ end
+end
+
+class XML::Document
+ include Enumerable
+
+ # maybe, maybe not...
+ def each(&blk) #:nodoc:
+ find('//*').each(&blk)
+ end
+end
+
+class XML::Node::Set
+ # inefficient, but maybe can find a way to cache the
+ # ary and dump on change?
+ def [](i, count = nil) #:nodoc:
+ if count
+ to_a[i,count]
+ else
+ to_a[i]
+ end
+ end
+
+ def to_s #:nodoc:
+ to_a.to_s
+ end
+end
+
+module XML::SiblingEnum #:nodoc:all
+ private
+
+ # Iterates nodes and attributes
+ def siblings(node, &blk)
+ if n = node
+ loop do
+ blk.call(n)
+ break unless n = n.next
+ end
+ end
+ end
+end
+
+class XML::Node
+ include XML::SiblingEnum
+ include Enumerable
+ include Comparable
+
+ # maybe these don't belong on all nodes...
+ def each_child(&blk) #:nodoc:
+ siblings(child, &blk)
+ end
+
+ def each_attr(&blk) #:nodoc:
+ siblings(properties, &blk)
+ end
+
+ # all siblings INCLUDING self
+ def each_sibling(&blk) #:nodoc:
+ siblings(self, &blk)
+ end
+
+ # I guess this is what you'd expect?
+ alias :each :each_child
+
+ def to_a #:nodoc:
+ inject([]) { |ary,n| ary << n }
+ end
+
+ def <=>(other) #:nodoc:
+ to_s <=> other.to_s
+ end
+end
+
+class XML::Attr
+ include XML::SiblingEnum
+ include Enumerable
+
+ def each_sibling(&blk) #:nodoc:
+ siblings(self,&blk)
+ end
+
+ alias :each_attr :each_sibling
+ alias :each :each_sibling
+
+ def to_h #:nodoc:
+ inject({}) do |h,a| h[a.name] = a.value end
+ end
+
+ def to_a #:nodoc:
+ inject([]) do |ary,a| ary << [a.name, a.value] end
+ end
+
+ def to_s #:nodoc:
+ "#{name} = #{value}"
+ end
+end
Added: packages-wip/libxml-ruby/trunk/ruby_xml_attr.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_attr.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_attr.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,372 @@
+/* $Id: ruby_xml_attr.c,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#include "libxml.h"
+#include "ruby_xml_attr.h"
+
+VALUE cXMLAttr;
+
+void
+ruby_xml_attr_free(ruby_xml_attr *rxa) {
+ if (rxa->attr != NULL && !rxa->is_ptr) {
+ xmlUnlinkNode((xmlNodePtr)rxa->attr);
+ xmlFreeNode((xmlNodePtr)rxa->attr);
+ rxa->attr = NULL;
+ }
+
+ free(rxa);
+}
+
+
+/*
+ * call-seq:
+ * attr.child => node
+ *
+ * Obtain this attribute's child attribute(s).
+ */
+VALUE
+ruby_xml_attr_child_get(VALUE self) {
+ ruby_xml_attr *rxa;
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
+ if (rxa->attr->children == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_node_new2(cXMLNode, rxa->xd, rxa->attr->children));
+}
+
+
+/*
+ * call-seq:
+ * attr.child? => (true|false)
+ *
+ * Determine whether this attribute has child attributes.
+ */
+VALUE
+ruby_xml_attr_child_q(VALUE self) {
+ ruby_xml_attr *rxa;
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
+ if (rxa->attr->children == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * attr.doc => document
+ *
+ * Obtain the XML::Document this attribute is associated with,
+ * if any.
+ */
+VALUE
+ruby_xml_attr_doc_get(VALUE self) {
+ ruby_xml_attr *rxa;
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
+ if (rxa->attr->doc == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_document_new(cXMLDocument, rxa->attr->doc));
+}
+
+
+/*
+ * call-seq:
+ * attr.doc? => (true|false)
+ *
+ * Determine whether this attribute is associated with an
+ * XML::Document.
+ */
+VALUE
+ruby_xml_attr_doc_q(VALUE self) {
+ ruby_xml_attr *rxa;
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
+ if (rxa->attr->doc == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * attr.last => node
+ *
+ * Obtain the last attribute.
+ */
+VALUE
+ruby_xml_attr_last_get(VALUE self) {
+ ruby_xml_attr *rxa;
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
+ if (rxa->attr->last == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_node_new2(cXMLNode, rxa->xd, rxa->attr->last));
+}
+
+
+/*
+ * call-seq:
+ * attr.last? => (true|false)
+ *
+ * Determine whether this is the last attribute.
+ */
+VALUE
+ruby_xml_attr_last_q(VALUE self) {
+ ruby_xml_attr *rxa;
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
+ if (rxa->attr->last == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+static void
+ruby_xml_attr_mark(ruby_xml_attr *rxa) {
+ if (rxa == NULL) return;
+ if (!NIL_P(rxa->xd)) rb_gc_mark(rxa->xd);
+}
+
+
+/*
+ * call-seq:
+ * attr.name => "name"
+ *
+ * Obtain this attribute's name.
+ */
+VALUE
+ruby_xml_attr_name_get(VALUE self) {
+ ruby_xml_attr *rxa;
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
+
+ if (rxa->attr->name == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)rxa->attr->name));
+}
+
+
+VALUE
+ruby_xml_attr_new(VALUE class, VALUE xd, xmlAttrPtr attr) {
+ ruby_xml_attr *rxa;
+
+ rxa = ALLOC(ruby_xml_attr);
+ rxa->attr = attr;
+ rxa->xd = xd;
+ rxa->is_ptr = 0;
+ return(Data_Wrap_Struct(class, ruby_xml_attr_mark,
+ ruby_xml_attr_free, rxa));
+}
+
+
+VALUE
+ruby_xml_attr_new2(VALUE class, VALUE xd, xmlAttrPtr attr) {
+ ruby_xml_attr *rxa;
+
+ rxa = ALLOC(ruby_xml_attr);
+ rxa->attr = xmlCopyProp(attr->parent, attr);
+ rxa->xd = xd;
+ rxa->is_ptr = 0;
+ return(Data_Wrap_Struct(class, ruby_xml_attr_mark,
+ ruby_xml_attr_free, rxa));
+}
+
+
+/*
+ * call-seq:
+ * attr.next => node
+ *
+ * Obtain the next attribute.
+ */
+VALUE
+ruby_xml_attr_next_get(VALUE self) {
+ ruby_xml_attr *rxa;
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
+ if (rxa->attr->next == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_attr_new(cXMLAttr, rxa->xd, rxa->attr->next));
+}
+
+
+/*
+ * call-seq:
+ * attr.next? => (true|false)
+ *
+ * Determine whether there is a next attribute.
+ */
+VALUE
+ruby_xml_attr_next_q(VALUE self) {
+ ruby_xml_attr *rxa;
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
+ if (rxa->attr->next == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * attr.type_name => "attribute"
+ *
+ * Obtain this attribute node's type name.
+ */
+VALUE
+ruby_xml_attr_node_type_name(VALUE self) {
+ /* I think libxml2's naming convention blows monkey ass */
+ return(rb_str_new2("attribute"));
+}
+
+
+/*
+ * call-seq:
+ * attr.ns => namespace
+ *
+ * Obtain this attribute's associated XML::NS, if any.
+ */
+VALUE
+ruby_xml_attr_ns_get(VALUE self) {
+ ruby_xml_attr *rxa;
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
+ if (rxa->attr->ns == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_ns_new2(cXMLNS, rxa->xd, rxa->attr->ns));
+}
+
+
+/*
+ * call-seq:
+ * attr.ns? => (true|false)
+ *
+ * Determine whether this attribute has an associated
+ * namespace.
+ */
+VALUE
+ruby_xml_attr_ns_q(VALUE self) {
+ ruby_xml_attr *rxa;
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
+ if (rxa->attr->ns == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * attr.parent => node
+ *
+ * Obtain this attribute node's parent.
+ */
+VALUE
+ruby_xml_attr_parent_get(VALUE self) {
+ ruby_xml_attr *rxa;
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
+ if (rxa->attr->parent == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_node_new2(cXMLNode, rxa->xd, rxa->attr->parent));
+}
+
+
+/*
+ * call-seq:
+ * attr.parent? => (true|false)
+ *
+ * Determine whether this attribute has a parent.
+ */
+VALUE
+ruby_xml_attr_parent_q(VALUE self) {
+ ruby_xml_attr *rxa;
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
+ if (rxa->attr->parent == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * attr.prev => node
+ *
+ * Obtain the previous attribute.
+ */
+VALUE
+ruby_xml_attr_prev_get(VALUE self) {
+ ruby_xml_attr *rxa;
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
+ if (rxa->attr->prev == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_attr_new(cXMLAttr, rxa->xd, rxa->attr->prev));
+}
+
+
+/*
+ * call-seq:
+ * attr.prev? => (true|false)
+ *
+ * Determine whether there is a previous attribute.
+ */
+VALUE
+ruby_xml_attr_prev_q(VALUE self) {
+ ruby_xml_attr *rxa;
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
+ if (rxa->attr->prev == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * attr.value => "value"
+ *
+ * Obtain the value of this attribute.
+ */
+VALUE
+ruby_xml_attr_value(VALUE self) {
+ ruby_xml_attr *rxa;
+ xmlChar *value;
+
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
+ if (ruby_xml_attr_parent_q(self) == Qtrue) {
+ value = xmlGetProp(rxa->attr->parent, rxa->attr->name);
+ if (value != NULL)
+ return(rb_str_new2((const char*)value));
+ }
+ return(Qnil);
+}
+
+// Rdoc needs to know
+#ifdef RDOC_NEVER_DEFINED
+ mXML = rb_define_module("XML");
+#endif
+
+void
+ruby_init_xml_attr(void) {
+ cXMLAttr = rb_define_class_under(mXML, "Attr", rb_cObject);
+ rb_define_method(cXMLAttr, "child", ruby_xml_attr_child_get, 0);
+ rb_define_method(cXMLAttr, "child?", ruby_xml_attr_child_q, 0);
+ rb_define_method(cXMLAttr, "doc", ruby_xml_attr_doc_get, 0);
+ rb_define_method(cXMLAttr, "doc?", ruby_xml_attr_doc_q, 0);
+ rb_define_method(cXMLAttr, "last", ruby_xml_attr_last_get, 0);
+ rb_define_method(cXMLAttr, "last?", ruby_xml_attr_last_q, 0);
+ rb_define_method(cXMLAttr, "name", ruby_xml_attr_name_get, 0);
+ rb_define_method(cXMLAttr, "next", ruby_xml_attr_next_get, 0);
+ rb_define_method(cXMLAttr, "next?", ruby_xml_attr_next_q, 0);
+ rb_define_method(cXMLAttr, "node_type_name", ruby_xml_attr_node_type_name, 0);
+ rb_define_method(cXMLAttr, "ns", ruby_xml_attr_ns_get, 0);
+ rb_define_method(cXMLAttr, "ns?", ruby_xml_attr_ns_q, 0);
+ rb_define_method(cXMLAttr, "parent", ruby_xml_attr_parent_get, 0);
+ rb_define_method(cXMLAttr, "parent?", ruby_xml_attr_parent_q, 0);
+ rb_define_method(cXMLAttr, "prev", ruby_xml_attr_prev_get, 0);
+ rb_define_method(cXMLAttr, "prev?", ruby_xml_attr_prev_q, 0);
+ rb_define_method(cXMLAttr, "value", ruby_xml_attr_value, 0);
+}
Added: packages-wip/libxml-ruby/trunk/ruby_xml_attr.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_attr.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_attr.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,21 @@
+/* $Id: ruby_xml_attr.h,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RUBY_XML_ATTR__
+#define __RUBY_XML_ATTR__
+
+extern VALUE cXMLAttr;
+
+typedef struct ruby_xml_attr {
+ xmlAttrPtr attr;
+ VALUE xd;
+ int is_ptr;
+} ruby_xml_attr;
+
+void ruby_xml_attr_free(ruby_xml_attr *rxn);
+void ruby_init_xml_attr(void);
+VALUE ruby_xml_attr_new(VALUE class, VALUE xd, xmlAttrPtr attr);
+VALUE ruby_xml_attr_new2(VALUE class, VALUE xd, xmlAttrPtr attr);
+VALUE ruby_xml_attr_name_get(VALUE self);
+#endif
Added: packages-wip/libxml-ruby/trunk/ruby_xml_attribute.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_attribute.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_attribute.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,224 @@
+/* $Id: ruby_xml_attribute.c,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#include "libxml.h"
+#include "ruby_xml_attribute.h"
+
+VALUE cXMLAttribute;
+
+// TODO Wtf is this about? It's not referenced outside this file AFAIK...
+
+VALUE
+ruby_xml_attribute_child_get(VALUE self) {
+ ruby_xml_attribute *rxa;
+ Data_Get_Struct(self, ruby_xml_attribute, rxa);
+ if (rxa->attribute->children == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_node_new2(cXMLNode, rxa->xd, rxa->attribute->children));
+}
+
+
+VALUE
+ruby_xml_attribute_children_q(VALUE self) {
+ ruby_xml_attribute *rxa;
+ Data_Get_Struct(self, ruby_xml_attribute, rxa);
+ if (rxa->attribute->children == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+VALUE
+ruby_xml_attribute_default_get(VALUE self) {
+ ruby_xml_attribute *rxa;
+ Data_Get_Struct(self, ruby_xml_attribute, rxa);
+
+ if (rxa->attribute->defaultValue == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)rxa->attribute->defaultValue));
+}
+
+
+VALUE
+ruby_xml_attribute_element_get(VALUE self) {
+ ruby_xml_attribute *rxa;
+ Data_Get_Struct(self, ruby_xml_attribute, rxa);
+
+ if (rxa->attribute->elem == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)rxa->attribute->elem));
+}
+
+
+void
+ruby_xml_attribute_free(ruby_xml_attribute *rxa) {
+ if (rxa->attribute != NULL && !rxa->is_ptr) {
+ xmlUnlinkNode((xmlNodePtr)rxa->attribute);
+ xmlFreeNode((xmlNodePtr)rxa->attribute);
+ rxa->attribute = NULL;
+ }
+
+ free(rxa);
+}
+
+
+VALUE
+ruby_xml_attribute_last_get(VALUE self) {
+ ruby_xml_attribute *rxa;
+ Data_Get_Struct(self, ruby_xml_attribute, rxa);
+ if (rxa->attribute->last == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_node_new2(cXMLNode, rxa->xd, rxa->attribute->last));
+}
+
+
+VALUE
+ruby_xml_attribute_last_q(VALUE self) {
+ ruby_xml_attribute *rxa;
+ Data_Get_Struct(self, ruby_xml_attribute, rxa);
+ if (rxa->attribute->last == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+static void
+ruby_xml_attribute_mark(ruby_xml_attribute *rxa) {
+ if (rxa == NULL) return;
+ if (!NIL_P(rxa->xd)) rb_gc_mark(rxa->xd);
+}
+
+
+VALUE
+ruby_xml_attribute_name_get(VALUE self) {
+ ruby_xml_attribute *rxa;
+ Data_Get_Struct(self, ruby_xml_attribute, rxa);
+
+ if (rxa->attribute->name == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)rxa->attribute->name));
+}
+
+
+VALUE
+ruby_xml_attribute_new(VALUE class, VALUE xd, xmlAttributePtr attribute) {
+ ruby_xml_attribute *rxa;
+
+ rxa = ALLOC(ruby_xml_attribute);
+ rxa->is_ptr = 0;
+ rxa->attribute = attribute;
+ if (NIL_P(xd))
+ rxa->xd = Qnil;
+ else
+ rxa->xd = xd;
+ return(Data_Wrap_Struct(class, ruby_xml_attribute_mark,
+ ruby_xml_attribute_free, rxa));
+}
+
+
+VALUE
+ruby_xml_attribute_new2(VALUE class, VALUE xd, xmlAttributePtr attribute) {
+ ruby_xml_attribute *rxa;
+
+ rxa = ALLOC(ruby_xml_attribute);
+ rxa->is_ptr = 1;
+ rxa->attribute = attribute;
+ if (NIL_P(xd))
+ rxa->xd = Qnil;
+ else
+ rxa->xd = xd;
+ return(Data_Wrap_Struct(class, ruby_xml_attribute_mark,
+ ruby_xml_attribute_free, rxa));
+}
+
+
+VALUE
+ruby_xml_attribute_next_get(VALUE self) {
+ ruby_xml_attribute *rxa;
+ Data_Get_Struct(self, ruby_xml_attribute, rxa);
+ if (rxa->attribute->next == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_node_new2(cXMLNode, rxa->xd, rxa->attribute->next));
+}
+
+
+VALUE
+ruby_xml_attribute_next_q(VALUE self) {
+ ruby_xml_attribute *rxa;
+ Data_Get_Struct(self, ruby_xml_attribute, rxa);
+ if (rxa->attribute->next == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+VALUE
+ruby_xml_attribute_node_type_name(VALUE self) {
+ return(rb_str_new2("attribute"));
+}
+
+
+VALUE
+ruby_xml_attribute_prefix_get(VALUE self) {
+ ruby_xml_attribute *rxa;
+ Data_Get_Struct(self, ruby_xml_attribute, rxa);
+
+ if (rxa->attribute->prefix == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)rxa->attribute->prefix));
+}
+
+
+VALUE
+ruby_xml_attribute_prev_get(VALUE self) {
+ ruby_xml_attribute *rxa;
+ Data_Get_Struct(self, ruby_xml_attribute, rxa);
+ if (rxa->attribute->prev == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_node_new2(cXMLNode, rxa->xd, rxa->attribute->prev));
+}
+
+VALUE
+ruby_xml_attribute_prev_q(VALUE self) {
+ ruby_xml_attribute *rxa;
+ Data_Get_Struct(self, ruby_xml_attribute, rxa);
+ if (rxa->attribute->prev == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+// Rdoc maybe doesn't need to know
+// #ifdef RDOC_NEVER_DEFINED
+// mXML = rb_define_module("XML");
+// #endif
+
+void
+ruby_init_xml_attribute(void) {
+ cXMLAttribute = rb_define_class_under(mXML, "Attribute", rb_cObject);
+ rb_define_method(cXMLAttribute, "child", ruby_xml_attribute_child_get, 0);
+ rb_define_method(cXMLAttribute, "children?", ruby_xml_attribute_children_q, 0);
+ rb_define_method(cXMLAttribute, "default", ruby_xml_attribute_default_get, 0);
+ rb_define_method(cXMLAttribute, "element", ruby_xml_attribute_element_get, 0);
+ rb_define_method(cXMLAttribute, "last", ruby_xml_attribute_last_get, 0);
+ rb_define_method(cXMLAttribute, "last?", ruby_xml_attribute_last_q, 0);
+ rb_define_method(cXMLAttribute, "node_type_name", ruby_xml_attribute_node_type_name, 0);
+ rb_define_method(cXMLAttribute, "name", ruby_xml_attribute_name_get, 0);
+ rb_define_method(cXMLAttribute, "next", ruby_xml_attribute_next_get, 0);
+ rb_define_method(cXMLAttribute, "next?", ruby_xml_attribute_next_q, 0);
+ rb_define_method(cXMLAttribute, "prefix", ruby_xml_attribute_prefix_get, 0);
+ rb_define_method(cXMLAttribute, "prev", ruby_xml_attribute_prev_get, 0);
+ rb_define_method(cXMLAttribute, "prev?", ruby_xml_attribute_prev_q, 0);
+}
Added: packages-wip/libxml-ruby/trunk/ruby_xml_attribute.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_attribute.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_attribute.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,21 @@
+/* $Id: ruby_xml_attribute.h,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RUBY_XML_ATTRIBUTE__
+#define __RUBY_XML_ATTRIBUTE__
+
+extern VALUE cXMLAttribute;
+
+typedef struct ruby_xml_attribute {
+ xmlAttributePtr attribute;
+ VALUE xd;
+ int is_ptr;
+} ruby_xml_attribute;
+
+void ruby_xml_attribute_free(ruby_xml_attribute *rxa);
+void ruby_init_xml_attribute(void);
+VALUE ruby_xml_attribute_new(VALUE class, VALUE xd, xmlAttributePtr attribute);
+VALUE ruby_xml_attribute_new2(VALUE class, VALUE xd, xmlAttributePtr attribute);
+VALUE ruby_xml_attribute_name_get(VALUE self);
+#endif
Added: packages-wip/libxml-ruby/trunk/ruby_xml_document.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_document.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_document.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,1159 @@
+/* $Id: ruby_xml_document.c,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#include "libxml.h"
+#include "ruby_xml_document.h"
+
+VALUE cXMLDocument;
+
+/*
+ * call-seq:
+ * document.compression => num
+ *
+ * Obtain this document's compression mode identifier.
+ */
+VALUE
+ruby_xml_document_compression_get(VALUE self) {
+#ifdef HAVE_ZLIB_H
+ ruby_xml_document *rxd;
+ int compmode;
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+
+ compmode = xmlGetDocCompressMode(rxd->doc);
+ if (compmode == -1)
+ return(Qnil);
+ else
+ return(INT2NUM(compmode));
+#else
+ rb_warn("libxml not compiled with zlib support");
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * document.compression = num
+ *
+ * Set this document's compression mode.
+ */
+VALUE
+ruby_xml_document_compression_set(VALUE self, VALUE num) {
+#ifdef HAVE_ZLIB_H
+ ruby_xml_document *rxd;
+ int compmode;
+ Check_Type(num, T_FIXNUM);
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+
+ if (rxd->doc == NULL) {
+ return(Qnil);
+ } else {
+ xmlSetDocCompressMode(rxd->doc, NUM2INT(num));
+
+ compmode = xmlGetDocCompressMode(rxd->doc);
+ if (compmode == -1)
+ return(Qnil);
+ else
+ return(INT2NUM(compmode));
+ }
+#else
+ rb_warn("libxml compiled without zlib support");
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * document.compression? => (true|false)
+ *
+ * Determine whether this document is compressed.
+ */
+VALUE
+ruby_xml_document_compression_q(VALUE self) {
+#ifdef HAVE_ZLIB_H
+ ruby_xml_document *rxd;
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+
+ if (rxd->doc->compression != -1)
+ return(Qtrue);
+ else
+ return(Qfalse);
+#else
+ rb_warn("libxml compiled without zlib support");
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * document.child => node
+ *
+ * Get this document's child node.
+ */
+VALUE
+ruby_xml_document_child_get(VALUE self) {
+ ruby_xml_document *rxd;
+ ruby_xml_node *rxn;
+ VALUE node;
+
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+
+ if (rxd->doc->children == NULL)
+ return(Qnil);
+
+ node = ruby_xml_node_new2(cXMLNode, self, rxd->doc->children);
+ Data_Get_Struct(node, ruby_xml_node, rxn);
+ rxn->xd = self;
+ return(node);
+}
+
+
+/*
+ * call-seq:
+ * document.child? => (true|false)
+ *
+ * Determine whether this document has a child node.
+ */
+VALUE
+ruby_xml_document_child_q(VALUE self) {
+ ruby_xml_document *rxd;
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+
+ if (rxd->doc->children == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * document.dump([stream]) => true
+ *
+ * Dump this document's XML to the specified IO stream.
+ * If no stream is specified, stdout is used.
+ */
+VALUE
+ruby_xml_document_dump(int argc, VALUE *argv, VALUE self) {
+ OpenFile *fptr;
+ VALUE io;
+ FILE *out;
+ ruby_xml_document *rxd;
+
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+ if (rxd->doc == NULL)
+ return(Qnil);
+
+ switch (argc) {
+ case 0:
+ io = rb_stdout;
+ break;
+ case 1:
+ io = argv[0];
+ if (!rb_obj_is_kind_of(io, rb_cIO))
+ rb_raise(rb_eTypeError, "need an IO object");
+ break;
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)");
+ }
+
+ GetOpenFile(io, fptr);
+ rb_io_check_writable(fptr);
+ out = GetWriteFile(fptr);
+ xmlDocDump(out, rxd->doc);
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * document.debug_dump([stream]) => true
+ *
+ * Debug version of dump.
+ */
+VALUE
+ruby_xml_document_debug_dump(int argc, VALUE *argv, VALUE self) {
+#ifdef LIBXML_DEBUG_ENABLED
+ OpenFile *fptr;
+ VALUE io;
+ FILE *out;
+ ruby_xml_document *rxd;
+
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+ if (rxd->doc == NULL)
+ return(Qnil);
+
+ switch (argc) {
+ case 0:
+ io = rb_stderr;
+ break;
+ case 1:
+ io = argv[0];
+ if (!rb_obj_is_kind_of(io, rb_cIO))
+ rb_raise(rb_eTypeError, "need an IO object");
+ break;
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)");
+ }
+
+ GetOpenFile(io, fptr);
+ rb_io_check_writable(fptr);
+ out = GetWriteFile(fptr);
+ xmlDebugDumpDocument(out, rxd->doc);
+ return(Qtrue);
+#else
+ rb_warn("libxml was compiled without debugging support. Please recompile libxml and ruby-libxml");
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * document.debug_dump_head([stream]) => true
+ *
+ * Debug-dump this document's header to the specified IO stream.
+ * If no stream is specified, stdout is used.
+ */
+VALUE
+ruby_xml_document_debug_dump_head(int argc, VALUE *argv, VALUE self) {
+#ifdef LIBXML_DEBUG_ENABLED
+ OpenFile *fptr;
+ VALUE io;
+ FILE *out;
+ ruby_xml_document *rxd;
+
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+ if (rxd->doc == NULL)
+ return(Qnil);
+
+ switch (argc) {
+ case 0:
+ io = rb_stdout;
+ break;
+ case 1:
+ io = argv[0];
+ if (!rb_obj_is_kind_of(io, rb_cIO))
+ rb_raise(rb_eTypeError, "need an IO object");
+ break;
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)");
+ }
+
+ GetOpenFile(io, fptr);
+ rb_io_check_writable(fptr);
+ out = GetWriteFile(fptr);
+ xmlDebugDumpDocumentHead(out, rxd->doc);
+ return(Qtrue);
+#else
+ rb_warn("libxml was compiled without debugging support. Please recompile libxml and ruby-libxml");
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * document.format_dump([stream], [spacing]) => true
+ *
+ * Dump this document's formatted XML to the specified IO stream.
+ * If no stream is specified, stdout is used. If spacing is
+ * specified, it must be a boolean that determines whether
+ * spacing is used.
+ */
+VALUE
+ruby_xml_document_format_dump(int argc, VALUE *argv, VALUE self) {
+ OpenFile *fptr;
+ VALUE bool, io;
+ FILE *out;
+ ruby_xml_document *rxd;
+ int size, spacing;
+
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+ if (rxd->doc == NULL)
+ return(Qnil);
+
+ switch (argc) {
+ case 0:
+ io = rb_stdout;
+ spacing = 1;
+ break;
+ case 1:
+ io = argv[0];
+ if (!rb_obj_is_kind_of(io, rb_cIO))
+ rb_raise(rb_eTypeError, "need an IO object");
+ spacing = 1;
+ break;
+ case 2:
+ io = argv[0];
+ if (!rb_obj_is_kind_of(io, rb_cIO))
+ rb_raise(rb_eTypeError, "need an IO object");
+ bool = argv[1];
+ if (TYPE(bool) == T_TRUE)
+ spacing = 1;
+ else if (TYPE(bool) == T_FALSE)
+ spacing = 0;
+ else
+ rb_raise(rb_eTypeError, "incorect argument type, second argument must be bool");
+
+ break;
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)");
+ }
+
+ GetOpenFile(io, fptr);
+ rb_io_check_writable(fptr);
+ out = GetWriteFile(fptr);
+ size = xmlDocFormatDump(out, rxd->doc, spacing);
+ return(INT2NUM(size));
+}
+
+
+/*
+ * call-seq:
+ * document.debug_format_dump([stream]) => true
+ *
+ * *Deprecated* in favour of format_dump.
+ */
+VALUE
+ruby_xml_document_debug_format_dump(int argc, VALUE *argv, VALUE self) {
+ rb_warn("debug_format_dump has been deprecaited, use format_dump instead");
+ return(ruby_xml_document_format_dump(argc, argv, self));
+}
+
+
+/*
+ * call-seq:
+ * document.encoding => "encoding"
+ *
+ * Obtain the encoding specified by this document.
+ */
+VALUE
+ruby_xml_document_encoding_get(VALUE self) {
+ ruby_xml_document *rxd;
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+ if (rxd->doc->encoding == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)rxd->doc->encoding));
+}
+
+
+/*
+ * call-seq:
+ * document.encoding = "encoding"
+ *
+ * Set the encoding for this document.
+ */
+VALUE
+ruby_xml_document_encoding_set(VALUE self, VALUE encoding) {
+ ruby_xml_document *rxd;
+
+ Check_Type(encoding, T_STRING);
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+ rxd->doc->encoding = (xmlChar*)ruby_strdup(StringValuePtr(encoding));
+ return(ruby_xml_document_encoding_get(self));
+}
+
+
+/*
+ * call-seq:
+ * document.filename => "filename"
+ *
+ * Obtain the filename this document was read from.
+ */
+VALUE
+ruby_xml_document_filename_get(VALUE self) {
+ ruby_xml_document *rxd;
+ rx_file_data *data;
+
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+ if (rxd->data == NULL)
+ return(Qnil);
+
+ switch (rxd->data_type) {
+ case RUBY_LIBXML_SRC_TYPE_NULL:
+ return(Qnil);
+ case RUBY_LIBXML_SRC_TYPE_FILE:
+ data = (rx_file_data *)rxd->data;
+ return(data->filename);
+ default:
+ rb_fatal("Unknown document type in libxml");
+ }
+
+ return(Qnil);
+}
+
+
+/*
+ * call-seq:
+ * document.find(xpath_expr, [namespace]) => nodeset
+ *
+ * Find nodes matching the specified xpath expression, optionally
+ * using the specified namespace. Returns an XML::Node::Set.
+ */
+VALUE
+ruby_xml_document_find(int argc, VALUE *argv, VALUE self) {
+ int i, vargc;
+ VALUE *vargv;
+
+ if (argc > 2 || argc < 1)
+ rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
+
+ vargc = argc + 1;
+ vargv = ALLOC_N(VALUE, vargc + 1);
+ vargv[0] = ruby_xml_document_root_get(self);
+ for (i = 0; i<argc; i++)
+ vargv[i + 1] = argv[i];
+
+ return(ruby_xml_xpath_find2(vargc, vargv));
+}
+
+
+void
+ruby_xml_document_free(ruby_xml_document *rxd) {
+ void *data;
+
+ if (rxd->doc != NULL && !rxd->is_ptr) {
+ xmlFreeDoc(rxd->doc);
+ ruby_xml_parser_count--;
+ rxd->doc = NULL;
+ }
+
+ if (ruby_xml_parser_count == 0)
+ xmlCleanupParser();
+
+ switch(rxd->data_type) {
+ case RUBY_LIBXML_SRC_TYPE_NULL:
+ break;
+ case RUBY_LIBXML_SRC_TYPE_FILE:
+ data = (void*)(rx_file_data *)rxd->data;
+ free((rx_file_data *)data);
+ break;
+ case RUBY_LIBXML_SRC_TYPE_STRING:
+ data = (void*)(rx_string_data *)rxd->data;
+ free((rx_string_data *)data);
+ break;
+ case RUBY_LIBXML_SRC_TYPE_IO:
+ data = (void*)(rx_io_data *)rxd->data;
+ free((rx_io_data *)data);
+ break;
+ default:
+ rb_fatal("Unknown data type, %d", rxd->data_type);
+ }
+
+ free(rxd);
+}
+
+
+/*
+ * call-seq:
+ * XML::Document.new(xml_version = 1.0) => document
+ *
+ * Create a new XML::Document, optionally specifying the
+ * XML version.
+ */
+VALUE
+ruby_xml_document_initialize(int argc, VALUE *argv, VALUE class) {
+ VALUE docobj, xmlver;
+
+ switch (argc) {
+ case 0:
+ xmlver = rb_str_new2("1.0");
+ break;
+ case 1:
+ rb_scan_args(argc, argv, "01", &xmlver);
+ break;
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (need 0 or 1)");
+ }
+
+ docobj = ruby_xml_document_new2(cXMLDocument, xmlver);
+ return(docobj);
+}
+
+
+/*
+ * call-seq:
+ * document.last => node
+ *
+ * Obtain the last node.
+ */
+VALUE
+ruby_xml_document_last_get(VALUE self) {
+ ruby_xml_document *rxd;
+ ruby_xml_node *rxn;
+ VALUE node;
+
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+
+ if (rxd->doc->last == NULL)
+ return(Qnil);
+
+ node = ruby_xml_node_new2(cXMLNode, self, rxd->doc->last);
+ Data_Get_Struct(node, ruby_xml_node, rxn);
+ rxn->xd = self;
+ return(node);
+}
+
+
+/*
+ * call-seq:
+ * document.last? => (true|false)
+ *
+ * Determine whether there is a last node.
+ */
+VALUE
+ruby_xml_document_last_q(VALUE self) {
+ ruby_xml_document *rxd;
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+
+ if (rxd->doc->last == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+static void
+ruby_xml_document_mark(ruby_xml_document *rxd) {
+ if (rxd == NULL) return;
+ if (!NIL_P(rxd->xmlver)) rb_gc_mark(rxd->xmlver);
+}
+
+
+VALUE
+ruby_xml_document_new(VALUE class, xmlDocPtr doc) {
+ ruby_xml_document *rxd;
+
+ rxd = ALLOC(ruby_xml_document);
+ ruby_xml_parser_count++;
+
+ rxd->data = NULL;
+ rxd->data_type = RUBY_LIBXML_SRC_TYPE_NULL;
+ rxd->doc = doc;
+ rxd->is_ptr = 0;
+ rxd->xmlver = Qnil;
+
+ return(Data_Wrap_Struct(cXMLDocument, ruby_xml_document_mark,
+ ruby_xml_document_free, rxd));
+}
+
+
+VALUE
+ruby_xml_document_new2(VALUE class, VALUE xmlver) {
+ ruby_xml_document *rxd;
+
+ Check_Type(xmlver, T_STRING);
+ rxd = ALLOC(ruby_xml_document);
+ ruby_xml_parser_count++;
+
+ rxd->data = NULL;
+ rxd->data_type = RUBY_LIBXML_SRC_TYPE_NULL;
+ rxd->doc = xmlNewDoc((xmlChar*)StringValuePtr(xmlver));
+ rxd->is_ptr = 0;
+ rxd->xmlver = xmlver;
+
+ if (rxd->doc == NULL)
+ rb_fatal("bad");
+
+ return(Data_Wrap_Struct(cXMLDocument, ruby_xml_document_mark,
+ ruby_xml_document_free, rxd));
+}
+
+
+VALUE
+ruby_xml_document_new3(VALUE class) {
+ return(ruby_xml_document_new2(class, rb_str_new2("1.0")));
+}
+
+
+VALUE
+ruby_xml_document_new4(VALUE class, xmlDocPtr doc) {
+ ruby_xml_document *rxd;
+
+ rxd = ALLOC(ruby_xml_document);
+
+ rxd->data = NULL;
+ rxd->data_type = RUBY_LIBXML_SRC_TYPE_NULL;
+ rxd->doc = doc;
+ rxd->is_ptr = 1;
+ rxd->xmlver = Qnil;
+
+ return(Data_Wrap_Struct(cXMLDocument, ruby_xml_document_mark,
+ ruby_xml_document_free, rxd));
+}
+
+
+/*
+ * call-seq:
+ * XML::Document.file(filename) => document
+ *
+ * Create a new XML::Document by parsing the specified
+ * file.
+ */
+VALUE
+ruby_xml_document_new_file(VALUE class, VALUE filename) {
+ VALUE parser;
+
+ parser = ruby_xml_parser_new(cXMLParser);
+ ruby_xml_parser_filename_set(parser, filename);
+ return(ruby_xml_parser_parse(parser));
+}
+
+
+/*
+ * call-seq:
+ * document.next => node
+ *
+ * Obtain the next node.
+ */
+VALUE
+ruby_xml_document_next_get(VALUE self) {
+ ruby_xml_document *rxd;
+ ruby_xml_node *rxn;
+ VALUE node;
+
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+
+ if (rxd->doc->next == NULL)
+ return(Qnil);
+
+ node = ruby_xml_node_new2(cXMLNode, self, rxd->doc->next);
+ Data_Get_Struct(node, ruby_xml_node, rxn);
+ rxn->xd = self;
+ return(node);
+}
+
+
+/*
+ * call-seq:
+ * document.next? => (true|false)
+ *
+ * Determine whether there is a next node.
+ */
+VALUE
+ruby_xml_document_next_q(VALUE self) {
+ ruby_xml_document *rxd;
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+
+ if (rxd->doc->next == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * document.parent => node
+ *
+ * Obtain the parent node.
+ */
+VALUE
+ruby_xml_document_parent_get(VALUE self) {
+ ruby_xml_document *rxd;
+ ruby_xml_node *rxn;
+ VALUE node;
+
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+
+ if (rxd->doc->parent == NULL)
+ return(Qnil);
+
+ node = ruby_xml_node_new2(cXMLNode, self, rxd->doc->parent);
+ Data_Get_Struct(node, ruby_xml_node, rxn);
+ rxn->xd = self;
+ return(node);
+}
+
+
+/*
+ * call-seq:
+ * document.parent? => (true|false)
+ *
+ * Determine whether there is a parent node.
+ */
+VALUE
+ruby_xml_document_parent_q(VALUE self) {
+ ruby_xml_document *rxd;
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+
+ if (rxd->doc->parent == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * document.prev => node
+ *
+ * Obtain the previous node.
+ */
+VALUE
+ruby_xml_document_prev_get(VALUE self) {
+ ruby_xml_document *rxd;
+ ruby_xml_node *rxn;
+ VALUE node;
+
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+
+ if (rxd->doc->prev == NULL)
+ return(Qnil);
+
+ node = ruby_xml_node_new2(cXMLNode, self, rxd->doc->prev);
+ Data_Get_Struct(node, ruby_xml_node, rxn);
+ rxn->xd = self;
+ return(node);
+}
+
+
+/*
+ * call-seq:
+ * document.prev? => (true|false)
+ *
+ * Determine whether there is a previous node.
+ */
+VALUE
+ruby_xml_document_prev_q(VALUE self) {
+ ruby_xml_document *rxd;
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+
+ if (rxd->doc->prev == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * document["key"] => "value"
+ *
+ * Obtain the named property.
+ */
+VALUE
+ruby_xml_document_property_get(VALUE self, VALUE key) {
+ return(ruby_xml_node_property_get(ruby_xml_document_root_get(self), key));
+}
+
+
+/*
+ * call-seq:
+ * document["key"] = "value"
+ *
+ * Set the named property.
+ */
+VALUE
+ruby_xml_document_property_set(VALUE self, VALUE key, VALUE val) {
+ return(ruby_xml_node_property_set(ruby_xml_document_root_get(self), key, val));
+}
+
+
+/*
+ * call-seq:
+ * document.root => node
+ *
+ * Obtain the root node.
+ */
+VALUE
+ruby_xml_document_root_get(VALUE self) {
+ ruby_xml_document *rxd;
+ ruby_xml_node *rxn;
+ VALUE node;
+ xmlNodePtr root;
+
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+ root = xmlDocGetRootElement(rxd->doc);
+
+ if (root == NULL)
+ return(Qnil);
+
+ node = ruby_xml_node_new2(cXMLNode, self, root);
+ Data_Get_Struct(node, ruby_xml_node, rxn);
+ rxn->xd = self;
+ return(node);
+}
+
+
+/*
+ * call-seq:
+ * document.root = node
+ *
+ * Set the root node.
+ */
+VALUE
+ruby_xml_document_root_set(VALUE self, VALUE node) {
+ ruby_xml_document *rxd;
+ ruby_xml_node *rxn;
+ VALUE retnode;
+ xmlNodePtr root;
+
+ if (rb_obj_is_kind_of(node, cXMLNode) == Qfalse)
+ rb_raise(rb_eTypeError, "must pass an XML::Node type object");
+
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+ Data_Get_Struct(node, ruby_xml_node, rxn);
+ ruby_xml_node_set_ptr(node, 1);
+ root = xmlDocSetRootElement(rxd->doc, rxn->node);
+ if (root == NULL)
+ return(Qnil);
+
+ retnode = ruby_xml_node_new2(cXMLNode, self, root);
+ return(retnode);
+}
+
+
+/*
+ * call-seq:
+ * document.save(format = false)
+ *
+ * Save this document to the file given by filename,
+ * optionally formatting the output.
+ */
+VALUE
+ruby_xml_document_save(int argc, VALUE *argv, VALUE self) {
+ ruby_xml_document *rxd;
+ const char *filename;
+ int format, len;
+
+ format = 0;
+ switch (argc) {
+ case 1:
+ break;
+ case 2:
+ if (TYPE(argv[1]) == T_TRUE)
+ format = 1;
+ else if (TYPE(argv[1]) == T_FALSE)
+ format = 0;
+ else
+ rb_raise(rb_eTypeError, "wrong type of argument, must be bool");
+ break;
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)");
+ }
+
+ Check_Type(argv[0], T_STRING);
+ filename = StringValuePtr(argv[0]);
+
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+ len = xmlSaveFormatFileEnc(filename, rxd->doc, (const char*)rxd->doc->encoding, format);
+ if (len == -1)
+ rb_fatal("Unable to write out file");
+ else
+ return(INT2NUM(len));
+}
+
+
+/*
+ * call-seq:
+ * document.standalone? => (true|false)
+ *
+ * Determine whether this is a standalone document.
+ */
+VALUE
+ruby_xml_document_standalone_q(VALUE self) {
+ ruby_xml_document *rxd;
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+ if (rxd->doc->standalone)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * document.to_s => "xml"
+ *
+ * Coerce this document to a string representation
+ * of it's XML.
+ */
+VALUE
+ruby_xml_document_to_s(int argc, VALUE *argv, VALUE self) {
+ ruby_xml_document *rxd;
+ xmlChar *result;
+ int format, len;
+
+ switch (argc) {
+ case 0:
+ format = 1;
+ break;
+ case 1:
+ if (TYPE(argv[0]) == T_TRUE)
+ format = 1;
+ else if (TYPE(argv[0]) == T_FALSE)
+ format = 0;
+ else
+ rb_raise(rb_eTypeError, "wrong type of argument, must be bool");
+ break;
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (0 or 1)");
+ }
+
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+ if (rxd->doc == NULL) {
+ return(Qnil);
+ } else if (rxd->doc->encoding != NULL) {
+ if (format) {
+ xmlDocDumpFormatMemoryEnc(rxd->doc, &result, &len,
+ (const char*)rxd->doc->encoding, format);
+ } else {
+ xmlDocDumpMemoryEnc(rxd->doc, &result, &len,
+ (const char*)rxd->doc->encoding);
+ }
+ } else {
+ if (format)
+ xmlDocDumpFormatMemory(rxd->doc, &result, &len, format);
+ else
+ xmlDocDumpMemory(rxd->doc, &result, &len);
+ }
+
+ return(rb_str_new2((const char*)result));
+}
+
+
+/*
+ * call-seq:
+ * document.url => "url"
+ *
+ * Obtain this document's source URL, if any.
+ */
+VALUE
+ruby_xml_document_url_get(VALUE self) {
+ ruby_xml_document *rxd;
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+ if (rxd->doc->URL == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)rxd->doc->URL));
+}
+
+
+/*
+ * call-seq:
+ * document.version => "version"
+ *
+ * Obtain the XML version specified by this document.
+ */
+VALUE
+ruby_xml_document_version_get(VALUE self) {
+ ruby_xml_document *rxd;
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+ if (rxd->doc->version == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)rxd->doc->version));
+}
+
+
+/*
+ * call-seq:
+ * document.xinclude => num
+ *
+ * Process xinclude directives in this document.
+ */
+VALUE
+ruby_xml_document_xinclude(VALUE self) {
+#ifdef LIBXML_XINCLUDE_ENABLED
+ ruby_xml_document *rxd;
+ int ret;
+
+ Data_Get_Struct(self, ruby_xml_document, rxd);
+ ret = xmlXIncludeProcess(rxd->doc);
+ if (ret >= 0)
+ return(INT2NUM(ret));
+ else
+ rb_raise(eXMLXIncludeError, "error processing xinclude directives in document");
+#else
+ rb_warn("libxml was compiled without XInclude support. Please recompile libxml and ruby-libxml");
+ return(Qfalse);
+#endif
+}
+
+void
+LibXML_validity_error(void * ctxt, const char * msg, va_list ap)
+{
+ if (rb_block_given_p()) {
+ char buff[1024];
+ snprintf(buff, 1024, msg, ap);
+ rb_yield(rb_ary_new3(2, rb_str_new2(buff), Qtrue));
+ } else {
+ fprintf(stderr, "error -- found validity error: ");
+ fprintf(stderr, msg, ap);
+ }
+}
+
+void
+LibXML_validity_warning(void * ctxt, const char * msg, va_list ap)
+{
+ if (rb_block_given_p()) {
+ char buff[1024];
+ snprintf(buff, 1024, msg, ap);
+ rb_yield(rb_ary_new3(2, rb_str_new2(buff), Qfalse));
+ } else {
+ fprintf(stderr, "warning -- found validity error: ");
+ fprintf(stderr, msg, ap);
+ }
+}
+
+/*
+ * call-seq:
+ * document.validate(schema) => (true|false)
+ *
+ * Validate this document against the specified XML::Schema.
+ */
+VALUE
+ruby_xml_document_validate_schema(VALUE self, VALUE schema) {
+ xmlSchemaValidCtxtPtr vptr;
+ ruby_xml_document *c_doc;
+ ruby_xml_schema *c_schema;
+ int is_invalid;
+
+ Data_Get_Struct(self, ruby_xml_document, c_doc);
+ Data_Get_Struct(schema, ruby_xml_schema, c_schema);
+
+ vptr = xmlSchemaNewValidCtxt(c_schema->schema);
+
+ xmlSchemaSetValidErrors(vptr, (xmlSchemaValidityErrorFunc)LibXML_validity_error,
+ (xmlSchemaValidityWarningFunc)LibXML_validity_warning, NULL);
+
+ is_invalid = xmlSchemaValidateDoc(vptr, c_doc->doc);
+ xmlSchemaFreeValidCtxt(vptr);
+ if (is_invalid) {
+ return Qfalse;
+ } else {
+ return Qtrue;
+ }
+}
+
+
+/*
+ * call-seq:
+ * document.validate(schema) => (true|false)
+ *
+ * Validate this document against the specified XML::DTD.
+ */
+VALUE
+ruby_xml_document_validate_dtd(VALUE self, VALUE dtd) {
+ xmlValidCtxt cvp;
+ ruby_xml_document *c_doc;
+ ruby_xml_dtd *c_dtd;
+
+ Data_Get_Struct(self, ruby_xml_document, c_doc);
+ Data_Get_Struct(dtd, ruby_xml_dtd, c_dtd);
+
+ cvp.userData = NULL;
+ cvp.error = (xmlValidityErrorFunc)LibXML_validity_error;
+ cvp.warning = (xmlValidityWarningFunc)LibXML_validity_warning;
+
+ cvp.nodeNr = 0;
+ cvp.nodeTab = NULL;
+ cvp.vstateNr = 0;
+ cvp.vstateTab = NULL;
+
+ if ( xmlValidateDtd(&cvp, c_doc->doc, c_dtd->dtd) )
+ return(Qtrue);
+ else
+ return(Qfalse);
+
+// int xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd)
+/*
+int
+validate(self, ...)
+ xmlDocPtr self
+ PREINIT:
+ xmlValidCtxt cvp;
+ xmlDtdPtr dtd;
+ SV * dtd_sv;
+ STRLEN n_a, len;
+ CODE:
+ LibXML_init_error();
+ cvp.userData = (void*)PerlIO_stderr();
+ cvp.error = (xmlValidityErrorFunc)LibXML_validity_error;
+ cvp.warning = (xmlValidityWarningFunc)LibXML_validity_warning;
+ // we need to initialize the node stack, because perl might
+ // already messed it up.
+ //
+ cvp.nodeNr = 0;
+ cvp.nodeTab = NULL;
+ cvp.vstateNr = 0;
+ cvp.vstateTab = NULL;
+
+ if (items > 1) {
+ dtd_sv = ST(1);
+ if ( sv_isobject(dtd_sv) && (SvTYPE(SvRV(dtd_sv)) == SVt_PVMG) ) {
+ dtd = (xmlDtdPtr)PmmSvNode(dtd_sv);
+ }
+ else {
+ croak("is_valid: argument must be a DTD object");
+ }
+ RETVAL = xmlValidateDtd(&cvp, self , dtd);
+ }
+ else {
+ RETVAL = xmlValidateDocument(&cvp, self);
+ }
+ sv_2mortal(LibXML_error);
+
+ if (RETVAL == 0) {
+ LibXML_croak_error();
+ }
+ OUTPUT:
+ RETVAL
+*/
+}
+
+// Rdoc needs to know
+#ifdef RDOC_NEVER_DEFINED
+ mXML = rb_define_module("XML");
+#endif
+
+void
+ruby_init_xml_document(void) {
+ cXMLDocument = rb_define_class_under(mXML, "Document", rb_cObject);
+ rb_define_singleton_method(cXMLDocument, "file", ruby_xml_document_new_file, 1);
+ rb_define_singleton_method(cXMLDocument, "new", ruby_xml_document_initialize, -1);
+
+ //rb_raise(eXMLNodeFailedModify, "unable to add a child to the document");
+ //eDTDValidityWarning = rb_define_class_under(cXMLNode, "ValidityWarning", rb_eException);
+ //eDTDValidityError = rb_define_class_under(cXMLNode, "ValidityWarning", rb_eException);
+ rb_define_method(cXMLDocument, "[]", ruby_xml_document_property_get, 1);
+ rb_define_method(cXMLDocument, "[]=", ruby_xml_document_property_set, 2);
+ rb_define_method(cXMLDocument, "child", ruby_xml_document_child_get, 0);
+ rb_define_method(cXMLDocument, "child?", ruby_xml_document_child_q, 0);
+ rb_define_method(cXMLDocument, "compression", ruby_xml_document_compression_get, 0);
+ rb_define_method(cXMLDocument, "compression=", ruby_xml_document_compression_set, 1);
+ rb_define_method(cXMLDocument, "compression?", ruby_xml_document_compression_q, 0);
+ rb_define_method(cXMLDocument, "dump", ruby_xml_document_dump, -1);
+ rb_define_method(cXMLDocument, "debug_dump", ruby_xml_document_debug_dump, -1);
+ rb_define_method(cXMLDocument, "debug_dump_head", ruby_xml_document_debug_dump_head, -1);
+ rb_define_method(cXMLDocument, "debug_format_dump", ruby_xml_document_debug_format_dump, -1);
+ rb_define_method(cXMLDocument, "encoding", ruby_xml_document_encoding_get, 0);
+ rb_define_method(cXMLDocument, "encoding=", ruby_xml_document_encoding_set, 1);
+ rb_define_method(cXMLDocument, "filename", ruby_xml_document_filename_get, 0);
+ rb_define_method(cXMLDocument, "find", ruby_xml_document_find, -1);
+ rb_define_method(cXMLDocument, "format_dump", ruby_xml_document_format_dump, -1);
+ rb_define_method(cXMLDocument, "last", ruby_xml_document_last_get, 0);
+ rb_define_method(cXMLDocument, "last?", ruby_xml_document_last_q, 0);
+ rb_define_method(cXMLDocument, "next", ruby_xml_document_next_get, 0);
+ rb_define_method(cXMLDocument, "next?", ruby_xml_document_next_q, 0);
+ rb_define_method(cXMLDocument, "parent", ruby_xml_document_parent_get, 0);
+ rb_define_method(cXMLDocument, "parent?", ruby_xml_document_parent_q, 0);
+ rb_define_method(cXMLDocument, "prev", ruby_xml_document_prev_get, 0);
+ rb_define_method(cXMLDocument, "prev?", ruby_xml_document_prev_q, 0);
+ rb_define_method(cXMLDocument, "root", ruby_xml_document_root_get, 0);
+ rb_define_method(cXMLDocument, "root=", ruby_xml_document_root_set, 1);
+ rb_define_method(cXMLDocument, "save", ruby_xml_document_save, -1);
+ rb_define_method(cXMLDocument, "standalone?", ruby_xml_document_standalone_q, 0);
+ rb_define_method(cXMLDocument, "to_s", ruby_xml_document_to_s, -1);
+ rb_define_method(cXMLDocument, "url", ruby_xml_document_url_get, 0);
+ rb_define_method(cXMLDocument, "version", ruby_xml_document_version_get, 0);
+ rb_define_method(cXMLDocument, "xinclude", ruby_xml_document_xinclude, 0);
+ rb_define_method(cXMLDocument, "validate", ruby_xml_document_validate_dtd, 1);
+ rb_define_method(cXMLDocument, "validate_schema", ruby_xml_document_validate_schema, 1);
+}
Added: packages-wip/libxml-ruby/trunk/ruby_xml_document.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_document.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_document.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,27 @@
+/* $Id: ruby_xml_document.h,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RUBY_XML_DOCUMENT__
+#define __RUBY_XML_DOCUMENT__
+
+extern VALUE cXMLDocument;
+
+typedef struct rxp_document {
+ xmlDocPtr doc; /* Tree/DOM interface */
+ int data_type; /* The data type referenced by *data */
+ void *data; /* Pointer to an external structure of options */
+ int is_ptr; /* Determines if this object owns its data or points to it someplace else */
+ VALUE xmlver; /* T_STRING with the xml version */
+} ruby_xml_document;
+
+VALUE ruby_xml_document_filename_get(VALUE self);
+void ruby_xml_document_free(ruby_xml_document *rxd);
+VALUE ruby_xml_document_new(VALUE class, xmlDocPtr doc);
+VALUE ruby_xml_document_new2(VALUE class, VALUE xmlver);
+VALUE ruby_xml_document_new3(VALUE class);
+VALUE ruby_xml_document_new4(VALUE class, xmlDocPtr doc);
+VALUE ruby_xml_document_root_get(VALUE self);
+void ruby_init_xml_document(void);
+
+#endif
Added: packages-wip/libxml-ruby/trunk/ruby_xml_dtd.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_dtd.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_dtd.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,168 @@
+#include "libxml.h"
+#include "ruby_xml_dtd.h"
+
+VALUE cXMLDtd;
+
+void
+ruby_xml_dtd_free(ruby_xml_dtd *rxdtd) {
+ if (rxdtd->dtd != NULL) {
+ xmlFreeDtd(rxdtd->dtd);
+ rxdtd->dtd = NULL;
+ }
+
+ free(rxdtd);
+}
+
+static void
+ruby_xml_dtd_mark(ruby_xml_dtd *rxdtd) {
+ return;
+ //if (rxdtd == NULL) return;
+ //if (!NIL_P(rxd->xmlver)) rb_gc_mark(rxd->xmlver);
+}
+
+/*
+ * call-seq:
+ * XML::Dtd.new("public system") => dtd
+ * XML::Dtd.new("public", "system") => dtd
+ *
+ * Create a new Dtd from the specified public and system
+ * identifiers.
+ */
+VALUE
+ruby_xml_dtd_initialize(int argc, VALUE *argv, VALUE class) {
+ ruby_xml_dtd *rxdtd;
+ VALUE external, system, dtd_string;
+ xmlParserInputBufferPtr buffer;
+ xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
+ xmlChar *new_string;
+
+ // 1 argument -- string --> parsujeme jako dtd
+ // 2 argumenty -- public, system --> bude se hledat
+ switch (argc) {
+ case 2:
+ rb_scan_args(argc, argv, "20", &external, &system);
+
+ Check_Type(external, T_STRING);
+ Check_Type(system, T_STRING);
+ rxdtd = ALLOC(ruby_xml_dtd);
+ rxdtd->dtd = xmlParseDTD( (xmlChar*)StringValuePtr(external),
+ (xmlChar*)StringValuePtr(system) );
+ if (rxdtd->dtd == NULL) {
+ free(rxdtd);
+ return(Qfalse);
+ }
+
+ xmlSetTreeDoc( (xmlNodePtr)rxdtd->dtd, NULL );
+ return( Data_Wrap_Struct(cXMLDtd, ruby_xml_dtd_mark, ruby_xml_dtd_free, rxdtd) );
+ break;
+
+/*
+SV *
+new(CLASS, external, system)
+ char * CLASS
+ char * external
+ char * system
+ ALIAS:
+ parse_uri = 1
+ PREINIT:
+ xmlDtdPtr dtd = NULL;
+ CODE:
+ LibXML_error = sv_2mortal(newSVpv("", 0));
+ dtd = xmlParseDTD((const xmlChar*)external, (const xmlChar*)system);
+ if ( dtd == NULL ) {
+ XSRETURN_UNDEF;
+ }
+ xmlSetTreeDoc((xmlNodePtr)dtd, NULL);
+ RETVAL = PmmNodeToSv( (xmlNodePtr) dtd, NULL );
+ OUTPUT:
+ RETVAL
+*/
+
+ case 1:
+
+ rb_scan_args(argc, argv, "10", &dtd_string);
+ buffer = xmlAllocParserInputBuffer(enc);
+ //if ( !buffer) return Qnil
+ new_string = xmlStrdup((xmlChar*)StringValuePtr(dtd_string));
+ xmlParserInputBufferPush(buffer, xmlStrlen(new_string), (const char*)new_string);
+
+ rxdtd = ALLOC(ruby_xml_dtd);
+ rxdtd->dtd = xmlIOParseDTD(NULL, buffer, enc);
+
+ // NOTE: For some reason freeing this InputBuffer causes a segfault!
+ // xmlFreeParserInputBuffer(buffer);
+ xmlFree(new_string);
+
+ return( Data_Wrap_Struct(cXMLDtd, ruby_xml_dtd_mark, ruby_xml_dtd_free, rxdtd) );
+
+ break;
+/*
+SV * parse_string(CLASS, str, ...)
+ char * CLASS
+ char * str
+ PREINIT:
+ STRLEN n_a;
+ xmlDtdPtr res;
+ SV * encoding_sv;
+ xmlParserInputBufferPtr buffer;
+ xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
+ xmlChar * new_string;
+ STRLEN len;
+ CODE:
+ LibXML_init_error();
+ if (items > 2) {
+ encoding_sv = ST(2);
+ if (items > 3) {
+ croak("parse_string: too many parameters");
+ }
+ // warn("getting encoding...\n");
+ enc = xmlParseCharEncoding(SvPV(encoding_sv, n_a));
+ if (enc == XML_CHAR_ENCODING_ERROR) {
+ croak("Parse of encoding %s failed: %s", SvPV(encoding_sv, n_a), SvPV(LibXML_error, n_a));
+ }
+ }
+ buffer = xmlAllocParserInputBuffer(enc);
+ // buffer = xmlParserInputBufferCreateMem(str, xmlStrlen(str), enc);
+ if ( !buffer)
+ croak("cant create buffer!\n" );
+
+ new_string = xmlStrdup((const xmlChar*)str);
+ xmlParserInputBufferPush(buffer, xmlStrlen(new_string), (const char*)new_string);
+
+ res = xmlIOParseDTD(NULL, buffer, enc);
+
+ // NOTE: For some reason freeing this InputBuffer causes a segfault!
+ // xmlFreeParserInputBuffer(buffer);
+ xmlFree(new_string);
+
+ sv_2mortal( LibXML_error );
+ LibXML_croak_error();
+
+ if (res == NULL) {
+ croak("no DTD parsed!");
+ }
+ RETVAL = PmmNodeToSv((xmlNodePtr)res, NULL);
+ OUTPUT:
+ RETVAL
+ */
+
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
+ }
+
+ //docobj = ruby_xml_document_new2(cXMLDocument, xmlver);
+ return Qnil;
+}
+
+// Rdoc needs to know
+#ifdef RDOC_NEVER_DEFINED
+ mXML = rb_define_module("XML");
+#endif
+
+void
+ruby_init_xml_dtd(void) {
+ cXMLDtd = rb_define_class_under(mXML, "Dtd", rb_cObject);
+ rb_define_singleton_method(cXMLDtd, "new", ruby_xml_dtd_initialize, -1);
+ //rb_define_method(cXMLDocument, "xinclude", ruby_xml_document_xinclude, 0);
+}
+
Added: packages-wip/libxml-ruby/trunk/ruby_xml_dtd.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_dtd.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_dtd.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,17 @@
+#ifndef __RUBY_XML_DTD__
+#define __RUBY_XML_DTD__
+
+extern VALUE cXMLDtd;
+
+typedef struct rxp_dtd {
+ xmlDtdPtr dtd; /* DTD interface */
+ //int data_type; /* The data type referenced by *data */
+ //void *data; /* Pointer to an external structure of options */
+ //int is_ptr; /* Determines if this object owns its data or points to it someplace else */
+ //VALUE xmlver; /* T_STRING with the xml version */
+} ruby_xml_dtd;
+
+void ruby_init_xml_dtd(void);
+void ruby_dtd_free(ruby_xml_dtd *rxdtd);
+
+#endif
Added: packages-wip/libxml-ruby/trunk/ruby_xml_input_cbg.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_input_cbg.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_input_cbg.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,167 @@
+
+/* ruby support for custom scheme handlers */
+/* Author: Martin Povolny (xpovolny at fi.muni.cz) */
+
+#include "libxml.h"
+#include "ruby_xml_input_cbg.h"
+
+static ic_scheme *first_scheme = 0;
+
+int ic_match (char const *filename) {
+ ic_scheme *scheme;
+
+ //fprintf( stderr, "ic_match: %s\n", filename );
+
+ scheme = first_scheme;
+ while (0 != scheme) {
+ if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST scheme->scheme_name, scheme->name_len)) {
+ return 1;
+ }
+ scheme = scheme->next_scheme;
+ }
+ return 0;
+}
+
+void* ic_open (char const *filename) {
+ ic_doc_context *ic_doc;
+ ic_scheme *scheme;
+ VALUE res;
+
+ scheme = first_scheme;
+ while (0 != scheme) {
+ if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST scheme->scheme_name, scheme->name_len)) {
+ ic_doc = (ic_doc_context*)malloc( sizeof(ic_doc_context) );
+
+// MUFF res = rb_funcall(
+// rb_funcall( rb_mKernel,
+// rb_intern("const_get"), 1,
+// rb_str_new2(scheme->class) ),
+// rb_intern("document_query"), 1, rb_str_new2(filename) );
+ res = rb_funcall( scheme->class,
+ rb_intern("document_query"),
+ 1,
+ rb_str_new2(filename) );
+
+ ic_doc->buffer = strdup( StringValuePtr(res) );
+
+ ic_doc->bpos = ic_doc->buffer;
+ ic_doc->remaining = strlen(ic_doc->buffer);
+ return ic_doc;
+ }
+ scheme = scheme->next_scheme;
+ }
+ return 0;
+}
+
+int ic_read (void *context, char *buffer, int len) {
+ ic_doc_context *ic_doc;
+ int ret_len;
+ ic_doc = (ic_doc_context*)context;
+
+ if (len >= ic_doc->remaining) {
+ ret_len = ic_doc->remaining;
+ } else {
+ ret_len = len;
+ }
+ ic_doc->remaining -= ret_len;
+ strncpy( buffer, ic_doc->bpos, ret_len );
+ ic_doc->bpos += ret_len;
+
+ return ret_len;
+}
+
+int ic_close (void *context) {
+ free( ((ic_doc_context*)context)->buffer );
+ free( context );
+ return 1;
+}
+
+VALUE input_callbacks_register_input_callbacks() {
+ xmlRegisterInputCallbacks( ic_match, ic_open, ic_read, ic_close );
+ return(Qtrue);
+}
+
+VALUE
+input_callbacks_add_scheme (VALUE self, VALUE scheme_name, VALUE class) {
+ ic_scheme *scheme;
+
+ Check_Type(scheme_name, T_STRING);
+ //MUFF Check_Type(class, T_STRING);
+
+ scheme = (ic_scheme*)malloc(sizeof(ic_scheme));
+ scheme->next_scheme = 0;
+ scheme->scheme_name = strdup(StringValuePtr(scheme_name)); /* TODO alloc, dealloc */
+ scheme->name_len = strlen(scheme->scheme_name);
+ //MUFF scheme->class = strdup(StringValuePtr(class)); /* TODO alloc, dealloc */
+ scheme->class = class; /* TODO alloc, dealloc */
+
+ //fprintf( stderr, "registered: %s, %d, %s\n", scheme->scheme_name, scheme->name_len, scheme->class );
+
+ if (0 == first_scheme)
+ first_scheme = scheme;
+ else {
+ ic_scheme *pos;
+ pos = first_scheme;
+ while (0 != pos->next_scheme)
+ pos = pos->next_scheme;
+ pos->next_scheme = scheme;
+ }
+
+ return(Qtrue);
+}
+
+VALUE
+input_callbacks_remove_scheme (VALUE self, VALUE scheme_name) {
+ char *name;
+ ic_scheme *save_scheme, *scheme;
+
+ Check_Type(scheme_name, T_STRING);
+ name = StringValuePtr(scheme_name);
+
+ if (0 == first_scheme)
+ return Qfalse;
+
+ /* check the first one */
+ if (!strncmp(name, first_scheme->scheme_name, first_scheme->name_len)) {
+ save_scheme = first_scheme->next_scheme;
+
+ free(first_scheme->scheme_name);
+ //MUFF free(first_scheme->class);
+ free(first_scheme);
+
+ first_scheme = save_scheme;
+ return Qtrue;
+ }
+
+ scheme = first_scheme;
+ while (0 != scheme->next_scheme) {
+ if ( !strncmp( name, scheme->next_scheme->scheme_name, scheme->next_scheme->name_len ) ) {
+ save_scheme = scheme->next_scheme->next_scheme;
+
+ free(scheme->next_scheme->scheme_name);
+ //MUFF free(scheme->next_scheme->class);
+ free(scheme->next_scheme);
+
+ scheme->next_scheme = save_scheme;
+ return Qtrue;
+ }
+ scheme = scheme->next_scheme;
+ }
+ return Qfalse;
+}
+
+// Rdoc needs to know
+#ifdef RDOC_NEVER_DEFINED
+ mXML = rb_define_module("XML");
+#endif
+
+void
+ruby_init_input_callbacks(void) {
+ VALUE cInputCallbacks;
+ cInputCallbacks = rb_define_class_under(mXML, "InputCallbacks", rb_cObject);
+
+ /* Class Methods */
+ rb_define_singleton_method(cInputCallbacks, "register", input_callbacks_register_input_callbacks, 0);
+ rb_define_singleton_method(cInputCallbacks, "add_scheme", input_callbacks_add_scheme, 2);
+ rb_define_singleton_method(cInputCallbacks, "remove_scheme", input_callbacks_remove_scheme, 1);
+}
Added: packages-wip/libxml-ruby/trunk/ruby_xml_input_cbg.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_input_cbg.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_input_cbg.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,21 @@
+#ifndef _INPUT_CBG_
+#define _INPUT_CBG_
+
+void ruby_init_input_callbacks(void);
+
+typedef struct ic_doc_context {
+ char *buffer;
+ char *bpos;
+ int remaining;
+} ic_doc_context;
+
+typedef struct ic_scheme {
+ char *scheme_name;
+ //MUFF char *class;
+ VALUE class;
+ int name_len;
+
+ struct ic_scheme *next_scheme;
+} ic_scheme;
+
+#endif
Added: packages-wip/libxml-ruby/trunk/ruby_xml_node.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_node.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_node.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,2139 @@
+/* $Id: ruby_xml_node.c,v 1.3 2006/04/12 12:08:39 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#include "libxml.h"
+#include "ruby_xml_node.h"
+
+VALUE cXMLNode;
+VALUE eXMLNodeSetNamespace;
+VALUE eXMLNodeFailedModify;
+VALUE eXMLNodeUnknownType;
+
+/*
+ * call-seq:
+ * node.attribute? => (true|false)
+ *
+ * Determine whether this is an attribute node,
+ */
+VALUE
+ruby_xml_node_attribute_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_ATTRIBUTE_NODE)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * node.attribute_decl? => (true|false)
+ *
+ * Determine whether this is an attribute declaration node,
+ */
+VALUE
+ruby_xml_node_attribute_decl_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_ATTRIBUTE_DECL)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * node.base => "uri"
+ *
+ * Obtain this node's base URI.
+ */
+VALUE
+ruby_xml_node_base_get(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->doc == NULL)
+ return(Qnil);
+
+ // TODO some NULL checking, raises ArgumentError in Ruby:
+ // ArgumentError: NULL pointer given
+
+ return(rb_str_new2((const char*)xmlNodeGetBase(rxn->node->doc, rxn->node)));
+}
+
+
+// TODO node_base_set should support setting back to nil
+
+/*
+ * call-seq:
+ * node.base = "uri"
+ *
+ * Set this node's base URI.
+ */
+VALUE
+ruby_xml_node_base_set(VALUE self, VALUE uri) {
+ ruby_xml_node *node;
+
+ Check_Type(uri, T_STRING);
+ Data_Get_Struct(self, ruby_xml_node, node);
+ if (node->node->doc == NULL)
+ return(Qnil);
+
+ xmlNodeSetBase(node->node, (xmlChar*)StringValuePtr(uri));
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * node.cdata? => (true|false)
+ *
+ * Determine whether this is a #CDATA node
+ */
+VALUE
+ruby_xml_node_cdata_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_CDATA_SECTION_NODE)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * node.comment? => (true|false)
+ *
+ * Determine whether this is a comment node
+ */
+VALUE
+ruby_xml_node_comment_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_COMMENT_NODE)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * node << ("string" | node)
+ *
+ * Add the specified string or XML::Node to this node's
+ * content.
+ */
+VALUE
+ruby_xml_node_content_add(VALUE self, VALUE obj) {
+ ruby_xml_node *node;
+ VALUE str;
+
+ Data_Get_Struct(self, ruby_xml_node, node);
+ if (rb_obj_is_kind_of(obj, cXMLNode)) {
+ return(ruby_xml_node_child_set(self, obj));
+ } else if (TYPE(obj) == T_STRING) {
+ xmlNodeAddContent(node->node, (xmlChar*)StringValuePtr(obj));
+ return(obj);
+ } else {
+ str = rb_obj_as_string(obj);
+ if (NIL_P(str) || TYPE(str) != T_STRING)
+ rb_raise(rb_eTypeError, "invalid argument: must be string or XML::Node");
+
+ xmlNodeAddContent(node->node, (xmlChar*)StringValuePtr(str));
+ return(obj);
+ }
+}
+
+
+/*
+ * call-seq:
+ * node.content => "string"
+ *
+ * Obtain this node's content as a string.
+ */
+VALUE
+ruby_xml_node_content_get(VALUE self) {
+ ruby_xml_node *rxn;
+ xmlChar *content;
+ VALUE out;
+
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ content = xmlNodeGetContent(rxn->node);
+ out = rb_str_new2((const char *) content);
+ xmlFree(content);
+
+ return out;
+}
+
+/*
+ * call-seq:
+ * node.content = "string"
+ *
+ * Set this node's content to the specified string.
+ */
+VALUE
+ruby_xml_node_content_set(VALUE self, VALUE content) {
+ ruby_xml_node *node;
+
+ Check_Type(content, T_STRING);
+ Data_Get_Struct(self, ruby_xml_node, node);
+ xmlNodeSetContent(node->node, (xmlChar*)StringValuePtr(content));
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * node.content_stripped => "string"
+ *
+ * Obtain this node's stripped content.
+ *
+ * *Deprecated*: Stripped content can be obtained via the
+ * +content+ method.
+ */
+VALUE
+ruby_xml_node_content_stripped_get(VALUE self) {
+ ruby_xml_node *rxn;
+
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->content == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)xmlNodeGetContent(rxn->node)));
+}
+
+////////////////////////////////////////////////////
+// TODO This whole child thing seems to work in some odd ways.
+// Try setting child= to a node with multiple children,
+// then get it back through child= .
+
+/*
+ * call-seq:
+ * node.child => node
+ *
+ * Obtain this node's first child node, if any.
+ */
+VALUE
+ruby_xml_node_child_get(VALUE self) {
+ ruby_xml_node *node;
+ xmlNodePtr tmp;
+
+ Data_Get_Struct(self, ruby_xml_node, node);
+
+ switch (node->node->type) {
+ case XML_ELEMENT_NODE:
+ case XML_ENTITY_REF_NODE:
+ case XML_ENTITY_NODE:
+ case XML_PI_NODE:
+ case XML_COMMENT_NODE:
+ case XML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+ case XML_DOCB_DOCUMENT_NODE:
+#endif
+ case XML_HTML_DOCUMENT_NODE:
+ case XML_DTD_NODE:
+ tmp = node->node->children;
+ break;
+ case XML_ATTRIBUTE_NODE:
+ {
+ xmlAttrPtr attr = (xmlAttrPtr) node->node;
+ tmp = attr->children;
+ break;
+ }
+ default:
+ tmp = NULL;
+ break;
+ }
+
+ if (tmp == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_node_new2(cXMLNode, node->xd, tmp));
+}
+
+
+/*
+ * call-seq:
+ * node.child? => (true|false)
+ *
+ * Determine whether this node has at least one child.
+ */
+VALUE
+ruby_xml_node_child_q(VALUE self) {
+ ruby_xml_node *rxn;
+ xmlNodePtr node;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+
+ node = NULL;
+ switch (rxn->node->type) {
+ case XML_ELEMENT_NODE:
+ case XML_ENTITY_REF_NODE:
+ case XML_ENTITY_NODE:
+ case XML_PI_NODE:
+ case XML_COMMENT_NODE:
+ case XML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+ case XML_DOCB_DOCUMENT_NODE:
+#endif
+ case XML_HTML_DOCUMENT_NODE:
+ case XML_DTD_NODE:
+ node = rxn->node->children;
+ break;
+ case XML_ATTRIBUTE_NODE:
+ {
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
+ node = attr->children;
+ break;
+ }
+ default:
+ node = NULL;
+ }
+
+ if (node == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * node.child = node
+ *
+ * Set a child node for this node.
+ */
+VALUE
+ruby_xml_node_child_set(VALUE self, VALUE rnode) {
+ ruby_xml_node *cnode, *pnode;
+ xmlNodePtr ret;
+
+ if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
+ rb_raise(rb_eTypeError, "Must pass an XML::Node object");
+
+ Data_Get_Struct(self, ruby_xml_node, pnode);
+ Data_Get_Struct(rnode, ruby_xml_node, cnode);
+
+ ret = xmlAddChild(pnode->node, cnode->node);
+ if (ret == NULL)
+ rb_raise(eXMLNodeFailedModify, "unable to add a child to the document");
+
+ ruby_xml_node_set_ptr(rnode, 1);
+ return(ruby_xml_node_new2(cXMLNode, pnode->xd, ret));
+}
+
+////////////////////////////////////////////////
+// TODO new Documents seem to be created quite readily...
+
+/*
+ * call-seq:
+ * node.doc => document
+ *
+ * Obtain the XML::Document this node belongs to.
+ */
+VALUE
+ruby_xml_node_doc(VALUE self) {
+ ruby_xml_document *rxd;
+ ruby_xml_node *rxn;
+ xmlDocPtr doc;
+ VALUE docobj;
+
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+
+ switch (rxn->node->type) {
+ case XML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+ case XML_DOCB_DOCUMENT_NODE:
+#endif
+ case XML_HTML_DOCUMENT_NODE:
+ doc = NULL;
+ break;
+ case XML_ATTRIBUTE_NODE:
+ {
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
+ doc = attr->doc;
+ break;
+ }
+ case XML_NAMESPACE_DECL:
+ doc = NULL;
+ break;
+ default:
+ doc = rxn->node->doc;
+ break;
+ }
+
+ if (doc == NULL)
+ return(Qnil);
+
+ docobj = ruby_xml_document_new(cXMLDocument, doc);
+ Data_Get_Struct(docobj, ruby_xml_document, rxd);
+ rxd->is_ptr = 1;
+ return(docobj);
+}
+
+
+/*
+ * call-seq:
+ * node.docbook? => (true|false)
+ *
+ * Determine whether this is a docbook node.
+ */
+VALUE
+ruby_xml_node_docbook_doc_q(VALUE self) {
+#ifdef LIBXML_DOCB_ENABLED
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_DOCB_DOCUMENT_NODE)
+ return(Qtrue);
+ else
+ return(Qfalse);
+#else
+ rb_warn("libxml compiled without docbook support");
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * node.doctype? => (true|false)
+ *
+ * Determine whether this is a DOCTYPE node.
+ */
+VALUE
+ruby_xml_node_doctype_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_DOCUMENT_TYPE_NODE)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * node.document? => (true|false)
+ *
+ * Determine whether this is a document node.
+ */
+VALUE
+ruby_xml_node_document_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_DOCUMENT_NODE)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * node.dtd? => (true|false)
+ *
+ * Determine whether this is a DTD node.
+ */
+VALUE
+ruby_xml_node_dtd_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_DTD_NODE)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * node.dump => (true|nil)
+ *
+ * Dump this node to stdout.
+ */
+VALUE
+ruby_xml_node_dump(VALUE self) {
+ ruby_xml_node *rxn;
+ xmlBufferPtr buf;
+
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+
+ if (rxn->node->doc == NULL)
+ return(Qnil);
+
+ buf = xmlBufferCreate();
+ xmlNodeDump(buf, rxn->node->doc, rxn->node, 0, 1);
+ xmlBufferDump(stdout, buf);
+ xmlBufferFree(buf);
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * node.debug_dump => (true|nil)
+ *
+ * Dump this node to stdout, including any debugging
+ * information.
+ */
+VALUE
+ruby_xml_node_debug_dump(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+
+ if (rxn->node->doc == NULL)
+ return(Qnil);
+
+ xmlElemDump(stdout, rxn->node->doc, rxn->node);
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * node.element? => (true|false)
+ *
+ * Determine whether this is an element node.
+ */
+VALUE
+ruby_xml_node_element_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_ELEMENT_NODE)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * node.element_decl? => (true|false)
+ *
+ * Determine whether this is an element declaration node.
+ */
+VALUE
+ruby_xml_node_element_decl_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_ELEMENT_DECL)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * node.empty? => (true|false)
+ *
+ * Determine whether this node is empty.
+ */
+VALUE
+ruby_xml_node_empty_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node == NULL)
+ return(Qnil);
+
+ return((xmlIsBlankNode(rxn->node) == 1) ? Qtrue : Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * node.entity? => (true|false)
+ *
+ * Determine whether this is an entity node.
+ */
+VALUE
+ruby_xml_node_entity_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_ENTITY_NODE)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * node.entity_ref? => (true|false)
+ *
+ * Determine whether this is an entity reference node.
+ */
+VALUE
+ruby_xml_node_entity_ref_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_ENTITY_REF_NODE)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+VALUE ruby_xml_node_to_s(VALUE self);
+
+/*
+ * call-seq:
+ * node.eql?(other_node) => (true|false)
+ *
+ * Test equality between the two nodes. Equality is determined based
+ * on the XML representation of the nodes.
+ */
+VALUE
+ruby_xml_node_eql_q(VALUE self, VALUE other) {
+ // TODO this isn't the best way to handle this
+ ruby_xml_node *rxn, *orxn;
+ VALUE thisxml, otherxml;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ Data_Get_Struct(other, ruby_xml_node, orxn);
+ thisxml = ruby_xml_node_to_s(self);
+ otherxml = ruby_xml_node_to_s(other);
+
+ return(rb_funcall(thisxml, rb_intern("=="), 1, otherxml));
+}
+
+
+/*
+ * call-seq:
+ * node.find(xpath_expr, namespace = [any]) => nodeset
+ *
+ * Find nodes matching the specified xpath expression, optionally
+ * using the specified namespaces. Returns an XML::Node::Set.
+ */
+VALUE
+ruby_xml_node_find(int argc, VALUE *argv, VALUE self) {
+ int i, vargc;
+ VALUE *vargv;
+
+ if (argc > 2 || argc < 1)
+ rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
+
+ vargc = argc + 1;
+ vargv = ALLOC_N(VALUE, vargc + 1);
+ vargv[0] = self;
+ for (i = 0; i<argc; i++)
+ vargv[i + 1] = argv[i];
+
+ return(ruby_xml_xpath_find2(vargc, vargv));
+}
+
+/*
+ * call-seq:
+ * node.find_first(xpath_expr, namespace = [any]) => nodeset
+ *
+ * Find the first node matching the specified xpath expression, optionally
+ * using the specified namespaces. Returns an XML::Node.
+ */
+VALUE
+ruby_xml_node_find_first(int argc, VALUE *argv, VALUE self) {
+ VALUE ns = ruby_xml_node_find(argc, argv, self);
+ ruby_xml_node_set *rxnset;
+
+ Data_Get_Struct(ns, ruby_xml_node_set, rxnset);
+ if (rxnset->node_set == NULL || rxnset->node_set->nodeNr < 1)
+ return(Qnil);
+
+ VALUE nodeobj;
+ switch(rxnset->node_set->nodeTab[0]->type) {
+ case XML_ATTRIBUTE_NODE:
+ nodeobj = ruby_xml_attr_new2(cXMLAttr, rxnset->xd, (xmlAttrPtr)rxnset->node_set->nodeTab[0]);
+ break;
+ default:
+ nodeobj = ruby_xml_node_new2(cXMLNode, rxnset->xd, rxnset->node_set->nodeTab[0]);
+ }
+
+ return(nodeobj);
+}
+
+
+/*
+ * call-seq:
+ * node.fragment? => (true|false)
+ *
+ * Determine whether this node is a fragment.
+ */
+VALUE
+ruby_xml_node_fragment_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_DOCUMENT_FRAG_NODE)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+void ruby_xml_node_free(ruby_xml_node *rxn) {
+ if (rxn->node != NULL && !rxn->is_ptr) {
+ xmlUnlinkNode(rxn->node);
+ xmlFreeNode(rxn->node);
+ rxn->node = NULL;
+ }
+
+ free(rxn);
+}
+
+
+/*
+ * call-seq:
+ * node.hash => fixnum
+ *
+ * Returns the hash-code for this node. This is the hash of the XML
+ * representation in order to be consistent with eql.
+ */
+VALUE
+ruby_xml_node_hash(VALUE self) {
+ ruby_xml_node *rxn;
+ VALUE thisxml;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ thisxml = ruby_xml_node_to_s(self);
+
+ return(rb_funcall(thisxml, rb_intern("hash"), 0));
+}
+
+
+/*
+ * call-seq:
+ * node.html_doc? => (true|false)
+ *
+ * Determine whether this node is an html document node.
+ */
+VALUE
+ruby_xml_node_html_doc_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_HTML_DOCUMENT_NODE)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * XML::Node.new(name, content = nil) => node
+ *
+ * Create a new node with the specified name, optionally setting
+ * the node's content.
+ */
+VALUE
+ruby_xml_node_initialize(int argc, VALUE *argv, VALUE class) {
+ ruby_xml_node *rxn;
+ VALUE name, node, str;
+
+ str = Qnil;
+
+ switch(argc) {
+ case 2:
+ switch (TYPE(str)) {
+ case T_STRING:
+ str = argv[1];
+ break;
+ default:
+ str = rb_obj_as_string(argv[1]);
+ if (NIL_P(str))
+ Check_Type(str, T_STRING);
+ break;
+ }
+
+ /* Intentionally fall through to case 1: as a way of setting up
+ * the object. Sneaky, but effective. Probably should use a goto
+ * instead. */
+ case 1:
+ name = argv[0];
+ Check_Type(name, T_STRING);
+ node = ruby_xml_node_new(class, NULL);
+ Data_Get_Struct(node, ruby_xml_node, rxn);
+ rxn->node = xmlNewNode(NULL, (xmlChar*)StringValuePtr(name));
+ if (rxn->node == NULL)
+ return(Qnil);
+
+ if (!NIL_P(str))
+ ruby_xml_node_content_set(node, str);
+
+ break;
+
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
+ }
+
+ return(node);
+}
+
+
+/*
+ * call-seq:
+ * node.lang => "string"
+ *
+ * Obtain the language set for this node, if any.
+ * This is set in XML via the xml:lang attribute.
+ */
+VALUE
+ruby_xml_node_lang_get(VALUE self) {
+ ruby_xml_node *rxn;
+ xmlChar *lang;
+
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ lang = xmlNodeGetLang(rxn->node);
+
+ if (lang == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)lang));
+}
+
+
+// TODO node_lang_set should support setting back to nil
+
+/*
+ * call-seq:
+ * node.lang = "string"
+ *
+ * Set the language for this node. This affects the value
+ * of the xml:lang attribute.
+ */
+VALUE
+ruby_xml_node_lang_set(VALUE self, VALUE lang) {
+ ruby_xml_node *node;
+
+ Check_Type(lang, T_STRING);
+ Data_Get_Struct(self, ruby_xml_node, node);
+ xmlNodeSetLang(node->node, (xmlChar*)StringValuePtr(lang));
+
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * node.last => node
+ *
+ * Obtain the last child node of this node, if any.
+ */
+VALUE
+ruby_xml_node_last_get(VALUE self) {
+ ruby_xml_node *rxn;
+ xmlNodePtr node;
+
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+
+ switch (rxn->node->type) {
+ case XML_ELEMENT_NODE:
+ case XML_ENTITY_REF_NODE:
+ case XML_ENTITY_NODE:
+ case XML_PI_NODE:
+ case XML_COMMENT_NODE:
+ case XML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+ case XML_DOCB_DOCUMENT_NODE:
+#endif
+ case XML_HTML_DOCUMENT_NODE:
+ case XML_DTD_NODE:
+ node = rxn->node->last;
+ break;
+ case XML_ATTRIBUTE_NODE:
+ {
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
+ node = attr->last;
+ }
+ default:
+ node = NULL;
+ break;
+ }
+
+ if (node == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_node_new2(cXMLNode, rxn->xd, node));
+}
+
+
+/*
+ * call-seq:
+ * node.last? => (true|false)
+ *
+ * Determine whether this node has a last child node.
+ */
+VALUE
+ruby_xml_node_last_q(VALUE self) {
+ ruby_xml_node *rxn;
+ xmlNodePtr node;
+
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+
+ switch (rxn->node->type) {
+ case XML_ELEMENT_NODE:
+ case XML_ENTITY_REF_NODE:
+ case XML_ENTITY_NODE:
+ case XML_PI_NODE:
+ case XML_COMMENT_NODE:
+ case XML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+ case XML_DOCB_DOCUMENT_NODE:
+#endif
+ case XML_HTML_DOCUMENT_NODE:
+ case XML_DTD_NODE:
+ node = rxn->node->last;
+ break;
+ case XML_ATTRIBUTE_NODE:
+ {
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
+ node = attr->last;
+ }
+ default:
+ node = NULL;
+ break;
+ }
+
+ if (node == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * node.line_num => num
+ *
+ * Obtain the line number (in the XML document) that this
+ * node was read from. If +default_line_numbers+ is set
+ * false (the default), this method returns zero.
+ */
+VALUE
+ruby_xml_node_line_num(VALUE self) {
+ ruby_xml_node *rxn;
+ long line_num;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+
+ if (!xmlLineNumbersDefaultValue)
+ rb_warn("Line numbers were not retained: use XML::Parser::default_line_numbers=true");
+
+ line_num = xmlGetLineNo(rxn->node);
+ if (line_num == -1)
+ return(Qnil);
+ else
+ return(INT2NUM((long)line_num));
+}
+
+
+/*
+ * call-seq:
+ * node.xlink? => (true|false)
+ *
+ * Determine whether this node is an xlink node.
+ */
+VALUE
+ruby_xml_node_xlink_q(VALUE self) {
+ ruby_xml_node *node;
+ ruby_xml_document *doc;
+ xlinkType xlt;
+
+ Data_Get_Struct(self, ruby_xml_node, node);
+ Data_Get_Struct(node->xd, ruby_xml_document, doc);
+ xlt = xlinkIsLink(doc->doc, node->node);
+
+ if (xlt == XLINK_TYPE_NONE)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * node.xlink_type => num
+ *
+ * Obtain the type identifier for this xlink, if applicable.
+ * If this is not an xlink node (see +xlink?+), will return
+ * nil.
+ */
+VALUE
+ruby_xml_node_xlink_type(VALUE self) {
+ ruby_xml_node *node;
+ ruby_xml_document *doc;
+ xlinkType xlt;
+
+ Data_Get_Struct(self, ruby_xml_node, node);
+ Data_Get_Struct(node->xd, ruby_xml_document, doc);
+ xlt = xlinkIsLink(doc->doc, node->node);
+
+ if (xlt == XLINK_TYPE_NONE)
+ return(Qnil);
+ else
+ return(INT2NUM(xlt));
+}
+
+
+/*
+ * call-seq:
+ * node.xlink_type_name => "string"
+ *
+ * Obtain the type name for this xlink, if applicable.
+ * If this is not an xlink node (see +xlink?+), will return
+ * nil.
+ */
+VALUE
+ruby_xml_node_xlink_type_name(VALUE self) {
+ ruby_xml_node *node;
+ ruby_xml_document *doc;
+ xlinkType xlt;
+
+ Data_Get_Struct(self, ruby_xml_node, node);
+ Data_Get_Struct(node->xd, ruby_xml_document, doc);
+ xlt = xlinkIsLink(doc->doc, node->node);
+
+ switch(xlt) {
+ case XLINK_TYPE_NONE:
+ return(Qnil);
+ case XLINK_TYPE_SIMPLE:
+ return(rb_str_new2("simple"));
+ case XLINK_TYPE_EXTENDED:
+ return(rb_str_new2("extended"));
+ case XLINK_TYPE_EXTENDED_SET:
+ return(rb_str_new2("extended_set"));
+ default:
+ rb_fatal("Unknowng xlink type, %d", xlt);
+ }
+}
+
+
+static void
+ruby_xml_node_mark(ruby_xml_node *rxn) {
+ if (rxn == NULL) return;
+ if (!NIL_P(rxn->xd)) rb_gc_mark(rxn->xd);
+}
+
+
+/*
+ * call-seq:
+ * node.name => "string"
+ *
+ * Obtain this node's name.
+ */
+VALUE
+ruby_xml_node_name_get(VALUE self) {
+ ruby_xml_node *rxn;
+ const xmlChar *name;
+
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+
+ switch (rxn->node->type) {
+ case XML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+ case XML_DOCB_DOCUMENT_NODE:
+#endif
+ case XML_HTML_DOCUMENT_NODE:
+ {
+ xmlDocPtr doc = (xmlDocPtr) rxn->node;
+ name = doc->URL;
+ break;
+ }
+ case XML_ATTRIBUTE_NODE:
+ {
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
+ name = attr->name;
+ break;
+ }
+ case XML_NAMESPACE_DECL:
+ {
+ xmlNsPtr ns = (xmlNsPtr) rxn->node;
+ name = ns->prefix;
+ break;
+ }
+ default:
+ name = rxn->node->name;
+ break;
+ }
+
+ if (rxn->node->name == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)name));
+}
+
+
+/*
+ * call-seq:
+ * node.name = "string"
+ *
+ * Set this node's name.
+ */
+VALUE
+ruby_xml_node_name_set(VALUE self, VALUE name) {
+ ruby_xml_node *node;
+
+ Check_Type(name, T_STRING);
+ Data_Get_Struct(self, ruby_xml_node, node);
+ xmlNodeSetName(node->node, (xmlChar*)StringValuePtr(name));
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * node.namespace => [namespace, ..., namespace]
+ *
+ * Obtain an array of +XML::NS+ objects representing
+ * this node's xmlns attributes
+ */
+VALUE
+ruby_xml_node_namespace_get(VALUE self) {
+ ruby_xml_node *node;
+ xmlNsPtr *nsList, *cur;
+ VALUE arr, ns;
+
+ Data_Get_Struct(self, ruby_xml_node, node);
+ if (node->node == NULL)
+ return(Qnil);
+
+ nsList = xmlGetNsList(node->node->doc, node->node);
+
+ if (nsList == NULL)
+ return(Qnil);
+
+ arr = rb_ary_new();
+ for (cur = nsList; *cur != NULL; cur++) {
+ ns = ruby_xml_ns_new2(cXMLNS, node->xd, *cur);
+ if (ns == Qnil)
+ continue;
+ else
+ rb_ary_push(arr, ns);
+ }
+ xmlFree(nsList);
+
+ return(arr);
+}
+
+
+/*
+ * call-seq:
+ * node.namespace_node => namespace.
+ *
+ * Obtain this node's namespace node.
+ */
+VALUE
+ruby_xml_node_namespace_get_node(VALUE self) {
+ ruby_xml_node *node;
+
+ Data_Get_Struct(self, ruby_xml_node, node);
+ if (node->node->ns == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_ns_new2(cXMLNS, node->xd, node->node->ns));
+}
+
+// TODO namespace_set can take varargs (in fact, must if used
+// with strings), but I cannot see how you can call
+// that version, apart from with 'send'
+//
+// Would sure be nice to support foo.namespace['foo'] = 'bar'
+// but maybe that's not practical...
+
+/*
+ * call-seq:
+ * node.namespace = namespace
+ *
+ * Add the specified XML::NS object to this node's xmlns attributes.
+ */
+VALUE
+ruby_xml_node_namespace_set(int argc, VALUE *argv, VALUE self) {
+ VALUE rns, rprefix;
+ ruby_xml_node *rxn;
+ ruby_xml_ns *rxns;
+ xmlNsPtr ns;
+ char *cp, *href;
+
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ switch (argc) {
+ case 1:
+ rns = argv[0];
+ if (TYPE(rns) == T_STRING) {
+ cp = strchr(StringValuePtr(rns), (int)':');
+ if (cp == NULL) {
+ rprefix = rns;
+ href = NULL;
+ } else {
+ rprefix = rb_str_new(StringValuePtr(rns), (int)((long)cp - (long)StringValuePtr(rns)));
+ href = &cp[1]; /* skip the : */
+ }
+ } else if (rb_obj_is_kind_of(rns, cXMLNS) == Qtrue) {
+ Data_Get_Struct(self, ruby_xml_ns, rxns);
+ xmlSetNs(rxn->node, rxns->ns);
+ return(rns);
+ } else
+ rb_raise(rb_eTypeError, "must pass a string or an XML::Ns object");
+
+ /* Fall through to next case because when argc == 1, we need to
+ * manually setup the additional args unless the arg passed is of
+ * cXMLNS type */
+ case 2:
+ /* Don't want this code run in the fall through case */
+ if (argc == 2) {
+ rprefix = argv[0];
+ href = StringValuePtr(argv[1]);
+ }
+
+ ns = xmlNewNs(rxn->node, (xmlChar*)href, (xmlChar*)StringValuePtr(rprefix));
+ if (ns == NULL)
+ rb_raise(eXMLNodeSetNamespace, "unable to set the namespace");
+ else
+ return(ruby_xml_ns_new2(cXMLNS, rxn->xd, ns));
+ break;
+
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
+ }
+
+ /* can't get here */
+ return(Qnil);
+}
+
+
+/*
+ * call-seq:
+ * node.namespace? => (true|false)
+ *
+ * Determine whether this node *is* (not has) a namespace
+ * node.
+ */
+VALUE
+ruby_xml_node_namespace_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_NAMESPACE_DECL)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+VALUE
+ruby_xml_node_new(VALUE class, xmlNodePtr node) {
+ ruby_xml_node *rxn;
+
+ rxn = ALLOC(ruby_xml_node);
+ rxn->is_ptr = 0;
+ rxn->node = node;
+ rxn->xd = Qnil;
+ return(Data_Wrap_Struct(class, ruby_xml_node_mark,
+ ruby_xml_node_free, rxn));
+}
+
+
+VALUE
+ruby_xml_node_new2(VALUE class, VALUE xd, xmlNodePtr node) {
+ ruby_xml_node *rxn;
+
+ rxn = ALLOC(ruby_xml_node);
+ rxn->is_ptr = 1;
+ rxn->node = node;
+ if (NIL_P(xd))
+ rxn->xd = Qnil;
+ else
+ rxn->xd = xd;
+ return(Data_Wrap_Struct(class, ruby_xml_node_mark,
+ ruby_xml_node_free, rxn));
+}
+
+
+/*
+ * call-seq:
+ * node.next => node
+ *
+ * Obtain the next sibling node, if any.
+ */
+VALUE
+ruby_xml_node_next_get(VALUE self) {
+ ruby_xml_node *rxn;
+ xmlNodePtr node;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+
+ switch (rxn->node->type) {
+ case XML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+ case XML_DOCB_DOCUMENT_NODE:
+#endif
+ case XML_HTML_DOCUMENT_NODE:
+ node = NULL;
+ break;
+ case XML_ATTRIBUTE_NODE:
+ {
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
+ node = (xmlNodePtr) attr->next;
+ break;
+ }
+ case XML_NAMESPACE_DECL:
+ {
+ xmlNsPtr ns = (xmlNsPtr) rxn->node;
+ node = (xmlNodePtr) ns->next;
+ break;
+ }
+ default:
+ node = rxn->node->next;
+ break;
+ }
+
+ if (node == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_node_new2(cXMLNode, rxn->xd, node));
+}
+
+
+/*
+ * call-seq:
+ * node.next? => (true|false)
+ *
+ * Determine whether this node has a next sibling.
+ */
+VALUE
+ruby_xml_node_next_q(VALUE self) {
+ ruby_xml_node *rxn;
+ xmlNodePtr node;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+
+ switch (rxn->node->type) {
+ case XML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+ case XML_DOCB_DOCUMENT_NODE:
+#endif
+ case XML_HTML_DOCUMENT_NODE:
+ node = NULL;
+ break;
+ case XML_ATTRIBUTE_NODE:
+ {
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
+ node = (xmlNodePtr) attr->next;
+ break;
+ }
+ case XML_NAMESPACE_DECL:
+ {
+ xmlNsPtr ns = (xmlNsPtr) rxn->node;
+ node = (xmlNodePtr) ns->next;
+ break;
+ }
+ default:
+ node = rxn->node->next;
+ break;
+ }
+
+ if (node == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * node.notation? => (true|false)
+ *
+ * Determine whether this is a notation node
+ */
+VALUE
+ruby_xml_node_notation_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_NOTATION_NODE)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * node.ns? => (true|false)
+ *
+ * Determine whether this node is a namespace node.
+ */
+VALUE
+ruby_xml_node_ns_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->ns == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * node.ns_def => namespace
+ *
+ * Obtain this node's default namespace.
+ */
+VALUE
+ruby_xml_node_ns_def_get(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->nsDef == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_ns_new2(cXMLNS, rxn->xd, rxn->node->nsDef));
+}
+
+
+/*
+ * call-seq:
+ * node.ns_def? => (true|false)
+ *
+ * Obtain an array of +XML::NS+ objects representing
+ * this node's xmlns attributes
+ */
+VALUE
+ruby_xml_node_ns_def_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->nsDef == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * node.parent => node
+ *
+ * Obtain this node's parent node, if any.
+ */
+VALUE
+ruby_xml_node_parent_get(VALUE self) {
+ ruby_xml_node *rxn;
+ xmlNodePtr node;
+
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+
+ switch (rxn->node->type) {
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+ case XML_DOCB_DOCUMENT_NODE:
+#endif
+ node = NULL;
+ break;
+ case XML_ATTRIBUTE_NODE:
+ {
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
+ node = attr->parent;
+ }
+ case XML_ENTITY_DECL:
+ case XML_NAMESPACE_DECL:
+ case XML_XINCLUDE_START:
+ case XML_XINCLUDE_END:
+ node = NULL;
+ break;
+ default:
+ node = rxn->node->parent;
+ break;
+ }
+
+ if (node == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_node_new2(cXMLNode, rxn->xd, node));
+}
+
+
+/*
+ * call-seq:
+ * node.parent? => (true|false)
+ *
+ * Determine whether this node has a parent node.
+ */
+VALUE
+ruby_xml_node_parent_q(VALUE self) {
+ ruby_xml_node *rxn;
+ xmlNodePtr node;
+
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+
+ switch (rxn->node->type) {
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+ case XML_DOCB_DOCUMENT_NODE:
+#endif
+ node = NULL;
+ break;
+ case XML_ATTRIBUTE_NODE:
+ {
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
+ node = attr->parent;
+ }
+ case XML_ENTITY_DECL:
+ case XML_NAMESPACE_DECL:
+ case XML_XINCLUDE_START:
+ case XML_XINCLUDE_END:
+ node = NULL;
+ break;
+ default:
+ node = rxn->node->parent;
+ break;
+ }
+
+ if (node == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * node.path => path
+ *
+ * Obtain this node's path.
+ */
+VALUE
+ruby_xml_node_path(VALUE self) {
+ ruby_xml_node *rxn;
+ xmlChar *path;
+
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ path = xmlGetNodePath(rxn->node);
+
+ if (path == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)path));
+}
+
+
+/*
+ * call-seq:
+ * node.pi? => (true|false)
+ *
+ * Determine whether this is a processing instruction node.
+ */
+VALUE
+ruby_xml_node_pi_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_PI_NODE)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * node.pointer => node_set
+ *
+ * Evaluates an XPointer expression relative to this node.
+ */
+VALUE
+ruby_xml_node_pointer(VALUE self, VALUE xptr_str) {
+ return(ruby_xml_xpointer_point2(self, xptr_str));
+}
+
+
+/*
+ * call-seq:
+ * node.prev => node
+ *
+ * Obtain the previous sibling, if any.
+ */
+VALUE
+ruby_xml_node_prev_get(VALUE self) {
+ ruby_xml_node *rxn;
+ xmlNodePtr node;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+
+ switch (rxn->node->type) {
+ case XML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+ case XML_DOCB_DOCUMENT_NODE:
+#endif
+ case XML_HTML_DOCUMENT_NODE:
+ case XML_NAMESPACE_DECL:
+ node = NULL;
+ break;
+ case XML_ATTRIBUTE_NODE:
+ {
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
+ node = (xmlNodePtr) attr->next;
+ }
+ break;
+ default:
+ node = rxn->node->next;
+ break;
+ }
+
+ if (node == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_node_new2(cXMLNode, rxn->xd, node));
+}
+
+
+/*
+ * call-seq:
+ * node.prev? => (true|false)
+ *
+ * Determines whether this node has a previous sibling node.
+ */
+VALUE
+ruby_xml_node_prev_q(VALUE self) {
+ ruby_xml_node *rxn;
+ xmlNodePtr node;
+
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+
+ switch (rxn->node->type) {
+ case XML_DOCUMENT_NODE:
+#ifdef LIBXML_DOCB_ENABLED
+ case XML_DOCB_DOCUMENT_NODE:
+#endif
+ case XML_HTML_DOCUMENT_NODE:
+ case XML_NAMESPACE_DECL:
+ node = NULL;
+ break;
+ case XML_ATTRIBUTE_NODE:
+ {
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
+ node = (xmlNodePtr) attr->next;
+ }
+ break;
+ default:
+ node = rxn->node->next;
+ break;
+ }
+
+ if (node == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * node.property("name") => "string"
+ * node["name"] => "string"
+ *
+ * Obtain the named property.
+ */
+VALUE
+ruby_xml_node_property_get(VALUE self, VALUE prop) {
+ ruby_xml_node *rxn;
+ xmlChar *p;
+ VALUE r;
+
+ Check_Type(prop, T_STRING);
+
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ p = xmlGetProp(rxn->node, (xmlChar*)StringValuePtr(prop));
+
+ if (p == NULL)
+ r = Qnil;
+ else {
+ r = rb_str_new2((const char*)p);
+ xmlFree(p);
+ }
+
+ return r;
+}
+
+
+/*
+ * call-seq:
+ * node["name"] = "string"
+ *
+ * Set the named property.
+ */
+VALUE
+ruby_xml_node_property_set(VALUE self, VALUE key, VALUE val) {
+ ruby_xml_node *node;
+ ruby_xml_attr *rxa;
+ xmlAttrPtr attr;
+ VALUE rattr;
+
+ Data_Get_Struct(self, ruby_xml_node, node);
+ Check_Type(key, T_STRING);
+
+ if( val == Qnil ) {
+ attr = xmlSetProp(node->node, (xmlChar*)StringValuePtr(key), NULL);
+ xmlRemoveProp( attr );
+ return Qnil;
+ } else {
+ Check_Type(val, T_STRING);
+ }
+
+ attr = xmlSetProp(node->node, (xmlChar*)StringValuePtr(key), (xmlChar*)StringValuePtr(val));
+ if (attr == NULL) {
+ attr = xmlNewProp(node->node, (xmlChar*)StringValuePtr(key), (xmlChar*)StringValuePtr(val));
+ if (attr == NULL)
+ return(Qnil);
+ }
+ rattr = ruby_xml_attr_new(cXMLAttr, node->xd, attr);
+ Data_Get_Struct(rattr, ruby_xml_attr, rxa);
+ rxa->is_ptr = 1;
+ return(rattr);
+}
+
+
+/*
+ * call-seq:
+ * node.properties => attributes
+ *
+ * Returns the +XML::Attr+ for this node.
+ */
+VALUE
+ruby_xml_node_properties_get(VALUE self) {
+ ruby_xml_node *node;
+ xmlAttrPtr attr;
+
+ Data_Get_Struct(self, ruby_xml_node, node);
+
+ if (node->node->type == XML_ELEMENT_NODE) {
+ attr = node->node->properties;
+ return(ruby_xml_attr_new2(cXMLAttr, node->xd, attr));
+ } else {
+ return(Qnil);
+ }
+}
+
+
+/*
+ * call-seq:
+ * node.properties? => (true|false)
+ *
+ * Determine whether this node has properties
+ * (attributes).
+ */
+VALUE
+ruby_xml_node_properties_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_ELEMENT_NODE && rxn->node->properties != NULL)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+* node.remove! => nil
+*
+* Removes this node from it's parent.
+*/
+VALUE
+ruby_xml_node_remove_ex(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ xmlUnlinkNode(rxn->node);
+ return(Qnil);
+}
+
+
+/*
+ * call-seq:
+ * node.search_href => namespace
+ *
+ * Search for a namespace by href.
+ */
+VALUE
+ruby_xml_node_search_href(VALUE self, VALUE href) {
+ ruby_xml_document *doc;
+ ruby_xml_node *node;
+
+ Check_Type(href, T_STRING);
+ Data_Get_Struct(self, ruby_xml_node, node);
+ Data_Get_Struct(node->xd, ruby_xml_document, doc);
+ return(ruby_xml_ns_new2(cXMLNS, node->xd,
+ xmlSearchNsByHref(doc->doc, node->node,
+ (xmlChar*)StringValuePtr(href))));
+}
+
+
+/*
+ * call-seq:
+ * node.search_ns => namespace
+ *
+ * Search for a namespace by namespace.
+ */
+VALUE
+ruby_xml_node_search_ns(VALUE self, VALUE ns) {
+ ruby_xml_document *doc;
+ ruby_xml_node *node;
+
+ Check_Type(ns, T_STRING);
+ Data_Get_Struct(self, ruby_xml_node, node);
+ Data_Get_Struct(node->xd, ruby_xml_document, doc);
+ return(ruby_xml_ns_new2(cXMLNS, node->xd,
+ xmlSearchNs(doc->doc, node->node,
+ (xmlChar*)StringValuePtr(ns))));
+}
+
+
+VALUE
+ruby_xml_node_set_ptr(VALUE node, int is_ptr) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(node, ruby_xml_node, rxn);
+ rxn->is_ptr = is_ptr;
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * node.sibling(node) => node
+ *
+ * Add the specified node as a sibling of this node.
+ */
+VALUE
+ruby_xml_node_sibling_set(VALUE self, VALUE rnode) {
+ ruby_xml_node *cnode, *pnode;
+ xmlNodePtr ret;
+
+ if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
+ rb_raise(rb_eTypeError, "Must pass an XML::Node object");
+
+ Data_Get_Struct(self, ruby_xml_node, pnode);
+ Data_Get_Struct(rnode, ruby_xml_node, cnode);
+
+ ret = xmlAddSibling(pnode->node, cnode->node);
+ if (ret == NULL)
+ rb_raise(eXMLNodeFailedModify, "unable to add a sibling to the document");
+
+ cnode->is_ptr = 1;
+ return(ruby_xml_node_new2(cXMLNode, pnode->xd, ret));
+}
+
+
+/*
+ * call-seq:
+ * node.space_preserve => (true|false)
+ *
+ * Determine whether this node preserves whitespace.
+ */
+VALUE
+ruby_xml_node_space_preserve_get(VALUE self) {
+ ruby_xml_node *rxn;
+
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ return(INT2NUM(xmlNodeGetSpacePreserve(rxn->node)));
+}
+
+
+/*
+ * call-seq:
+ * node.space_preserve = true|false
+ *
+ * Control whether this node preserves whitespace.
+ */
+VALUE
+ruby_xml_node_space_preserve_set(VALUE self, VALUE bool) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+
+ if (TYPE(bool) == T_FALSE)
+ xmlNodeSetSpacePreserve(rxn->node, 1);
+ else
+ xmlNodeSetSpacePreserve(rxn->node, 0);
+
+ return(Qnil);
+}
+
+
+/*
+ * call-seq:
+ * node.text? => (true|false)
+ *
+ * Determine whether this node has text.
+ */
+VALUE
+ruby_xml_node_text_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node == NULL)
+ return(Qnil);
+
+ return((xmlNodeIsText(rxn->node) == 1) ? Qtrue : Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * node.to_s => "string"
+ *
+ * Coerce this node to a string representation of
+ * it's XML.
+ */
+VALUE
+ruby_xml_node_to_s(VALUE self) {
+ ruby_xml_node *rxn;
+ xmlBufferPtr buf;
+ VALUE result;
+
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ buf = xmlBufferCreate();
+ xmlNodeDump(buf, rxn->node->doc, rxn->node, 0, 1);
+ result = rb_str_new2((const char*)buf->content);
+
+ xmlBufferFree(buf);
+ return result;
+}
+
+
+/*
+ * call-seq:
+ * node.type => num
+ *
+ * Obtain this node's type identifier.
+ */
+VALUE
+ruby_xml_node_type(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ return(INT2NUM(rxn->node->type));
+}
+
+
+/*
+ * call-seq:
+ * node.type_name => num
+ *
+ * Obtain this node's type name.
+ */
+VALUE
+ruby_xml_node_type_name(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+
+ switch(rxn->node->type) {
+ case XML_ELEMENT_NODE:
+ return(rb_str_new2("element"));
+ case XML_ATTRIBUTE_NODE:
+ return(rb_str_new2("attribute"));
+ case XML_TEXT_NODE:
+ return(rb_str_new2("text"));
+ case XML_CDATA_SECTION_NODE:
+ return(rb_str_new2("cdata"));
+ case XML_ENTITY_REF_NODE:
+ return(rb_str_new2("entity_ref"));
+ case XML_ENTITY_NODE:
+ return(rb_str_new2("entity"));
+ case XML_PI_NODE:
+ return(rb_str_new2("pi"));
+ case XML_COMMENT_NODE:
+ return(rb_str_new2("comment"));
+ case XML_DOCUMENT_NODE:
+ return(rb_str_new2("document_xml"));
+ case XML_DOCUMENT_TYPE_NODE:
+ return(rb_str_new2("doctype"));
+ case XML_DOCUMENT_FRAG_NODE:
+ return(rb_str_new2("fragment"));
+ case XML_NOTATION_NODE:
+ return(rb_str_new2("notation"));
+ case XML_HTML_DOCUMENT_NODE:
+ return(rb_str_new2("document_html"));
+ case XML_DTD_NODE:
+ return(rb_str_new2("dtd"));
+ case XML_ELEMENT_DECL:
+ return(rb_str_new2("elem_decl"));
+ case XML_ATTRIBUTE_DECL:
+ return(rb_str_new2("attribute_decl"));
+ case XML_ENTITY_DECL:
+ return(rb_str_new2("entity_decl"));
+ case XML_NAMESPACE_DECL:
+ return(rb_str_new2("namespace"));
+ case XML_XINCLUDE_START:
+ return(rb_str_new2("xinclude_start"));
+ case XML_XINCLUDE_END:
+ return(rb_str_new2("xinclude_end"));
+#ifdef LIBXML_DOCB_ENABLED
+ case XML_DOCB_DOCUMENT_NODE:
+ return(rb_str_new2("document_docbook"));
+#endif
+ default:
+ rb_raise(eXMLNodeUnknownType, "Unknown node type: %n", rxn->node->type);
+ return(Qfalse);
+ }
+}
+
+
+/*
+ * call-seq:
+ * node.xinclude_end? => num
+ *
+ * Determine whether this node is an xinclude end node.
+ */
+VALUE
+ruby_xml_node_xinclude_end_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_XINCLUDE_END)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * node.xinclude_start? => num
+ *
+ * Determine whether this node is an xinclude start node.
+ */
+VALUE
+ruby_xml_node_xinclude_start_q(VALUE self) {
+ ruby_xml_node *rxn;
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+ if (rxn->node->type == XML_XINCLUDE_START)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+// TODO my gut tells me this is where our sigseg etc. problems start...
+
+/*
+ * call-seq:
+ * node.copy => node
+ *
+ * Create a copy of this node.
+ */
+VALUE
+ruby_xml_node_copy(VALUE self, VALUE deep) { /* MUFF */
+ ruby_xml_node *rxn, *n_rxn;
+ VALUE n_node;
+
+ Data_Get_Struct(self, ruby_xml_node, rxn);
+
+ n_node = ruby_xml_node_new(cXMLNode, NULL); // class??
+ Data_Get_Struct(n_node, ruby_xml_node, n_rxn);
+
+ n_rxn->node = xmlCopyNode( rxn->node, ((deep==Qnil)||(deep==Qfalse))?0:1 );
+ if (rxn->node == NULL)
+ return(Qnil);
+
+ return n_node;
+}
+
+
+// Rdoc needs to know
+#ifdef RDOC_NEVER_DEFINED
+ mXML = rb_define_module("XML");
+#endif
+
+void
+ruby_init_xml_node(void) {
+ cXMLNode = rb_define_class_under(mXML, "Node", rb_cObject);
+ eXMLNodeSetNamespace = rb_define_class_under(cXMLNode, "SetNamespace", rb_eException);
+ eXMLNodeFailedModify = rb_define_class_under(cXMLNode, "FailedModify", rb_eException);
+ eXMLNodeUnknownType = rb_define_class_under(cXMLNode, "UnknownType", rb_eException);
+
+ rb_define_const(cXMLNode, "SPACE_DEFAULT", INT2NUM(0));
+ rb_define_const(cXMLNode, "SPACE_PRESERVE", INT2NUM(1));
+ rb_define_const(cXMLNode, "SPACE_NOT_INHERIT", INT2NUM(-1));
+ rb_define_const(cXMLNode, "XLINK_ACTUATE_AUTO", INT2NUM(1));
+ rb_define_const(cXMLNode, "XLINK_ACTUATE_NONE", INT2NUM(0));
+ rb_define_const(cXMLNode, "XLINK_ACTUATE_ONREQUEST", INT2NUM(2));
+ rb_define_const(cXMLNode, "XLINK_SHOW_EMBED", INT2NUM(2));
+ rb_define_const(cXMLNode, "XLINK_SHOW_NEW", INT2NUM(1));
+ rb_define_const(cXMLNode, "XLINK_SHOW_NONE", INT2NUM(0));
+ rb_define_const(cXMLNode, "XLINK_SHOW_REPLACE", INT2NUM(3));
+ rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED", INT2NUM(2));
+ rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED_SET", INT2NUM(3));
+ rb_define_const(cXMLNode, "XLINK_TYPE_NONE", INT2NUM(0));
+ rb_define_const(cXMLNode, "XLINK_TYPE_SIMPLE", INT2NUM(1));
+
+ rb_define_singleton_method(cXMLNode, "new", ruby_xml_node_initialize, -1);
+
+ rb_define_method(cXMLNode, "<<", ruby_xml_node_content_add, 1);
+ rb_define_method(cXMLNode, "[]", ruby_xml_node_property_get, 1);
+ rb_define_method(cXMLNode, "[]=", ruby_xml_node_property_set, 2);
+ rb_define_method(cXMLNode, "attribute?", ruby_xml_node_attribute_q, 0);
+ rb_define_method(cXMLNode, "attribute_decl?", ruby_xml_node_attribute_decl_q, 0);
+ rb_define_method(cXMLNode, "base", ruby_xml_node_base_get, 0);
+ rb_define_method(cXMLNode, "base=", ruby_xml_node_base_set, 1);
+ rb_define_method(cXMLNode, "blank?", ruby_xml_node_empty_q, 0);
+ rb_define_method(cXMLNode, "cdata?", ruby_xml_node_cdata_q, 0);
+ rb_define_method(cXMLNode, "comment?", ruby_xml_node_comment_q, 0);
+ rb_define_method(cXMLNode, "copy", ruby_xml_node_copy, 1);
+ rb_define_method(cXMLNode, "child", ruby_xml_node_child_get, 0);
+ rb_define_method(cXMLNode, "child?", ruby_xml_node_child_q, 0);
+ rb_define_method(cXMLNode, "child=", ruby_xml_node_child_set, 1);
+ rb_define_method(cXMLNode, "children", ruby_xml_node_child_get, 0);
+ rb_define_method(cXMLNode, "children?", ruby_xml_node_child_q, 0);
+ rb_define_method(cXMLNode, "content", ruby_xml_node_content_get, 0);
+ rb_define_method(cXMLNode, "content=", ruby_xml_node_content_set, 1);
+ rb_define_method(cXMLNode, "content_stripped", ruby_xml_node_content_stripped_get, 0);
+ rb_define_method(cXMLNode, "doc", ruby_xml_node_doc, 0);
+ rb_define_method(cXMLNode, "docbook_doc?", ruby_xml_node_docbook_doc_q, 0);
+ rb_define_method(cXMLNode, "doctype?", ruby_xml_node_doctype_q, 0);
+ rb_define_method(cXMLNode, "document?", ruby_xml_node_document_q, 0);
+ rb_define_method(cXMLNode, "dtd?", ruby_xml_node_dtd_q, 0);
+ rb_define_method(cXMLNode, "dump", ruby_xml_node_dump, 0);
+ rb_define_method(cXMLNode, "debug_dump", ruby_xml_node_debug_dump, 0);
+ rb_define_method(cXMLNode, "element?", ruby_xml_node_element_q, 0);
+ rb_define_method(cXMLNode, "element_decl?", ruby_xml_node_element_decl_q, 0);
+ rb_define_method(cXMLNode, "empty?", ruby_xml_node_empty_q, 0);
+ rb_define_method(cXMLNode, "entity?", ruby_xml_node_entity_q, 0);
+ rb_define_method(cXMLNode, "entity_ref?", ruby_xml_node_entity_ref_q, 0);
+ rb_define_method(cXMLNode, "eql?", ruby_xml_node_eql_q, 1);
+ rb_define_method(cXMLNode, "find", ruby_xml_node_find, -1);
+ rb_define_method(cXMLNode, "find_first", ruby_xml_node_find_first, -1);
+ rb_define_method(cXMLNode, "fragment?", ruby_xml_node_fragment_q, 0);
+ rb_define_method(cXMLNode, "hash", ruby_xml_node_hash, 0);
+ rb_define_method(cXMLNode, "html_doc?", ruby_xml_node_html_doc_q, 0);
+ rb_define_method(cXMLNode, "lang", ruby_xml_node_lang_get, 0);
+ rb_define_method(cXMLNode, "lang=", ruby_xml_node_lang_set, 1);
+ rb_define_method(cXMLNode, "last", ruby_xml_node_last_get, 0);
+ rb_define_method(cXMLNode, "last?", ruby_xml_node_last_q, 0);
+ rb_define_method(cXMLNode, "line_num", ruby_xml_node_line_num, 0);
+ rb_define_method(cXMLNode, "name", ruby_xml_node_name_get, 0);
+ rb_define_method(cXMLNode, "name=", ruby_xml_node_name_set, 1);
+ rb_define_method(cXMLNode, "namespace", ruby_xml_node_namespace_get, 0);
+ rb_define_method(cXMLNode, "namespace_node", ruby_xml_node_namespace_get_node, 0);
+ rb_define_method(cXMLNode, "namespace?", ruby_xml_node_namespace_q, 0);
+ rb_define_method(cXMLNode, "namespace=", ruby_xml_node_namespace_set, -1);
+ rb_define_method(cXMLNode, "next", ruby_xml_node_next_get, 0);
+ rb_define_method(cXMLNode, "next?", ruby_xml_node_next_q, 0);
+ rb_define_method(cXMLNode, "node_type", ruby_xml_node_type, 0);
+ rb_define_method(cXMLNode, "node_type_name", ruby_xml_node_type_name, 0);
+ rb_define_method(cXMLNode, "notation?", ruby_xml_node_notation_q, 0);
+ rb_define_method(cXMLNode, "ns", ruby_xml_node_namespace_get, 0);
+ rb_define_method(cXMLNode, "ns?", ruby_xml_node_ns_q, 0);
+ rb_define_method(cXMLNode, "ns_def", ruby_xml_node_ns_def_get, 0);
+ rb_define_method(cXMLNode, "ns_def?", ruby_xml_node_ns_def_q, 0);
+ rb_define_method(cXMLNode, "parent", ruby_xml_node_parent_get, 0);
+ rb_define_method(cXMLNode, "parent?", ruby_xml_node_parent_q, 0);
+ rb_define_method(cXMLNode, "path", ruby_xml_node_path, 0);
+ rb_define_method(cXMLNode, "pi?", ruby_xml_node_pi_q, 0);
+ rb_define_method(cXMLNode, "pointer", ruby_xml_node_pointer, 1);
+ rb_define_method(cXMLNode, "prev", ruby_xml_node_prev_get, 0);
+ rb_define_method(cXMLNode, "prev?", ruby_xml_node_prev_q, 0);
+ rb_define_method(cXMLNode, "property", ruby_xml_node_property_get, 1);
+ rb_define_method(cXMLNode, "properties", ruby_xml_node_properties_get, 0);
+ rb_define_method(cXMLNode, "properties?", ruby_xml_node_properties_q, 0);
+ rb_define_method(cXMLNode, "remove!", ruby_xml_node_remove_ex, 0);
+ rb_define_method(cXMLNode, "search_ns", ruby_xml_node_search_ns, 1);
+ rb_define_method(cXMLNode, "search_href", ruby_xml_node_search_href, 1);
+ rb_define_method(cXMLNode, "sibling=", ruby_xml_node_sibling_set, 1);
+ rb_define_method(cXMLNode, "space_preserve", ruby_xml_node_space_preserve_get, 0);
+ rb_define_method(cXMLNode, "space_preserve=", ruby_xml_node_space_preserve_set, 1);
+ rb_define_method(cXMLNode, "text?", ruby_xml_node_text_q, 0);
+ rb_define_method(cXMLNode, "to_s", ruby_xml_node_to_s, 0);
+ rb_define_method(cXMLNode, "xinclude_end?", ruby_xml_node_xinclude_end_q, 0);
+ rb_define_method(cXMLNode, "xinclude_start?", ruby_xml_node_xinclude_start_q, 0);
+ rb_define_method(cXMLNode, "xlink?", ruby_xml_node_xlink_q, 0);
+ rb_define_method(cXMLNode, "xlink_type", ruby_xml_node_xlink_type, 0);
+ rb_define_method(cXMLNode, "xlink_type_name", ruby_xml_node_xlink_type_name, 0);
+
+ rb_define_alias(cXMLNode, "==", "eql?");
+}
Added: packages-wip/libxml-ruby/trunk/ruby_xml_node.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_node.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_node.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,28 @@
+/* $Id: ruby_xml_node.h,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RUBY_XML_NODE__
+#define __RUBY_XML_NODE__
+
+extern VALUE cXMLNode;
+extern VALUE eXMLNodeSetNamespace;
+extern VALUE eXMLNodeFailedModify;
+extern VALUE eXMLNodeUnknownType;
+
+typedef struct ruby_xml_node {
+ xmlNodePtr node;
+ VALUE xd;
+ int is_ptr;
+} ruby_xml_node;
+
+void ruby_xml_node_free(ruby_xml_node *rxn);
+void ruby_init_xml_node(void);
+VALUE ruby_xml_node_child_set(VALUE self, VALUE obj);
+VALUE ruby_xml_node_new(VALUE class, xmlNodePtr node);
+VALUE ruby_xml_node_new2(VALUE class, VALUE xd, xmlNodePtr node);
+VALUE ruby_xml_node_name_get(VALUE self);
+VALUE ruby_xml_node_property_get(VALUE self, VALUE key);
+VALUE ruby_xml_node_property_set(VALUE self, VALUE key, VALUE val);
+VALUE ruby_xml_node_set_ptr(VALUE node, int is_ptr);
+#endif
Added: packages-wip/libxml-ruby/trunk/ruby_xml_node_set.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_node_set.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_node_set.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,248 @@
+/* $Id: ruby_xml_node_set.c,v 1.3 2006/04/14 14:45:25 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#include "libxml.h"
+#include "ruby_xml_node_set.h"
+
+/*
+ * Document-class: XML::Node::Set
+ *
+ * Includes Enumerable.
+ */
+VALUE cXMLNodeSet;
+
+// TODO maybe we should support [] on nodeset?
+// Would also give us on xpath too...
+
+/*
+ * call-seq:
+ * nodeset.to_a => [node, ..., node]
+ *
+ * Obtain an array of the nodes in this set.
+ */
+VALUE
+ruby_xml_node_set_to_a(VALUE self) {
+ int i;
+ ruby_xml_node_set *rxnset;
+ VALUE nodeobj, set_ary;
+
+ Data_Get_Struct(self, ruby_xml_node_set, rxnset);
+
+ set_ary = rb_ary_new();
+ if (!((rxnset->node_set == NULL) || (rxnset->node_set->nodeNr == 0))) {
+ for (i = 0; i < rxnset->node_set->nodeNr; i++) {
+ nodeobj = ruby_xml_node_new2(cXMLNode, rxnset->xd, rxnset->node_set->nodeTab[i]);
+ rb_ary_push(set_ary, nodeobj);
+ }
+ }
+
+ return(set_ary);
+}
+
+
+/*
+ * call-seq:
+ * nodeset.each { |node| ... } => self
+ *
+ * Call the supplied block for each node in this set.
+ */
+VALUE
+ruby_xml_node_set_each(VALUE self) {
+ int i;
+ ruby_xml_node_set *rxnset;
+ VALUE nodeobj;
+
+ Data_Get_Struct(self, ruby_xml_node_set, rxnset);
+
+ if (rxnset->node_set == NULL)
+ return(Qnil);
+
+ for (i = 0; i < rxnset->node_set->nodeNr; i++) {
+ switch(rxnset->node_set->nodeTab[i]->type) {
+ case XML_ATTRIBUTE_NODE:
+ nodeobj = ruby_xml_attr_new2(cXMLAttr, rxnset->xd, (xmlAttrPtr)rxnset->node_set->nodeTab[i]);
+ break;
+ default:
+ nodeobj = ruby_xml_node_new2(cXMLNode, rxnset->xd, rxnset->node_set->nodeTab[i]);
+ }
+
+ rb_yield(nodeobj);
+ }
+ return(self);
+}
+
+
+/*
+ * call-seq:
+ * nodeset.empty? => (true|false)
+ *
+ * Determine whether this nodeset is empty (contains no nodes).
+ */
+VALUE
+ruby_xml_node_set_empty_q(VALUE self) {
+ ruby_xml_node_set *rxnset;
+ Data_Get_Struct(self, ruby_xml_node_set, rxnset);
+ return ( rxnset->node_set == NULL || rxnset->node_set->nodeNr <= 0 ) ? Qtrue : Qfalse;
+}
+
+
+/*
+ * call-seq:
+ * nodeset.first => node
+ *
+ * Returns the first node in this node set, or nil if none exist.
+ */
+VALUE
+ruby_xml_node_set_first(VALUE self) {
+ ruby_xml_node_set *rxnset;
+ VALUE nodeobj;
+
+ Data_Get_Struct(self, ruby_xml_node_set, rxnset);
+
+ if (rxnset->node_set == NULL || rxnset->node_set->nodeNr < 1)
+ return(Qnil);
+
+ switch(rxnset->node_set->nodeTab[0]->type) {
+ case XML_ATTRIBUTE_NODE:
+ nodeobj = ruby_xml_attr_new2(cXMLAttr, rxnset->xd, (xmlAttrPtr)rxnset->node_set->nodeTab[0]);
+ break;
+ default:
+ nodeobj = ruby_xml_node_new2(cXMLNode, rxnset->xd, rxnset->node_set->nodeTab[0]);
+ }
+
+ return(nodeobj);
+}
+
+
+void
+ruby_xml_node_set_free(ruby_xml_node_set *rxnset) {
+ void *data;
+
+ switch(rxnset->data_type) {
+ case RUBY_LIBXML_SRC_TYPE_NULL:
+ break;
+ case RUBY_LIBXML_SRC_TYPE_XPATH:
+ data = (void*)(rx_xpath_data *)rxnset->data;
+ free((rx_xpath_data *)data);
+ default:
+ rb_fatal("Unknown data type, %d", rxnset->data_type);
+ }
+
+ /* Don't need to free the node set because the nodeset is a child of
+ the XPath object that created the set.
+ if (rxnset->node_set != NULL)
+ xmlXPathFreeNodeSet(rxnset->node_set);
+ */
+
+ free(rxnset);
+}
+
+
+/*
+ * call-seq:
+ * nodeset.length => num
+ *
+ * Obtain the length of this nodeset.
+ */
+VALUE
+ruby_xml_node_set_length(VALUE self) {
+ ruby_xml_node_set *rxnset;
+ Data_Get_Struct(self, ruby_xml_node_set, rxnset);
+ if (rxnset->node_set == NULL)
+ return(Qnil);
+ else
+ return(INT2NUM(rxnset->node_set->nodeNr));
+}
+
+
+static void
+ruby_xml_node_set_mark(ruby_xml_node_set *rxnset) {
+ if (rxnset == NULL) return;
+ if (!NIL_P(rxnset->xd)) rb_gc_mark(rxnset->xd);
+ if (!NIL_P(rxnset->xpath)) rb_gc_mark(rxnset->xpath);
+}
+
+
+VALUE
+ruby_xml_node_set_new(VALUE class, VALUE xd, VALUE xpath,
+ xmlNodeSetPtr node_set) {
+ ruby_xml_node_set *rxnset;
+
+ rxnset = ALLOC(ruby_xml_node_set);
+ rxnset->node_set = node_set;
+ rxnset->data = NULL;
+ rxnset->data_type = RUBY_LIBXML_SRC_TYPE_NULL;
+ rxnset->xd = xd;
+ rxnset->xpath = xpath;
+ return(Data_Wrap_Struct(class, ruby_xml_node_set_mark,
+ ruby_xml_node_set_free, rxnset));
+}
+
+
+VALUE
+ruby_xml_node_set_new2(VALUE xd, VALUE xpath,
+ xmlNodeSetPtr node_set) {
+ return(ruby_xml_node_set_new(cXMLNodeSet, xd, xpath, node_set));
+}
+
+
+/*
+ * call-seq:
+ * nodeset.xpath => xpath
+ *
+ * Obtain the xpath corresponding to this nodeset, if any.
+ */
+VALUE
+ruby_xml_node_set_xpath_get(VALUE self) {
+ ruby_xml_node_set *rxnset;
+
+ Data_Get_Struct(self, ruby_xml_node_set, rxnset);
+ if (NIL_P(rxnset->xpath))
+ return(Qnil);
+ else
+ return(rxnset->xpath);
+}
+
+
+/*
+ * call-seq:
+ * nodeset.xpath_ctxt => context
+ *
+ * Return the xpath context corresponding to this nodeset,
+ * if any.
+ */
+VALUE
+ruby_xml_node_set_xpath_data_get(VALUE self) {
+ ruby_xml_node_set *rxnset;
+ rx_xpath_data *rxxpd;
+
+ Data_Get_Struct(self, ruby_xml_node_set, rxnset);
+ if (rxnset->data_type != RUBY_LIBXML_SRC_TYPE_XPATH)
+ return(Qnil);
+
+ rxxpd = (rx_xpath_data *)rxnset->data;
+ return(rxxpd->ctxt);
+}
+
+// Rdoc needs to know
+#ifdef RDOC_NEVER_DEFINED
+ mXML = rb_define_module("XML");
+ cXMLNode = rb_define_class_under(mXML, "Node", rb_cObject);
+#endif
+
+void
+ruby_init_xml_node_set(void) {
+ cXMLNodeSet = rb_define_class_under(cXMLNode, "Set", rb_cObject);
+ rb_include_module(cXMLNodeSet, rb_const_get(rb_cObject, rb_intern("Enumerable")));
+
+ rb_define_method(cXMLNodeSet, "each", ruby_xml_node_set_each, 0);
+ rb_define_method(cXMLNodeSet, "empty?", ruby_xml_node_set_empty_q, 0);
+ rb_define_method(cXMLNodeSet, "first", ruby_xml_node_set_first, 0);
+ rb_define_method(cXMLNodeSet, "length", ruby_xml_node_set_length, 0);
+ rb_define_method(cXMLNodeSet, "to_a", ruby_xml_node_set_to_a, 0);
+ rb_define_method(cXMLNodeSet, "xpath", ruby_xml_node_set_xpath_get, 0);
+ rb_define_method(cXMLNodeSet, "xpath_ctxt",
+ ruby_xml_node_set_xpath_data_get, 0);
+
+}
Added: packages-wip/libxml-ruby/trunk/ruby_xml_node_set.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_node_set.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_node_set.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,26 @@
+/* $Id: ruby_xml_node_set.h,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RUBY_XML_NODE_SET__
+#define __RUBY_XML_NODE_SET__
+
+extern VALUE cXMLNodeSet;
+
+typedef struct ruby_xml_node_set {
+ xmlNodeSetPtr node_set;
+ VALUE xd;
+ VALUE xpath;
+ int data_type;
+ void *data;
+} ruby_xml_node_set;
+
+void ruby_xml_node_set_free(ruby_xml_node_set *rxnset);
+void ruby_init_xml_node_set(void);
+VALUE ruby_xml_node_set_new(VALUE class, VALUE xd, VALUE xpath,
+ xmlNodeSetPtr node_set);
+VALUE ruby_xml_node_set_new2(VALUE xd, VALUE xpath,
+ xmlNodeSetPtr node_set);
+VALUE ruby_xml_node_set_each(VALUE self);
+
+#endif
Added: packages-wip/libxml-ruby/trunk/ruby_xml_ns.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_ns.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_ns.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,153 @@
+/* $Id: ruby_xml_ns.c,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#include "libxml.h"
+#include "ruby_xml_ns.h"
+
+VALUE cXMLNS;
+
+/*
+ * call-seq:
+ * ns.href => "href"
+ *
+ * Obtain the namespace's href.
+ */
+VALUE
+ruby_xml_ns_href_get(VALUE self) {
+ ruby_xml_ns *rxns;
+ Data_Get_Struct(self, ruby_xml_ns, rxns);
+ if (rxns->ns == NULL || rxns->ns->href == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)rxns->ns->href));
+}
+
+
+/*
+ * call-seq:
+ * ns.href? => (true|false)
+ *
+ * Determine whether this namespace has an href.
+ */
+VALUE
+ruby_xml_ns_href_q(VALUE self) {
+ ruby_xml_ns *rxns;
+ Data_Get_Struct(self, ruby_xml_ns, rxns);
+ if (rxns->ns == NULL || rxns->ns->href == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+void
+ruby_xml_ns_free(ruby_xml_ns *rxns) {
+ if (rxns->ns != NULL && !rxns->is_ptr) {
+ xmlFreeNs(rxns->ns);
+ rxns->ns = NULL;
+ }
+
+ free(rxns);
+}
+
+
+static void
+ruby_xml_ns_mark(ruby_xml_ns *rxns) {
+ if (rxns == NULL) return;
+ if (!NIL_P(rxns->xd)) rb_gc_mark(rxns->xd);
+}
+
+
+VALUE
+ruby_xml_ns_new(VALUE class, VALUE xd, xmlNsPtr ns) {
+ ruby_xml_ns *rxns;
+
+ rxns = ALLOC(ruby_xml_ns);
+ rxns->is_ptr = 0;
+ rxns->ns = ns;
+ rxns->xd = xd;
+ return(Data_Wrap_Struct(class, ruby_xml_ns_mark,
+ ruby_xml_ns_free, rxns));
+}
+
+
+VALUE
+ruby_xml_ns_new2(VALUE class, VALUE xd, xmlNsPtr ns) {
+ ruby_xml_ns *rxns;
+
+ rxns = ALLOC(ruby_xml_ns);
+ rxns->is_ptr = 1;
+ rxns->ns = ns;
+ rxns->xd = xd;
+ return(Data_Wrap_Struct(class, ruby_xml_ns_mark,
+ ruby_xml_ns_free, rxns));
+}
+
+
+/*
+ * call-seq:
+ * ns.next => ns
+ *
+ * Obtain the next namespace.
+ */
+VALUE
+ruby_xml_ns_next(VALUE self) {
+ ruby_xml_ns *rxns;
+ Data_Get_Struct(self, ruby_xml_ns, rxns);
+ if (rxns->ns == NULL || rxns->ns->next == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_ns_new2(cXMLNS, rxns->xd, rxns->ns->next));
+}
+
+
+/*
+ * call-seq:
+ * ns.prefix => "prefix"
+ * ns.to_s => "prefix"
+ *
+ * Obtain the namespace's prefix.
+ */
+VALUE
+ruby_xml_ns_prefix_get(VALUE self) {
+ ruby_xml_ns *rxns;
+ Data_Get_Struct(self, ruby_xml_ns, rxns);
+ if (rxns->ns == NULL || rxns->ns->prefix == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)rxns->ns->prefix));
+}
+
+
+/*
+ * call-seq:
+ * ns.prefix? => (true|false)
+ *
+ * Determine whether this namespace has a prefix.
+ */
+VALUE
+ruby_xml_ns_prefix_q(VALUE self) {
+ ruby_xml_ns *rxns;
+ Data_Get_Struct(self, ruby_xml_ns, rxns);
+ if (rxns->ns == NULL || rxns->ns->prefix == NULL)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+// Rdoc needs to know
+#ifdef RDOC_NEVER_DEFINED
+ mXML = rb_define_module("XML");
+#endif
+
+void
+ruby_init_xml_ns(void) {
+ cXMLNS = rb_define_class_under(mXML, "NS", rb_cObject);
+ rb_define_method(cXMLNS, "href", ruby_xml_ns_href_get, 0);
+ rb_define_method(cXMLNS, "href?", ruby_xml_ns_href_q, 0);
+ rb_define_method(cXMLNS, "next", ruby_xml_ns_next, 0);
+ rb_define_method(cXMLNS, "prefix", ruby_xml_ns_prefix_get, 0);
+ rb_define_method(cXMLNS, "prefix?", ruby_xml_ns_prefix_q, 0);
+ rb_define_method(cXMLNS, "to_s", ruby_xml_ns_prefix_get, 0);
+}
Added: packages-wip/libxml-ruby/trunk/ruby_xml_ns.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_ns.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_ns.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,21 @@
+/* $Id: ruby_xml_ns.h,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RUBY_XML_NS__
+#define __RUBY_XML_NS__
+
+extern VALUE cXMLNS;
+
+typedef struct ruby_xml_ns {
+ xmlNsPtr ns;
+ int is_ptr;
+ VALUE xd;
+} ruby_xml_ns;
+
+void ruby_xml_ns_free(ruby_xml_ns *rxn);
+void ruby_init_xml_ns(void);
+VALUE ruby_xml_ns_new(VALUE class, VALUE xd, xmlNsPtr ns);
+VALUE ruby_xml_ns_new2(VALUE class, VALUE xd, xmlNsPtr ns);
+VALUE ruby_xml_ns_name_get(VALUE self);
+#endif
Added: packages-wip/libxml-ruby/trunk/ruby_xml_parser.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_parser.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_parser.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,1417 @@
+/* $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
+ctxtRead(FILE *f, char * buf, int len) {
+ return(fread(buf, 1, len, f));
+}
+
+/*
+ * call-seq:
+ * XML::Parser.catalog_dump => true
+ *
+ * Dump the parser resource catalogs to stdout.
+ */
+VALUE
+ruby_xml_parser_catalog_dump(VALUE self) {
+ xmlCatalogDump(stdout);
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.catalog_remove(catalog) => true
+ *
+ * Remove the specified resource catalog.
+ */
+VALUE
+ruby_xml_parser_catalog_remove(VALUE self, VALUE cat) {
+ Check_Type(cat, T_STRING);
+ xmlCatalogRemove((xmlChar *)StringValuePtr(cat));
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.check_lib_versions => true
+ *
+ * Check LIBXML version matches version the bindings
+ * were compiled to. Throws an exception if not.
+ */
+VALUE
+ruby_xml_parser_check_lib_versions(VALUE class) {
+ xmlCheckVersion(LIBXML_VERSION);
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_automata? => (true|false)
+ *
+ * Determine whether libxml regexp automata support is enabled.
+ */
+VALUE
+ruby_xml_parser_enabled_automata_q(VALUE class) {
+#ifdef LIBXML_AUTOMATA_ENABLED
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_c14n? => (true|false)
+ *
+ * Determine whether libxml 'canonical XML' support is enabled.
+ * See "Canonical XML" (http://www.w3.org/TR/xml-c14n)
+ */
+VALUE
+ruby_xml_parser_enabled_c14n_q(VALUE class) {
+#ifdef LIBXML_C14N_ENABLED
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_catalog? => (true|false)
+ *
+ * Determine whether libxml resource catalog support is enabled.
+ */
+VALUE
+ruby_xml_parser_enabled_catalog_q(VALUE class) {
+#ifdef LIBXML_CATALOG_ENABLED
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_debug? => (true|false)
+ *
+ * Determine whether libxml debugging support is enabled.
+ */
+VALUE
+ruby_xml_parser_enabled_debug_q(VALUE class) {
+#ifdef LIBXML_DEBUG_ENABLED
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_docbook? => (true|false)
+ *
+ * Determine whether libxml docbook support is enabled.
+ */
+VALUE
+ruby_xml_parser_enabled_docbook_q(VALUE class) {
+#ifdef LIBXML_DOCB_ENABLED
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_ftp? => (true|false)
+ *
+ * Determine whether libxml ftp client support is enabled.
+ */
+VALUE
+ruby_xml_parser_enabled_ftp_q(VALUE class) {
+#ifdef LIBXML_FTP_ENABLED
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_http? => (true|false)
+ *
+ * Determine whether libxml http client support is enabled.
+ */
+VALUE
+ruby_xml_parser_enabled_http_q(VALUE class) {
+#ifdef LIBXML_HTTP_ENABLED
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_html? => (true|false)
+ *
+ * Determine whether libxml html support is enabled.
+ */
+VALUE
+ruby_xml_parser_enabled_html_q(VALUE class) {
+#ifdef LIBXML_HTML_ENABLED
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_iconv? => (true|false)
+ *
+ * Determine whether libxml iconv support is enabled.
+ */
+VALUE
+ruby_xml_parser_enabled_iconv_q(VALUE class) {
+#ifdef LIBXML_ICONV_ENABLED
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_memory_debug? => (true|false)
+ *
+ * Determine whether libxml memory location debugging support
+ * is enabled.
+ */
+VALUE
+ruby_xml_parser_enabled_memory_debug_location_q(VALUE class) {
+#ifdef DEBUG_MEMORY_LOCATION
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_regexp? => (true|false)
+ *
+ * Determine whether libxml regular expression support is enabled.
+ */
+VALUE
+ruby_xml_parser_enabled_regexp_q(VALUE class) {
+#ifdef LIBXML_REGEXP_ENABLED
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_schemas? => (true|false)
+ *
+ * Determine whether libxml schema support is enabled.
+ */
+VALUE
+ruby_xml_parser_enabled_schemas_q(VALUE class) {
+#ifdef LIBXML_SCHEMAS_ENABLED
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_thread? => (true|false)
+ *
+ * Determine whether libxml thread-safe semantics support
+ * is enabled (I think?).
+ */
+VALUE
+ruby_xml_parser_enabled_thread_q(VALUE class) {
+#ifdef LIBXML_THREAD_ENABLED
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_unicode? => (true|false)
+ *
+ * Determine whether libxml unicode support is enabled.
+ */
+VALUE
+ruby_xml_parser_enabled_unicode_q(VALUE class) {
+#ifdef LIBXML_UNICODE_ENABLED
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_xinclude? => (true|false)
+ *
+ * Determine whether libxml xinclude support is enabled.
+ */
+VALUE
+ruby_xml_parser_enabled_xinclude_q(VALUE class) {
+#ifdef LIBXML_XINCLUDE_ENABLED
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_xpath? => (true|false)
+ *
+ * Determine whether libxml xpath support is enabled.
+ */
+VALUE
+ruby_xml_parser_enabled_xpath_q(VALUE class) {
+#ifdef LIBXML_XPATH_ENABLED
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_xpointer? => (true|false)
+ *
+ * Determine whether libxml xpointer support is enabled.
+ */
+VALUE
+ruby_xml_parser_enabled_xpointer_q(VALUE class) {
+#ifdef LIBXML_XPTR_ENABLED
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.enabled_zlib? => (true|false)
+ *
+ * Determine whether libxml zlib support is enabled.
+ */
+VALUE
+ruby_xml_parser_enabled_zlib_q(VALUE class) {
+#ifdef HAVE_ZLIB_H
+ return(Qtrue);
+#else
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.debug_entities => (true|false)
+ *
+ * Determine whether included-entity debugging is enabled.
+ * (Requires Libxml to be compiled with debugging support)
+ */
+VALUE
+ruby_xml_parser_debug_entities_get(VALUE class) {
+#ifdef LIBXML_DEBUG_ENABLED
+ if (xmlParserDebugEntities)
+ return(Qtrue);
+ else
+ return(Qfalse);
+#else
+ rb_warn("libxml was compiled with debugging turned off");
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.debug_entities = true|false
+ *
+ * Enable or disable included-entity debugging.
+ * (Requires Libxml to be compiled with debugging support)
+ */
+VALUE
+ruby_xml_parser_debug_entities_set(VALUE class, VALUE bool) {
+#ifdef LIBXML_DEBUG_ENABLED
+ if (TYPE(bool) == T_FALSE) {
+ xmlParserDebugEntities = 0;
+ return(Qfalse);
+ } else {
+ xmlParserDebugEntities = 1;
+ return(Qtrue);
+ }
+#else
+ rb_warn("libxml was compiled with debugging turned off");
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_keep_blanks => (true|false)
+ *
+ * Determine whether parsers retain whitespace by default.
+ */
+VALUE
+ruby_xml_parser_default_keep_blanks_get(VALUE class) {
+ if (xmlKeepBlanksDefaultValue)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_keep_blanks = true|false
+ *
+ * Controls whether parsers retain whitespace by default.
+ */
+VALUE
+ruby_xml_parser_default_keep_blanks_set(VALUE class, VALUE bool) {
+ if (TYPE(bool) == T_FALSE) {
+ xmlKeepBlanksDefaultValue = 0;
+ return(Qfalse);
+ } else if (TYPE(bool) == T_TRUE) {
+ xmlKeepBlanksDefaultValue = 1;
+ return(Qtrue);
+ } else {
+ rb_raise(rb_eArgError, "invalid argument, must be a boolean");
+ }
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_load_external_dtd => (true|false)
+ *
+ * Determine whether parsers load external DTDs by default.
+ */
+VALUE
+ruby_xml_parser_default_load_external_dtd_get(VALUE class) {
+ if (xmlSubstituteEntitiesDefaultValue)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_load_external_dtd = true|false
+ *
+ * Controls whether parsers load external DTDs by default.
+ */
+VALUE
+ruby_xml_parser_default_load_external_dtd_set(VALUE class, VALUE bool) {
+ if (TYPE(bool) == T_FALSE) {
+ xmlLoadExtDtdDefaultValue = 0;
+ return(Qfalse);
+ } else {
+ xmlLoadExtDtdDefaultValue = 1;
+ return(Qtrue);
+ }
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_line_numbers => (true|false)
+ *
+ * Determine whether parsers retain line-numbers by default.
+ */
+VALUE
+ruby_xml_parser_default_line_numbers_get(VALUE class) {
+ if (xmlLineNumbersDefaultValue)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_line_numbers = true|false
+ *
+ * Controls whether parsers retain line-numbers by default.
+ */
+VALUE
+ruby_xml_parser_default_line_numbers_set(VALUE class, VALUE bool) {
+ if (TYPE(bool) == T_FALSE) {
+ xmlLineNumbersDefault(0);
+ return(Qfalse);
+ } else {
+ xmlLineNumbersDefault(1);
+ return(Qtrue);
+ }
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_pedantic_parser => (true|false)
+ *
+ * Determine whether parsers are pedantic by default.
+ */
+VALUE
+ruby_xml_parser_default_pedantic_parser_get(VALUE class) {
+ if (xmlPedanticParserDefaultValue)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_pedantic_parser = true|false
+ *
+ * Controls whether parsers are pedantic by default.
+ */
+VALUE
+ruby_xml_parser_default_pedantic_parser_set(VALUE class, VALUE bool) {
+ if (TYPE(bool) == T_FALSE) {
+ xmlPedanticParserDefault(0);
+ return(Qfalse);
+ } else {
+ xmlPedanticParserDefault(1);
+ return(Qtrue);
+ }
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_substitute_entities => (true|false)
+ *
+ * Determine whether parsers perform inline entity substitution
+ * (for external entities) by default.
+ */
+VALUE
+ruby_xml_parser_default_substitute_entities_get(VALUE class) {
+ if (xmlSubstituteEntitiesDefaultValue)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_substitute_entities = true|false
+ *
+ * Controls whether parsers perform inline entity substitution
+ * (for external entities) by default.
+ */
+VALUE
+ruby_xml_parser_default_substitute_entities_set(VALUE class, VALUE bool) {
+ if (TYPE(bool) == T_FALSE) {
+ xmlSubstituteEntitiesDefault(0);
+ return(Qfalse);
+ } else {
+ xmlSubstituteEntitiesDefault(1);
+ return(Qtrue);
+ }
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_tree_indent_string => "string"
+ *
+ * Obtain the default string used by parsers to indent the XML tree
+ * for output.
+ */
+VALUE
+ruby_xml_parser_default_tree_indent_string_get(VALUE class) {
+ if (xmlTreeIndentString == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2(xmlTreeIndentString));
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_tree_indent_string = "string"
+ *
+ * Set the default string used by parsers to indent the XML tree
+ * for output.
+ */
+VALUE
+ruby_xml_parser_default_tree_indent_string_set(VALUE class, VALUE string) {
+ Check_Type(string, T_STRING);
+ xmlTreeIndentString = ruby_strdup(StringValuePtr(string));
+ return(string);
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_validity_checking => (true|false)
+ *
+ * Determine whether parsers perform XML validation by default.
+ */
+VALUE
+ruby_xml_parser_default_validity_checking_get(VALUE class) {
+ if (xmlDoValidityCheckingDefaultValue)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_validity_checking = true|false
+ *
+ * Controls whether parsers perform XML validation by default.
+ */
+VALUE
+ruby_xml_parser_default_validity_checking_set(VALUE class, VALUE bool) {
+ if (TYPE(bool) == T_FALSE) {
+ xmlDoValidityCheckingDefaultValue = 0;
+ return(Qfalse);
+ } else {
+ xmlDoValidityCheckingDefaultValue = 1;
+ return(Qtrue);
+ }
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_warnings => (true|false)
+ *
+ * Determine whether parsers output warnings by default.
+ */
+VALUE
+ruby_xml_parser_default_warnings_get(VALUE class) {
+ if (xmlGetWarningsDefaultValue)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_warnings = true|false
+ *
+ * Controls whether parsers output warnings by default.
+ */
+VALUE
+ruby_xml_parser_default_warnings_set(VALUE class, VALUE bool) {
+ if (TYPE(bool) == T_FALSE) {
+ xmlGetWarningsDefaultValue = 0;
+ return(Qfalse);
+ } else {
+ xmlGetWarningsDefaultValue = 1;
+ return(Qtrue);
+ }
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_compression => (true|false)
+ *
+ * Determine whether parsers use Zlib compression by default
+ * (requires libxml to be compiled with Zlib support).
+ */
+VALUE
+ruby_xml_parser_default_compression_get(VALUE class) {
+#ifdef HAVE_ZLIB_H
+ return(INT2FIX(xmlGetCompressMode()));
+#else
+ rb_warn("libxml was compiled without zlib support");
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.default_compression = true|false
+ *
+ * Controls whether parsers use Zlib compression by default
+ * (requires libxml to be compiled with Zlib support).
+ */
+VALUE
+ruby_xml_parser_default_compression_set(VALUE class, VALUE num) {
+#ifdef HAVE_ZLIB_H
+ Check_Type(num, T_FIXNUM);
+ xmlSetCompressMode(FIX2INT(num));
+ return(num);
+#else
+ rb_warn("libxml was compiled without zlib support");
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.features => ["feature", ..., "feature"]
+ *
+ * Obtains an array of strings representing features supported
+ * (and enabled) by the installed libxml.
+ */
+VALUE
+ruby_xml_parser_features(VALUE class) {
+ VALUE arr, str;
+ int i, len = MAX_LIBXML_FEATURES_LEN;
+ char **list = NULL;
+
+ list = ALLOC_N(char *,MAX_LIBXML_FEATURES_LEN);
+ MEMZERO(list, char *, MAX_LIBXML_FEATURES_LEN);
+
+ arr = rb_ary_new();
+ if (xmlGetFeaturesList(&len, (const char **)list) == -1)
+ return Qnil;
+
+ for (i = 0; i < len; i++) {
+ str = rb_str_new2((const char *)list[i]);
+ rb_gc_unregister_address(&str);
+ rb_ary_push(arr, str);
+ }
+
+ if (len == MAX_LIBXML_FEATURES_LEN)
+ rb_warn("Please contact libxml-devel at rubyforge.org and ask to have the \"MAX_LIBXML_FEATURES_LEN increased\" because you could possibly be seeing an incomplete list");
+
+ ruby_xfree(list);
+ return(arr);
+}
+
+
+/*
+ * call-seq:
+ * parser.filename => "filename"
+ *
+ * Obtain the filename this parser will read from.
+ */
+VALUE
+ruby_xml_parser_filename_get(VALUE self) {
+ ruby_xml_parser *rxp;
+ rx_file_data *data;
+
+ Data_Get_Struct(self, ruby_xml_parser, rxp);
+ if (rxp->data == NULL)
+ return(Qnil);
+
+ if (rxp->data_type != RUBY_LIBXML_SRC_TYPE_FILE)
+ return(Qnil);
+
+ data = (rx_file_data *)rxp->data;
+ return(data->filename);
+}
+
+
+/*
+ * call-seq:
+ * parser.filename = "filename"
+ *
+ * Set the filename this parser will read from.
+ */
+VALUE
+ruby_xml_parser_filename_set(VALUE self, VALUE filename) {
+ ruby_xml_parser *rxp;
+ ruby_xml_parser_context *rxpc;
+ rx_file_data *data;
+
+ Check_Type(filename, T_STRING);
+ Data_Get_Struct(self, ruby_xml_parser, rxp);
+
+ if (rxp->data_type == RUBY_LIBXML_SRC_TYPE_NULL) {
+ if (rxp->data != NULL)
+ rb_fatal("crap, this should be null");
+
+ rxp->data_type = RUBY_LIBXML_SRC_TYPE_FILE;
+ data = ALLOC(rx_file_data);
+ rxp->data = data;
+ } else if (rxp->data_type != RUBY_LIBXML_SRC_TYPE_FILE) {
+ return(Qnil);
+ }
+
+ rxp->ctxt = ruby_xml_parser_context_new3();
+ data = (rx_file_data *)rxp->data;
+ data->filename = filename;
+
+ Data_Get_Struct(rxp->ctxt, ruby_xml_parser_context, rxpc);
+ rxpc->ctxt = xmlCreateFileParserCtxt(StringValuePtr(filename));
+ if (rxpc->ctxt == NULL)
+ rb_sys_fail(StringValuePtr(filename));
+
+ return(data->filename);
+}
+
+
+void
+ruby_xml_parser_free(ruby_xml_parser *rxp) {
+ void *data;
+
+ ruby_xml_parser_count--;
+ if (ruby_xml_parser_count == 0)
+ xmlCleanupParser();
+
+ switch(rxp->data_type) {
+ case RUBY_LIBXML_SRC_TYPE_NULL:
+ break;
+ case RUBY_LIBXML_SRC_TYPE_FILE:
+ data = (void *)(rx_file_data *)rxp->data;
+ free((rx_file_data *)data);
+ break;
+ case RUBY_LIBXML_SRC_TYPE_STRING:
+ data = (void *)(rx_string_data *)rxp->data;
+ free((rx_string_data *)data);
+ break;
+ case RUBY_LIBXML_SRC_TYPE_IO:
+ data = (void *)(rx_io_data *)rxp->data;
+ free((rx_io_data *)data);
+ break;
+ default:
+ rb_fatal("Unknown data type, %d", rxp->data_type);
+ }
+
+ free(rxp);
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.indent_tree_output => (true|false)
+ *
+ * Determines whether XML output will be indented
+ * (using the string supplied to +default_indent_tree_string+)
+ */
+VALUE
+ruby_xml_parser_indent_tree_output_get(VALUE class) {
+ if (xmlIndentTreeOutput)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.indent_tree_output = true|false
+ *
+ * Controls whether XML output will be indented
+ * (using the string supplied to +default_indent_tree_string+)
+ */
+VALUE
+ruby_xml_parser_indent_tree_output_set(VALUE class, VALUE bool) {
+ if (TYPE(bool) == T_TRUE) {
+ xmlIndentTreeOutput = 1;
+ return(Qtrue);
+ } else if (TYPE(bool) == T_FALSE) {
+ xmlIndentTreeOutput = 0;
+ return(Qfalse);
+ } else {
+ rb_raise(rb_eArgError, "invalid argument, must be boolean");
+ }
+}
+
+
+/*
+ * call-seq:
+ * parser.io => IO
+ *
+ * Obtain the IO instance this parser works with.
+ */
+VALUE
+ruby_xml_parser_io_get(VALUE self, VALUE io) {
+ ruby_xml_parser *rxp;
+ rx_io_data *data;
+
+ Data_Get_Struct(self, ruby_xml_parser, rxp);
+
+ if (rxp->data_type == RUBY_LIBXML_SRC_TYPE_NULL ||
+ rxp->data_type != RUBY_LIBXML_SRC_TYPE_IO ||
+ rxp->data == NULL)
+ return(Qnil);
+
+ data = (rx_io_data *)rxp->data;
+
+ return(data->io);
+}
+
+
+/*
+ * call-seq:
+ * parser.io = IO
+ *
+ * Set the IO instance this parser works with.
+ */
+VALUE
+ruby_xml_parser_io_set(VALUE self, VALUE io) {
+ ruby_xml_parser *rxp;
+ ruby_xml_parser_context *rxpc;
+ rx_io_data *data;
+ OpenFile *fptr;
+ FILE *f;
+
+ if (!rb_obj_is_kind_of(io, rb_cIO))
+ rb_raise(rb_eTypeError, "need an IO object");
+
+ Data_Get_Struct(self, ruby_xml_parser, rxp);
+
+ if (rxp->data_type == RUBY_LIBXML_SRC_TYPE_NULL) {
+ if (rxp->data != NULL)
+ rb_fatal("crap, this should be null");
+
+ rxp->data_type = RUBY_LIBXML_SRC_TYPE_IO;
+ data = ALLOC(rx_io_data);
+ rxp->data = data;
+ } else if (rxp->data_type != RUBY_LIBXML_SRC_TYPE_IO) {
+ return(Qnil);
+ }
+
+ rxp->ctxt = ruby_xml_parser_context_new3();
+ data = (rx_io_data *)rxp->data;
+ data->io = io;
+
+ GetOpenFile(io, fptr);
+ rb_io_check_readable(fptr);
+ f = GetWriteFile(fptr);
+
+ Data_Get_Struct(rxp->ctxt, ruby_xml_parser_context, rxpc);
+ rxpc->ctxt = xmlCreateIOParserCtxt(NULL, NULL,
+ (xmlInputReadCallback) ctxtRead,
+ NULL, f, XML_CHAR_ENCODING_NONE);
+ if (NIL_P(rxpc->ctxt))
+ rb_sys_fail(0);
+
+ return(data->io);
+}
+
+
+void
+ruby_xml_parser_mark(ruby_xml_parser *rxp) {
+ if (rxp == NULL) return;
+ if (!NIL_P(rxp->ctxt)) rb_gc_mark(rxp->ctxt);
+
+ switch(rxp->data_type) {
+ case RUBY_LIBXML_SRC_TYPE_NULL:
+ break;
+ case RUBY_LIBXML_SRC_TYPE_FILE:
+ if (!NIL_P(((rx_file_data *)rxp->data)->filename))
+ rb_gc_mark(((rx_file_data *)rxp->data)->filename);
+ break;
+ case RUBY_LIBXML_SRC_TYPE_STRING:
+ if (!NIL_P(((rx_string_data *)rxp->data)->str))
+ rb_gc_mark(((rx_string_data *)rxp->data)->str);
+ break;
+ case RUBY_LIBXML_SRC_TYPE_IO:
+ if (!NIL_P(((rx_io_data *)rxp->data)->io))
+ rb_gc_mark(((rx_io_data *)rxp->data)->io);
+ break;
+ default:
+ rb_fatal("unknown datatype: %d", rxp->data_type);
+ }
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.memory_dump => (true|false)
+ *
+ * Perform a parser memory dump (requires memory debugging
+ * support in libxml).
+ */
+VALUE
+ruby_xml_parser_memory_dump(VALUE self) {
+#ifdef DEBUG_MEMORY_LOCATION
+ xmlMemoryDump();
+ return(Qtrue);
+#else
+ rb_warn("libxml was compiled without memory debugging support");
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.memory_used => num_bytes
+ *
+ * Perform a parser memory dump (requires memory debugging
+ * support in libxml).
+ */
+VALUE
+ruby_xml_parser_memory_used(VALUE self) {
+#ifdef DEBUG_MEMORY_LOCATION
+ return(INT2NUM(xmlMemUsed()));
+#else
+ rb_warn("libxml was compiled without memory debugging support");
+ return(Qfalse);
+#endif
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.new => parser
+ *
+ * Create a new parser instance with no pre-determined source.
+ */
+VALUE
+ruby_xml_parser_new(VALUE class) {
+ ruby_xml_parser *rxp;
+
+ ruby_xml_parser_count++;
+ rxp = ALLOC(ruby_xml_parser);
+ rxp->ctxt = Qnil;
+ rxp->data_type = RUBY_LIBXML_SRC_TYPE_NULL;
+ rxp->data = NULL;
+ rxp->parsed = 0;
+
+ return(Data_Wrap_Struct(class, ruby_xml_parser_mark,
+ ruby_xml_parser_free, rxp));
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.file => parser
+ *
+ * Create a new parser instance that will read the specified file.
+ */
+VALUE
+ruby_xml_parser_new_file(VALUE class, VALUE filename) {
+ VALUE obj;
+ ruby_xml_parser *rxp;
+ rx_file_data *data;
+
+ obj = ruby_xml_parser_new(class);
+ Data_Get_Struct(obj, ruby_xml_parser, rxp);
+
+ data = ALLOC(rx_file_data);
+ rxp->data_type = RUBY_LIBXML_SRC_TYPE_FILE;
+ rxp->data = data;
+
+ ruby_xml_parser_filename_set(obj, filename);
+
+ return(obj);
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.io => parser
+ *
+ * Create a new parser instance that will read from the
+ * specified IO object.
+ */
+VALUE
+ruby_xml_parser_new_io(VALUE class, VALUE io) {
+ VALUE obj;
+ ruby_xml_parser *rxp;
+ rx_io_data *data;
+
+ obj = ruby_xml_parser_new(class);
+ Data_Get_Struct(obj, ruby_xml_parser, rxp);
+
+ data = ALLOC(rx_io_data);
+ rxp->data_type = RUBY_LIBXML_SRC_TYPE_IO;
+ rxp->data = data;
+
+ ruby_xml_parser_io_set(obj, io);
+
+ return(obj);
+}
+
+
+/*
+ * call-seq:
+ * XML::Parser.string => parser
+ *
+ * Create a new parser instance that will parse the given
+ * string.
+ */
+VALUE
+ruby_xml_parser_new_string(VALUE class, VALUE str) {
+ VALUE obj;
+ ruby_xml_parser *rxp;
+ rx_string_data *data;
+
+ obj = ruby_xml_parser_new(class);
+ Data_Get_Struct(obj, ruby_xml_parser, rxp);
+
+ data = ALLOC(rx_string_data);
+ rxp->data_type = RUBY_LIBXML_SRC_TYPE_STRING;
+ rxp->data = data;
+
+ ruby_xml_parser_str_set(obj, str);
+
+ return(obj);
+}
+
+
+/*
+ * call-seq:
+ * parser.parse => document
+ *
+ * Parse the input XML and create an XML::Document with
+ * it's content. If an error occurs, XML::Parser::ParseError
+ * is thrown.
+ */
+VALUE
+ruby_xml_parser_parse(VALUE self) {
+ ruby_xml_document *rxd;
+ ruby_xml_parser *rxp;
+ ruby_xml_parser_context *rxpc;
+ xmlDocPtr xdp;
+ VALUE doc;
+
+ Data_Get_Struct(self, ruby_xml_parser, rxp);
+
+ switch (rxp->data_type) {
+ case RUBY_LIBXML_SRC_TYPE_NULL:
+ return(Qnil);
+ case RUBY_LIBXML_SRC_TYPE_STRING:
+ case RUBY_LIBXML_SRC_TYPE_FILE:
+ case RUBY_LIBXML_SRC_TYPE_IO:
+ Data_Get_Struct(rxp->ctxt, ruby_xml_parser_context, rxpc);
+ if (xmlParseDocument(rxpc->ctxt) == -1) {
+ xmlFreeDoc(rxpc->ctxt->myDoc);
+ rb_raise(eXMLParserParseError, "Document didn't parse");
+ }
+
+ xdp = rxpc->ctxt->myDoc;
+ if (!rxpc->ctxt->wellFormed) {
+ xmlFreeDoc(xdp);
+ xdp = NULL;
+ rb_raise(eXMLParserParseError, "Document did not contain well-formed XML");
+ } else {
+ rxp->parsed = 1;
+ }
+
+ doc = ruby_xml_document_new(cXMLDocument, xdp);
+ Data_Get_Struct(doc, ruby_xml_document, rxd);
+ rxd->is_ptr = 0;
+ rxd->doc = xdp;
+ break;
+ default:
+ rb_fatal("Unknown data type, %d", rxp->data_type);
+ }
+
+ return(doc);
+}
+
+
+/*
+ * call-seq:
+ * parser.context => context
+ *
+ * Obtain the XML::Parser::Context associated with this
+ * parser.
+ */
+VALUE
+ruby_xml_parser_parser_context_get(VALUE self) {
+ ruby_xml_parser *rxp;
+
+ Data_Get_Struct(self, ruby_xml_parser, rxp);
+ if (rxp->ctxt == Qnil)
+ return(Qnil);
+ else
+ return(rxp->ctxt);
+}
+
+
+/*
+ * call-seq:
+ * parser.string => "string"
+ *
+ * Obtain the string this parser works with.
+ */
+VALUE
+ruby_xml_parser_str_get(VALUE self) {
+ ruby_xml_parser *rxp;
+ rx_string_data *data;
+
+ Data_Get_Struct(self, ruby_xml_parser, rxp);
+ if (rxp->data == NULL || rxp->data_type != RUBY_LIBXML_SRC_TYPE_STRING)
+ return(Qnil);
+
+ data = (rx_string_data *)rxp->data;
+ return(data->str);
+}
+
+
+/*
+ * call-seq:
+ * parser.string = "string"
+ *
+ * Set the string this parser works with.
+ */
+VALUE
+ruby_xml_parser_str_set(VALUE self, VALUE str) {
+ ruby_xml_parser *rxp;
+ ruby_xml_parser_context *rxpc;
+ rx_string_data *data;
+
+ Check_Type(str, T_STRING);
+ Data_Get_Struct(self, ruby_xml_parser, rxp);
+
+ if (rxp->data_type == RUBY_LIBXML_SRC_TYPE_NULL) {
+ rxp->data_type = RUBY_LIBXML_SRC_TYPE_STRING;
+ data = ALLOC(rx_string_data);
+ rxp->data = data;
+ } else if (rxp->data_type != RUBY_LIBXML_SRC_TYPE_STRING) {
+ return(Qnil);
+ }
+
+ rxp->ctxt = ruby_xml_parser_context_new3();
+ data = (rx_string_data *)rxp->data;
+ data->str = str;
+
+ Data_Get_Struct(rxp->ctxt, ruby_xml_parser_context, rxpc);
+ 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"
+///
+///VALUE ruby_register_deb(VALUE self) {
+/// deb_register_cbg();
+/// return(Qtrue);
+///}
+
+// Rdoc needs to know
+#ifdef RDOC_NEVER_DEFINED
+ mXML = rb_define_module("XML");
+#endif
+
+void
+ruby_init_parser(void) {
+
+ cXMLParser = rb_define_class_under(mXML, "Parser", rb_cObject);
+ eXMLParserParseError = rb_define_class_under(cXMLParser, "ParseError",
+ rb_eRuntimeError);
+
+ /* Constants */
+ rb_define_const(cXMLParser, "LIBXML_VERSION",
+ rb_str_new2(LIBXML_DOTTED_VERSION));
+ rb_define_const(cXMLParser, "VERSION", rb_str_new2(RUBY_LIBXML_VERSION));
+ rb_define_const(cXMLParser, "VERNUM", INT2NUM(RUBY_LIBXML_VERNUM));
+
+ /* Question-esqe Class Methods */
+ /* RDoc won't have them defined by a macro... */
+ rb_define_singleton_method(cXMLParser, "enabled_automata?",
+ ruby_xml_parser_enabled_automata_q, 0);
+ rb_define_singleton_method(cXMLParser, "enabled_c14n?",
+ ruby_xml_parser_enabled_c14n_q, 0);
+ rb_define_singleton_method(cXMLParser, "enabled_catalog?",
+ ruby_xml_parser_enabled_catalog_q, 0);
+ rb_define_singleton_method(cXMLParser, "enabled_debug?",
+ ruby_xml_parser_enabled_debug_q, 0);
+ rb_define_singleton_method(cXMLParser, "enabled_docbook?",
+ ruby_xml_parser_enabled_docbook_q, 0);
+ rb_define_singleton_method(cXMLParser, "enabled_ftp?",
+ ruby_xml_parser_enabled_ftp_q, 0);
+ rb_define_singleton_method(cXMLParser, "enabled_http?",
+ ruby_xml_parser_enabled_http_q, 0);
+ rb_define_singleton_method(cXMLParser, "enabled_html?",
+ ruby_xml_parser_enabled_html_q, 0);
+ rb_define_singleton_method(cXMLParser, "enabled_iconv?",
+ ruby_xml_parser_enabled_iconv_q, 0);
+ rb_define_singleton_method(cXMLParser, "enabled_memory_debug?",
+ ruby_xml_parser_enabled_memory_debug_location_q, 0);
+ rb_define_singleton_method(cXMLParser, "enabled_regexp?",
+ ruby_xml_parser_enabled_regexp_q, 0);
+ rb_define_singleton_method(cXMLParser, "enabled_schemas?",
+ ruby_xml_parser_enabled_schemas_q, 0);
+ rb_define_singleton_method(cXMLParser, "enabled_thread?",
+ ruby_xml_parser_enabled_thread_q, 0);
+ rb_define_singleton_method(cXMLParser, "enabled_unicode?",
+ ruby_xml_parser_enabled_unicode_q, 0);
+ rb_define_singleton_method(cXMLParser, "enabled_xinclude?",
+ ruby_xml_parser_enabled_xinclude_q, 0);
+ rb_define_singleton_method(cXMLParser, "enabled_xpath?",
+ ruby_xml_parser_enabled_xpath_q, 0);
+ rb_define_singleton_method(cXMLParser, "enabled_xpointer?",
+ ruby_xml_parser_enabled_xpointer_q, 0);
+ rb_define_singleton_method(cXMLParser, "enabled_zlib?",
+ ruby_xml_parser_enabled_zlib_q, 0);
+
+ /* Other Class Methods */
+/// rb_define_singleton_method(cXMLParser, "register_deb",
+/// ruby_register_deb, 0);
+
+ // TODO Maybe a set of 'xxxx_catalog' aliases might be more Ruby?
+ rb_define_singleton_method(cXMLParser, "catalog_dump",
+ ruby_xml_parser_catalog_dump, 0);
+ rb_define_singleton_method(cXMLParser, "catalog_remove",
+ ruby_xml_parser_catalog_remove, 1);
+ rb_define_singleton_method(cXMLParser, "check_lib_versions",
+ ruby_xml_parser_check_lib_versions, 0);
+
+ // TODO should this be debug_entities_q / debug_entities_set?
+ // should all these default attribute pairs work that way?
+ rb_define_singleton_method(cXMLParser, "debug_entities",
+ ruby_xml_parser_debug_entities_get, 0);
+ rb_define_singleton_method(cXMLParser, "debug_entities=",
+ ruby_xml_parser_debug_entities_set, 1);
+ rb_define_singleton_method(cXMLParser, "default_compression",
+ ruby_xml_parser_default_compression_get, 0);
+ rb_define_singleton_method(cXMLParser, "default_compression=",
+ ruby_xml_parser_default_compression_set, 1);
+ rb_define_singleton_method(cXMLParser, "default_keep_blanks",
+ ruby_xml_parser_default_keep_blanks_get, 0);
+ rb_define_singleton_method(cXMLParser, "default_keep_blanks=",
+ ruby_xml_parser_default_keep_blanks_set, 1);
+ rb_define_singleton_method(cXMLParser, "default_load_external_dtd",
+ ruby_xml_parser_default_load_external_dtd_set, 0);
+ rb_define_singleton_method(cXMLParser, "default_load_external_dtd=",
+ ruby_xml_parser_default_load_external_dtd_get, 1);
+ rb_define_singleton_method(cXMLParser, "default_line_numbers",
+ ruby_xml_parser_default_line_numbers_get, 0);
+ rb_define_singleton_method(cXMLParser, "default_line_numbers=",
+ ruby_xml_parser_default_line_numbers_set, 1);
+ rb_define_singleton_method(cXMLParser, "default_pedantic_parser",
+ ruby_xml_parser_default_pedantic_parser_get, 0);
+ rb_define_singleton_method(cXMLParser, "default_pedantic_parser=",
+ ruby_xml_parser_default_pedantic_parser_set, 1);
+ rb_define_singleton_method(cXMLParser, "default_substitute_entities",
+ ruby_xml_parser_default_substitute_entities_get, 0);
+ rb_define_singleton_method(cXMLParser, "default_substitute_entities=",
+ ruby_xml_parser_default_substitute_entities_set, 1);
+ rb_define_singleton_method(cXMLParser, "default_tree_indent_string",
+ ruby_xml_parser_default_tree_indent_string_get, 0);
+ rb_define_singleton_method(cXMLParser, "default_tree_indent_string=",
+ ruby_xml_parser_default_tree_indent_string_set, 1);
+ rb_define_singleton_method(cXMLParser, "default_validity_checking",
+ ruby_xml_parser_default_validity_checking_get, 0);
+ rb_define_singleton_method(cXMLParser, "default_validity_checking=",
+ ruby_xml_parser_default_validity_checking_set, 1);
+ rb_define_singleton_method(cXMLParser, "default_warnings",
+ ruby_xml_parser_default_warnings_get, 0);
+ rb_define_singleton_method(cXMLParser, "default_warnings=",
+ ruby_xml_parser_default_warnings_set, 1);
+
+ rb_define_singleton_method(cXMLParser, "features", ruby_xml_parser_features, 0);
+ rb_define_singleton_method(cXMLParser, "file", ruby_xml_parser_new_file, 1);
+ rb_define_singleton_method(cXMLParser, "indent_tree_output", ruby_xml_parser_indent_tree_output_get, 0);
+ rb_define_singleton_method(cXMLParser, "indent_tree_output=", ruby_xml_parser_indent_tree_output_set, 1);
+ rb_define_singleton_method(cXMLParser, "io", ruby_xml_parser_new_io, 1);
+ rb_define_singleton_method(cXMLParser, "memory_dump",
+ 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");
+}
Added: packages-wip/libxml-ruby/trunk/ruby_xml_parser.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_parser.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_parser.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,31 @@
+/* $Id: ruby_xml_parser.h,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RUBY_XML_PARSER__
+#define __RUBY_XML_PARSER__
+
+#define MAX_LIBXML_FEATURES_LEN 50
+
+extern int ruby_xml_parser_count;
+extern VALUE cXMLParser;
+extern VALUE eXMLParserParseError;
+
+typedef struct ruby_xml_parser {
+ VALUE ctxt;
+ int parsed;
+ void *data;
+ int data_type;
+} ruby_xml_parser;
+
+VALUE ruby_xml_parser_default_load_external_dtd_set(VALUE class, VALUE bool);
+VALUE ruby_xml_parser_default_substitute_entities_set(VALUE class, VALUE bool);
+VALUE ruby_xml_parser_features(VALUE self);
+VALUE ruby_xml_parser_filename_get(VALUE self);
+VALUE ruby_xml_parser_filename_set(VALUE self, VALUE filename);
+VALUE ruby_xml_parser_new(VALUE class);
+VALUE ruby_xml_parser_parse(VALUE self);
+VALUE ruby_xml_parser_str_get(VALUE self);
+VALUE ruby_xml_parser_str_set(VALUE self, VALUE str);
+
+#endif
Added: packages-wip/libxml-ruby/trunk/ruby_xml_parser_context.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_parser_context.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_parser_context.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,715 @@
+/* $Id: ruby_xml_parser_context.c,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#include "libxml.h"
+#include "ruby_xml_parser_context.h"
+
+/* TODO:
+ *
+ * *) xmlParserInput class/structure
+ * *) errNo and mappings
+ * *) validity context
+ * *) record_info or stats class/structure
+ * *) xmlParserNodeInfoSeq
+ * *) xmlParserInputState
+ */
+VALUE cXMLParserContext;
+
+/*
+ * call-seq:
+ * context.data_directory => "dir"
+ *
+ * Obtain the data directory associated with this context.
+ */
+VALUE
+ruby_xml_parser_context_data_directory_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->directory == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2(rxpc->ctxt->directory));
+}
+
+
+/*
+ * call-seq:
+ * context.depth => num
+ *
+ * Obtain the depth of this context.
+ */
+VALUE
+ruby_xml_parser_context_depth_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ return(INT2NUM(rxpc->ctxt->depth));
+}
+
+
+/*
+ * call-seq:
+ * context.disable_sax? => (true|false)
+ *
+ * Determine whether SAX-based processing is disabled
+ * in this context.
+ */
+VALUE
+ruby_xml_parser_context_disable_sax_q(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->disableSAX)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * context.doc => document
+ *
+ * Obtain the +XML::Document+ associated with this context.
+ */
+VALUE
+ruby_xml_parser_context_doc_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->myDoc == NULL)
+ return(Qnil);
+
+ return(ruby_xml_document_new4(cXMLDocument, rxpc->ctxt->myDoc));
+}
+
+
+/*
+ * call-seq:
+ * context.docbook? => (true|false)
+ *
+ * Determine whether this is a docbook context.
+ */
+VALUE
+ruby_xml_parser_context_docbook_q(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->html == 2) // TODO check this
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * context.encoding => "encoding"
+ *
+ * Obtain the character encoding identifier used in
+ * this context.
+ */
+VALUE
+ruby_xml_parser_context_encoding_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->encoding == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)rxpc->ctxt->encoding));
+}
+
+
+/*
+ * call-seq:
+ * context.errno => num
+ *
+ * Obtain the last-error number in this context.
+ */
+VALUE
+ruby_xml_parser_context_errno_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ return(INT2NUM(rxpc->ctxt->errNo));
+}
+
+
+void
+ruby_xml_parser_context_free(ruby_xml_parser_context *rxpc) {
+ if (rxpc->ctxt != NULL && !rxpc->is_ptr) {
+ xmlFreeParserCtxt(rxpc->ctxt);
+ ruby_xml_parser_count--;
+ rxpc->ctxt = NULL;
+ }
+
+ if (ruby_xml_parser_count == 0)
+ xmlCleanupParser();
+
+ free(rxpc);
+}
+
+
+/*
+ * call-seq:
+ * context.html? => (true|false)
+ *
+ * Determine whether this is an html context.
+ */
+VALUE
+ruby_xml_parser_context_html_q(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->html == 1)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * context.max_num_streams => num
+ *
+ * Obtain the limit on the number of IO streams opened in
+ * this context.
+ */
+VALUE
+ruby_xml_parser_context_io_max_num_streams_get(VALUE self) {
+ // TODO alias to max_streams and dep this?
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ return(INT2NUM(rxpc->ctxt->inputMax));
+}
+
+
+/*
+ * call-seq:
+ * context.num_streams => "dir"
+ *
+ * Obtain the actual number of IO streams in this
+ * context.
+ */
+VALUE
+ruby_xml_parser_context_io_num_streams_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ return(INT2NUM(rxpc->ctxt->inputNr));
+}
+
+
+/*
+ * call-seq:
+ * context.keep_blanks? => (true|false)
+ *
+ * Determine whether parsers in this context retain
+ * whitespace.
+ */
+VALUE
+ruby_xml_parser_context_keep_blanks_q(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->keepBlanks)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * context.name_depth => num
+ *
+ * Obtain the name depth for this context.
+ */
+VALUE
+ruby_xml_parser_context_name_depth_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ return(INT2NUM(rxpc->ctxt->nameNr));
+}
+
+
+/*
+ * call-seq:
+ * context.name_depth_max => num
+ *
+ * Obtain the maximum name depth for this context.
+ */
+VALUE
+ruby_xml_parser_context_name_depth_max_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ return(INT2NUM(rxpc->ctxt->nameMax));
+}
+
+
+/*
+ * call-seq:
+ * context.name_node => "name"
+ *
+ * Obtain the name node for this context.
+ */
+VALUE
+ruby_xml_parser_context_name_node_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->name == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)rxpc->ctxt->name));
+}
+
+
+/*
+ * call-seq:
+ * context.name_tab => ["name", ..., "name"]
+ *
+ * Obtain the name table for this context.
+ */
+VALUE
+ruby_xml_parser_context_name_tab_get(VALUE self) {
+ int i;
+ ruby_xml_parser_context *rxpc;
+ VALUE tab_ary;
+
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->nameTab == NULL)
+ return(Qnil);
+
+ tab_ary = rb_ary_new();
+
+ for (i = (rxpc->ctxt->nameNr - 1); i >= 0; i--) {
+ if (rxpc->ctxt->nameTab[i] == NULL)
+ continue;
+ else
+ rb_ary_push(tab_ary, rb_str_new2((const char*)rxpc->ctxt->nameTab[i]));
+ }
+
+ return(tab_ary);
+}
+
+
+/*
+ * call-seq:
+ * context.node_depth => num
+ *
+ * Obtain the node depth for this context.
+ */
+VALUE
+ruby_xml_parser_context_node_depth_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ return(INT2NUM(rxpc->ctxt->nodeNr));
+}
+
+
+/*
+ * call-seq:
+ * context.node => node
+ *
+ * Obtain the root node of this context.
+ */
+VALUE
+ruby_xml_parser_context_node_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->node == NULL)
+ return(Qnil);
+ else
+ return(ruby_xml_node_new2(cXMLNode,
+ ruby_xml_document_new(cXMLDocument, rxpc->ctxt->myDoc),
+ rxpc->ctxt->node));
+}
+
+
+/*
+ * call-seq:
+ * context.node_depth_max => num
+ *
+ * Obtain the maximum node depth for this context.
+ */
+VALUE
+ruby_xml_parser_context_node_depth_max_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ return(INT2NUM(rxpc->ctxt->nodeMax));
+}
+
+
+/*
+ * call-seq:
+ * context.num_chars => num
+ *
+ * Obtain the number of characters in this context.
+ */
+VALUE
+ruby_xml_parser_context_num_chars_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ return(LONG2NUM(rxpc->ctxt->nbChars));
+}
+
+
+VALUE
+ruby_xml_parser_context_new(VALUE class, xmlParserCtxtPtr ctxt) {
+ ruby_xml_parser_context *rxpc;
+
+ rxpc = ALLOC(ruby_xml_parser_context);
+ ruby_xml_parser_count++;
+
+ rxpc->ctxt = ctxt;
+ rxpc->is_ptr = 0;
+ return(Data_Wrap_Struct(class, 0, ruby_xml_parser_context_free, rxpc));
+}
+
+
+VALUE
+ruby_xml_parser_context_new2(VALUE class) {
+ return(ruby_xml_parser_context_new(class, NULL));
+}
+
+
+VALUE
+ruby_xml_parser_context_new3() {
+ return(ruby_xml_parser_context_new2(cXMLParserContext));
+}
+
+
+/*
+ * call-seq:
+ * context.replace_entities? => (true|false)
+ *
+ * Determine whether external entity replacement is enabled in this
+ * context.
+ */
+VALUE
+ruby_xml_parser_context_replace_entities_q(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->replaceEntities)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * context.replace_entities = true|false
+ *
+ * Control whether external entity replacement is enabled in this
+ * context.
+ */
+VALUE
+ruby_xml_parser_context_replace_entities_set(VALUE self, VALUE bool) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (TYPE(bool) == T_FALSE) {
+ rxpc->ctxt->replaceEntities = 0;
+ return(Qfalse);
+ } else {
+ rxpc->ctxt->replaceEntities = 1;
+ return(Qfalse);
+ }
+}
+
+
+/*
+ * call-seq:
+ * context.space_depth => num
+ *
+ * Obtain the space depth for this context.
+ */
+VALUE
+ruby_xml_parser_context_space_depth_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ return(INT2NUM(rxpc->ctxt->spaceNr));
+}
+
+
+/*
+ * call-seq:
+ * context.space_depth => num
+ *
+ * Obtain the maximum space depth for this context.
+ */
+VALUE
+ruby_xml_parser_context_space_depth_max_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ return(INT2NUM(rxpc->ctxt->spaceMax));
+}
+
+
+/*
+ * call-seq:
+ * context.subset_external? => (true|false)
+ *
+ * Determine whether this context is a subset of an
+ * external context.
+ */
+VALUE
+ruby_xml_parser_context_subset_external_q(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->inSubset == 2)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * context.subset_internal? => (true|false)
+ *
+ * Determine whether this context is a subset of an
+ * internal context.
+ */
+VALUE
+ruby_xml_parser_context_subset_internal_q(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->inSubset == 1)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * context.subset_name => "name"
+ *
+ * Obtain this context's subset name (valid only if
+ * either of subset_external? or subset_internal?
+ * is true).
+ */
+VALUE
+ruby_xml_parser_context_subset_name_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->intSubName == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)rxpc->ctxt->intSubName));
+}
+
+
+/*
+ * call-seq:
+ * context.subset_external_uri => "uri"
+ *
+ * Obtain this context's external subset URI. (valid only if
+ * either of subset_external? or subset_internal?
+ * is true).
+ */
+VALUE
+ruby_xml_parser_context_subset_external_uri_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->extSubURI == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)rxpc->ctxt->extSubURI));
+}
+
+
+/*
+ * call-seq:
+ * context.subset_external_system_id => "system_id"
+ *
+ * Obtain this context's external subset system identifier.
+ * (valid only if either of subset_external? or subset_internal?
+ * is true).
+ */
+VALUE
+ruby_xml_parser_context_subset_external_system_id_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->extSubSystem == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)rxpc->ctxt->extSubSystem));
+}
+
+
+/*
+ * call-seq:
+ * context.standalone? => (true|false)
+ *
+ * Determine whether this is a standalone context.
+ */
+VALUE
+ruby_xml_parser_context_standalone_q(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->standalone)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * context.stats? => (true|false)
+ *
+ * Determine whether this context maintains statistics.
+ */
+VALUE
+ruby_xml_parser_context_stats_q(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->record_info)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * context.valid? => (true|false)
+ *
+ * Determine whether this context is valid.
+ */
+VALUE
+ruby_xml_parser_context_valid_q(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->valid)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * context.validate? => (true|false)
+ *
+ * Determine whether validation is enabled in this context.
+ */
+VALUE
+ruby_xml_parser_context_validate_q(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->validate)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+/*
+ * call-seq:
+ * context.version => "version"
+ *
+ * Obtain this context's version identifier.
+ */
+VALUE
+ruby_xml_parser_context_version_get(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->version == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)rxpc->ctxt->version));
+}
+
+
+/*
+ * call-seq:
+ * context.well_formed? => (true|false)
+ *
+ * Determine whether this context contains well-formed XML.
+ */
+VALUE
+ruby_xml_parser_context_well_formed_q(VALUE self) {
+ ruby_xml_parser_context *rxpc;
+ Data_Get_Struct(self, ruby_xml_parser_context, rxpc);
+
+ if (rxpc->ctxt->wellFormed)
+ return(Qtrue);
+ else
+ return(Qfalse);
+}
+
+
+// Rdoc needs to know
+#ifdef RDOC_NEVER_DEFINED
+ mXML = rb_define_module("XML");
+ cXMLParser = rb_define_class_under(mXML, "Parser", rb_cObject);
+#endif
+
+void
+ruby_init_xml_parser_context(void) {
+ cXMLParserContext = rb_define_class_under(cXMLParser, "Context", rb_cObject);
+
+ rb_define_method(cXMLParserContext, "data_directory", ruby_xml_parser_context_data_directory_get, 0);
+ rb_define_method(cXMLParserContext, "depth", ruby_xml_parser_context_depth_get, 0);
+ rb_define_method(cXMLParserContext, "disable_sax?", ruby_xml_parser_context_disable_sax_q, 0);
+ rb_define_method(cXMLParserContext, "doc", ruby_xml_parser_context_doc_get, 0);
+ rb_define_method(cXMLParserContext, "docbook?", ruby_xml_parser_context_docbook_q, 0);
+ rb_define_method(cXMLParserContext, "encoding", ruby_xml_parser_context_encoding_get, 0);
+ rb_define_method(cXMLParserContext, "errno", ruby_xml_parser_context_errno_get, 0);
+ rb_define_method(cXMLParserContext, "html?", ruby_xml_parser_context_html_q, 0);
+ rb_define_method(cXMLParserContext, "io_max_num_streams", ruby_xml_parser_context_io_max_num_streams_get, 0);
+ rb_define_method(cXMLParserContext, "io_num_streams", ruby_xml_parser_context_io_num_streams_get, 0);
+ rb_define_method(cXMLParserContext, "keep_blanks?", ruby_xml_parser_context_keep_blanks_q, 0);
+ rb_define_method(cXMLParserContext, "name_node", ruby_xml_parser_context_name_node_get, 0);
+ rb_define_method(cXMLParserContext, "name_depth", ruby_xml_parser_context_name_depth_get, 0);
+ rb_define_method(cXMLParserContext, "name_depth_max", ruby_xml_parser_context_name_depth_max_get, 0);
+ rb_define_method(cXMLParserContext, "name_tab", ruby_xml_parser_context_name_tab_get, 0);
+ rb_define_method(cXMLParserContext, "node", ruby_xml_parser_context_node_get, 0);
+ rb_define_method(cXMLParserContext, "node_depth", ruby_xml_parser_context_node_depth_get, 0);
+ rb_define_method(cXMLParserContext, "node_depth_max", ruby_xml_parser_context_node_depth_max_get, 0);
+ rb_define_method(cXMLParserContext, "num_chars", ruby_xml_parser_context_num_chars_get, 0);
+ rb_define_method(cXMLParserContext, "replace_entities?", ruby_xml_parser_context_replace_entities_q, 0);
+ rb_define_method(cXMLParserContext, "replace_entities=", ruby_xml_parser_context_replace_entities_set, 1);
+ rb_define_method(cXMLParserContext, "space_depth", ruby_xml_parser_context_space_depth_get, 0);
+ rb_define_method(cXMLParserContext, "space_depth_max", ruby_xml_parser_context_space_depth_max_get, 0);
+ rb_define_method(cXMLParserContext, "subset_external?", ruby_xml_parser_context_subset_external_q, 0);
+ rb_define_method(cXMLParserContext, "subset_external_system_id", ruby_xml_parser_context_subset_external_system_id_get, 0);
+ rb_define_method(cXMLParserContext, "subset_external_uri", ruby_xml_parser_context_subset_name_get, 0);
+ rb_define_method(cXMLParserContext, "subset_internal?", ruby_xml_parser_context_subset_internal_q, 0);
+ rb_define_method(cXMLParserContext, "subset_internal_name", ruby_xml_parser_context_subset_name_get, 0);
+ rb_define_method(cXMLParserContext, "stats?", ruby_xml_parser_context_stats_q, 0);
+ rb_define_method(cXMLParserContext, "standalone?", ruby_xml_parser_context_standalone_q, 0);
+ rb_define_method(cXMLParserContext, "valid", ruby_xml_parser_context_valid_q, 0);
+ rb_define_method(cXMLParserContext, "validate?", ruby_xml_parser_context_validate_q, 0);
+ rb_define_method(cXMLParserContext, "version", ruby_xml_parser_context_version_get, 0);
+ rb_define_method(cXMLParserContext, "well_formed?", ruby_xml_parser_context_well_formed_q, 0);
+}
Added: packages-wip/libxml-ruby/trunk/ruby_xml_parser_context.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_parser_context.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_parser_context.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,22 @@
+/* $Id: ruby_xml_parser_context.h,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RUBY_XML_PARSER_CONTEXT__
+#define __RUBY_XML_PARSER_CONTEXT__
+
+extern VALUE cXMLParserContext;
+
+typedef struct ruby_xml_parser_context {
+ xmlParserCtxtPtr ctxt;
+ int is_ptr;
+} ruby_xml_parser_context;
+
+void ruby_xml_parser_context_free(ruby_xml_parser_context *ctxt);
+void ruby_init_xml_parser_context(void);
+VALUE ruby_xml_parser_context_new(VALUE class, xmlParserCtxtPtr ctxt);
+VALUE ruby_xml_parser_context_new2(VALUE class);
+VALUE ruby_xml_parser_context_new3();
+VALUE ruby_xml_parser_context_each(VALUE self);
+
+#endif
Added: packages-wip/libxml-ruby/trunk/ruby_xml_sax_parser.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_sax_parser.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_sax_parser.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,426 @@
+/* $Id: ruby_xml_sax_parser.c,v 1.4 2006/04/14 23:46:06 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#include "libxml.h"
+#include "ruby_xml_sax_parser.h"
+
+VALUE cXMLSaxParser;
+VALUE callsym;
+
+#include "sax_parser_callbacks.inc"
+
+void
+ruby_xml_sax_parser_free(ruby_xml_sax_parser *rxsp) {
+ /* Apparently this isn't needed: time will tell */
+ /* if (rxsp->xsh != NULL) */
+ /* xmlFreeSax_Parser(rxsp->sax_parser); */
+}
+
+#define mark_handler(rxsp, handler) \
+ if (rxsp->cbp->handler && (rxsp->cbp->handler != Qnil)) \
+ rb_gc_mark(rxsp->cbp->handler)
+
+void
+ruby_xml_sax_parser_mark(ruby_xml_sax_parser *rxsp) {
+ mark_handler(rxsp, internalSubset);
+ mark_handler(rxsp, isStandalone);
+ mark_handler(rxsp, hasInternalSubset);
+ mark_handler(rxsp, hasExternalSubset);
+ mark_handler(rxsp, startDocument);
+ mark_handler(rxsp, endDocument);
+ mark_handler(rxsp, startElement);
+ mark_handler(rxsp, endElement);
+ mark_handler(rxsp, reference);
+ mark_handler(rxsp, characters);
+ mark_handler(rxsp, processingInstruction);
+ mark_handler(rxsp, comment);
+ mark_handler(rxsp, xmlParserWarning);
+ mark_handler(rxsp, xmlParserError);
+ mark_handler(rxsp, xmlParserFatalError);
+ mark_handler(rxsp, cdataBlock);
+}
+
+
+/*
+ * call-seq:
+ * XML::SaxParser.new => sax_parser
+ *
+ * Create a new XML::SaxParser instance.
+ */
+VALUE
+ruby_xml_sax_parser_new(VALUE class) {
+ ruby_xml_sax_parser *rxsp;
+
+ rxsp = ALLOC(ruby_xml_sax_parser);
+ rxsp->cbp = ALLOC(ruby_xml_sax_parser_callbacks);
+ memset(rxsp->cbp, 0, sizeof(ruby_xml_sax_parser_callbacks));
+ rxsp->xsh = &rubySAXHandlerStruct;
+
+ rxsp->xpc = NULL;
+ rxsp->filename = Qnil;
+ rxsp->str = Qnil;
+
+ return(Data_Wrap_Struct(class, ruby_xml_sax_parser_mark,
+ ruby_xml_sax_parser_free, rxsp));
+}
+
+
+/*
+ * call-seq:
+ * sax_parser.filename => "filename"
+ *
+ * Obtain the filename this parser reads from.
+ */
+VALUE
+ruby_xml_sax_parser_filename_get(VALUE self) {
+ ruby_xml_sax_parser *rxsp;
+ Data_Get_Struct(self, ruby_xml_sax_parser, rxsp);
+ return(rxsp->filename);
+}
+
+
+/*
+ * call-seq:
+ * sax_parser.filename = "filename"
+ *
+ * Set the filename this parser reads from.
+ */
+VALUE
+ruby_xml_sax_parser_filename_set(VALUE self, VALUE filename) {
+ ruby_xml_sax_parser *rxsp;
+ Check_Type(filename, T_STRING);
+ Data_Get_Struct(self, ruby_xml_sax_parser, rxsp);
+ rxsp->filename = filename;
+ return(rxsp->filename);
+}
+
+#define set_handler(self, argc, argv, handler) \
+ VALUE proc; \
+ rb_scan_args(argc, argv, "0&", &proc); \
+ ruby_xml_sax_parser *rxsp; \
+ Data_Get_Struct(self, ruby_xml_sax_parser, rxsp); \
+ rxsp->cbp->handler = proc; \
+ return(Qnil);
+
+
+/*
+ * call-seq:
+ * parser.on_internal_subset { |name, external_id, system_id| ... } => nil
+ *
+ * Set the callback block for an internal subset event.
+ */
+VALUE
+ruby_xml_sax_parser_on_internal_subset(int argc, VALUE *argv, VALUE self) {
+ set_handler(self, argc, argv, internalSubset);
+}
+
+
+/*
+ * call-seq:
+ * parser.on_is_standalone { || ... } => nil
+ *
+ * Set the callback proc for 'is standalone' event.
+ */
+VALUE
+ruby_xml_sax_parser_on_is_standalone(int argc, VALUE *argv, VALUE self) {
+ set_handler(self, argc, argv, isStandalone);
+}
+
+
+/*
+ * call-seq:
+ * parser.on_has_internal_subset { || ... } => nil
+ *
+ * Set the callback proc for an internal subset notification event.
+ */
+VALUE
+ruby_xml_sax_parser_on_has_internal_subset(int argc, VALUE *argv, VALUE self) {
+ set_handler(self, argc, argv, hasInternalSubset);
+}
+
+
+/*
+ * call-seq:
+ * parser.on_has_external_subset { || ... } => nil
+ *
+ * Set the callback proc for an external subset notification event.
+ */
+VALUE
+ruby_xml_sax_parser_on_has_external_subset(int argc, VALUE *argv, VALUE self) {
+ set_handler(self, argc, argv, hasExternalSubset);
+}
+
+
+/*
+ * call-seq:
+ * parser.on_start_document { || ... } => nil
+ *
+ * Set the callback proc for a start document event.
+ */
+VALUE
+ruby_xml_sax_parser_on_start_document(int argc, VALUE *argv, VALUE self) {
+ set_handler(self, argc, argv, startDocument);
+}
+
+
+/*
+ * call-seq:
+ * parser.on_end_document { || ... } => nil
+ *
+ * Set the callback proc for an end document event.
+ */
+VALUE
+ruby_xml_sax_parser_on_end_document(int argc, VALUE *argv, VALUE self) {
+ set_handler(self, argc, argv, endDocument);
+}
+
+
+/*
+ * call-seq:
+ * parser.on_start_element { |name, attr_hash| ... } => nil
+ *
+ * Set the callback proc for an element start event.
+ */
+VALUE
+ruby_xml_sax_parser_on_start_element(int argc, VALUE *argv, VALUE self) {
+ set_handler(self, argc, argv, startElement);
+}
+
+
+/*
+ * call-seq:
+ * parser.on_end_element { |name| ... } => nil
+ *
+ * Set the callback proc for an element end event.
+ */
+VALUE
+ruby_xml_sax_parser_on_end_element(int argc, VALUE *argv, VALUE self) {
+ set_handler(self, argc, argv, endElement);
+}
+
+
+/*
+ * call-seq:
+ * parser.on_reference { |name| ... } => nil
+ *
+ * Set the callback proc for a reference event.
+ */
+VALUE
+ruby_xml_sax_parser_on_reference(int argc, VALUE *argv, VALUE self) {
+ set_handler(self, argc, argv, reference);
+}
+
+
+/*
+ * call-seq:
+ * parser.on_characters { |chars| ... } => nil
+ *
+ * Set the callback proc for a characters event.
+ */
+VALUE
+ruby_xml_sax_parser_on_characters(int argc, VALUE *argv, VALUE self) {
+ set_handler(self, argc, argv, characters);
+}
+
+
+/*
+ * call-seq:
+ * parser.on_processing_instruction { |target, data| ... } => nil
+ *
+ * Set the callback proc for an processing instruction event.
+ */
+VALUE
+ruby_xml_sax_parser_on_processing_instruction(int argc, VALUE *argv, VALUE self) {
+ set_handler(self, argc, argv, processingInstruction);
+}
+
+
+/*
+ * call-seq:
+ * parser.on_comment { |msg| ... } => nil
+ *
+ * Set the callback proc for a comment event.
+ */
+VALUE
+ruby_xml_sax_parser_on_comment(int argc, VALUE *argv, VALUE self) {
+ set_handler(self, argc, argv, comment);
+}
+
+
+/*
+ * call-seq:
+ * parser.on_parser_warning { |msg| ... } => nil
+ *
+ * Set the callback proc that receives parser warnings.
+ */
+VALUE
+ruby_xml_sax_parser_on_parser_warning(int argc, VALUE *argv, VALUE self) {
+ set_handler(self, argc, argv, xmlParserWarning);
+}
+
+
+/*
+ * call-seq:
+ * parser.on_parser_error { |msg| ... } => nil
+ *
+ * Set the callback proc that receives parser errors.
+ */
+VALUE
+ruby_xml_sax_parser_on_parser_error(int argc, VALUE *argv, VALUE self) {
+ set_handler(self, argc, argv, xmlParserError);
+}
+
+
+/*
+ * call-seq:
+ * parser.on_parser_fatal_error { |msg| ... } => nil
+ *
+ * Set the callback proc that receives fatal parser errors.
+ */
+VALUE
+ruby_xml_sax_parser_on_parser_fatal_error(int argc, VALUE *argv, VALUE self) {
+ set_handler(self, argc, argv, xmlParserFatalError);
+}
+
+/*
+ * call-seq:
+ * parser.on_cdata_block { |cdata| ... } => nil
+ *
+ * Set the callback proc for a CDATA block event.
+ */
+VALUE
+ruby_xml_sax_parser_on_cdata_block(int argc, VALUE *argv, VALUE self) {
+ set_handler(self, argc, argv, cdataBlock);
+}
+
+/*
+ * call-seq:
+ * parser.on_external_subset { |name, external_id, system_id| ... } => nil
+ *
+ * Set the callback proc for an external subset event.
+ */
+VALUE
+ruby_xml_sax_parser_on_external_subset(int argc, VALUE *argv, VALUE self) {
+ set_handler(self, argc, argv, externalSubset);
+}
+
+
+/*
+ * call-seq:
+ * parser.parse => (true|false)
+ *
+ * Parse the input XML, generating callbacks to the procs
+ * registered with the parser (via the on_xxxx attributes).
+ */
+VALUE
+ruby_xml_sax_parser_parse(VALUE self) {
+ char *str;
+ int status = 1;
+ ruby_xml_sax_parser *rxsp;
+
+ Data_Get_Struct(self, ruby_xml_sax_parser, rxsp);
+
+ if (rxsp->filename != Qnil) {
+ status = xmlSAXUserParseFile(rxsp->xsh, rxsp->cbp, StringValuePtr(rxsp->filename));
+ } else if (rxsp->str != Qnil) {
+ str = StringValuePtr(rxsp->str);
+ status = //ruby_xml_document_new(cXMLDocument,
+ xmlSAXUserParseMemory(rxsp->xsh, rxsp->cbp,
+ str, strlen(str)); //);
+ }
+
+ /* XXX This should return an exception for the various error codes
+ * that can come back in status, but I'm too lazy to do that right
+ * now. */
+ if (status)
+ return(Qfalse);
+ else
+ return(Qtrue);
+}
+
+
+/*
+ * call-seq:
+ * parser.string => "xml"
+ *
+ * Obtain the parser's input string.
+ */
+VALUE
+ruby_xml_sax_parser_str_get(VALUE self) {
+ ruby_xml_sax_parser *rxsp;
+ Data_Get_Struct(self, ruby_xml_sax_parser, rxsp);
+ return(rxsp->str);
+}
+
+
+/*
+ * call-seq:
+ * parser.string = "xml"
+ *
+ * Set the parser's input string.
+ */
+VALUE
+ruby_xml_sax_parser_str_set(VALUE self, VALUE str) {
+ ruby_xml_sax_parser *rxsp;
+ Check_Type(str, T_STRING);
+ Data_Get_Struct(self, ruby_xml_sax_parser, rxsp);
+ rxsp->str = str;
+ return(rxsp->str);
+}
+
+// Rdoc needs to know
+#ifdef RDOC_NEVER_DEFINED
+ mXML = rb_define_module("XML");
+#endif
+
+void
+ruby_init_xml_sax_parser(void) {
+ cXMLSaxParser = rb_define_class_under(mXML, "SaxParser", rb_cObject);
+ callsym = rb_intern("call");
+
+ rb_define_singleton_method(cXMLSaxParser, "new", ruby_xml_sax_parser_new, 0);
+
+ rb_define_method(cXMLSaxParser, "filename",
+ ruby_xml_sax_parser_filename_get, 0);
+ rb_define_method(cXMLSaxParser, "filename=",
+ ruby_xml_sax_parser_filename_set, 1);
+ rb_define_method(cXMLSaxParser, "parse", ruby_xml_sax_parser_parse, 0);
+ rb_define_method(cXMLSaxParser, "string", ruby_xml_sax_parser_str_get, 0);
+ rb_define_method(cXMLSaxParser, "string=", ruby_xml_sax_parser_str_set, 1);
+
+ rb_define_method(cXMLSaxParser, "on_internal_subset",
+ ruby_xml_sax_parser_on_internal_subset, -1);
+ rb_define_method(cXMLSaxParser, "on_is_standalone",
+ ruby_xml_sax_parser_on_is_standalone, -1);
+ rb_define_method(cXMLSaxParser, "on_has_internal_subset",
+ ruby_xml_sax_parser_on_has_internal_subset, -1);
+ rb_define_method(cXMLSaxParser, "on_has_external_subset",
+ ruby_xml_sax_parser_on_has_external_subset, -1);
+ rb_define_method(cXMLSaxParser, "on_start_document",
+ ruby_xml_sax_parser_on_start_document, -1);
+ rb_define_method(cXMLSaxParser, "on_end_document",
+ ruby_xml_sax_parser_on_end_document, -1);
+ rb_define_method(cXMLSaxParser, "on_start_element",
+ ruby_xml_sax_parser_on_start_element, -1);
+ rb_define_method(cXMLSaxParser, "on_end_element",
+ ruby_xml_sax_parser_on_end_element, -1);
+ rb_define_method(cXMLSaxParser, "on_reference",
+ ruby_xml_sax_parser_on_reference, -1);
+ rb_define_method(cXMLSaxParser, "on_characters",
+ ruby_xml_sax_parser_on_characters, -1);
+ rb_define_method(cXMLSaxParser, "on_processing_instruction",
+ ruby_xml_sax_parser_on_processing_instruction, -1);
+ rb_define_method(cXMLSaxParser, "on_comment",
+ ruby_xml_sax_parser_on_comment, -1);
+ rb_define_method(cXMLSaxParser, "on_parser_warning",
+ ruby_xml_sax_parser_on_parser_warning, -1);
+ rb_define_method(cXMLSaxParser, "on_parser_error",
+ ruby_xml_sax_parser_on_parser_error, -1);
+ rb_define_method(cXMLSaxParser, "on_parser_fatal_error",
+ ruby_xml_sax_parser_on_parser_fatal_error, -1);
+ rb_define_method(cXMLSaxParser, "on_cdata_block",
+ ruby_xml_sax_parser_on_cdata_block, -1);
+ rb_define_method(cXMLSaxParser, "on_external_subset",
+ ruby_xml_sax_parser_on_external_subset, -1);
+}
Added: packages-wip/libxml-ruby/trunk/ruby_xml_sax_parser.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_sax_parser.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_sax_parser.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,52 @@
+/* $Id: ruby_xml_sax_parser.h,v 1.2 2006/04/14 14:45:52 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RUBY_XML_SAX_PARSER__
+#define __RUBY_XML_SAX_PARSER__
+
+extern VALUE cXMLSaxParser;
+
+typedef struct ruby_xml_sax_parser_callbacks {
+ VALUE internalSubset;
+ VALUE isStandalone;
+ VALUE hasInternalSubset;
+ VALUE hasExternalSubset;
+ VALUE resolveEntity;
+ VALUE getEntity;
+ VALUE entityDecl;
+ VALUE notationDecl;
+ VALUE attributeDecl;
+ VALUE elementDecl;
+ VALUE unparsedEntityDecl;
+ VALUE setDocumentLocator;
+ VALUE startDocument;
+ VALUE endDocument;
+ VALUE startElement;
+ VALUE endElement;
+ VALUE reference;
+ VALUE characters;
+ VALUE ignorableWhitespace;
+ VALUE processingInstruction;
+ VALUE comment;
+ VALUE xmlParserWarning;
+ VALUE xmlParserError;
+ VALUE xmlParserFatalError;
+ VALUE getParameterEntity;
+ VALUE cdataBlock;
+ VALUE externalSubset;
+} ruby_xml_sax_parser_callbacks;
+
+typedef struct ruby_xml_sax_parser {
+ xmlParserCtxtPtr xpc;
+ xmlSAXHandlerPtr xsh;
+ ruby_xml_sax_parser_callbacks *cbp;
+ VALUE filename;
+ VALUE str;
+} ruby_xml_sax_parser;
+
+void ruby_xml_sax_parser_free(ruby_xml_sax_parser *rxsp);
+void ruby_init_xml_sax_parser(void);
+VALUE ruby_xml_sax_parser_new(VALUE class);
+
+#endif
Added: packages-wip/libxml-ruby/trunk/ruby_xml_schema.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_schema.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_schema.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,142 @@
+#include "libxml.h"
+#include "ruby_xml_schema.h"
+
+VALUE cXMLSchema;
+
+static void
+ruby_xml_schema_mark(ruby_xml_schema *rxschema) {
+ return;
+}
+
+void
+ruby_xml_schema_free(ruby_xml_schema *rxschema) {
+ if (rxschema->schema != NULL) {
+ xmlSchemaFree(rxschema->schema);
+ rxschema->schema = NULL;
+ }
+
+ free(rxschema);
+}
+
+/*
+ * call-seq:
+ * XML::Schema.new(schema_uri) => schema
+ *
+ * Create a new schema from the specified URI.
+ */
+VALUE
+ruby_xml_schema_init_from_uri(int argc, VALUE *argv, VALUE class) {
+ VALUE uri;
+ xmlSchemaParserCtxtPtr parser;
+ xmlSchemaPtr sptr;
+
+ switch (argc) {
+ case 1:
+ rb_scan_args(argc, argv, "10", &uri);
+
+ Check_Type(uri, T_STRING);
+
+ parser = xmlSchemaNewParserCtxt(StringValuePtr(uri));
+ sptr = xmlSchemaParse(parser);
+ xmlSchemaFreeParserCtxt(parser);
+ break;
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (need 1)");
+ }
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * XML::Schema.from_string("schema_data") => "value"
+ *
+ * Create a new schema using the specified string.
+ */
+VALUE
+ruby_xml_schema_init_from_str(int argc, VALUE *argv, VALUE class) {
+ VALUE schema_str;
+
+ xmlSchemaParserCtxtPtr parser;
+ //xmlSchemaPtr sptr;
+ ruby_xml_schema *rxschema;
+
+ switch (argc) {
+ case 1:
+ rb_scan_args(argc, argv, "10", &schema_str);
+
+ Check_Type(schema_str, T_STRING);
+
+ parser = xmlSchemaNewMemParserCtxt(StringValuePtr(schema_str), strlen(StringValuePtr(schema_str)));
+ rxschema = ALLOC(ruby_xml_schema);
+ rxschema->schema = xmlSchemaParse(parser);
+ xmlSchemaFreeParserCtxt(parser);
+
+ return( Data_Wrap_Struct(cXMLSchema, ruby_xml_schema_mark, ruby_xml_schema_free, rxschema) );
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (need 1)");
+ }
+ return Qnil;
+}
+
+/* TODO what is this patch doing here?
+
+ xmlSchemaParserCtxtPtr parser;
+ xmlSchemaPtr sptr;
+ xmlSchemaValidCtxtPtr vptr;
++ int is_invalid;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &source) == FAILURE) {
+ return;
+@@ -598,26 +598,24 @@
+ convert_to_string_ex(&source);
+ parser = xmlSchemaNewParserCtxt(Z_STRVAL_P(source));
+ sptr = xmlSchemaParse(parser);
+ break;
+ case SCHEMA_BLOB:
+ convert_to_string_ex(&source);
+ parser = xmlSchemaNewMemParserCtxt(Z_STRVAL_P(source), Z_STRLEN_P(source));
+ sptr = xmlSchemaParse(parser);
+ break;
+ }
+
+ vptr = xmlSchemaNewValidCtxt(sptr);
++ is_invalid = xmlSchemaValidateDoc(vptr, (xmlDocPtr) sxe->document->ptr);
+ xmlSchemaFree(sptr);
+ xmlSchemaFreeValidCtxt(vptr);
+ xmlSchemaFreeParserCtxt(parser);
+
+- if (is_valid) {
+- RETURN_TRUE;
+- } else {
++ if (is_invalid) {
+ RETURN_FALSE;
++ } else {
++ RETURN_TRUE;
+ }
+ }
+ }}}
+@@ -695,7 +693,7 @@
+ {
+ if (!strcmp(method, "xsearch")) {
+ simplexml_ce_xpath_search(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+-#ifdef xmlSchemaParserCtxtPtr
++#ifdef LIBXML_SCHEMAS_ENABLED
+ } else if (!strcmp(method, "validate_schema_file")) {
+ simplexml_ce_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, SCHEMA_FILE);
+ } else if (!strcmp(method, "validate_schema_buffer")) {
+*/
+
+void ruby_schema_free(ruby_xml_schema *rxs) {
+}
+
+// Rdoc needs to know
+#ifdef RDOC_NEVER_DEFINED
+ mXML = rb_define_module("XML");
+#endif
+
+void ruby_init_xml_schema(void) {
+ cXMLSchema = rb_define_class_under(mXML, "Schema", rb_cObject);
+ rb_define_singleton_method(cXMLSchema, "new", ruby_xml_schema_init_from_uri, -1);
+ rb_define_singleton_method(cXMLSchema, "from_string", ruby_xml_schema_init_from_str, -1);
+}
+
Added: packages-wip/libxml-ruby/trunk/ruby_xml_schema.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_schema.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_schema.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,16 @@
+#ifndef __RUBY_XML_SCHEMA__
+#define __RUBY_XML_SCHEMA__
+
+#include <libxml/schemasInternals.h>
+#include <libxml/xmlschemas.h>
+
+extern VALUE cXMLSchema;
+
+typedef struct rxp_schema {
+ xmlSchemaPtr schema; /* Schema interface */
+} ruby_xml_schema;
+
+void ruby_init_xml_schema(void);
+void ruby_schema_free(ruby_xml_schema *rxs);
+#endif
+
Added: packages-wip/libxml-ruby/trunk/ruby_xml_tree.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_tree.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_tree.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,43 @@
+/* $Id: ruby_xml_tree.c,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#include "libxml.h"
+#include "ruby_xml_tree.h"
+
+VALUE cXMLTree;
+
+// Rdoc needs to know
+#ifdef RDOC_NEVER_DEFINED
+ mXML = rb_define_module("XML");
+#endif
+
+void
+ruby_init_xml_tree(void) {
+ cXMLTree = rb_define_class_under(mXML, "Tree", rb_cObject);
+
+ rb_define_const(cXMLTree, "ELEMENT_NODE", INT2FIX(XML_ELEMENT_NODE));
+ rb_define_const(cXMLTree, "ATTRIBUTE_NODE", INT2FIX(XML_ATTRIBUTE_NODE));
+ rb_define_const(cXMLTree, "TEXT_NODE", INT2FIX(XML_TEXT_NODE));
+ rb_define_const(cXMLTree, "CDATA_SECTION_NODE", INT2FIX(XML_CDATA_SECTION_NODE));
+ rb_define_const(cXMLTree, "ENTITY_REF_NODE", INT2FIX(XML_ENTITY_REF_NODE));
+ rb_define_const(cXMLTree, "ENTITY_NODE", INT2FIX(XML_ENTITY_NODE));
+ rb_define_const(cXMLTree, "PI_NODE", INT2FIX(XML_PI_NODE));
+ rb_define_const(cXMLTree, "COMMENT_NODE", INT2FIX(XML_COMMENT_NODE));
+ rb_define_const(cXMLTree, "DOCUMENT_NODE", INT2FIX(XML_DOCUMENT_NODE));
+ rb_define_const(cXMLTree, "DOCUMENT_TYPE_NODE", INT2FIX(XML_DOCUMENT_TYPE_NODE));
+ rb_define_const(cXMLTree, "DOCUMENT_FRAG_NODE", INT2FIX(XML_DOCUMENT_FRAG_NODE));
+ rb_define_const(cXMLTree, "NOTATION_NODE", INT2FIX(XML_NOTATION_NODE));
+ rb_define_const(cXMLTree, "HTML_DOCUMENT_NODE", INT2FIX(XML_HTML_DOCUMENT_NODE));
+ rb_define_const(cXMLTree, "DTD_NODE", INT2FIX(XML_DTD_NODE));
+ rb_define_const(cXMLTree, "ELEMENT_DECL", INT2FIX(XML_ELEMENT_DECL));
+ rb_define_const(cXMLTree, "ATTRIBUTE_DECL", INT2FIX(XML_ATTRIBUTE_DECL));
+ rb_define_const(cXMLTree, "ENTITY_DECL", INT2FIX(XML_ENTITY_DECL));
+ rb_define_const(cXMLTree, "NAMESPACE_DECL", INT2FIX(XML_NAMESPACE_DECL));
+ rb_define_const(cXMLTree, "XINCLUDE_START", INT2FIX(XML_XINCLUDE_START));
+ rb_define_const(cXMLTree, "XINCLUDE_END", INT2FIX(XML_XINCLUDE_END));
+
+#ifdef LIBXML_DOCB_ENABLED
+ rb_define_const(cXMLTree, "DOCB_DOCUMENT_NODE", INT2FIX(XML_DOCB_DOCUMENT_NODE));
+#endif
+}
Added: packages-wip/libxml-ruby/trunk/ruby_xml_tree.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_tree.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_tree.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,12 @@
+/* $Id: ruby_xml_tree.h,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RUBY_XML_TREE__
+#define __RUBY_XML_TREE__
+
+extern VALUE cXMLTree;
+
+void ruby_init_xml_tree(void);
+
+#endif
Added: packages-wip/libxml-ruby/trunk/ruby_xml_xinclude.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_xinclude.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_xinclude.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,20 @@
+/* $Id: ruby_xml_xinclude.c,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#include "libxml.h"
+#include "ruby_xml_xinclude.h"
+
+VALUE cXMLXInclude;
+VALUE eXMLXIncludeError;
+
+// Rdoc needs to know
+#ifdef RDOC_NEVER_DEFINED
+ mXML = rb_define_module("XML");
+#endif
+
+void
+ruby_init_xml_xinclude(void) {
+ cXMLXInclude = rb_define_class_under(mXML, "XInclude", rb_cObject);
+ eXMLXIncludeError = rb_define_class_under(cXMLXInclude, "Error", rb_eRuntimeError);
+}
Added: packages-wip/libxml-ruby/trunk/ruby_xml_xinclude.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_xinclude.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_xinclude.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,13 @@
+/* $Id: ruby_xml_xinclude.h,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RUBY_XML_XINCLUDE__
+#define __RUBY_XML_XINCLUDE__
+
+extern VALUE cXMLXInclude;
+extern VALUE eXMLXIncludeError;
+
+void ruby_init_xml_xinclude(void);
+
+#endif
Added: packages-wip/libxml-ruby/trunk/ruby_xml_xpath.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_xpath.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_xpath.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,363 @@
+/* $Id: ruby_xml_xpath.c,v 1.2 2006/04/14 14:45:25 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#include "libxml.h"
+#include "ruby_xml_xpath.h"
+
+/*
+ * Document-class: XML::XPath
+ *
+ * Includes Enumerable.
+ */
+VALUE cXMLXPath;
+VALUE eXMLXPathInvalidPath;
+
+#ifdef LIBXML_XPATH_ENABLED
+
+/*
+ * call-seq:
+ * xpath.debug => (true|false)
+ *
+ * Dump libxml debugging information to stdout.
+ * Requires Libxml be compiled with debugging enabled.
+ */
+VALUE
+ruby_xml_xpath_debug(VALUE self) {
+#ifdef LIBXML_DEBUG_ENABLED
+ ruby_xml_xpath *rxxp;
+ Data_Get_Struct(self, ruby_xml_xpath, rxxp);
+
+ if (rxxp->xpop != NULL) {
+ xmlXPathDebugDumpObject(stdout, rxxp->xpop, 0);
+ return(Qtrue);
+ } else {
+ return(Qfalse);
+ }
+#else
+ rb_warn("libxml does not have debugging turned on");
+ return(Qfalse);
+#endif
+}
+
+// TODO Maybe we should support [] or some other kind of access if poss.
+
+/*
+ * call-seq:
+ * xpath.each { |node| ... } => self
+ *
+ * Call the supplied block for each matching node.
+ */
+VALUE
+ruby_xml_xpath_each(VALUE self) {
+ ruby_xml_xpath *rxxp;
+ VALUE rxnset;
+
+ Data_Get_Struct(self, ruby_xml_xpath, rxxp);
+
+ if (rxxp->xpop == NULL || rxxp->xpop->type != XPATH_NODESET)
+ return(Qnil);
+
+ rxnset = ruby_xml_node_set_new(cXMLNodeSet, rxxp->xd, self,
+ rxxp->xpop->nodesetval);
+ ruby_xml_node_set_each(rxnset);
+ return(rxnset);
+}
+
+///////////////////////////////////////////////////
+// TODO xpath_find is throwing TypeError:
+//
+// TypeError: can't convert nil into String
+//
+// When given a namespace when non exist.
+
+/*
+ * call-seq:
+ * XML::XPath.find(path, namespaces = [any]) => xpath
+ *
+ * Find nodes matching the specified xpath (and optionally any of the
+ * supplied namespaces) and return as an XML::Node::Set.
+ *
+ * The optional namespaces argument may take one of
+ * two forms:
+ *
+ * * A string in the form of: "prefix:uri", or
+ * * An array of:
+ * * strings in the form like above
+ * * arrays in the form of ['prefix','uri']
+ *
+ * If not specified, matching nodes from any namespace
+ * will be included.
+ */
+VALUE
+ruby_xml_xpath_find(int argc, VALUE *argv, VALUE class) {
+#ifdef LIBXML_XPATH_ENABLED
+ xmlXPathCompExprPtr comp;
+ ruby_xml_node *node;
+ ruby_xml_xpath *rxxp;
+ ruby_xml_xpath_context *rxxpc;
+ ruby_xml_ns *rxns;
+ VALUE rnode, rprefix, ruri, xxpc, xpath, xpath_expr;
+ char *cp;
+ long i;
+
+ switch(argc) {
+ case 3:
+ /* array of namespaces we allow.
+ *
+ * Accept either:
+ * A string in the form of: "prefix:uri", or
+ * An array of:
+ * *) strings in the form like above
+ * *) arrays in the form of ['prefix','uri']
+ */
+
+ /* Intentionally fall through, we deal with the last arg below
+ * after the XPathContext object has been setup */
+ case 2:
+ rnode = argv[0];
+ xpath_expr = argv[1];
+ break;
+ default:
+ rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
+ }
+
+ Data_Get_Struct(rnode, ruby_xml_node, node);
+
+ xxpc = ruby_xml_xpath_context_new4(rnode);
+ if (NIL_P(xxpc))
+ return(Qnil);
+ Data_Get_Struct(xxpc, ruby_xml_xpath_context, rxxpc);
+
+ xpath = ruby_xml_xpath_new(cXMLXPath, rnode, xxpc, NULL);
+ Data_Get_Struct(xpath, ruby_xml_xpath, rxxp);
+
+ rxxpc->ctxt->node = node->node;
+ if (node->node->type == XML_DOCUMENT_NODE) {
+ rxxpc->ctxt->namespaces = xmlGetNsList(node->node->doc,
+ xmlDocGetRootElement(node->node->doc));
+ } else {
+ rxxpc->ctxt->namespaces = xmlGetNsList(node->node->doc, node->node);
+ }
+
+ rxxpc->ctxt->nsNr = 0;
+ if (rxxpc->ctxt->namespaces != NULL) {
+ while (rxxpc->ctxt->namespaces[rxxpc->ctxt->nsNr] != NULL)
+ rxxpc->ctxt->nsNr++;
+ }
+
+ /* Need to loop through the 2nd argument and iterate through the
+ * list of namespaces that we want to allow */
+ if (argc == 3) {
+ switch (TYPE(argv[2])) {
+ case T_STRING:
+ cp = strchr(StringValuePtr(argv[2]), (int)':');
+ if (cp == NULL) {
+ rprefix = argv[2];
+ ruri = Qnil;
+ } else {
+ rprefix = rb_str_new(StringValuePtr(argv[2]), (int)((long)cp - (long)StringValuePtr(argv[2])));
+ ruri = rb_str_new2(&cp[1]);
+ }
+ /* Should test the results of this */
+ ruby_xml_xpath_context_register_namespace(xxpc, rprefix, ruri);
+ break;
+ case T_ARRAY:
+ for (i = 0; i < RARRAY(argv[2])->len; i++) {
+ switch (TYPE(RARRAY(argv[2])->ptr[i])) {
+ case T_STRING:
+ cp = strchr(StringValuePtr(RARRAY(argv[2])->ptr[i]), (int)':');
+ if (cp == NULL) {
+ rprefix = RARRAY(argv[2])->ptr[i];
+ ruri = Qnil;
+ } else {
+ rprefix = rb_str_new(StringValuePtr(RARRAY(argv[2])->ptr[i]), (int)((long)cp - (long)StringValuePtr(RARRAY(argv[2])->ptr[i])));
+ ruri = rb_str_new2(&cp[1]);
+ }
+ /* Should test the results of this */
+ ruby_xml_xpath_context_register_namespace(xxpc, rprefix, ruri);
+ break;
+ case T_ARRAY:
+ if (RARRAY(RARRAY(argv[2])->ptr[i])->len == 2) {
+ rprefix = RARRAY(RARRAY(argv[2])->ptr[i])->ptr[0];
+ ruri = RARRAY(RARRAY(argv[2])->ptr[i])->ptr[1];
+ ruby_xml_xpath_context_register_namespace(xxpc, rprefix, ruri);
+ } else {
+ rb_raise(rb_eArgError, "nested array must be an array of strings, prefix and href/uri");
+ }
+ break;
+ default:
+ if (rb_obj_is_kind_of(RARRAY(argv[2])->ptr[i], cXMLNS) == Qtrue) {
+ Data_Get_Struct(argv[2], ruby_xml_ns, rxns);
+ rprefix = rb_str_new2((const char*)rxns->ns->prefix);
+ ruri = rb_str_new2((const char*)rxns->ns->href);
+ ruby_xml_xpath_context_register_namespace(xxpc, rprefix, ruri);
+ } else
+ rb_raise(rb_eArgError, "Invalid argument type, only accept string, array of strings, or an array of arrays");
+ }
+ }
+ break;
+ default:
+ if (rb_obj_is_kind_of(argv[2], cXMLNS) == Qtrue) {
+ Data_Get_Struct(argv[2], ruby_xml_ns, rxns);
+ rprefix = rb_str_new2((const char*)rxns->ns->prefix);
+ ruri = rb_str_new2((const char*)rxns->ns->href);
+ ruby_xml_xpath_context_register_namespace(xxpc, rprefix, ruri);
+ } else
+ rb_raise(rb_eArgError, "Invalid argument type, only accept string, array of strings, or an array of arrays");
+ }
+ }
+ comp = xmlXPathCompile((xmlChar*)StringValuePtr(xpath_expr));
+
+ if (comp == NULL) {
+ xmlXPathFreeCompExpr(comp);
+ rb_raise(eXMLXPathInvalidPath, "Invalid XPath expression");
+ }
+ rxxp->xpop = xmlXPathCompiledEval(comp, rxxpc->ctxt);
+ xmlXPathFreeCompExpr(comp);
+
+ if (rxxpc->ctxt->namespaces != NULL)
+ xmlFree(rxxpc->ctxt->namespaces);
+
+ if (rxxp->xpop == NULL)
+ rb_raise(eXMLXPathInvalidPath,
+ "Invalid XPath expression for this document");
+
+ if (rxxp->xpop->type != XPATH_NODESET)
+ return(Qnil);
+
+ return(ruby_xml_node_set_new2(node->xd, xpath,
+ rxxp->xpop->nodesetval));
+#else
+ rb_warn("libxml was compiled without XPath support");
+ return(Qfalse);
+#endif
+}
+
+
+VALUE
+ruby_xml_xpath_find2(int argc, VALUE *argv) {
+ return(ruby_xml_xpath_find(argc, argv, cXMLXPath));
+}
+
+
+void
+ruby_xml_xpath_free(ruby_xml_xpath *rxxp) {
+ if (rxxp->xpop != NULL) {
+ xmlXPathFreeObject(rxxp->xpop);
+ rxxp->xpop = NULL;
+ }
+
+ free(rxxp);
+}
+
+
+void
+ruby_xml_xpath_mark(ruby_xml_xpath *rxxp) {
+ if (rxxp == NULL) return;
+ if (!NIL_P(rxxp->ctxt)) rb_gc_mark(rxxp->ctxt);
+ if (!NIL_P(rxxp->xd)) rb_gc_mark(rxxp->xd);
+}
+
+
+VALUE
+ruby_xml_xpath_new(VALUE class, VALUE xd, VALUE ctxt,
+ xmlXPathObjectPtr xpop) {
+ ruby_xml_xpath *rxxp;
+
+ rxxp = ALLOC(ruby_xml_xpath);
+ rxxp->ctxt = ctxt;
+ rxxp->xd = xd;
+ rxxp->xpop = xpop;
+ return(Data_Wrap_Struct(class, ruby_xml_xpath_mark,
+ ruby_xml_xpath_free, rxxp));
+}
+
+
+/*
+ * call-seq:
+ * xpath.set => nodeset
+ *
+ * Obtain an XML::Node::Set with nodes matching this xpath.
+ */
+VALUE
+ruby_xml_xpath_set(VALUE self) {
+ ruby_xml_xpath *rxxp;
+ Data_Get_Struct(self, ruby_xml_xpath, rxxp);
+
+ if (rxxp->xpop == NULL || rxxp->xpop->type != XPATH_NODESET)
+ return(Qnil);
+
+ return(ruby_xml_node_set_new(cXMLNodeSet, rxxp->xd, self,
+ rxxp->xpop->nodesetval));
+}
+
+
+/*
+ * call-seq:
+ * xpath.set_type => num
+ *
+ * Obtains the type identifier of this xpath
+ * set.
+ */
+VALUE
+ruby_xml_xpath_set_type(VALUE self) {
+ ruby_xml_xpath *rxxp;
+ Data_Get_Struct(self, ruby_xml_xpath, rxxp);
+
+ return(INT2FIX(rxxp->xpop->type));
+}
+
+// TODO maybe 'string' should alias as 'to_s'?
+
+/*
+ * call-seq:
+ * xpath.string => "xpath"
+ *
+ * Obtain a string representation of this xpath.
+ */
+VALUE
+ruby_xml_xpath_string(VALUE self) {
+ ruby_xml_xpath *rxxp;
+ Data_Get_Struct(self, ruby_xml_xpath, rxxp);
+
+ if (rxxp->xpop->stringval == NULL)
+ return(Qnil);
+ else
+ return(rb_str_new2((const char*)rxxp->xpop->stringval));
+}
+
+// Rdoc needs to know
+#ifdef RDOC_NEVER_DEFINED
+ mXML = rb_define_module("XML");
+#endif
+
+void
+ruby_init_xml_xpath(void) {
+ cXMLXPath = rb_define_class_under(mXML, "XPath", rb_cObject);
+ rb_include_module(cXMLNode, rb_const_get(rb_cObject, rb_intern("Enumerable")));
+
+ eXMLXPathInvalidPath = rb_define_class_under(cXMLXPath,
+ "InvalidPath", rb_eException);
+
+ rb_define_const(cXMLXPath, "UNDEFINED", INT2NUM(XPATH_UNDEFINED));
+ rb_define_const(cXMLXPath, "NODESET", INT2NUM(XPATH_NODESET));
+ rb_define_const(cXMLXPath, "BOOLEAN", INT2NUM(XPATH_BOOLEAN));
+ rb_define_const(cXMLXPath, "NUMBER", INT2NUM(XPATH_NUMBER));
+ rb_define_const(cXMLXPath, "STRING", INT2NUM(XPATH_STRING));
+ rb_define_const(cXMLXPath, "POINT", INT2NUM(XPATH_POINT));
+ rb_define_const(cXMLXPath, "RANGE", INT2NUM(XPATH_RANGE));
+ rb_define_const(cXMLXPath, "LOCATIONSET", INT2NUM(XPATH_LOCATIONSET));
+ rb_define_const(cXMLXPath, "USERS", INT2NUM(XPATH_USERS));
+ rb_define_const(cXMLXPath, "XSLT_TREE", INT2NUM(XPATH_XSLT_TREE));
+
+ rb_define_singleton_method(cXMLXPath, "find", ruby_xml_xpath_find, 2);
+
+ rb_define_method(cXMLXPath, "debug", ruby_xml_xpath_debug, 0);
+ rb_define_method(cXMLXPath, "each", ruby_xml_xpath_each, 0);
+ rb_define_method(cXMLXPath, "set", ruby_xml_xpath_set, 0);
+ rb_define_method(cXMLXPath, "set_type", ruby_xml_xpath_set_type, 0);
+ rb_define_method(cXMLXPath, "string", ruby_xml_xpath_string, 0);
+}
+
+#endif /* ifdef LIBXML_XPATH_ENABLED */
Added: packages-wip/libxml-ruby/trunk/ruby_xml_xpath.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_xpath.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_xpath.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,24 @@
+/* $Id: ruby_xml_xpath.h,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RUBY_XML_XPATH__
+#define __RUBY_XML_XPATH__
+
+extern VALUE cXMLXPath;
+extern VALUE eXMLXPathInvalidPath;
+
+typedef struct ruby_xml_xpath {
+ VALUE xd;
+ VALUE ctxt;
+ xmlXPathObjectPtr xpop;
+} ruby_xml_xpath;
+
+void ruby_xml_xpath_free(ruby_xml_xpath *rxxp);
+VALUE ruby_xml_xpath_find(int argc, VALUE *argv, VALUE class);
+VALUE ruby_xml_xpath_find2(int argc, VALUE *argv);
+VALUE ruby_xml_xpath_new(VALUE class, VALUE xd, VALUE xxpc,
+ xmlXPathObjectPtr xpop);
+void ruby_init_xml_xpath(void);
+
+#endif
Added: packages-wip/libxml-ruby/trunk/ruby_xml_xpath_context.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_xpath_context.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_xpath_context.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,125 @@
+/* $Id: ruby_xml_xpath_context.c,v 1.2 2006/02/27 12:55:32 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#include "libxml.h"
+#include "ruby_xml_xpath_context.h"
+
+VALUE cXMLXPathContext;
+
+/*
+ * call-seq:
+ * context.doc => document
+ *
+ * Obtain the XML::Document associated with this XPath.
+ */
+VALUE
+ruby_xml_xpath_context_doc_get(VALUE self) {
+ ruby_xml_xpath_context *rxxpc;
+ Data_Get_Struct(self, ruby_xml_xpath_context, rxxpc);
+
+ return(rxxpc->xd);
+}
+
+
+void
+ruby_xml_xpath_context_free(ruby_xml_xpath_context *rxxpc) {
+ if (rxxpc->ctxt != NULL) {
+ xmlXPathFreeContext(rxxpc->ctxt);
+ rxxpc->ctxt = NULL;
+ }
+
+ free(rxxpc);
+}
+
+
+void
+ruby_xml_xpath_context_mark(ruby_xml_xpath_context *rxxpc) {
+ if (rxxpc == NULL) return;
+ if (!NIL_P(rxxpc->xd)) rb_gc_mark(rxxpc->xd);
+}
+
+
+VALUE
+ruby_xml_xpath_context_new(VALUE class, VALUE xd,
+ xmlXPathContextPtr xxpc) {
+ ruby_xml_xpath_context *rxxpc;
+
+ rxxpc = ALLOC(ruby_xml_xpath_context);
+ rxxpc->ctxt = xxpc;
+ rxxpc->xd = xd;
+ return(Data_Wrap_Struct(class, ruby_xml_xpath_context_mark,
+ ruby_xml_xpath_context_free, rxxpc));
+}
+
+
+VALUE
+ruby_xml_xpath_context_new2(VALUE xd, xmlXPathContextPtr xxpc) {
+ return(ruby_xml_xpath_context_new(cXMLXPathContext, xd, xxpc));
+}
+
+
+VALUE
+ruby_xml_xpath_context_new3(VALUE xd) {
+ ruby_xml_document *rxd;
+ xmlXPathContextPtr ctxt;
+
+ Data_Get_Struct(xd, ruby_xml_document, rxd);
+ if (rxd->doc == NULL)
+ return(Qnil);
+
+ ctxt = xmlXPathNewContext(rxd->doc);
+ if (ctxt == NULL)
+ return(Qnil);
+
+ return(ruby_xml_xpath_context_new2(xd, ctxt));
+}
+
+
+VALUE
+ruby_xml_xpath_context_new4(VALUE rnode) {
+ ruby_xml_node *node;
+
+ Data_Get_Struct(rnode, ruby_xml_node, node);
+ return(ruby_xml_xpath_context_new3(node->xd));
+}
+
+
+/*
+ * call-seq:
+ * context.register_namespace(prefix, uri) => (true|false)
+ *
+ * Register the specified namespace URI with the specified prefix
+ * in this context.
+ */
+VALUE
+ruby_xml_xpath_context_register_namespace(VALUE self, VALUE prefix, VALUE uri) {
+ ruby_xml_xpath_context *rxxpc;
+
+ Data_Get_Struct(self, ruby_xml_xpath_context, rxxpc);
+ if (xmlXPathRegisterNs(rxxpc->ctxt,
+ (xmlChar*)StringValuePtr(prefix),
+ (xmlChar*)StringValuePtr(uri))
+ == 0) {
+ return(Qtrue);
+ } else {
+ /* Should raise an exception, IMHO */
+ return(Qfalse);
+ }
+}
+
+// Rdoc needs to know
+#ifdef RDOC_NEVER_DEFINED
+ mXML = rb_define_module("XML");
+ cXMLXPath = rb_define_class_under(mXML, "XPath", rb_cObject);
+#endif
+
+void
+ruby_init_xml_xpath_context(void) {
+ cXMLXPathContext = rb_define_class_under(cXMLXPath, "Context", rb_cObject);
+
+ rb_define_method(cXMLXPathContext, "register_namespace",
+ ruby_xml_xpath_context_register_namespace, 2);
+ rb_define_method(cXMLXPathContext, "doc",
+ ruby_xml_xpath_context_doc_get, 0);
+}
Added: packages-wip/libxml-ruby/trunk/ruby_xml_xpath_context.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_xpath_context.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_xpath_context.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,24 @@
+/* $Id: ruby_xml_xpath_context.h,v 1.2 2006/02/27 12:55:32 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RUBY_XML_XPATH_CONTEXT__
+#define __RUBY_XML_XPATH_CONTEXT__
+
+extern VALUE cXMLXPathContext;
+
+typedef struct ruby_xml_xpath_context {
+ VALUE xd;
+ xmlXPathContextPtr ctxt;
+} ruby_xml_xpath_context;
+
+void ruby_xml_xpath_context_free(ruby_xml_xpath_context *rxxpc);
+VALUE ruby_xml_xpath_context_new(VALUE class, VALUE xd,
+ xmlXPathContextPtr ctxt);
+VALUE ruby_xml_xpath_context_new2(VALUE xd, xmlXPathContextPtr ctxt);
+VALUE ruby_xml_xpath_context_new3(VALUE xd);
+VALUE ruby_xml_xpath_context_new4(VALUE rnode);
+VALUE ruby_xml_xpath_context_register_namespace(VALUE self, VALUE prefix, VALUE uri);
+void ruby_init_xml_xpath_context(void);
+
+#endif
Added: packages-wip/libxml-ruby/trunk/ruby_xml_xpointer.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_xpointer.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_xpointer.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,100 @@
+/* $Id: ruby_xml_xpointer.c,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#include "libxml.h"
+#include "ruby_xml_xpointer.h"
+
+VALUE cXMLXPointer;
+VALUE eXMLXPointerInvalidExpression;
+
+VALUE
+ruby_xml_xpointer_point(VALUE class, VALUE rnode, VALUE xptr_str) {
+#ifdef LIBXML_XPTR_ENABLED
+ ruby_xml_node *node;
+ ruby_xml_xpath_context *xxpc;
+ VALUE rxptr_xpth_ctxt, rxxp;
+ xmlXPathObjectPtr xpath;
+
+ Check_Type(xptr_str, T_STRING);
+ if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
+ rb_raise(rb_eTypeError, "require an XML::Node object");
+
+ Data_Get_Struct(rnode, ruby_xml_node, node);
+
+ rxptr_xpth_ctxt = ruby_xml_xpath_context_new(cXMLXPathContext, node->xd,
+ xmlXPtrNewContext(node->node->doc, node->node, NULL));
+ if (NIL_P(rxptr_xpth_ctxt))
+ return(Qnil);
+ Data_Get_Struct(rxptr_xpth_ctxt, ruby_xml_xpath_context, xxpc);
+
+ xpath = xmlXPtrEval((xmlChar*)StringValuePtr(xptr_str), xxpc->ctxt);
+ if (xpath == NULL)
+ rb_raise(eXMLXPointerInvalidExpression, "invalid xpointer expression");
+
+ rxxp = ruby_xml_xpath_new(cXMLXPath, node->xd, rxptr_xpth_ctxt, xpath);
+ return(rxxp);
+#else
+ rb_warn("libxml was compiled without XPointer support");
+ return(Qfalse);
+#endif
+}
+
+
+VALUE
+ruby_xml_xpointer_point2(VALUE node, VALUE xptr_str) {
+ return(ruby_xml_xpointer_point(cXMLXPointer, node, xptr_str));
+}
+
+
+/*
+ * call-seq:
+ * XML::XPointer.range(start_node, end_node) => xpath
+ *
+ * Create an xpath representing the range between the supplied
+ * start and end node.
+ */
+VALUE
+ruby_xml_xpointer_range(VALUE class, VALUE rstart, VALUE rend) {
+#ifdef LIBXML_XPTR_ENABLED
+ ruby_xml_node *start, *end;
+ VALUE rxxp;
+ xmlXPathObjectPtr xpath;
+
+ if (rb_obj_is_kind_of(rstart, cXMLNode) == Qfalse)
+ rb_raise(rb_eTypeError, "require an XML::Node object as a starting point");
+ if (rb_obj_is_kind_of(rend, cXMLNode) == Qfalse)
+ rb_raise(rb_eTypeError, "require an XML::Node object as an ending point");
+
+ Data_Get_Struct(rstart, ruby_xml_node, start);
+ if (start->node == NULL)
+ return(Qnil);
+
+ Data_Get_Struct(rend, ruby_xml_node, end);
+ if (end->node == NULL)
+ return(Qnil);
+
+ xpath = xmlXPtrNewRangeNodes(start->node, end->node);
+ if (xpath == NULL)
+ rb_fatal("You shouldn't be able to have this happen");
+
+ rxxp = ruby_xml_xpath_new(cXMLXPath, start->xd, Qnil, xpath);
+ return(rxxp);
+#else
+ rb_warn("libxml was compiled without XPointer support");
+ return(Qfalse);
+#endif
+}
+
+// Rdoc needs to know
+#ifdef RDOC_NEVER_DEFINED
+ mXML = rb_define_module("XML");
+#endif
+
+void
+ruby_init_xml_xpointer(void) {
+ cXMLXPointer = rb_define_class_under(mXML, "XPointer", rb_cObject);
+ eXMLXPointerInvalidExpression = rb_define_class_under(cXMLXPointer, "InvalidExpression", rb_eException);
+
+ rb_define_singleton_method(cXMLXPointer, "range", ruby_xml_xpointer_range, 2);
+}
Added: packages-wip/libxml-ruby/trunk/ruby_xml_xpointer.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_xpointer.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_xpointer.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,27 @@
+/* $Id: ruby_xml_xpointer.h,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RUBY_XML_XPOINTER__
+#define __RUBY_XML_XPOINTER__
+
+extern VALUE cXMLXPointer;
+extern VALUE eXMLXPointerInvalidExpression;
+
+typedef struct ruby_xml_xpointer {
+ VALUE xd;
+ VALUE ctxt;
+ /*
+ * This needs to go into a xpointer data struct:
+ *
+ * xmlLocationSetPtr xptr;
+ *
+ * I also need an xpointer data struct type.
+ */
+} ruby_xml_xpointer;
+
+VALUE ruby_xml_xpointer_point(VALUE class, VALUE node, VALUE xptr_string);
+VALUE ruby_xml_xpointer_point2(VALUE node, VALUE xptr_string);
+void ruby_init_xml_xpointer(void);
+
+#endif
Added: packages-wip/libxml-ruby/trunk/ruby_xml_xpointer_context.c
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_xpointer_context.c 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_xpointer_context.c 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,21 @@
+/* $Id: ruby_xml_xpointer_context.c,v 1.2 2006/02/27 12:55:32 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#include "libxml.h"
+#include "ruby_xml_xpointer_context.h"
+
+VALUE cXMLXPointerContext;
+VALUE eXMLXPointerContextInvalidPath;
+
+// Rdoc needs to know
+#ifdef RDOC_NEVER_DEFINED
+ mXML = rb_define_module("XML");
+ cXMLXPointer = rb_define_class_under(mXML, "XPointer", rb_cObject);
+#endif
+
+void
+ruby_init_xml_xpointer_context(void) {
+ cXMLXPointerContext = rb_define_class_under(cXMLXPointer, "Context", cXMLXPathContext);
+ eXMLXPointerContextInvalidPath = rb_define_class_under(cXMLXPointerContext, "InvalidPath", rb_eException);
+}
Added: packages-wip/libxml-ruby/trunk/ruby_xml_xpointer_context.h
===================================================================
--- packages-wip/libxml-ruby/trunk/ruby_xml_xpointer_context.h 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/ruby_xml_xpointer_context.h 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,18 @@
+/* $Id: ruby_xml_xpointer_context.h,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+#ifndef __RUBY_XML_XPOINTER_CONTEXT__
+#define __RUBY_XML_XPOINTER_CONTEXT__
+
+extern VALUE cXMLXPointerContext;
+extern VALUE eXMLXPointerContextInvalidPath;
+
+typedef struct ruby_xml_xpointer_context {
+ VALUE xd;
+ xmlXPathContextPtr ctxt;
+} ruby_xml_xpointer_context;
+
+void ruby_init_xml_xpointer_context(void);
+
+#endif
Added: packages-wip/libxml-ruby/trunk/sax_parser_callbacks.inc
===================================================================
--- packages-wip/libxml-ruby/trunk/sax_parser_callbacks.inc 2006-11-03 21:03:21 UTC (rev 963)
+++ packages-wip/libxml-ruby/trunk/sax_parser_callbacks.inc 2006-11-03 21:04:08 UTC (rev 964)
@@ -0,0 +1,202 @@
+/* $Id: sax_parser_callbacks.inc,v 1.1 2006/04/14 14:50:58 roscopeco Exp $ */
+
+/* Please see the LICENSE file for copyright and distribution information */
+
+/*
+ * SAX CALLBACK HANDLERS
+ */
+static void internal_subset_func(ruby_xml_sax_parser_callbacks *cbp,
+ const char *name,
+ const char *extid,
+ const char *sysid) {
+ VALUE handler = cbp->internalSubset;
+
+ if (handler && handler != Qnil) {
+ rb_funcall(handler, callsym, 3, rb_str_new2(name),
+ rb_str_new2(extid), rb_str_new2(sysid));
+ }
+}
+
+static void is_standalone_func(ruby_xml_sax_parser_callbacks *cbp) {
+ VALUE handler = cbp->isStandalone;
+
+ if (handler && handler != Qnil) {
+ rb_funcall(handler,callsym,0);
+ }
+}
+
+static void has_internal_subset_func(ruby_xml_sax_parser_callbacks *cbp) {
+ VALUE handler = cbp->hasInternalSubset;
+
+ if (handler && handler != Qnil) {
+ rb_funcall(handler,callsym,0);
+ }
+}
+
+static void has_external_subset_func(ruby_xml_sax_parser_callbacks *cbp) {
+ VALUE handler = cbp->hasExternalSubset;
+
+ if (handler && handler != Qnil) {
+ rb_funcall(handler,callsym,0);
+ }
+}
+
+static void start_document_func(ruby_xml_sax_parser_callbacks *cbp) {
+ VALUE handler = cbp->startDocument;
+
+ if (handler && handler != Qnil) {
+ rb_funcall(handler,callsym,0);
+ }
+}
+
+static void end_document_func(ruby_xml_sax_parser_callbacks *cbp) {
+ VALUE handler = cbp->endDocument;
+
+ if (handler && handler != Qnil) {
+ rb_funcall(handler,callsym,0);
+ }
+}
+
+static void start_element_func(ruby_xml_sax_parser_callbacks *cbp,
+ const char *name, const char **attrs) {
+ VALUE handler = cbp->startElement;
+ VALUE ahsh = rb_hash_new();
+ const char *attr, *value;
+
+ if (attrs) {
+ while ((attr = *(attrs++))) {
+ value = *(attrs++);
+ rb_hash_aset(ahsh, rb_str_new2(attr), rb_str_new2(value));
+ }
+ }
+
+ if (handler && handler != Qnil) {
+ rb_funcall(handler,callsym,2,rb_str_new2(name),ahsh);
+ }
+}
+
+static void end_element_func(ruby_xml_sax_parser_callbacks *cbp,
+ const char *name) {
+ VALUE handler = cbp->endElement;
+
+ if (handler && handler != Qnil) {
+ rb_funcall(handler,callsym,1,rb_str_new2(name));
+ }
+}
+
+static void reference_func(ruby_xml_sax_parser_callbacks *cbp,
+ const char *name) {
+ VALUE handler = cbp->reference;
+
+ if (handler && handler != Qnil) {
+ rb_funcall(handler,callsym,1,rb_str_new2(name));
+ }
+}
+
+static void characters_func(ruby_xml_sax_parser_callbacks *cbp,
+ const char *chars, int len) {
+ VALUE handler = cbp->characters;
+
+ if (handler && handler != Qnil) {
+ rb_funcall(handler,callsym,1,rb_str_new(chars, len));
+ }
+}
+
+static void processing_instruction_func(ruby_xml_sax_parser_callbacks *cbp,
+ const char *target, const char *data) {
+ VALUE handler = cbp->processingInstruction;
+
+ if (handler && handler != Qnil) {
+ rb_funcall(handler, callsym, 2,
+ rb_str_new2(target),rb_str_new2(data));
+ }
+}
+
+static void comment_func(ruby_xml_sax_parser_callbacks *cbp,
+ const char *msg) {
+ VALUE handler = cbp->comment;
+
+ if (handler && handler != Qnil) {
+ rb_funcall(handler,callsym,1,rb_str_new2(msg));
+ }
+}
+
+// TODO these next three should actually be formatting messages.
+static void warning_func(ruby_xml_sax_parser_callbacks *cbp,
+ const char *msg, ...) {
+ VALUE handler = cbp->xmlParserWarning;
+
+ if (handler && handler != Qnil) {
+ rb_funcall(handler,callsym,1,rb_str_new2(msg));
+ }
+}
+
+static void error_func(ruby_xml_sax_parser_callbacks *cbp,
+ const char *msg, ...) {
+ VALUE handler = cbp->xmlParserError;
+
+ if (handler && handler != Qnil) {
+ rb_funcall(handler,callsym,1,rb_str_new2(msg));
+ }
+}
+
+static void fatal_error_func(ruby_xml_sax_parser_callbacks *cbp,
+ const char *msg, ...) {
+ VALUE handler = cbp->xmlParserFatalError;
+
+ if (handler && handler != Qnil) {
+ rb_funcall(handler,callsym,1,rb_str_new2(msg));
+ }
+}
+
+static void cdata_block_func(ruby_xml_sax_parser_callbacks *cbp,
+ const char *value, int len) {
+ VALUE handler = cbp->cdataBlock;
+
+ if (handler && handler != Qnil) {
+ rb_funcall(handler,callsym,1,rb_str_new(value, len));
+ }
+}
+
+static void external_subset_func(ruby_xml_sax_parser_callbacks *cbp,
+ const char *name,
+ const char *extid,
+ const char *sysid) {
+ VALUE handler = cbp->externalSubset;
+
+ if (handler && handler != Qnil) {
+ rb_funcall(handler, callsym, 3, rb_str_new2(name),
+ rb_str_new2(extid), rb_str_new2(sysid));
+ }
+}
+
+static xmlSAXHandler rubySAXHandlerStruct = {
+ (internalSubsetSAXFunc)internal_subset_func,
+ (isStandaloneSAXFunc)is_standalone_func,
+ (hasInternalSubsetSAXFunc)has_internal_subset_func,
+ (hasExternalSubsetSAXFunc)has_external_subset_func,
+ 0, /* resolveEntity */
+ 0, /* getEntity */
+ 0, /* entityDecl */
+ 0, /* notationDecl */
+ 0, /* attributeDecl */
+ 0, /* elementDecl */
+ 0, /* unparsedEntityDecl */
+ 0, /* setDocumentLocator */
+ (startDocumentSAXFunc)start_document_func,
+ (endDocumentSAXFunc)end_document_func,
+ (startElementSAXFunc)start_element_func,
+ (endElementSAXFunc)end_element_func,
+ (referenceSAXFunc)reference_func,
+ (charactersSAXFunc)characters_func,
+ 0, /* ignorableWhitespace */
+ (processingInstructionSAXFunc)processing_instruction_func,
+ (commentSAXFunc)comment_func,
+ (warningSAXFunc)warning_func,
+ (errorSAXFunc)error_func,
+ (fatalErrorSAXFunc)fatal_error_func,
+ 0, /* xmlGetParameterEntity */
+ (cdataBlockSAXFunc)cdata_block_func,
+ (externalSubsetSAXFunc)external_subset_func,
+ 1
+};
More information about the pkg-ruby-extras-maintainers
mailing list