[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 whet