summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--acinclude.m452
-rw-r--r--build/build.mk2
-rw-r--r--bundle/expat/Changes99
-rw-r--r--bundle/expat/README72
-rw-r--r--bundle/expat/README.php11
-rw-r--r--bundle/expat/ascii.h85
-rw-r--r--bundle/expat/asciitab.h36
-rw-r--r--bundle/expat/config.m443
-rw-r--r--bundle/expat/expat.h910
-rw-r--r--bundle/expat/iasciitab.h37
-rw-r--r--bundle/expat/internal.h46
-rw-r--r--bundle/expat/latin1tab.h36
-rw-r--r--bundle/expat/nametab.h150
-rw-r--r--bundle/expat/utf8tab.h37
-rw-r--r--bundle/expat/winconfig.h30
-rw-r--r--bundle/expat/xmlparse.c5592
-rw-r--r--bundle/expat/xmlrole.c1330
-rw-r--r--bundle/expat/xmlrole.h114
-rw-r--r--bundle/expat/xmltok.c1641
-rw-r--r--bundle/expat/xmltok.h312
-rw-r--r--bundle/expat/xmltok_impl.c1778
-rw-r--r--bundle/expat/xmltok_impl.h46
-rw-r--r--bundle/expat/xmltok_ns.c106
-rw-r--r--bundle/libxml/DOCBparser.c6107
-rw-r--r--bundle/libxml/HTMLparser.c5013
-rw-r--r--bundle/libxml/HTMLtree.c1099
-rw-r--r--bundle/libxml/SAX.c2015
-rw-r--r--bundle/libxml/c14n.c1930
-rw-r--r--bundle/libxml/catalog.c3502
-rw-r--r--bundle/libxml/config.m480
-rw-r--r--bundle/libxml/debugXML.c2480
-rw-r--r--bundle/libxml/encoding.c2340
-rw-r--r--bundle/libxml/entities.c1006
-rw-r--r--bundle/libxml/error.c420
-rw-r--r--bundle/libxml/globals.c653
-rw-r--r--bundle/libxml/hash.c822
-rw-r--r--bundle/libxml/include/libxml/DOCBparser.h73
-rw-r--r--bundle/libxml/include/libxml/HTMLparser.h117
-rw-r--r--bundle/libxml/include/libxml/HTMLtree.h117
-rw-r--r--bundle/libxml/include/libxml/Makefile.am46
-rw-r--r--bundle/libxml/include/libxml/Makefile.in335
-rw-r--r--bundle/libxml/include/libxml/SAX.h128
-rw-r--r--bundle/libxml/include/libxml/c14n.h91
-rw-r--r--bundle/libxml/include/libxml/catalog.h138
-rw-r--r--bundle/libxml/include/libxml/debugXML.h163
-rw-r--r--bundle/libxml/include/libxml/encoding.h230
-rw-r--r--bundle/libxml/include/libxml/entities.h109
-rw-r--r--bundle/libxml/include/libxml/globals.h336
-rw-r--r--bundle/libxml/include/libxml/hash.h166
-rw-r--r--bundle/libxml/include/libxml/list.h116
-rw-r--r--bundle/libxml/include/libxml/nanoftp.h117
-rw-r--r--bundle/libxml/include/libxml/nanohttp.h56
-rw-r--r--bundle/libxml/include/libxml/parser.h869
-rw-r--r--bundle/libxml/include/libxml/parserInternals.h413
-rw-r--r--bundle/libxml/include/libxml/schemasInternals.h353
-rw-r--r--bundle/libxml/include/libxml/threads.h62
-rw-r--r--bundle/libxml/include/libxml/tree.h894
-rw-r--r--bundle/libxml/include/libxml/uri.h67
-rw-r--r--bundle/libxml/include/libxml/valid.h319
-rw-r--r--bundle/libxml/include/libxml/xinclude.h26
-rw-r--r--bundle/libxml/include/libxml/xlink.h180
-rw-r--r--bundle/libxml/include/libxml/xmlIO.h283
-rw-r--r--bundle/libxml/include/libxml/xmlautomata.h94
-rw-r--r--bundle/libxml/include/libxml/xmlerror.h184
-rw-r--r--bundle/libxml/include/libxml/xmlmemory.h169
-rw-r--r--bundle/libxml/include/libxml/xmlreader.h56
-rw-r--r--bundle/libxml/include/libxml/xmlregexp.h81
-rw-r--r--bundle/libxml/include/libxml/xmlschemas.h106
-rw-r--r--bundle/libxml/include/libxml/xmlschemastypes.h42
-rw-r--r--bundle/libxml/include/libxml/xmlunicode.h164
-rw-r--r--bundle/libxml/include/libxml/xmlversion.h272
-rw-r--r--bundle/libxml/include/libxml/xmlversion.h.in272
-rw-r--r--bundle/libxml/include/libxml/xpath.h410
-rw-r--r--bundle/libxml/include/libxml/xpathInternals.h580
-rw-r--r--bundle/libxml/include/libxml/xpointer.h83
-rw-r--r--bundle/libxml/include/win32config.h111
-rw-r--r--bundle/libxml/include/wsockcompat.h61
-rw-r--r--bundle/libxml/libxml.h28
-rw-r--r--bundle/libxml/list.c720
-rw-r--r--bundle/libxml/nanoftp.c1924
-rw-r--r--bundle/libxml/nanohttp.c1528
-rw-r--r--bundle/libxml/parser.c10912
-rw-r--r--bundle/libxml/parserInternals.c3481
-rw-r--r--bundle/libxml/stamp-h.in1
-rw-r--r--bundle/libxml/threads.c537
-rw-r--r--bundle/libxml/tree.c7566
-rw-r--r--bundle/libxml/trio.c6760
-rw-r--r--bundle/libxml/trio.h216
-rw-r--r--bundle/libxml/triodef.h182
-rw-r--r--bundle/libxml/trionan.c913
-rw-r--r--bundle/libxml/trionan.h81
-rw-r--r--bundle/libxml/triop.h150
-rw-r--r--bundle/libxml/triostr.c2024
-rw-r--r--bundle/libxml/triostr.h127
-rw-r--r--bundle/libxml/uri.c1962
-rw-r--r--bundle/libxml/valid.c5968
-rw-r--r--bundle/libxml/xinclude.c1729
-rw-r--r--bundle/libxml/xlink.c179
-rw-r--r--bundle/libxml/xmlIO.c2839
-rw-r--r--bundle/libxml/xmlmemory.c777
-rw-r--r--bundle/libxml/xmlreader.c882
-rw-r--r--bundle/libxml/xmlregexp.c4319
-rw-r--r--bundle/libxml/xmlschemas.c5468
-rw-r--r--bundle/libxml/xmlschemastypes.c1880
-rw-r--r--bundle/libxml/xmlunicode.c4290
-rw-r--r--bundle/libxml/xpath.c10990
-rw-r--r--bundle/libxml/xpointer.c2902
-rw-r--r--configure.in8
-rw-r--r--ext/domxml/config.m472
-rw-r--r--ext/xml/config.m455
-rw-r--r--ext/xmlrpc/config.m46
111 files changed, 120 insertions, 129877 deletions
diff --git a/acinclude.m4 b/acinclude.m4
index 64669c57c9..d3b7760f81 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -578,23 +578,6 @@ AC_ARG_ENABLE($1,[$3],$5=[$]enableval,
PHP_ARG_ANALYZE($5,[$2],$6)
])
-AC_DEFUN([PHP_ARG_BUNDLE],[
-PHP_REAL_ARG_BUNDLE([$1],[$2],[$3],[$4],PHP_[]translit($1,a-z-,A-Z_),[ifelse($5,,yes,$5)])
-])
-
-AC_DEFUN([PHP_REAL_ARG_BUNDLE],[
-ifelse([$2],,,[AC_MSG_CHECKING([$2])])
-AC_ARG_WITH($1,[$3],$5=[$]withval,
-[
- $5=ifelse($4,,no,$4)
-
- if test "$PHP_BUNDLE_ALL" && test "$6" = "yes"; then
- $5=$PHP_BUNDLE_ALL
- fi
-])
-PHP_ARG_ANALYZE($5,[$2],$6)
-])
-
AC_DEFUN([PHP_MODULE_PTR],[
EXTRA_MODULE_PTRS="$EXTRA_MODULE_PTRS $1,"
])
@@ -1717,6 +1700,41 @@ ifelse([$3],[],,[else $3])
fi
])
+dnl
+dnl PHP_SETUP_LIBXML(shared-add [, action-found [, action-not-found]])
+dnl
+dnl Common setup macro for libxml
+dnl
+AC_DEFUN([PHP_SETUP_LIBXML], [
+
+ for i in $PHP_LIBXML_DIR /usr/local /usr; do
+ if test -x "$i/bin/xml2-config"; then
+ XML2_CONFIG="$i/bin/xml2-config"
+ break
+ fi
+ done
+
+ if test -x "$XML2_CONFIG"; then
+ libxml_full_version=`$XML2_CONFIG --version`
+ ac_IFS=$IFS
+ IFS="."
+ set $libxml_full_version
+ IFS=$ac_IFS
+ LIBXML_VERSION=`expr [$]1 \* 1000000 + [$]2 \* 1000 + [$]3`
+ if test "$LIBXML_VERSION" -ge "2004014"; then
+ LIBXML_LIBS=`$XML2_CONFIG --libs`
+ LIBXML_INCS=`$XML2_CONFIG --cflags`
+ PHP_EVAL_LIBLINE($LIBXML_LIBS, $shared_lib_add)
+ PHP_EVAL_INCLINE($LIBXML_INCS)
+ AC_DEFINE(HAVE_LIBXML, 1, [ ])
+ $2
+ else
+ AC_MSG_ERROR([libxml2 version 2.4.14 or greater required.])
+ fi
+ifelse([$3],[],,[else $3])
+ fi
+])
+
AC_DEFUN([PHP_DEF_HAVE],[AC_DEFINE([HAVE_]translit($1,a-z_-,A-Z__), 1, [ ])])
dnl
diff --git a/build/build.mk b/build/build.mk
index d9bb151857..85080c675c 100644
--- a/build/build.mk
+++ b/build/build.mk
@@ -36,7 +36,7 @@ generated_lists:
@echo makefile_am_files = $(ZENDDIR)/Makefile.am \
TSRM/Makefile.am > $@
@echo config_h_files = $(ZENDDIR)/acconfig.h TSRM/acconfig.h >> $@
- @echo config_m4_files = $(ZENDDIR)/Zend.m4 TSRM/tsrm.m4 TSRM/threads.m4 bundle/*/config*.m4 \
+ @echo config_m4_files = $(ZENDDIR)/Zend.m4 TSRM/tsrm.m4 TSRM/threads.m4 \
$(ZENDDIR)/acinclude.m4 ext/*/config*.m4 sapi/*/config.m4 >> $@
$(STAMP): build/buildcheck.sh
diff --git a/bundle/expat/Changes b/bundle/expat/Changes
deleted file mode 100644
index 1df159b652..0000000000
--- a/bundle/expat/Changes
+++ /dev/null
@@ -1,99 +0,0 @@
-Release 1.95.5 Fri Sep 6 2002
- - Added XML_UseForeignDTD() for improved SAX2 support.
- - Added XML_GetFeatureList().
- - Defined XML_Bool type and the values XML_TRUE and XML_FALSE.
- - Use an incomplete struct instead of a void* for the parser
- (may not retain).
- - Fixed UTF-8 decoding bug that caused legal UTF-8 to be rejected.
- - Finally fixed bug where default handler would report DTD
- events that were already handled by another handler.
- Initial patch contributed by Darryl Miller.
- - Removed unnecessary DllMain() function that caused static
- linking into a DLL to be difficult.
- - Added VC++ projects for building static libraries.
- - Reduced line-length for all source code and headers to be
- no longer than 80 characters, to help with AS/400 support.
- - Reduced memory copying during parsing (SF patch #600964).
- - Fixed a variety of bugs: see SF issues 580793, 434664,
- 483514, 580503, 581069, 584041, 584183, 584832, 585537,
- 596555, 596678, 598352, 598944, 599715, 600479, 600971.
-
-Release 1.95.4 Fri Jul 12 2002
- - Added support for VMS, contributed by Craig Berry. See
- vms/README.vms for more information.
- - Added Mac OS (classic) support, with a makefile for MPW,
- contributed by Thomas Wegner and Daryle Walker.
- - Added Borland C++ Builder 5 / BCC 5.5 support, contributed
- by Patrick McConnell (SF patch #538032).
- - Fixed a variety of bugs: see SF issues 441449, 563184,
- 564342, 566334, 566901, 569461, 570263, 575168, 579196.
- - Made skippedEntityHandler conform to SAX2 (see source comment)
- - Re-implemented WFC: Entity Declared from XML 1.0 spec and
- added a new error "entity declared in parameter entity":
- see SF bug report 569461 and SF patch 578161
- - Re-implemented section 5.1 from XML 1.0 spec:
- see SF bug report 570263 and SF patch 578161
-
-Release 1.95.3 Mon Jun 3 2002
- - Added a project to the MSVC workspace to create a wchar_t
- version of the library; the DLLs are named libexpatw.dll.
- - Changed the name of the Windows DLLs from expat.dll to
- libexpat.dll; this fixes SF bug #432456.
- - Added the XML_ParserReset() API function.
- - Fixed XML_SetReturnNSTriplet() to work for element names.
- - Made the XML_UNICODE builds usable (thanks, Karl!).
- - Allow xmlwf to read from standard input.
- - Install a man page for xmlwf on Unix systems.
- - Fixed many bugs; see SF bug reports 231864, 461380, 464837,
- 466885, 469226, 477667, 484419, 487840, 494749, 496505,
- 547350. Other bugs which we can't test as easily may also
- have been fixed, especially in the area of build support.
-
-Release 1.95.2 Fri Jul 27 2001
- - More changes to make MSVC happy with the build; add a single
- workspace to support both the library and xmlwf application.
- - Added a Windows installer for Windows users; includes
- xmlwf.exe.
- - Added compile-time constants that can be used to determine the
- Expat version
- - Removed a lot of GNU-specific dependencies to aide portability
- among the various Unix flavors.
- - Fix the UTF-8 BOM bug.
- - Cleaned up warning messages for several compilers.
- - Added the -Wall, -Wstrict-prototypes options for GCC.
-
-Release 1.95.1 Sun Oct 22 15:11:36 EDT 2000
- - Changes to get expat to build under Microsoft compiler
- - Removed all aborts and instead return an UNEXPECTED_STATE error.
- - Fixed a bug where a stray '%' in an entity value would cause an
- abort.
- - Defined XML_SetEndNamespaceDeclHandler. Thanks to Darryl Miles for
- finding this oversight.
- - Changed default patterns in lib/Makefile.in to fit non-GNU makes
- Thanks to robin@unrated.net for reporting and providing an
- account to test on.
- - The reference had the wrong label for XML_SetStartNamespaceDecl.
- Reported by an anonymous user.
-
-Release 1.95.0 Fri Sep 29 2000
- - XML_ParserCreate_MM
- Allows you to set a memory management suite to replace the
- standard malloc,realloc, and free.
- - XML_SetReturnNSTriplet
- If you turn this feature on when namespace processing is in
- effect, then qualified, prefixed element and attribute names
- are returned as "uri|name|prefix" where '|' is whatever
- separator character is used in namespace processing.
- - Merged in features from perl-expat
- o XML_SetElementDeclHandler
- o XML_SetAttlistDeclHandler
- o XML_SetXmlDeclHandler
- o XML_SetEntityDeclHandler
- o StartDoctypeDeclHandler takes 3 additional parameters:
- sysid, pubid, has_internal_subset
- o Many paired handler setters (like XML_SetElementHandler)
- now have corresponding individual handler setters
- o XML_GetInputContext for getting the input context of
- the current parse position.
- - Added reference material
- - Packaged into a distribution that builds a sharable library
diff --git a/bundle/expat/README b/bundle/expat/README
deleted file mode 100644
index 15bcdccb50..0000000000
--- a/bundle/expat/README
+++ /dev/null
@@ -1,72 +0,0 @@
-
- Expat, Release 1.95.2
-
-This is expat, a C library for parsing XML, written by James Clark.
-Expat is a stream-oriented XML parser. This means that you register
-handlers with the parser before starting the parse. These handlers
-are called when the parser discovers the associated structures in the
-document being parsed. A start tag is an example of the kind of
-structures for which you may register handlers.
-
-Windows users should use the expat_win32bin package, which includes
-both precompiled libraries and executalbes, and source code for
-developers.
-
-Expat is free software. You may copy, distribute, and modify it under
-the terms of the License contained in the file COPYING distributed
-with this package. This license is the same as the MIT/X Consortium
-license.
-
-Versions of expat that have an odd minor version (the middle number in
-the release above), are development releases and should be considered
-as beta software. Releases with even minor version numbers are
-intended to be production grade software.
-
-To build expat, you first run the configuration shell script in the
-top level distribution directory:
-
- ./configure
-
-There are many options which you may provide to configure (which you
-can discover by running configure with the --help option). But the
-one of most interest is the one that sets the installation directory.
-By default, the configure script will set things up to install
-libexpat into /usr/local/lib, expat.h into /usr/local/include, and
-xmlwf into /usr/local/bin. If, for example, you'd prefer to install
-into /home/me/mystuff/lib, /home/me/mystuff/include, and
-/home/me/mystuff/bin, you can tell configure about that with:
-
- ./configure --prefix=/home/me/mystuff
-
-After running the configure script, the "make" command will build
-things and "make install" will install things into their proper
-location. Note that you need to have write permission into the
-directories into which things will be installed.
-
-When building for use with C++, you may need to add additional
-compiler flags to support proper interaction with exceptions. This
-can be done by setting the CFLAGS environment variable. For example,
-when using GCC, you can use:
-
- CFLAGS=-fexceptions ./configure
-
-Note for Solaris users: The "ar" command is usually located in
-"/usr/ccs/bin", which is not in the default PATH. You will need to
-add this to your path for the "make" command, and probably also switch
-to GNU make (the "make" found in /usr/ccs/bin does not seem to work
-properly -- appearantly it does not understand .PHONY directives). If
-you're using ksh or bash, use this command to build:
-
- PATH=/usr/ccs/bin:$PATH make
-
-A reference manual is available in the file doc/reference.html in this
-distribution.
-
-The homepage for this project is http://expat.sourceforge.net/. There
-are links there to connect you to the bug reports page. If you need
-to report a bug when you don't have access to a browser, you may also
-send a bug report by email to expat-bugs@lists.sourceforge.net.
-
-Discussion related to the direction of future expat development takes
-place on expat-discuss@lists.sourceforge.net. Archives of this list
-may be found at http://www.geocrawler.com/redir-sf.php3?list=expat-discuss.
diff --git a/bundle/expat/README.php b/bundle/expat/README.php
deleted file mode 100644
index 187ef60be8..0000000000
--- a/bundle/expat/README.php
+++ /dev/null
@@ -1,11 +0,0 @@
-this is the PHP-bundled version of expat 1.95.1
-
-changes from the original version:
-- include <php_config.h> instead of <config.h>
-- include "php_compat.h" for namespace protection
-- hardcode version in xmlparse.c
-- stripped off all unneded files
-
-
-thies@thieso.net, 11th May, 2001
-
diff --git a/bundle/expat/ascii.h b/bundle/expat/ascii.h
deleted file mode 100644
index 073e8a5fb6..0000000000
--- a/bundle/expat/ascii.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-#define ASCII_A 0x41
-#define ASCII_B 0x42
-#define ASCII_C 0x43
-#define ASCII_D 0x44
-#define ASCII_E 0x45
-#define ASCII_F 0x46
-#define ASCII_G 0x47
-#define ASCII_H 0x48
-#define ASCII_I 0x49
-#define ASCII_J 0x4A
-#define ASCII_K 0x4B
-#define ASCII_L 0x4C
-#define ASCII_M 0x4D
-#define ASCII_N 0x4E
-#define ASCII_O 0x4F
-#define ASCII_P 0x50
-#define ASCII_Q 0x51
-#define ASCII_R 0x52
-#define ASCII_S 0x53
-#define ASCII_T 0x54
-#define ASCII_U 0x55
-#define ASCII_V 0x56
-#define ASCII_W 0x57
-#define ASCII_X 0x58
-#define ASCII_Y 0x59
-#define ASCII_Z 0x5A
-
-#define ASCII_a 0x61
-#define ASCII_b 0x62
-#define ASCII_c 0x63
-#define ASCII_d 0x64
-#define ASCII_e 0x65
-#define ASCII_f 0x66
-#define ASCII_g 0x67
-#define ASCII_h 0x68
-#define ASCII_i 0x69
-#define ASCII_j 0x6A
-#define ASCII_k 0x6B
-#define ASCII_l 0x6C
-#define ASCII_m 0x6D
-#define ASCII_n 0x6E
-#define ASCII_o 0x6F
-#define ASCII_p 0x70
-#define ASCII_q 0x71
-#define ASCII_r 0x72
-#define ASCII_s 0x73
-#define ASCII_t 0x74
-#define ASCII_u 0x75
-#define ASCII_v 0x76
-#define ASCII_w 0x77
-#define ASCII_x 0x78
-#define ASCII_y 0x79
-#define ASCII_z 0x7A
-
-#define ASCII_0 0x30
-#define ASCII_1 0x31
-#define ASCII_2 0x32
-#define ASCII_3 0x33
-#define ASCII_4 0x34
-#define ASCII_5 0x35
-#define ASCII_6 0x36
-#define ASCII_7 0x37
-#define ASCII_8 0x38
-#define ASCII_9 0x39
-
-#define ASCII_TAB 0x09
-#define ASCII_SPACE 0x20
-#define ASCII_EXCL 0x21
-#define ASCII_QUOT 0x22
-#define ASCII_AMP 0x26
-#define ASCII_APOS 0x27
-#define ASCII_MINUS 0x2D
-#define ASCII_PERIOD 0x2E
-#define ASCII_COLON 0x3A
-#define ASCII_SEMI 0x3B
-#define ASCII_LT 0x3C
-#define ASCII_EQUALS 0x3D
-#define ASCII_GT 0x3E
-#define ASCII_LSQB 0x5B
-#define ASCII_RSQB 0x5D
-#define ASCII_UNDERSCORE 0x5F
diff --git a/bundle/expat/asciitab.h b/bundle/expat/asciitab.h
deleted file mode 100644
index 79a15c28ca..0000000000
--- a/bundle/expat/asciitab.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
-/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
-/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
-/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
-/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
-/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
-/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
-/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
-/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
-/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
-/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/bundle/expat/config.m4 b/bundle/expat/config.m4
deleted file mode 100644
index 89e12be2c6..0000000000
--- a/bundle/expat/config.m4
+++ /dev/null
@@ -1,43 +0,0 @@
-dnl
-dnl $Id$
-dnl
-
-PHP_ARG_BUNDLE(bundle-expat, Whether to bundle the expat library,
-[ --without-bundle-expat Disable the bundled expat library], yes)
-
-# BC ini option
-PHP_ARG_WITH(expat-dir, external libexpat install dir,
-[ --with-expat-dir=DIR XML: external libexpat install dir], no, no)
-
-if test "$PHP_BUNDLE_EXPAT" = "yes" && test "$PHP_EXPAT_DIR" = "no"; then
- AC_C_BIGENDIAN
- if test "$ac_cv_c_bigendian" = "yes"; then
- order=4321
- else
- order=1234
- fi
-
- AC_DEFINE(HAVE_LIBEXPAT_BUNDLED, 1, [ ])
- AC_DEFINE(HAVE_LIBEXPAT, 1, [ ])
- AC_DEFINE(BYTEORDER, $order, [ ])
- PHP_ADD_SOURCES(bundle/expat, xmlparse.c xmlrole.c xmltok.c)
- PHP_ADD_INCLUDE(bundle/expat)
- PHP_ADD_BUILD_DIR(bundle/expat)
-elif test "$PHP_BUNDLE_EXPAT" != "no" && test "$PHP_EXPAT_DIR" != "no"; then
- # Find external expat library
-
- for i in $PHP_BUNDLE_EXPAT $PHP_EXPAT_DIR; do
- if test -f $i/lib/libexpat.a -o -f $i/lib/libexpat.$SHLIB_SUFFIX_NAME; then
- EXPAT_DIR=$i
- fi
- done
-
- if test -z "$EXPAT_DIR"; then
- AC_MSG_ERROR(not found. Please reinstall the expat distribution.)
- fi
-
- AC_DEFINE(HAVE_LIBEXPAT, 1, [ ])
- PHP_ADD_INCLUDE($EXPAT_DIR/include)
- PHP_ADD_LIBRARY_WITH_PATH(expat, $EXPAT_DIR/lib, EXPAT_SHARED_LIBADD)
- PHP_SUBST(EXPAT_SHARED_LIBADD)
-fi
diff --git a/bundle/expat/expat.h b/bundle/expat/expat.h
deleted file mode 100644
index c137f61226..0000000000
--- a/bundle/expat/expat.h
+++ /dev/null
@@ -1,910 +0,0 @@
-/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-#ifndef XmlParse_INCLUDED
-#define XmlParse_INCLUDED 1
-
-#ifdef __VMS
-/* 0 1 2 3 0 1 2 3
- 1234567890123456789012345678901 1234567890123456789012345678901 */
-#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler
-#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler
-#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler
-#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg
-#endif
-
-#include <stdlib.h>
-#include "php_compat.h"
-
-#ifndef XMLPARSEAPI
-#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
-#ifdef PHP_EXPORTS
-#define XMLPARSEAPI(type) type __cdecl
-#else
-#define XMLPARSEAPI(type) __declspec(dllimport) type __cdecl
-#endif
-#else
-#define XMLPARSEAPI(type) type
-#endif
-#endif /* not defined XMLPARSEAPI */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef XML_UNICODE_WCHAR_T
-#define XML_UNICODE
-#endif
-
-struct XML_ParserStruct;
-typedef struct XML_ParserStruct *XML_Parser;
-
-#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
-#ifdef XML_UNICODE_WCHAR_T
-typedef wchar_t XML_Char;
-typedef wchar_t XML_LChar;
-#else
-typedef unsigned short XML_Char;
-typedef char XML_LChar;
-#endif /* XML_UNICODE_WCHAR_T */
-#else /* Information is UTF-8 encoded. */
-typedef char XML_Char;
-typedef char XML_LChar;
-#endif /* XML_UNICODE */
-
-/* Should this be defined using stdbool.h when C99 is available? */
-typedef unsigned char XML_Bool;
-#define XML_TRUE ((XML_Bool) 1)
-#define XML_FALSE ((XML_Bool) 0)
-
-enum XML_Error {
- XML_ERROR_NONE,
- XML_ERROR_NO_MEMORY,
- XML_ERROR_SYNTAX,
- XML_ERROR_NO_ELEMENTS,
- XML_ERROR_INVALID_TOKEN,
- XML_ERROR_UNCLOSED_TOKEN,
- XML_ERROR_PARTIAL_CHAR,
- XML_ERROR_TAG_MISMATCH,
- XML_ERROR_DUPLICATE_ATTRIBUTE,
- XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
- XML_ERROR_PARAM_ENTITY_REF,
- XML_ERROR_UNDEFINED_ENTITY,
- XML_ERROR_RECURSIVE_ENTITY_REF,
- XML_ERROR_ASYNC_ENTITY,
- XML_ERROR_BAD_CHAR_REF,
- XML_ERROR_BINARY_ENTITY_REF,
- XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
- XML_ERROR_MISPLACED_XML_PI,
- XML_ERROR_UNKNOWN_ENCODING,
- XML_ERROR_INCORRECT_ENCODING,
- XML_ERROR_UNCLOSED_CDATA_SECTION,
- XML_ERROR_EXTERNAL_ENTITY_HANDLING,
- XML_ERROR_NOT_STANDALONE,
- XML_ERROR_UNEXPECTED_STATE,
- XML_ERROR_ENTITY_DECLARED_IN_PE,
- XML_ERROR_FEATURE_REQUIRES_XML_DTD,
- XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING
-};
-
-enum XML_Content_Type {
- XML_CTYPE_EMPTY = 1,
- XML_CTYPE_ANY,
- XML_CTYPE_MIXED,
- XML_CTYPE_NAME,
- XML_CTYPE_CHOICE,
- XML_CTYPE_SEQ
-};
-
-enum XML_Content_Quant {
- XML_CQUANT_NONE,
- XML_CQUANT_OPT,
- XML_CQUANT_REP,
- XML_CQUANT_PLUS
-};
-
-/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be
- XML_CQUANT_NONE, and the other fields will be zero or NULL.
- If type == XML_CTYPE_MIXED, then quant will be NONE or REP and
- numchildren will contain number of elements that may be mixed in
- and children point to an array of XML_Content cells that will be
- all of XML_CTYPE_NAME type with no quantification.
-
- If type == XML_CTYPE_NAME, then the name points to the name, and
- the numchildren field will be zero and children will be NULL. The
- quant fields indicates any quantifiers placed on the name.
-
- CHOICE and SEQ will have name NULL, the number of children in
- numchildren and children will point, recursively, to an array
- of XML_Content cells.
-
- The EMPTY, ANY, and MIXED types will only occur at top level.
-*/
-
-typedef struct XML_cp XML_Content;
-
-struct XML_cp {
- enum XML_Content_Type type;
- enum XML_Content_Quant quant;
- XML_Char * name;
- unsigned int numchildren;
- XML_Content * children;
-};
-
-
-/* This is called for an element declaration. See above for
- description of the model argument. It's the caller's responsibility
- to free model when finished with it.
-*/
-typedef void (*XML_ElementDeclHandler) (void *userData,
- const XML_Char *name,
- XML_Content *model);
-
-XMLPARSEAPI(void)
-XML_SetElementDeclHandler(XML_Parser parser,
- XML_ElementDeclHandler eldecl);
-
-/* The Attlist declaration handler is called for *each* attribute. So
- a single Attlist declaration with multiple attributes declared will
- generate multiple calls to this handler. The "default" parameter
- may be NULL in the case of the "#IMPLIED" or "#REQUIRED"
- keyword. The "isrequired" parameter will be true and the default
- value will be NULL in the case of "#REQUIRED". If "isrequired" is
- true and default is non-NULL, then this is a "#FIXED" default.
-*/
-typedef void (*XML_AttlistDeclHandler) (void *userData,
- const XML_Char *elname,
- const XML_Char *attname,
- const XML_Char *att_type,
- const XML_Char *dflt,
- int isrequired);
-
-XMLPARSEAPI(void)
-XML_SetAttlistDeclHandler(XML_Parser parser,
- XML_AttlistDeclHandler attdecl);
-
-/* The XML declaration handler is called for *both* XML declarations
- and text declarations. The way to distinguish is that the version
- parameter will be NULL for text declarations. The encoding
- parameter may be NULL for XML declarations. The standalone
- parameter will be -1, 0, or 1 indicating respectively that there
- was no standalone parameter in the declaration, that it was given
- as no, or that it was given as yes.
-*/
-typedef void (*XML_XmlDeclHandler) (void *userData,
- const XML_Char *version,
- const XML_Char *encoding,
- int standalone);
-
-XMLPARSEAPI(void)
-XML_SetXmlDeclHandler(XML_Parser parser,
- XML_XmlDeclHandler xmldecl);
-
-
-typedef struct {
- void *(*malloc_fcn)(size_t size);
- void *(*realloc_fcn)(void *ptr, size_t size);
- void (*free_fcn)(void *ptr);
-} XML_Memory_Handling_Suite;
-
-/* Constructs a new parser; encoding is the encoding specified by the
- external protocol or NULL if there is none specified.
-*/
-XMLPARSEAPI(XML_Parser)
-XML_ParserCreate(const XML_Char *encoding);
-
-/* Constructs a new parser and namespace processor. Element type
- names and attribute names that belong to a namespace will be
- expanded; unprefixed attribute names are never expanded; unprefixed
- element type names are expanded only if there is a default
- namespace. The expanded name is the concatenation of the namespace
- URI, the namespace separator character, and the local part of the
- name. If the namespace separator is '\0' then the namespace URI
- and the local part will be concatenated without any separator.
- When a namespace is not declared, the name and prefix will be
- passed through without expansion.
-*/
-XMLPARSEAPI(XML_Parser)
-XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
-
-
-/* Constructs a new parser using the memory management suit referred to
- by memsuite. If memsuite is NULL, then use the standard library memory
- suite. If namespaceSeparator is non-NULL it creates a parser with
- namespace processing as described above. The character pointed at
- will serve as the namespace separator.
-
- All further memory operations used for the created parser will come from
- the given suite.
-*/
-XMLPARSEAPI(XML_Parser)
-XML_ParserCreate_MM(const XML_Char *encoding,
- const XML_Memory_Handling_Suite *memsuite,
- const XML_Char *namespaceSeparator);
-
-/* Prepare a parser object to be re-used. This is particularly
- valuable when memory allocation overhead is disproportionatly high,
- such as when a large number of small documnents need to be parsed.
- All handlers are cleared from the parser, except for the
- unknownEncodingHandler. The parser's external state is re-initialized
- except for the values of ns and ns_triplets.
-
- Added in Expat 1.95.3.
-*/
-XMLPARSEAPI(XML_Bool)
-XML_ParserReset(XML_Parser parser, const XML_Char *encoding);
-
-/* atts is array of name/value pairs, terminated by 0;
- names and values are 0 terminated.
-*/
-typedef void (*XML_StartElementHandler)(void *userData,
- const XML_Char *name,
- const XML_Char **atts);
-
-typedef void (*XML_EndElementHandler)(void *userData,
- const XML_Char *name);
-
-
-/* s is not 0 terminated. */
-typedef void (*XML_CharacterDataHandler)(void *userData,
- const XML_Char *s,
- int len);
-
-/* target and data are 0 terminated */
-typedef void (*XML_ProcessingInstructionHandler)(void *userData,
- const XML_Char *target,
- const XML_Char *data);
-
-/* data is 0 terminated */
-typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data);
-
-typedef void (*XML_StartCdataSectionHandler)(void *userData);
-typedef void (*XML_EndCdataSectionHandler)(void *userData);
-
-/* This is called for any characters in the XML document for which
- there is no applicable handler. This includes both characters that
- are part of markup which is of a kind that is not reported
- (comments, markup declarations), or characters that are part of a
- construct which could be reported but for which no handler has been
- supplied. The characters are passed exactly as they were in the XML
- document except that they will be encoded in UTF-8 or UTF-16.
- Line boundaries are not normalized. Note that a byte order mark
- character is not passed to the default handler. There are no
- guarantees about how characters are divided between calls to the
- default handler: for example, a comment might be split between
- multiple calls.
-*/
-typedef void (*XML_DefaultHandler)(void *userData,
- const XML_Char *s,
- int len);
-
-/* This is called for the start of the DOCTYPE declaration, before
- any DTD or internal subset is parsed.
-*/
-typedef void (*XML_StartDoctypeDeclHandler)(void *userData,
- const XML_Char *doctypeName,
- const XML_Char *sysid,
- const XML_Char *pubid,
- int has_internal_subset);
-
-/* This is called for the start of the DOCTYPE declaration when the
- closing > is encountered, but after processing any external
- subset.
-*/
-typedef void (*XML_EndDoctypeDeclHandler)(void *userData);
-
-/* This is called for entity declarations. The is_parameter_entity
- argument will be non-zero if the entity is a parameter entity, zero
- otherwise.
-
- For internal entities (<!ENTITY foo "bar">), value will
- be non-NULL and systemId, publicID, and notationName will be NULL.
- The value string is NOT nul-terminated; the length is provided in
- the value_length argument. Since it is legal to have zero-length
- values, do not use this argument to test for internal entities.
-
- For external entities, value will be NULL and systemId will be
- non-NULL. The publicId argument will be NULL unless a public
- identifier was provided. The notationName argument will have a
- non-NULL value only for unparsed entity declarations.
-
- Note that is_parameter_entity can't be changed to XML_Bool, since
- that would break binary compatibility.
-*/
-typedef void (*XML_EntityDeclHandler) (void *userData,
- const XML_Char *entityName,
- int is_parameter_entity,
- const XML_Char *value,
- int value_length,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId,
- const XML_Char *notationName);
-
-XMLPARSEAPI(void)
-XML_SetEntityDeclHandler(XML_Parser parser,
- XML_EntityDeclHandler handler);
-
-/* OBSOLETE -- OBSOLETE -- OBSOLETE
- This handler has been superceded by the EntityDeclHandler above.
- It is provided here for backward compatibility.
-
- This is called for a declaration of an unparsed (NDATA) entity.
- The base argument is whatever was set by XML_SetBase. The
- entityName, systemId and notationName arguments will never be
- NULL. The other arguments may be.
-*/
-typedef void (*XML_UnparsedEntityDeclHandler)(void *userData,
- const XML_Char *entityName,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId,
- const XML_Char *notationName);
-
-/* This is called for a declaration of notation. The base argument is
- whatever was set by XML_SetBase. The notationName will never be
- NULL. The other arguments can be.
-*/
-typedef void (*XML_NotationDeclHandler)(void *userData,
- const XML_Char *notationName,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId);
-
-/* When namespace processing is enabled, these are called once for
- each namespace declaration. The call to the start and end element
- handlers occur between the calls to the start and end namespace
- declaration handlers. For an xmlns attribute, prefix will be
- NULL. For an xmlns="" attribute, uri will be NULL.
-*/
-typedef void (*XML_StartNamespaceDeclHandler)(void *userData,
- const XML_Char *prefix,
- const XML_Char *uri);
-
-typedef void (*XML_EndNamespaceDeclHandler)(void *userData,
- const XML_Char *prefix);
-
-/* This is called if the document is not standalone, that is, it has an
- external subset or a reference to a parameter entity, but does not
- have standalone="yes". If this handler returns 0, then processing
- will not continue, and the parser will return a
- XML_ERROR_NOT_STANDALONE error.
- If parameter entity parsing is enabled, then in addition to the
- conditions above this handler will only be called if the referenced
- entity was actually read.
-*/
-typedef int (*XML_NotStandaloneHandler)(void *userData);
-
-/* This is called for a reference to an external parsed general
- entity. The referenced entity is not automatically parsed. The
- application can parse it immediately or later using
- XML_ExternalEntityParserCreate.
-
- The parser argument is the parser parsing the entity containing the
- reference; it can be passed as the parser argument to
- XML_ExternalEntityParserCreate. The systemId argument is the
- system identifier as specified in the entity declaration; it will
- not be NULL.
-
- The base argument is the system identifier that should be used as
- the base for resolving systemId if systemId was relative; this is
- set by XML_SetBase; it may be NULL.
-
- The publicId argument is the public identifier as specified in the
- entity declaration, or NULL if none was specified; the whitespace
- in the public identifier will have been normalized as required by
- the XML spec.
-
- The context argument specifies the parsing context in the format
- expected by the context argument to XML_ExternalEntityParserCreate;
- context is valid only until the handler returns, so if the
- referenced entity is to be parsed later, it must be copied.
-
- The handler should return 0 if processing should not continue
- because of a fatal error in the handling of the external entity.
- In this case the calling parser will return an
- XML_ERROR_EXTERNAL_ENTITY_HANDLING error.
-
- Note that unlike other handlers the first argument is the parser,
- not userData.
-*/
-typedef int (*XML_ExternalEntityRefHandler)(XML_Parser parser,
- const XML_Char *context,
- const XML_Char *base,
- const XML_Char *systemId,
- const XML_Char *publicId);
-
-/* This is called in two situations:
- 1) An entity reference is encountered for which no declaration
- has been read *and* this is not an error.
- 2) An internal entity reference is read, but not expanded, because
- XML_SetDefaultHandler has been called.
- Note: skipped parameter entities in declarations and skipped general
- entities in attribute values cannot be reported, because
- the event would be out of sync with the reporting of the
- declarations or attribute values
-*/
-typedef void (*XML_SkippedEntityHandler)(void *userData,
- const XML_Char *entityName,
- int is_parameter_entity);
-
-/* This structure is filled in by the XML_UnknownEncodingHandler to
- provide information to the parser about encodings that are unknown
- to the parser.
-
- The map[b] member gives information about byte sequences whose
- first byte is b.
-
- If map[b] is c where c is >= 0, then b by itself encodes the
- Unicode scalar value c.
-
- If map[b] is -1, then the byte sequence is malformed.
-
- If map[b] is -n, where n >= 2, then b is the first byte of an
- n-byte sequence that encodes a single Unicode scalar value.
-
- The data member will be passed as the first argument to the convert
- function.
-
- The convert function is used to convert multibyte sequences; s will
- point to a n-byte sequence where map[(unsigned char)*s] == -n. The
- convert function must return the Unicode scalar value represented
- by this byte sequence or -1 if the byte sequence is malformed.
-
- The convert function may be NULL if the encoding is a single-byte
- encoding, that is if map[b] >= -1 for all bytes b.
-
- When the parser is finished with the encoding, then if release is
- not NULL, it will call release passing it the data member; once
- release has been called, the convert function will not be called
- again.
-
- Expat places certain restrictions on the encodings that are supported
- using this mechanism.
-
- 1. Every ASCII character that can appear in a well-formed XML document,
- other than the characters
-
- $@\^`{}~
-
- must be represented by a single byte, and that byte must be the
- same byte that represents that character in ASCII.
-
- 2. No character may require more than 4 bytes to encode.
-
- 3. All characters encoded must have Unicode scalar values <=
- 0xFFFF, (i.e., characters that would be encoded by surrogates in
- UTF-16 are not allowed). Note that this restriction doesn't
- apply to the built-in support for UTF-8 and UTF-16.
-
- 4. No Unicode character may be encoded by more than one distinct
- sequence of bytes.
-*/
-typedef struct {
- int map[256];
- void *data;
- int (*convert)(void *data, const char *s);
- void (*release)(void *data);
-} XML_Encoding;
-
-/* This is called for an encoding that is unknown to the parser.
-
- The encodingHandlerData argument is that which was passed as the
- second argument to XML_SetUnknownEncodingHandler.
-
- The name argument gives the name of the encoding as specified in
- the encoding declaration.
-
- If the callback can provide information about the encoding, it must
- fill in the XML_Encoding structure, and return 1. Otherwise it
- must return 0.
-
- If info does not describe a suitable encoding, then the parser will
- return an XML_UNKNOWN_ENCODING error.
-*/
-typedef int (*XML_UnknownEncodingHandler)(void *encodingHandlerData,
- const XML_Char *name,
- XML_Encoding *info);
-
-XMLPARSEAPI(void)
-XML_SetElementHandler(XML_Parser parser,
- XML_StartElementHandler start,
- XML_EndElementHandler end);
-
-XMLPARSEAPI(void)
-XML_SetStartElementHandler(XML_Parser, XML_StartElementHandler);
-
-XMLPARSEAPI(void)
-XML_SetEndElementHandler(XML_Parser, XML_EndElementHandler);
-
-XMLPARSEAPI(void)
-XML_SetCharacterDataHandler(XML_Parser parser,
- XML_CharacterDataHandler handler);
-
-XMLPARSEAPI(void)
-XML_SetProcessingInstructionHandler(XML_Parser parser,
- XML_ProcessingInstructionHandler handler);
-XMLPARSEAPI(void)
-XML_SetCommentHandler(XML_Parser parser,
- XML_CommentHandler handler);
-
-XMLPARSEAPI(void)
-XML_SetCdataSectionHandler(XML_Parser parser,
- XML_StartCdataSectionHandler start,
- XML_EndCdataSectionHandler end);
-
-XMLPARSEAPI(void)
-XML_SetStartCdataSectionHandler(XML_Parser parser,
- XML_StartCdataSectionHandler start);
-
-XMLPARSEAPI(void)
-XML_SetEndCdataSectionHandler(XML_Parser parser,
- XML_EndCdataSectionHandler end);
-
-/* This sets the default handler and also inhibits expansion of
- internal entities. These entity references will be passed to the
- default handler, or to the skipped entity handler, if one is set.
-*/
-XMLPARSEAPI(void)
-XML_SetDefaultHandler(XML_Parser parser,
- XML_DefaultHandler handler);
-
-/* This sets the default handler but does not inhibit expansion of
- internal entities. The entity reference will not be passed to the
- default handler.
-*/
-XMLPARSEAPI(void)
-XML_SetDefaultHandlerExpand(XML_Parser parser,
- XML_DefaultHandler handler);
-
-XMLPARSEAPI(void)
-XML_SetDoctypeDeclHandler(XML_Parser parser,
- XML_StartDoctypeDeclHandler start,
- XML_EndDoctypeDeclHandler end);
-
-XMLPARSEAPI(void)
-XML_SetStartDoctypeDeclHandler(XML_Parser parser,
- XML_StartDoctypeDeclHandler start);
-
-XMLPARSEAPI(void)
-XML_SetEndDoctypeDeclHandler(XML_Parser parser,
- XML_EndDoctypeDeclHandler end);
-
-XMLPARSEAPI(void)
-XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
- XML_UnparsedEntityDeclHandler handler);
-
-XMLPARSEAPI(void)
-XML_SetNotationDeclHandler(XML_Parser parser,
- XML_NotationDeclHandler handler);
-
-XMLPARSEAPI(void)
-XML_SetNamespaceDeclHandler(XML_Parser parser,
- XML_StartNamespaceDeclHandler start,
- XML_EndNamespaceDeclHandler end);
-
-XMLPARSEAPI(void)
-XML_SetStartNamespaceDeclHandler(XML_Parser parser,
- XML_StartNamespaceDeclHandler start);
-
-XMLPARSEAPI(void)
-XML_SetEndNamespaceDeclHandler(XML_Parser parser,
- XML_EndNamespaceDeclHandler end);
-
-XMLPARSEAPI(void)
-XML_SetNotStandaloneHandler(XML_Parser parser,
- XML_NotStandaloneHandler handler);
-
-XMLPARSEAPI(void)
-XML_SetExternalEntityRefHandler(XML_Parser parser,
- XML_ExternalEntityRefHandler handler);
-
-/* If a non-NULL value for arg is specified here, then it will be
- passed as the first argument to the external entity ref handler
- instead of the parser object.
-*/
-XMLPARSEAPI(void)
-XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg);
-
-XMLPARSEAPI(void)
-XML_SetSkippedEntityHandler(XML_Parser parser,
- XML_SkippedEntityHandler handler);
-
-XMLPARSEAPI(void)
-XML_SetUnknownEncodingHandler(XML_Parser parser,
- XML_UnknownEncodingHandler handler,
- void *encodingHandlerData);
-
-/* This can be called within a handler for a start element, end
- element, processing instruction or character data. It causes the
- corresponding markup to be passed to the default handler.
-*/
-XMLPARSEAPI(void)
-XML_DefaultCurrent(XML_Parser parser);
-
-/* If do_nst is non-zero, and namespace processing is in effect, and
- a name has a prefix (i.e. an explicit namespace qualifier) then
- that name is returned as a triplet in a single string separated by
- the separator character specified when the parser was created: URI
- + sep + local_name + sep + prefix.
-
- If do_nst is zero, then namespace information is returned in the
- default manner (URI + sep + local_name) whether or not the name
- has a prefix.
-
- Note: Calling XML_SetReturnNSTriplet after XML_Parse or
- XML_ParseBuffer has no effect.
-*/
-
-XMLPARSEAPI(void)
-XML_SetReturnNSTriplet(XML_Parser parser, int do_nst);
-
-/* This value is passed as the userData argument to callbacks. */
-XMLPARSEAPI(void)
-XML_SetUserData(XML_Parser parser, void *userData);
-
-/* Returns the last value set by XML_SetUserData or NULL. */
-#define XML_GetUserData(parser) (*(void **)(parser))
-
-/* This is equivalent to supplying an encoding argument to
- XML_ParserCreate. On success XML_SetEncoding returns non-zero,
- zero otherwise.
- Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer
- has no effect and returns zero.
-*/
-XMLPARSEAPI(int)
-XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
-
-/* If this function is called, then the parser will be passed as the
- first argument to callbacks instead of userData. The userData will
- still be accessible using XML_GetUserData.
-*/
-XMLPARSEAPI(void)
-XML_UseParserAsHandlerArg(XML_Parser parser);
-
-/* If useDTD == XML_TRUE is passed to this function, then the parser
- will assume that there is an external subset, even if none is
- specified in the document. In such a case the parser will call the
- externalEntityRefHandler with a value of NULL for the systemId
- argument (the publicId and context arguments will be NULL as well).
- Note: If this function is called, then this must be done before
- the first call to XML_Parse or XML_ParseBuffer, since it will
- have no effect after that. Returns
- XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING.
- Note: If the document does not have a DOCTYPE declaration at all,
- then startDoctypeDeclHandler and endDoctypeDeclHandler will not
- be called, despite an external subset being parsed.
- Note: If XML_DTD is not defined when Expat is compiled, returns
- XML_ERROR_FEATURE_REQUIRES_XML_DTD.
-*/
-XMLPARSEAPI(enum XML_Error)
-XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);
-
-
-/* Sets the base to be used for resolving relative URIs in system
- identifiers in declarations. Resolving relative identifiers is
- left to the application: this value will be passed through as the
- base argument to the XML_ExternalEntityRefHandler,
- XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base
- argument will be copied. Returns zero if out of memory, non-zero
- otherwise.
-*/
-XMLPARSEAPI(int)
-XML_SetBase(XML_Parser parser, const XML_Char *base);
-
-XMLPARSEAPI(const XML_Char *)
-XML_GetBase(XML_Parser parser);
-
-/* Returns the number of the attribute/value pairs passed in last call
- to the XML_StartElementHandler that were specified in the start-tag
- rather than defaulted. Each attribute/value pair counts as 2; thus
- this correspondds to an index into the atts array passed to the
- XML_StartElementHandler.
-*/
-XMLPARSEAPI(int)
-XML_GetSpecifiedAttributeCount(XML_Parser parser);
-
-/* Returns the index of the ID attribute passed in the last call to
- XML_StartElementHandler, or -1 if there is no ID attribute. Each
- attribute/value pair counts as 2; thus this correspondds to an
- index into the atts array passed to the XML_StartElementHandler.
-*/
-XMLPARSEAPI(int)
-XML_GetIdAttributeIndex(XML_Parser parser);
-
-/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is
- detected. The last call to XML_Parse must have isFinal true; len
- may be zero for this call (or any other).
-
- The XML_Status enum gives the possible return values for the
- XML_Parse and XML_ParseBuffer functions. Though the return values
- for these functions has always been described as a Boolean value,
- the implementation, at least for the 1.95.x series, has always
- returned exactly one of these values. The preprocessor #defines
- are included so this stanza can be added to code that still needs
- to support older versions of Expat 1.95.x:
-
- #ifndef XML_STATUS_OK
- #define XML_STATUS_OK 1
- #define XML_STATUS_ERROR 0
- #endif
-
- Otherwise, the #define hackery is quite ugly and would have been dropped.
-*/
-enum XML_Status {
- XML_STATUS_ERROR = 0,
-#define XML_STATUS_ERROR XML_STATUS_ERROR
- XML_STATUS_OK = 1
-#define XML_STATUS_OK XML_STATUS_OK
-};
-
-XMLPARSEAPI(enum XML_Status)
-XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);
-
-XMLPARSEAPI(void *)
-XML_GetBuffer(XML_Parser parser, int len);
-
-XMLPARSEAPI(enum XML_Status)
-XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
-
-/* Creates an XML_Parser object that can parse an external general
- entity; context is a '\0'-terminated string specifying the parse
- context; encoding is a '\0'-terminated string giving the name of
- the externally specified encoding, or NULL if there is no
- externally specified encoding. The context string consists of a
- sequence of tokens separated by formfeeds (\f); a token consisting
- of a name specifies that the general entity of the name is open; a
- token of the form prefix=uri specifies the namespace for a
- particular prefix; a token of the form =uri specifies the default
- namespace. This can be called at any point after the first call to
- an ExternalEntityRefHandler so longer as the parser has not yet
- been freed. The new parser is completely independent and may
- safely be used in a separate thread. The handlers and userData are
- initialized from the parser argument. Returns 0 if out of memory.
- Otherwise returns a new XML_Parser object.
-*/
-XMLPARSEAPI(XML_Parser)
-XML_ExternalEntityParserCreate(XML_Parser parser,
- const XML_Char *context,
- const XML_Char *encoding);
-
-enum XML_ParamEntityParsing {
- XML_PARAM_ENTITY_PARSING_NEVER,
- XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,
- XML_PARAM_ENTITY_PARSING_ALWAYS
-};
-
-/* Controls parsing of parameter entities (including the external DTD
- subset). If parsing of parameter entities is enabled, then
- references to external parameter entities (including the external
- DTD subset) will be passed to the handler set with
- XML_SetExternalEntityRefHandler. The context passed will be 0.
-
- Unlike external general entities, external parameter entities can
- only be parsed synchronously. If the external parameter entity is
- to be parsed, it must be parsed during the call to the external
- entity ref handler: the complete sequence of
- XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and
- XML_ParserFree calls must be made during this call. After
- XML_ExternalEntityParserCreate has been called to create the parser
- for the external parameter entity (context must be 0 for this
- call), it is illegal to make any calls on the old parser until
- XML_ParserFree has been called on the newly created parser.
- If the library has been compiled without support for parameter
- entity parsing (ie without XML_DTD being defined), then
- XML_SetParamEntityParsing will return 0 if parsing of parameter
- entities is requested; otherwise it will return non-zero.
- Note: If XML_SetParamEntityParsing is called after XML_Parse or
- XML_ParseBuffer, then it has no effect and will always return 0.
-*/
-XMLPARSEAPI(int)
-XML_SetParamEntityParsing(XML_Parser parser,
- enum XML_ParamEntityParsing parsing);
-
-/* If XML_Parse or XML_ParseBuffer have returned 0, then
- XML_GetErrorCode returns information about the error.
-*/
-XMLPARSEAPI(enum XML_Error)
-XML_GetErrorCode(XML_Parser parser);
-
-/* These functions return information about the current parse
- location. They may be called when XML_Parse or XML_ParseBuffer
- return 0; in this case the location is the location of the
- character at which the error was detected.
-
- They may also be called from any other callback called to report
- some parse event; in this the location is the location of the first
- of the sequence of characters that generated the event.
-*/
-XMLPARSEAPI(int) XML_GetCurrentLineNumber(XML_Parser parser);
-XMLPARSEAPI(int) XML_GetCurrentColumnNumber(XML_Parser parser);
-XMLPARSEAPI(long) XML_GetCurrentByteIndex(XML_Parser parser);
-
-/* Return the number of bytes in the current event.
- Returns 0 if the event is in an internal entity.
-*/
-XMLPARSEAPI(int)
-XML_GetCurrentByteCount(XML_Parser parser);
-
-/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets
- the integer pointed to by offset to the offset within this buffer
- of the current parse position, and sets the integer pointed to by size
- to the size of this buffer (the number of input bytes). Otherwise
- returns a NULL pointer. Also returns a NULL pointer if a parse isn't
- active.
-
- NOTE: The character pointer returned should not be used outside
- the handler that makes the call.
-*/
-XMLPARSEAPI(const char *)
-XML_GetInputContext(XML_Parser parser,
- int *offset,
- int *size);
-
-/* For backwards compatibility with previous versions. */
-#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
-#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
-#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
-
-/* Frees memory used by the parser. */
-XMLPARSEAPI(void)
-XML_ParserFree(XML_Parser parser);
-
-/* Returns a string describing the error. */
-XMLPARSEAPI(const XML_LChar *)
-XML_ErrorString(enum XML_Error code);
-
-/* Return a string containing the version number of this expat */
-XMLPARSEAPI(const XML_LChar *)
-XML_ExpatVersion(void);
-
-typedef struct {
- int major;
- int minor;
- int micro;
-} XML_Expat_Version;
-
-/* Return an XML_Expat_Version structure containing numeric version
- number information for this version of expat.
-*/
-XMLPARSEAPI(XML_Expat_Version)
-XML_ExpatVersionInfo(void);
-
-/* Added in Expat 1.95.5. */
-enum XML_FeatureEnum {
- XML_FEATURE_END = 0,
- XML_FEATURE_UNICODE,
- XML_FEATURE_UNICODE_WCHAR_T,
- XML_FEATURE_DTD,
- XML_FEATURE_CONTEXT_BYTES,
- XML_FEATURE_MIN_SIZE,
- XML_FEATURE_SIZEOF_XML_CHAR,
- XML_FEATURE_SIZEOF_XML_LCHAR
- /* Additional features must be added to the end of this enum. */
-};
-
-typedef struct {
- enum XML_FeatureEnum feature;
- XML_LChar *name;
- long int value;
-} XML_Feature;
-
-XMLPARSEAPI(const XML_Feature *)
-XML_GetFeatureList(void);
-
-
-/* Expat follows the GNU/Linux convention of odd number minor version for
- beta/development releases and even number minor version for stable
- releases. Micro is bumped with each release, and set to 0 with each
- change to major or minor version.
-*/
-#define XML_MAJOR_VERSION 1
-#define XML_MINOR_VERSION 95
-#define XML_MICRO_VERSION 5
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* not XmlParse_INCLUDED */
diff --git a/bundle/expat/iasciitab.h b/bundle/expat/iasciitab.h
deleted file mode 100644
index 24a1d5ccc9..0000000000
--- a/bundle/expat/iasciitab.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
-/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
-/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
-/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
-/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
-/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
-/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
-/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
-/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
-/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
-/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
-/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/bundle/expat/internal.h b/bundle/expat/internal.h
deleted file mode 100644
index 6e2c5ed45f..0000000000
--- a/bundle/expat/internal.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* internal.h
-
- Internal definitions used by Expat. This is not needed to compile
- client code.
-
- The following definitions are made:
-
- FASTCALL -- Used for most internal functions to specify that the
- fastest possible calling convention be used.
-
- inline -- Used for selected internal functions for which inlining
- may improve performance on some platforms.
-*/
-
-#if defined(__GNUC__)
-/* Last minute instability reported with egcs on a RedHat Linux 7.3
- box; argh!
-*/
-/* #define FASTCALL __attribute__((stdcall, regparm(3))) */
-#elif defined(WIN32)
-/* XXX This seems to have an unexpected negative effect on Windows so
- we'll disable it for now on that platform. It may be reconsidered
- for a future release if it can be made more effective.
-*/
-/* #define FASTCALL __fastcall */
-#endif
-
-#ifndef FASTCALL
-#define FASTCALL
-#endif
-
-#ifndef XML_MIN_SIZE
-#if !defined(__cplusplus) && !defined(inline)
-#ifdef __GNUC__
-#define inline __inline
-#endif /* __GNUC__ */
-#endif
-#endif /* XML_MIN_SIZE */
-
-#ifdef __cplusplus
-#define inline inline
-#else
-#ifndef inline
-#define inline
-#endif
-#endif
diff --git a/bundle/expat/latin1tab.h b/bundle/expat/latin1tab.h
deleted file mode 100644
index 53c25d76b2..0000000000
--- a/bundle/expat/latin1tab.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
-/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
-/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
-/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
diff --git a/bundle/expat/nametab.h b/bundle/expat/nametab.h
deleted file mode 100644
index b05e62c77a..0000000000
--- a/bundle/expat/nametab.h
+++ /dev/null
@@ -1,150 +0,0 @@
-static const unsigned namingBitmap[] = {
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
-0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
-0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
-0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
-0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
-0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
-0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
-0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
-0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
-0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
-0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
-0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
-0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
-0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
-0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
-0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
-0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
-0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
-0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
-0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
-0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
-0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
-0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
-0x40000000, 0xF580C900, 0x00000007, 0x02010800,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
-0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
-0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
-0x00000000, 0x00004C40, 0x00000000, 0x00000000,
-0x00000007, 0x00000000, 0x00000000, 0x00000000,
-0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
-0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
-0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
-0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
-0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
-0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
-0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
-0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
-0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
-0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
-0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
-0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
-0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
-0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
-0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
-0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
-0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
-0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
-0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
-0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
-0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
-0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
-0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
-0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
-0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
-0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
-0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
-0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
-};
-static const unsigned char nmstrtPages[] = {
-0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
-0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
-0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-static const unsigned char namePages[] = {
-0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
-0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
-0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
-0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
diff --git a/bundle/expat/utf8tab.h b/bundle/expat/utf8tab.h
deleted file mode 100644
index 7bb3e77603..0000000000
--- a/bundle/expat/utf8tab.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-
-/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
-/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
diff --git a/bundle/expat/winconfig.h b/bundle/expat/winconfig.h
deleted file mode 100644
index ce91577f20..0000000000
--- a/bundle/expat/winconfig.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*================================================================
-** Copyright 2000, Clark Cooper
-** All rights reserved.
-**
-** This is free software. You are permitted to copy, distribute, or modify
-** it under the terms of the MIT/X license (contained in the COPYING file
-** with this distribution.)
-*/
-
-#ifndef WINCONFIG_H
-#define WINCONFIG_H
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#undef WIN32_LEAN_AND_MEAN
-
-#include <memory.h>
-#include <string.h>
-
-#define XML_NS 1
-#define XML_DTD 1
-#define XML_CONTEXT_BYTES 1024
-
-/* we will assume all Windows platforms are little endian */
-#define BYTEORDER 1234
-
-/* Windows has memmove() available. */
-/* #define HAVE_MEMMOVE */
-
-#endif /* ndef WINCONFIG_H */
diff --git a/bundle/expat/xmlparse.c b/bundle/expat/xmlparse.c
deleted file mode 100644
index 60e65d6907..0000000000
--- a/bundle/expat/xmlparse.c
+++ /dev/null
@@ -1,5592 +0,0 @@
-/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-#include <stddef.h>
-#include <string.h> /* memset(), memcpy() */
-#if PHP_WIN32
-#include "config.w32.h"
-#else
-#include "php_config.h"
-#endif
-#include "php_compat.h"
-
-#ifdef COMPILED_FROM_DSP
-
-#include "winconfig.h"
-#ifdef _LIB
-#define XMLPARSEAPI(type) type __cdecl
-#else
-#define XMLPARSEAPI(type) __declspec(dllexport) type __cdecl
-#endif
-#include "expat.h"
-#undef XMLPARSEAPI
-
-#elif defined(MACOS_CLASSIC)
-
-#include "macconfig.h"
-#include "expat.h"
-
-#else
-
-#include <php_config.h>
-
-#ifdef __declspec
-#define XMLPARSEAPI(type) __declspec(dllexport) type __cdecl
-#endif
-
-#include "expat.h"
-
-#ifdef __declspec
-#undef XMLPARSEAPI
-#endif
-#endif /* ndef COMPILED_FROM_DSP */
-
-#ifdef XML_UNICODE
-#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
-#define XmlConvert XmlUtf16Convert
-#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
-#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
-#define XmlEncode XmlUtf16Encode
-#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
-typedef unsigned short ICHAR;
-#else
-#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
-#define XmlConvert XmlUtf8Convert
-#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
-#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
-#define XmlEncode XmlUtf8Encode
-#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
-typedef char ICHAR;
-#endif
-
-
-#ifndef XML_NS
-
-#define XmlInitEncodingNS XmlInitEncoding
-#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
-#undef XmlGetInternalEncodingNS
-#define XmlGetInternalEncodingNS XmlGetInternalEncoding
-#define XmlParseXmlDeclNS XmlParseXmlDecl
-
-#endif
-
-#ifdef XML_UNICODE
-
-#ifdef XML_UNICODE_WCHAR_T
-#define XML_T(x) (const wchar_t)x
-#define XML_L(x) L ## x
-#else
-#define XML_T(x) (const unsigned short)x
-#define XML_L(x) x
-#endif
-
-#else
-
-#define XML_T(x) x
-#define XML_L(x) x
-
-#endif
-
-/* Round up n to be a multiple of sz, where sz is a power of 2. */
-#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
-
-/* Handle the case where memmove() doesn't exist. */
-#ifndef HAVE_MEMMOVE
-#ifdef HAVE_BCOPY
-#define memmove(d,s,l) bcopy((s),(d),(l))
-#else
-#error memmove does not exist on this platform, nor is a substitute available
-#endif /* HAVE_BCOPY */
-#endif /* HAVE_MEMMOVE */
-
-#include "internal.h"
-#include "xmltok.h"
-#include "xmlrole.h"
-
-typedef const XML_Char *KEY;
-
-typedef struct {
- KEY name;
-} NAMED;
-
-typedef struct {
- NAMED **v;
- size_t size;
- size_t used;
- size_t usedLim;
- XML_Memory_Handling_Suite *mem;
-} HASH_TABLE;
-
-typedef struct {
- NAMED **p;
- NAMED **end;
-} HASH_TABLE_ITER;
-
-#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
-#define INIT_DATA_BUF_SIZE 1024
-#define INIT_ATTS_SIZE 16
-#define INIT_BLOCK_SIZE 1024
-#define INIT_BUFFER_SIZE 1024
-
-#define EXPAND_SPARE 24
-
-typedef struct binding {
- struct prefix *prefix;
- struct binding *nextTagBinding;
- struct binding *prevPrefixBinding;
- const struct attribute_id *attId;
- XML_Char *uri;
- int uriLen;
- int uriAlloc;
-} BINDING;
-
-typedef struct prefix {
- const XML_Char *name;
- BINDING *binding;
-} PREFIX;
-
-typedef struct {
- const XML_Char *str;
- const XML_Char *localPart;
- const XML_Char *prefix;
- int strLen;
- int uriLen;
- int prefixLen;
-} TAG_NAME;
-
-/* TAG represents an open element.
- The name of the element is stored in both the document and API
- encodings. The memory buffer 'buf' is a separately-allocated
- memory area which stores the name. During the XML_Parse()/
- XMLParseBuffer() when the element is open, the memory for the 'raw'
- version of the name (in the document encoding) is shared with the
- document buffer. If the element is open across calls to
- XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
- contain the 'raw' name as well.
-
- A parser re-uses these structures, maintaining a list of allocated
- TAG objects in a free list.
-*/
-typedef struct tag {
- struct tag *parent; /* parent of this element */
- const char *rawName; /* tagName in the original encoding */
- int rawNameLength;
- TAG_NAME name; /* tagName in the API encoding */
- char *buf; /* buffer for name components */
- char *bufEnd; /* end of the buffer */
- BINDING *bindings;
-} TAG;
-
-typedef struct {
- const XML_Char *name;
- const XML_Char *textPtr;
- int textLen;
- const XML_Char *systemId;
- const XML_Char *base;
- const XML_Char *publicId;
- const XML_Char *notation;
- XML_Bool open;
- XML_Bool is_param;
- XML_Bool is_internal; /* true if declared in internal subset outside PE */
-} ENTITY;
-
-typedef struct {
- enum XML_Content_Type type;
- enum XML_Content_Quant quant;
- const XML_Char * name;
- int firstchild;
- int lastchild;
- int childcnt;
- int nextsib;
-} CONTENT_SCAFFOLD;
-
-#define INIT_SCAFFOLD_ELEMENTS 32
-
-typedef struct block {
- struct block *next;
- int size;
- XML_Char s[1];
-} BLOCK;
-
-typedef struct {
- BLOCK *blocks;
- BLOCK *freeBlocks;
- const XML_Char *end;
- XML_Char *ptr;
- XML_Char *start;
- XML_Memory_Handling_Suite *mem;
-} STRING_POOL;
-
-/* The XML_Char before the name is used to determine whether
- an attribute has been specified. */
-typedef struct attribute_id {
- XML_Char *name;
- PREFIX *prefix;
- XML_Bool maybeTokenized;
- XML_Bool xmlns;
-} ATTRIBUTE_ID;
-
-typedef struct {
- const ATTRIBUTE_ID *id;
- XML_Bool isCdata;
- const XML_Char *value;
-} DEFAULT_ATTRIBUTE;
-
-typedef struct {
- const XML_Char *name;
- PREFIX *prefix;
- const ATTRIBUTE_ID *idAtt;
- int nDefaultAtts;
- int allocDefaultAtts;
- DEFAULT_ATTRIBUTE *defaultAtts;
-} ELEMENT_TYPE;
-
-typedef struct {
- HASH_TABLE generalEntities;
- HASH_TABLE elementTypes;
- HASH_TABLE attributeIds;
- HASH_TABLE prefixes;
- STRING_POOL pool;
- STRING_POOL entityValuePool;
- /* false once a parameter entity reference has been skipped */
- XML_Bool keepProcessing;
- /* true once an internal or external PE reference has been encountered;
- any external subset is considered an external PE reference */
- XML_Bool hasParamEntityRefs;
- XML_Bool standalone;
-#ifdef XML_DTD
- /* indicates if external PE has been read */
- XML_Bool paramEntityRead;
- HASH_TABLE paramEntities;
-#endif /* XML_DTD */
- PREFIX defaultPrefix;
- /* === scaffolding for building content model === */
- XML_Bool in_eldecl;
- CONTENT_SCAFFOLD *scaffold;
- unsigned contentStringLen;
- unsigned scaffSize;
- unsigned scaffCount;
- int scaffLevel;
- int *scaffIndex;
-} DTD;
-
-typedef struct open_internal_entity {
- const char *internalEventPtr;
- const char *internalEventEndPtr;
- struct open_internal_entity *next;
- ENTITY *entity;
-} OPEN_INTERNAL_ENTITY;
-
-typedef enum XML_Error FASTCALL Processor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr);
-
-static Processor prologProcessor;
-static Processor prologInitProcessor;
-static Processor contentProcessor;
-static Processor cdataSectionProcessor;
-#ifdef XML_DTD
-static Processor ignoreSectionProcessor;
-static Processor externalParEntProcessor;
-static Processor externalParEntInitProcessor;
-static Processor entityValueProcessor;
-static Processor entityValueInitProcessor;
-#endif /* XML_DTD */
-static Processor epilogProcessor;
-static Processor errorProcessor;
-static Processor externalEntityInitProcessor;
-static Processor externalEntityInitProcessor2;
-static Processor externalEntityInitProcessor3;
-static Processor externalEntityContentProcessor;
-
-static enum XML_Error FASTCALL
-handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
-static enum XML_Error FASTCALL
-processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
- const char *, const char *);
-static enum XML_Error FASTCALL
-initializeEncoding(XML_Parser parser);
-static enum XML_Error FASTCALL
-doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
- const char *end, int tok, const char *next, const char **nextPtr);
-static enum XML_Error FASTCALL
-processInternalParamEntity(XML_Parser parser, ENTITY *entity);
-static enum XML_Error FASTCALL
-doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
- const char *start, const char *end, const char **endPtr);
-static enum XML_Error FASTCALL
-doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
- const char *end, const char **nextPtr);
-#ifdef XML_DTD
-static enum XML_Error FASTCALL
-doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
- const char *end, const char **nextPtr);
-#endif /* XML_DTD */
-static enum XML_Error FASTCALL
-storeAtts(XML_Parser parser, const ENCODING *,
- const char *s, TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
-static int FASTCALL
-addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
- const XML_Char *uri, BINDING **bindingsPtr);
-
-static int FASTCALL
-defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *,
- XML_Bool isCdata, XML_Bool isId, const XML_Char *dfltValue,
- XML_Parser parser);
-
-static enum XML_Error FASTCALL
-storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
- const char *, const char *, STRING_POOL *);
-static enum XML_Error FASTCALL
-appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
- const char *, const char *, STRING_POOL *);
-static ATTRIBUTE_ID * FASTCALL
-getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
- const char *end);
-static int FASTCALL
-setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
-static enum XML_Error FASTCALL
-storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
- const char *end);
-static int FASTCALL
-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end);
-static int FASTCALL
-reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
- const char *end);
-static void FASTCALL
-reportDefault(XML_Parser parser, const ENCODING *enc, const char *start,
- const char *end);
-
-static const XML_Char * FASTCALL getContext(XML_Parser parser);
-static XML_Bool FASTCALL
-setContext(XML_Parser parser, const XML_Char *context);
-static void FASTCALL normalizePublicId(XML_Char *s);
-static void FASTCALL dtdInit(DTD *, XML_Parser parser);
-
-/* do not call if parentParser != NULL */
-static void FASTCALL dtdReset(DTD *, XML_Parser parser);
-static void FASTCALL dtdDestroy(DTD *, XML_Parser parser);
-
-static int FASTCALL dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser);
-
-static int FASTCALL copyEntityTable(HASH_TABLE *, STRING_POOL *,
- const HASH_TABLE *, XML_Parser parser);
-
-#ifdef XML_DTD
-static void FASTCALL dtdSwap(DTD *, DTD *);
-#endif /* XML_DTD */
-
-static NAMED * FASTCALL
-lookup(HASH_TABLE *table, KEY name, size_t createSize);
-
-static void FASTCALL
-hashTableInit(HASH_TABLE *, XML_Memory_Handling_Suite *ms);
-
-static void FASTCALL hashTableClear(HASH_TABLE *);
-static void FASTCALL hashTableDestroy(HASH_TABLE *);
-static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
-static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
-static void FASTCALL poolInit(STRING_POOL *, XML_Memory_Handling_Suite *ms);
-static void FASTCALL poolClear(STRING_POOL *);
-static void FASTCALL poolDestroy(STRING_POOL *);
-static XML_Char * FASTCALL
-poolAppend(STRING_POOL *pool, const ENCODING *enc,
- const char *ptr, const char *end);
-static XML_Char * FASTCALL
-poolStoreString(STRING_POOL *pool, const ENCODING *enc,
- const char *ptr, const char *end);
-
-static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
-
-static int FASTCALL nextScaffoldPart(XML_Parser parser);
-static XML_Content * FASTCALL build_model(XML_Parser parser);
-
-static const XML_Char * FASTCALL
-poolCopyString(STRING_POOL *pool, const XML_Char *s);
-static const XML_Char * FASTCALL
-poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
-static const XML_Char * FASTCALL
-poolAppendString(STRING_POOL *pool, const XML_Char *s);
-static ELEMENT_TYPE * FASTCALL
-getElementType(XML_Parser Paraser, const ENCODING *enc,
- const char *ptr, const char *end);
-
-static void FASTCALL
-parserInit(XML_Parser parser, const XML_Char *encodingName);
-
-#define poolStart(pool) ((pool)->start)
-#define poolEnd(pool) ((pool)->ptr)
-#define poolLength(pool) ((pool)->ptr - (pool)->start)
-#define poolChop(pool) ((void)--(pool->ptr))
-#define poolLastChar(pool) (((pool)->ptr)[-1])
-#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
-#define poolFinish(pool) ((pool)->start = (pool)->ptr)
-#define poolAppendChar(pool, c) \
- (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
- ? 0 \
- : ((*((pool)->ptr)++ = c), 1))
-
-struct XML_ParserStruct {
- /* The first member must be userData so that the XML_GetUserData
- macro works. */
- void *m_userData;
- void *m_handlerArg;
- char *m_buffer;
- XML_Memory_Handling_Suite m_mem;
- /* first character to be parsed */
- const char *m_bufferPtr;
- /* past last character to be parsed */
- char *m_bufferEnd;
- /* allocated end of buffer */
- const char *m_bufferLim;
- long m_parseEndByteIndex;
- const char *m_parseEndPtr;
- XML_Char *m_dataBuf;
- XML_Char *m_dataBufEnd;
- XML_StartElementHandler m_startElementHandler;
- XML_EndElementHandler m_endElementHandler;
- XML_CharacterDataHandler m_characterDataHandler;
- XML_ProcessingInstructionHandler m_processingInstructionHandler;
- XML_CommentHandler m_commentHandler;
- XML_StartCdataSectionHandler m_startCdataSectionHandler;
- XML_EndCdataSectionHandler m_endCdataSectionHandler;
- XML_DefaultHandler m_defaultHandler;
- XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
- XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
- XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
- XML_NotationDeclHandler m_notationDeclHandler;
- XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
- XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
- XML_NotStandaloneHandler m_notStandaloneHandler;
- XML_ExternalEntityRefHandler m_externalEntityRefHandler;
- void *m_externalEntityRefHandlerArg;
- XML_SkippedEntityHandler m_skippedEntityHandler;
- XML_UnknownEncodingHandler m_unknownEncodingHandler;
- XML_ElementDeclHandler m_elementDeclHandler;
- XML_AttlistDeclHandler m_attlistDeclHandler;
- XML_EntityDeclHandler m_entityDeclHandler;
- XML_XmlDeclHandler m_xmlDeclHandler;
- const ENCODING *m_encoding;
- INIT_ENCODING m_initEncoding;
- const ENCODING *m_internalEncoding;
- const XML_Char *m_protocolEncodingName;
- XML_Bool m_ns;
- XML_Bool m_ns_triplets;
- void *m_unknownEncodingMem;
- void *m_unknownEncodingData;
- void *m_unknownEncodingHandlerData;
- void (*m_unknownEncodingRelease)(void *);
- PROLOG_STATE m_prologState;
- Processor *m_processor;
- enum XML_Error m_errorCode;
- const char *m_eventPtr;
- const char *m_eventEndPtr;
- const char *m_positionPtr;
- OPEN_INTERNAL_ENTITY *m_openInternalEntities;
- XML_Bool m_defaultExpandInternalEntities;
- int m_tagLevel;
- ENTITY *m_declEntity;
- const XML_Char *m_doctypeName;
- const XML_Char *m_doctypeSysid;
- const XML_Char *m_doctypePubid;
- const XML_Char *m_declAttributeType;
- const XML_Char *m_declNotationName;
- const XML_Char *m_declNotationPublicId;
- ELEMENT_TYPE *m_declElementType;
- ATTRIBUTE_ID *m_declAttributeId;
- XML_Bool m_declAttributeIsCdata;
- XML_Bool m_declAttributeIsId;
- DTD m_dtd;
- const XML_Char *m_curBase;
- TAG *m_tagStack;
- TAG *m_freeTagList;
- BINDING *m_inheritedBindings;
- BINDING *m_freeBindingList;
- int m_attsSize;
- int m_nSpecifiedAtts;
- int m_idAttIndex;
- ATTRIBUTE *m_atts;
- POSITION m_position;
- STRING_POOL m_tempPool;
- STRING_POOL m_temp2Pool;
- char *m_groupConnector;
- unsigned m_groupSize;
- XML_Char m_namespaceSeparator;
- XML_Parser m_parentParser;
-#ifdef XML_DTD
- XML_Bool m_isParamEntity;
- XML_Bool m_useForeignDTD;
- enum XML_ParamEntityParsing m_paramEntityParsing;
-#endif
-};
-
-#define MALLOC(s) ((parser)->m_mem.malloc_fcn((s)))
-#define REALLOC(p,s) ((parser)->m_mem.realloc_fcn((p),(s)))
-#define FREE(p) ((parser)->m_mem.free_fcn((p)))
-
-#define userData (parser->m_userData)
-#define handlerArg (parser->m_handlerArg)
-#define startElementHandler (parser->m_startElementHandler)
-#define endElementHandler (parser->m_endElementHandler)
-#define characterDataHandler (parser->m_characterDataHandler)
-#define processingInstructionHandler \
- (parser->m_processingInstructionHandler)
-#define commentHandler (parser->m_commentHandler)
-#define startCdataSectionHandler \
- (parser->m_startCdataSectionHandler)
-#define endCdataSectionHandler (parser->m_endCdataSectionHandler)
-#define defaultHandler (parser->m_defaultHandler)
-#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler)
-#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler)
-#define unparsedEntityDeclHandler \
- (parser->m_unparsedEntityDeclHandler)
-#define notationDeclHandler (parser->m_notationDeclHandler)
-#define startNamespaceDeclHandler \
- (parser->m_startNamespaceDeclHandler)
-#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler)
-#define notStandaloneHandler (parser->m_notStandaloneHandler)
-#define externalEntityRefHandler \
- (parser->m_externalEntityRefHandler)
-#define externalEntityRefHandlerArg \
- (parser->m_externalEntityRefHandlerArg)
-#define internalEntityRefHandler \
- (parser->m_internalEntityRefHandler)
-#define skippedEntityHandler (parser->m_skippedEntityHandler)
-#define unknownEncodingHandler (parser->m_unknownEncodingHandler)
-#define elementDeclHandler (parser->m_elementDeclHandler)
-#define attlistDeclHandler (parser->m_attlistDeclHandler)
-#define entityDeclHandler (parser->m_entityDeclHandler)
-#define xmlDeclHandler (parser->m_xmlDeclHandler)
-#define encoding (parser->m_encoding)
-#define initEncoding (parser->m_initEncoding)
-#define internalEncoding (parser->m_internalEncoding)
-#define unknownEncodingMem (parser->m_unknownEncodingMem)
-#define unknownEncodingData (parser->m_unknownEncodingData)
-#define unknownEncodingHandlerData \
- (parser->m_unknownEncodingHandlerData)
-#define unknownEncodingRelease (parser->m_unknownEncodingRelease)
-#define protocolEncodingName (parser->m_protocolEncodingName)
-#define ns (parser->m_ns)
-#define ns_triplets (parser->m_ns_triplets)
-#define prologState (parser->m_prologState)
-#define processor (parser->m_processor)
-#define errorCode (parser->m_errorCode)
-#define eventPtr (parser->m_eventPtr)
-#define eventEndPtr (parser->m_eventEndPtr)
-#define positionPtr (parser->m_positionPtr)
-#define position (parser->m_position)
-#define openInternalEntities (parser->m_openInternalEntities)
-#define defaultExpandInternalEntities \
- (parser->m_defaultExpandInternalEntities)
-#define tagLevel (parser->m_tagLevel)
-#define buffer (parser->m_buffer)
-#define bufferPtr (parser->m_bufferPtr)
-#define bufferEnd (parser->m_bufferEnd)
-#define parseEndByteIndex (parser->m_parseEndByteIndex)
-#define parseEndPtr (parser->m_parseEndPtr)
-#define bufferLim (parser->m_bufferLim)
-#define dataBuf (parser->m_dataBuf)
-#define dataBufEnd (parser->m_dataBufEnd)
-#define dtd (parser->m_dtd)
-#define curBase (parser->m_curBase)
-#define declEntity (parser->m_declEntity)
-#define doctypeName (parser->m_doctypeName)
-#define doctypeSysid (parser->m_doctypeSysid)
-#define doctypePubid (parser->m_doctypePubid)
-#define declAttributeType (parser->m_declAttributeType)
-#define declNotationName (parser->m_declNotationName)
-#define declNotationPublicId (parser->m_declNotationPublicId)
-#define declElementType (parser->m_declElementType)
-#define declAttributeId (parser->m_declAttributeId)
-#define declAttributeIsCdata (parser->m_declAttributeIsCdata)
-#define declAttributeIsId (parser->m_declAttributeIsId)
-#define freeTagList (parser->m_freeTagList)
-#define freeBindingList (parser->m_freeBindingList)
-#define inheritedBindings (parser->m_inheritedBindings)
-#define tagStack (parser->m_tagStack)
-#define atts (parser->m_atts)
-#define attsSize (parser->m_attsSize)
-#define nSpecifiedAtts (parser->m_nSpecifiedAtts)
-#define idAttIndex (parser->m_idAttIndex)
-#define tempPool (parser->m_tempPool)
-#define temp2Pool (parser->m_temp2Pool)
-#define groupConnector (parser->m_groupConnector)
-#define groupSize (parser->m_groupSize)
-#define namespaceSeparator (parser->m_namespaceSeparator)
-#define parentParser (parser->m_parentParser)
-#ifdef XML_DTD
-#define isParamEntity (parser->m_isParamEntity)
-#define useForeignDTD (parser->m_useForeignDTD)
-#define paramEntityParsing (parser->m_paramEntityParsing)
-#endif /* XML_DTD */
-
-#define parsing (processor != prologInitProcessor)
-
-
-XML_Parser
-XML_ParserCreate(const XML_Char *encodingName)
-{
- return XML_ParserCreate_MM(encodingName, NULL, NULL);
-}
-
-XML_Parser
-XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
-{
- XML_Char tmp[2];
- *tmp = nsSep;
- return XML_ParserCreate_MM(encodingName, NULL, tmp);
-}
-
-XML_Parser
-XML_ParserCreate_MM(const XML_Char *encodingName,
- const XML_Memory_Handling_Suite *memsuite,
- const XML_Char *nameSep) {
- XML_Parser parser;
- static const XML_Char implicitContext[] = {
- 'x', 'm', 'l', '=', 'h', 't', 't', 'p', ':', '/', '/',
- 'w', 'w', 'w', '.', 'w', '3', '.', 'o', 'r', 'g', '/',
- 'X', 'M', 'L', '/', '1', '9', '9', '8', '/',
- 'n', 'a', 'm', 'e', 's', 'p', 'a', 'c', 'e', '\0'
- };
-
-
- if (memsuite) {
- XML_Memory_Handling_Suite *mtemp;
- parser = memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
- if (parser != NULL) {
- mtemp = &(parser->m_mem);
- mtemp->malloc_fcn = memsuite->malloc_fcn;
- mtemp->realloc_fcn = memsuite->realloc_fcn;
- mtemp->free_fcn = memsuite->free_fcn;
- }
- }
- else {
- XML_Memory_Handling_Suite *mtemp;
- parser = malloc(sizeof(struct XML_ParserStruct));
- if (parser != NULL) {
- mtemp = &(parser->m_mem);
- mtemp->malloc_fcn = malloc;
- mtemp->realloc_fcn = realloc;
- mtemp->free_fcn = free;
- }
- }
-
- if (!parser)
- return parser;
-
- buffer = NULL;
- bufferLim = NULL;
-
- attsSize = INIT_ATTS_SIZE;
- atts = MALLOC(attsSize * sizeof(ATTRIBUTE));
- if (atts == NULL) {
- FREE(parser);
- return NULL;
- }
- dataBuf = MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
- if (dataBuf == NULL) {
- FREE(atts);
- FREE(parser);
- return NULL;
- }
- dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
-
- freeBindingList = NULL;
- freeTagList = NULL;
-
- groupSize = 0;
- groupConnector = NULL;
-
- unknownEncodingHandler = NULL;
- unknownEncodingHandlerData = NULL;
-
- namespaceSeparator = '!';
- ns = XML_FALSE;
- ns_triplets = XML_FALSE;
-
- poolInit(&tempPool, &(parser->m_mem));
- poolInit(&temp2Pool, &(parser->m_mem));
- parserInit(parser, encodingName);
- dtdInit(&dtd, parser);
-
- if (!atts || !dataBuf || (encodingName && !protocolEncodingName)) {
- XML_ParserFree(parser);
- return NULL;
- }
-
- if (nameSep) {
- ns = XML_TRUE;
- internalEncoding = XmlGetInternalEncodingNS();
- namespaceSeparator = *nameSep;
-
- if (!setContext(parser, implicitContext)) {
- XML_ParserFree(parser);
- return NULL;
- }
- }
- else {
- internalEncoding = XmlGetInternalEncoding();
- }
-
- return parser;
-}
-
-static void FASTCALL
-parserInit(XML_Parser parser, const XML_Char *encodingName)
-{
- processor = prologInitProcessor;
- XmlPrologStateInit(&prologState);
- protocolEncodingName = (encodingName != NULL
- ? poolCopyString(&tempPool, encodingName)
- : NULL);
- curBase = NULL;
- XmlInitEncoding(&initEncoding, &encoding, 0);
- userData = NULL;
- handlerArg = NULL;
- startElementHandler = NULL;
- endElementHandler = NULL;
- characterDataHandler = NULL;
- processingInstructionHandler = NULL;
- commentHandler = NULL;
- startCdataSectionHandler = NULL;
- endCdataSectionHandler = NULL;
- defaultHandler = NULL;
- startDoctypeDeclHandler = NULL;
- endDoctypeDeclHandler = NULL;
- unparsedEntityDeclHandler = NULL;
- notationDeclHandler = NULL;
- startNamespaceDeclHandler = NULL;
- endNamespaceDeclHandler = NULL;
- notStandaloneHandler = NULL;
- externalEntityRefHandler = NULL;
- externalEntityRefHandlerArg = parser;
- skippedEntityHandler = NULL;
- elementDeclHandler = NULL;
- attlistDeclHandler = NULL;
- entityDeclHandler = NULL;
- xmlDeclHandler = NULL;
- bufferPtr = buffer;
- bufferEnd = buffer;
- parseEndByteIndex = 0;
- parseEndPtr = NULL;
- declElementType = NULL;
- declAttributeId = NULL;
- declEntity = NULL;
- doctypeName = NULL;
- doctypeSysid = NULL;
- doctypePubid = NULL;
- declAttributeType = NULL;
- declNotationName = NULL;
- declNotationPublicId = NULL;
- declAttributeIsCdata = XML_FALSE;
- declAttributeIsId = XML_FALSE;
- memset(&position, 0, sizeof(POSITION));
- errorCode = XML_ERROR_NONE;
- eventPtr = NULL;
- eventEndPtr = NULL;
- positionPtr = NULL;
- openInternalEntities = 0;
- defaultExpandInternalEntities = XML_TRUE;
- tagLevel = 0;
- tagStack = NULL;
- inheritedBindings = NULL;
- nSpecifiedAtts = 0;
- unknownEncodingMem = NULL;
- unknownEncodingRelease = NULL;
- unknownEncodingData = NULL;
- parentParser = NULL;
-#ifdef XML_DTD
- isParamEntity = XML_FALSE;
- useForeignDTD = XML_FALSE;
- paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
-#endif
-}
-
-/* moves list of bindings to freeBindingList */
-static void FASTCALL
-moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
-{
- while (bindings) {
- BINDING *b = bindings;
- bindings = bindings->nextTagBinding;
- b->nextTagBinding = freeBindingList;
- freeBindingList = b;
- }
-}
-
-XML_Bool
-XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
-{
- TAG *tStk;
- if (parentParser)
- return XML_FALSE;
- /* move tagStack to freeTagList */
- tStk = tagStack;
- while (tStk) {
- TAG *tag = tStk;
- tStk = tStk->parent;
- tag->parent = freeTagList;
- moveToFreeBindingList(parser, tag->bindings);
- tag->bindings = NULL;
- freeTagList = tag;
- }
- moveToFreeBindingList(parser, inheritedBindings);
- if (unknownEncodingMem)
- FREE(unknownEncodingMem);
- if (unknownEncodingRelease)
- unknownEncodingRelease(unknownEncodingData);
- poolClear(&tempPool);
- poolClear(&temp2Pool);
- parserInit(parser, encodingName);
- dtdReset(&dtd, parser);
- return XML_TRUE;
-}
-
-int
-XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
-{
- /* block after XML_Parse()/XML_ParseBuffer() has been called */
- if (parsing)
- return 0;
- if (encodingName == NULL)
- protocolEncodingName = NULL;
- else {
- protocolEncodingName = poolCopyString(&tempPool, encodingName);
- if (!protocolEncodingName)
- return 0;
- }
- return 1;
-}
-
-XML_Parser
-XML_ExternalEntityParserCreate(XML_Parser oldParser,
- const XML_Char *context,
- const XML_Char *encodingName)
-{
- XML_Parser parser = oldParser;
- DTD *oldDtd = &dtd;
- XML_StartElementHandler oldStartElementHandler = startElementHandler;
- XML_EndElementHandler oldEndElementHandler = endElementHandler;
- XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
- XML_ProcessingInstructionHandler oldProcessingInstructionHandler
- = processingInstructionHandler;
- XML_CommentHandler oldCommentHandler = commentHandler;
- XML_StartCdataSectionHandler oldStartCdataSectionHandler
- = startCdataSectionHandler;
- XML_EndCdataSectionHandler oldEndCdataSectionHandler
- = endCdataSectionHandler;
- XML_DefaultHandler oldDefaultHandler = defaultHandler;
- XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
- = unparsedEntityDeclHandler;
- XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
- XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
- = startNamespaceDeclHandler;
- XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
- = endNamespaceDeclHandler;
- XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
- XML_ExternalEntityRefHandler oldExternalEntityRefHandler
- = externalEntityRefHandler;
- XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
- XML_UnknownEncodingHandler oldUnknownEncodingHandler
- = unknownEncodingHandler;
- XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
- XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
- XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
- XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
- ELEMENT_TYPE * oldDeclElementType = declElementType;
-
- void *oldUserData = userData;
- void *oldHandlerArg = handlerArg;
- XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
- void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
-#ifdef XML_DTD
- int oldParamEntityParsing = paramEntityParsing;
- int oldInEntityValue = prologState.inEntityValue;
-#endif
- XML_Bool oldns_triplets = ns_triplets;
-
- /* Note that the magical uses of the pre-processor to make field
- access look more like C++ require that `parser' be overwritten
- here. This makes this function more painful to follow than it
- would be otherwise.
- */
- if (ns) {
- XML_Char tmp[2];
-
- *tmp = namespaceSeparator;
- parser = XML_ParserCreate_MM(encodingName, &parser->m_mem,
- tmp);
- }
- else {
- parser = XML_ParserCreate_MM(encodingName, &parser->m_mem,
- NULL);
- }
-
- if (!parser)
- return NULL;
-
- startElementHandler = oldStartElementHandler;
- endElementHandler = oldEndElementHandler;
- characterDataHandler = oldCharacterDataHandler;
- processingInstructionHandler = oldProcessingInstructionHandler;
- commentHandler = oldCommentHandler;
- startCdataSectionHandler = oldStartCdataSectionHandler;
- endCdataSectionHandler = oldEndCdataSectionHandler;
- defaultHandler = oldDefaultHandler;
- unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
- notationDeclHandler = oldNotationDeclHandler;
- startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
- endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
- notStandaloneHandler = oldNotStandaloneHandler;
- externalEntityRefHandler = oldExternalEntityRefHandler;
- skippedEntityHandler = oldSkippedEntityHandler;
- unknownEncodingHandler = oldUnknownEncodingHandler;
- elementDeclHandler = oldElementDeclHandler;
- attlistDeclHandler = oldAttlistDeclHandler;
- entityDeclHandler = oldEntityDeclHandler;
- xmlDeclHandler = oldXmlDeclHandler;
- declElementType = oldDeclElementType;
- userData = oldUserData;
- if (oldUserData == oldHandlerArg)
- handlerArg = userData;
- else
- handlerArg = parser;
- if (oldExternalEntityRefHandlerArg != oldParser)
- externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
- defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
- ns_triplets = oldns_triplets;
- parentParser = oldParser;
-#ifdef XML_DTD
- paramEntityParsing = oldParamEntityParsing;
- prologState.inEntityValue = oldInEntityValue;
- if (context) {
-#endif /* XML_DTD */
- if (!dtdCopy(&dtd, oldDtd, parser) || !setContext(parser, context)) {
- XML_ParserFree(parser);
- return NULL;
- }
- processor = externalEntityInitProcessor;
-#ifdef XML_DTD
- }
- else {
- dtdSwap(&dtd, oldDtd);
- isParamEntity = XML_TRUE;
- XmlPrologStateInitExternalEntity(&prologState);
- processor = externalParEntInitProcessor;
- }
-#endif /* XML_DTD */
- return parser;
-}
-
-static void FASTCALL
-destroyBindings(BINDING *bindings, XML_Parser parser)
-{
- for (;;) {
- BINDING *b = bindings;
- if (!b)
- break;
- bindings = b->nextTagBinding;
- FREE(b->uri);
- FREE(b);
- }
-}
-
-void
-XML_ParserFree(XML_Parser parser)
-{
- for (;;) {
- TAG *p;
- if (tagStack == 0) {
- if (freeTagList == NULL)
- break;
- tagStack = freeTagList;
- freeTagList = NULL;
- }
- p = tagStack;
- tagStack = tagStack->parent;
- FREE(p->buf);
- destroyBindings(p->bindings, parser);
- FREE(p);
- }
- destroyBindings(freeBindingList, parser);
- destroyBindings(inheritedBindings, parser);
- poolDestroy(&tempPool);
- poolDestroy(&temp2Pool);
-#ifdef XML_DTD
- if (isParamEntity)
- dtdSwap(&dtd, &parentParser->m_dtd);
-#endif /* XML_DTD */
- dtdDestroy(&dtd, parser);
- FREE((void *)atts);
- if (groupConnector)
- FREE(groupConnector);
- if (buffer)
- FREE(buffer);
- FREE(dataBuf);
- if (unknownEncodingMem)
- FREE(unknownEncodingMem);
- if (unknownEncodingRelease)
- unknownEncodingRelease(unknownEncodingData);
- FREE(parser);
-}
-
-void
-XML_UseParserAsHandlerArg(XML_Parser parser)
-{
- handlerArg = parser;
-}
-
-enum XML_Error
-XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
-{
-#ifdef XML_DTD
- /* block after XML_Parse()/XML_ParseBuffer() has been called */
- if (parsing)
- return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
- useForeignDTD = useDTD;
- return XML_ERROR_NONE;
-#else
- return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
-#endif
-}
-
-void
-XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
-{
- /* block after XML_Parse()/XML_ParseBuffer() has been called */
- if (parsing)
- return;
- ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
-}
-
-void
-XML_SetUserData(XML_Parser parser, void *p)
-{
- if (handlerArg == userData)
- handlerArg = userData = p;
- else
- userData = p;
-}
-
-int
-XML_SetBase(XML_Parser parser, const XML_Char *p)
-{
- if (p) {
- p = poolCopyString(&dtd.pool, p);
- if (!p)
- return 0;
- curBase = p;
- }
- else
- curBase = NULL;
- return 1;
-}
-
-const XML_Char *
-XML_GetBase(XML_Parser parser)
-{
- return curBase;
-}
-
-int
-XML_GetSpecifiedAttributeCount(XML_Parser parser)
-{
- return nSpecifiedAtts;
-}
-
-int
-XML_GetIdAttributeIndex(XML_Parser parser)
-{
- return idAttIndex;
-}
-
-void
-XML_SetElementHandler(XML_Parser parser,
- XML_StartElementHandler start,
- XML_EndElementHandler end)
-{
- startElementHandler = start;
- endElementHandler = end;
-}
-
-void
-XML_SetStartElementHandler(XML_Parser parser,
- XML_StartElementHandler start) {
- startElementHandler = start;
-}
-
-void
-XML_SetEndElementHandler(XML_Parser parser,
- XML_EndElementHandler end) {
- endElementHandler = end;
-}
-
-void
-XML_SetCharacterDataHandler(XML_Parser parser,
- XML_CharacterDataHandler handler)
-{
- characterDataHandler = handler;
-}
-
-void
-XML_SetProcessingInstructionHandler(XML_Parser parser,
- XML_ProcessingInstructionHandler handler)
-{
- processingInstructionHandler = handler;
-}
-
-void
-XML_SetCommentHandler(XML_Parser parser,
- XML_CommentHandler handler)
-{
- commentHandler = handler;
-}
-
-void
-XML_SetCdataSectionHandler(XML_Parser parser,
- XML_StartCdataSectionHandler start,
- XML_EndCdataSectionHandler end)
-{
- startCdataSectionHandler = start;
- endCdataSectionHandler = end;
-}
-
-void
-XML_SetStartCdataSectionHandler(XML_Parser parser,
- XML_StartCdataSectionHandler start) {
- startCdataSectionHandler = start;
-}
-
-void
-XML_SetEndCdataSectionHandler(XML_Parser parser,
- XML_EndCdataSectionHandler end) {
- endCdataSectionHandler = end;
-}
-
-void
-XML_SetDefaultHandler(XML_Parser parser,
- XML_DefaultHandler handler)
-{
- defaultHandler = handler;
- defaultExpandInternalEntities = XML_FALSE;
-}
-
-void
-XML_SetDefaultHandlerExpand(XML_Parser parser,
- XML_DefaultHandler handler)
-{
- defaultHandler = handler;
- defaultExpandInternalEntities = XML_TRUE;
-}
-
-void
-XML_SetDoctypeDeclHandler(XML_Parser parser,
- XML_StartDoctypeDeclHandler start,
- XML_EndDoctypeDeclHandler end)
-{
- startDoctypeDeclHandler = start;
- endDoctypeDeclHandler = end;
-}
-
-void
-XML_SetStartDoctypeDeclHandler(XML_Parser parser,
- XML_StartDoctypeDeclHandler start) {
- startDoctypeDeclHandler = start;
-}
-
-void
-XML_SetEndDoctypeDeclHandler(XML_Parser parser,
- XML_EndDoctypeDeclHandler end) {
- endDoctypeDeclHandler = end;
-}
-
-void
-XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
- XML_UnparsedEntityDeclHandler handler)
-{
- unparsedEntityDeclHandler = handler;
-}
-
-void
-XML_SetNotationDeclHandler(XML_Parser parser,
- XML_NotationDeclHandler handler)
-{
- notationDeclHandler = handler;
-}
-
-void
-XML_SetNamespaceDeclHandler(XML_Parser parser,
- XML_StartNamespaceDeclHandler start,
- XML_EndNamespaceDeclHandler end)
-{
- startNamespaceDeclHandler = start;
- endNamespaceDeclHandler = end;
-}
-
-void
-XML_SetStartNamespaceDeclHandler(XML_Parser parser,
- XML_StartNamespaceDeclHandler start) {
- startNamespaceDeclHandler = start;
-}
-
-void
-XML_SetEndNamespaceDeclHandler(XML_Parser parser,
- XML_EndNamespaceDeclHandler end) {
- endNamespaceDeclHandler = end;
-}
-
-void
-XML_SetNotStandaloneHandler(XML_Parser parser,
- XML_NotStandaloneHandler handler)
-{
- notStandaloneHandler = handler;
-}
-
-void
-XML_SetExternalEntityRefHandler(XML_Parser parser,
- XML_ExternalEntityRefHandler handler)
-{
- externalEntityRefHandler = handler;
-}
-
-void
-XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
-{
- if (arg)
- externalEntityRefHandlerArg = arg;
- else
- externalEntityRefHandlerArg = parser;
-}
-
-void
-XML_SetSkippedEntityHandler(XML_Parser parser,
- XML_SkippedEntityHandler handler)
-{
- skippedEntityHandler = handler;
-}
-
-void
-XML_SetUnknownEncodingHandler(XML_Parser parser,
- XML_UnknownEncodingHandler handler,
- void *data)
-{
- unknownEncodingHandler = handler;
- unknownEncodingHandlerData = data;
-}
-
-void
-XML_SetElementDeclHandler(XML_Parser parser,
- XML_ElementDeclHandler eldecl)
-{
- elementDeclHandler = eldecl;
-}
-
-void
-XML_SetAttlistDeclHandler(XML_Parser parser,
- XML_AttlistDeclHandler attdecl)
-{
- attlistDeclHandler = attdecl;
-}
-
-void
-XML_SetEntityDeclHandler(XML_Parser parser,
- XML_EntityDeclHandler handler)
-{
- entityDeclHandler = handler;
-}
-
-void
-XML_SetXmlDeclHandler(XML_Parser parser,
- XML_XmlDeclHandler handler) {
- xmlDeclHandler = handler;
-}
-
-int
-XML_SetParamEntityParsing(XML_Parser parser,
- enum XML_ParamEntityParsing peParsing)
-{
- /* block after XML_Parse()/XML_ParseBuffer() has been called */
- if (parsing)
- return 0;
-#ifdef XML_DTD
- paramEntityParsing = peParsing;
- return 1;
-#else
- return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
-#endif
-}
-
-enum XML_Status
-XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
-{
- if (len == 0) {
- if (!isFinal)
- return XML_STATUS_OK;
- positionPtr = bufferPtr;
- errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
- if (errorCode == XML_ERROR_NONE)
- return XML_STATUS_OK;
- eventEndPtr = eventPtr;
- processor = errorProcessor;
- return XML_STATUS_ERROR;
- }
-#ifndef XML_CONTEXT_BYTES
- else if (bufferPtr == bufferEnd) {
- const char *end;
- int nLeftOver;
- parseEndByteIndex += len;
- positionPtr = s;
- if (isFinal) {
- errorCode = processor(parser, s, parseEndPtr = s + len, 0);
- if (errorCode == XML_ERROR_NONE)
- return XML_STATUS_OK;
- eventEndPtr = eventPtr;
- processor = errorProcessor;
- return XML_STATUS_ERROR;
- }
- errorCode = processor(parser, s, parseEndPtr = s + len, &end);
- if (errorCode != XML_ERROR_NONE) {
- eventEndPtr = eventPtr;
- processor = errorProcessor;
- return XML_STATUS_ERROR;
- }
- XmlUpdatePosition(encoding, positionPtr, end, &position);
- nLeftOver = s + len - end;
- if (nLeftOver) {
- if (buffer == NULL || nLeftOver > bufferLim - buffer) {
- /* FIXME avoid integer overflow */
- char *temp;
- temp = buffer == NULL ? MALLOC(len * 2) : REALLOC(buffer, len * 2);
- if (temp == NULL) {
- errorCode = XML_ERROR_NO_MEMORY;
- return XML_STATUS_ERROR;
- }
- buffer = temp;
- if (!buffer) {
- errorCode = XML_ERROR_NO_MEMORY;
- eventPtr = eventEndPtr = NULL;
- processor = errorProcessor;
- return XML_STATUS_ERROR;
- }
- bufferLim = buffer + len * 2;
- }
- memcpy(buffer, end, nLeftOver);
- bufferPtr = buffer;
- bufferEnd = buffer + nLeftOver;
- }
- return XML_STATUS_OK;
- }
-#endif /* not defined XML_CONTEXT_BYTES */
- else {
- void *buff = XML_GetBuffer(parser, len);
- if (buff == NULL)
- return XML_STATUS_ERROR;
- else {
- memcpy(buff, s, len);
- return XML_ParseBuffer(parser, len, isFinal);
- }
- }
-}
-
-enum XML_Status
-XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
-{
- const char *start = bufferPtr;
- positionPtr = start;
- bufferEnd += len;
- parseEndByteIndex += len;
- errorCode = processor(parser, start, parseEndPtr = bufferEnd,
- isFinal ? (const char **)NULL : &bufferPtr);
- if (errorCode == XML_ERROR_NONE) {
- if (!isFinal)
- XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
- return XML_STATUS_OK;
- }
- else {
- eventEndPtr = eventPtr;
- processor = errorProcessor;
- return XML_STATUS_ERROR;
- }
-}
-
-void *
-XML_GetBuffer(XML_Parser parser, int len)
-{
- if (len > bufferLim - bufferEnd) {
- /* FIXME avoid integer overflow */
- int neededSize = len + (bufferEnd - bufferPtr);
-#ifdef XML_CONTEXT_BYTES
- int keep = bufferPtr - buffer;
-
- if (keep > XML_CONTEXT_BYTES)
- keep = XML_CONTEXT_BYTES;
- neededSize += keep;
-#endif /* defined XML_CONTEXT_BYTES */
- if (neededSize <= bufferLim - buffer) {
-#ifdef XML_CONTEXT_BYTES
- if (keep < bufferPtr - buffer) {
- int offset = (bufferPtr - buffer) - keep;
- memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
- bufferEnd -= offset;
- bufferPtr -= offset;
- }
-#else
- memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
- bufferEnd = buffer + (bufferEnd - bufferPtr);
- bufferPtr = buffer;
-#endif /* not defined XML_CONTEXT_BYTES */
- }
- else {
- char *newBuf;
- int bufferSize = bufferLim - bufferPtr;
- if (bufferSize == 0)
- bufferSize = INIT_BUFFER_SIZE;
- do {
- bufferSize *= 2;
- } while (bufferSize < neededSize);
- newBuf = MALLOC(bufferSize);
- if (newBuf == 0) {
- errorCode = XML_ERROR_NO_MEMORY;
- return NULL;
- }
- bufferLim = newBuf + bufferSize;
-#ifdef XML_CONTEXT_BYTES
- if (bufferPtr) {
- int keep = bufferPtr - buffer;
- if (keep > XML_CONTEXT_BYTES)
- keep = XML_CONTEXT_BYTES;
- memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
- FREE(buffer);
- buffer = newBuf;
- bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
- bufferPtr = buffer + keep;
- }
- else {
- bufferEnd = newBuf + (bufferEnd - bufferPtr);
- bufferPtr = buffer = newBuf;
- }
-#else
- if (bufferPtr) {
- memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
- FREE(buffer);
- }
- bufferEnd = newBuf + (bufferEnd - bufferPtr);
- bufferPtr = buffer = newBuf;
-#endif /* not defined XML_CONTEXT_BYTES */
- }
- }
- return bufferEnd;
-}
-
-enum XML_Error
-XML_GetErrorCode(XML_Parser parser)
-{
- return errorCode;
-}
-
-long
-XML_GetCurrentByteIndex(XML_Parser parser)
-{
- if (eventPtr)
- return parseEndByteIndex - (parseEndPtr - eventPtr);
- return -1;
-}
-
-int
-XML_GetCurrentByteCount(XML_Parser parser)
-{
- if (eventEndPtr && eventPtr)
- return eventEndPtr - eventPtr;
- return 0;
-}
-
-const char *
-XML_GetInputContext(XML_Parser parser, int *offset, int *size)
-{
-#ifdef XML_CONTEXT_BYTES
- if (eventPtr && buffer) {
- *offset = eventPtr - buffer;
- *size = bufferEnd - buffer;
- return buffer;
- }
-#endif /* defined XML_CONTEXT_BYTES */
- return (char *) 0;
-}
-
-int
-XML_GetCurrentLineNumber(XML_Parser parser)
-{
- if (eventPtr) {
- XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
- positionPtr = eventPtr;
- }
- return position.lineNumber + 1;
-}
-
-int
-XML_GetCurrentColumnNumber(XML_Parser parser)
-{
- if (eventPtr) {
- XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
- positionPtr = eventPtr;
- }
- return position.columnNumber;
-}
-
-void
-XML_DefaultCurrent(XML_Parser parser)
-{
- if (defaultHandler) {
- if (openInternalEntities)
- reportDefault(parser,
- internalEncoding,
- openInternalEntities->internalEventPtr,
- openInternalEntities->internalEventEndPtr);
- else
- reportDefault(parser, encoding, eventPtr, eventEndPtr);
- }
-}
-
-const XML_LChar *
-XML_ErrorString(enum XML_Error code)
-{
- static const XML_LChar *message[] = {
- 0,
- XML_L("out of memory"),
- XML_L("syntax error"),
- XML_L("no element found"),
- XML_L("not well-formed (invalid token)"),
- XML_L("unclosed token"),
- XML_L("partial character"),
- XML_L("mismatched tag"),
- XML_L("duplicate attribute"),
- XML_L("junk after document element"),
- XML_L("illegal parameter entity reference"),
- XML_L("undefined entity"),
- XML_L("recursive entity reference"),
- XML_L("asynchronous entity"),
- XML_L("reference to invalid character number"),
- XML_L("reference to binary entity"),
- XML_L("reference to external entity in attribute"),
- XML_L("xml declaration not at start of external entity"),
- XML_L("unknown encoding"),
- XML_L("encoding specified in XML declaration is incorrect"),
- XML_L("unclosed CDATA section"),
- XML_L("error in processing external entity reference"),
- XML_L("document is not standalone"),
- XML_L("unexpected parser state - please send a bug report"),
- XML_L("entity declared in parameter entity"),
- XML_L("requested feature requires XML_DTD support in Expat"),
- XML_L("cannot change setting once parsing has begun")
- };
- if (code > 0 && code < sizeof(message)/sizeof(message[0]))
- return message[code];
- return NULL;
-}
-
-const XML_LChar *
-XML_ExpatVersion(void) {
- return "1.95.5";
-}
-
-XML_Expat_Version
-XML_ExpatVersionInfo(void)
-{
- XML_Expat_Version version;
-
- version.major = XML_MAJOR_VERSION;
- version.minor = XML_MINOR_VERSION;
- version.micro = XML_MICRO_VERSION;
-
- return version;
-}
-
-const XML_Feature *
-XML_GetFeatureList(void)
-{
- static XML_Feature features[] = {
- {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)")},
- {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)")},
-#ifdef XML_UNICODE
- {XML_FEATURE_UNICODE, XML_L("XML_UNICODE")},
-#endif
-#ifdef XML_UNICODE_WCHAR_T
- {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T")},
-#endif
-#ifdef XML_DTD
- {XML_FEATURE_DTD, XML_L("XML_DTD")},
-#endif
-#ifdef XML_CONTEXT_BYTES
- {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
- XML_CONTEXT_BYTES},
-#endif
-#ifdef XML_MIN_SIZE
- {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE")},
-#endif
- {XML_FEATURE_END, NULL}
- };
-
- features[0].value = sizeof(XML_Char);
- features[1].value = sizeof(XML_LChar);
- return features;
-}
-
-/* Initially tag->rawName always points into the parse buffer;
- for those TAG instances opened while the current parse buffer was
- processed, and not yet closed, we need to store tag->rawName in a more
- permanent location, since the parse buffer is about to be discarded.
-*/
-static XML_Bool FASTCALL
-storeRawNames(XML_Parser parser)
-{
- TAG *tag = tagStack;
- while (tag) {
- int bufSize;
- int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
- char *rawNameBuf = tag->buf + nameLen;
- /* Stop if already stored. Since tagStack is a stack, we can stop
- at the first entry that has already been copied; everything
- below it in the stack is already been accounted for in a
- previous call to this function.
- */
- if (tag->rawName == rawNameBuf)
- break;
- /* For re-use purposes we need to ensure that the
- size of tag->buf is a multiple of sizeof(XML_Char).
- */
- bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
- if (bufSize > tag->bufEnd - tag->buf) {
- char *temp = REALLOC(tag->buf, bufSize);
- if (temp == NULL)
- return XML_FALSE;
- tag->buf = temp;
- tag->name.str = (XML_Char *)temp;
- tag->bufEnd = temp + bufSize;
- rawNameBuf = temp + nameLen;
- }
- memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
- tag->rawName = rawNameBuf;
- tag = tag->parent;
- }
- return XML_TRUE;
-}
-
-static enum XML_Error FASTCALL
-contentProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- enum XML_Error result =
- doContent(parser, 0, encoding, start, end, endPtr);
- if (result != XML_ERROR_NONE)
- return result;
- if (!storeRawNames(parser))
- return XML_ERROR_NO_MEMORY;
- return result;
-}
-
-static enum XML_Error FASTCALL
-externalEntityInitProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- enum XML_Error result = initializeEncoding(parser);
- if (result != XML_ERROR_NONE)
- return result;
- processor = externalEntityInitProcessor2;
- return externalEntityInitProcessor2(parser, start, end, endPtr);
-}
-
-static enum XML_Error FASTCALL
-externalEntityInitProcessor2(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- const char *next = start; /* XmlContentTok doesn't always set the last arg */
- int tok = XmlContentTok(encoding, start, end, &next);
- switch (tok) {
- case XML_TOK_BOM:
- /* If we are at the end of the buffer, this would cause the next stage,
- i.e. externalEntityInitProcessor3, to pass control directly to
- doContent (by detecting XML_TOK_NONE) without processing any xml text
- declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
- */
- if (next == end && endPtr) {
- *endPtr = next;
- return XML_ERROR_NONE;
- }
- start = next;
- break;
- case XML_TOK_PARTIAL:
- if (endPtr) {
- *endPtr = start;
- return XML_ERROR_NONE;
- }
- eventPtr = start;
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (endPtr) {
- *endPtr = start;
- return XML_ERROR_NONE;
- }
- eventPtr = start;
- return XML_ERROR_PARTIAL_CHAR;
- }
- processor = externalEntityInitProcessor3;
- return externalEntityInitProcessor3(parser, start, end, endPtr);
-}
-
-static enum XML_Error FASTCALL
-externalEntityInitProcessor3(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- const char *next = start; /* XmlContentTok doesn't always set the last arg */
- int tok = XmlContentTok(encoding, start, end, &next);
- switch (tok) {
- case XML_TOK_XML_DECL:
- {
- enum XML_Error result = processXmlDecl(parser, 1, start, next);
- if (result != XML_ERROR_NONE)
- return result;
- start = next;
- }
- break;
- case XML_TOK_PARTIAL:
- if (endPtr) {
- *endPtr = start;
- return XML_ERROR_NONE;
- }
- eventPtr = start;
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (endPtr) {
- *endPtr = start;
- return XML_ERROR_NONE;
- }
- eventPtr = start;
- return XML_ERROR_PARTIAL_CHAR;
- }
- processor = externalEntityContentProcessor;
- tagLevel = 1;
- return externalEntityContentProcessor(parser, start, end, endPtr);
-}
-
-static enum XML_Error FASTCALL
-externalEntityContentProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- enum XML_Error result =
- doContent(parser, 1, encoding, start, end, endPtr);
- if (result != XML_ERROR_NONE)
- return result;
- if (!storeRawNames(parser))
- return XML_ERROR_NO_MEMORY;
- return result;
-}
-
-static enum XML_Error FASTCALL
-doContent(XML_Parser parser,
- int startTagLevel,
- const ENCODING *enc,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- const char **eventPP;
- const char **eventEndPP;
- if (enc == encoding) {
- eventPP = &eventPtr;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
- }
- *eventPP = s;
- for (;;) {
- const char *next = s; /* XmlContentTok doesn't always set the last arg */
- int tok = XmlContentTok(enc, s, end, &next);
- *eventEndPP = next;
- switch (tok) {
- case XML_TOK_TRAILING_CR:
- if (nextPtr) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- *eventEndPP = end;
- if (characterDataHandler) {
- XML_Char c = 0xA;
- characterDataHandler(handlerArg, &c, 1);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, end);
- if (startTagLevel == 0)
- return XML_ERROR_NO_ELEMENTS;
- if (tagLevel != startTagLevel)
- return XML_ERROR_ASYNC_ENTITY;
- return XML_ERROR_NONE;
- case XML_TOK_NONE:
- if (nextPtr) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- if (startTagLevel > 0) {
- if (tagLevel != startTagLevel)
- return XML_ERROR_ASYNC_ENTITY;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_NO_ELEMENTS;
- case XML_TOK_INVALID:
- *eventPP = next;
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- if (nextPtr) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (nextPtr) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_ENTITY_REF:
- {
- const XML_Char *name;
- ENTITY *entity;
- XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (ch) {
- if (characterDataHandler)
- characterDataHandler(handlerArg, &ch, 1);
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
- name = poolStoreString(&dtd.pool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name)
- return XML_ERROR_NO_MEMORY;
- entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
- poolDiscard(&dtd.pool);
- /* First, determine if a check for an existing declaration is needed;
- if yes, check that the entity exists, and that it is internal,
- otherwise call the skipped entity or default handler.
- */
- if (!dtd.hasParamEntityRefs || dtd.standalone) {
- if (!entity)
- return XML_ERROR_UNDEFINED_ENTITY;
- else if (!entity->is_internal)
- return XML_ERROR_ENTITY_DECLARED_IN_PE;
- }
- else if (!entity) {
- if (skippedEntityHandler)
- skippedEntityHandler(handlerArg, name, 0);
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
- if (entity->open)
- return XML_ERROR_RECURSIVE_ENTITY_REF;
- if (entity->notation)
- return XML_ERROR_BINARY_ENTITY_REF;
- if (entity->textPtr) {
- enum XML_Error result;
- OPEN_INTERNAL_ENTITY openEntity;
- if (!defaultExpandInternalEntities) {
- if (skippedEntityHandler)
- skippedEntityHandler(handlerArg, entity->name, 0);
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
- entity->open = XML_TRUE;
- openEntity.next = openInternalEntities;
- openInternalEntities = &openEntity;
- openEntity.entity = entity;
- openEntity.internalEventPtr = NULL;
- openEntity.internalEventEndPtr = NULL;
- result = doContent(parser,
- tagLevel,
- internalEncoding,
- (char *)entity->textPtr,
- (char *)(entity->textPtr + entity->textLen),
- 0);
- entity->open = XML_FALSE;
- openInternalEntities = openEntity.next;
- if (result)
- return result;
- }
- else if (externalEntityRefHandler) {
- const XML_Char *context;
- entity->open = XML_TRUE;
- context = getContext(parser);
- entity->open = XML_FALSE;
- if (!context)
- return XML_ERROR_NO_MEMORY;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- context,
- entity->base,
- entity->systemId,
- entity->publicId))
- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- poolDiscard(&tempPool);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
- case XML_TOK_START_TAG_WITH_ATTS:
- if (!startElementHandler) {
- enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
- if (result)
- return result;
- }
- /* fall through */
- case XML_TOK_START_TAG_NO_ATTS:
- {
- TAG *tag;
- enum XML_Error result;
- XML_Char *toPtr;
- if (freeTagList) {
- tag = freeTagList;
- freeTagList = freeTagList->parent;
- }
- else {
- tag = MALLOC(sizeof(TAG));
- if (!tag)
- return XML_ERROR_NO_MEMORY;
- tag->buf = MALLOC(INIT_TAG_BUF_SIZE);
- if (!tag->buf) {
- FREE(tag);
- return XML_ERROR_NO_MEMORY;
- }
- tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
- }
- tag->bindings = NULL;
- tag->parent = tagStack;
- tagStack = tag;
- tag->name.localPart = NULL;
- tag->name.prefix = NULL;
- tag->rawName = s + enc->minBytesPerChar;
- tag->rawNameLength = XmlNameLength(enc, tag->rawName);
- ++tagLevel;
- {
- const char *rawNameEnd = tag->rawName + tag->rawNameLength;
- const char *fromPtr = tag->rawName;
- toPtr = (XML_Char *)tag->buf;
- for (;;) {
- int bufSize;
- int convLen;
- XmlConvert(enc,
- &fromPtr, rawNameEnd,
- (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
- convLen = toPtr - (XML_Char *)tag->buf;
- if (fromPtr == rawNameEnd) {
- tag->name.strLen = convLen;
- break;
- }
- bufSize = (tag->bufEnd - tag->buf) << 1;
- {
- char *temp = REALLOC(tag->buf, bufSize);
- if (temp == NULL)
- return XML_ERROR_NO_MEMORY;
- tag->buf = temp;
- tag->bufEnd = temp + bufSize;
- toPtr = (XML_Char *)temp + convLen;
- }
- }
- }
- tag->name.str = (XML_Char *)tag->buf;
- *toPtr = XML_T('\0');
- if (startElementHandler) {
- result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
- if (result)
- return result;
- startElementHandler(handlerArg, tag->name.str,
- (const XML_Char **)atts);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- poolClear(&tempPool);
- break;
- }
- case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
- if (!startElementHandler) {
- enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
- if (result)
- return result;
- }
- /* fall through */
- case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
- if (startElementHandler || endElementHandler) {
- const char *rawName = s + enc->minBytesPerChar;
- enum XML_Error result;
- BINDING *bindings = NULL;
- TAG_NAME name;
- name.str = poolStoreString(&tempPool, enc, rawName,
- rawName + XmlNameLength(enc, rawName));
- if (!name.str)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- result = storeAtts(parser, enc, s, &name, &bindings);
- if (result)
- return result;
- poolFinish(&tempPool);
- if (startElementHandler)
- startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
- if (endElementHandler) {
- if (startElementHandler)
- *eventPP = *eventEndPP;
- endElementHandler(handlerArg, name.str);
- }
- poolClear(&tempPool);
- while (bindings) {
- BINDING *b = bindings;
- if (endNamespaceDeclHandler)
- endNamespaceDeclHandler(handlerArg, b->prefix->name);
- bindings = bindings->nextTagBinding;
- b->nextTagBinding = freeBindingList;
- freeBindingList = b;
- b->prefix->binding = b->prevPrefixBinding;
- }
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- if (tagLevel == 0)
- return epilogProcessor(parser, next, end, nextPtr);
- break;
- case XML_TOK_END_TAG:
- if (tagLevel == startTagLevel)
- return XML_ERROR_ASYNC_ENTITY;
- else {
- int len;
- const char *rawName;
- TAG *tag = tagStack;
- tagStack = tag->parent;
- tag->parent = freeTagList;
- freeTagList = tag;
- rawName = s + enc->minBytesPerChar*2;
- len = XmlNameLength(enc, rawName);
- if (len != tag->rawNameLength
- || memcmp(tag->rawName, rawName, len) != 0) {
- *eventPP = rawName;
- return XML_ERROR_TAG_MISMATCH;
- }
- --tagLevel;
- if (endElementHandler) {
- const XML_Char *localPart;
- const XML_Char *prefix;
- XML_Char *uri;
- localPart = tag->name.localPart;
- if (ns && localPart) {
- /* localPart and prefix may have been overwritten in
- tag->name.str, since this points to the binding->uri
- buffer which gets re-used; so we have to add them again
- */
- uri = (XML_Char *)tag->name.str + tag->name.uriLen;
- /* don't need to check for space - already done in storeAtts() */
- while (*localPart) *uri++ = *localPart++;
- prefix = (XML_Char *)tag->name.prefix;
- if (ns_triplets && prefix) {
- *uri++ = namespaceSeparator;
- while (*prefix) *uri++ = *prefix++;
- }
- *uri = XML_T('\0');
- }
- endElementHandler(handlerArg, tag->name.str);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- while (tag->bindings) {
- BINDING *b = tag->bindings;
- if (endNamespaceDeclHandler)
- endNamespaceDeclHandler(handlerArg, b->prefix->name);
- tag->bindings = tag->bindings->nextTagBinding;
- b->nextTagBinding = freeBindingList;
- freeBindingList = b;
- b->prefix->binding = b->prevPrefixBinding;
- }
- if (tagLevel == 0)
- return epilogProcessor(parser, next, end, nextPtr);
- }
- break;
- case XML_TOK_CHAR_REF:
- {
- int n = XmlCharRefNumber(enc, s);
- if (n < 0)
- return XML_ERROR_BAD_CHAR_REF;
- if (characterDataHandler) {
- XML_Char buf[XML_ENCODE_MAX];
- characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- }
- break;
- case XML_TOK_XML_DECL:
- return XML_ERROR_MISPLACED_XML_PI;
- case XML_TOK_DATA_NEWLINE:
- if (characterDataHandler) {
- XML_Char c = 0xA;
- characterDataHandler(handlerArg, &c, 1);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- case XML_TOK_CDATA_SECT_OPEN:
- {
- enum XML_Error result;
- if (startCdataSectionHandler)
- startCdataSectionHandler(handlerArg);
-#if 0
- /* Suppose you doing a transformation on a document that involves
- changing only the character data. You set up a defaultHandler
- and a characterDataHandler. The defaultHandler simply copies
- characters through. The characterDataHandler does the
- transformation and writes the characters out escaping them as
- necessary. This case will fail to work if we leave out the
- following two lines (because & and < inside CDATA sections will
- be incorrectly escaped).
-
- However, now we have a start/endCdataSectionHandler, so it seems
- easier to let the user deal with this.
- */
- else if (characterDataHandler)
- characterDataHandler(handlerArg, dataBuf, 0);
-#endif
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- result = doCdataSection(parser, enc, &next, end, nextPtr);
- if (!next) {
- processor = cdataSectionProcessor;
- return result;
- }
- }
- break;
- case XML_TOK_TRAILING_RSQB:
- if (nextPtr) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- if (characterDataHandler) {
- if (MUST_CONVERT(enc, s)) {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
- characterDataHandler(handlerArg, dataBuf,
- dataPtr - (ICHAR *)dataBuf);
- }
- else
- characterDataHandler(handlerArg,
- (XML_Char *)s,
- (XML_Char *)end - (XML_Char *)s);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, end);
- if (startTagLevel == 0) {
- *eventPP = end;
- return XML_ERROR_NO_ELEMENTS;
- }
- if (tagLevel != startTagLevel) {
- *eventPP = end;
- return XML_ERROR_ASYNC_ENTITY;
- }
- return XML_ERROR_NONE;
- case XML_TOK_DATA_CHARS:
- if (characterDataHandler) {
- if (MUST_CONVERT(enc, s)) {
- for (;;) {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
- *eventEndPP = s;
- characterDataHandler(handlerArg, dataBuf,
- dataPtr - (ICHAR *)dataBuf);
- if (s == next)
- break;
- *eventPP = s;
- }
- }
- else
- characterDataHandler(handlerArg,
- (XML_Char *)s,
- (XML_Char *)next - (XML_Char *)s);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- case XML_TOK_PI:
- if (!reportProcessingInstruction(parser, enc, s, next))
- return XML_ERROR_NO_MEMORY;
- break;
- case XML_TOK_COMMENT:
- if (!reportComment(parser, enc, s, next))
- return XML_ERROR_NO_MEMORY;
- break;
- default:
- if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- }
- *eventPP = s = next;
- }
- /* not reached */
-}
-
-/* If tagNamePtr is non-null, build a real list of attributes,
- otherwise just check the attributes for well-formedness.
-*/
-static enum XML_Error FASTCALL
-storeAtts(XML_Parser parser, const ENCODING *enc,
- const char *attStr, TAG_NAME *tagNamePtr,
- BINDING **bindingsPtr)
-{
- ELEMENT_TYPE *elementType = NULL;
- int nDefaultAtts = 0;
- const XML_Char **appAtts; /* the attribute list for the application */
- int attIndex = 0;
- int prefixLen;
- int i;
- int n;
- XML_Char *uri;
- int nPrefixes = 0;
- BINDING *binding;
- const XML_Char *localPart;
-
- /* lookup the element type name */
- if (tagNamePtr) {
- elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str,0);
- if (!elementType) {
- tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
- if (!tagNamePtr->str)
- return XML_ERROR_NO_MEMORY;
- elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str,
- sizeof(ELEMENT_TYPE));
- if (!elementType)
- return XML_ERROR_NO_MEMORY;
- if (ns && !setElementTypePrefix(parser, elementType))
- return XML_ERROR_NO_MEMORY;
- }
- nDefaultAtts = elementType->nDefaultAtts;
- }
- /* get the attributes from the tokenizer */
- n = XmlGetAttributes(enc, attStr, attsSize, atts);
- if (n + nDefaultAtts > attsSize) {
- int oldAttsSize = attsSize;
- ATTRIBUTE *temp;
- attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
- temp = REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
- if (temp == NULL)
- return XML_ERROR_NO_MEMORY;
- atts = temp;
- if (n > oldAttsSize)
- XmlGetAttributes(enc, attStr, n, atts);
- }
- appAtts = (const XML_Char **)atts;
- for (i = 0; i < n; i++) {
- /* add the name and value to the attribute list */
- ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
- atts[i].name
- + XmlNameLength(enc, atts[i].name));
- if (!attId)
- return XML_ERROR_NO_MEMORY;
- /* detect duplicate attributes */
- if ((attId->name)[-1]) {
- if (enc == encoding)
- eventPtr = atts[i].name;
- return XML_ERROR_DUPLICATE_ATTRIBUTE;
- }
- (attId->name)[-1] = 1;
- appAtts[attIndex++] = attId->name;
- if (!atts[i].normalized) {
- enum XML_Error result;
- XML_Bool isCdata = XML_TRUE;
-
- /* figure out whether declared as other than CDATA */
- if (attId->maybeTokenized) {
- int j;
- for (j = 0; j < nDefaultAtts; j++) {
- if (attId == elementType->defaultAtts[j].id) {
- isCdata = elementType->defaultAtts[j].isCdata;
- break;
- }
- }
- }
-
- /* normalize the attribute value */
- result = storeAttributeValue(parser, enc, isCdata,
- atts[i].valuePtr, atts[i].valueEnd,
- &tempPool);
- if (result)
- return result;
- if (tagNamePtr) {
- appAtts[attIndex] = poolStart(&tempPool);
- poolFinish(&tempPool);
- }
- else
- poolDiscard(&tempPool);
- }
- else if (tagNamePtr) {
- /* the value did not need normalizing */
- appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr,
- atts[i].valueEnd);
- if (appAtts[attIndex] == 0)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- }
- /* handle prefixed attribute names */
- if (attId->prefix && tagNamePtr) {
- if (attId->xmlns) {
- /* deal with namespace declarations here */
- if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex],
- bindingsPtr))
- return XML_ERROR_NO_MEMORY;
- --attIndex;
- }
- else {
- /* deal with other prefixed names later */
- attIndex++;
- nPrefixes++;
- (attId->name)[-1] = 2;
- }
- }
- else
- attIndex++;
- }
- if (tagNamePtr) {
- int j;
- nSpecifiedAtts = attIndex;
- if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
- for (i = 0; i < attIndex; i += 2)
- if (appAtts[i] == elementType->idAtt->name) {
- idAttIndex = i;
- break;
- }
- }
- else
- idAttIndex = -1;
- /* do attribute defaulting */
- for (j = 0; j < nDefaultAtts; j++) {
- const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
- if (!(da->id->name)[-1] && da->value) {
- if (da->id->prefix) {
- if (da->id->xmlns) {
- if (!addBinding(parser, da->id->prefix, da->id, da->value,
- bindingsPtr))
- return XML_ERROR_NO_MEMORY;
- }
- else {
- (da->id->name)[-1] = 2;
- nPrefixes++;
- appAtts[attIndex++] = da->id->name;
- appAtts[attIndex++] = da->value;
- }
- }
- else {
- (da->id->name)[-1] = 1;
- appAtts[attIndex++] = da->id->name;
- appAtts[attIndex++] = da->value;
- }
- }
- }
- appAtts[attIndex] = 0;
- }
- i = 0;
- if (nPrefixes) {
- /* expand prefixed attribute names */
- for (; i < attIndex; i += 2) {
- if (appAtts[i][-1] == 2) {
- ATTRIBUTE_ID *id;
- ((XML_Char *)(appAtts[i]))[-1] = 0;
- id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
- if (id->prefix->binding) {
- int j;
- const BINDING *b = id->prefix->binding;
- const XML_Char *s = appAtts[i];
- for (j = 0; j < b->uriLen; j++) {
- if (!poolAppendChar(&tempPool, b->uri[j]))
- return XML_ERROR_NO_MEMORY;
- }
- while (*s++ != XML_T(':'))
- ;
- do {
- if (!poolAppendChar(&tempPool, *s))
- return XML_ERROR_NO_MEMORY;
- } while (*s++);
- if (ns_triplets) {
- tempPool.ptr[-1] = namespaceSeparator;
- s = b->prefix->name;
- do {
- if (!poolAppendChar(&tempPool, *s))
- return XML_ERROR_NO_MEMORY;
- } while (*s++);
- }
-
- appAtts[i] = poolStart(&tempPool);
- poolFinish(&tempPool);
- }
- if (!--nPrefixes)
- break;
- }
- else
- ((XML_Char *)(appAtts[i]))[-1] = 0;
- }
- }
- /* clear the flags that say whether attributes were specified */
- for (; i < attIndex; i += 2)
- ((XML_Char *)(appAtts[i]))[-1] = 0;
- if (!tagNamePtr)
- return XML_ERROR_NONE;
- for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
- binding->attId->name[-1] = 0;
- /* expand the element type name */
- if (elementType->prefix) {
- binding = elementType->prefix->binding;
- if (!binding)
- return XML_ERROR_NONE;
- localPart = tagNamePtr->str;
- while (*localPart++ != XML_T(':'))
- ;
- }
- else if (dtd.defaultPrefix.binding) {
- binding = dtd.defaultPrefix.binding;
- localPart = tagNamePtr->str;
- }
- else
- return XML_ERROR_NONE;
- prefixLen = 0;
- if (ns && ns_triplets && binding->prefix->name) {
- for (; binding->prefix->name[prefixLen++];)
- ;
- }
- tagNamePtr->localPart = localPart;
- tagNamePtr->uriLen = binding->uriLen;
- tagNamePtr->prefix = binding->prefix->name;
- tagNamePtr->prefixLen = prefixLen;
- for (i = 0; localPart[i++];)
- ;
- n = i + binding->uriLen + prefixLen;
- if (n > binding->uriAlloc) {
- TAG *p;
- uri = MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
- if (!uri)
- return XML_ERROR_NO_MEMORY;
- binding->uriAlloc = n + EXPAND_SPARE;
- memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
- for (p = tagStack; p; p = p->parent)
- if (p->name.str == binding->uri)
- p->name.str = uri;
- FREE(binding->uri);
- binding->uri = uri;
- }
- uri = binding->uri + binding->uriLen;
- memcpy(uri, localPart, i * sizeof(XML_Char));
- if (prefixLen) {
- uri = uri + (i - 1);
- if (namespaceSeparator) { *(uri) = namespaceSeparator; }
- memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
- }
- tagNamePtr->str = binding->uri;
- return XML_ERROR_NONE;
-}
-
-static int FASTCALL
-addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
- const XML_Char *uri, BINDING **bindingsPtr)
-{
- BINDING *b;
- int len;
- for (len = 0; uri[len]; len++)
- ;
- if (namespaceSeparator)
- len++;
- if (freeBindingList) {
- b = freeBindingList;
- if (len > b->uriAlloc) {
- XML_Char *temp = REALLOC(b->uri,
- sizeof(XML_Char) * (len + EXPAND_SPARE));
- if (temp == NULL)
- return 0;
- b->uri = temp;
- b->uriAlloc = len + EXPAND_SPARE;
- }
- freeBindingList = b->nextTagBinding;
- }
- else {
- b = MALLOC(sizeof(BINDING));
- if (!b)
- return 0;
- b->uri = MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
- if (!b->uri) {
- FREE(b);
- return 0;
- }
- b->uriAlloc = len + EXPAND_SPARE;
- }
- b->uriLen = len;
- memcpy(b->uri, uri, len * sizeof(XML_Char));
- if (namespaceSeparator)
- b->uri[len - 1] = namespaceSeparator;
- b->prefix = prefix;
- b->attId = attId;
- b->prevPrefixBinding = prefix->binding;
- if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
- prefix->binding = NULL;
- else
- prefix->binding = b;
- b->nextTagBinding = *bindingsPtr;
- *bindingsPtr = b;
- if (startNamespaceDeclHandler)
- startNamespaceDeclHandler(handlerArg, prefix->name,
- prefix->binding ? uri : 0);
- return 1;
-}
-
-/* The idea here is to avoid using stack for each CDATA section when
- the whole file is parsed with one call.
-*/
-static enum XML_Error FASTCALL
-cdataSectionProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- enum XML_Error result = doCdataSection(parser, encoding, &start,
- end, endPtr);
- if (start) {
- if (parentParser) { /* we are parsing an external entity */
- processor = externalEntityContentProcessor;
- return externalEntityContentProcessor(parser, start, end, endPtr);
- }
- else {
- processor = contentProcessor;
- return contentProcessor(parser, start, end, endPtr);
- }
- }
- return result;
-}
-
-/* startPtr gets set to non-null is the section is closed, and to null if
- the section is not yet closed.
-*/
-static enum XML_Error FASTCALL
-doCdataSection(XML_Parser parser,
- const ENCODING *enc,
- const char **startPtr,
- const char *end,
- const char **nextPtr)
-{
- const char *s = *startPtr;
- const char **eventPP;
- const char **eventEndPP;
- if (enc == encoding) {
- eventPP = &eventPtr;
- *eventPP = s;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
- }
- *eventPP = s;
- *startPtr = NULL;
- for (;;) {
- const char *next;
- int tok = XmlCdataSectionTok(enc, s, end, &next);
- *eventEndPP = next;
- switch (tok) {
- case XML_TOK_CDATA_SECT_CLOSE:
- if (endCdataSectionHandler)
- endCdataSectionHandler(handlerArg);
-#if 0
- /* see comment under XML_TOK_CDATA_SECT_OPEN */
- else if (characterDataHandler)
- characterDataHandler(handlerArg, dataBuf, 0);
-#endif
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- *startPtr = next;
- return XML_ERROR_NONE;
- case XML_TOK_DATA_NEWLINE:
- if (characterDataHandler) {
- XML_Char c = 0xA;
- characterDataHandler(handlerArg, &c, 1);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- case XML_TOK_DATA_CHARS:
- if (characterDataHandler) {
- if (MUST_CONVERT(enc, s)) {
- for (;;) {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
- *eventEndPP = next;
- characterDataHandler(handlerArg, dataBuf,
- dataPtr - (ICHAR *)dataBuf);
- if (s == next)
- break;
- *eventPP = s;
- }
- }
- else
- characterDataHandler(handlerArg,
- (XML_Char *)s,
- (XML_Char *)next - (XML_Char *)s);
- }
- else if (defaultHandler)
- reportDefault(parser, enc, s, next);
- break;
- case XML_TOK_INVALID:
- *eventPP = next;
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (nextPtr) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_PARTIAL:
- case XML_TOK_NONE:
- if (nextPtr) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_UNCLOSED_CDATA_SECTION;
- default:
- *eventPP = next;
- return XML_ERROR_UNEXPECTED_STATE;
- }
- *eventPP = s = next;
- }
- /* not reached */
-}
-
-#ifdef XML_DTD
-
-/* The idea here is to avoid using stack for each IGNORE section when
- the whole file is parsed with one call.
-*/
-static enum XML_Error FASTCALL
-ignoreSectionProcessor(XML_Parser parser,
- const char *start,
- const char *end,
- const char **endPtr)
-{
- enum XML_Error result = doIgnoreSection(parser, encoding, &start,
- end, endPtr);
- if (start) {
- processor = prologProcessor;
- return prologProcessor(parser, start, end, endPtr);
- }
- return result;
-}
-
-/* startPtr gets set to non-null is the section is closed, and to null
- if the section is not yet closed.
-*/
-static enum XML_Error FASTCALL
-doIgnoreSection(XML_Parser parser,
- const ENCODING *enc,
- const char **startPtr,
- const char *end,
- const char **nextPtr)
-{
- const char *next;
- int tok;
- const char *s = *startPtr;
- const char **eventPP;
- const char **eventEndPP;
- if (enc == encoding) {
- eventPP = &eventPtr;
- *eventPP = s;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
- }
- *eventPP = s;
- *startPtr = NULL;
- tok = XmlIgnoreSectionTok(enc, s, end, &next);
- *eventEndPP = next;
- switch (tok) {
- case XML_TOK_IGNORE_SECT:
- if (defaultHandler)
- reportDefault(parser, enc, s, next);
- *startPtr = next;
- return XML_ERROR_NONE;
- case XML_TOK_INVALID:
- *eventPP = next;
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (nextPtr) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_PARTIAL:
- case XML_TOK_NONE:
- if (nextPtr) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
- default:
- *eventPP = next;
- return XML_ERROR_UNEXPECTED_STATE;
- }
- /* not reached */
-}
-
-#endif /* XML_DTD */
-
-static enum XML_Error FASTCALL
-initializeEncoding(XML_Parser parser)
-{
- const char *s;
-#ifdef XML_UNICODE
- char encodingBuf[128];
- if (!protocolEncodingName)
- s = NULL;
- else {
- int i;
- for (i = 0; protocolEncodingName[i]; i++) {
- if (i == sizeof(encodingBuf) - 1
- || (protocolEncodingName[i] & ~0x7f) != 0) {
- encodingBuf[0] = '\0';
- break;
- }
- encodingBuf[i] = (char)protocolEncodingName[i];
- }
- encodingBuf[i] = '\0';
- s = encodingBuf;
- }
-#else
- s = protocolEncodingName;
-#endif
- if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
- return XML_ERROR_NONE;
- return handleUnknownEncoding(parser, protocolEncodingName);
-}
-
-static enum XML_Error FASTCALL
-processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
- const char *s, const char *next)
-{
- const char *encodingName = NULL;
- const XML_Char *storedEncName = NULL;
- const ENCODING *newEncoding = NULL;
- const char *version = NULL;
- const char *versionend;
- const XML_Char *storedversion = NULL;
- int standalone = -1;
- if (!(ns
- ? XmlParseXmlDeclNS
- : XmlParseXmlDecl)(isGeneralTextEntity,
- encoding,
- s,
- next,
- &eventPtr,
- &version,
- &versionend,
- &encodingName,
- &newEncoding,
- &standalone))
- return XML_ERROR_SYNTAX;
- if (!isGeneralTextEntity && standalone == 1) {
- dtd.standalone = XML_TRUE;
-#ifdef XML_DTD
- if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
- paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
-#endif /* XML_DTD */
- }
- if (xmlDeclHandler) {
- if (encodingName != NULL) {
- storedEncName = poolStoreString(&temp2Pool,
- encoding,
- encodingName,
- encodingName
- + XmlNameLength(encoding, encodingName));
- if (!storedEncName)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&temp2Pool);
- }
- if (version) {
- storedversion = poolStoreString(&temp2Pool,
- encoding,
- version,
- versionend - encoding->minBytesPerChar);
- if (!storedversion)
- return XML_ERROR_NO_MEMORY;
- }
- xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
- }
- else if (defaultHandler)
- reportDefault(parser, encoding, s, next);
- if (protocolEncodingName == NULL) {
- if (newEncoding) {
- if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
- eventPtr = encodingName;
- return XML_ERROR_INCORRECT_ENCODING;
- }
- encoding = newEncoding;
- }
- else if (encodingName) {
- enum XML_Error result;
- if (!storedEncName) {
- storedEncName = poolStoreString(
- &temp2Pool, encoding, encodingName,
- encodingName + XmlNameLength(encoding, encodingName));
- if (!storedEncName)
- return XML_ERROR_NO_MEMORY;
- }
- result = handleUnknownEncoding(parser, storedEncName);
- poolClear(&temp2Pool);
- if (result == XML_ERROR_UNKNOWN_ENCODING)
- eventPtr = encodingName;
- return result;
- }
- }
-
- if (storedEncName || storedversion)
- poolClear(&temp2Pool);
-
- return XML_ERROR_NONE;
-}
-
-static enum XML_Error FASTCALL
-handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
-{
- if (unknownEncodingHandler) {
- XML_Encoding info;
- int i;
- for (i = 0; i < 256; i++)
- info.map[i] = -1;
- info.convert = NULL;
- info.data = NULL;
- info.release = NULL;
- if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName,
- &info)) {
- ENCODING *enc;
- unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
- if (!unknownEncodingMem) {
- if (info.release)
- info.release(info.data);
- return XML_ERROR_NO_MEMORY;
- }
- enc = (ns
- ? XmlInitUnknownEncodingNS
- : XmlInitUnknownEncoding)(unknownEncodingMem,
- info.map,
- info.convert,
- info.data);
- if (enc) {
- unknownEncodingData = info.data;
- unknownEncodingRelease = info.release;
- encoding = enc;
- return XML_ERROR_NONE;
- }
- }
- if (info.release != NULL)
- info.release(info.data);
- }
- return XML_ERROR_UNKNOWN_ENCODING;
-}
-
-static enum XML_Error FASTCALL
-prologInitProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- enum XML_Error result = initializeEncoding(parser);
- if (result != XML_ERROR_NONE)
- return result;
- processor = prologProcessor;
- return prologProcessor(parser, s, end, nextPtr);
-}
-
-#ifdef XML_DTD
-
-static enum XML_Error FASTCALL
-externalParEntInitProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- enum XML_Error result = initializeEncoding(parser);
- if (result != XML_ERROR_NONE)
- return result;
-
- /* we know now that XML_Parse(Buffer) has been called,
- so we consider the external parameter entity read */
- dtd.paramEntityRead = XML_TRUE;
-
- if (prologState.inEntityValue) {
- processor = entityValueInitProcessor;
- return entityValueInitProcessor(parser, s, end, nextPtr);
- }
- else {
- processor = externalParEntProcessor;
- return externalParEntProcessor(parser, s, end, nextPtr);
- }
-}
-
-static enum XML_Error FASTCALL
-entityValueInitProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- const char *start = s;
- const char *next = s;
- int tok;
-
- for (;;) {
- tok = XmlPrologTok(encoding, start, end, &next);
- if (tok <= 0) {
- if (nextPtr != 0 && tok != XML_TOK_INVALID) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- switch (tok) {
- case XML_TOK_INVALID:
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_NONE: /* start == end */
- default:
- break;
- }
- return storeEntityValue(parser, encoding, s, end);
- }
- else if (tok == XML_TOK_XML_DECL) {
- enum XML_Error result = processXmlDecl(parser, 0, start, next);
- if (result != XML_ERROR_NONE)
- return result;
- if (nextPtr) *nextPtr = next;
- /* stop scanning for text declaration - we found one */
- processor = entityValueProcessor;
- return entityValueProcessor(parser, next, end, nextPtr);
- }
- /* If we are at the end of the buffer, this would cause XmlPrologTok to
- return XML_TOK_NONE on the next call, which would then cause the
- function to exit with *nextPtr set to s - that is what we want for other
- tokens, but not for the BOM - we would rather like to skip it;
- then, when this routine is entered the next time, XmlPrologTok will
- return XML_TOK_INVALID, since the BOM is still in the buffer
- */
- else if (tok == XML_TOK_BOM && next == end && nextPtr) {
- *nextPtr = next;
- return XML_ERROR_NONE;
- }
- start = next;
- }
-}
-
-static enum XML_Error FASTCALL
-externalParEntProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- const char *start = s;
- const char *next = s;
- int tok;
-
- tok = XmlPrologTok(encoding, start, end, &next);
- if (tok <= 0) {
- if (nextPtr != 0 && tok != XML_TOK_INVALID) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- switch (tok) {
- case XML_TOK_INVALID:
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_NONE: /* start == end */
- default:
- break;
- }
- }
- /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
- However, when parsing an external subset, doProlog will not accept a BOM
- as valid, and report a syntax error, so we have to skip the BOM
- */
- else if (tok == XML_TOK_BOM) {
- s = next;
- tok = XmlPrologTok(encoding, s, end, &next);
- }
-
- processor = prologProcessor;
- return doProlog(parser, encoding, s, end, tok, next, nextPtr);
-}
-
-static enum XML_Error FASTCALL
-entityValueProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- const char *start = s;
- const char *next = s;
- const ENCODING *enc = encoding;
- int tok;
-
- for (;;) {
- tok = XmlPrologTok(enc, start, end, &next);
- if (tok <= 0) {
- if (nextPtr != 0 && tok != XML_TOK_INVALID) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- switch (tok) {
- case XML_TOK_INVALID:
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_NONE: /* start == end */
- default:
- break;
- }
- return storeEntityValue(parser, enc, s, end);
- }
- start = next;
- }
-}
-
-#endif /* XML_DTD */
-
-static enum XML_Error FASTCALL
-prologProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- const char *next = s;
- int tok = XmlPrologTok(encoding, s, end, &next);
- return doProlog(parser, encoding, s, end, tok, next, nextPtr);
-}
-
-static enum XML_Error FASTCALL
-doProlog(XML_Parser parser,
- const ENCODING *enc,
- const char *s,
- const char *end,
- int tok,
- const char *next,
- const char **nextPtr)
-{
-#ifdef XML_DTD
- static const XML_Char externalSubsetName[] = { '#' , '\0' };
-#endif /* XML_DTD */
- static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', '\0' };
- static const XML_Char atypeID[] = { 'I', 'D', '\0' };
- static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', '\0' };
- static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', '\0' };
- static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', '\0' };
- static const XML_Char atypeENTITIES[] =
- { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', '\0' };
- static const XML_Char atypeNMTOKEN[] = {
- 'N', 'M', 'T', 'O', 'K', 'E', 'N', '\0' };
- static const XML_Char atypeNMTOKENS[] = {
- 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', '\0' };
- static const XML_Char notationPrefix[] = {
- 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', '\0' };
- static const XML_Char enumValueSep[] = { '|', '\0' };
- static const XML_Char enumValueStart[] = { '(', '\0' };
-
- const char **eventPP;
- const char **eventEndPP;
- enum XML_Content_Quant quant;
-
- if (enc == encoding) {
- eventPP = &eventPtr;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
- }
- for (;;) {
- int role;
- XML_Bool handleDefault = XML_TRUE;
- *eventPP = s;
- *eventEndPP = next;
- if (tok <= 0) {
- if (nextPtr != 0 && tok != XML_TOK_INVALID) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- switch (tok) {
- case XML_TOK_INVALID:
- *eventPP = next;
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_NONE:
-#ifdef XML_DTD
- if (enc != encoding)
- return XML_ERROR_NONE;
- if (isParamEntity) {
- if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
- == XML_ROLE_ERROR)
- return XML_ERROR_SYNTAX;
- return XML_ERROR_NONE;
- }
-#endif /* XML_DTD */
- return XML_ERROR_NO_ELEMENTS;
- default:
- tok = -tok;
- next = end;
- break;
- }
- }
- role = XmlTokenRole(&prologState, tok, s, next, enc);
- switch (role) {
- case XML_ROLE_XML_DECL:
- {
- enum XML_Error result = processXmlDecl(parser, 0, s, next);
- if (result != XML_ERROR_NONE)
- return result;
- enc = encoding;
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_DOCTYPE_NAME:
- if (startDoctypeDeclHandler) {
- doctypeName = poolStoreString(&tempPool, enc, s, next);
- if (!doctypeName)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- doctypePubid = NULL;
- handleDefault = XML_FALSE;
- }
- doctypeSysid = NULL; /* always initialize to NULL */
- break;
- case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
- if (startDoctypeDeclHandler) {
- startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
- doctypePubid, 1);
- doctypeName = NULL;
- poolClear(&tempPool);
- handleDefault = XML_FALSE;
- }
- break;
-#ifdef XML_DTD
- case XML_ROLE_TEXT_DECL:
- {
- enum XML_Error result = processXmlDecl(parser, 1, s, next);
- if (result != XML_ERROR_NONE)
- return result;
- enc = encoding;
- handleDefault = XML_FALSE;
- }
- break;
-#endif /* XML_DTD */
- case XML_ROLE_DOCTYPE_PUBLIC_ID:
-#ifdef XML_DTD
- useForeignDTD = XML_FALSE;
-#endif /* XML_DTD */
- dtd.hasParamEntityRefs = XML_TRUE;
- if (startDoctypeDeclHandler) {
- doctypePubid = poolStoreString(&tempPool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!doctypePubid)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- handleDefault = XML_FALSE;
- }
-#ifdef XML_DTD
- declEntity = (ENTITY *)lookup(&dtd.paramEntities,
- externalSubsetName,
- sizeof(ENTITY));
- if (!declEntity)
- return XML_ERROR_NO_MEMORY;
-#endif /* XML_DTD */
- /* fall through */
- case XML_ROLE_ENTITY_PUBLIC_ID:
- if (!XmlIsPublicId(enc, s, next, eventPP))
- return XML_ERROR_SYNTAX;
- if (dtd.keepProcessing && declEntity) {
- XML_Char *tem = poolStoreString(&dtd.pool,
- enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!tem)
- return XML_ERROR_NO_MEMORY;
- normalizePublicId(tem);
- declEntity->publicId = tem;
- poolFinish(&dtd.pool);
- if (entityDeclHandler)
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_DOCTYPE_CLOSE:
- if (doctypeName) {
- startDoctypeDeclHandler(handlerArg, doctypeName,
- doctypeSysid, doctypePubid, 0);
- poolClear(&tempPool);
- handleDefault = XML_FALSE;
- }
- /* doctypeSysid will be non-NULL in the case of a previous
- XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
- was not set, indicating an external subset
- */
-#ifdef XML_DTD
- if (doctypeSysid || useForeignDTD) {
- dtd.hasParamEntityRefs = XML_TRUE; /* when docTypeSysid == NULL */
- if (paramEntityParsing && externalEntityRefHandler) {
- ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
- externalSubsetName,
- sizeof(ENTITY));
- if (!entity)
- return XML_ERROR_NO_MEMORY;
- if (useForeignDTD)
- entity->base = curBase;
- dtd.paramEntityRead = XML_FALSE;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId))
- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- if (dtd.paramEntityRead &&
- !dtd.standalone &&
- notStandaloneHandler &&
- !notStandaloneHandler(handlerArg))
- return XML_ERROR_NOT_STANDALONE;
- /* end of DTD - no need to update dtd.keepProcessing */
- }
- useForeignDTD = XML_FALSE;
- }
-#endif /* XML_DTD */
- if (endDoctypeDeclHandler) {
- endDoctypeDeclHandler(handlerArg);
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_INSTANCE_START:
-#ifdef XML_DTD
- /* if there is no DOCTYPE declaration then now is the
- last chance to read the foreign DTD
- */
- if (useForeignDTD) {
- dtd.hasParamEntityRefs = XML_TRUE;
- if (paramEntityParsing && externalEntityRefHandler) {
- ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
- externalSubsetName,
- sizeof(ENTITY));
- if (!entity)
- return XML_ERROR_NO_MEMORY;
- entity->base = curBase;
- dtd.paramEntityRead = XML_FALSE;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId))
- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- if (dtd.paramEntityRead &&
- !dtd.standalone &&
- notStandaloneHandler &&
- !notStandaloneHandler(handlerArg))
- return XML_ERROR_NOT_STANDALONE;
- /* end of DTD - no need to update dtd.keepProcessing */
- }
- }
-#endif /* XML_DTD */
- processor = contentProcessor;
- return contentProcessor(parser, s, end, nextPtr);
- case XML_ROLE_ATTLIST_ELEMENT_NAME:
- declElementType = getElementType(parser, enc, s, next);
- if (!declElementType)
- return XML_ERROR_NO_MEMORY;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_NAME:
- declAttributeId = getAttributeId(parser, enc, s, next);
- if (!declAttributeId)
- return XML_ERROR_NO_MEMORY;
- declAttributeIsCdata = XML_FALSE;
- declAttributeType = NULL;
- declAttributeIsId = XML_FALSE;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
- declAttributeIsCdata = XML_TRUE;
- declAttributeType = atypeCDATA;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_ID:
- declAttributeIsId = XML_TRUE;
- declAttributeType = atypeID;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
- declAttributeType = atypeIDREF;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
- declAttributeType = atypeIDREFS;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
- declAttributeType = atypeENTITY;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
- declAttributeType = atypeENTITIES;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
- declAttributeType = atypeNMTOKEN;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
- declAttributeType = atypeNMTOKENS;
- checkAttListDeclHandler:
- if (dtd.keepProcessing && attlistDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
- case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
- if (dtd.keepProcessing && attlistDeclHandler) {
- const XML_Char *prefix;
- if (declAttributeType) {
- prefix = enumValueSep;
- }
- else {
- prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
- ? notationPrefix
- : enumValueStart);
- }
- if (!poolAppendString(&tempPool, prefix))
- return XML_ERROR_NO_MEMORY;
- if (!poolAppend(&tempPool, enc, s, next))
- return XML_ERROR_NO_MEMORY;
- declAttributeType = tempPool.start;
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
- case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
- if (dtd.keepProcessing) {
- if (!defineAttribute(declElementType, declAttributeId,
- declAttributeIsCdata, declAttributeIsId, 0,
- parser))
- return XML_ERROR_NO_MEMORY;
- if (attlistDeclHandler && declAttributeType) {
- if (*declAttributeType == XML_T('(')
- || (*declAttributeType == XML_T('N')
- && declAttributeType[1] == XML_T('O'))) {
- /* Enumerated or Notation type */
- if (!poolAppendChar(&tempPool, XML_T(')'))
- || !poolAppendChar(&tempPool, XML_T('\0')))
- return XML_ERROR_NO_MEMORY;
- declAttributeType = tempPool.start;
- poolFinish(&tempPool);
- }
- *eventEndPP = s;
- attlistDeclHandler(handlerArg, declElementType->name,
- declAttributeId->name, declAttributeType,
- 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
- poolClear(&tempPool);
- handleDefault = XML_FALSE;
- }
- }
- break;
- case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
- case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
- if (dtd.keepProcessing) {
- const XML_Char *attVal;
- enum XML_Error result
- = storeAttributeValue(parser, enc, declAttributeIsCdata,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar,
- &dtd.pool);
- if (result)
- return result;
- attVal = poolStart(&dtd.pool);
- poolFinish(&dtd.pool);
- /* ID attributes aren't allowed to have a default */
- if (!defineAttribute(declElementType, declAttributeId,
- declAttributeIsCdata, XML_FALSE, attVal, parser))
- return XML_ERROR_NO_MEMORY;
- if (attlistDeclHandler && declAttributeType) {
- if (*declAttributeType == XML_T('(')
- || (*declAttributeType == XML_T('N')
- && declAttributeType[1] == XML_T('O'))) {
- /* Enumerated or Notation type */
- if (!poolAppendChar(&tempPool, XML_T(')'))
- || !poolAppendChar(&tempPool, XML_T('\0')))
- return XML_ERROR_NO_MEMORY;
- declAttributeType = tempPool.start;
- poolFinish(&tempPool);
- }
- *eventEndPP = s;
- attlistDeclHandler(handlerArg, declElementType->name,
- declAttributeId->name, declAttributeType,
- attVal,
- role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
- poolClear(&tempPool);
- handleDefault = XML_FALSE;
- }
- }
- break;
- case XML_ROLE_ENTITY_VALUE:
- if (dtd.keepProcessing) {
- enum XML_Error result = storeEntityValue(parser, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (declEntity) {
- declEntity->textPtr = poolStart(&dtd.entityValuePool);
- declEntity->textLen = poolLength(&dtd.entityValuePool);
- poolFinish(&dtd.entityValuePool);
- if (entityDeclHandler) {
- *eventEndPP = s;
- entityDeclHandler(handlerArg,
- declEntity->name,
- declEntity->is_param,
- declEntity->textPtr,
- declEntity->textLen,
- curBase, 0, 0, 0);
- handleDefault = XML_FALSE;
- }
- }
- else
- poolDiscard(&dtd.entityValuePool);
- if (result != XML_ERROR_NONE)
- return result;
- }
- break;
- case XML_ROLE_DOCTYPE_SYSTEM_ID:
-#ifdef XML_DTD
- useForeignDTD = XML_FALSE;
-#endif /* XML_DTD */
- dtd.hasParamEntityRefs = XML_TRUE;
- if (startDoctypeDeclHandler) {
- doctypeSysid = poolStoreString(&tempPool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (doctypeSysid == NULL)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- handleDefault = XML_FALSE;
- }
-#ifdef XML_DTD
- else
- /* use externalSubsetName to make doctypeSysid non-NULL
- for the case where no startDoctypeDeclHandler is set */
- doctypeSysid = externalSubsetName;
-#endif /* XML_DTD */
- if (!dtd.standalone
-#ifdef XML_DTD
- && !paramEntityParsing
-#endif /* XML_DTD */
- && notStandaloneHandler
- && !notStandaloneHandler(handlerArg))
- return XML_ERROR_NOT_STANDALONE;
-#ifndef XML_DTD
- break;
-#else /* XML_DTD */
- if (!declEntity) {
- declEntity = (ENTITY *)lookup(&dtd.paramEntities,
- externalSubsetName,
- sizeof(ENTITY));
- if (!declEntity)
- return XML_ERROR_NO_MEMORY;
- declEntity->publicId = NULL;
- }
- /* fall through */
-#endif /* XML_DTD */
- case XML_ROLE_ENTITY_SYSTEM_ID:
- if (dtd.keepProcessing && declEntity) {
- declEntity->systemId = poolStoreString(&dtd.pool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!declEntity->systemId)
- return XML_ERROR_NO_MEMORY;
- declEntity->base = curBase;
- poolFinish(&dtd.pool);
- if (entityDeclHandler)
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_ENTITY_COMPLETE:
- if (dtd.keepProcessing && declEntity && entityDeclHandler) {
- *eventEndPP = s;
- entityDeclHandler(handlerArg,
- declEntity->name,
- declEntity->is_param,
- 0,0,
- declEntity->base,
- declEntity->systemId,
- declEntity->publicId,
- 0);
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_ENTITY_NOTATION_NAME:
- if (dtd.keepProcessing && declEntity) {
- declEntity->notation = poolStoreString(&dtd.pool, enc, s, next);
- if (!declEntity->notation)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&dtd.pool);
- if (unparsedEntityDeclHandler) {
- *eventEndPP = s;
- unparsedEntityDeclHandler(handlerArg,
- declEntity->name,
- declEntity->base,
- declEntity->systemId,
- declEntity->publicId,
- declEntity->notation);
- handleDefault = XML_FALSE;
- }
- else if (entityDeclHandler) {
- *eventEndPP = s;
- entityDeclHandler(handlerArg,
- declEntity->name,
- 0,0,0,
- declEntity->base,
- declEntity->systemId,
- declEntity->publicId,
- declEntity->notation);
- handleDefault = XML_FALSE;
- }
- }
- break;
- case XML_ROLE_GENERAL_ENTITY_NAME:
- {
- if (XmlPredefinedEntityName(enc, s, next)) {
- declEntity = NULL;
- break;
- }
- if (dtd.keepProcessing) {
- const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
- if (!name)
- return XML_ERROR_NO_MEMORY;
- declEntity = (ENTITY *)lookup(&dtd.generalEntities, name,
- sizeof(ENTITY));
- if (!declEntity)
- return XML_ERROR_NO_MEMORY;
- if (declEntity->name != name) {
- poolDiscard(&dtd.pool);
- declEntity = NULL;
- }
- else {
- poolFinish(&dtd.pool);
- declEntity->publicId = NULL;
- declEntity->is_param = XML_FALSE;
- /* if we have a parent parser or are reading an internal parameter
- entity, then the entity declaration is not considered "internal"
- */
- declEntity->is_internal = !(parentParser || openInternalEntities);
- if (entityDeclHandler)
- handleDefault = XML_FALSE;
- }
- }
- else {
- poolDiscard(&dtd.pool);
- declEntity = NULL;
- }
- }
- break;
- case XML_ROLE_PARAM_ENTITY_NAME:
-#ifdef XML_DTD
- if (dtd.keepProcessing) {
- const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
- if (!name)
- return XML_ERROR_NO_MEMORY;
- declEntity = (ENTITY *)lookup(&dtd.paramEntities,
- name, sizeof(ENTITY));
- if (!declEntity)
- return XML_ERROR_NO_MEMORY;
- if (declEntity->name != name) {
- poolDiscard(&dtd.pool);
- declEntity = NULL;
- }
- else {
- poolFinish(&dtd.pool);
- declEntity->publicId = NULL;
- declEntity->is_param = XML_TRUE;
- /* if we have a parent parser or are reading an internal parameter
- entity, then the entity declaration is not considered "internal"
- */
- declEntity->is_internal = !(parentParser || openInternalEntities);
- if (entityDeclHandler)
- handleDefault = XML_FALSE;
- }
- }
- else {
- poolDiscard(&dtd.pool);
- declEntity = NULL;
- }
-#else /* not XML_DTD */
- declEntity = NULL;
-#endif /* XML_DTD */
- break;
- case XML_ROLE_NOTATION_NAME:
- declNotationPublicId = NULL;
- declNotationName = NULL;
- if (notationDeclHandler) {
- declNotationName = poolStoreString(&tempPool, enc, s, next);
- if (!declNotationName)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_NOTATION_PUBLIC_ID:
- if (!XmlIsPublicId(enc, s, next, eventPP))
- return XML_ERROR_SYNTAX;
- if (declNotationName) { /* means notationDeclHandler != NULL */
- XML_Char *tem = poolStoreString(&tempPool,
- enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!tem)
- return XML_ERROR_NO_MEMORY;
- normalizePublicId(tem);
- declNotationPublicId = tem;
- poolFinish(&tempPool);
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_NOTATION_SYSTEM_ID:
- if (declNotationName && notationDeclHandler) {
- const XML_Char *systemId
- = poolStoreString(&tempPool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!systemId)
- return XML_ERROR_NO_MEMORY;
- *eventEndPP = s;
- notationDeclHandler(handlerArg,
- declNotationName,
- curBase,
- systemId,
- declNotationPublicId);
- handleDefault = XML_FALSE;
- }
- poolClear(&tempPool);
- break;
- case XML_ROLE_NOTATION_NO_SYSTEM_ID:
- if (declNotationPublicId && notationDeclHandler) {
- *eventEndPP = s;
- notationDeclHandler(handlerArg,
- declNotationName,
- curBase,
- 0,
- declNotationPublicId);
- handleDefault = XML_FALSE;
- }
- poolClear(&tempPool);
- break;
- case XML_ROLE_ERROR:
- switch (tok) {
- case XML_TOK_PARAM_ENTITY_REF:
- return XML_ERROR_PARAM_ENTITY_REF;
- case XML_TOK_XML_DECL:
- return XML_ERROR_MISPLACED_XML_PI;
- default:
- return XML_ERROR_SYNTAX;
- }
-#ifdef XML_DTD
- case XML_ROLE_IGNORE_SECT:
- {
- enum XML_Error result;
- if (defaultHandler)
- reportDefault(parser, enc, s, next);
- handleDefault = XML_FALSE;
- result = doIgnoreSection(parser, enc, &next, end, nextPtr);
- if (!next) {
- processor = ignoreSectionProcessor;
- return result;
- }
- }
- break;
-#endif /* XML_DTD */
- case XML_ROLE_GROUP_OPEN:
- if (prologState.level >= groupSize) {
- if (groupSize) {
- char *temp = REALLOC(groupConnector, groupSize *= 2);
- if (temp == NULL)
- return XML_ERROR_NO_MEMORY;
- groupConnector = temp;
- if (dtd.scaffIndex) {
- int *temp = REALLOC(dtd.scaffIndex, groupSize * sizeof(int));
- if (temp == NULL)
- return XML_ERROR_NO_MEMORY;
- dtd.scaffIndex = temp;
- }
- }
- else {
- groupConnector = MALLOC(groupSize = 32);
- if (!groupConnector)
- return XML_ERROR_NO_MEMORY;
- }
- }
- groupConnector[prologState.level] = 0;
- if (dtd.in_eldecl) {
- int myindex = nextScaffoldPart(parser);
- if (myindex < 0)
- return XML_ERROR_NO_MEMORY;
- dtd.scaffIndex[dtd.scaffLevel] = myindex;
- dtd.scaffLevel++;
- dtd.scaffold[myindex].type = XML_CTYPE_SEQ;
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_GROUP_SEQUENCE:
- if (groupConnector[prologState.level] == '|')
- return XML_ERROR_SYNTAX;
- groupConnector[prologState.level] = ',';
- if (dtd.in_eldecl && elementDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_GROUP_CHOICE:
- if (groupConnector[prologState.level] == ',')
- return XML_ERROR_SYNTAX;
- if (dtd.in_eldecl
- && !groupConnector[prologState.level]
- && (dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type
- != XML_CTYPE_MIXED)
- ) {
- dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type
- = XML_CTYPE_CHOICE;
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- }
- groupConnector[prologState.level] = '|';
- break;
- case XML_ROLE_PARAM_ENTITY_REF:
-#ifdef XML_DTD
- case XML_ROLE_INNER_PARAM_ENTITY_REF:
- /* PE references in internal subset are
- not allowed within declarations */
- if (prologState.documentEntity &&
- role == XML_ROLE_INNER_PARAM_ENTITY_REF)
- return XML_ERROR_PARAM_ENTITY_REF;
- dtd.hasParamEntityRefs = XML_TRUE;
- if (!paramEntityParsing)
- dtd.keepProcessing = dtd.standalone;
- else {
- const XML_Char *name;
- ENTITY *entity;
- name = poolStoreString(&dtd.pool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name)
- return XML_ERROR_NO_MEMORY;
- entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
- poolDiscard(&dtd.pool);
- /* first, determine if a check for an existing declaration is needed;
- if yes, check that the entity exists, and that it is internal,
- otherwise call the skipped entity handler
- */
- if (prologState.documentEntity &&
- (dtd.standalone
- ? !openInternalEntities
- : !dtd.hasParamEntityRefs)) {
- if (!entity)
- return XML_ERROR_UNDEFINED_ENTITY;
- else if (!entity->is_internal)
- return XML_ERROR_ENTITY_DECLARED_IN_PE;
- }
- else if (!entity) {
- dtd.keepProcessing = dtd.standalone;
- /* cannot report skipped entities in declarations */
- if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
- skippedEntityHandler(handlerArg, name, 1);
- handleDefault = XML_FALSE;
- }
- break;
- }
- if (entity->open)
- return XML_ERROR_RECURSIVE_ENTITY_REF;
- if (entity->textPtr) {
- enum XML_Error result;
- result = processInternalParamEntity(parser, entity);
- if (result != XML_ERROR_NONE)
- return result;
- handleDefault = XML_FALSE;
- break;
- }
- if (externalEntityRefHandler) {
- dtd.paramEntityRead = XML_FALSE;
- entity->open = XML_TRUE;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId)) {
- entity->open = XML_FALSE;
- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- }
- entity->open = XML_FALSE;
- handleDefault = XML_FALSE;
- if (!dtd.paramEntityRead) {
- dtd.keepProcessing = dtd.standalone;
- break;
- }
- }
- else {
- dtd.keepProcessing = dtd.standalone;
- break;
- }
- }
-#endif /* XML_DTD */
- if (!dtd.standalone &&
- notStandaloneHandler &&
- !notStandaloneHandler(handlerArg))
- return XML_ERROR_NOT_STANDALONE;
- break;
-
- /* Element declaration stuff */
-
- case XML_ROLE_ELEMENT_NAME:
- if (elementDeclHandler) {
- declElementType = getElementType(parser, enc, s, next);
- if (!declElementType)
- return XML_ERROR_NO_MEMORY;
- dtd.scaffLevel = 0;
- dtd.scaffCount = 0;
- dtd.in_eldecl = XML_TRUE;
- handleDefault = XML_FALSE;
- }
- break;
-
- case XML_ROLE_CONTENT_ANY:
- case XML_ROLE_CONTENT_EMPTY:
- if (dtd.in_eldecl) {
- if (elementDeclHandler) {
- XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
- if (!content)
- return XML_ERROR_NO_MEMORY;
- content->quant = XML_CQUANT_NONE;
- content->name = NULL;
- content->numchildren = 0;
- content->children = NULL;
- content->type = ((role == XML_ROLE_CONTENT_ANY) ?
- XML_CTYPE_ANY :
- XML_CTYPE_EMPTY);
- *eventEndPP = s;
- elementDeclHandler(handlerArg, declElementType->name, content);
- handleDefault = XML_FALSE;
- }
- dtd.in_eldecl = XML_FALSE;
- }
- break;
-
- case XML_ROLE_CONTENT_PCDATA:
- if (dtd.in_eldecl) {
- dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type
- = XML_CTYPE_MIXED;
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- }
- break;
-
- case XML_ROLE_CONTENT_ELEMENT:
- quant = XML_CQUANT_NONE;
- goto elementContent;
- case XML_ROLE_CONTENT_ELEMENT_OPT:
- quant = XML_CQUANT_OPT;
- goto elementContent;
- case XML_ROLE_CONTENT_ELEMENT_REP:
- quant = XML_CQUANT_REP;
- goto elementContent;
- case XML_ROLE_CONTENT_ELEMENT_PLUS:
- quant = XML_CQUANT_PLUS;
- elementContent:
- if (dtd.in_eldecl) {
- ELEMENT_TYPE *el;
- const XML_Char *name;
- int nameLen;
- const char *nxt = (quant == XML_CQUANT_NONE
- ? next
- : next - enc->minBytesPerChar);
- int myindex = nextScaffoldPart(parser);
- if (myindex < 0)
- return XML_ERROR_NO_MEMORY;
- dtd.scaffold[myindex].type = XML_CTYPE_NAME;
- dtd.scaffold[myindex].quant = quant;
- el = getElementType(parser, enc, s, nxt);
- if (!el)
- return XML_ERROR_NO_MEMORY;
- name = el->name;
- dtd.scaffold[myindex].name = name;
- nameLen = 0;
- for (; name[nameLen++]; );
- dtd.contentStringLen += nameLen;
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- }
- break;
-
- case XML_ROLE_GROUP_CLOSE:
- quant = XML_CQUANT_NONE;
- goto closeGroup;
- case XML_ROLE_GROUP_CLOSE_OPT:
- quant = XML_CQUANT_OPT;
- goto closeGroup;
- case XML_ROLE_GROUP_CLOSE_REP:
- quant = XML_CQUANT_REP;
- goto closeGroup;
- case XML_ROLE_GROUP_CLOSE_PLUS:
- quant = XML_CQUANT_PLUS;
- closeGroup:
- if (dtd.in_eldecl) {
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- dtd.scaffLevel--;
- dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel]].quant = quant;
- if (dtd.scaffLevel == 0) {
- if (!handleDefault) {
- XML_Content *model = build_model(parser);
- if (!model)
- return XML_ERROR_NO_MEMORY;
- *eventEndPP = s;
- elementDeclHandler(handlerArg, declElementType->name, model);
- }
- dtd.in_eldecl = XML_FALSE;
- dtd.contentStringLen = 0;
- }
- }
- break;
- /* End element declaration stuff */
-
- case XML_ROLE_PI:
- if (!reportProcessingInstruction(parser, enc, s, next))
- return XML_ERROR_NO_MEMORY;
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_COMMENT:
- if (!reportComment(parser, enc, s, next))
- return XML_ERROR_NO_MEMORY;
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_NONE:
- switch (tok) {
- case XML_TOK_BOM:
- handleDefault = XML_FALSE;
- break;
- }
- break;
- case XML_ROLE_DOCTYPE_NONE:
- if (startDoctypeDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_ENTITY_NONE:
- if (dtd.keepProcessing && entityDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_NOTATION_NONE:
- if (notationDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_ATTLIST_NONE:
- if (dtd.keepProcessing && attlistDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_ELEMENT_NONE:
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- break;
- } /* end of big switch */
-
- if (handleDefault && defaultHandler)
- reportDefault(parser, enc, s, next);
-
- s = next;
- tok = XmlPrologTok(enc, s, end, &next);
- }
- /* not reached */
-}
-
-static enum XML_Error FASTCALL
-epilogProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- processor = epilogProcessor;
- eventPtr = s;
- for (;;) {
- const char *next = NULL;
- int tok = XmlPrologTok(encoding, s, end, &next);
- eventEndPtr = next;
- switch (tok) {
- /* report partial linebreak - it might be the last token */
- case -XML_TOK_PROLOG_S:
- if (defaultHandler) {
- eventEndPtr = next;
- reportDefault(parser, encoding, s, next);
- }
- if (nextPtr)
- *nextPtr = next;
- return XML_ERROR_NONE;
- case XML_TOK_NONE:
- if (nextPtr)
- *nextPtr = s;
- return XML_ERROR_NONE;
- case XML_TOK_PROLOG_S:
- if (defaultHandler)
- reportDefault(parser, encoding, s, next);
- break;
- case XML_TOK_PI:
- if (!reportProcessingInstruction(parser, encoding, s, next))
- return XML_ERROR_NO_MEMORY;
- break;
- case XML_TOK_COMMENT:
- if (!reportComment(parser, encoding, s, next))
- return XML_ERROR_NO_MEMORY;
- break;
- case XML_TOK_INVALID:
- eventPtr = next;
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- if (nextPtr) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- if (nextPtr) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- return XML_ERROR_PARTIAL_CHAR;
- default:
- return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
- }
- eventPtr = s = next;
- }
-}
-
-#ifdef XML_DTD
-
-static enum XML_Error FASTCALL
-processInternalParamEntity(XML_Parser parser, ENTITY *entity)
-{
- const char *s, *end, *next;
- int tok;
- enum XML_Error result;
- OPEN_INTERNAL_ENTITY openEntity;
- entity->open = XML_TRUE;
- openEntity.next = openInternalEntities;
- openInternalEntities = &openEntity;
- openEntity.entity = entity;
- openEntity.internalEventPtr = NULL;
- openEntity.internalEventEndPtr = NULL;
- s = (char *)entity->textPtr;
- end = (char *)(entity->textPtr + entity->textLen);
- tok = XmlPrologTok(internalEncoding, s, end, &next);
- result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
- entity->open = XML_FALSE;
- openInternalEntities = openEntity.next;
- return result;
-}
-
-#endif /* XML_DTD */
-
-static enum XML_Error FASTCALL
-errorProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
-{
- return errorCode;
-}
-
-static enum XML_Error FASTCALL
-storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
- const char *ptr, const char *end,
- STRING_POOL *pool)
-{
- enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
- end, pool);
- if (result)
- return result;
- if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
- poolChop(pool);
- if (!poolAppendChar(pool, XML_T('\0')))
- return XML_ERROR_NO_MEMORY;
- return XML_ERROR_NONE;
-}
-
-static enum XML_Error FASTCALL
-appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
- const char *ptr, const char *end,
- STRING_POOL *pool)
-{
- for (;;) {
- const char *next;
- int tok = XmlAttributeValueTok(enc, ptr, end, &next);
- switch (tok) {
- case XML_TOK_NONE:
- return XML_ERROR_NONE;
- case XML_TOK_INVALID:
- if (enc == encoding)
- eventPtr = next;
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_CHAR_REF:
- {
- XML_Char buf[XML_ENCODE_MAX];
- int i;
- int n = XmlCharRefNumber(enc, ptr);
- if (n < 0) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_BAD_CHAR_REF;
- }
- if (!isCdata
- && n == 0x20 /* space */
- && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
- break;
- n = XmlEncode(n, (ICHAR *)buf);
- if (!n) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_BAD_CHAR_REF;
- }
- for (i = 0; i < n; i++) {
- if (!poolAppendChar(pool, buf[i]))
- return XML_ERROR_NO_MEMORY;
- }
- }
- break;
- case XML_TOK_DATA_CHARS:
- if (!poolAppend(pool, enc, ptr, next))
- return XML_ERROR_NO_MEMORY;
- break;
- case XML_TOK_TRAILING_CR:
- next = ptr + enc->minBytesPerChar;
- /* fall through */
- case XML_TOK_ATTRIBUTE_VALUE_S:
- case XML_TOK_DATA_NEWLINE:
- if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
- break;
- if (!poolAppendChar(pool, 0x20))
- return XML_ERROR_NO_MEMORY;
- break;
- case XML_TOK_ENTITY_REF:
- {
- const XML_Char *name;
- ENTITY *entity;
- char checkEntityDecl;
- XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc,
- ptr + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (ch) {
- if (!poolAppendChar(pool, ch))
- return XML_ERROR_NO_MEMORY;
- break;
- }
- name = poolStoreString(&temp2Pool, enc,
- ptr + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name)
- return XML_ERROR_NO_MEMORY;
- entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
- poolDiscard(&temp2Pool);
- /* first, determine if a check for an existing declaration is needed;
- if yes, check that the entity exists, and that it is internal,
- otherwise call the default handler (if called from content)
- */
- if (pool == &dtd.pool) /* are we called from prolog? */
- checkEntityDecl =
-#ifdef XML_DTD
- prologState.documentEntity &&
-#endif /* XML_DTD */
- (dtd.standalone
- ? !openInternalEntities
- : !dtd.hasParamEntityRefs);
- else /* if (pool == &tempPool): we are called from content */
- checkEntityDecl = !dtd.hasParamEntityRefs || dtd.standalone;
- if (checkEntityDecl) {
- if (!entity)
- return XML_ERROR_UNDEFINED_ENTITY;
- else if (!entity->is_internal)
- return XML_ERROR_ENTITY_DECLARED_IN_PE;
- }
- else if (!entity) {
- /* cannot report skipped entity here - see comments on
- skippedEntityHandler
- if (skippedEntityHandler)
- skippedEntityHandler(handlerArg, name, 0);
- */
- if ((pool == &tempPool) && defaultHandler)
- reportDefault(parser, enc, ptr, next);
- break;
- }
- if (entity->open) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_RECURSIVE_ENTITY_REF;
- }
- if (entity->notation) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_BINARY_ENTITY_REF;
- }
- if (!entity->textPtr) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
- }
- else {
- enum XML_Error result;
- const XML_Char *textEnd = entity->textPtr + entity->textLen;
- entity->open = XML_TRUE;
- result = appendAttributeValue(parser, internalEncoding, isCdata,
- (char *)entity->textPtr,
- (char *)textEnd, pool);
- entity->open = XML_FALSE;
- if (result)
- return result;
- }
- }
- break;
- default:
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_UNEXPECTED_STATE;
- }
- ptr = next;
- }
- /* not reached */
-}
-
-static enum XML_Error FASTCALL
-storeEntityValue(XML_Parser parser,
- const ENCODING *enc,
- const char *entityTextPtr,
- const char *entityTextEnd)
-{
- STRING_POOL *pool = &(dtd.entityValuePool);
- enum XML_Error result = XML_ERROR_NONE;
-#ifdef XML_DTD
- int oldInEntityValue = prologState.inEntityValue;
- prologState.inEntityValue = 1;
-#endif /* XML_DTD */
- /* never return Null for the value argument in EntityDeclHandler,
- since this would indicate an external entity; therefore we
- have to make sure that entityValuePool.start is not null */
- if (!pool->blocks) {
- if (!poolGrow(pool))
- return XML_ERROR_NO_MEMORY;
- }
-
- for (;;) {
- const char *next;
- int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
- switch (tok) {
- case XML_TOK_PARAM_ENTITY_REF:
-#ifdef XML_DTD
- if (isParamEntity || enc != encoding) {
- const XML_Char *name;
- ENTITY *entity;
- name = poolStoreString(&tempPool, enc,
- entityTextPtr + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name) {
- result = XML_ERROR_NO_MEMORY;
- goto endEntityValue;
- }
- entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
- poolDiscard(&tempPool);
- if (!entity) {
- /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
- /* cannot report skipped entity here - see comments on
- skippedEntityHandler
- if (skippedEntityHandler)
- skippedEntityHandler(handlerArg, name, 0);
- */
- dtd.keepProcessing = dtd.standalone;
- goto endEntityValue;
- }
- if (entity->open) {
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_RECURSIVE_ENTITY_REF;
- goto endEntityValue;
- }
- if (entity->systemId) {
- if (externalEntityRefHandler) {
- dtd.paramEntityRead = XML_FALSE;
- entity->open = XML_TRUE;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId)) {
- entity->open = XML_FALSE;
- result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- goto endEntityValue;
- }
- entity->open = XML_FALSE;
- if (!dtd.paramEntityRead)
- dtd.keepProcessing = dtd.standalone;
- }
- else
- dtd.keepProcessing = dtd.standalone;
- }
- else {
- entity->open = XML_TRUE;
- result = storeEntityValue(parser,
- internalEncoding,
- (char *)entity->textPtr,
- (char *)(entity->textPtr
- + entity->textLen));
- entity->open = XML_FALSE;
- if (result)
- goto endEntityValue;
- }
- break;
- }
-#endif /* XML_DTD */
- /* in the internal subset, PE references are not legal
- within markup declarations, e.g entity values in this case */
- eventPtr = entityTextPtr;
- result = XML_ERROR_PARAM_ENTITY_REF;
- goto endEntityValue;
- case XML_TOK_NONE:
- result = XML_ERROR_NONE;
- goto endEntityValue;
- case XML_TOK_ENTITY_REF:
- case XML_TOK_DATA_CHARS:
- if (!poolAppend(pool, enc, entityTextPtr, next)) {
- result = XML_ERROR_NO_MEMORY;
- goto endEntityValue;
- }
- break;
- case XML_TOK_TRAILING_CR:
- next = entityTextPtr + enc->minBytesPerChar;
- /* fall through */
- case XML_TOK_DATA_NEWLINE:
- if (pool->end == pool->ptr && !poolGrow(pool)) {
- result = XML_ERROR_NO_MEMORY;
- goto endEntityValue;
- }
- *(pool->ptr)++ = 0xA;
- break;
- case XML_TOK_CHAR_REF:
- {
- XML_Char buf[XML_ENCODE_MAX];
- int i;
- int n = XmlCharRefNumber(enc, entityTextPtr);
- if (n < 0) {
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_BAD_CHAR_REF;
- goto endEntityValue;
- }
- n = XmlEncode(n, (ICHAR *)buf);
- if (!n) {
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_BAD_CHAR_REF;
- goto endEntityValue;
- }
- for (i = 0; i < n; i++) {
- if (pool->end == pool->ptr && !poolGrow(pool)) {
- result = XML_ERROR_NO_MEMORY;
- goto endEntityValue;
- }
- *(pool->ptr)++ = buf[i];
- }
- }
- break;
- case XML_TOK_PARTIAL:
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_INVALID_TOKEN;
- goto endEntityValue;
- case XML_TOK_INVALID:
- if (enc == encoding)
- eventPtr = next;
- result = XML_ERROR_INVALID_TOKEN;
- goto endEntityValue;
- default:
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_UNEXPECTED_STATE;
- goto endEntityValue;
- }
- entityTextPtr = next;
- }
-endEntityValue:
-#ifdef XML_DTD
- prologState.inEntityValue = oldInEntityValue;
-#endif /* XML_DTD */
- return result;
-}
-
-static void FASTCALL
-normalizeLines(XML_Char *s)
-{
- XML_Char *p;
- for (;; s++) {
- if (*s == XML_T('\0'))
- return;
- if (*s == 0xD)
- break;
- }
- p = s;
- do {
- if (*s == 0xD) {
- *p++ = 0xA;
- if (*++s == 0xA)
- s++;
- }
- else
- *p++ = *s++;
- } while (*s);
- *p = XML_T('\0');
-}
-
-static int FASTCALL
-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end)
-{
- const XML_Char *target;
- XML_Char *data;
- const char *tem;
- if (!processingInstructionHandler) {
- if (defaultHandler)
- reportDefault(parser, enc, start, end);
- return 1;
- }
- start += enc->minBytesPerChar * 2;
- tem = start + XmlNameLength(enc, start);
- target = poolStoreString(&tempPool, enc, start, tem);
- if (!target)
- return 0;
- poolFinish(&tempPool);
- data = poolStoreString(&tempPool, enc,
- XmlSkipS(enc, tem),
- end - enc->minBytesPerChar*2);
- if (!data)
- return 0;
- normalizeLines(data);
- processingInstructionHandler(handlerArg, target, data);
- poolClear(&tempPool);
- return 1;
-}
-
-static int FASTCALL
-reportComment(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end)
-{
- XML_Char *data;
- if (!commentHandler) {
- if (defaultHandler)
- reportDefault(parser, enc, start, end);
- return 1;
- }
- data = poolStoreString(&tempPool,
- enc,
- start + enc->minBytesPerChar * 4,
- end - enc->minBytesPerChar * 3);
- if (!data)
- return 0;
- normalizeLines(data);
- commentHandler(handlerArg, data);
- poolClear(&tempPool);
- return 1;
-}
-
-static void FASTCALL
-reportDefault(XML_Parser parser, const ENCODING *enc,
- const char *s, const char *end)
-{
- if (MUST_CONVERT(enc, s)) {
- const char **eventPP;
- const char **eventEndPP;
- if (enc == encoding) {
- eventPP = &eventPtr;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
- }
- do {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
- *eventEndPP = s;
- defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
- *eventPP = s;
- } while (s != end);
- }
- else
- defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
-}
-
-
-static int FASTCALL
-defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
- XML_Bool isId, const XML_Char *value, XML_Parser parser)
-{
- DEFAULT_ATTRIBUTE *att;
- if (value || isId) {
- /* The handling of default attributes gets messed up if we have
- a default which duplicates a non-default. */
- int i;
- for (i = 0; i < type->nDefaultAtts; i++)
- if (attId == type->defaultAtts[i].id)
- return 1;
- if (isId && !type->idAtt && !attId->xmlns)
- type->idAtt = attId;
- }
- if (type->nDefaultAtts == type->allocDefaultAtts) {
- if (type->allocDefaultAtts == 0) {
- type->allocDefaultAtts = 8;
- type->defaultAtts = MALLOC(type->allocDefaultAtts
- * sizeof(DEFAULT_ATTRIBUTE));
- if (!type->defaultAtts)
- return 0;
- }
- else {
- DEFAULT_ATTRIBUTE *temp;
- int count = type->allocDefaultAtts * 2;
- temp = REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
- if (temp == NULL)
- return 0;
- type->allocDefaultAtts = count;
- type->defaultAtts = temp;
- }
- }
- att = type->defaultAtts + type->nDefaultAtts;
- att->id = attId;
- att->value = value;
- att->isCdata = isCdata;
- if (!isCdata)
- attId->maybeTokenized = XML_TRUE;
- type->nDefaultAtts += 1;
- return 1;
-}
-
-static int FASTCALL
-setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
-{
- const XML_Char *name;
- for (name = elementType->name; *name; name++) {
- if (*name == XML_T(':')) {
- PREFIX *prefix;
- const XML_Char *s;
- for (s = elementType->name; s != name; s++) {
- if (!poolAppendChar(&dtd.pool, *s))
- return 0;
- }
- if (!poolAppendChar(&dtd.pool, XML_T('\0')))
- return 0;
- prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool),
- sizeof(PREFIX));
- if (!prefix)
- return 0;
- if (prefix->name == poolStart(&dtd.pool))
- poolFinish(&dtd.pool);
- else
- poolDiscard(&dtd.pool);
- elementType->prefix = prefix;
-
- }
- }
- return 1;
-}
-
-static ATTRIBUTE_ID * FASTCALL
-getAttributeId(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end)
-{
- ATTRIBUTE_ID *id;
- const XML_Char *name;
- if (!poolAppendChar(&dtd.pool, XML_T('\0')))
- return NULL;
- name = poolStoreString(&dtd.pool, enc, start, end);
- if (!name)
- return NULL;
- ++name;
- id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
- if (!id)
- return NULL;
- if (id->name != name)
- poolDiscard(&dtd.pool);
- else {
- poolFinish(&dtd.pool);
- if (!ns)
- ;
- else if (name[0] == 'x'
- && name[1] == 'm'
- && name[2] == 'l'
- && name[3] == 'n'
- && name[4] == 's'
- && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
- if (name[5] == '\0')
- id->prefix = &dtd.defaultPrefix;
- else
- id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
- id->xmlns = XML_TRUE;
- }
- else {
- int i;
- for (i = 0; name[i]; i++) {
- if (name[i] == XML_T(':')) {
- int j;
- for (j = 0; j < i; j++) {
- if (!poolAppendChar(&dtd.pool, name[j]))
- return NULL;
- }
- if (!poolAppendChar(&dtd.pool, XML_T('\0')))
- return NULL;
- id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool),
- sizeof(PREFIX));
- if (id->prefix->name == poolStart(&dtd.pool))
- poolFinish(&dtd.pool);
- else
- poolDiscard(&dtd.pool);
- break;
- }
- }
- }
- }
- return id;
-}
-
-#define CONTEXT_SEP XML_T('\f')
-
-static const XML_Char * FASTCALL
-getContext(XML_Parser parser)
-{
- HASH_TABLE_ITER iter;
- XML_Bool needSep = XML_FALSE;
-
- if (dtd.defaultPrefix.binding) {
- int i;
- int len;
- if (!poolAppendChar(&tempPool, XML_T('=')))
- return NULL;
- len = dtd.defaultPrefix.binding->uriLen;
- if (namespaceSeparator != XML_T('\0'))
- len--;
- for (i = 0; i < len; i++)
- if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
- return NULL;
- needSep = XML_TRUE;
- }
-
- hashTableIterInit(&iter, &(dtd.prefixes));
- for (;;) {
- int i;
- int len;
- const XML_Char *s;
- PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
- if (!prefix)
- break;
- if (!prefix->binding)
- continue;
- if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
- return NULL;
- for (s = prefix->name; *s; s++)
- if (!poolAppendChar(&tempPool, *s))
- return NULL;
- if (!poolAppendChar(&tempPool, XML_T('=')))
- return NULL;
- len = prefix->binding->uriLen;
- if (namespaceSeparator != XML_T('\0'))
- len--;
- for (i = 0; i < len; i++)
- if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
- return NULL;
- needSep = XML_TRUE;
- }
-
-
- hashTableIterInit(&iter, &(dtd.generalEntities));
- for (;;) {
- const XML_Char *s;
- ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
- if (!e)
- break;
- if (!e->open)
- continue;
- if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
- return NULL;
- for (s = e->name; *s; s++)
- if (!poolAppendChar(&tempPool, *s))
- return 0;
- needSep = XML_TRUE;
- }
-
- if (!poolAppendChar(&tempPool, XML_T('\0')))
- return NULL;
- return tempPool.start;
-}
-
-static XML_Bool FASTCALL
-setContext(XML_Parser parser, const XML_Char *context)
-{
- const XML_Char *s = context;
-
- while (*context != XML_T('\0')) {
- if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
- ENTITY *e;
- if (!poolAppendChar(&tempPool, XML_T('\0')))
- return XML_FALSE;
- e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
- if (e)
- e->open = XML_TRUE;
- if (*s != XML_T('\0'))
- s++;
- context = s;
- poolDiscard(&tempPool);
- }
- else if (*s == XML_T('=')) {
- PREFIX *prefix;
- if (poolLength(&tempPool) == 0)
- prefix = &dtd.defaultPrefix;
- else {
- if (!poolAppendChar(&tempPool, XML_T('\0')))
- return XML_FALSE;
- prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool),
- sizeof(PREFIX));
- if (!prefix)
- return XML_FALSE;
- if (prefix->name == poolStart(&tempPool)) {
- prefix->name = poolCopyString(&dtd.pool, prefix->name);
- if (!prefix->name)
- return XML_FALSE;
- }
- poolDiscard(&tempPool);
- }
- for (context = s + 1;
- *context != CONTEXT_SEP && *context != XML_T('\0');
- context++)
- if (!poolAppendChar(&tempPool, *context))
- return XML_FALSE;
- if (!poolAppendChar(&tempPool, XML_T('\0')))
- return XML_FALSE;
- if (!addBinding(parser, prefix, 0, poolStart(&tempPool),
- &inheritedBindings))
- return XML_FALSE;
- poolDiscard(&tempPool);
- if (*context != XML_T('\0'))
- ++context;
- s = context;
- }
- else {
- if (!poolAppendChar(&tempPool, *s))
- return XML_FALSE;
- s++;
- }
- }
- return XML_TRUE;
-}
-
-static void FASTCALL
-normalizePublicId(XML_Char *publicId)
-{
- XML_Char *p = publicId;
- XML_Char *s;
- for (s = publicId; *s; s++) {
- switch (*s) {
- case 0x20:
- case 0xD:
- case 0xA:
- if (p != publicId && p[-1] != 0x20)
- *p++ = 0x20;
- break;
- default:
- *p++ = *s;
- }
- }
- if (p != publicId && p[-1] == 0x20)
- --p;
- *p = XML_T('\0');
-}
-
-static void FASTCALL
-dtdInit(DTD *p, XML_Parser parser)
-{
- XML_Memory_Handling_Suite *ms = &parser->m_mem;
- poolInit(&(p->pool), ms);
-#ifdef XML_DTD
- poolInit(&(p->entityValuePool), ms);
-#endif /* XML_DTD */
- hashTableInit(&(p->generalEntities), ms);
- hashTableInit(&(p->elementTypes), ms);
- hashTableInit(&(p->attributeIds), ms);
- hashTableInit(&(p->prefixes), ms);
-#ifdef XML_DTD
- p->paramEntityRead = XML_FALSE;
- hashTableInit(&(p->paramEntities), ms);
-#endif /* XML_DTD */
- p->defaultPrefix.name = NULL;
- p->defaultPrefix.binding = NULL;
-
- p->in_eldecl = XML_FALSE;
- p->scaffIndex = NULL;
- p->scaffold = NULL;
- p->scaffLevel = 0;
- p->scaffSize = 0;
- p->scaffCount = 0;
- p->contentStringLen = 0;
-
- p->keepProcessing = XML_TRUE;
- p->hasParamEntityRefs = XML_FALSE;
- p->standalone = XML_FALSE;
-}
-
-#ifdef XML_DTD
-
-static void FASTCALL
-dtdSwap(DTD *p1, DTD *p2)
-{
- DTD tem;
- memcpy(&tem, p1, sizeof(DTD));
- memcpy(p1, p2, sizeof(DTD));
- memcpy(p2, &tem, sizeof(DTD));
-}
-
-#endif /* XML_DTD */
-
-static void FASTCALL
-dtdReset(DTD *p, XML_Parser parser)
-{
- HASH_TABLE_ITER iter;
- hashTableIterInit(&iter, &(p->elementTypes));
- for (;;) {
- ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
- if (!e)
- break;
- if (e->allocDefaultAtts != 0)
- FREE(e->defaultAtts);
- }
- hashTableClear(&(p->generalEntities));
-#ifdef XML_DTD
- p->paramEntityRead = XML_FALSE;
- hashTableClear(&(p->paramEntities));
-#endif /* XML_DTD */
- hashTableClear(&(p->elementTypes));
- hashTableClear(&(p->attributeIds));
- hashTableClear(&(p->prefixes));
- poolClear(&(p->pool));
-#ifdef XML_DTD
- poolClear(&(p->entityValuePool));
-#endif /* XML_DTD */
- p->defaultPrefix.name = NULL;
- p->defaultPrefix.binding = NULL;
-
- p->in_eldecl = XML_FALSE;
- if (p->scaffIndex) {
- FREE(p->scaffIndex);
- p->scaffIndex = NULL;
- }
- if (p->scaffold) {
- FREE(p->scaffold);
- p->scaffold = NULL;
- }
- p->scaffLevel = 0;
- p->scaffSize = 0;
- p->scaffCount = 0;
- p->contentStringLen = 0;
-
- p->keepProcessing = XML_TRUE;
- p->hasParamEntityRefs = XML_FALSE;
- p->standalone = XML_FALSE;
-}
-
-static void FASTCALL
-dtdDestroy(DTD *p, XML_Parser parser)
-{
- HASH_TABLE_ITER iter;
- hashTableIterInit(&iter, &(p->elementTypes));
- for (;;) {
- ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
- if (!e)
- break;
- if (e->allocDefaultAtts != 0)
- FREE(e->defaultAtts);
- }
- hashTableDestroy(&(p->generalEntities));
-#ifdef XML_DTD
- hashTableDestroy(&(p->paramEntities));
-#endif /* XML_DTD */
- hashTableDestroy(&(p->elementTypes));
- hashTableDestroy(&(p->attributeIds));
- hashTableDestroy(&(p->prefixes));
- poolDestroy(&(p->pool));
-#ifdef XML_DTD
- poolDestroy(&(p->entityValuePool));
-#endif /* XML_DTD */
- if (!parentParser) {
- if (p->scaffIndex)
- FREE(p->scaffIndex);
- if (p->scaffold)
- FREE(p->scaffold);
- }
-}
-
-/* Do a deep copy of the DTD. Return 0 for out of memory; non-zero otherwise.
- The new DTD has already been initialized.
-*/
-static int FASTCALL
-dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser)
-{
- HASH_TABLE_ITER iter;
-
- /* Copy the prefix table. */
-
- hashTableIterInit(&iter, &(oldDtd->prefixes));
- for (;;) {
- const XML_Char *name;
- const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
- if (!oldP)
- break;
- name = poolCopyString(&(newDtd->pool), oldP->name);
- if (!name)
- return 0;
- if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
- return 0;
- }
-
- hashTableIterInit(&iter, &(oldDtd->attributeIds));
-
- /* Copy the attribute id table. */
-
- for (;;) {
- ATTRIBUTE_ID *newA;
- const XML_Char *name;
- const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
-
- if (!oldA)
- break;
- /* Remember to allocate the scratch byte before the name. */
- if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
- return 0;
- name = poolCopyString(&(newDtd->pool), oldA->name);
- if (!name)
- return 0;
- ++name;
- newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name,
- sizeof(ATTRIBUTE_ID));
- if (!newA)
- return 0;
- newA->maybeTokenized = oldA->maybeTokenized;
- if (oldA->prefix) {
- newA->xmlns = oldA->xmlns;
- if (oldA->prefix == &oldDtd->defaultPrefix)
- newA->prefix = &newDtd->defaultPrefix;
- else
- newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
- oldA->prefix->name, 0);
- }
- }
-
- /* Copy the element type table. */
-
- hashTableIterInit(&iter, &(oldDtd->elementTypes));
-
- for (;;) {
- int i;
- ELEMENT_TYPE *newE;
- const XML_Char *name;
- const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
- if (!oldE)
- break;
- name = poolCopyString(&(newDtd->pool), oldE->name);
- if (!name)
- return 0;
- newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name,
- sizeof(ELEMENT_TYPE));
- if (!newE)
- return 0;
- if (oldE->nDefaultAtts) {
- newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
- MALLOC(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
- if (!newE->defaultAtts) {
- FREE(newE);
- return 0;
- }
- }
- if (oldE->idAtt)
- newE->idAtt = (ATTRIBUTE_ID *)
- lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
- newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
- if (oldE->prefix)
- newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
- oldE->prefix->name, 0);
- for (i = 0; i < newE->nDefaultAtts; i++) {
- newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
- lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
- newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
- if (oldE->defaultAtts[i].value) {
- newE->defaultAtts[i].value
- = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
- if (!newE->defaultAtts[i].value)
- return 0;
- }
- else
- newE->defaultAtts[i].value = NULL;
- }
- }
-
- /* Copy the entity tables. */
- if (!copyEntityTable(&(newDtd->generalEntities),
- &(newDtd->pool),
- &(oldDtd->generalEntities), parser))
- return 0;
-
-#ifdef XML_DTD
- if (!copyEntityTable(&(newDtd->paramEntities),
- &(newDtd->pool),
- &(oldDtd->paramEntities), parser))
- return 0;
- newDtd->paramEntityRead = oldDtd->paramEntityRead;
-#endif /* XML_DTD */
-
- newDtd->keepProcessing = oldDtd->keepProcessing;
- newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
- newDtd->standalone = oldDtd->standalone;
-
- /* Don't want deep copying for scaffolding */
- newDtd->in_eldecl = oldDtd->in_eldecl;
- newDtd->scaffold = oldDtd->scaffold;
- newDtd->contentStringLen = oldDtd->contentStringLen;
- newDtd->scaffSize = oldDtd->scaffSize;
- newDtd->scaffLevel = oldDtd->scaffLevel;
- newDtd->scaffIndex = oldDtd->scaffIndex;
-
- return 1;
-} /* End dtdCopy */
-
-static int FASTCALL
-copyEntityTable(HASH_TABLE *newTable,
- STRING_POOL *newPool,
- const HASH_TABLE *oldTable,
- XML_Parser parser)
-{
- HASH_TABLE_ITER iter;
- const XML_Char *cachedOldBase = NULL;
- const XML_Char *cachedNewBase = NULL;
-
- hashTableIterInit(&iter, oldTable);
-
- for (;;) {
- ENTITY *newE;
- const XML_Char *name;
- const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
- if (!oldE)
- break;
- name = poolCopyString(newPool, oldE->name);
- if (!name)
- return 0;
- newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
- if (!newE)
- return 0;
- if (oldE->systemId) {
- const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
- if (!tem)
- return 0;
- newE->systemId = tem;
- if (oldE->base) {
- if (oldE->base == cachedOldBase)
- newE->base = cachedNewBase;
- else {
- cachedOldBase = oldE->base;
- tem = poolCopyString(newPool, cachedOldBase);
- if (!tem)
- return 0;
- cachedNewBase = newE->base = tem;
- }
- }
- if (oldE->publicId) {
- tem = poolCopyString(newPool, oldE->publicId);
- if (!tem)
- return 0;
- newE->publicId = tem;
- }
- }
- else {
- const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
- oldE->textLen);
- if (!tem)
- return 0;
- newE->textPtr = tem;
- newE->textLen = oldE->textLen;
- }
- if (oldE->notation) {
- const XML_Char *tem = poolCopyString(newPool, oldE->notation);
- if (!tem)
- return 0;
- newE->notation = tem;
- }
- newE->is_param = oldE->is_param;
- newE->is_internal = oldE->is_internal;
- }
- return 1;
-}
-
-#define INIT_SIZE 64
-
-static int FASTCALL
-keyeq(KEY s1, KEY s2)
-{
- for (; *s1 == *s2; s1++, s2++)
- if (*s1 == 0)
- return 1;
- return 0;
-}
-
-static unsigned long FASTCALL
-hash(KEY s)
-{
- unsigned long h = 0;
- while (*s)
- h = (h << 5) + h + (unsigned char)*s++;
- return h;
-}
-
-static NAMED * FASTCALL
-lookup(HASH_TABLE *table, KEY name, size_t createSize)
-{
- size_t i;
- if (table->size == 0) {
- size_t tsize;
-
- if (!createSize)
- return NULL;
- tsize = INIT_SIZE * sizeof(NAMED *);
- table->v = table->mem->malloc_fcn(tsize);
- if (!table->v)
- return NULL;
- memset(table->v, 0, tsize);
- table->size = INIT_SIZE;
- table->usedLim = INIT_SIZE / 2;
- i = hash(name) & (table->size - 1);
- }
- else {
- unsigned long h = hash(name);
- for (i = h & (table->size - 1);
- table->v[i];
- i == 0 ? i = table->size - 1 : --i) {
- if (keyeq(name, table->v[i]->name))
- return table->v[i];
- }
- if (!createSize)
- return NULL;
- if (table->used == table->usedLim) {
- /* check for overflow */
- size_t newSize = table->size * 2;
- size_t tsize = newSize * sizeof(NAMED *);
- NAMED **newV = table->mem->malloc_fcn(tsize);
- if (!newV)
- return NULL;
- memset(newV, 0, tsize);
- for (i = 0; i < table->size; i++)
- if (table->v[i]) {
- size_t j;
- for (j = hash(table->v[i]->name) & (newSize - 1);
- newV[j];
- j == 0 ? j = newSize - 1 : --j)
- ;
- newV[j] = table->v[i];
- }
- table->mem->free_fcn(table->v);
- table->v = newV;
- table->size = newSize;
- table->usedLim = newSize/2;
- for (i = h & (table->size - 1);
- table->v[i];
- i == 0 ? i = table->size - 1 : --i)
- ;
- }
- }
- table->v[i] = table->mem->malloc_fcn(createSize);
- if (!table->v[i])
- return NULL;
- memset(table->v[i], 0, createSize);
- table->v[i]->name = name;
- (table->used)++;
- return table->v[i];
-}
-
-static void FASTCALL
-hashTableClear(HASH_TABLE *table)
-{
- size_t i;
- for (i = 0; i < table->size; i++) {
- NAMED *p = table->v[i];
- if (p) {
- table->mem->free_fcn(p);
- table->v[i] = NULL;
- }
- }
- table->usedLim = table->size / 2;
- table->used = 0;
-}
-
-static void FASTCALL
-hashTableDestroy(HASH_TABLE *table)
-{
- size_t i;
- for (i = 0; i < table->size; i++) {
- NAMED *p = table->v[i];
- if (p)
- table->mem->free_fcn(p);
- }
- if (table->v)
- table->mem->free_fcn(table->v);
-}
-
-static void FASTCALL
-hashTableInit(HASH_TABLE *p, XML_Memory_Handling_Suite *ms)
-{
- p->size = 0;
- p->usedLim = 0;
- p->used = 0;
- p->v = NULL;
- p->mem = ms;
-}
-
-static void FASTCALL
-hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
-{
- iter->p = table->v;
- iter->end = iter->p + table->size;
-}
-
-static NAMED * FASTCALL
-hashTableIterNext(HASH_TABLE_ITER *iter)
-{
- while (iter->p != iter->end) {
- NAMED *tem = *(iter->p)++;
- if (tem)
- return tem;
- }
- return NULL;
-}
-
-static void FASTCALL
-poolInit(STRING_POOL *pool, XML_Memory_Handling_Suite *ms)
-{
- pool->blocks = NULL;
- pool->freeBlocks = NULL;
- pool->start = NULL;
- pool->ptr = NULL;
- pool->end = NULL;
- pool->mem = ms;
-}
-
-static void FASTCALL
-poolClear(STRING_POOL *pool)
-{
- if (!pool->freeBlocks)
- pool->freeBlocks = pool->blocks;
- else {
- BLOCK *p = pool->blocks;
- while (p) {
- BLOCK *tem = p->next;
- p->next = pool->freeBlocks;
- pool->freeBlocks = p;
- p = tem;
- }
- }
- pool->blocks = NULL;
- pool->start = NULL;
- pool->ptr = NULL;
- pool->end = NULL;
-}
-
-static void FASTCALL
-poolDestroy(STRING_POOL *pool)
-{
- BLOCK *p = pool->blocks;
- while (p) {
- BLOCK *tem = p->next;
- pool->mem->free_fcn(p);
- p = tem;
- }
- p = pool->freeBlocks;
- while (p) {
- BLOCK *tem = p->next;
- pool->mem->free_fcn(p);
- p = tem;
- }
-}
-
-static XML_Char * FASTCALL
-poolAppend(STRING_POOL *pool, const ENCODING *enc,
- const char *ptr, const char *end)
-{
- if (!pool->ptr && !poolGrow(pool))
- return NULL;
- for (;;) {
- XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
- if (ptr == end)
- break;
- if (!poolGrow(pool))
- return NULL;
- }
- return pool->start;
-}
-
-static const XML_Char * FASTCALL
-poolCopyString(STRING_POOL *pool, const XML_Char *s)
-{
- do {
- if (!poolAppendChar(pool, *s))
- return NULL;
- } while (*s++);
- s = pool->start;
- poolFinish(pool);
- return s;
-}
-
-static const XML_Char * FASTCALL
-poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
-{
- if (!pool->ptr && !poolGrow(pool))
- return NULL;
- for (; n > 0; --n, s++) {
- if (!poolAppendChar(pool, *s))
- return NULL;
- }
- s = pool->start;
- poolFinish(pool);
- return s;
-}
-
-static const XML_Char * FASTCALL
-poolAppendString(STRING_POOL *pool, const XML_Char *s)
-{
- while (*s) {
- if (!poolAppendChar(pool, *s))
- return NULL;
- s++;
- }
- return pool->start;
-}
-
-static XML_Char * FASTCALL
-poolStoreString(STRING_POOL *pool, const ENCODING *enc,
- const char *ptr, const char *end)
-{
- if (!poolAppend(pool, enc, ptr, end))
- return NULL;
- if (pool->ptr == pool->end && !poolGrow(pool))
- return NULL;
- *(pool->ptr)++ = 0;
- return pool->start;
-}
-
-static XML_Bool FASTCALL
-poolGrow(STRING_POOL *pool)
-{
- if (pool->freeBlocks) {
- if (pool->start == 0) {
- pool->blocks = pool->freeBlocks;
- pool->freeBlocks = pool->freeBlocks->next;
- pool->blocks->next = NULL;
- pool->start = pool->blocks->s;
- pool->end = pool->start + pool->blocks->size;
- pool->ptr = pool->start;
- return XML_TRUE;
- }
- if (pool->end - pool->start < pool->freeBlocks->size) {
- BLOCK *tem = pool->freeBlocks->next;
- pool->freeBlocks->next = pool->blocks;
- pool->blocks = pool->freeBlocks;
- pool->freeBlocks = tem;
- memcpy(pool->blocks->s, pool->start,
- (pool->end - pool->start) * sizeof(XML_Char));
- pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
- pool->start = pool->blocks->s;
- pool->end = pool->start + pool->blocks->size;
- return XML_TRUE;
- }
- }
- if (pool->blocks && pool->start == pool->blocks->s) {
- int blockSize = (pool->end - pool->start)*2;
- pool->blocks = pool->mem->realloc_fcn(pool->blocks,
- offsetof(BLOCK, s)
- + blockSize * sizeof(XML_Char));
- if (pool->blocks == NULL)
- return XML_FALSE;
- pool->blocks->size = blockSize;
- pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
- pool->start = pool->blocks->s;
- pool->end = pool->start + blockSize;
- }
- else {
- BLOCK *tem;
- int blockSize = pool->end - pool->start;
- if (blockSize < INIT_BLOCK_SIZE)
- blockSize = INIT_BLOCK_SIZE;
- else
- blockSize *= 2;
- tem = pool->mem->malloc_fcn(offsetof(BLOCK, s)
- + blockSize * sizeof(XML_Char));
- if (!tem)
- return XML_FALSE;
- tem->size = blockSize;
- tem->next = pool->blocks;
- pool->blocks = tem;
- if (pool->ptr != pool->start)
- memcpy(tem->s, pool->start,
- (pool->ptr - pool->start) * sizeof(XML_Char));
- pool->ptr = tem->s + (pool->ptr - pool->start);
- pool->start = tem->s;
- pool->end = tem->s + blockSize;
- }
- return XML_TRUE;
-}
-
-static int FASTCALL
-nextScaffoldPart(XML_Parser parser)
-{
- CONTENT_SCAFFOLD * me;
- int next;
-
- if (!dtd.scaffIndex) {
- dtd.scaffIndex = MALLOC(groupSize * sizeof(int));
- if (!dtd.scaffIndex)
- return -1;
- dtd.scaffIndex[0] = 0;
- }
-
- if (dtd.scaffCount >= dtd.scaffSize) {
- CONTENT_SCAFFOLD *temp;
- if (dtd.scaffold) {
- temp = (CONTENT_SCAFFOLD *)
- REALLOC(dtd.scaffold, dtd.scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
- if (temp == NULL)
- return -1;
- dtd.scaffSize *= 2;
- }
- else {
- temp = MALLOC(INIT_SCAFFOLD_ELEMENTS * sizeof(CONTENT_SCAFFOLD));
- if (temp == NULL)
- return -1;
- dtd.scaffSize = INIT_SCAFFOLD_ELEMENTS;
- }
- dtd.scaffold = temp;
- }
- next = dtd.scaffCount++;
- me = &dtd.scaffold[next];
- if (dtd.scaffLevel) {
- CONTENT_SCAFFOLD *parent = &dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel-1]];
- if (parent->lastchild) {
- dtd.scaffold[parent->lastchild].nextsib = next;
- }
- if (!parent->childcnt)
- parent->firstchild = next;
- parent->lastchild = next;
- parent->childcnt++;
- }
- me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
- return next;
-}
-
-static void FASTCALL
-build_node(XML_Parser parser,
- int src_node,
- XML_Content *dest,
- XML_Content **contpos,
- XML_Char **strpos)
-{
- dest->type = dtd.scaffold[src_node].type;
- dest->quant = dtd.scaffold[src_node].quant;
- if (dest->type == XML_CTYPE_NAME) {
- const XML_Char *src;
- dest->name = *strpos;
- src = dtd.scaffold[src_node].name;
- for (;;) {
- *(*strpos)++ = *src;
- if (!*src)
- break;
- src++;
- }
- dest->numchildren = 0;
- dest->children = NULL;
- }
- else {
- unsigned int i;
- int cn;
- dest->numchildren = dtd.scaffold[src_node].childcnt;
- dest->children = *contpos;
- *contpos += dest->numchildren;
- for (i = 0, cn = dtd.scaffold[src_node].firstchild;
- i < dest->numchildren;
- i++, cn = dtd.scaffold[cn].nextsib) {
- build_node(parser, cn, &(dest->children[i]), contpos, strpos);
- }
- dest->name = NULL;
- }
-}
-
-static XML_Content * FASTCALL
-build_model (XML_Parser parser)
-{
- XML_Content *ret;
- XML_Content *cpos;
- XML_Char * str;
- int allocsize = (dtd.scaffCount * sizeof(XML_Content)
- + (dtd.contentStringLen * sizeof(XML_Char)));
-
- ret = MALLOC(allocsize);
- if (!ret)
- return NULL;
-
- str = (XML_Char *) (&ret[dtd.scaffCount]);
- cpos = &ret[1];
-
- build_node(parser, 0, ret, &cpos, &str);
- return ret;
-}
-
-static ELEMENT_TYPE * FASTCALL
-getElementType(XML_Parser parser,
- const ENCODING *enc,
- const char *ptr,
- const char *end)
-{
- const XML_Char *name = poolStoreString(&dtd.pool, enc, ptr, end);
- ELEMENT_TYPE *ret;
-
- if (!name)
- return NULL;
- ret = (ELEMENT_TYPE *) lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
- if (!ret)
- return NULL;
- if (ret->name != name)
- poolDiscard(&dtd.pool);
- else {
- poolFinish(&dtd.pool);
- if (!setElementTypePrefix(parser, ret))
- return NULL;
- }
- return ret;
-}
diff --git a/bundle/expat/xmlrole.c b/bundle/expat/xmlrole.c
deleted file mode 100644
index d9a2367087..0000000000
--- a/bundle/expat/xmlrole.c
+++ /dev/null
@@ -1,1330 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-#if PHP_WIN32
-#include "config.w32.h"
-#else
-#include "php_config.h"
-#endif
-#include "php_compat.h"
-
-#ifdef COMPILED_FROM_DSP
-#include "winconfig.h"
-#elif defined(MACOS_CLASSIC)
-#include "macconfig.h"
-/*
-#else
-#include <php_config.h>
-*/
-#endif /* ndef COMPILED_FROM_DSP */
-
-#include "internal.h"
-#include "xmlrole.h"
-#include "ascii.h"
-
-/* Doesn't check:
-
- that ,| are not mixed in a model group
- content of literals
-
-*/
-
-static const char KW_ANY[] = {
- ASCII_A, ASCII_N, ASCII_Y, '\0' };
-static const char KW_ATTLIST[] = {
- ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' };
-static const char KW_CDATA[] = {
- ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
-static const char KW_DOCTYPE[] = {
- ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' };
-static const char KW_ELEMENT[] = {
- ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' };
-static const char KW_EMPTY[] = {
- ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' };
-static const char KW_ENTITIES[] = {
- ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S,
- '\0' };
-static const char KW_ENTITY[] = {
- ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
-static const char KW_FIXED[] = {
- ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' };
-static const char KW_ID[] = {
- ASCII_I, ASCII_D, '\0' };
-static const char KW_IDREF[] = {
- ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
-static const char KW_IDREFS[] = {
- ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
-static const char KW_IGNORE[] = {
- ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' };
-static const char KW_IMPLIED[] = {
- ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' };
-static const char KW_INCLUDE[] = {
- ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' };
-static const char KW_NDATA[] = {
- ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
-static const char KW_NMTOKEN[] = {
- ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
-static const char KW_NMTOKENS[] = {
- ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S,
- '\0' };
-static const char KW_NOTATION[] =
- { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N,
- '\0' };
-static const char KW_PCDATA[] = {
- ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
-static const char KW_PUBLIC[] = {
- ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' };
-static const char KW_REQUIRED[] = {
- ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D,
- '\0' };
-static const char KW_SYSTEM[] = {
- ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' };
-
-#ifndef MIN_BYTES_PER_CHAR
-#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)
-#endif
-
-#ifdef XML_DTD
-#define setTopLevel(state) \
- ((state)->handler = ((state)->documentEntity \
- ? internalSubset \
- : externalSubset1))
-#else /* not XML_DTD */
-#define setTopLevel(state) ((state)->handler = internalSubset)
-#endif /* not XML_DTD */
-
-typedef int FASTCALL PROLOG_HANDLER(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc);
-
-static PROLOG_HANDLER
- prolog0, prolog1, prolog2,
- doctype0, doctype1, doctype2, doctype3, doctype4, doctype5,
- internalSubset,
- entity0, entity1, entity2, entity3, entity4, entity5, entity6,
- entity7, entity8, entity9, entity10,
- notation0, notation1, notation2, notation3, notation4,
- attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6,
- attlist7, attlist8, attlist9,
- element0, element1, element2, element3, element4, element5, element6,
- element7,
-#ifdef XML_DTD
- externalSubset0, externalSubset1,
- condSect0, condSect1, condSect2,
-#endif /* XML_DTD */
- declClose,
- error;
-
-static int FASTCALL common(PROLOG_STATE *state, int tok);
-
-static int FASTCALL
-prolog0(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- state->handler = prolog1;
- return XML_ROLE_NONE;
- case XML_TOK_XML_DECL:
- state->handler = prolog1;
- return XML_ROLE_XML_DECL;
- case XML_TOK_PI:
- state->handler = prolog1;
- return XML_ROLE_PI;
- case XML_TOK_COMMENT:
- state->handler = prolog1;
- return XML_ROLE_COMMENT;
- case XML_TOK_BOM:
- return XML_ROLE_NONE;
- case XML_TOK_DECL_OPEN:
- if (!XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
- KW_DOCTYPE))
- break;
- state->handler = doctype0;
- return XML_ROLE_DOCTYPE_NONE;
- case XML_TOK_INSTANCE_START:
- state->handler = error;
- return XML_ROLE_INSTANCE_START;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-prolog1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NONE;
- case XML_TOK_PI:
- return XML_ROLE_PI;
- case XML_TOK_COMMENT:
- return XML_ROLE_COMMENT;
- case XML_TOK_BOM:
- return XML_ROLE_NONE;
- case XML_TOK_DECL_OPEN:
- if (!XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
- KW_DOCTYPE))
- break;
- state->handler = doctype0;
- return XML_ROLE_DOCTYPE_NONE;
- case XML_TOK_INSTANCE_START:
- state->handler = error;
- return XML_ROLE_INSTANCE_START;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-prolog2(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NONE;
- case XML_TOK_PI:
- return XML_ROLE_PI;
- case XML_TOK_COMMENT:
- return XML_ROLE_COMMENT;
- case XML_TOK_INSTANCE_START:
- state->handler = error;
- return XML_ROLE_INSTANCE_START;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-doctype0(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_DOCTYPE_NONE;
- case XML_TOK_NAME:
- case XML_TOK_PREFIXED_NAME:
- state->handler = doctype1;
- return XML_ROLE_DOCTYPE_NAME;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-doctype1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_DOCTYPE_NONE;
- case XML_TOK_OPEN_BRACKET:
- state->handler = internalSubset;
- return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
- case XML_TOK_DECL_CLOSE:
- state->handler = prolog2;
- return XML_ROLE_DOCTYPE_CLOSE;
- case XML_TOK_NAME:
- if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
- state->handler = doctype3;
- return XML_ROLE_DOCTYPE_NONE;
- }
- if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
- state->handler = doctype2;
- return XML_ROLE_DOCTYPE_NONE;
- }
- break;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-doctype2(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_DOCTYPE_NONE;
- case XML_TOK_LITERAL:
- state->handler = doctype3;
- return XML_ROLE_DOCTYPE_PUBLIC_ID;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-doctype3(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_DOCTYPE_NONE;
- case XML_TOK_LITERAL:
- state->handler = doctype4;
- return XML_ROLE_DOCTYPE_SYSTEM_ID;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-doctype4(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_DOCTYPE_NONE;
- case XML_TOK_OPEN_BRACKET:
- state->handler = internalSubset;
- return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
- case XML_TOK_DECL_CLOSE:
- state->handler = prolog2;
- return XML_ROLE_DOCTYPE_CLOSE;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-doctype5(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_DOCTYPE_NONE;
- case XML_TOK_DECL_CLOSE:
- state->handler = prolog2;
- return XML_ROLE_DOCTYPE_CLOSE;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-internalSubset(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NONE;
- case XML_TOK_DECL_OPEN:
- if (XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
- KW_ENTITY)) {
- state->handler = entity0;
- return XML_ROLE_ENTITY_NONE;
- }
- if (XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
- KW_ATTLIST)) {
- state->handler = attlist0;
- return XML_ROLE_ATTLIST_NONE;
- }
- if (XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
- KW_ELEMENT)) {
- state->handler = element0;
- return XML_ROLE_ELEMENT_NONE;
- }
- if (XmlNameMatchesAscii(enc,
- ptr + 2 * MIN_BYTES_PER_CHAR(enc),
- end,
- KW_NOTATION)) {
- state->handler = notation0;
- return XML_ROLE_NOTATION_NONE;
- }
- break;
- case XML_TOK_PI:
- return XML_ROLE_PI;
- case XML_TOK_COMMENT:
- return XML_ROLE_COMMENT;
- case XML_TOK_PARAM_ENTITY_REF:
- return XML_ROLE_PARAM_ENTITY_REF;
- case XML_TOK_CLOSE_BRACKET:
- state->handler = doctype5;
- return XML_ROLE_DOCTYPE_NONE;
- }
- return common(state, tok);
-}
-
-#ifdef XML_DTD
-
-static int FASTCALL
-externalSubset0(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- state->handler = externalSubset1;
- if (tok == XML_TOK_XML_DECL)
- return XML_ROLE_TEXT_DECL;
- return externalSubset1(state, tok, ptr, end, enc);
-}
-
-static int FASTCALL
-externalSubset1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_COND_SECT_OPEN:
- state->handler = condSect0;
- return XML_ROLE_NONE;
- case XML_TOK_COND_SECT_CLOSE:
- if (state->includeLevel == 0)
- break;
- state->includeLevel -= 1;
- return XML_ROLE_NONE;
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NONE;
- case XML_TOK_CLOSE_BRACKET:
- break;
- case XML_TOK_NONE:
- if (state->includeLevel)
- break;
- return XML_ROLE_NONE;
- default:
- return internalSubset(state, tok, ptr, end, enc);
- }
- return common(state, tok);
-}
-
-#endif /* XML_DTD */
-
-static int FASTCALL
-entity0(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_PERCENT:
- state->handler = entity1;
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_NAME:
- state->handler = entity2;
- return XML_ROLE_GENERAL_ENTITY_NAME;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-entity1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_NAME:
- state->handler = entity7;
- return XML_ROLE_PARAM_ENTITY_NAME;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-entity2(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_NAME:
- if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
- state->handler = entity4;
- return XML_ROLE_ENTITY_NONE;
- }
- if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
- state->handler = entity3;
- return XML_ROLE_ENTITY_NONE;
- }
- break;
- case XML_TOK_LITERAL:
- state->handler = declClose;
- state->role_none = XML_ROLE_ENTITY_NONE;
- return XML_ROLE_ENTITY_VALUE;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-entity3(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_LITERAL:
- state->handler = entity4;
- return XML_ROLE_ENTITY_PUBLIC_ID;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-entity4(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_LITERAL:
- state->handler = entity5;
- return XML_ROLE_ENTITY_SYSTEM_ID;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-entity5(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_DECL_CLOSE:
- setTopLevel(state);
- return XML_ROLE_ENTITY_COMPLETE;
- case XML_TOK_NAME:
- if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) {
- state->handler = entity6;
- return XML_ROLE_ENTITY_NONE;
- }
- break;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-entity6(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_NAME:
- state->handler = declClose;
- state->role_none = XML_ROLE_ENTITY_NONE;
- return XML_ROLE_ENTITY_NOTATION_NAME;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-entity7(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_NAME:
- if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
- state->handler = entity9;
- return XML_ROLE_ENTITY_NONE;
- }
- if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
- state->handler = entity8;
- return XML_ROLE_ENTITY_NONE;
- }
- break;
- case XML_TOK_LITERAL:
- state->handler = declClose;
- state->role_none = XML_ROLE_ENTITY_NONE;
- return XML_ROLE_ENTITY_VALUE;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-entity8(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_LITERAL:
- state->handler = entity9;
- return XML_ROLE_ENTITY_PUBLIC_ID;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-entity9(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_LITERAL:
- state->handler = entity10;
- return XML_ROLE_ENTITY_SYSTEM_ID;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-entity10(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ENTITY_NONE;
- case XML_TOK_DECL_CLOSE:
- setTopLevel(state);
- return XML_ROLE_ENTITY_COMPLETE;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-notation0(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NOTATION_NONE;
- case XML_TOK_NAME:
- state->handler = notation1;
- return XML_ROLE_NOTATION_NAME;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-notation1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NOTATION_NONE;
- case XML_TOK_NAME:
- if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
- state->handler = notation3;
- return XML_ROLE_NOTATION_NONE;
- }
- if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
- state->handler = notation2;
- return XML_ROLE_NOTATION_NONE;
- }
- break;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-notation2(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NOTATION_NONE;
- case XML_TOK_LITERAL:
- state->handler = notation4;
- return XML_ROLE_NOTATION_PUBLIC_ID;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-notation3(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NOTATION_NONE;
- case XML_TOK_LITERAL:
- state->handler = declClose;
- state->role_none = XML_ROLE_NOTATION_NONE;
- return XML_ROLE_NOTATION_SYSTEM_ID;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-notation4(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NOTATION_NONE;
- case XML_TOK_LITERAL:
- state->handler = declClose;
- state->role_none = XML_ROLE_NOTATION_NONE;
- return XML_ROLE_NOTATION_SYSTEM_ID;
- case XML_TOK_DECL_CLOSE:
- setTopLevel(state);
- return XML_ROLE_NOTATION_NO_SYSTEM_ID;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-attlist0(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_NAME:
- case XML_TOK_PREFIXED_NAME:
- state->handler = attlist1;
- return XML_ROLE_ATTLIST_ELEMENT_NAME;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-attlist1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_DECL_CLOSE:
- setTopLevel(state);
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_NAME:
- case XML_TOK_PREFIXED_NAME:
- state->handler = attlist2;
- return XML_ROLE_ATTRIBUTE_NAME;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-attlist2(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_NAME:
- {
- static const char *types[] = {
- KW_CDATA,
- KW_ID,
- KW_IDREF,
- KW_IDREFS,
- KW_ENTITY,
- KW_ENTITIES,
- KW_NMTOKEN,
- KW_NMTOKENS,
- };
- int i;
- for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++)
- if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {
- state->handler = attlist8;
- return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
- }
- }
- if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) {
- state->handler = attlist5;
- return XML_ROLE_ATTLIST_NONE;
- }
- break;
- case XML_TOK_OPEN_PAREN:
- state->handler = attlist3;
- return XML_ROLE_ATTLIST_NONE;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-attlist3(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_NMTOKEN:
- case XML_TOK_NAME:
- case XML_TOK_PREFIXED_NAME:
- state->handler = attlist4;
- return XML_ROLE_ATTRIBUTE_ENUM_VALUE;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-attlist4(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_CLOSE_PAREN:
- state->handler = attlist8;
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_OR:
- state->handler = attlist3;
- return XML_ROLE_ATTLIST_NONE;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-attlist5(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_OPEN_PAREN:
- state->handler = attlist6;
- return XML_ROLE_ATTLIST_NONE;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-attlist6(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_NAME:
- state->handler = attlist7;
- return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-attlist7(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_CLOSE_PAREN:
- state->handler = attlist8;
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_OR:
- state->handler = attlist6;
- return XML_ROLE_ATTLIST_NONE;
- }
- return common(state, tok);
-}
-
-/* default value */
-static int FASTCALL
-attlist8(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_POUND_NAME:
- if (XmlNameMatchesAscii(enc,
- ptr + MIN_BYTES_PER_CHAR(enc),
- end,
- KW_IMPLIED)) {
- state->handler = attlist1;
- return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE;
- }
- if (XmlNameMatchesAscii(enc,
- ptr + MIN_BYTES_PER_CHAR(enc),
- end,
- KW_REQUIRED)) {
- state->handler = attlist1;
- return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE;
- }
- if (XmlNameMatchesAscii(enc,
- ptr + MIN_BYTES_PER_CHAR(enc),
- end,
- KW_FIXED)) {
- state->handler = attlist9;
- return XML_ROLE_ATTLIST_NONE;
- }
- break;
- case XML_TOK_LITERAL:
- state->handler = attlist1;
- return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-attlist9(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ATTLIST_NONE;
- case XML_TOK_LITERAL:
- state->handler = attlist1;
- return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-element0(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ELEMENT_NONE;
- case XML_TOK_NAME:
- case XML_TOK_PREFIXED_NAME:
- state->handler = element1;
- return XML_ROLE_ELEMENT_NAME;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-element1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ELEMENT_NONE;
- case XML_TOK_NAME:
- if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) {
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- return XML_ROLE_CONTENT_EMPTY;
- }
- if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) {
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- return XML_ROLE_CONTENT_ANY;
- }
- break;
- case XML_TOK_OPEN_PAREN:
- state->handler = element2;
- state->level = 1;
- return XML_ROLE_GROUP_OPEN;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-element2(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ELEMENT_NONE;
- case XML_TOK_POUND_NAME:
- if (XmlNameMatchesAscii(enc,
- ptr + MIN_BYTES_PER_CHAR(enc),
- end,
- KW_PCDATA)) {
- state->handler = element3;
- return XML_ROLE_CONTENT_PCDATA;
- }
- break;
- case XML_TOK_OPEN_PAREN:
- state->level = 2;
- state->handler = element6;
- return XML_ROLE_GROUP_OPEN;
- case XML_TOK_NAME:
- case XML_TOK_PREFIXED_NAME:
- state->handler = element7;
- return XML_ROLE_CONTENT_ELEMENT;
- case XML_TOK_NAME_QUESTION:
- state->handler = element7;
- return XML_ROLE_CONTENT_ELEMENT_OPT;
- case XML_TOK_NAME_ASTERISK:
- state->handler = element7;
- return XML_ROLE_CONTENT_ELEMENT_REP;
- case XML_TOK_NAME_PLUS:
- state->handler = element7;
- return XML_ROLE_CONTENT_ELEMENT_PLUS;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-element3(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ELEMENT_NONE;
- case XML_TOK_CLOSE_PAREN:
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- return XML_ROLE_GROUP_CLOSE;
- case XML_TOK_CLOSE_PAREN_ASTERISK:
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- return XML_ROLE_GROUP_CLOSE_REP;
- case XML_TOK_OR:
- state->handler = element4;
- return XML_ROLE_ELEMENT_NONE;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-element4(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ELEMENT_NONE;
- case XML_TOK_NAME:
- case XML_TOK_PREFIXED_NAME:
- state->handler = element5;
- return XML_ROLE_CONTENT_ELEMENT;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-element5(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ELEMENT_NONE;
- case XML_TOK_CLOSE_PAREN_ASTERISK:
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- return XML_ROLE_GROUP_CLOSE_REP;
- case XML_TOK_OR:
- state->handler = element4;
- return XML_ROLE_ELEMENT_NONE;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-element6(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ELEMENT_NONE;
- case XML_TOK_OPEN_PAREN:
- state->level += 1;
- return XML_ROLE_GROUP_OPEN;
- case XML_TOK_NAME:
- case XML_TOK_PREFIXED_NAME:
- state->handler = element7;
- return XML_ROLE_CONTENT_ELEMENT;
- case XML_TOK_NAME_QUESTION:
- state->handler = element7;
- return XML_ROLE_CONTENT_ELEMENT_OPT;
- case XML_TOK_NAME_ASTERISK:
- state->handler = element7;
- return XML_ROLE_CONTENT_ELEMENT_REP;
- case XML_TOK_NAME_PLUS:
- state->handler = element7;
- return XML_ROLE_CONTENT_ELEMENT_PLUS;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-element7(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_ELEMENT_NONE;
- case XML_TOK_CLOSE_PAREN:
- state->level -= 1;
- if (state->level == 0) {
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- }
- return XML_ROLE_GROUP_CLOSE;
- case XML_TOK_CLOSE_PAREN_ASTERISK:
- state->level -= 1;
- if (state->level == 0) {
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- }
- return XML_ROLE_GROUP_CLOSE_REP;
- case XML_TOK_CLOSE_PAREN_QUESTION:
- state->level -= 1;
- if (state->level == 0) {
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- }
- return XML_ROLE_GROUP_CLOSE_OPT;
- case XML_TOK_CLOSE_PAREN_PLUS:
- state->level -= 1;
- if (state->level == 0) {
- state->handler = declClose;
- state->role_none = XML_ROLE_ELEMENT_NONE;
- }
- return XML_ROLE_GROUP_CLOSE_PLUS;
- case XML_TOK_COMMA:
- state->handler = element6;
- return XML_ROLE_GROUP_SEQUENCE;
- case XML_TOK_OR:
- state->handler = element6;
- return XML_ROLE_GROUP_CHOICE;
- }
- return common(state, tok);
-}
-
-#ifdef XML_DTD
-
-static int FASTCALL
-condSect0(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NONE;
- case XML_TOK_NAME:
- if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) {
- state->handler = condSect1;
- return XML_ROLE_NONE;
- }
- if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) {
- state->handler = condSect2;
- return XML_ROLE_NONE;
- }
- break;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-condSect1(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NONE;
- case XML_TOK_OPEN_BRACKET:
- state->handler = externalSubset1;
- state->includeLevel += 1;
- return XML_ROLE_NONE;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-condSect2(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return XML_ROLE_NONE;
- case XML_TOK_OPEN_BRACKET:
- state->handler = externalSubset1;
- return XML_ROLE_IGNORE_SECT;
- }
- return common(state, tok);
-}
-
-#endif /* XML_DTD */
-
-static int FASTCALL
-declClose(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- switch (tok) {
- case XML_TOK_PROLOG_S:
- return state->role_none;
- case XML_TOK_DECL_CLOSE:
- setTopLevel(state);
- return state->role_none;
- }
- return common(state, tok);
-}
-
-static int FASTCALL
-error(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
-{
- return XML_ROLE_NONE;
-}
-
-static int FASTCALL
-common(PROLOG_STATE *state, int tok)
-{
-#ifdef XML_DTD
- if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
- return XML_ROLE_INNER_PARAM_ENTITY_REF;
-#endif
- state->handler = error;
- return XML_ROLE_ERROR;
-}
-
-void
-XmlPrologStateInit(PROLOG_STATE *state)
-{
- state->handler = prolog0;
-#ifdef XML_DTD
- state->documentEntity = 1;
- state->includeLevel = 0;
- state->inEntityValue = 0;
-#endif /* XML_DTD */
-}
-
-#ifdef XML_DTD
-
-void
-XmlPrologStateInitExternalEntity(PROLOG_STATE *state)
-{
- state->handler = externalSubset0;
- state->documentEntity = 0;
- state->includeLevel = 0;
-}
-
-#endif /* XML_DTD */
diff --git a/bundle/expat/xmlrole.h b/bundle/expat/xmlrole.h
deleted file mode 100644
index 281aba0481..0000000000
--- a/bundle/expat/xmlrole.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-#ifndef XmlRole_INCLUDED
-#define XmlRole_INCLUDED 1
-
-#ifdef __VMS
-/* 0 1 2 3 0 1 2 3
- 1234567890123456789012345678901 1234567890123456789012345678901 */
-#define XmlPrologStateInitExternalEntity XmlPrologStateInitExternalEnt
-#endif
-
-#include "xmltok.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum {
- XML_ROLE_ERROR = -1,
- XML_ROLE_NONE = 0,
- XML_ROLE_XML_DECL,
- XML_ROLE_INSTANCE_START,
- XML_ROLE_DOCTYPE_NONE,
- XML_ROLE_DOCTYPE_NAME,
- XML_ROLE_DOCTYPE_SYSTEM_ID,
- XML_ROLE_DOCTYPE_PUBLIC_ID,
- XML_ROLE_DOCTYPE_INTERNAL_SUBSET,
- XML_ROLE_DOCTYPE_CLOSE,
- XML_ROLE_GENERAL_ENTITY_NAME,
- XML_ROLE_PARAM_ENTITY_NAME,
- XML_ROLE_ENTITY_NONE,
- XML_ROLE_ENTITY_VALUE,
- XML_ROLE_ENTITY_SYSTEM_ID,
- XML_ROLE_ENTITY_PUBLIC_ID,
- XML_ROLE_ENTITY_COMPLETE,
- XML_ROLE_ENTITY_NOTATION_NAME,
- XML_ROLE_NOTATION_NONE,
- XML_ROLE_NOTATION_NAME,
- XML_ROLE_NOTATION_SYSTEM_ID,
- XML_ROLE_NOTATION_NO_SYSTEM_ID,
- XML_ROLE_NOTATION_PUBLIC_ID,
- XML_ROLE_ATTRIBUTE_NAME,
- XML_ROLE_ATTRIBUTE_TYPE_CDATA,
- XML_ROLE_ATTRIBUTE_TYPE_ID,
- XML_ROLE_ATTRIBUTE_TYPE_IDREF,
- XML_ROLE_ATTRIBUTE_TYPE_IDREFS,
- XML_ROLE_ATTRIBUTE_TYPE_ENTITY,
- XML_ROLE_ATTRIBUTE_TYPE_ENTITIES,
- XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN,
- XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS,
- XML_ROLE_ATTRIBUTE_ENUM_VALUE,
- XML_ROLE_ATTRIBUTE_NOTATION_VALUE,
- XML_ROLE_ATTLIST_NONE,
- XML_ROLE_ATTLIST_ELEMENT_NAME,
- XML_ROLE_IMPLIED_ATTRIBUTE_VALUE,
- XML_ROLE_REQUIRED_ATTRIBUTE_VALUE,
- XML_ROLE_DEFAULT_ATTRIBUTE_VALUE,
- XML_ROLE_FIXED_ATTRIBUTE_VALUE,
- XML_ROLE_ELEMENT_NONE,
- XML_ROLE_ELEMENT_NAME,
- XML_ROLE_CONTENT_ANY,
- XML_ROLE_CONTENT_EMPTY,
- XML_ROLE_CONTENT_PCDATA,
- XML_ROLE_GROUP_OPEN,
- XML_ROLE_GROUP_CLOSE,
- XML_ROLE_GROUP_CLOSE_REP,
- XML_ROLE_GROUP_CLOSE_OPT,
- XML_ROLE_GROUP_CLOSE_PLUS,
- XML_ROLE_GROUP_CHOICE,
- XML_ROLE_GROUP_SEQUENCE,
- XML_ROLE_CONTENT_ELEMENT,
- XML_ROLE_CONTENT_ELEMENT_REP,
- XML_ROLE_CONTENT_ELEMENT_OPT,
- XML_ROLE_CONTENT_ELEMENT_PLUS,
- XML_ROLE_PI,
- XML_ROLE_COMMENT,
-#ifdef XML_DTD
- XML_ROLE_TEXT_DECL,
- XML_ROLE_IGNORE_SECT,
- XML_ROLE_INNER_PARAM_ENTITY_REF,
-#endif /* XML_DTD */
- XML_ROLE_PARAM_ENTITY_REF
-};
-
-typedef struct prolog_state {
- int (FASTCALL *handler) (struct prolog_state *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc);
- unsigned level;
- int role_none;
-#ifdef XML_DTD
- unsigned includeLevel;
- int documentEntity;
- int inEntityValue;
-#endif /* XML_DTD */
-} PROLOG_STATE;
-
-void XmlPrologStateInit(PROLOG_STATE *);
-#ifdef XML_DTD
-void XmlPrologStateInitExternalEntity(PROLOG_STATE *);
-#endif /* XML_DTD */
-
-#define XmlTokenRole(state, tok, ptr, end, enc) \
- (((state)->handler)(state, tok, ptr, end, enc))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* not XmlRole_INCLUDED */
diff --git a/bundle/expat/xmltok.c b/bundle/expat/xmltok.c
deleted file mode 100644
index 0a11e56748..0000000000
--- a/bundle/expat/xmltok.c
+++ /dev/null
@@ -1,1641 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-#if PHP_WIN32
-#include "config.w32.h"
-#else
-#include "php_config.h"
-#endif
-#include "php_compat.h"
-
-#ifdef COMPILED_FROM_DSP
-#include "winconfig.h"
-#elif defined(MACOS_CLASSIC)
-#include "macconfig.h"
-/*
-#else
-#include <php_config.h>
-*/
-#endif /* ndef COMPILED_FROM_DSP */
-
-#include "internal.h"
-#include "xmltok.h"
-#include "nametab.h"
-
-#ifdef XML_DTD
-#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)
-#else
-#define IGNORE_SECTION_TOK_VTABLE /* as nothing */
-#endif
-
-#define VTABLE1 \
- { PREFIX(prologTok), PREFIX(contentTok), \
- PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \
- { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \
- PREFIX(sameName), \
- PREFIX(nameMatchesAscii), \
- PREFIX(nameLength), \
- PREFIX(skipS), \
- PREFIX(getAtts), \
- PREFIX(charRefNumber), \
- PREFIX(predefinedEntityName), \
- PREFIX(updatePosition), \
- PREFIX(isPublicId)
-
-#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
-
-#define UCS2_GET_NAMING(pages, hi, lo) \
- (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))
-
-/* A 2 byte UTF-8 representation splits the characters 11 bits between
- the bottom 5 and 6 bits of the bytes. We need 8 bits to index into
- pages, 3 bits to add to that index and 5 bits to generate the mask.
-*/
-#define UTF8_GET_NAMING2(pages, byte) \
- (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
- + ((((byte)[0]) & 3) << 1) \
- + ((((byte)[1]) >> 5) & 1)] \
- & (1 << (((byte)[1]) & 0x1F)))
-
-/* A 3 byte UTF-8 representation splits the characters 16 bits between
- the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index
- into pages, 3 bits to add to that index and 5 bits to generate the
- mask.
-*/
-#define UTF8_GET_NAMING3(pages, byte) \
- (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \
- + ((((byte)[1]) >> 2) & 0xF)] \
- << 3) \
- + ((((byte)[1]) & 3) << 1) \
- + ((((byte)[2]) >> 5) & 1)] \
- & (1 << (((byte)[2]) & 0x1F)))
-
-#define UTF8_GET_NAMING(pages, p, n) \
- ((n) == 2 \
- ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \
- : ((n) == 3 \
- ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
- : 0))
-
-/* Detection of invalid UTF-8 sequences is based on Table 3.1B
- of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/
- with the additional restriction of not allowing the Unicode
- code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE).
- Implementation details:
- (A & 0x80) == 0 means A < 0x80
- and
- (A & 0xC0) == 0xC0 means A > 0xBF
-*/
-
-#define UTF8_INVALID2(p) \
- ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0)
-
-#define UTF8_INVALID3(p) \
- (((p)[2] & 0x80) == 0 \
- || \
- ((*p) == 0xEF && (p)[1] == 0xBF \
- ? \
- (p)[2] > 0xBD \
- : \
- ((p)[2] & 0xC0) == 0xC0) \
- || \
- ((*p) == 0xE0 \
- ? \
- (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \
- : \
- ((p)[1] & 0x80) == 0 \
- || \
- ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0)))
-
-#define UTF8_INVALID4(p) \
- (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 \
- || \
- ((p)[2] & 0x80) == 0 || ((p)[2] & 0xC0) == 0xC0 \
- || \
- ((*p) == 0xF0 \
- ? \
- (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \
- : \
- ((p)[1] & 0x80) == 0 \
- || \
- ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
-
-static int FASTCALL
-isNever(const ENCODING *enc, const char *p)
-{
- return 0;
-}
-
-static int FASTCALL
-utf8_isName2(const ENCODING *enc, const char *p)
-{
- return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
-}
-
-static int FASTCALL
-utf8_isName3(const ENCODING *enc, const char *p)
-{
- return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
-}
-
-#define utf8_isName4 isNever
-
-static int FASTCALL
-utf8_isNmstrt2(const ENCODING *enc, const char *p)
-{
- return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
-}
-
-static int FASTCALL
-utf8_isNmstrt3(const ENCODING *enc, const char *p)
-{
- return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
-}
-
-#define utf8_isNmstrt4 isNever
-
-static int FASTCALL
-utf8_isInvalid2(const ENCODING *enc, const char *p)
-{
- return UTF8_INVALID2((const unsigned char *)p);
-}
-
-static int FASTCALL
-utf8_isInvalid3(const ENCODING *enc, const char *p)
-{
- return UTF8_INVALID3((const unsigned char *)p);
-}
-
-static int FASTCALL
-utf8_isInvalid4(const ENCODING *enc, const char *p)
-{
- return UTF8_INVALID4((const unsigned char *)p);
-}
-
-struct normal_encoding {
- ENCODING enc;
- unsigned char type[256];
-#ifdef XML_MIN_SIZE
- int (FASTCALL *byteType)(const ENCODING *, const char *);
- int (FASTCALL *isNameMin)(const ENCODING *, const char *);
- int (FASTCALL *isNmstrtMin)(const ENCODING *, const char *);
- int (FASTCALL *byteToAscii)(const ENCODING *, const char *);
- int (FASTCALL *charMatches)(const ENCODING *, const char *, int);
-#endif /* XML_MIN_SIZE */
- int (FASTCALL *isName2)(const ENCODING *, const char *);
- int (FASTCALL *isName3)(const ENCODING *, const char *);
- int (FASTCALL *isName4)(const ENCODING *, const char *);
- int (FASTCALL *isNmstrt2)(const ENCODING *, const char *);
- int (FASTCALL *isNmstrt3)(const ENCODING *, const char *);
- int (FASTCALL *isNmstrt4)(const ENCODING *, const char *);
- int (FASTCALL *isInvalid2)(const ENCODING *, const char *);
- int (FASTCALL *isInvalid3)(const ENCODING *, const char *);
- int (FASTCALL *isInvalid4)(const ENCODING *, const char *);
-};
-
-#define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *) (enc))
-
-#ifdef XML_MIN_SIZE
-
-#define STANDARD_VTABLE(E) \
- E ## byteType, \
- E ## isNameMin, \
- E ## isNmstrtMin, \
- E ## byteToAscii, \
- E ## charMatches,
-
-#else
-
-#define STANDARD_VTABLE(E) /* as nothing */
-
-#endif
-
-#define NORMAL_VTABLE(E) \
- E ## isName2, \
- E ## isName3, \
- E ## isName4, \
- E ## isNmstrt2, \
- E ## isNmstrt3, \
- E ## isNmstrt4, \
- E ## isInvalid2, \
- E ## isInvalid3, \
- E ## isInvalid4
-
-static int FASTCALL checkCharRefNumber(int);
-
-#include "xmltok_impl.h"
-#include "ascii.h"
-
-#ifdef XML_MIN_SIZE
-#define sb_isNameMin isNever
-#define sb_isNmstrtMin isNever
-#endif
-
-#ifdef XML_MIN_SIZE
-#define MINBPC(enc) ((enc)->minBytesPerChar)
-#else
-/* minimum bytes per character */
-#define MINBPC(enc) 1
-#endif
-
-#define SB_BYTE_TYPE(enc, p) \
- (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
-
-#ifdef XML_MIN_SIZE
-static int FASTCALL
-sb_byteType(const ENCODING *enc, const char *p)
-{
- return SB_BYTE_TYPE(enc, p);
-}
-#define BYTE_TYPE(enc, p) \
- (AS_NORMAL_ENCODING(enc)->byteType(enc, p))
-#else
-#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
-#endif
-
-#ifdef XML_MIN_SIZE
-#define BYTE_TO_ASCII(enc, p) \
- (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p))
-static int FASTCALL
-sb_byteToAscii(const ENCODING *enc, const char *p)
-{
- return *p;
-}
-#else
-#define BYTE_TO_ASCII(enc, p) (*(p))
-#endif
-
-#define IS_NAME_CHAR(enc, p, n) \
- (AS_NORMAL_ENCODING(enc)->isName ## n(enc, p))
-#define IS_NMSTRT_CHAR(enc, p, n) \
- (AS_NORMAL_ENCODING(enc)->isNmstrt ## n(enc, p))
-#define IS_INVALID_CHAR(enc, p, n) \
- (AS_NORMAL_ENCODING(enc)->isInvalid ## n(enc, p))
-
-#ifdef XML_MIN_SIZE
-#define IS_NAME_CHAR_MINBPC(enc, p) \
- (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p))
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) \
- (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p))
-#else
-#define IS_NAME_CHAR_MINBPC(enc, p) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
-#endif
-
-#ifdef XML_MIN_SIZE
-#define CHAR_MATCHES(enc, p, c) \
- (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c))
-static int FASTCALL
-sb_charMatches(const ENCODING *enc, const char *p, int c)
-{
- return *p == c;
-}
-#else
-/* c is an ASCII character */
-#define CHAR_MATCHES(enc, p, c) (*(p) == c)
-#endif
-
-#define PREFIX(ident) normal_ ## ident
-#include "xmltok_impl.c"
-
-#undef MINBPC
-#undef BYTE_TYPE
-#undef BYTE_TO_ASCII
-#undef CHAR_MATCHES
-#undef IS_NAME_CHAR
-#undef IS_NAME_CHAR_MINBPC
-#undef IS_NMSTRT_CHAR
-#undef IS_NMSTRT_CHAR_MINBPC
-#undef IS_INVALID_CHAR
-
-enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */
- UTF8_cval1 = 0x00,
- UTF8_cval2 = 0xc0,
- UTF8_cval3 = 0xe0,
- UTF8_cval4 = 0xf0
-};
-
-static void FASTCALL
-utf8_toUtf8(const ENCODING *enc,
- const char **fromP, const char *fromLim,
- char **toP, const char *toLim)
-{
- char *to;
- const char *from;
- if (fromLim - *fromP > toLim - *toP) {
- /* Avoid copying partial characters. */
- for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
- if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
- break;
- }
- for (to = *toP, from = *fromP; from != fromLim; from++, to++)
- *to = *from;
- *fromP = from;
- *toP = to;
-}
-
-static void FASTCALL
-utf8_toUtf16(const ENCODING *enc,
- const char **fromP, const char *fromLim,
- unsigned short **toP, const unsigned short *toLim)
-{
- unsigned short *to = *toP;
- const char *from = *fromP;
- while (from != fromLim && to != toLim) {
- switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
- case BT_LEAD2:
- *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
- from += 2;
- break;
- case BT_LEAD3:
- *to++ = (unsigned short)(((from[0] & 0xf) << 12)
- | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));
- from += 3;
- break;
- case BT_LEAD4:
- {
- unsigned long n;
- if (to + 1 == toLim)
- goto after;
- n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)
- | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
- n -= 0x10000;
- to[0] = (unsigned short)((n >> 10) | 0xD800);
- to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
- to += 2;
- from += 4;
- }
- break;
- default:
- *to++ = *from++;
- break;
- }
- }
-after:
- *fromP = from;
- *toP = to;
-}
-
-#ifdef XML_NS
-static const struct normal_encoding utf8_encoding_ns = {
- { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
- {
-#include "asciitab.h"
-#include "utf8tab.h"
- },
- STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-};
-#endif
-
-static const struct normal_encoding utf8_encoding = {
- { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
- {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-#include "utf8tab.h"
- },
- STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-};
-
-#ifdef XML_NS
-
-static const struct normal_encoding internal_utf8_encoding_ns = {
- { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
- {
-#include "iasciitab.h"
-#include "utf8tab.h"
- },
- STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-};
-
-#endif
-
-static const struct normal_encoding internal_utf8_encoding = {
- { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
- {
-#define BT_COLON BT_NMSTRT
-#include "iasciitab.h"
-#undef BT_COLON
-#include "utf8tab.h"
- },
- STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-};
-
-static void FASTCALL
-latin1_toUtf8(const ENCODING *enc,
- const char **fromP, const char *fromLim,
- char **toP, const char *toLim)
-{
- for (;;) {
- unsigned char c;
- if (*fromP == fromLim)
- break;
- c = (unsigned char)**fromP;
- if (c & 0x80) {
- if (toLim - *toP < 2)
- break;
- *(*toP)++ = (char)((c >> 6) | UTF8_cval2);
- *(*toP)++ = (char)((c & 0x3f) | 0x80);
- (*fromP)++;
- }
- else {
- if (*toP == toLim)
- break;
- *(*toP)++ = *(*fromP)++;
- }
- }
-}
-
-static void FASTCALL
-latin1_toUtf16(const ENCODING *enc,
- const char **fromP, const char *fromLim,
- unsigned short **toP, const unsigned short *toLim)
-{
- while (*fromP != fromLim && *toP != toLim)
- *(*toP)++ = (unsigned char)*(*fromP)++;
-}
-
-#ifdef XML_NS
-
-static const struct normal_encoding latin1_encoding_ns = {
- { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
- {
-#include "asciitab.h"
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(sb_)
-};
-
-#endif
-
-static const struct normal_encoding latin1_encoding = {
- { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
- {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(sb_)
-};
-
-static void FASTCALL
-ascii_toUtf8(const ENCODING *enc,
- const char **fromP, const char *fromLim,
- char **toP, const char *toLim)
-{
- while (*fromP != fromLim && *toP != toLim)
- *(*toP)++ = *(*fromP)++;
-}
-
-#ifdef XML_NS
-
-static const struct normal_encoding ascii_encoding_ns = {
- { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
- {
-#include "asciitab.h"
-/* BT_NONXML == 0 */
- },
- STANDARD_VTABLE(sb_)
-};
-
-#endif
-
-static const struct normal_encoding ascii_encoding = {
- { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
- {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-/* BT_NONXML == 0 */
- },
- STANDARD_VTABLE(sb_)
-};
-
-static int FASTCALL
-unicode_byte_type(char hi, char lo)
-{
- switch ((unsigned char)hi) {
- case 0xD8: case 0xD9: case 0xDA: case 0xDB:
- return BT_LEAD4;
- case 0xDC: case 0xDD: case 0xDE: case 0xDF:
- return BT_TRAIL;
- case 0xFF:
- switch ((unsigned char)lo) {
- case 0xFF:
- case 0xFE:
- return BT_NONXML;
- }
- break;
- }
- return BT_NONASCII;
-}
-
-#define DEFINE_UTF16_TO_UTF8(E) \
-static void FASTCALL \
-E ## toUtf8(const ENCODING *enc, \
- const char **fromP, const char *fromLim, \
- char **toP, const char *toLim) \
-{ \
- const char *from; \
- for (from = *fromP; from != fromLim; from += 2) { \
- int plane; \
- unsigned char lo2; \
- unsigned char lo = GET_LO(from); \
- unsigned char hi = GET_HI(from); \
- switch (hi) { \
- case 0: \
- if (lo < 0x80) { \
- if (*toP == toLim) { \
- *fromP = from; \
- return; \
- } \
- *(*toP)++ = lo; \
- break; \
- } \
- /* fall through */ \
- case 0x1: case 0x2: case 0x3: \
- case 0x4: case 0x5: case 0x6: case 0x7: \
- if (toLim - *toP < 2) { \
- *fromP = from; \
- return; \
- } \
- *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \
- *(*toP)++ = ((lo & 0x3f) | 0x80); \
- break; \
- default: \
- if (toLim - *toP < 3) { \
- *fromP = from; \
- return; \
- } \
- /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
- *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
- *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \
- *(*toP)++ = ((lo & 0x3f) | 0x80); \
- break; \
- case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
- if (toLim - *toP < 4) { \
- *fromP = from; \
- return; \
- } \
- plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
- *(*toP)++ = ((plane >> 2) | UTF8_cval4); \
- *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \
- from += 2; \
- lo2 = GET_LO(from); \
- *(*toP)++ = (((lo & 0x3) << 4) \
- | ((GET_HI(from) & 0x3) << 2) \
- | (lo2 >> 6) \
- | 0x80); \
- *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
- break; \
- } \
- } \
- *fromP = from; \
-}
-
-#define DEFINE_UTF16_TO_UTF16(E) \
-static void FASTCALL \
-E ## toUtf16(const ENCODING *enc, \
- const char **fromP, const char *fromLim, \
- unsigned short **toP, const unsigned short *toLim) \
-{ \
- /* Avoid copying first half only of surrogate */ \
- if (fromLim - *fromP > ((toLim - *toP) << 1) \
- && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \
- fromLim -= 2; \
- for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \
- *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
-}
-
-#define SET2(ptr, ch) \
- (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))
-#define GET_LO(ptr) ((unsigned char)(ptr)[0])
-#define GET_HI(ptr) ((unsigned char)(ptr)[1])
-
-DEFINE_UTF16_TO_UTF8(little2_)
-DEFINE_UTF16_TO_UTF16(little2_)
-
-#undef SET2
-#undef GET_LO
-#undef GET_HI
-
-#define SET2(ptr, ch) \
- (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF)))
-#define GET_LO(ptr) ((unsigned char)(ptr)[1])
-#define GET_HI(ptr) ((unsigned char)(ptr)[0])
-
-DEFINE_UTF16_TO_UTF8(big2_)
-DEFINE_UTF16_TO_UTF16(big2_)
-
-#undef SET2
-#undef GET_LO
-#undef GET_HI
-
-#define LITTLE2_BYTE_TYPE(enc, p) \
- ((p)[1] == 0 \
- ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \
- : unicode_byte_type((p)[1], (p)[0]))
-#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1)
-#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c)
-#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \
- UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
-#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
- UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
-
-#ifdef XML_MIN_SIZE
-
-static int FASTCALL
-little2_byteType(const ENCODING *enc, const char *p)
-{
- return LITTLE2_BYTE_TYPE(enc, p);
-}
-
-static int FASTCALL
-little2_byteToAscii(const ENCODING *enc, const char *p)
-{
- return LITTLE2_BYTE_TO_ASCII(enc, p);
-}
-
-static int FASTCALL
-little2_charMatches(const ENCODING *enc, const char *p, int c)
-{
- return LITTLE2_CHAR_MATCHES(enc, p, c);
-}
-
-static int FASTCALL
-little2_isNameMin(const ENCODING *enc, const char *p)
-{
- return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p);
-}
-
-static int FASTCALL
-little2_isNmstrtMin(const ENCODING *enc, const char *p)
-{
- return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p);
-}
-
-#undef VTABLE
-#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
-
-#else /* not XML_MIN_SIZE */
-
-#undef PREFIX
-#define PREFIX(ident) little2_ ## ident
-#define MINBPC(enc) 2
-/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
-#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
-#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p)
-#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c)
-#define IS_NAME_CHAR(enc, p, n) 0
-#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p)
-#define IS_NMSTRT_CHAR(enc, p, n) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p)
-
-#include "xmltok_impl.c"
-
-#undef MINBPC
-#undef BYTE_TYPE
-#undef BYTE_TO_ASCII
-#undef CHAR_MATCHES
-#undef IS_NAME_CHAR
-#undef IS_NAME_CHAR_MINBPC
-#undef IS_NMSTRT_CHAR
-#undef IS_NMSTRT_CHAR_MINBPC
-#undef IS_INVALID_CHAR
-
-#endif /* not XML_MIN_SIZE */
-
-#ifdef XML_NS
-
-static const struct normal_encoding little2_encoding_ns = {
- { VTABLE, 2, 0,
-#if BYTEORDER == 1234
- 1
-#else
- 0
-#endif
- },
- {
-#include "asciitab.h"
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(little2_)
-};
-
-#endif
-
-static const struct normal_encoding little2_encoding = {
- { VTABLE, 2, 0,
-#if BYTEORDER == 1234
- 1
-#else
- 0
-#endif
- },
- {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(little2_)
-};
-
-#if BYTEORDER != 4321
-
-#ifdef XML_NS
-
-static const struct normal_encoding internal_little2_encoding_ns = {
- { VTABLE, 2, 0, 1 },
- {
-#include "iasciitab.h"
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(little2_)
-};
-
-#endif
-
-static const struct normal_encoding internal_little2_encoding = {
- { VTABLE, 2, 0, 1 },
- {
-#define BT_COLON BT_NMSTRT
-#include "iasciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(little2_)
-};
-
-#endif
-
-
-#define BIG2_BYTE_TYPE(enc, p) \
- ((p)[0] == 0 \
- ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \
- : unicode_byte_type((p)[0], (p)[1]))
-#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1)
-#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c)
-#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \
- UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
-#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
- UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
-
-#ifdef XML_MIN_SIZE
-
-static int FASTCALL
-big2_byteType(const ENCODING *enc, const char *p)
-{
- return BIG2_BYTE_TYPE(enc, p);
-}
-
-static int FASTCALL
-big2_byteToAscii(const ENCODING *enc, const char *p)
-{
- return BIG2_BYTE_TO_ASCII(enc, p);
-}
-
-static int FASTCALL
-big2_charMatches(const ENCODING *enc, const char *p, int c)
-{
- return BIG2_CHAR_MATCHES(enc, p, c);
-}
-
-static int FASTCALL
-big2_isNameMin(const ENCODING *enc, const char *p)
-{
- return BIG2_IS_NAME_CHAR_MINBPC(enc, p);
-}
-
-static int FASTCALL
-big2_isNmstrtMin(const ENCODING *enc, const char *p)
-{
- return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p);
-}
-
-#undef VTABLE
-#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
-
-#else /* not XML_MIN_SIZE */
-
-#undef PREFIX
-#define PREFIX(ident) big2_ ## ident
-#define MINBPC(enc) 2
-/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
-#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
-#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p)
-#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c)
-#define IS_NAME_CHAR(enc, p, n) 0
-#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p)
-#define IS_NMSTRT_CHAR(enc, p, n) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p)
-
-#include "xmltok_impl.c"
-
-#undef MINBPC
-#undef BYTE_TYPE
-#undef BYTE_TO_ASCII
-#undef CHAR_MATCHES
-#undef IS_NAME_CHAR
-#undef IS_NAME_CHAR_MINBPC
-#undef IS_NMSTRT_CHAR
-#undef IS_NMSTRT_CHAR_MINBPC
-#undef IS_INVALID_CHAR
-
-#endif /* not XML_MIN_SIZE */
-
-#ifdef XML_NS
-
-static const struct normal_encoding big2_encoding_ns = {
- { VTABLE, 2, 0,
-#if BYTEORDER == 4321
- 1
-#else
- 0
-#endif
- },
- {
-#include "asciitab.h"
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(big2_)
-};
-
-#endif
-
-static const struct normal_encoding big2_encoding = {
- { VTABLE, 2, 0,
-#if BYTEORDER == 4321
- 1
-#else
- 0
-#endif
- },
- {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(big2_)
-};
-
-#if BYTEORDER != 1234
-
-#ifdef XML_NS
-
-static const struct normal_encoding internal_big2_encoding_ns = {
- { VTABLE, 2, 0, 1 },
- {
-#include "iasciitab.h"
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(big2_)
-};
-
-#endif
-
-static const struct normal_encoding internal_big2_encoding = {
- { VTABLE, 2, 0, 1 },
- {
-#define BT_COLON BT_NMSTRT
-#include "iasciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
- },
- STANDARD_VTABLE(big2_)
-};
-
-#endif
-
-#undef PREFIX
-
-static int FASTCALL
-streqci(const char *s1, const char *s2)
-{
- for (;;) {
- char c1 = *s1++;
- char c2 = *s2++;
- if (ASCII_a <= c1 && c1 <= ASCII_z)
- c1 += ASCII_A - ASCII_a;
- if (ASCII_a <= c2 && c2 <= ASCII_z)
- c2 += ASCII_A - ASCII_a;
- if (c1 != c2)
- return 0;
- if (!c1)
- break;
- }
- return 1;
-}
-
-static void FASTCALL
-initUpdatePosition(const ENCODING *enc, const char *ptr,
- const char *end, POSITION *pos)
-{
- normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
-}
-
-static int FASTCALL
-toAscii(const ENCODING *enc, const char *ptr, const char *end)
-{
- char buf[1];
- char *p = buf;
- XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
- if (p == buf)
- return -1;
- else
- return buf[0];
-}
-
-static int FASTCALL
-isSpace(int c)
-{
- switch (c) {
- case 0x20:
- case 0xD:
- case 0xA:
- case 0x9:
- return 1;
- }
- return 0;
-}
-
-/* Return 1 if there's just optional white space or there's an S
- followed by name=val.
-*/
-static int FASTCALL
-parsePseudoAttribute(const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **namePtr,
- const char **nameEndPtr,
- const char **valPtr,
- const char **nextTokPtr)
-{
- int c;
- char open;
- if (ptr == end) {
- *namePtr = NULL;
- return 1;
- }
- if (!isSpace(toAscii(enc, ptr, end))) {
- *nextTokPtr = ptr;
- return 0;
- }
- do {
- ptr += enc->minBytesPerChar;
- } while (isSpace(toAscii(enc, ptr, end)));
- if (ptr == end) {
- *namePtr = NULL;
- return 1;
- }
- *namePtr = ptr;
- for (;;) {
- c = toAscii(enc, ptr, end);
- if (c == -1) {
- *nextTokPtr = ptr;
- return 0;
- }
- if (c == ASCII_EQUALS) {
- *nameEndPtr = ptr;
- break;
- }
- if (isSpace(c)) {
- *nameEndPtr = ptr;
- do {
- ptr += enc->minBytesPerChar;
- } while (isSpace(c = toAscii(enc, ptr, end)));
- if (c != ASCII_EQUALS) {
- *nextTokPtr = ptr;
- return 0;
- }
- break;
- }
- ptr += enc->minBytesPerChar;
- }
- if (ptr == *namePtr) {
- *nextTokPtr = ptr;
- return 0;
- }
- ptr += enc->minBytesPerChar;
- c = toAscii(enc, ptr, end);
- while (isSpace(c)) {
- ptr += enc->minBytesPerChar;
- c = toAscii(enc, ptr, end);
- }
- if (c != ASCII_QUOT && c != ASCII_APOS) {
- *nextTokPtr = ptr;
- return 0;
- }
- open = (char)c;
- ptr += enc->minBytesPerChar;
- *valPtr = ptr;
- for (;; ptr += enc->minBytesPerChar) {
- c = toAscii(enc, ptr, end);
- if (c == open)
- break;
- if (!(ASCII_a <= c && c <= ASCII_z)
- && !(ASCII_A <= c && c <= ASCII_Z)
- && !(ASCII_0 <= c && c <= ASCII_9)
- && c != ASCII_PERIOD
- && c != ASCII_MINUS
- && c != ASCII_UNDERSCORE) {
- *nextTokPtr = ptr;
- return 0;
- }
- }
- *nextTokPtr = ptr + enc->minBytesPerChar;
- return 1;
-}
-
-static const char KW_version[] = {
- ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'
-};
-
-static const char KW_encoding[] = {
- ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0'
-};
-
-static const char KW_standalone[] = {
- ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o,
- ASCII_n, ASCII_e, '\0'
-};
-
-static const char KW_yes[] = {
- ASCII_y, ASCII_e, ASCII_s, '\0'
-};
-
-static const char KW_no[] = {
- ASCII_n, ASCII_o, '\0'
-};
-
-static int
-doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
- const char *,
- const char *),
- int isGeneralTextEntity,
- const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **badPtr,
- const char **versionPtr,
- const char **versionEndPtr,
- const char **encodingName,
- const ENCODING **encoding,
- int *standalone)
-{
- const char *val = NULL;
- const char *name = NULL;
- const char *nameEnd = NULL;
- ptr += 5 * enc->minBytesPerChar;
- end -= 2 * enc->minBytesPerChar;
- if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)
- || !name) {
- *badPtr = ptr;
- return 0;
- }
- if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {
- if (!isGeneralTextEntity) {
- *badPtr = name;
- return 0;
- }
- }
- else {
- if (versionPtr)
- *versionPtr = val;
- if (versionEndPtr)
- *versionEndPtr = ptr;
- if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
- *badPtr = ptr;
- return 0;
- }
- if (!name) {
- if (isGeneralTextEntity) {
- /* a TextDecl must have an EncodingDecl */
- *badPtr = ptr;
- return 0;
- }
- return 1;
- }
- }
- if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) {
- int c = toAscii(enc, val, end);
- if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) {
- *badPtr = val;
- return 0;
- }
- if (encodingName)
- *encodingName = val;
- if (encoding)
- *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);
- if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
- *badPtr = ptr;
- return 0;
- }
- if (!name)
- return 1;
- }
- if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone)
- || isGeneralTextEntity) {
- *badPtr = name;
- return 0;
- }
- if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) {
- if (standalone)
- *standalone = 1;
- }
- else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {
- if (standalone)
- *standalone = 0;
- }
- else {
- *badPtr = val;
- return 0;
- }
- while (isSpace(toAscii(enc, ptr, end)))
- ptr += enc->minBytesPerChar;
- if (ptr != end) {
- *badPtr = ptr;
- return 0;
- }
- return 1;
-}
-
-static int FASTCALL
-checkCharRefNumber(int result)
-{
- switch (result >> 8) {
- case 0xD8: case 0xD9: case 0xDA: case 0xDB:
- case 0xDC: case 0xDD: case 0xDE: case 0xDF:
- return -1;
- case 0:
- if (latin1_encoding.type[result] == BT_NONXML)
- return -1;
- break;
- case 0xFF:
- if (result == 0xFFFE || result == 0xFFFF)
- return -1;
- break;
- }
- return result;
-}
-
-int
-XmlUtf8Encode(int c, char *buf)
-{
- enum {
- /* minN is minimum legal resulting value for N byte sequence */
- min2 = 0x80,
- min3 = 0x800,
- min4 = 0x10000
- };
-
- if (c < 0)
- return 0;
- if (c < min2) {
- buf[0] = (char)(c | UTF8_cval1);
- return 1;
- }
- if (c < min3) {
- buf[0] = (char)((c >> 6) | UTF8_cval2);
- buf[1] = (char)((c & 0x3f) | 0x80);
- return 2;
- }
- if (c < min4) {
- buf[0] = (char)((c >> 12) | UTF8_cval3);
- buf[1] = (char)(((c >> 6) & 0x3f) | 0x80);
- buf[2] = (char)((c & 0x3f) | 0x80);
- return 3;
- }
- if (c < 0x110000) {
- buf[0] = (char)((c >> 18) | UTF8_cval4);
- buf[1] = (char)(((c >> 12) & 0x3f) | 0x80);
- buf[2] = (char)(((c >> 6) & 0x3f) | 0x80);
- buf[3] = (char)((c & 0x3f) | 0x80);
- return 4;
- }
- return 0;
-}
-
-int
-XmlUtf16Encode(int charNum, unsigned short *buf)
-{
- if (charNum < 0)
- return 0;
- if (charNum < 0x10000) {
- buf[0] = (unsigned short)charNum;
- return 1;
- }
- if (charNum < 0x110000) {
- charNum -= 0x10000;
- buf[0] = (unsigned short)((charNum >> 10) + 0xD800);
- buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00);
- return 2;
- }
- return 0;
-}
-
-struct unknown_encoding {
- struct normal_encoding normal;
- int (*convert)(void *userData, const char *p);
- void *userData;
- unsigned short utf16[256];
- char utf8[256][4];
-};
-
-#define AS_UNKNOWN_ENCODING(enc) ((const struct unknown_encoding *) (enc))
-
-int
-XmlSizeOfUnknownEncoding(void)
-{
- return sizeof(struct unknown_encoding);
-}
-
-static int FASTCALL
-unknown_isName(const ENCODING *enc, const char *p)
-{
- const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
- int c = uenc->convert(uenc->userData, p);
- if (c & ~0xFFFF)
- return 0;
- return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
-}
-
-static int FASTCALL
-unknown_isNmstrt(const ENCODING *enc, const char *p)
-{
- const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
- int c = uenc->convert(uenc->userData, p);
- if (c & ~0xFFFF)
- return 0;
- return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
-}
-
-static int FASTCALL
-unknown_isInvalid(const ENCODING *enc, const char *p)
-{
- const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
- int c = uenc->convert(uenc->userData, p);
- return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
-}
-
-static void FASTCALL
-unknown_toUtf8(const ENCODING *enc,
- const char **fromP, const char *fromLim,
- char **toP, const char *toLim)
-{
- const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
- char buf[XML_UTF8_ENCODE_MAX];
- for (;;) {
- const char *utf8;
- int n;
- if (*fromP == fromLim)
- break;
- utf8 = uenc->utf8[(unsigned char)**fromP];
- n = *utf8++;
- if (n == 0) {
- int c = uenc->convert(uenc->userData, *fromP);
- n = XmlUtf8Encode(c, buf);
- if (n > toLim - *toP)
- break;
- utf8 = buf;
- *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
- - (BT_LEAD2 - 2));
- }
- else {
- if (n > toLim - *toP)
- break;
- (*fromP)++;
- }
- do {
- *(*toP)++ = *utf8++;
- } while (--n != 0);
- }
-}
-
-static void FASTCALL
-unknown_toUtf16(const ENCODING *enc,
- const char **fromP, const char *fromLim,
- unsigned short **toP, const unsigned short *toLim)
-{
- const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
- while (*fromP != fromLim && *toP != toLim) {
- unsigned short c = uenc->utf16[(unsigned char)**fromP];
- if (c == 0) {
- c = (unsigned short)
- uenc->convert(uenc->userData, *fromP);
- *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
- - (BT_LEAD2 - 2));
- }
- else
- (*fromP)++;
- *(*toP)++ = c;
- }
-}
-
-ENCODING *
-XmlInitUnknownEncoding(void *mem,
- int *table,
- int (*convert)(void *userData, const char *p),
- void *userData)
-{
- int i;
- struct unknown_encoding *e = mem;
- for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
- ((char *)mem)[i] = ((char *)&latin1_encoding)[i];
- for (i = 0; i < 128; i++)
- if (latin1_encoding.type[i] != BT_OTHER
- && latin1_encoding.type[i] != BT_NONXML
- && table[i] != i)
- return 0;
- for (i = 0; i < 256; i++) {
- int c = table[i];
- if (c == -1) {
- e->normal.type[i] = BT_MALFORM;
- /* This shouldn't really get used. */
- e->utf16[i] = 0xFFFF;
- e->utf8[i][0] = 1;
- e->utf8[i][1] = 0;
- }
- else if (c < 0) {
- if (c < -4)
- return 0;
- e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));
- e->utf8[i][0] = 0;
- e->utf16[i] = 0;
- }
- else if (c < 0x80) {
- if (latin1_encoding.type[c] != BT_OTHER
- && latin1_encoding.type[c] != BT_NONXML
- && c != i)
- return 0;
- e->normal.type[i] = latin1_encoding.type[c];
- e->utf8[i][0] = 1;
- e->utf8[i][1] = (char)c;
- e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c);
- }
- else if (checkCharRefNumber(c) < 0) {
- e->normal.type[i] = BT_NONXML;
- /* This shouldn't really get used. */
- e->utf16[i] = 0xFFFF;
- e->utf8[i][0] = 1;
- e->utf8[i][1] = 0;
- }
- else {
- if (c > 0xFFFF)
- return 0;
- if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
- e->normal.type[i] = BT_NMSTRT;
- else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff))
- e->normal.type[i] = BT_NAME;
- else
- e->normal.type[i] = BT_OTHER;
- e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1);
- e->utf16[i] = (unsigned short)c;
- }
- }
- e->userData = userData;
- e->convert = convert;
- if (convert) {
- e->normal.isName2 = unknown_isName;
- e->normal.isName3 = unknown_isName;
- e->normal.isName4 = unknown_isName;
- e->normal.isNmstrt2 = unknown_isNmstrt;
- e->normal.isNmstrt3 = unknown_isNmstrt;
- e->normal.isNmstrt4 = unknown_isNmstrt;
- e->normal.isInvalid2 = unknown_isInvalid;
- e->normal.isInvalid3 = unknown_isInvalid;
- e->normal.isInvalid4 = unknown_isInvalid;
- }
- e->normal.enc.utf8Convert = unknown_toUtf8;
- e->normal.enc.utf16Convert = unknown_toUtf16;
- return &(e->normal.enc);
-}
-
-/* If this enumeration is changed, getEncodingIndex and encodings
-must also be changed. */
-enum {
- UNKNOWN_ENC = -1,
- ISO_8859_1_ENC = 0,
- US_ASCII_ENC,
- UTF_8_ENC,
- UTF_16_ENC,
- UTF_16BE_ENC,
- UTF_16LE_ENC,
- /* must match encodingNames up to here */
- NO_ENC
-};
-
-static const char KW_ISO_8859_1[] = {
- ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9,
- ASCII_MINUS, ASCII_1, '\0'
-};
-static const char KW_US_ASCII[] = {
- ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I,
- '\0'
-};
-static const char KW_UTF_8[] = {
- ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'
-};
-static const char KW_UTF_16[] = {
- ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'
-};
-static const char KW_UTF_16BE[] = {
- ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E,
- '\0'
-};
-static const char KW_UTF_16LE[] = {
- ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E,
- '\0'
-};
-
-static int FASTCALL
-getEncodingIndex(const char *name)
-{
- static const char *encodingNames[] = {
- KW_ISO_8859_1,
- KW_US_ASCII,
- KW_UTF_8,
- KW_UTF_16,
- KW_UTF_16BE,
- KW_UTF_16LE,
- };
- int i;
- if (name == NULL)
- return NO_ENC;
- for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++)
- if (streqci(name, encodingNames[i]))
- return i;
- return UNKNOWN_ENC;
-}
-
-/* For binary compatibility, we store the index of the encoding
- specified at initialization in the isUtf16 member.
-*/
-
-#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16)
-#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i)
-
-/* This is what detects the encoding. encodingTable maps from
- encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of
- the external (protocol) specified encoding; state is
- XML_CONTENT_STATE if we're parsing an external text entity, and
- XML_PROLOG_STATE otherwise.
-*/
-
-
-static int FASTCALL
-initScan(const ENCODING **encodingTable,
- const INIT_ENCODING *enc,
- int state,
- const char *ptr,
- const char *end,
- const char **nextTokPtr)
-{
- const ENCODING **encPtr;
-
- if (ptr == end)
- return XML_TOK_NONE;
- encPtr = enc->encPtr;
- if (ptr + 1 == end) {
- /* only a single byte available for auto-detection */
-#ifndef XML_DTD /* FIXME */
- /* a well-formed document entity must have more than one byte */
- if (state != XML_CONTENT_STATE)
- return XML_TOK_PARTIAL;
-#endif
- /* so we're parsing an external text entity... */
- /* if UTF-16 was externally specified, then we need at least 2 bytes */
- switch (INIT_ENC_INDEX(enc)) {
- case UTF_16_ENC:
- case UTF_16LE_ENC:
- case UTF_16BE_ENC:
- return XML_TOK_PARTIAL;
- }
- switch ((unsigned char)*ptr) {
- case 0xFE:
- case 0xFF:
- case 0xEF: /* possibly first byte of UTF-8 BOM */
- if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
- && state == XML_CONTENT_STATE)
- break;
- /* fall through */
- case 0x00:
- case 0x3C:
- return XML_TOK_PARTIAL;
- }
- }
- else {
- switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
- case 0xFEFF:
- if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
- && state == XML_CONTENT_STATE)
- break;
- *nextTokPtr = ptr + 2;
- *encPtr = encodingTable[UTF_16BE_ENC];
- return XML_TOK_BOM;
- /* 00 3C is handled in the default case */
- case 0x3C00:
- if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC
- || INIT_ENC_INDEX(enc) == UTF_16_ENC)
- && state == XML_CONTENT_STATE)
- break;
- *encPtr = encodingTable[UTF_16LE_ENC];
- return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
- case 0xFFFE:
- if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
- && state == XML_CONTENT_STATE)
- break;
- *nextTokPtr = ptr + 2;
- *encPtr = encodingTable[UTF_16LE_ENC];
- return XML_TOK_BOM;
- case 0xEFBB:
- /* Maybe a UTF-8 BOM (EF BB BF) */
- /* If there's an explicitly specified (external) encoding
- of ISO-8859-1 or some flavour of UTF-16
- and this is an external text entity,
- don't look for the BOM,
- because it might be a legal data.
- */
- if (state == XML_CONTENT_STATE) {
- int e = INIT_ENC_INDEX(enc);
- if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC
- || e == UTF_16LE_ENC || e == UTF_16_ENC)
- break;
- }
- if (ptr + 2 == end)
- return XML_TOK_PARTIAL;
- if ((unsigned char)ptr[2] == 0xBF) {
- *nextTokPtr = ptr + 3;
- *encPtr = encodingTable[UTF_8_ENC];
- return XML_TOK_BOM;
- }
- break;
- default:
- if (ptr[0] == '\0') {
- /* 0 isn't a legal data character. Furthermore a document
- entity can only start with ASCII characters. So the only
- way this can fail to be big-endian UTF-16 if it it's an
- external parsed general entity that's labelled as
- UTF-16LE.
- */
- if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)
- break;
- *encPtr = encodingTable[UTF_16BE_ENC];
- return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
- }
- else if (ptr[1] == '\0') {
- /* We could recover here in the case:
- - parsing an external entity
- - second byte is 0
- - no externally specified encoding
- - no encoding declaration
- by assuming UTF-16LE. But we don't, because this would mean when
- presented just with a single byte, we couldn't reliably determine
- whether we needed further bytes.
- */
- if (state == XML_CONTENT_STATE)
- break;
- *encPtr = encodingTable[UTF_16LE_ENC];
- return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
- }
- break;
- }
- }
- *encPtr = encodingTable[INIT_ENC_INDEX(enc)];
- return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
-}
-
-
-#define NS(x) x
-#define ns(x) x
-#include "xmltok_ns.c"
-#undef NS
-#undef ns
-
-#ifdef XML_NS
-
-#define NS(x) x ## NS
-#define ns(x) x ## _ns
-
-#include "xmltok_ns.c"
-
-#undef NS
-#undef ns
-
-ENCODING *
-XmlInitUnknownEncodingNS(void *mem,
- int *table,
- int (*convert)(void *userData, const char *p),
- void *userData)
-{
- ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
- if (enc)
- ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON;
- return enc;
-}
-
-#endif /* XML_NS */
diff --git a/bundle/expat/xmltok.h b/bundle/expat/xmltok.h
deleted file mode 100644
index 55cc181e7b..0000000000
--- a/bundle/expat/xmltok.h
+++ /dev/null
@@ -1,312 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-#ifndef XmlTok_INCLUDED
-#define XmlTok_INCLUDED 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* The following token may be returned by XmlContentTok */
-#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be
- start of illegal ]]> sequence */
-/* The following tokens may be returned by both XmlPrologTok and
- XmlContentTok.
-*/
-#define XML_TOK_NONE -4 /* The string to be scanned is empty */
-#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan;
- might be part of CRLF sequence */
-#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
-#define XML_TOK_PARTIAL -1 /* only part of a token */
-#define XML_TOK_INVALID 0
-
-/* The following tokens are returned by XmlContentTok; some are also
- returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok.
-*/
-#define XML_TOK_START_TAG_WITH_ATTS 1
-#define XML_TOK_START_TAG_NO_ATTS 2
-#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
-#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
-#define XML_TOK_END_TAG 5
-#define XML_TOK_DATA_CHARS 6
-#define XML_TOK_DATA_NEWLINE 7
-#define XML_TOK_CDATA_SECT_OPEN 8
-#define XML_TOK_ENTITY_REF 9
-#define XML_TOK_CHAR_REF 10 /* numeric character reference */
-
-/* The following tokens may be returned by both XmlPrologTok and
- XmlContentTok.
-*/
-#define XML_TOK_PI 11 /* processing instruction */
-#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
-#define XML_TOK_COMMENT 13
-#define XML_TOK_BOM 14 /* Byte order mark */
-
-/* The following tokens are returned only by XmlPrologTok */
-#define XML_TOK_PROLOG_S 15
-#define XML_TOK_DECL_OPEN 16 /* <!foo */
-#define XML_TOK_DECL_CLOSE 17 /* > */
-#define XML_TOK_NAME 18
-#define XML_TOK_NMTOKEN 19
-#define XML_TOK_POUND_NAME 20 /* #name */
-#define XML_TOK_OR 21 /* | */
-#define XML_TOK_PERCENT 22
-#define XML_TOK_OPEN_PAREN 23
-#define XML_TOK_CLOSE_PAREN 24
-#define XML_TOK_OPEN_BRACKET 25
-#define XML_TOK_CLOSE_BRACKET 26
-#define XML_TOK_LITERAL 27
-#define XML_TOK_PARAM_ENTITY_REF 28
-#define XML_TOK_INSTANCE_START 29
-
-/* The following occur only in element type declarations */
-#define XML_TOK_NAME_QUESTION 30 /* name? */
-#define XML_TOK_NAME_ASTERISK 31 /* name* */
-#define XML_TOK_NAME_PLUS 32 /* name+ */
-#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
-#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
-#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
-#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
-#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
-#define XML_TOK_COMMA 38
-
-/* The following token is returned only by XmlAttributeValueTok */
-#define XML_TOK_ATTRIBUTE_VALUE_S 39
-
-/* The following token is returned only by XmlCdataSectionTok */
-#define XML_TOK_CDATA_SECT_CLOSE 40
-
-/* With namespace processing this is returned by XmlPrologTok for a
- name with a colon.
-*/
-#define XML_TOK_PREFIXED_NAME 41
-
-#ifdef XML_DTD
-#define XML_TOK_IGNORE_SECT 42
-#endif /* XML_DTD */
-
-#ifdef XML_DTD
-#define XML_N_STATES 4
-#else /* not XML_DTD */
-#define XML_N_STATES 3
-#endif /* not XML_DTD */
-
-#define XML_PROLOG_STATE 0
-#define XML_CONTENT_STATE 1
-#define XML_CDATA_SECTION_STATE 2
-#ifdef XML_DTD
-#define XML_IGNORE_SECTION_STATE 3
-#endif /* XML_DTD */
-
-#define XML_N_LITERAL_TYPES 2
-#define XML_ATTRIBUTE_VALUE_LITERAL 0
-#define XML_ENTITY_VALUE_LITERAL 1
-
-/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
-#define XML_UTF8_ENCODE_MAX 4
-/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
-#define XML_UTF16_ENCODE_MAX 2
-
-typedef struct position {
- /* first line and first column are 0 not 1 */
- unsigned long lineNumber;
- unsigned long columnNumber;
-} POSITION;
-
-typedef struct {
- const char *name;
- const char *valuePtr;
- const char *valueEnd;
- char normalized;
-} ATTRIBUTE;
-
-struct encoding;
-typedef struct encoding ENCODING;
-
-typedef int (FASTCALL *SCANNER)(const ENCODING *,
- const char *,
- const char *,
- const char **);
-
-struct encoding {
- SCANNER scanners[XML_N_STATES];
- SCANNER literalScanners[XML_N_LITERAL_TYPES];
- int (FASTCALL *sameName)(const ENCODING *,
- const char *,
- const char *);
- int (FASTCALL *nameMatchesAscii)(const ENCODING *,
- const char *,
- const char *,
- const char *);
- int (FASTCALL *nameLength)(const ENCODING *, const char *);
- const char *(FASTCALL *skipS)(const ENCODING *, const char *);
- int (FASTCALL *getAtts)(const ENCODING *enc,
- const char *ptr,
- int attsMax,
- ATTRIBUTE *atts);
- int (FASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
- int (FASTCALL *predefinedEntityName)(const ENCODING *,
- const char *,
- const char *);
- void (FASTCALL *updatePosition)(const ENCODING *,
- const char *ptr,
- const char *end,
- POSITION *);
- int (FASTCALL *isPublicId)(const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **badPtr);
- void (FASTCALL *utf8Convert)(const ENCODING *enc,
- const char **fromP,
- const char *fromLim,
- char **toP,
- const char *toLim);
- void (FASTCALL *utf16Convert)(const ENCODING *enc,
- const char **fromP,
- const char *fromLim,
- unsigned short **toP,
- const unsigned short *toLim);
- int minBytesPerChar;
- char isUtf8;
- char isUtf16;
-};
-
-/* Scan the string starting at ptr until the end of the next complete
- token, but do not scan past eptr. Return an integer giving the
- type of token.
-
- Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
-
- Return XML_TOK_PARTIAL when the string does not contain a complete
- token; nextTokPtr will not be set.
-
- Return XML_TOK_INVALID when the string does not start a valid
- token; nextTokPtr will be set to point to the character which made
- the token invalid.
-
- Otherwise the string starts with a valid token; nextTokPtr will be
- set to point to the character following the end of that token.
-
- Each data character counts as a single token, but adjacent data
- characters may be returned together. Similarly for characters in
- the prolog outside literals, comments and processing instructions.
-*/
-
-
-#define XmlTok(enc, state, ptr, end, nextTokPtr) \
- (((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
-
-#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
- XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
-
-#define XmlContentTok(enc, ptr, end, nextTokPtr) \
- XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
-
-#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
- XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
-
-#ifdef XML_DTD
-
-#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
- XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
-
-#endif /* XML_DTD */
-
-/* This is used for performing a 2nd-level tokenization on the content
- of a literal that has already been returned by XmlTok.
-*/
-#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
- (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
-
-#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
- XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
-
-#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
- XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
-
-#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
-
-#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
- (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
-
-#define XmlNameLength(enc, ptr) \
- (((enc)->nameLength)(enc, ptr))
-
-#define XmlSkipS(enc, ptr) \
- (((enc)->skipS)(enc, ptr))
-
-#define XmlGetAttributes(enc, ptr, attsMax, atts) \
- (((enc)->getAtts)(enc, ptr, attsMax, atts))
-
-#define XmlCharRefNumber(enc, ptr) \
- (((enc)->charRefNumber)(enc, ptr))
-
-#define XmlPredefinedEntityName(enc, ptr, end) \
- (((enc)->predefinedEntityName)(enc, ptr, end))
-
-#define XmlUpdatePosition(enc, ptr, end, pos) \
- (((enc)->updatePosition)(enc, ptr, end, pos))
-
-#define XmlIsPublicId(enc, ptr, end, badPtr) \
- (((enc)->isPublicId)(enc, ptr, end, badPtr))
-
-#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
- (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
-
-#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
- (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
-
-typedef struct {
- ENCODING initEnc;
- const ENCODING **encPtr;
-} INIT_ENCODING;
-
-int XmlParseXmlDecl(int isGeneralTextEntity,
- const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **badPtr,
- const char **versionPtr,
- const char **versionEndPtr,
- const char **encodingNamePtr,
- const ENCODING **namedEncodingPtr,
- int *standalonePtr);
-
-int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
-const ENCODING *XmlGetUtf8InternalEncoding(void);
-const ENCODING *XmlGetUtf16InternalEncoding(void);
-int XmlUtf8Encode(int charNumber, char *buf);
-int XmlUtf16Encode(int charNumber, unsigned short *buf);
-
-int XmlSizeOfUnknownEncoding(void);
-ENCODING *
-XmlInitUnknownEncoding(void *mem,
- int *table,
- int (*conv)(void *userData, const char *p),
- void *userData);
-
-int XmlParseXmlDeclNS(int isGeneralTextEntity,
- const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **badPtr,
- const char **versionPtr,
- const char **versionEndPtr,
- const char **encodingNamePtr,
- const ENCODING **namedEncodingPtr,
- int *standalonePtr);
-int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
-const ENCODING *XmlGetUtf8InternalEncodingNS(void);
-const ENCODING *XmlGetUtf16InternalEncodingNS(void);
-ENCODING *
-XmlInitUnknownEncodingNS(void *mem,
- int *table,
- int (*conv)(void *userData, const char *p),
- void *userData);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* not XmlTok_INCLUDED */
diff --git a/bundle/expat/xmltok_impl.c b/bundle/expat/xmltok_impl.c
deleted file mode 100644
index be3d1d31ca..0000000000
--- a/bundle/expat/xmltok_impl.c
+++ /dev/null
@@ -1,1778 +0,0 @@
-/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
- See the file COPYING for copying permission.
-*/
-
-#ifndef IS_INVALID_CHAR
-#define IS_INVALID_CHAR(enc, ptr, n) (0)
-#endif
-
-#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
- case BT_LEAD ## n: \
- if (end - ptr < n) \
- return XML_TOK_PARTIAL_CHAR; \
- if (IS_INVALID_CHAR(enc, ptr, n)) { \
- *(nextTokPtr) = (ptr); \
- return XML_TOK_INVALID; \
- } \
- ptr += n; \
- break;
-
-#define INVALID_CASES(ptr, nextTokPtr) \
- INVALID_LEAD_CASE(2, ptr, nextTokPtr) \
- INVALID_LEAD_CASE(3, ptr, nextTokPtr) \
- INVALID_LEAD_CASE(4, ptr, nextTokPtr) \
- case BT_NONXML: \
- case BT_MALFORM: \
- case BT_TRAIL: \
- *(nextTokPtr) = (ptr); \
- return XML_TOK_INVALID;
-
-#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \
- case BT_LEAD ## n: \
- if (end - ptr < n) \
- return XML_TOK_PARTIAL_CHAR; \
- if (!IS_NAME_CHAR(enc, ptr, n)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_INVALID; \
- } \
- ptr += n; \
- break;
-
-#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \
- case BT_NONASCII: \
- if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_INVALID; \
- } \
- case BT_NMSTRT: \
- case BT_HEX: \
- case BT_DIGIT: \
- case BT_NAME: \
- case BT_MINUS: \
- ptr += MINBPC(enc); \
- break; \
- CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \
- CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \
- CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr)
-
-#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \
- case BT_LEAD ## n: \
- if (end - ptr < n) \
- return XML_TOK_PARTIAL_CHAR; \
- if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_INVALID; \
- } \
- ptr += n; \
- break;
-
-#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \
- case BT_NONASCII: \
- if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_INVALID; \
- } \
- case BT_NMSTRT: \
- case BT_HEX: \
- ptr += MINBPC(enc); \
- break; \
- CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \
- CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \
- CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
-
-#ifndef PREFIX
-#define PREFIX(ident) ident
-#endif
-
-/* ptr points to character following "<!-" */
-
-static int FASTCALL
-PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- if (ptr != end) {
- if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- ptr += MINBPC(enc);
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
- INVALID_CASES(ptr, nextTokPtr)
- case BT_MINUS:
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
- if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
- if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_COMMENT;
- }
- break;
- default:
- ptr += MINBPC(enc);
- break;
- }
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "<!" */
-
-static int FASTCALL
-PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- if (ptr == end)
- return XML_TOK_PARTIAL;
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_MINUS:
- return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_LSQB:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_COND_SECT_OPEN;
- case BT_NMSTRT:
- case BT_HEX:
- ptr += MINBPC(enc);
- break;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_PERCNT:
- if (ptr + MINBPC(enc) == end)
- return XML_TOK_PARTIAL;
- /* don't allow <!ENTITY% foo "whatever"> */
- switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
- case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- /* fall through */
- case BT_S: case BT_CR: case BT_LF:
- *nextTokPtr = ptr;
- return XML_TOK_DECL_OPEN;
- case BT_NMSTRT:
- case BT_HEX:
- ptr += MINBPC(enc);
- break;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-static int FASTCALL
-PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr,
- const char *end, int *tokPtr)
-{
- int upper = 0;
- *tokPtr = XML_TOK_PI;
- if (end - ptr != MINBPC(enc)*3)
- return 1;
- switch (BYTE_TO_ASCII(enc, ptr)) {
- case ASCII_x:
- break;
- case ASCII_X:
- upper = 1;
- break;
- default:
- return 1;
- }
- ptr += MINBPC(enc);
- switch (BYTE_TO_ASCII(enc, ptr)) {
- case ASCII_m:
- break;
- case ASCII_M:
- upper = 1;
- break;
- default:
- return 1;
- }
- ptr += MINBPC(enc);
- switch (BYTE_TO_ASCII(enc, ptr)) {
- case ASCII_l:
- break;
- case ASCII_L:
- upper = 1;
- break;
- default:
- return 1;
- }
- if (upper)
- return 0;
- *tokPtr = XML_TOK_XML_DECL;
- return 1;
-}
-
-/* ptr points to character following "<?" */
-
-static int FASTCALL
-PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- int tok;
- const char *target = ptr;
- if (ptr == end)
- return XML_TOK_PARTIAL;
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- case BT_S: case BT_CR: case BT_LF:
- if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- ptr += MINBPC(enc);
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
- INVALID_CASES(ptr, nextTokPtr)
- case BT_QUEST:
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
- if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
- *nextTokPtr = ptr + MINBPC(enc);
- return tok;
- }
- break;
- default:
- ptr += MINBPC(enc);
- break;
- }
- }
- return XML_TOK_PARTIAL;
- case BT_QUEST:
- if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
- if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
- *nextTokPtr = ptr + MINBPC(enc);
- return tok;
- }
- /* fall through */
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-static int FASTCALL
-PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A,
- ASCII_T, ASCII_A, ASCII_LSQB };
- int i;
- /* CDATA[ */
- if (end - ptr < 6 * MINBPC(enc))
- return XML_TOK_PARTIAL;
- for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
- if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- *nextTokPtr = ptr;
- return XML_TOK_CDATA_SECT_OPEN;
-}
-
-static int FASTCALL
-PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- if (ptr == end)
- return XML_TOK_NONE;
- if (MINBPC(enc) > 1) {
- size_t n = end - ptr;
- if (n & (MINBPC(enc) - 1)) {
- n &= ~(MINBPC(enc) - 1);
- if (n == 0)
- return XML_TOK_PARTIAL;
- end = ptr + n;
- }
- }
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_RSQB:
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
- if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
- break;
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
- if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
- ptr -= MINBPC(enc);
- break;
- }
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_CDATA_SECT_CLOSE;
- case BT_CR:
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
- if (BYTE_TYPE(enc, ptr) == BT_LF)
- ptr += MINBPC(enc);
- *nextTokPtr = ptr;
- return XML_TOK_DATA_NEWLINE;
- case BT_LF:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_DATA_NEWLINE;
- INVALID_CASES(ptr, nextTokPtr)
- default:
- ptr += MINBPC(enc);
- break;
- }
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: \
- if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_DATA_CHARS; \
- } \
- ptr += n; \
- break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
- case BT_NONXML:
- case BT_MALFORM:
- case BT_TRAIL:
- case BT_CR:
- case BT_LF:
- case BT_RSQB:
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- default:
- ptr += MINBPC(enc);
- break;
- }
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
-}
-
-/* ptr points to character following "</" */
-
-static int FASTCALL
-PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- if (ptr == end)
- return XML_TOK_PARTIAL;
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- case BT_S: case BT_CR: case BT_LF:
- for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_S: case BT_CR: case BT_LF:
- break;
- case BT_GT:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_END_TAG;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return XML_TOK_PARTIAL;
-#ifdef XML_NS
- case BT_COLON:
- /* no need to check qname syntax here,
- since end-tag must match exactly */
- ptr += MINBPC(enc);
- break;
-#endif
- case BT_GT:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_END_TAG;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "&#X" */
-
-static int FASTCALL
-PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- if (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_DIGIT:
- case BT_HEX:
- break;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_DIGIT:
- case BT_HEX:
- break;
- case BT_SEMI:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_CHAR_REF;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "&#" */
-
-static int FASTCALL
-PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- if (ptr != end) {
- if (CHAR_MATCHES(enc, ptr, ASCII_x))
- return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_DIGIT:
- break;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_DIGIT:
- break;
- case BT_SEMI:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_CHAR_REF;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "&" */
-
-static int FASTCALL
-PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- if (ptr == end)
- return XML_TOK_PARTIAL;
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- case BT_NUM:
- return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- case BT_SEMI:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_ENTITY_REF;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following first character of attribute name */
-
-static int FASTCALL
-PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
-#ifdef XML_NS
- int hadColon = 0;
-#endif
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-#ifdef XML_NS
- case BT_COLON:
- if (hadColon) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- hadColon = 1;
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- break;
-#endif
- case BT_S: case BT_CR: case BT_LF:
- for (;;) {
- int t;
-
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
- t = BYTE_TYPE(enc, ptr);
- if (t == BT_EQUALS)
- break;
- switch (t) {
- case BT_S:
- case BT_LF:
- case BT_CR:
- break;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- /* fall through */
- case BT_EQUALS:
- {
- int open;
-#ifdef XML_NS
- hadColon = 0;
-#endif
- for (;;) {
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
- open = BYTE_TYPE(enc, ptr);
- if (open == BT_QUOT || open == BT_APOS)
- break;
- switch (open) {
- case BT_S:
- case BT_LF:
- case BT_CR:
- break;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- ptr += MINBPC(enc);
- /* in attribute value */
- for (;;) {
- int t;
- if (ptr == end)
- return XML_TOK_PARTIAL;
- t = BYTE_TYPE(enc, ptr);
- if (t == open)
- break;
- switch (t) {
- INVALID_CASES(ptr, nextTokPtr)
- case BT_AMP:
- {
- int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
- if (tok <= 0) {
- if (tok == XML_TOK_INVALID)
- *nextTokPtr = ptr;
- return tok;
- }
- break;
- }
- case BT_LT:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- default:
- ptr += MINBPC(enc);
- break;
- }
- }
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_S:
- case BT_CR:
- case BT_LF:
- break;
- case BT_SOL:
- goto sol;
- case BT_GT:
- goto gt;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- /* ptr points to closing quote */
- for (;;) {
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- case BT_S: case BT_CR: case BT_LF:
- continue;
- case BT_GT:
- gt:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_START_TAG_WITH_ATTS;
- case BT_SOL:
- sol:
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
- if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- break;
- }
- break;
- }
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "<" */
-
-static int FASTCALL
-PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
-#ifdef XML_NS
- int hadColon;
-#endif
- if (ptr == end)
- return XML_TOK_PARTIAL;
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- case BT_EXCL:
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_MINUS:
- return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_LSQB:
- return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc),
- end, nextTokPtr);
- }
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- case BT_QUEST:
- return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_SOL:
- return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
-#ifdef XML_NS
- hadColon = 0;
-#endif
- /* we have a start-tag */
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-#ifdef XML_NS
- case BT_COLON:
- if (hadColon) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- hadColon = 1;
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- break;
-#endif
- case BT_S: case BT_CR: case BT_LF:
- {
- ptr += MINBPC(enc);
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- case BT_GT:
- goto gt;
- case BT_SOL:
- goto sol;
- case BT_S: case BT_CR: case BT_LF:
- ptr += MINBPC(enc);
- continue;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
- }
- return XML_TOK_PARTIAL;
- }
- case BT_GT:
- gt:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_START_TAG_NO_ATTS;
- case BT_SOL:
- sol:
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
- if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_EMPTY_ELEMENT_NO_ATTS;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-static int FASTCALL
-PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- if (ptr == end)
- return XML_TOK_NONE;
- if (MINBPC(enc) > 1) {
- size_t n = end - ptr;
- if (n & (MINBPC(enc) - 1)) {
- n &= ~(MINBPC(enc) - 1);
- if (n == 0)
- return XML_TOK_PARTIAL;
- end = ptr + n;
- }
- }
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_LT:
- return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_AMP:
- return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_CR:
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_TRAILING_CR;
- if (BYTE_TYPE(enc, ptr) == BT_LF)
- ptr += MINBPC(enc);
- *nextTokPtr = ptr;
- return XML_TOK_DATA_NEWLINE;
- case BT_LF:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_DATA_NEWLINE;
- case BT_RSQB:
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_TRAILING_RSQB;
- if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
- break;
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_TRAILING_RSQB;
- if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
- ptr -= MINBPC(enc);
- break;
- }
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- INVALID_CASES(ptr, nextTokPtr)
- default:
- ptr += MINBPC(enc);
- break;
- }
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: \
- if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
- *nextTokPtr = ptr; \
- return XML_TOK_DATA_CHARS; \
- } \
- ptr += n; \
- break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
- case BT_RSQB:
- if (ptr + MINBPC(enc) != end) {
- if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
- ptr += MINBPC(enc);
- break;
- }
- if (ptr + 2*MINBPC(enc) != end) {
- if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
- ptr += MINBPC(enc);
- break;
- }
- *nextTokPtr = ptr + 2*MINBPC(enc);
- return XML_TOK_INVALID;
- }
- }
- /* fall through */
- case BT_AMP:
- case BT_LT:
- case BT_NONXML:
- case BT_MALFORM:
- case BT_TRAIL:
- case BT_CR:
- case BT_LF:
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- default:
- ptr += MINBPC(enc);
- break;
- }
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
-}
-
-/* ptr points to character following "%" */
-
-static int FASTCALL
-PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- if (ptr == end)
- return XML_TOK_PARTIAL;
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
- *nextTokPtr = ptr;
- return XML_TOK_PERCENT;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- case BT_SEMI:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_PARAM_ENTITY_REF;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-static int FASTCALL
-PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- if (ptr == end)
- return XML_TOK_PARTIAL;
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- case BT_CR: case BT_LF: case BT_S:
- case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR:
- *nextTokPtr = ptr;
- return XML_TOK_POUND_NAME;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return -XML_TOK_POUND_NAME;
-}
-
-static int FASTCALL
-PREFIX(scanLit)(int open, const ENCODING *enc,
- const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- while (ptr != end) {
- int t = BYTE_TYPE(enc, ptr);
- switch (t) {
- INVALID_CASES(ptr, nextTokPtr)
- case BT_QUOT:
- case BT_APOS:
- ptr += MINBPC(enc);
- if (t != open)
- break;
- if (ptr == end)
- return -XML_TOK_LITERAL;
- *nextTokPtr = ptr;
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_S: case BT_CR: case BT_LF:
- case BT_GT: case BT_PERCNT: case BT_LSQB:
- return XML_TOK_LITERAL;
- default:
- return XML_TOK_INVALID;
- }
- default:
- ptr += MINBPC(enc);
- break;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-static int FASTCALL
-PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- int tok;
- if (ptr == end)
- return XML_TOK_NONE;
- if (MINBPC(enc) > 1) {
- size_t n = end - ptr;
- if (n & (MINBPC(enc) - 1)) {
- n &= ~(MINBPC(enc) - 1);
- if (n == 0)
- return XML_TOK_PARTIAL;
- end = ptr + n;
- }
- }
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_QUOT:
- return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_APOS:
- return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_LT:
- {
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_EXCL:
- return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_QUEST:
- return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_NMSTRT:
- case BT_HEX:
- case BT_NONASCII:
- case BT_LEAD2:
- case BT_LEAD3:
- case BT_LEAD4:
- *nextTokPtr = ptr - MINBPC(enc);
- return XML_TOK_INSTANCE_START;
- }
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- case BT_CR:
- if (ptr + MINBPC(enc) == end) {
- *nextTokPtr = end;
- /* indicate that this might be part of a CR/LF pair */
- return -XML_TOK_PROLOG_S;
- }
- /* fall through */
- case BT_S: case BT_LF:
- for (;;) {
- ptr += MINBPC(enc);
- if (ptr == end)
- break;
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_S: case BT_LF:
- break;
- case BT_CR:
- /* don't split CR/LF pair */
- if (ptr + MINBPC(enc) != end)
- break;
- /* fall through */
- default:
- *nextTokPtr = ptr;
- return XML_TOK_PROLOG_S;
- }
- }
- *nextTokPtr = ptr;
- return XML_TOK_PROLOG_S;
- case BT_PERCNT:
- return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- case BT_COMMA:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_COMMA;
- case BT_LSQB:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_OPEN_BRACKET;
- case BT_RSQB:
- ptr += MINBPC(enc);
- if (ptr == end)
- return -XML_TOK_CLOSE_BRACKET;
- if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
- if (ptr + MINBPC(enc) == end)
- return XML_TOK_PARTIAL;
- if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
- *nextTokPtr = ptr + 2*MINBPC(enc);
- return XML_TOK_COND_SECT_CLOSE;
- }
- }
- *nextTokPtr = ptr;
- return XML_TOK_CLOSE_BRACKET;
- case BT_LPAR:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_OPEN_PAREN;
- case BT_RPAR:
- ptr += MINBPC(enc);
- if (ptr == end)
- return -XML_TOK_CLOSE_PAREN;
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_AST:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_CLOSE_PAREN_ASTERISK;
- case BT_QUEST:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_CLOSE_PAREN_QUESTION;
- case BT_PLUS:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_CLOSE_PAREN_PLUS;
- case BT_CR: case BT_LF: case BT_S:
- case BT_GT: case BT_COMMA: case BT_VERBAR:
- case BT_RPAR:
- *nextTokPtr = ptr;
- return XML_TOK_CLOSE_PAREN;
- }
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- case BT_VERBAR:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_OR;
- case BT_GT:
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_DECL_CLOSE;
- case BT_NUM:
- return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: \
- if (end - ptr < n) \
- return XML_TOK_PARTIAL_CHAR; \
- if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
- ptr += n; \
- tok = XML_TOK_NAME; \
- break; \
- } \
- if (IS_NAME_CHAR(enc, ptr, n)) { \
- ptr += n; \
- tok = XML_TOK_NMTOKEN; \
- break; \
- } \
- *nextTokPtr = ptr; \
- return XML_TOK_INVALID;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
- case BT_NMSTRT:
- case BT_HEX:
- tok = XML_TOK_NAME;
- ptr += MINBPC(enc);
- break;
- case BT_DIGIT:
- case BT_NAME:
- case BT_MINUS:
-#ifdef XML_NS
- case BT_COLON:
-#endif
- tok = XML_TOK_NMTOKEN;
- ptr += MINBPC(enc);
- break;
- case BT_NONASCII:
- if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) {
- ptr += MINBPC(enc);
- tok = XML_TOK_NAME;
- break;
- }
- if (IS_NAME_CHAR_MINBPC(enc, ptr)) {
- ptr += MINBPC(enc);
- tok = XML_TOK_NMTOKEN;
- break;
- }
- /* fall through */
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- case BT_GT: case BT_RPAR: case BT_COMMA:
- case BT_VERBAR: case BT_LSQB: case BT_PERCNT:
- case BT_S: case BT_CR: case BT_LF:
- *nextTokPtr = ptr;
- return tok;
-#ifdef XML_NS
- case BT_COLON:
- ptr += MINBPC(enc);
- switch (tok) {
- case XML_TOK_NAME:
- if (ptr == end)
- return XML_TOK_PARTIAL;
- tok = XML_TOK_PREFIXED_NAME;
- switch (BYTE_TYPE(enc, ptr)) {
- CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
- default:
- tok = XML_TOK_NMTOKEN;
- break;
- }
- break;
- case XML_TOK_PREFIXED_NAME:
- tok = XML_TOK_NMTOKEN;
- break;
- }
- break;
-#endif
- case BT_PLUS:
- if (tok == XML_TOK_NMTOKEN) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_NAME_PLUS;
- case BT_AST:
- if (tok == XML_TOK_NMTOKEN) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_NAME_ASTERISK;
- case BT_QUEST:
- if (tok == XML_TOK_NMTOKEN) {
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_NAME_QUESTION;
- default:
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- }
- }
- return -tok;
-}
-
-static int FASTCALL
-PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- const char *start;
- if (ptr == end)
- return XML_TOK_NONE;
- start = ptr;
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: ptr += n; break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
- case BT_AMP:
- if (ptr == start)
- return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- case BT_LT:
- /* this is for inside entity references */
- *nextTokPtr = ptr;
- return XML_TOK_INVALID;
- case BT_LF:
- if (ptr == start) {
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_DATA_NEWLINE;
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- case BT_CR:
- if (ptr == start) {
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_TRAILING_CR;
- if (BYTE_TYPE(enc, ptr) == BT_LF)
- ptr += MINBPC(enc);
- *nextTokPtr = ptr;
- return XML_TOK_DATA_NEWLINE;
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- case BT_S:
- if (ptr == start) {
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_ATTRIBUTE_VALUE_S;
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- default:
- ptr += MINBPC(enc);
- break;
- }
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
-}
-
-static int FASTCALL
-PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- const char *start;
- if (ptr == end)
- return XML_TOK_NONE;
- start = ptr;
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: ptr += n; break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
- case BT_AMP:
- if (ptr == start)
- return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- case BT_PERCNT:
- if (ptr == start) {
- int tok = PREFIX(scanPercent)(enc, ptr + MINBPC(enc),
- end, nextTokPtr);
- return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok;
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- case BT_LF:
- if (ptr == start) {
- *nextTokPtr = ptr + MINBPC(enc);
- return XML_TOK_DATA_NEWLINE;
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- case BT_CR:
- if (ptr == start) {
- ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_TRAILING_CR;
- if (BYTE_TYPE(enc, ptr) == BT_LF)
- ptr += MINBPC(enc);
- *nextTokPtr = ptr;
- return XML_TOK_DATA_NEWLINE;
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
- default:
- ptr += MINBPC(enc);
- break;
- }
- }
- *nextTokPtr = ptr;
- return XML_TOK_DATA_CHARS;
-}
-
-#ifdef XML_DTD
-
-static int FASTCALL
-PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,
- const char *end, const char **nextTokPtr)
-{
- int level = 0;
- if (MINBPC(enc) > 1) {
- size_t n = end - ptr;
- if (n & (MINBPC(enc) - 1)) {
- n &= ~(MINBPC(enc) - 1);
- end = ptr + n;
- }
- }
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
- INVALID_CASES(ptr, nextTokPtr)
- case BT_LT:
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
- if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
- if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
- ++level;
- ptr += MINBPC(enc);
- }
- }
- break;
- case BT_RSQB:
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
- if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
- if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
- ptr += MINBPC(enc);
- if (level == 0) {
- *nextTokPtr = ptr;
- return XML_TOK_IGNORE_SECT;
- }
- --level;
- }
- }
- break;
- default:
- ptr += MINBPC(enc);
- break;
- }
- }
- return XML_TOK_PARTIAL;
-}
-
-#endif /* XML_DTD */
-
-static int FASTCALL
-PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
- const char **badPtr)
-{
- ptr += MINBPC(enc);
- end -= MINBPC(enc);
- for (; ptr != end; ptr += MINBPC(enc)) {
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_DIGIT:
- case BT_HEX:
- case BT_MINUS:
- case BT_APOS:
- case BT_LPAR:
- case BT_RPAR:
- case BT_PLUS:
- case BT_COMMA:
- case BT_SOL:
- case BT_EQUALS:
- case BT_QUEST:
- case BT_CR:
- case BT_LF:
- case BT_SEMI:
- case BT_EXCL:
- case BT_AST:
- case BT_PERCNT:
- case BT_NUM:
-#ifdef XML_NS
- case BT_COLON:
-#endif
- break;
- case BT_S:
- if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) {
- *badPtr = ptr;
- return 0;
- }
- break;
- case BT_NAME:
- case BT_NMSTRT:
- if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f))
- break;
- default:
- switch (BYTE_TO_ASCII(enc, ptr)) {
- case 0x24: /* $ */
- case 0x40: /* @ */
- break;
- default:
- *badPtr = ptr;
- return 0;
- }
- break;
- }
- }
- return 1;
-}
-
-/* This must only be called for a well-formed start-tag or empty
- element tag. Returns the number of attributes. Pointers to the
- first attsMax attributes are stored in atts.
-*/
-
-static int FASTCALL
-PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
- int attsMax, ATTRIBUTE *atts)
-{
- enum { other, inName, inValue } state = inName;
- int nAtts = 0;
- int open = 0; /* defined when state == inValue;
- initialization just to shut up compilers */
-
- for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) {
- switch (BYTE_TYPE(enc, ptr)) {
-#define START_NAME \
- if (state == other) { \
- if (nAtts < attsMax) { \
- atts[nAtts].name = ptr; \
- atts[nAtts].normalized = 1; \
- } \
- state = inName; \
- }
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
- case BT_NONASCII:
- case BT_NMSTRT:
- case BT_HEX:
- START_NAME
- break;
-#undef START_NAME
- case BT_QUOT:
- if (state != inValue) {
- if (nAtts < attsMax)
- atts[nAtts].valuePtr = ptr + MINBPC(enc);
- state = inValue;
- open = BT_QUOT;
- }
- else if (open == BT_QUOT) {
- state = other;
- if (nAtts < attsMax)
- atts[nAtts].valueEnd = ptr;
- nAtts++;
- }
- break;
- case BT_APOS:
- if (state != inValue) {
- if (nAtts < attsMax)
- atts[nAtts].valuePtr = ptr + MINBPC(enc);
- state = inValue;
- open = BT_APOS;
- }
- else if (open == BT_APOS) {
- state = other;
- if (nAtts < attsMax)
- atts[nAtts].valueEnd = ptr;
- nAtts++;
- }
- break;
- case BT_AMP:
- if (nAtts < attsMax)
- atts[nAtts].normalized = 0;
- break;
- case BT_S:
- if (state == inName)
- state = other;
- else if (state == inValue
- && nAtts < attsMax
- && atts[nAtts].normalized
- && (ptr == atts[nAtts].valuePtr
- || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE
- || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE
- || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
- atts[nAtts].normalized = 0;
- break;
- case BT_CR: case BT_LF:
- /* This case ensures that the first attribute name is counted
- Apart from that we could just change state on the quote. */
- if (state == inName)
- state = other;
- else if (state == inValue && nAtts < attsMax)
- atts[nAtts].normalized = 0;
- break;
- case BT_GT:
- case BT_SOL:
- if (state != inValue)
- return nAtts;
- break;
- default:
- break;
- }
- }
- /* not reached */
-}
-
-static int FASTCALL
-PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
-{
- int result = 0;
- /* skip &# */
- ptr += 2*MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_x)) {
- for (ptr += MINBPC(enc);
- !CHAR_MATCHES(enc, ptr, ASCII_SEMI);
- ptr += MINBPC(enc)) {
- int c = BYTE_TO_ASCII(enc, ptr);
- switch (c) {
- case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4:
- case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9:
- result <<= 4;
- result |= (c - ASCII_0);
- break;
- case ASCII_A: case ASCII_B: case ASCII_C:
- case ASCII_D: case ASCII_E: case ASCII_F:
- result <<= 4;
- result += 10 + (c - ASCII_A);
- break;
- case ASCII_a: case ASCII_b: case ASCII_c:
- case ASCII_d: case ASCII_e: case ASCII_f:
- result <<= 4;
- result += 10 + (c - ASCII_a);
- break;
- }
- if (result >= 0x110000)
- return -1;
- }
- }
- else {
- for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
- int c = BYTE_TO_ASCII(enc, ptr);
- result *= 10;
- result += (c - ASCII_0);
- if (result >= 0x110000)
- return -1;
- }
- }
- return checkCharRefNumber(result);
-}
-
-static int FASTCALL
-PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,
- const char *end)
-{
- switch ((end - ptr)/MINBPC(enc)) {
- case 2:
- if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) {
- switch (BYTE_TO_ASCII(enc, ptr)) {
- case ASCII_l:
- return ASCII_LT;
- case ASCII_g:
- return ASCII_GT;
- }
- }
- break;
- case 3:
- if (CHAR_MATCHES(enc, ptr, ASCII_a)) {
- ptr += MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_m)) {
- ptr += MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_p))
- return ASCII_AMP;
- }
- }
- break;
- case 4:
- switch (BYTE_TO_ASCII(enc, ptr)) {
- case ASCII_q:
- ptr += MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_u)) {
- ptr += MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
- ptr += MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_t))
- return ASCII_QUOT;
- }
- }
- break;
- case ASCII_a:
- ptr += MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_p)) {
- ptr += MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
- ptr += MINBPC(enc);
- if (CHAR_MATCHES(enc, ptr, ASCII_s))
- return ASCII_APOS;
- }
- }
- break;
- }
- }
- return 0;
-}
-
-static int FASTCALL
-PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
-{
- for (;;) {
- switch (BYTE_TYPE(enc, ptr1)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: \
- if (*ptr1++ != *ptr2++) \
- return 0;
- LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2)
-#undef LEAD_CASE
- /* fall through */
- if (*ptr1++ != *ptr2++)
- return 0;
- break;
- case BT_NONASCII:
- case BT_NMSTRT:
-#ifdef XML_NS
- case BT_COLON:
-#endif
- case BT_HEX:
- case BT_DIGIT:
- case BT_NAME:
- case BT_MINUS:
- if (*ptr2++ != *ptr1++)
- return 0;
- if (MINBPC(enc) > 1) {
- if (*ptr2++ != *ptr1++)
- return 0;
- if (MINBPC(enc) > 2) {
- if (*ptr2++ != *ptr1++)
- return 0;
- if (MINBPC(enc) > 3) {
- if (*ptr2++ != *ptr1++)
- return 0;
- }
- }
- }
- break;
- default:
- if (MINBPC(enc) == 1 && *ptr1 == *ptr2)
- return 1;
- switch (BYTE_TYPE(enc, ptr2)) {
- case BT_LEAD2:
- case BT_LEAD3:
- case BT_LEAD4:
- case BT_NONASCII:
- case BT_NMSTRT:
-#ifdef XML_NS
- case BT_COLON:
-#endif
- case BT_HEX:
- case BT_DIGIT:
- case BT_NAME:
- case BT_MINUS:
- return 0;
- default:
- return 1;
- }
- }
- }
- /* not reached */
-}
-
-static int FASTCALL
-PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
- const char *end1, const char *ptr2)
-{
- for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
- if (ptr1 == end1)
- return 0;
- if (!CHAR_MATCHES(enc, ptr1, *ptr2))
- return 0;
- }
- return ptr1 == end1;
-}
-
-static int FASTCALL
-PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
-{
- const char *start = ptr;
- for (;;) {
- switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: ptr += n; break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
- case BT_NONASCII:
- case BT_NMSTRT:
-#ifdef XML_NS
- case BT_COLON:
-#endif
- case BT_HEX:
- case BT_DIGIT:
- case BT_NAME:
- case BT_MINUS:
- ptr += MINBPC(enc);
- break;
- default:
- return ptr - start;
- }
- }
-}
-
-static const char * FASTCALL
-PREFIX(skipS)(const ENCODING *enc, const char *ptr)
-{
- for (;;) {
- switch (BYTE_TYPE(enc, ptr)) {
- case BT_LF:
- case BT_CR:
- case BT_S:
- ptr += MINBPC(enc);
- break;
- default:
- return ptr;
- }
- }
-}
-
-static void FASTCALL
-PREFIX(updatePosition)(const ENCODING *enc,
- const char *ptr,
- const char *end,
- POSITION *pos)
-{
- while (ptr != end) {
- switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
- case BT_LEAD ## n: \
- ptr += n; \
- break;
- LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
- case BT_LF:
- pos->columnNumber = (unsigned)-1;
- pos->lineNumber++;
- ptr += MINBPC(enc);
- break;
- case BT_CR:
- pos->lineNumber++;
- ptr += MINBPC(enc);
- if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
- ptr += MINBPC(enc);
- pos->columnNumber = (unsigned)-1;
- break;
- default:
- ptr += MINBPC(enc);
- break;
- }
- pos->columnNumber++;
- }
-}
-
-#undef DO_LEAD_CASE
-#undef MULTIBYTE_CASES
-#undef INVALID_CASES
-#undef CHECK_NAME_CASE
-#undef CHECK_NAME_CASES
-#undef CHECK_NMSTRT_CASE
-#undef CHECK_NMSTRT_CASES
diff --git a/bundle/expat/xmltok_impl.h b/bundle/expat/xmltok_impl.h
deleted file mode 100644
index da0ea60a65..0000000000
--- a/bundle/expat/xmltok_impl.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
-See the file COPYING for copying permission.
-*/
-
-enum {
- BT_NONXML,
- BT_MALFORM,
- BT_LT,
- BT_AMP,
- BT_RSQB,
- BT_LEAD2,
- BT_LEAD3,
- BT_LEAD4,
- BT_TRAIL,
- BT_CR,
- BT_LF,
- BT_GT,
- BT_QUOT,
- BT_APOS,
- BT_EQUALS,
- BT_QUEST,
- BT_EXCL,
- BT_SOL,
- BT_SEMI,
- BT_NUM,
- BT_LSQB,
- BT_S,
- BT_NMSTRT,
- BT_COLON,
- BT_HEX,
- BT_DIGIT,
- BT_NAME,
- BT_MINUS,
- BT_OTHER, /* known not to be a name or name start character */
- BT_NONASCII, /* might be a name or name start character */
- BT_PERCNT,
- BT_LPAR,
- BT_RPAR,
- BT_AST,
- BT_PLUS,
- BT_COMMA,
- BT_VERBAR
-};
-
-#include <stddef.h>
diff --git a/bundle/expat/xmltok_ns.c b/bundle/expat/xmltok_ns.c
deleted file mode 100644
index 011cb8f0c5..0000000000
--- a/bundle/expat/xmltok_ns.c
+++ /dev/null
@@ -1,106 +0,0 @@
-const ENCODING *
-NS(XmlGetUtf8InternalEncoding)(void)
-{
- return &ns(internal_utf8_encoding).enc;
-}
-
-const ENCODING *
-NS(XmlGetUtf16InternalEncoding)(void)
-{
-#if BYTEORDER == 1234
- return &ns(internal_little2_encoding).enc;
-#elif BYTEORDER == 4321
- return &ns(internal_big2_encoding).enc;
-#else
- const short n = 1;
- return (*(const char *)&n
- ? &ns(internal_little2_encoding).enc
- : &ns(internal_big2_encoding).enc);
-#endif
-}
-
-static const ENCODING *NS(encodings)[] = {
- &ns(latin1_encoding).enc,
- &ns(ascii_encoding).enc,
- &ns(utf8_encoding).enc,
- &ns(big2_encoding).enc,
- &ns(big2_encoding).enc,
- &ns(little2_encoding).enc,
- &ns(utf8_encoding).enc /* NO_ENC */
-};
-
-static int FASTCALL
-NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- return initScan(NS(encodings), (const INIT_ENCODING *)enc,
- XML_PROLOG_STATE, ptr, end, nextTokPtr);
-}
-
-static int FASTCALL
-NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
- const char **nextTokPtr)
-{
- return initScan(NS(encodings), (const INIT_ENCODING *)enc,
- XML_CONTENT_STATE, ptr, end, nextTokPtr);
-}
-
-int
-NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr,
- const char *name)
-{
- int i = getEncodingIndex(name);
- if (i == UNKNOWN_ENC)
- return 0;
- SET_INIT_ENC_INDEX(p, i);
- p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog);
- p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent);
- p->initEnc.updatePosition = initUpdatePosition;
- p->encPtr = encPtr;
- *encPtr = &(p->initEnc);
- return 1;
-}
-
-static const ENCODING *
-NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
-{
-#define ENCODING_MAX 128
- char buf[ENCODING_MAX];
- char *p = buf;
- int i;
- XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
- if (ptr != end)
- return 0;
- *p = 0;
- if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2)
- return enc;
- i = getEncodingIndex(buf);
- if (i == UNKNOWN_ENC)
- return 0;
- return NS(encodings)[i];
-}
-
-int
-NS(XmlParseXmlDecl)(int isGeneralTextEntity,
- const ENCODING *enc,
- const char *ptr,
- const char *end,
- const char **badPtr,
- const char **versionPtr,
- const char **versionEndPtr,
- const char **encodingName,
- const ENCODING **encoding,
- int *standalone)
-{
- return doParseXmlDecl(NS(findEncoding),
- isGeneralTextEntity,
- enc,
- ptr,
- end,
- badPtr,
- versionPtr,
- versionEndPtr,
- encodingName,
- encoding,
- standalone);
-}
diff --git a/bundle/libxml/DOCBparser.c b/bundle/libxml/DOCBparser.c
deleted file mode 100644
index f84a0be450..0000000000
--- a/bundle/libxml/DOCBparser.c
+++ /dev/null
@@ -1,6107 +0,0 @@
-/*
- * DOCBparser.c : an attempt to parse SGML Docbook documents
- *
- * This is extremely hackish. It also adds one extension
- * <?sgml-declaration encoding="ISO-8859-1"?>
- * allowing to store the encoding of the document within the instance.
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-#ifdef LIBXML_DOCB_ENABLED
-
-#include <string.h>
-#ifdef HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include <libxml/xmlmemory.h>
-#include <libxml/tree.h>
-#include <libxml/SAX.h>
-#include <libxml/parser.h>
-#include <libxml/parserInternals.h>
-#include <libxml/xmlerror.h>
-#include <libxml/DOCBparser.h>
-#include <libxml/entities.h>
-#include <libxml/encoding.h>
-#include <libxml/valid.h>
-#include <libxml/xmlIO.h>
-#include <libxml/uri.h>
-#include <libxml/globals.h>
-
-/*
- * DocBook XML current versions
- */
-
-#define XML_DOCBOOK_XML_PUBLIC (const xmlChar *) \
- "-//OASIS//DTD DocBook XML V4.1.2//EN"
-#define XML_DOCBOOK_XML_SYSTEM (const xmlChar *) \
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"
-
-/*
- * Internal description of an SGML entity
- */
-typedef struct _docbEntityDesc docbEntityDesc;
-typedef docbEntityDesc *docbEntityDescPtr;
-struct _docbEntityDesc {
- int value; /* the UNICODE value for the character */
- const char *name; /* The entity name */
- const char *desc; /* the description */
-};
-
-static int docbParseCharRef(docbParserCtxtPtr ctxt);
-static xmlEntityPtr docbParseEntityRef(docbParserCtxtPtr ctxt,
- xmlChar **str);
-static void docbParseElement(docbParserCtxtPtr ctxt);
-static void docbParseContent(docbParserCtxtPtr ctxt);
-
-/*
- * Internal description of an SGML element
- */
-typedef struct _docbElemDesc docbElemDesc;
-typedef docbElemDesc *docbElemDescPtr;
-struct _docbElemDesc {
- const char *name; /* The tag name */
- int startTag; /* Whether the start tag can be implied */
- int endTag; /* Whether the end tag can be implied */
- int empty; /* Is this an empty element ? */
- int depr; /* Is this a deprecated element ? */
- int dtd; /* 1: only in Loose DTD, 2: only Frameset one */
- const char *desc; /* the description */
-};
-
-
-#define DOCB_MAX_NAMELEN 1000
-#define DOCB_PARSER_BIG_BUFFER_SIZE 1000
-#define DOCB_PARSER_BUFFER_SIZE 100
-
-/* #define DEBUG */
-/* #define DEBUG_PUSH */
-
-/************************************************************************
- * *
- * Parser stacks related functions and macros *
- * *
- ************************************************************************/
-
-/**
- * docbnamePush:
- * @ctxt: a DocBook SGML parser context
- * @value: the element name
- *
- * Pushes a new element name on top of the name stack
- *
- * Returns 0 in case of error, the index in the stack otherwise
- */
-static int
-docbnamePush(docbParserCtxtPtr ctxt, xmlChar * value)
-{
- if (ctxt->nameNr >= ctxt->nameMax) {
- ctxt->nameMax *= 2;
- ctxt->nameTab =
- (xmlChar * *)xmlRealloc(ctxt->nameTab,
- ctxt->nameMax *
- sizeof(ctxt->nameTab[0]));
- if (ctxt->nameTab == NULL) {
- xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
- return (0);
- }
- }
- ctxt->nameTab[ctxt->nameNr] = value;
- ctxt->name = value;
- return (ctxt->nameNr++);
-}
-/**
- * docbnamePop:
- * @ctxt: a DocBook SGML parser context
- *
- * Pops the top element name from the name stack
- *
- * Returns the name just removed
- */
-static xmlChar *
-docbnamePop(docbParserCtxtPtr ctxt)
-{
- xmlChar *ret;
-
- if (ctxt->nameNr < 0)
- return (0);
- ctxt->nameNr--;
- if (ctxt->nameNr < 0)
- return (0);
- if (ctxt->nameNr > 0)
- ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
- else
- ctxt->name = NULL;
- ret = ctxt->nameTab[ctxt->nameNr];
- ctxt->nameTab[ctxt->nameNr] = 0;
- return (ret);
-}
-
-/*
- * Macros for accessing the content. Those should be used only by the parser,
- * and not exported.
- *
- * Dirty macros, i.e. one need to make assumption on the context to use them
- *
- * CUR_PTR return the current pointer to the xmlChar to be parsed.
- * CUR returns the current xmlChar value, i.e. a 8 bit value if compiled
- * in ISO-Latin or UTF-8, and the current 16 bit value if compiled
- * in UNICODE mode. This should be used internally by the parser
- * only to compare to ASCII values otherwise it would break when
- * running with UTF-8 encoding.
- * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only
- * to compare on ASCII based substring.
- * UPP(n) returns the n'th next xmlChar converted to uppercase. Same as CUR
- * it should be used only to compare on ASCII based substring.
- * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
- * strings within the parser.
- *
- * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
- *
- * CURRENT Returns the current char value, with the full decoding of
- * UTF-8 if we are using this mode. It returns an int.
- * NEXT Skip to the next character, this does the proper decoding
- * in UTF-8 mode. It also pop-up unfinished entities on the fly.
- * COPY(to) copy one char to *to, increment CUR_PTR and to accordingly
- */
-
-#define UPPER (toupper(*ctxt->input->cur))
-
-#define SKIP(val) ctxt->nbChars += (val),ctxt->input->cur += (val)
-
-#define NXT(val) ctxt->input->cur[(val)]
-
-#define UPP(val) (toupper(ctxt->input->cur[(val)]))
-
-#define CUR_PTR ctxt->input->cur
-
-#define SHRINK xmlParserInputShrink(ctxt->input)
-
-#define GROW xmlParserInputGrow(ctxt->input, INPUT_CHUNK)
-
-#define CURRENT ((int) (*ctxt->input->cur))
-
-#define SKIP_BLANKS docbSkipBlankChars(ctxt)
-
-/* Imported from XML */
-
-/* #define CUR (ctxt->token ? ctxt->token : (int) (*ctxt->input->cur)) */
-#define CUR ((int) (*ctxt->input->cur))
-#define NEXT xmlNextChar(ctxt),ctxt->nbChars++
-
-#define RAW (ctxt->token ? -1 : (*ctxt->input->cur))
-#define NXT(val) ctxt->input->cur[(val)]
-#define CUR_PTR ctxt->input->cur
-
-
-#define NEXTL(l) do { \
- if (*(ctxt->input->cur) == '\n') { \
- ctxt->input->line++; ctxt->input->col = 1; \
- } else ctxt->input->col++; \
- ctxt->token = 0; ctxt->input->cur += l; ctxt->nbChars++; \
- } while (0)
-
-/************
- \
- if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
- if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt);
- ************/
-
-#define CUR_CHAR(l) docbCurrentChar(ctxt, &l)
-#define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
-
-#define COPY_BUF(l,b,i,v) \
- if (l == 1) b[i++] = (xmlChar) v; \
- else i += xmlCopyChar(l,&b[i],v)
-
-/**
- * docbCurrentChar:
- * @ctxt: the DocBook SGML parser context
- * @len: pointer to the length of the char read
- *
- * The current char value, if using UTF-8 this may actually span multiple
- * bytes in the input buffer. Implement the end of line normalization:
- * 2.11 End-of-Line Handling
- * If the encoding is unspecified, in the case we find an ISO-Latin-1
- * char, then the encoding converter is plugged in automatically.
- *
- * Returns the current char value and its length
- */
-
-static int
-docbCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
- if (ctxt->instate == XML_PARSER_EOF)
- return(0);
-
- if (ctxt->token != 0) {
- *len = 0;
- return(ctxt->token);
- }
- if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
- /*
- * We are supposed to handle UTF8, check it's valid
- * From rfc2044: encoding of the Unicode values on UTF-8:
- *
- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
- * 0000 0000-0000 007F 0xxxxxxx
- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
- *
- * Check for the 0x110000 limit too
- */
- const unsigned char *cur = ctxt->input->cur;
- unsigned char c;
- unsigned int val;
-
- c = *cur;
- if (c & 0x80) {
- if (cur[1] == 0)
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- if ((cur[1] & 0xc0) != 0x80)
- goto encoding_error;
- if ((c & 0xe0) == 0xe0) {
-
- if (cur[2] == 0)
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- if ((cur[2] & 0xc0) != 0x80)
- goto encoding_error;
- if ((c & 0xf0) == 0xf0) {
- if (cur[3] == 0)
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- if (((c & 0xf8) != 0xf0) ||
- ((cur[3] & 0xc0) != 0x80))
- goto encoding_error;
- /* 4-byte code */
- *len = 4;
- val = (cur[0] & 0x7) << 18;
- val |= (cur[1] & 0x3f) << 12;
- val |= (cur[2] & 0x3f) << 6;
- val |= cur[3] & 0x3f;
- } else {
- /* 3-byte code */
- *len = 3;
- val = (cur[0] & 0xf) << 12;
- val |= (cur[1] & 0x3f) << 6;
- val |= cur[2] & 0x3f;
- }
- } else {
- /* 2-byte code */
- *len = 2;
- val = (cur[0] & 0x1f) << 6;
- val |= cur[1] & 0x3f;
- }
- if (!IS_CHAR(val)) {
- ctxt->errNo = XML_ERR_INVALID_ENCODING;
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Char 0x%X out of allowed range\n", val);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- return(val);
- } else {
- /* 1-byte code */
- *len = 1;
- return((int) *ctxt->input->cur);
- }
- }
- /*
- * Assume it's a fixed length encoding (1) with
- * a compatible encoding for the ASCII set, since
- * XML constructs only use < 128 chars
- */
- *len = 1;
- if ((int) *ctxt->input->cur < 0x80)
- return((int) *ctxt->input->cur);
-
- /*
- * Humm this is bad, do an automatic flow conversion
- */
- xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1);
- ctxt->charset = XML_CHAR_ENCODING_UTF8;
- return(xmlCurrentChar(ctxt, len));
-
-encoding_error:
- /*
- * If we detect an UTF8 error that probably mean that the
- * input encoding didn't get properly advertized in the
- * declaration header. Report the error and switch the encoding
- * to ISO-Latin-1 (if you don't like this policy, just declare the
- * encoding !)
- */
- ctxt->errNo = XML_ERR_INVALID_ENCODING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
- ctxt->sax->error(ctxt->userData,
- "Input is not proper UTF-8, indicate encoding !\n");
- ctxt->sax->error(ctxt->userData, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
- ctxt->input->cur[0], ctxt->input->cur[1],
- ctxt->input->cur[2], ctxt->input->cur[3]);
- }
-
- ctxt->charset = XML_CHAR_ENCODING_8859_1;
- *len = 1;
- return((int) *ctxt->input->cur);
-}
-
-#if 0
-/**
- * sgmlNextChar:
- * @ctxt: the DocBook SGML parser context
- *
- * Skip to the next char input char.
- */
-
-static void
-sgmlNextChar(docbParserCtxtPtr ctxt) {
- if (ctxt->instate == XML_PARSER_EOF)
- return;
- if ((*ctxt->input->cur == 0) &&
- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) {
- xmlPopInput(ctxt);
- } else {
- if (*(ctxt->input->cur) == '\n') {
- ctxt->input->line++; ctxt->input->col = 1;
- } else ctxt->input->col++;
- ctxt->input->cur++;
- ctxt->nbChars++;
- if (*ctxt->input->cur == 0)
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- }
-}
-#endif
-
-/**
- * docbSkipBlankChars:
- * @ctxt: the DocBook SGML parser context
- *
- * skip all blanks character found at that point in the input streams.
- *
- * Returns the number of space chars skipped
- */
-
-static int
-docbSkipBlankChars(xmlParserCtxtPtr ctxt) {
- int res = 0;
-
- while (IS_BLANK(*(ctxt->input->cur))) {
- if ((*ctxt->input->cur == 0) &&
- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) {
- xmlPopInput(ctxt);
- } else {
- if (*(ctxt->input->cur) == '\n') {
- ctxt->input->line++; ctxt->input->col = 1;
- } else ctxt->input->col++;
- ctxt->input->cur++;
- ctxt->nbChars++;
- if (*ctxt->input->cur == 0)
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- }
- res++;
- }
- return(res);
-}
-
-
-
-/************************************************************************
- * *
- * The list of SGML elements and their properties *
- * *
- ************************************************************************/
-
-/*
- * Start Tag: 1 means the start tag can be ommited
- * End Tag: 1 means the end tag can be ommited
- * 2 means it's forbidden (empty elements)
- * Depr: this element is deprecated
- * DTD: 1 means that this element is valid only in the Loose DTD
- * 2 means that this element is valid only in the Frameset DTD
- *
- * Name,Start Tag,End Tag, Empty, Depr., DTD, Description
- */
-static docbElemDesc
-docbookElementTable[] = {
-{ "abbrev", 0, 0, 0, 3, 0, "" }, /* word */
-{ "abstract", 0, 0, 0, 9, 0, "" }, /* title */
-{ "accel", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "ackno", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "acronym", 0, 0, 0, 3, 0, "" }, /* word */
-{ "action", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "address", 0, 0, 0, 1, 0, "" },
-{ "affiliation",0, 0, 0, 9, 0, "" }, /* shortaffil */
-{ "alt", 0, 0, 0, 1, 0, "" },
-{ "anchor", 0, 2, 1, 0, 0, "" },
-{ "answer", 0, 0, 0, 9, 0, "" }, /* label */
-{ "appendix", 0, 0, 0, 9, 0, "" }, /* appendixinfo */
-{ "appendixinfo",0, 0, 0, 9, 0, "" }, /* graphic */
-{ "application",0, 0, 0, 2, 0, "" }, /* para */
-{ "area", 0, 2, 1, 0, 0, "" },
-{ "areaset", 0, 0, 0, 9, 0, "" }, /* area */
-{ "areaspec", 0, 0, 0, 9, 0, "" }, /* area */
-{ "arg", 0, 0, 0, 1, 0, "" },
-{ "artheader", 0, 0, 0, 9, 0, "" },
-{ "article", 0, 0, 0, 9, 0, "" }, /* div.title.content */
-{ "articleinfo",0, 0, 0, 9, 0, "" }, /* graphic */
-{ "artpagenums",0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "attribution",0, 0, 0, 2, 0, "" }, /* para */
-{ "audiodata", 0, 2, 1, 0, 0, "" },
-{ "audioobject",0, 0, 0, 9, 0, "" }, /* objectinfo */
-{ "authorblurb",0, 0, 0, 9, 0, "" }, /* title */
-{ "authorgroup",0, 0, 0, 9, 0, "" }, /* author */
-{ "authorinitials",0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "author", 0, 0, 0, 9, 0, "" }, /* person.ident.mix */
-{ "beginpage", 0, 2, 1, 0, 0, "" },
-{ "bibliodiv", 0, 0, 0, 9, 0, "" }, /* sect.title.content */
-{ "biblioentry",0, 0, 0, 9, 0, "" }, /* articleinfo */
-{ "bibliography",0, 0, 0, 9, 0, "" }, /* bibliographyinfo */
-{ "bibliographyinfo",0, 0, 0, 9, 0, "" }, /* graphic */
-{ "bibliomisc", 0, 0, 0, 2, 0, "" }, /* para */
-{ "bibliomixed",0, 0, 0, 1, 0, "" }, /* %bibliocomponent.mix, bibliomset) */
-{ "bibliomset", 0, 0, 0, 1, 0, "" }, /* %bibliocomponent.mix; | bibliomset) */
-{ "biblioset", 0, 0, 0, 9, 0, "" }, /* bibliocomponent.mix */
-{ "blockquote", 0, 0, 0, 9, 0, "" }, /* title */
-{ "book", 0, 0, 0, 9, 0, "" }, /* div.title.content */
-{ "bookinfo", 0, 0, 0, 9, 0, "" }, /* graphic */
-{ "bridgehead", 0, 0, 0, 8, 0, "" }, /* title */
-{ "callout", 0, 0, 0, 9, 0, "" }, /* component.mix */
-{ "calloutlist",0, 0, 0, 9, 0, "" }, /* formalobject.title.content */
-{ "caption", 0, 0, 0, 9, 0, "" }, /* textobject.mix */
-{ "caution", 0, 0, 0, 9, 0, "" }, /* title */
-{ "chapter", 0, 0, 0, 9, 0, "" }, /* chapterinfo */
-{ "chapterinfo",0, 0, 0, 9, 0, "" }, /* graphic */
-{ "citation", 0, 0, 0, 2, 0, "" }, /* para */
-{ "citerefentry",0, 0, 0, 9, 0, "" }, /* refentrytitle */
-{ "citetitle", 0, 0, 0, 2, 0, "" }, /* para */
-{ "city", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "classname", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "classsynopsisinfo",0,0, 0, 9, 0, "" }, /* cptr */
-{ "classsynopsis",0, 0, 0, 9, 0, "" }, /* ooclass */
-{ "cmdsynopsis",0, 0, 0, 9, 0, "" }, /* command */
-{ "co", 0, 2, 1, 0, 0, "" },
-{ "collab", 0, 0, 0, 9, 0, "" }, /* collabname */
-{ "collabname", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "colophon", 0, 0, 0, 9, 0, "" }, /* sect.title.content */
-{ "colspec", 0, 2, 1, 0, 0, "" },
-{ "colspec", 0, 2, 1, 0, 0, "" },
-{ "command", 0, 0, 0, 9, 0, "" }, /* cptr */
-{ "computeroutput",0, 0, 0, 9, 0, "" }, /* cptr */
-{ "confdates", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "confgroup", 0, 0, 0, 9, 0, "" }, /* confdates */
-{ "confnum", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "confsponsor",0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "conftitle", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "constant", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "constructorsynopsis",0,0, 0, 9, 0, "" }, /* modifier */
-{ "contractnum",0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "contractsponsor",0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "contrib", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "copyright", 0, 0, 0, 9, 0, "" }, /* year */
-{ "corpauthor", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "corpname", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "country", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "database", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "date", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "dedication", 0, 0, 0, 9, 0, "" }, /* sect.title.content */
-{ "destructorsynopsis",0,0, 0, 9, 0, "" }, /* modifier */
-{ "docinfo", 0, 0, 0, 9, 0, "" },
-{ "edition", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "editor", 0, 0, 0, 9, 0, "" }, /* person.ident.mix */
-{ "email", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "emphasis", 0, 0, 0, 2, 0, "" }, /* para */
-{ "entry", 0, 0, 0, 9, 0, "" }, /* tbl.entry.mdl */
-{ "entrytbl", 0, 0, 0, 9, 0, "" }, /* tbl.entrytbl.mdl */
-{ "envar", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "epigraph", 0, 0, 0, 9, 0, "" }, /* attribution */
-{ "equation", 0, 0, 0, 9, 0, "" }, /* formalobject.title.content */
-{ "errorcode", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "errorname", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "errortype", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "example", 0, 0, 0, 9, 0, "" }, /* formalobject.title.content */
-{ "exceptionname",0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "fax", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "fieldsynopsis", 0, 0, 0, 9, 0, "" }, /* modifier */
-{ "figure", 0, 0, 0, 9, 0, "" }, /* formalobject.title.content */
-{ "filename", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "firstname", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "firstterm", 0, 0, 0, 3, 0, "" }, /* word */
-{ "footnote", 0, 0, 0, 9, 0, "" }, /* footnote.mix */
-{ "footnoteref",0, 2, 1, 0, 0, "" },
-{ "foreignphrase",0, 0, 0, 2, 0, "" }, /* para */
-{ "formalpara", 0, 0, 0, 9, 0, "" }, /* title */
-{ "funcdef", 0, 0, 0, 1, 0, "" },
-{ "funcparams", 0, 0, 0, 9, 0, "" }, /* cptr */
-{ "funcprototype",0, 0, 0, 9, 0, "" }, /* funcdef */
-{ "funcsynopsis",0, 0, 0, 9, 0, "" }, /* funcsynopsisinfo */
-{ "funcsynopsisinfo", 0, 0, 0, 9, 0, "" }, /* cptr */
-{ "function", 0, 0, 0, 9, 0, "" }, /* cptr */
-{ "glossary", 0, 0, 0, 9, 0, "" }, /* glossaryinfo */
-{ "glossaryinfo",0, 0, 0, 9, 0, "" }, /* graphic */
-{ "glossdef", 0, 0, 0, 9, 0, "" }, /* glossdef.mix */
-{ "glossdiv", 0, 0, 0, 9, 0, "" }, /* sect.title.content */
-{ "glossentry", 0, 0, 0, 9, 0, "" }, /* glossterm */
-{ "glosslist", 0, 0, 0, 9, 0, "" }, /* glossentry */
-{ "glossseealso",0, 0, 1, 2, 0, "" }, /* para */
-{ "glosssee", 0, 0, 1, 2, 0, "" }, /* para */
-{ "glossterm", 0, 0, 0, 2, 0, "" }, /* para */
-{ "graphic", 0, 0, 0, 9, 0, "" },
-{ "graphicco", 0, 0, 0, 9, 0, "" }, /* areaspec */
-{ "group", 0, 0, 0, 9, 0, "" }, /* arg */
-{ "guibutton", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "guiicon", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "guilabel", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "guimenuitem",0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "guimenu", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "guisubmenu", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "hardware", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "highlights", 0, 0, 0, 9, 0, "" }, /* highlights.mix */
-{ "holder", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "honorific", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "imagedata", 0, 2, 1, 0, 0, "" },
-{ "imageobjectco",0, 0, 0, 9, 0, "" }, /* areaspec */
-{ "imageobject",0, 0, 0, 9, 0, "" }, /* objectinfo */
-{ "important", 0, 0, 0, 9, 0, "" }, /* title */
-{ "indexdiv", 0, 0, 0, 9, 0, "" }, /* sect.title.content */
-{ "indexentry", 0, 0, 0, 9, 0, "" }, /* primaryie */
-{ "index", 0, 0, 0, 9, 0, "" }, /* indexinfo */
-{ "indexinfo", 0, 0, 0, 9, 0, "" }, /* graphic */
-{ "indexterm", 0, 0, 0, 9, 0, "" }, /* primary */
-{ "informalequation",0, 0, 0, 9, 0, "" }, /* equation.content */
-{ "informalexample",0, 0, 0, 9, 0, "" }, /* example.mix */
-{ "informalfigure",0, 0, 0, 9, 0, "" }, /* figure.mix */
-{ "informaltable",0, 0, 0, 9, 0, "" }, /* graphic */
-{ "initializer",0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "inlineequation",0, 0, 0, 9, 0, "" }, /* inlineequation.content */
-{ "inlinegraphic",0, 0, 0, 9, 0, "" },
-{ "inlinemediaobject",0,0, 0, 9, 0, "" }, /* objectinfo */
-{ "interfacename",0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "interface", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "invpartnumber",0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "isbn", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "issn", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "issuenum", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "itemizedlist",0, 0, 0, 9, 0, "" }, /* formalobject.title.content */
-{ "itermset", 0, 0, 0, 9, 0, "" }, /* indexterm */
-{ "jobtitle", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "keycap", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "keycode", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "keycombo", 0, 0, 0, 9, 0, "" }, /* keycap */
-{ "keysym", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "keyword", 0, 0, 0, 1, 0, "" },
-{ "keywordset", 0, 0, 0, 9, 0, "" }, /* keyword */
-{ "label", 0, 0, 0, 3, 0, "" }, /* word */
-{ "legalnotice",0, 0, 0, 9, 0, "" }, /* title */
-{ "lineage", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "lineannotation",0, 0, 0, 2, 0, "" }, /* para */
-{ "link", 0, 0, 0, 2, 0, "" }, /* para */
-{ "listitem", 0, 0, 0, 9, 0, "" }, /* component.mix */
-{ "literal", 0, 0, 0, 9, 0, "" }, /* cptr */
-{ "literallayout",0, 0, 0, 2, 0, "" }, /* para */
-{ "lot", 0, 0, 0, 9, 0, "" }, /* bookcomponent.title.content */
-{ "lotentry", 0, 0, 0, 2, 0, "" }, /* para */
-{ "manvolnum", 0, 0, 0, 3, 0, "" }, /* word */
-{ "markup", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "medialabel", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "mediaobjectco",0, 0, 0, 9, 0, "" }, /* objectinfo */
-{ "mediaobject",0, 0, 0, 9, 0, "" }, /* objectinfo */
-{ "member", 0, 0, 0, 2, 0, "" }, /* para */
-{ "menuchoice", 0, 0, 0, 9, 0, "" }, /* shortcut */
-{ "methodname", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "methodparam",0, 0, 0, 9, 0, "" }, /* modifier */
-{ "methodsynopsis",0, 0, 0, 9, 0, "" }, /* modifier */
-{ "modespec", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "modifier", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "mousebutton",0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "msgaud", 0, 0, 0, 2, 0, "" }, /* para */
-{ "msgentry", 0, 0, 0, 9, 0, "" }, /* msg */
-{ "msgexplan", 0, 0, 0, 9, 0, "" }, /* title */
-{ "msginfo", 0, 0, 0, 9, 0, "" }, /* msglevel */
-{ "msglevel", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "msgmain", 0, 0, 0, 9, 0, "" }, /* title */
-{ "msgorig", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "msgrel", 0, 0, 0, 9, 0, "" }, /* title */
-{ "msgset", 0, 0, 0, 9, 0, "" }, /* formalobject.title.content */
-{ "msgsub", 0, 0, 0, 9, 0, "" }, /* title */
-{ "msgtext", 0, 0, 0, 9, 0, "" }, /* component.mix */
-{ "msg", 0, 0, 0, 9, 0, "" }, /* title */
-{ "note", 0, 0, 0, 9, 0, "" }, /* title */
-{ "objectinfo", 0, 0, 0, 9, 0, "" }, /* graphic */
-{ "olink", 0, 0, 0, 2, 0, "" }, /* para */
-{ "ooclass", 0, 0, 0, 9, 0, "" }, /* modifier */
-{ "ooexception",0, 0, 0, 9, 0, "" }, /* modifier */
-{ "oointerface",0, 0, 0, 9, 0, "" }, /* modifier */
-{ "optional", 0, 0, 0, 9, 0, "" }, /* cptr */
-{ "option", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "orderedlist",0, 0, 0, 9, 0, "" }, /* formalobject.title.content */
-{ "orgdiv", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "orgname", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "otheraddr", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "othercredit",0, 0, 0, 9, 0, "" }, /* person.ident.mix */
-{ "othername", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "pagenums", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "paramdef", 0, 0, 0, 1, 0, "" },
-{ "parameter", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "para", 0, 0, 0, 2, 0, "" }, /* para */
-{ "partinfo", 0, 0, 0, 9, 0, "" }, /* graphic */
-{ "partintro", 0, 0, 0, 9, 0, "" }, /* div.title.content */
-{ "part", 0, 0, 0, 9, 0, "" }, /* partinfo */
-{ "phone", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "phrase", 0, 0, 0, 2, 0, "" }, /* para */
-{ "pob", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "postcode", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "prefaceinfo",0, 0, 0, 9, 0, "" }, /* graphic */
-{ "preface", 0, 0, 0, 9, 0, "" }, /* prefaceinfo */
-{ "primaryie", 0, 0, 0, 4, 0, "" }, /* ndxterm */
-{ "primary", 0, 0, 0, 9, 0, "" }, /* ndxterm */
-{ "printhistory",0, 0, 0, 9, 0, "" }, /* para.class */
-{ "procedure", 0, 0, 0, 9, 0, "" }, /* formalobject.title.content */
-{ "productname",0, 0, 0, 2, 0, "" }, /* para */
-{ "productnumber",0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "programlistingco",0, 0, 0, 9, 0, "" }, /* areaspec */
-{ "programlisting",0, 0, 0, 2, 0, "" }, /* para */
-{ "prompt", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "property", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "pubdate", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "publishername",0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "publisher", 0, 0, 0, 9, 0, "" }, /* publishername */
-{ "pubsnumber", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "qandadiv", 0, 0, 0, 9, 0, "" }, /* formalobject.title.content */
-{ "qandaentry", 0, 0, 0, 9, 0, "" }, /* revhistory */
-{ "qandaset", 0, 0, 0, 9, 0, "" }, /* formalobject.title.content */
-{ "question", 0, 0, 0, 9, 0, "" }, /* label */
-{ "quote", 0, 0, 0, 2, 0, "" }, /* para */
-{ "refclass", 0, 0, 0, 9, 0, "" }, /* refclass.char.mix */
-{ "refdescriptor",0, 0, 0, 9, 0, "" }, /* refname.char.mix */
-{ "refentryinfo",0, 0, 0, 9, 0, "" }, /* graphic */
-{ "refentry", 0, 0, 0, 9, 0, "" }, /* ndxterm.class */
-{ "refentrytitle",0, 0, 0, 2, 0, "" }, /* para */
-{ "referenceinfo",0, 0, 0, 9, 0, "" }, /* graphic */
-{ "reference", 0, 0, 0, 9, 0, "" }, /* referenceinfo */
-{ "refmeta", 0, 0, 0, 9, 0, "" }, /* ndxterm.class */
-{ "refmiscinfo",0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "refnamediv", 0, 0, 0, 9, 0, "" }, /* refdescriptor */
-{ "refname", 0, 0, 0, 9, 0, "" }, /* refname.char.mix */
-{ "refpurpose", 0, 0, 0, 9, 0, "" }, /* refinline.char.mix */
-{ "refsect1info",0, 0, 0, 9, 0, "" }, /* graphic */
-{ "refsect1", 0, 0, 0, 9, 0, "" }, /* refsect */
-{ "refsect2info",0, 0, 0, 9, 0, "" }, /* graphic */
-{ "refsect2", 0, 0, 0, 9, 0, "" }, /* refsect */
-{ "refsect3info",0, 0, 0, 9, 0, "" }, /* graphic */
-{ "refsect3", 0, 0, 0, 9, 0, "" }, /* refsect */
-{ "refsynopsisdivinfo",0,0, 0, 9, 0, "" }, /* graphic */
-{ "refsynopsisdiv",0, 0, 0, 9, 0, "" }, /* refsynopsisdivinfo */
-{ "releaseinfo",0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "remark", 0, 0, 0, 2, 0, "" }, /* para */
-{ "replaceable",0, 0, 0, 1, 0, "" },
-{ "returnvalue",0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "revdescription",0, 0, 0, 9, 0, "" }, /* revdescription.mix */
-{ "revhistory", 0, 0, 0, 9, 0, "" }, /* revision */
-{ "revision", 0, 0, 0, 9, 0, "" }, /* revnumber */
-{ "revnumber", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "revremark", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "row", 0, 0, 0, 9, 0, "" }, /* tbl.row.mdl */
-{ "row", 0, 0, 0, 9, 0, "" }, /* tbl.row.mdl */
-{ "sbr", 0, 2, 1, 0, 0, "" },
-{ "screenco", 0, 0, 0, 9, 0, "" }, /* areaspec */
-{ "screeninfo", 0, 0, 0, 2, 0, "" }, /* para */
-{ "screen", 0, 0, 0, 2, 0, "" }, /* para */
-{ "screenshot", 0, 0, 0, 9, 0, "" }, /* screeninfo */
-{ "secondaryie",0, 0, 0, 4, 0, "" }, /* ndxterm */
-{ "secondary", 0, 0, 0, 4, 0, "" }, /* ndxterm */
-{ "sect1info", 0, 0, 0, 9, 0, "" }, /* graphic */
-{ "sect1", 0, 0, 0, 9, 0, "" }, /* sect */
-{ "sect2info", 0, 0, 0, 9, 0, "" }, /* graphic */
-{ "sect2", 0, 0, 0, 9, 0, "" }, /* sect */
-{ "sect3info", 0, 0, 0, 9, 0, "" }, /* graphic */
-{ "sect3", 0, 0, 0, 9, 0, "" }, /* sect */
-{ "sect4info", 0, 0, 0, 9, 0, "" }, /* graphic */
-{ "sect4", 0, 0, 0, 9, 0, "" }, /* sect */
-{ "sect5info", 0, 0, 0, 9, 0, "" }, /* graphic */
-{ "sect5", 0, 0, 0, 9, 0, "" }, /* sect */
-{ "sectioninfo",0, 0, 0, 9, 0, "" }, /* graphic */
-{ "section", 0, 0, 0, 9, 0, "" }, /* sectioninfo */
-{ "seealsoie", 0, 0, 0, 4, 0, "" }, /* ndxterm */
-{ "seealso", 0, 0, 0, 4, 0, "" }, /* ndxterm */
-{ "seeie", 0, 0, 0, 4, 0, "" }, /* ndxterm */
-{ "see", 0, 0, 0, 4, 0, "" }, /* ndxterm */
-{ "seglistitem",0, 0, 0, 9, 0, "" }, /* seg */
-{ "segmentedlist",0, 0, 0, 9, 0, "" }, /* formalobject.title.content */
-{ "seg", 0, 0, 0, 2, 0, "" }, /* para */
-{ "segtitle", 0, 0, 0, 8, 0, "" }, /* title */
-{ "seriesvolnums", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "set", 0, 0, 0, 9, 0, "" }, /* div.title.content */
-{ "setindexinfo",0, 0, 0, 9, 0, "" }, /* graphic */
-{ "setindex", 0, 0, 0, 9, 0, "" }, /* setindexinfo */
-{ "setinfo", 0, 0, 0, 9, 0, "" }, /* graphic */
-{ "sgmltag", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "shortaffil", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "shortcut", 0, 0, 0, 9, 0, "" }, /* keycap */
-{ "sidebarinfo",0, 0, 0, 9, 0, "" }, /* graphic */
-{ "sidebar", 0, 0, 0, 9, 0, "" }, /* sidebarinfo */
-{ "simpara", 0, 0, 0, 2, 0, "" }, /* para */
-{ "simplelist", 0, 0, 0, 9, 0, "" }, /* member */
-{ "simplemsgentry", 0, 0, 0, 9, 0, "" }, /* msgtext */
-{ "simplesect", 0, 0, 0, 9, 0, "" }, /* sect.title.content */
-{ "spanspec", 0, 2, 1, 0, 0, "" },
-{ "state", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "step", 0, 0, 0, 9, 0, "" }, /* title */
-{ "street", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "structfield",0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "structname", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "subjectset", 0, 0, 0, 9, 0, "" }, /* subject */
-{ "subject", 0, 0, 0, 9, 0, "" }, /* subjectterm */
-{ "subjectterm",0, 0, 0, 1, 0, "" },
-{ "subscript", 0, 0, 0, 1, 0, "" },
-{ "substeps", 0, 0, 0, 9, 0, "" }, /* step */
-{ "subtitle", 0, 0, 0, 8, 0, "" }, /* title */
-{ "superscript", 0, 0, 0, 1, 0, "" },
-{ "surname", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "symbol", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "synopfragment", 0, 0, 0, 9, 0, "" }, /* arg */
-{ "synopfragmentref", 0, 0, 0, 1, 0, "" },
-{ "synopsis", 0, 0, 0, 2, 0, "" }, /* para */
-{ "systemitem", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "table", 0, 0, 0, 9, 0, "" }, /* tbl.table.mdl */
-/* { "%tbl.table.name;", 0, 0, 0, 9, 0, "" },*/ /* tbl.table.mdl */
-{ "tbody", 0, 0, 0, 9, 0, "" }, /* row */
-{ "tbody", 0, 0, 0, 9, 0, "" }, /* row */
-{ "term", 0, 0, 0, 2, 0, "" }, /* para */
-{ "tertiaryie", 0, 0, 0, 4, 0, "" }, /* ndxterm */
-{ "tertiary ", 0, 0, 0, 4, 0, "" }, /* ndxterm */
-{ "textobject", 0, 0, 0, 9, 0, "" }, /* objectinfo */
-{ "tfoot", 0, 0, 0, 9, 0, "" }, /* tbl.hdft.mdl */
-{ "tgroup", 0, 0, 0, 9, 0, "" }, /* tbl.tgroup.mdl */
-{ "tgroup", 0, 0, 0, 9, 0, "" }, /* tbl.tgroup.mdl */
-{ "thead", 0, 0, 0, 9, 0, "" }, /* row */
-{ "thead", 0, 0, 0, 9, 0, "" }, /* tbl.hdft.mdl */
-{ "tip", 0, 0, 0, 9, 0, "" }, /* title */
-{ "titleabbrev",0, 0, 0, 8, 0, "" }, /* title */
-{ "title", 0, 0, 0, 8, 0, "" }, /* title */
-{ "tocback", 0, 0, 0, 2, 0, "" }, /* para */
-{ "toc", 0, 0, 0, 9, 0, "" }, /* bookcomponent.title.content */
-{ "tocchap", 0, 0, 0, 9, 0, "" }, /* tocentry */
-{ "tocentry", 0, 0, 0, 2, 0, "" }, /* para */
-{ "tocfront", 0, 0, 0, 2, 0, "" }, /* para */
-{ "toclevel1", 0, 0, 0, 9, 0, "" }, /* tocentry */
-{ "toclevel2", 0, 0, 0, 9, 0, "" }, /* tocentry */
-{ "toclevel3", 0, 0, 0, 9, 0, "" }, /* tocentry */
-{ "toclevel4", 0, 0, 0, 9, 0, "" }, /* tocentry */
-{ "toclevel5", 0, 0, 0, 9, 0, "" }, /* tocentry */
-{ "tocpart", 0, 0, 0, 9, 0, "" }, /* tocentry */
-{ "token", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "trademark", 0, 0, 0, 1, 0, "" },
-{ "type", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "ulink", 0, 0, 0, 2, 0, "" }, /* para */
-{ "userinput", 0, 0, 0, 9, 0, "" }, /* cptr */
-{ "varargs", 0, 2, 1, 0, 0, "" },
-{ "variablelist",0, 0, 0, 9, 0, "" }, /* formalobject.title.content */
-{ "varlistentry",0, 0, 0, 9, 0, "" }, /* term */
-{ "varname", 0, 0, 0, 7, 0, "" }, /* smallcptr */
-{ "videodata", 0, 2, 1, 0, 0, "" },
-{ "videoobject",0, 0, 0, 9, 0, "" }, /* objectinfo */
-{ "void", 0, 2, 1, 0, 0, "" },
-{ "volumenum", 0, 0, 0, 4, 0, "" }, /* docinfo */
-{ "warning", 0, 0, 0, 9, 0, "" }, /* title */
-{ "wordasword", 0, 0, 0, 3, 0, "" }, /* word */
-{ "xref", 0, 2, 1, 0, 0, "" },
-{ "year", 0, 0, 0, 4, 0, "" }, /* docinfo */
-};
-
-#if 0
-/*
- * start tags that imply the end of a current element
- * any tag of each line implies the end of the current element if the type of
- * that element is in the same line
- */
-static const char *docbEquEnd[] = {
-"dt", "dd", "li", "option", NULL,
-"h1", "h2", "h3", "h4", "h5", "h6", NULL,
-"ol", "menu", "dir", "address", "pre", "listing", "xmp", NULL,
-NULL
-};
-#endif
-
-/*
- * according the SGML DTD, HR should be added to the 2nd line above, as it
- * is not allowed within a H1, H2, H3, etc. But we should tolerate that case
- * because many documents contain rules in headings...
- */
-
-/*
- * start tags that imply the end of current element
- */
-static const char *docbStartClose[] = {
-NULL
-};
-
-static const char** docbStartCloseIndex[100];
-static int docbStartCloseIndexinitialized = 0;
-
-/************************************************************************
- * *
- * functions to handle SGML specific data *
- * *
- ************************************************************************/
-
-/**
- * docbInitAutoClose:
- *
- * Initialize the docbStartCloseIndex for fast lookup of closing tags names.
- *
- */
-static void
-docbInitAutoClose(void) {
- int indx, i = 0;
-
- if (docbStartCloseIndexinitialized) return;
-
- for (indx = 0;indx < 100;indx ++) docbStartCloseIndex[indx] = NULL;
- indx = 0;
- while ((docbStartClose[i] != NULL) && (indx < 100 - 1)) {
- docbStartCloseIndex[indx++] = &docbStartClose[i];
- while (docbStartClose[i] != NULL) i++;
- i++;
- }
-}
-
-/**
- * docbTagLookup:
- * @tag: The tag name
- *
- * Lookup the SGML tag in the ElementTable
- *
- * Returns the related docbElemDescPtr or NULL if not found.
- */
-static docbElemDescPtr
-docbTagLookup(const xmlChar *tag) {
- unsigned int i;
-
- for (i = 0; i < (sizeof(docbookElementTable) /
- sizeof(docbookElementTable[0]));i++) {
- if (xmlStrEqual(tag, BAD_CAST docbookElementTable[i].name))
- return(&docbookElementTable[i]);
- }
- return(NULL);
-}
-
-/**
- * docbCheckAutoClose:
- * @newtag: The new tag name
- * @oldtag: The old tag name
- *
- * Checks whether the new tag is one of the registered valid tags for
- * closing old.
- * Initialize the docbStartCloseIndex for fast lookup of closing tags names.
- *
- * Returns 0 if no, 1 if yes.
- */
-static int
-docbCheckAutoClose(const xmlChar *newtag, const xmlChar *oldtag) {
- int i, indx;
- const char **closed = NULL;
-
- if (docbStartCloseIndexinitialized == 0) docbInitAutoClose();
-
- /* inefficient, but not a big deal */
- for (indx = 0; indx < 100;indx++) {
- closed = docbStartCloseIndex[indx];
- if (closed == NULL) return(0);
- if (xmlStrEqual(BAD_CAST *closed, newtag)) break;
- }
-
- i = closed - docbStartClose;
- i++;
- while (docbStartClose[i] != NULL) {
- if (xmlStrEqual(BAD_CAST docbStartClose[i], oldtag)) {
- return(1);
- }
- i++;
- }
- return(0);
-}
-
-/**
- * docbAutoCloseOnClose:
- * @ctxt: an SGML parser context
- * @newtag: The new tag name
- *
- * The DocBook DTD allows an ending tag to implicitly close other tags.
- */
-static void
-docbAutoCloseOnClose(docbParserCtxtPtr ctxt, const xmlChar *newtag) {
- docbElemDescPtr info;
- xmlChar *oldname;
- int i;
-
- if ((newtag[0] == '/') && (newtag[1] == 0))
- return;
-
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"Close of %s stack: %d elements\n", newtag, ctxt->nameNr);
- for (i = 0;i < ctxt->nameNr;i++)
- xmlGenericError(xmlGenericErrorContext,"%d : %s\n", i, ctxt->nameTab[i]);
-#endif
-
- for (i = (ctxt->nameNr - 1);i >= 0;i--) {
- if (xmlStrEqual(newtag, ctxt->nameTab[i])) break;
- }
- if (i < 0) return;
-
- while (!xmlStrEqual(newtag, ctxt->name)) {
- info = docbTagLookup(ctxt->name);
- if ((info == NULL) || (info->endTag == 1)) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"docbAutoCloseOnClose: %s closes %s\n", newtag, ctxt->name);
-#endif
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Opening and ending tag mismatch: %s and %s\n",
- newtag, ctxt->name);
- ctxt->wellFormed = 0;
- }
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
- ctxt->sax->endElement(ctxt->userData, ctxt->name);
- oldname = docbnamePop(ctxt);
- if (oldname != NULL) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"docbAutoCloseOnClose: popped %s\n", oldname);
-#endif
- xmlFree(oldname);
- }
- }
-}
-
-/**
- * docbAutoClose:
- * @ctxt: an SGML parser context
- * @newtag: The new tag name or NULL
- *
- * The DocBook DTD allows a tag to implicitly close other tags.
- * The list is kept in docbStartClose array. This function is
- * called when a new tag has been detected and generates the
- * appropriates closes if possible/needed.
- * If newtag is NULL this mean we are at the end of the resource
- * and we should check
- */
-static void
-docbAutoClose(docbParserCtxtPtr ctxt, const xmlChar *newtag) {
- xmlChar *oldname;
- while ((newtag != NULL) && (ctxt->name != NULL) &&
- (docbCheckAutoClose(newtag, ctxt->name))) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"docbAutoClose: %s closes %s\n", newtag, ctxt->name);
-#endif
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
- ctxt->sax->endElement(ctxt->userData, ctxt->name);
- oldname = docbnamePop(ctxt);
- if (oldname != NULL) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"docbAutoClose: popped %s\n", oldname);
-#endif
- xmlFree(oldname);
- }
- }
-}
-
-/**
- * docbAutoCloseTag:
- * @doc: the SGML document
- * @name: The tag name
- * @elem: the SGML element
- *
- * The DocBook DTD allows a tag to implicitly close other tags.
- * The list is kept in docbStartClose array. This function checks
- * if the element or one of it's children would autoclose the
- * given tag.
- *
- * Returns 1 if autoclose, 0 otherwise
- */
-static int
-docbAutoCloseTag(docbDocPtr doc, const xmlChar *name, docbNodePtr elem) {
- docbNodePtr child;
-
- if (elem == NULL) return(1);
- if (xmlStrEqual(name, elem->name)) return(0);
- if (docbCheckAutoClose(elem->name, name)) return(1);
- child = elem->children;
- while (child != NULL) {
- if (docbAutoCloseTag(doc, name, child)) return(1);
- child = child->next;
- }
- return(0);
-}
-
-/************************************************************************
- * *
- * The list of SGML predefined entities *
- * *
- ************************************************************************/
-
-
-static docbEntityDesc
-docbookEntitiesTable[] = {
-/*
- * the 4 absolute ones, plus apostrophe.
- */
-{ 0x0026, "amp", "AMPERSAND" },
-{ 0x003C, "lt", "LESS-THAN SIGN" },
-
-/*
- * Converted with VI macros from docbook ent files
- */
-{ 0x0021, "excl", "EXCLAMATION MARK" },
-{ 0x0022, "quot", "QUOTATION MARK" },
-{ 0x0023, "num", "NUMBER SIGN" },
-{ 0x0024, "dollar", "DOLLAR SIGN" },
-{ 0x0025, "percnt", "PERCENT SIGN" },
-{ 0x0027, "apos", "APOSTROPHE" },
-{ 0x0028, "lpar", "LEFT PARENTHESIS" },
-{ 0x0029, "rpar", "RIGHT PARENTHESIS" },
-{ 0x002A, "ast", "ASTERISK OPERATOR" },
-{ 0x002B, "plus", "PLUS SIGN" },
-{ 0x002C, "comma", "COMMA" },
-{ 0x002D, "hyphen", "HYPHEN-MINUS" },
-{ 0x002E, "period", "FULL STOP" },
-{ 0x002F, "sol", "SOLIDUS" },
-{ 0x003A, "colon", "COLON" },
-{ 0x003B, "semi", "SEMICOLON" },
-{ 0x003D, "equals", "EQUALS SIGN" },
-{ 0x003E, "gt", "GREATER-THAN SIGN" },
-{ 0x003F, "quest", "QUESTION MARK" },
-{ 0x0040, "commat", "COMMERCIAL AT" },
-{ 0x005B, "lsqb", "LEFT SQUARE BRACKET" },
-{ 0x005C, "bsol", "REVERSE SOLIDUS" },
-{ 0x005D, "rsqb", "RIGHT SQUARE BRACKET" },
-{ 0x005E, "circ", "RING OPERATOR" },
-{ 0x005F, "lowbar", "LOW LINE" },
-{ 0x0060, "grave", "GRAVE ACCENT" },
-{ 0x007B, "lcub", "LEFT CURLY BRACKET" },
-{ 0x007C, "verbar", "VERTICAL LINE" },
-{ 0x007D, "rcub", "RIGHT CURLY BRACKET" },
-{ 0x00A0, "nbsp", "NO-BREAK SPACE" },
-{ 0x00A1, "iexcl", "INVERTED EXCLAMATION MARK" },
-{ 0x00A2, "cent", "CENT SIGN" },
-{ 0x00A3, "pound", "POUND SIGN" },
-{ 0x00A4, "curren", "CURRENCY SIGN" },
-{ 0x00A5, "yen", "YEN SIGN" },
-{ 0x00A6, "brvbar", "BROKEN BAR" },
-{ 0x00A7, "sect", "SECTION SIGN" },
-{ 0x00A8, "die", "" },
-{ 0x00A8, "Dot", "" },
-{ 0x00A8, "uml", "" },
-{ 0x00A9, "copy", "COPYRIGHT SIGN" },
-{ 0x00AA, "ordf", "FEMININE ORDINAL INDICATOR" },
-{ 0x00AB, "laquo", "LEFT-POINTING DOUBLE ANGLE QUOTATION MARK" },
-{ 0x00AC, "not", "NOT SIGN" },
-{ 0x00AD, "shy", "SOFT HYPHEN" },
-{ 0x00AE, "reg", "REG TRADE MARK SIGN" },
-{ 0x00AF, "macr", "MACRON" },
-{ 0x00B0, "deg", "DEGREE SIGN" },
-{ 0x00B1, "plusmn", "PLUS-MINUS SIGN" },
-{ 0x00B2, "sup2", "SUPERSCRIPT TWO" },
-{ 0x00B3, "sup3", "SUPERSCRIPT THREE" },
-{ 0x00B4, "acute", "ACUTE ACCENT" },
-{ 0x00B5, "micro", "MICRO SIGN" },
-{ 0x00B6, "para", "PILCROW SIGN" },
-{ 0x00B7, "middot", "MIDDLE DOT" },
-{ 0x00B8, "cedil", "CEDILLA" },
-{ 0x00B9, "sup1", "SUPERSCRIPT ONE" },
-{ 0x00BA, "ordm", "MASCULINE ORDINAL INDICATOR" },
-{ 0x00BB, "raquo", "RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK" },
-{ 0x00BC, "frac14", "VULGAR FRACTION ONE QUARTER" },
-{ 0x00BD, "frac12", "VULGAR FRACTION ONE HALF" },
-{ 0x00BD, "half", "VULGAR FRACTION ONE HALF" },
-{ 0x00BE, "frac34", "VULGAR FRACTION THREE QUARTERS" },
-{ 0x00BF, "iquest", "INVERTED QUESTION MARK" },
-{ 0x00C0, "Agrave", "LATIN CAPITAL LETTER A WITH GRAVE" },
-{ 0x00C1, "Aacute", "LATIN CAPITAL LETTER A WITH ACUTE" },
-{ 0x00C2, "Acirc", "LATIN CAPITAL LETTER A WITH CIRCUMFLEX" },
-{ 0x00C3, "Atilde", "LATIN CAPITAL LETTER A WITH TILDE" },
-{ 0x00C4, "Auml", "LATIN CAPITAL LETTER A WITH DIAERESIS" },
-{ 0x00C5, "Aring", "LATIN CAPITAL LETTER A WITH RING ABOVE" },
-{ 0x00C6, "AElig", "LATIN CAPITAL LETTER AE" },
-{ 0x00C7, "Ccedil", "LATIN CAPITAL LETTER C WITH CEDILLA" },
-{ 0x00C8, "Egrave", "LATIN CAPITAL LETTER E WITH GRAVE" },
-{ 0x00C9, "Eacute", "LATIN CAPITAL LETTER E WITH ACUTE" },
-{ 0x00CA, "Ecirc", "LATIN CAPITAL LETTER E WITH CIRCUMFLEX" },
-{ 0x00CB, "Euml", "LATIN CAPITAL LETTER E WITH DIAERESIS" },
-{ 0x00CC, "Igrave", "LATIN CAPITAL LETTER I WITH GRAVE" },
-{ 0x00CD, "Iacute", "LATIN CAPITAL LETTER I WITH ACUTE" },
-{ 0x00CE, "Icirc", "LATIN CAPITAL LETTER I WITH CIRCUMFLEX" },
-{ 0x00CF, "Iuml", "LATIN CAPITAL LETTER I WITH DIAERESIS" },
-{ 0x00D0, "ETH", "LATIN CAPITAL LETTER ETH" },
-{ 0x00D1, "Ntilde", "LATIN CAPITAL LETTER N WITH TILDE" },
-{ 0x00D2, "Ograve", "LATIN CAPITAL LETTER O WITH GRAVE" },
-{ 0x00D3, "Oacute", "LATIN CAPITAL LETTER O WITH ACUTE" },
-{ 0x00D4, "Ocirc", "LATIN CAPITAL LETTER O WITH CIRCUMFLEX" },
-{ 0x00D5, "Otilde", "LATIN CAPITAL LETTER O WITH TILDE" },
-{ 0x00D6, "Ouml", "LATIN CAPITAL LETTER O WITH DIAERESIS" },
-{ 0x00D7, "times", "MULTIPLICATION SIGN" },
-{ 0x00D8, "Oslash", "LATIN CAPITAL LETTER O WITH STROKE" },
-{ 0x00D9, "Ugrave", "LATIN CAPITAL LETTER U WITH GRAVE" },
-{ 0x00DA, "Uacute", "LATIN CAPITAL LETTER U WITH ACUTE" },
-{ 0x00DB, "Ucirc", "LATIN CAPITAL LETTER U WITH CIRCUMFLEX" },
-{ 0x00DC, "Uuml", "LATIN CAPITAL LETTER U WITH DIAERESIS" },
-{ 0x00DD, "Yacute", "LATIN CAPITAL LETTER Y WITH ACUTE" },
-{ 0x00DE, "THORN", "LATIN CAPITAL LETTER THORN" },
-{ 0x00DF, "szlig", "LATIN SMALL LETTER SHARP S" },
-{ 0x00E0, "agrave", "LATIN SMALL LETTER A WITH GRAVE" },
-{ 0x00E1, "aacute", "LATIN SMALL LETTER A WITH ACUTE" },
-{ 0x00E2, "acirc", "LATIN SMALL LETTER A WITH CIRCUMFLEX" },
-{ 0x00E3, "atilde", "LATIN SMALL LETTER A WITH TILDE" },
-{ 0x00E4, "auml", "LATIN SMALL LETTER A WITH DIAERESIS" },
-{ 0x00E5, "aring", "LATIN SMALL LETTER A WITH RING ABOVE" },
-{ 0x00E6, "aelig", "LATIN SMALL LETTER AE" },
-{ 0x00E7, "ccedil", "LATIN SMALL LETTER C WITH CEDILLA" },
-{ 0x00E8, "egrave", "LATIN SMALL LETTER E WITH GRAVE" },
-{ 0x00E9, "eacute", "LATIN SMALL LETTER E WITH ACUTE" },
-{ 0x00EA, "ecirc", "LATIN SMALL LETTER E WITH CIRCUMFLEX" },
-{ 0x00EB, "euml", "LATIN SMALL LETTER E WITH DIAERESIS" },
-{ 0x00EC, "igrave", "LATIN SMALL LETTER I WITH GRAVE" },
-{ 0x00ED, "iacute", "LATIN SMALL LETTER I WITH ACUTE" },
-{ 0x00EE, "icirc", "LATIN SMALL LETTER I WITH CIRCUMFLEX" },
-{ 0x00EF, "iuml", "LATIN SMALL LETTER I WITH DIAERESIS" },
-{ 0x00F0, "eth", "LATIN SMALL LETTER ETH" },
-{ 0x00F1, "ntilde", "LATIN SMALL LETTER N WITH TILDE" },
-{ 0x00F2, "ograve", "LATIN SMALL LETTER O WITH GRAVE" },
-{ 0x00F3, "oacute", "LATIN SMALL LETTER O WITH ACUTE" },
-{ 0x00F4, "ocirc", "LATIN SMALL LETTER O WITH CIRCUMFLEX" },
-{ 0x00F5, "otilde", "LATIN SMALL LETTER O WITH TILDE" },
-{ 0x00F6, "ouml", "LATIN SMALL LETTER O WITH DIAERESIS" },
-{ 0x00F7, "divide", "DIVISION SIGN" },
-{ 0x00F8, "oslash", "CIRCLED DIVISION SLASH" },
-{ 0x00F9, "ugrave", "LATIN SMALL LETTER U WITH GRAVE" },
-{ 0x00FA, "uacute", "LATIN SMALL LETTER U WITH ACUTE" },
-{ 0x00FB, "ucirc", "LATIN SMALL LETTER U WITH CIRCUMFLEX" },
-{ 0x00FC, "uuml", "LATIN SMALL LETTER U WITH DIAERESIS" },
-{ 0x00FD, "yacute", "LATIN SMALL LETTER Y WITH ACUTE" },
-{ 0x00FE, "thorn", "LATIN SMALL LETTER THORN" },
-{ 0x00FF, "yuml", "LATIN SMALL LETTER Y WITH DIAERESIS" },
-{ 0x0100, "Amacr", "LATIN CAPITAL LETTER A WITH MACRON" },
-{ 0x0101, "amacr", "LATIN SMALL LETTER A WITH MACRON" },
-{ 0x0102, "Abreve", "LATIN CAPITAL LETTER A WITH BREVE" },
-{ 0x0103, "abreve", "LATIN SMALL LETTER A WITH BREVE" },
-{ 0x0104, "Aogon", "LATIN CAPITAL LETTER A WITH OGONEK" },
-{ 0x0105, "aogon", "LATIN SMALL LETTER A WITH OGONEK" },
-{ 0x0106, "Cacute", "LATIN CAPITAL LETTER C WITH ACUTE" },
-{ 0x0107, "cacute", "LATIN SMALL LETTER C WITH ACUTE" },
-{ 0x0108, "Ccirc", "LATIN CAPITAL LETTER C WITH CIRCUMFLEX" },
-{ 0x0109, "ccirc", "LATIN SMALL LETTER C WITH CIRCUMFLEX" },
-{ 0x010A, "Cdot", "LATIN CAPITAL LETTER C WITH DOT ABOVE" },
-{ 0x010B, "cdot", "DOT OPERATOR" },
-{ 0x010C, "Ccaron", "LATIN CAPITAL LETTER C WITH CARON" },
-{ 0x010D, "ccaron", "LATIN SMALL LETTER C WITH CARON" },
-{ 0x010E, "Dcaron", "LATIN CAPITAL LETTER D WITH CARON" },
-{ 0x010F, "dcaron", "LATIN SMALL LETTER D WITH CARON" },
-{ 0x0110, "Dstrok", "LATIN CAPITAL LETTER D WITH STROKE" },
-{ 0x0111, "dstrok", "LATIN SMALL LETTER D WITH STROKE" },
-{ 0x0112, "Emacr", "LATIN CAPITAL LETTER E WITH MACRON" },
-{ 0x0113, "emacr", "LATIN SMALL LETTER E WITH MACRON" },
-{ 0x0116, "Edot", "LATIN CAPITAL LETTER E WITH DOT ABOVE" },
-{ 0x0117, "edot", "LATIN SMALL LETTER E WITH DOT ABOVE" },
-{ 0x0118, "Eogon", "LATIN CAPITAL LETTER E WITH OGONEK" },
-{ 0x0119, "eogon", "LATIN SMALL LETTER E WITH OGONEK" },
-{ 0x011A, "Ecaron", "LATIN CAPITAL LETTER E WITH CARON" },
-{ 0x011B, "ecaron", "LATIN SMALL LETTER E WITH CARON" },
-{ 0x011C, "Gcirc", "LATIN CAPITAL LETTER G WITH CIRCUMFLEX" },
-{ 0x011D, "gcirc", "LATIN SMALL LETTER G WITH CIRCUMFLEX" },
-{ 0x011E, "Gbreve", "LATIN CAPITAL LETTER G WITH BREVE" },
-{ 0x011F, "gbreve", "LATIN SMALL LETTER G WITH BREVE" },
-{ 0x0120, "Gdot", "LATIN CAPITAL LETTER G WITH DOT ABOVE" },
-{ 0x0121, "gdot", "LATIN SMALL LETTER G WITH DOT ABOVE" },
-{ 0x0122, "Gcedil", "LATIN CAPITAL LETTER G WITH CEDILLA" },
-{ 0x0124, "Hcirc", "LATIN CAPITAL LETTER H WITH CIRCUMFLEX" },
-{ 0x0125, "hcirc", "LATIN SMALL LETTER H WITH CIRCUMFLEX" },
-{ 0x0126, "Hstrok", "LATIN CAPITAL LETTER H WITH STROKE" },
-{ 0x0127, "hstrok", "LATIN SMALL LETTER H WITH STROKE" },
-{ 0x0128, "Itilde", "LATIN CAPITAL LETTER I WITH TILDE" },
-{ 0x0129, "itilde", "LATIN SMALL LETTER I WITH TILDE" },
-{ 0x012A, "Imacr", "LATIN CAPITAL LETTER I WITH MACRON" },
-{ 0x012B, "imacr", "LATIN SMALL LETTER I WITH MACRON" },
-{ 0x012E, "Iogon", "LATIN CAPITAL LETTER I WITH OGONEK" },
-{ 0x012F, "iogon", "LATIN SMALL LETTER I WITH OGONEK" },
-{ 0x0130, "Idot", "LATIN CAPITAL LETTER I WITH DOT ABOVE" },
-{ 0x0131, "inodot", "LATIN SMALL LETTER DOTLESS I" },
-{ 0x0131, "inodot", "LATIN SMALL LETTER DOTLESS I" },
-{ 0x0132, "IJlig", "LATIN CAPITAL LIGATURE IJ" },
-{ 0x0133, "ijlig", "LATIN SMALL LIGATURE IJ" },
-{ 0x0134, "Jcirc", "LATIN CAPITAL LETTER J WITH CIRCUMFLEX" },
-{ 0x0135, "jcirc", "LATIN SMALL LETTER J WITH CIRCUMFLEX" },
-{ 0x0136, "Kcedil", "LATIN CAPITAL LETTER K WITH CEDILLA" },
-{ 0x0137, "kcedil", "LATIN SMALL LETTER K WITH CEDILLA" },
-{ 0x0138, "kgreen", "LATIN SMALL LETTER KRA" },
-{ 0x0139, "Lacute", "LATIN CAPITAL LETTER L WITH ACUTE" },
-{ 0x013A, "lacute", "LATIN SMALL LETTER L WITH ACUTE" },
-{ 0x013B, "Lcedil", "LATIN CAPITAL LETTER L WITH CEDILLA" },
-{ 0x013C, "lcedil", "LATIN SMALL LETTER L WITH CEDILLA" },
-{ 0x013D, "Lcaron", "LATIN CAPITAL LETTER L WITH CARON" },
-{ 0x013E, "lcaron", "LATIN SMALL LETTER L WITH CARON" },
-{ 0x013F, "Lmidot", "LATIN CAPITAL LETTER L WITH MIDDLE DOT" },
-{ 0x0140, "lmidot", "LATIN SMALL LETTER L WITH MIDDLE DOT" },
-{ 0x0141, "Lstrok", "LATIN CAPITAL LETTER L WITH STROKE" },
-{ 0x0142, "lstrok", "LATIN SMALL LETTER L WITH STROKE" },
-{ 0x0143, "Nacute", "LATIN CAPITAL LETTER N WITH ACUTE" },
-{ 0x0144, "nacute", "LATIN SMALL LETTER N WITH ACUTE" },
-{ 0x0145, "Ncedil", "LATIN CAPITAL LETTER N WITH CEDILLA" },
-{ 0x0146, "ncedil", "LATIN SMALL LETTER N WITH CEDILLA" },
-{ 0x0147, "Ncaron", "LATIN CAPITAL LETTER N WITH CARON" },
-{ 0x0148, "ncaron", "LATIN SMALL LETTER N WITH CARON" },
-{ 0x0149, "napos", "LATIN SMALL LETTER N PRECEDED BY APOSTROPHE" },
-{ 0x014A, "ENG", "LATIN CAPITAL LETTER ENG" },
-{ 0x014B, "eng", "LATIN SMALL LETTER ENG" },
-{ 0x014C, "Omacr", "LATIN CAPITAL LETTER O WITH MACRON" },
-{ 0x014D, "omacr", "LATIN SMALL LETTER O WITH MACRON" },
-{ 0x0150, "Odblac", "LATIN CAPITAL LETTER O WITH DOUBLE ACUTE" },
-{ 0x0151, "odblac", "LATIN SMALL LETTER O WITH DOUBLE ACUTE" },
-{ 0x0152, "OElig", "LATIN CAPITAL LIGATURE OE" },
-{ 0x0153, "oelig", "LATIN SMALL LIGATURE OE" },
-{ 0x0154, "Racute", "LATIN CAPITAL LETTER R WITH ACUTE" },
-{ 0x0155, "racute", "LATIN SMALL LETTER R WITH ACUTE" },
-{ 0x0156, "Rcedil", "LATIN CAPITAL LETTER R WITH CEDILLA" },
-{ 0x0157, "rcedil", "LATIN SMALL LETTER R WITH CEDILLA" },
-{ 0x0158, "Rcaron", "LATIN CAPITAL LETTER R WITH CARON" },
-{ 0x0159, "rcaron", "LATIN SMALL LETTER R WITH CARON" },
-{ 0x015A, "Sacute", "LATIN CAPITAL LETTER S WITH ACUTE" },
-{ 0x015B, "sacute", "LATIN SMALL LETTER S WITH ACUTE" },
-{ 0x015C, "Scirc", "LATIN CAPITAL LETTER S WITH CIRCUMFLEX" },
-{ 0x015D, "scirc", "LATIN SMALL LETTER S WITH CIRCUMFLEX" },
-{ 0x015E, "Scedil", "LATIN CAPITAL LETTER S WITH CEDILLA" },
-{ 0x015F, "scedil", "LATIN SMALL LETTER S WITH CEDILLA" },
-{ 0x0160, "Scaron", "LATIN CAPITAL LETTER S WITH CARON" },
-{ 0x0161, "scaron", "LATIN SMALL LETTER S WITH CARON" },
-{ 0x0162, "Tcedil", "LATIN CAPITAL LETTER T WITH CEDILLA" },
-{ 0x0163, "tcedil", "LATIN SMALL LETTER T WITH CEDILLA" },
-{ 0x0164, "Tcaron", "LATIN CAPITAL LETTER T WITH CARON" },
-{ 0x0165, "tcaron", "LATIN SMALL LETTER T WITH CARON" },
-{ 0x0166, "Tstrok", "LATIN CAPITAL LETTER T WITH STROKE" },
-{ 0x0167, "tstrok", "LATIN SMALL LETTER T WITH STROKE" },
-{ 0x0168, "Utilde", "LATIN CAPITAL LETTER U WITH TILDE" },
-{ 0x0169, "utilde", "LATIN SMALL LETTER U WITH TILDE" },
-{ 0x016A, "Umacr", "LATIN CAPITAL LETTER U WITH MACRON" },
-{ 0x016B, "umacr", "LATIN SMALL LETTER U WITH MACRON" },
-{ 0x016C, "Ubreve", "LATIN CAPITAL LETTER U WITH BREVE" },
-{ 0x016D, "ubreve", "LATIN SMALL LETTER U WITH BREVE" },
-{ 0x016E, "Uring", "LATIN CAPITAL LETTER U WITH RING ABOVE" },
-{ 0x016F, "uring", "LATIN SMALL LETTER U WITH RING ABOVE" },
-{ 0x0170, "Udblac", "LATIN CAPITAL LETTER U WITH DOUBLE ACUTE" },
-{ 0x0171, "udblac", "LATIN SMALL LETTER U WITH DOUBLE ACUTE" },
-{ 0x0172, "Uogon", "LATIN CAPITAL LETTER U WITH OGONEK" },
-{ 0x0173, "uogon", "LATIN SMALL LETTER U WITH OGONEK" },
-{ 0x0174, "Wcirc", "LATIN CAPITAL LETTER W WITH CIRCUMFLEX" },
-{ 0x0175, "wcirc", "LATIN SMALL LETTER W WITH CIRCUMFLEX" },
-{ 0x0176, "Ycirc", "LATIN CAPITAL LETTER Y WITH CIRCUMFLEX" },
-{ 0x0177, "ycirc", "LATIN SMALL LETTER Y WITH CIRCUMFLEX" },
-{ 0x0178, "Yuml", "LATIN CAPITAL LETTER Y WITH DIAERESIS" },
-{ 0x0179, "Zacute", "LATIN CAPITAL LETTER Z WITH ACUTE" },
-{ 0x017A, "zacute", "LATIN SMALL LETTER Z WITH ACUTE" },
-{ 0x017B, "Zdot", "LATIN CAPITAL LETTER Z WITH DOT ABOVE" },
-{ 0x017C, "zdot", "LATIN SMALL LETTER Z WITH DOT ABOVE" },
-{ 0x017D, "Zcaron", "LATIN CAPITAL LETTER Z WITH CARON" },
-{ 0x017E, "zcaron", "LATIN SMALL LETTER Z WITH CARON" },
-{ 0x0192, "fnof", "LATIN SMALL LETTER F WITH HOOK" },
-{ 0x01F5, "gacute", "LATIN SMALL LETTER G WITH ACUTE" },
-{ 0x02C7, "caron", "CARON" },
-{ 0x02D8, "breve", "BREVE" },
-{ 0x02D9, "dot", "DOT ABOVE" },
-{ 0x02DA, "ring", "RING ABOVE" },
-{ 0x02DB, "ogon", "OGONEK" },
-{ 0x02DC, "tilde", "TILDE" },
-{ 0x02DD, "dblac", "DOUBLE ACUTE ACCENT" },
-{ 0x0386, "Aacgr", "GREEK CAPITAL LETTER ALPHA WITH TONOS" },
-{ 0x0388, "Eacgr", "GREEK CAPITAL LETTER EPSILON WITH TONOS" },
-{ 0x0389, "EEacgr", "GREEK CAPITAL LETTER ETA WITH TONOS" },
-{ 0x038A, "Iacgr", "GREEK CAPITAL LETTER IOTA WITH TONOS" },
-{ 0x038C, "Oacgr", "GREEK CAPITAL LETTER OMICRON WITH TONOS" },
-{ 0x038E, "Uacgr", "GREEK CAPITAL LETTER UPSILON WITH TONOS" },
-{ 0x038F, "OHacgr", "GREEK CAPITAL LETTER OMEGA WITH TONOS" },
-{ 0x0390, "idiagr", "GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS" },
-{ 0x0391, "Agr", "GREEK CAPITAL LETTER ALPHA" },
-{ 0x0392, "Bgr", "GREEK CAPITAL LETTER BETA" },
-{ 0x0393, "b.Gamma", "GREEK CAPITAL LETTER GAMMA" },
-{ 0x0393, "Gamma", "GREEK CAPITAL LETTER GAMMA" },
-{ 0x0393, "Ggr", "GREEK CAPITAL LETTER GAMMA" },
-{ 0x0394, "b.Delta", "GREEK CAPITAL LETTER DELTA" },
-{ 0x0394, "Delta", "GREEK CAPITAL LETTER DELTA" },
-{ 0x0394, "Dgr", "GREEK CAPITAL LETTER DELTA" },
-{ 0x0395, "Egr", "GREEK CAPITAL LETTER EPSILON" },
-{ 0x0396, "Zgr", "GREEK CAPITAL LETTER ZETA" },
-{ 0x0397, "EEgr", "GREEK CAPITAL LETTER ETA" },
-{ 0x0398, "b.Theta", "GREEK CAPITAL LETTER THETA" },
-{ 0x0398, "Theta", "GREEK CAPITAL LETTER THETA" },
-{ 0x0398, "THgr", "GREEK CAPITAL LETTER THETA" },
-{ 0x0399, "Igr", "GREEK CAPITAL LETTER IOTA" },
-{ 0x039A, "Kgr", "GREEK CAPITAL LETTER KAPPA" },
-{ 0x039B, "b.Lambda", "GREEK CAPITAL LETTER LAMDA" },
-{ 0x039B, "Lambda", "GREEK CAPITAL LETTER LAMDA" },
-{ 0x039B, "Lgr", "GREEK CAPITAL LETTER LAMDA" },
-{ 0x039C, "Mgr", "GREEK CAPITAL LETTER MU" },
-{ 0x039D, "Ngr", "GREEK CAPITAL LETTER NU" },
-{ 0x039E, "b.Xi", "GREEK CAPITAL LETTER XI" },
-{ 0x039E, "Xgr", "GREEK CAPITAL LETTER XI" },
-{ 0x039E, "Xi", "GREEK CAPITAL LETTER XI" },
-{ 0x039F, "Ogr", "GREEK CAPITAL LETTER OMICRON" },
-{ 0x03A0, "b.Pi", "GREEK CAPITAL LETTER PI" },
-{ 0x03A0, "Pgr", "GREEK CAPITAL LETTER PI" },
-{ 0x03A0, "Pi", "GREEK CAPITAL LETTER PI" },
-{ 0x03A1, "Rgr", "GREEK CAPITAL LETTER RHO" },
-{ 0x03A3, "b.Sigma", "GREEK CAPITAL LETTER SIGMA" },
-{ 0x03A3, "Sgr", "GREEK CAPITAL LETTER SIGMA" },
-{ 0x03A3, "Sigma", "GREEK CAPITAL LETTER SIGMA" },
-{ 0x03A4, "Tgr", "GREEK CAPITAL LETTER TAU" },
-{ 0x03A5, "Ugr", "" },
-{ 0x03A6, "b.Phi", "GREEK CAPITAL LETTER PHI" },
-{ 0x03A6, "PHgr", "GREEK CAPITAL LETTER PHI" },
-{ 0x03A6, "Phi", "GREEK CAPITAL LETTER PHI" },
-{ 0x03A7, "KHgr", "GREEK CAPITAL LETTER CHI" },
-{ 0x03A8, "b.Psi", "GREEK CAPITAL LETTER PSI" },
-{ 0x03A8, "PSgr", "GREEK CAPITAL LETTER PSI" },
-{ 0x03A8, "Psi", "GREEK CAPITAL LETTER PSI" },
-{ 0x03A9, "b.Omega", "GREEK CAPITAL LETTER OMEGA" },
-{ 0x03A9, "OHgr", "GREEK CAPITAL LETTER OMEGA" },
-{ 0x03A9, "Omega", "GREEK CAPITAL LETTER OMEGA" },
-{ 0x03AA, "Idigr", "GREEK CAPITAL LETTER IOTA WITH DIALYTIKA" },
-{ 0x03AB, "Udigr", "GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA" },
-{ 0x03AC, "aacgr", "GREEK SMALL LETTER ALPHA WITH TONOS" },
-{ 0x03AD, "eacgr", "GREEK SMALL LETTER EPSILON WITH TONOS" },
-{ 0x03AE, "eeacgr", "GREEK SMALL LETTER ETA WITH TONOS" },
-{ 0x03AF, "iacgr", "GREEK SMALL LETTER IOTA WITH TONOS" },
-{ 0x03B0, "udiagr", "GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS" },
-{ 0x03B1, "agr", "" },
-{ 0x03B1, "alpha", "" },
-{ 0x03B1, "b.alpha", "" },
-{ 0x03B2, "b.beta", "GREEK SMALL LETTER BETA" },
-{ 0x03B2, "beta", "GREEK SMALL LETTER BETA" },
-{ 0x03B2, "bgr", "GREEK SMALL LETTER BETA" },
-{ 0x03B3, "b.gamma", "GREEK SMALL LETTER GAMMA" },
-{ 0x03B3, "gamma", "GREEK SMALL LETTER GAMMA" },
-{ 0x03B3, "ggr", "GREEK SMALL LETTER GAMMA" },
-{ 0x03B4, "b.delta", "GREEK SMALL LETTER DELTA" },
-{ 0x03B4, "delta", "GREEK SMALL LETTER DELTA" },
-{ 0x03B4, "dgr", "GREEK SMALL LETTER DELTA" },
-{ 0x03B5, "b.epsi", "" },
-{ 0x03B5, "b.epsis", "" },
-{ 0x03B5, "b.epsiv", "" },
-{ 0x03B5, "egr", "" },
-{ 0x03B5, "epsiv", "" },
-{ 0x03B6, "b.zeta", "GREEK SMALL LETTER ZETA" },
-{ 0x03B6, "zeta", "GREEK SMALL LETTER ZETA" },
-{ 0x03B6, "zgr", "GREEK SMALL LETTER ZETA" },
-{ 0x03B7, "b.eta", "GREEK SMALL LETTER ETA" },
-{ 0x03B7, "eegr", "GREEK SMALL LETTER ETA" },
-{ 0x03B7, "eta", "GREEK SMALL LETTER ETA" },
-{ 0x03B8, "b.thetas", "" },
-{ 0x03B8, "thetas", "" },
-{ 0x03B8, "thgr", "" },
-{ 0x03B9, "b.iota", "GREEK SMALL LETTER IOTA" },
-{ 0x03B9, "igr", "GREEK SMALL LETTER IOTA" },
-{ 0x03B9, "iota", "GREEK SMALL LETTER IOTA" },
-{ 0x03BA, "b.kappa", "GREEK SMALL LETTER KAPPA" },
-{ 0x03BA, "kappa", "GREEK SMALL LETTER KAPPA" },
-{ 0x03BA, "kgr", "GREEK SMALL LETTER KAPPA" },
-{ 0x03BB, "b.lambda", "GREEK SMALL LETTER LAMDA" },
-{ 0x03BB, "lambda", "GREEK SMALL LETTER LAMDA" },
-{ 0x03BB, "lgr", "GREEK SMALL LETTER LAMDA" },
-{ 0x03BC, "b.mu", "GREEK SMALL LETTER MU" },
-{ 0x03BC, "mgr", "GREEK SMALL LETTER MU" },
-{ 0x03BC, "mu", "GREEK SMALL LETTER MU" },
-{ 0x03BD, "b.nu", "GREEK SMALL LETTER NU" },
-{ 0x03BD, "ngr", "GREEK SMALL LETTER NU" },
-{ 0x03BD, "nu", "GREEK SMALL LETTER NU" },
-{ 0x03BE, "b.xi", "GREEK SMALL LETTER XI" },
-{ 0x03BE, "xgr", "GREEK SMALL LETTER XI" },
-{ 0x03BE, "xi", "GREEK SMALL LETTER XI" },
-{ 0x03BF, "ogr", "GREEK SMALL LETTER OMICRON" },
-{ 0x03C0, "b.pi", "GREEK SMALL LETTER PI" },
-{ 0x03C0, "pgr", "GREEK SMALL LETTER PI" },
-{ 0x03C0, "pi", "GREEK SMALL LETTER PI" },
-{ 0x03C1, "b.rho", "GREEK SMALL LETTER RHO" },
-{ 0x03C1, "rgr", "GREEK SMALL LETTER RHO" },
-{ 0x03C1, "rho", "GREEK SMALL LETTER RHO" },
-{ 0x03C2, "b.sigmav", "" },
-{ 0x03C2, "sfgr", "" },
-{ 0x03C2, "sigmav", "" },
-{ 0x03C3, "b.sigma", "GREEK SMALL LETTER SIGMA" },
-{ 0x03C3, "sgr", "GREEK SMALL LETTER SIGMA" },
-{ 0x03C3, "sigma", "GREEK SMALL LETTER SIGMA" },
-{ 0x03C4, "b.tau", "GREEK SMALL LETTER TAU" },
-{ 0x03C4, "tau", "GREEK SMALL LETTER TAU" },
-{ 0x03C4, "tgr", "GREEK SMALL LETTER TAU" },
-{ 0x03C5, "b.upsi", "GREEK SMALL LETTER UPSILON" },
-{ 0x03C5, "ugr", "GREEK SMALL LETTER UPSILON" },
-{ 0x03C5, "upsi", "GREEK SMALL LETTER UPSILON" },
-{ 0x03C6, "b.phis", "GREEK SMALL LETTER PHI" },
-{ 0x03C6, "phgr", "GREEK SMALL LETTER PHI" },
-{ 0x03C6, "phis", "GREEK SMALL LETTER PHI" },
-{ 0x03C7, "b.chi", "GREEK SMALL LETTER CHI" },
-{ 0x03C7, "chi", "GREEK SMALL LETTER CHI" },
-{ 0x03C7, "khgr", "GREEK SMALL LETTER CHI" },
-{ 0x03C8, "b.psi", "GREEK SMALL LETTER PSI" },
-{ 0x03C8, "psgr", "GREEK SMALL LETTER PSI" },
-{ 0x03C8, "psi", "GREEK SMALL LETTER PSI" },
-{ 0x03C9, "b.omega", "GREEK SMALL LETTER OMEGA" },
-{ 0x03C9, "ohgr", "GREEK SMALL LETTER OMEGA" },
-{ 0x03C9, "omega", "GREEK SMALL LETTER OMEGA" },
-{ 0x03CA, "idigr", "GREEK SMALL LETTER IOTA WITH DIALYTIKA" },
-{ 0x03CB, "udigr", "GREEK SMALL LETTER UPSILON WITH DIALYTIKA" },
-{ 0x03CC, "oacgr", "GREEK SMALL LETTER OMICRON WITH TONOS" },
-{ 0x03CD, "uacgr", "GREEK SMALL LETTER UPSILON WITH TONOS" },
-{ 0x03CE, "ohacgr", "GREEK SMALL LETTER OMEGA WITH TONOS" },
-{ 0x03D1, "b.thetav", "" },
-{ 0x03D1, "thetav", "" },
-{ 0x03D2, "b.Upsi", "" },
-{ 0x03D2, "Upsi", "" },
-{ 0x03D5, "b.phiv", "GREEK PHI SYMBOL" },
-{ 0x03D5, "phiv", "GREEK PHI SYMBOL" },
-{ 0x03D6, "b.piv", "GREEK PI SYMBOL" },
-{ 0x03D6, "piv", "GREEK PI SYMBOL" },
-{ 0x03DC, "b.gammad", "GREEK LETTER DIGAMMA" },
-{ 0x03DC, "gammad", "GREEK LETTER DIGAMMA" },
-{ 0x03F0, "b.kappav", "GREEK KAPPA SYMBOL" },
-{ 0x03F0, "kappav", "GREEK KAPPA SYMBOL" },
-{ 0x03F1, "b.rhov", "GREEK RHO SYMBOL" },
-{ 0x03F1, "rhov", "GREEK RHO SYMBOL" },
-{ 0x0401, "IOcy", "CYRILLIC CAPITAL LETTER IO" },
-{ 0x0402, "DJcy", "CYRILLIC CAPITAL LETTER DJE" },
-{ 0x0403, "GJcy", "CYRILLIC CAPITAL LETTER GJE" },
-{ 0x0404, "Jukcy", "CYRILLIC CAPITAL LETTER UKRAINIAN IE" },
-{ 0x0405, "DScy", "CYRILLIC CAPITAL LETTER DZE" },
-{ 0x0406, "Iukcy", "CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I" },
-{ 0x0407, "YIcy", "CYRILLIC CAPITAL LETTER YI" },
-{ 0x0408, "Jsercy", "CYRILLIC CAPITAL LETTER JE" },
-{ 0x0409, "LJcy", "CYRILLIC CAPITAL LETTER LJE" },
-{ 0x040A, "NJcy", "CYRILLIC CAPITAL LETTER NJE" },
-{ 0x040B, "TSHcy", "CYRILLIC CAPITAL LETTER TSHE" },
-{ 0x040C, "KJcy", "CYRILLIC CAPITAL LETTER KJE" },
-{ 0x040E, "Ubrcy", "CYRILLIC CAPITAL LETTER SHORT U" },
-{ 0x040F, "DZcy", "CYRILLIC CAPITAL LETTER DZHE" },
-{ 0x0410, "Acy", "CYRILLIC CAPITAL LETTER A" },
-{ 0x0411, "Bcy", "CYRILLIC CAPITAL LETTER BE" },
-{ 0x0412, "Vcy", "CYRILLIC CAPITAL LETTER VE" },
-{ 0x0413, "Gcy", "CYRILLIC CAPITAL LETTER GHE" },
-{ 0x0414, "Dcy", "CYRILLIC CAPITAL LETTER DE" },
-{ 0x0415, "IEcy", "CYRILLIC CAPITAL LETTER IE" },
-{ 0x0416, "ZHcy", "CYRILLIC CAPITAL LETTER ZHE" },
-{ 0x0417, "Zcy", "CYRILLIC CAPITAL LETTER ZE" },
-{ 0x0418, "Icy", "CYRILLIC CAPITAL LETTER I" },
-{ 0x0419, "Jcy", "CYRILLIC CAPITAL LETTER SHORT I" },
-{ 0x041A, "Kcy", "CYRILLIC CAPITAL LETTER KA" },
-{ 0x041B, "Lcy", "CYRILLIC CAPITAL LETTER EL" },
-{ 0x041C, "Mcy", "CYRILLIC CAPITAL LETTER EM" },
-{ 0x041D, "Ncy", "CYRILLIC CAPITAL LETTER EN" },
-{ 0x041E, "Ocy", "CYRILLIC CAPITAL LETTER O" },
-{ 0x041F, "Pcy", "CYRILLIC CAPITAL LETTER PE" },
-{ 0x0420, "Rcy", "CYRILLIC CAPITAL LETTER ER" },
-{ 0x0421, "Scy", "CYRILLIC CAPITAL LETTER ES" },
-{ 0x0422, "Tcy", "CYRILLIC CAPITAL LETTER TE" },
-{ 0x0423, "Ucy", "CYRILLIC CAPITAL LETTER U" },
-{ 0x0424, "Fcy", "CYRILLIC CAPITAL LETTER EF" },
-{ 0x0425, "KHcy", "CYRILLIC CAPITAL LETTER HA" },
-{ 0x0426, "TScy", "CYRILLIC CAPITAL LETTER TSE" },
-{ 0x0427, "CHcy", "CYRILLIC CAPITAL LETTER CHE" },
-{ 0x0428, "SHcy", "CYRILLIC CAPITAL LETTER SHA" },
-{ 0x0429, "SHCHcy", "CYRILLIC CAPITAL LETTER SHCHA" },
-{ 0x042A, "HARDcy", "CYRILLIC CAPITAL LETTER HARD SIGN" },
-{ 0x042B, "Ycy", "CYRILLIC CAPITAL LETTER YERU" },
-{ 0x042C, "SOFTcy", "CYRILLIC CAPITAL LETTER SOFT SIGN" },
-{ 0x042D, "Ecy", "CYRILLIC CAPITAL LETTER E" },
-{ 0x042E, "YUcy", "CYRILLIC CAPITAL LETTER YU" },
-{ 0x042F, "YAcy", "CYRILLIC CAPITAL LETTER YA" },
-{ 0x0430, "acy", "CYRILLIC SMALL LETTER A" },
-{ 0x0431, "bcy", "CYRILLIC SMALL LETTER BE" },
-{ 0x0432, "vcy", "CYRILLIC SMALL LETTER VE" },
-{ 0x0433, "gcy", "CYRILLIC SMALL LETTER GHE" },
-{ 0x0434, "dcy", "CYRILLIC SMALL LETTER DE" },
-{ 0x0435, "iecy", "CYRILLIC SMALL LETTER IE" },
-{ 0x0436, "zhcy", "CYRILLIC SMALL LETTER ZHE" },
-{ 0x0437, "zcy", "CYRILLIC SMALL LETTER ZE" },
-{ 0x0438, "icy", "CYRILLIC SMALL LETTER I" },
-{ 0x0439, "jcy", "CYRILLIC SMALL LETTER SHORT I" },
-{ 0x043A, "kcy", "CYRILLIC SMALL LETTER KA" },
-{ 0x043B, "lcy", "CYRILLIC SMALL LETTER EL" },
-{ 0x043C, "mcy", "CYRILLIC SMALL LETTER EM" },
-{ 0x043D, "ncy", "CYRILLIC SMALL LETTER EN" },
-{ 0x043E, "ocy", "CYRILLIC SMALL LETTER O" },
-{ 0x043F, "pcy", "CYRILLIC SMALL LETTER PE" },
-{ 0x0440, "rcy", "CYRILLIC SMALL LETTER ER" },
-{ 0x0441, "scy", "CYRILLIC SMALL LETTER ES" },
-{ 0x0442, "tcy", "CYRILLIC SMALL LETTER TE" },
-{ 0x0443, "ucy", "CYRILLIC SMALL LETTER U" },
-{ 0x0444, "fcy", "CYRILLIC SMALL LETTER EF" },
-{ 0x0445, "khcy", "CYRILLIC SMALL LETTER HA" },
-{ 0x0446, "tscy", "CYRILLIC SMALL LETTER TSE" },
-{ 0x0447, "chcy", "CYRILLIC SMALL LETTER CHE" },
-{ 0x0448, "shcy", "CYRILLIC SMALL LETTER SHA" },
-{ 0x0449, "shchcy", "CYRILLIC SMALL LETTER SHCHA" },
-{ 0x044A, "hardcy", "CYRILLIC SMALL LETTER HARD SIGN" },
-{ 0x044B, "ycy", "CYRILLIC SMALL LETTER YERU" },
-{ 0x044C, "softcy", "CYRILLIC SMALL LETTER SOFT SIGN" },
-{ 0x044D, "ecy", "CYRILLIC SMALL LETTER E" },
-{ 0x044E, "yucy", "CYRILLIC SMALL LETTER YU" },
-{ 0x044F, "yacy", "CYRILLIC SMALL LETTER YA" },
-{ 0x0451, "iocy", "CYRILLIC SMALL LETTER IO" },
-{ 0x0452, "djcy", "CYRILLIC SMALL LETTER DJE" },
-{ 0x0453, "gjcy", "CYRILLIC SMALL LETTER GJE" },
-{ 0x0454, "jukcy", "CYRILLIC SMALL LETTER UKRAINIAN IE" },
-{ 0x0455, "dscy", "CYRILLIC SMALL LETTER DZE" },
-{ 0x0456, "iukcy", "CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I" },
-{ 0x0457, "yicy", "CYRILLIC SMALL LETTER YI" },
-{ 0x0458, "jsercy", "CYRILLIC SMALL LETTER JE" },
-{ 0x0459, "ljcy", "CYRILLIC SMALL LETTER LJE" },
-{ 0x045A, "njcy", "CYRILLIC SMALL LETTER NJE" },
-{ 0x045B, "tshcy", "CYRILLIC SMALL LETTER TSHE" },
-{ 0x045C, "kjcy", "CYRILLIC SMALL LETTER KJE" },
-{ 0x045E, "ubrcy", "CYRILLIC SMALL LETTER SHORT U" },
-{ 0x045F, "dzcy", "CYRILLIC SMALL LETTER DZHE" },
-{ 0x2002, "ensp", "EN SPACE" },
-{ 0x2003, "emsp", "EM SPACE" },
-{ 0x2004, "emsp13", "THREE-PER-EM SPACE" },
-{ 0x2005, "emsp14", "FOUR-PER-EM SPACE" },
-{ 0x2007, "numsp", "FIGURE SPACE" },
-{ 0x2008, "puncsp", "PUNCTUATION SPACE" },
-{ 0x2009, "thinsp", "THIN SPACE" },
-{ 0x200A, "hairsp", "HAIR SPACE" },
-{ 0x2010, "dash", "HYPHEN" },
-{ 0x2013, "ndash", "EN DASH" },
-{ 0x2014, "mdash", "EM DASH" },
-{ 0x2015, "horbar", "HORIZONTAL BAR" },
-{ 0x2016, "Verbar", "DOUBLE VERTICAL LINE" },
-{ 0x2018, "lsquo", "" },
-{ 0x2018, "rsquor", "" },
-{ 0x2019, "rsquo", "RIGHT SINGLE QUOTATION MARK" },
-{ 0x201A, "lsquor", "SINGLE LOW-9 QUOTATION MARK" },
-{ 0x201C, "ldquo", "" },
-{ 0x201C, "rdquor", "" },
-{ 0x201D, "rdquo", "RIGHT DOUBLE QUOTATION MARK" },
-{ 0x201E, "ldquor", "DOUBLE LOW-9 QUOTATION MARK" },
-{ 0x2020, "dagger", "DAGGER" },
-{ 0x2021, "Dagger", "DOUBLE DAGGER" },
-{ 0x2022, "bull", "BULLET" },
-{ 0x2025, "nldr", "TWO DOT LEADER" },
-{ 0x2026, "hellip", "HORIZONTAL ELLIPSIS" },
-{ 0x2026, "mldr", "HORIZONTAL ELLIPSIS" },
-{ 0x2030, "permil", "PER MILLE SIGN" },
-{ 0x2032, "prime", "PRIME" },
-{ 0x2032, "vprime", "PRIME" },
-{ 0x2033, "Prime", "DOUBLE PRIME" },
-{ 0x2034, "tprime", "TRIPLE PRIME" },
-{ 0x2035, "bprime", "REVERSED PRIME" },
-{ 0x2041, "caret", "CARET" },
-{ 0x2043, "hybull", "HYPHEN BULLET" },
-{ 0x20DB, "tdot", "COMBINING THREE DOTS ABOVE" },
-{ 0x20DC, "DotDot", "COMBINING FOUR DOTS ABOVE" },
-{ 0x2105, "incare", "CARE OF" },
-{ 0x210B, "hamilt", "SCRIPT CAPITAL H" },
-{ 0x210F, "planck", "PLANCK CONSTANT OVER TWO PI" },
-{ 0x2111, "image", "BLACK-LETTER CAPITAL I" },
-{ 0x2112, "lagran", "SCRIPT CAPITAL L" },
-{ 0x2113, "ell", "SCRIPT SMALL L" },
-{ 0x2116, "numero", "NUMERO SIGN" },
-{ 0x2117, "copysr", "SOUND RECORDING COPYRIGHT" },
-{ 0x2118, "weierp", "SCRIPT CAPITAL P" },
-{ 0x211C, "real", "BLACK-LETTER CAPITAL R" },
-{ 0x211E, "rx", "PRESCRIPTION TAKE" },
-{ 0x2122, "trade", "TRADE MARK SIGN" },
-{ 0x2126, "ohm", "OHM SIGN" },
-{ 0x212B, "angst", "ANGSTROM SIGN" },
-{ 0x212C, "bernou", "SCRIPT CAPITAL B" },
-{ 0x2133, "phmmat", "SCRIPT CAPITAL M" },
-{ 0x2134, "order", "SCRIPT SMALL O" },
-{ 0x2135, "aleph", "ALEF SYMBOL" },
-{ 0x2136, "beth", "BET SYMBOL" },
-{ 0x2137, "gimel", "GIMEL SYMBOL" },
-{ 0x2138, "daleth", "DALET SYMBOL" },
-{ 0x2153, "frac13", "VULGAR FRACTION ONE THIRD" },
-{ 0x2154, "frac23", "VULGAR FRACTION TWO THIRDS" },
-{ 0x2155, "frac15", "VULGAR FRACTION ONE FIFTH" },
-{ 0x2156, "frac25", "VULGAR FRACTION TWO FIFTHS" },
-{ 0x2157, "frac35", "VULGAR FRACTION THREE FIFTHS" },
-{ 0x2158, "frac45", "VULGAR FRACTION FOUR FIFTHS" },
-{ 0x2159, "frac16", "VULGAR FRACTION ONE SIXTH" },
-{ 0x215A, "frac56", "VULGAR FRACTION FIVE SIXTHS" },
-{ 0x215B, "frac18", "" },
-{ 0x215C, "frac38", "" },
-{ 0x215D, "frac58", "" },
-{ 0x215E, "frac78", "" },
-{ 0x2190, "larr", "LEFTWARDS DOUBLE ARROW" },
-{ 0x2191, "uarr", "UPWARDS ARROW" },
-{ 0x2192, "rarr", "RIGHTWARDS DOUBLE ARROW" },
-{ 0x2193, "darr", "DOWNWARDS ARROW" },
-{ 0x2194, "harr", "LEFT RIGHT ARROW" },
-{ 0x2194, "xhArr", "LEFT RIGHT ARROW" },
-{ 0x2194, "xharr", "LEFT RIGHT ARROW" },
-{ 0x2195, "varr", "UP DOWN ARROW" },
-{ 0x2196, "nwarr", "NORTH WEST ARROW" },
-{ 0x2197, "nearr", "NORTH EAST ARROW" },
-{ 0x2198, "drarr", "SOUTH EAST ARROW" },
-{ 0x2199, "dlarr", "SOUTH WEST ARROW" },
-{ 0x219A, "nlarr", "LEFTWARDS ARROW WITH STROKE" },
-{ 0x219B, "nrarr", "RIGHTWARDS ARROW WITH STROKE" },
-{ 0x219D, "rarrw", "RIGHTWARDS SQUIGGLE ARROW" },
-{ 0x219E, "Larr", "LEFTWARDS TWO HEADED ARROW" },
-{ 0x21A0, "Rarr", "RIGHTWARDS TWO HEADED ARROW" },
-{ 0x21A2, "larrtl", "LEFTWARDS ARROW WITH TAIL" },
-{ 0x21A3, "rarrtl", "RIGHTWARDS ARROW WITH TAIL" },
-{ 0x21A6, "map", "RIGHTWARDS ARROW FROM BAR" },
-{ 0x21A9, "larrhk", "LEFTWARDS ARROW WITH HOOK" },
-{ 0x21AA, "rarrhk", "RIGHTWARDS ARROW WITH HOOK" },
-{ 0x21AB, "larrlp", "LEFTWARDS ARROW WITH LOOP" },
-{ 0x21AC, "rarrlp", "RIGHTWARDS ARROW WITH LOOP" },
-{ 0x21AD, "harrw", "LEFT RIGHT WAVE ARROW" },
-{ 0x21AE, "nharr", "LEFT RIGHT ARROW WITH STROKE" },
-{ 0x21B0, "lsh", "UPWARDS ARROW WITH TIP LEFTWARDS" },
-{ 0x21B1, "rsh", "UPWARDS ARROW WITH TIP RIGHTWARDS" },
-{ 0x21B6, "cularr", "ANTICLOCKWISE TOP SEMICIRCLE ARROW" },
-{ 0x21B7, "curarr", "CLOCKWISE TOP SEMICIRCLE ARROW" },
-{ 0x21BA, "olarr", "ANTICLOCKWISE OPEN CIRCLE ARROW" },
-{ 0x21BB, "orarr", "CLOCKWISE OPEN CIRCLE ARROW" },
-{ 0x21BC, "lharu", "LEFTWARDS HARPOON WITH BARB UPWARDS" },
-{ 0x21BD, "lhard", "LEFTWARDS HARPOON WITH BARB DOWNWARDS" },
-{ 0x21BE, "uharr", "UPWARDS HARPOON WITH BARB RIGHTWARDS" },
-{ 0x21BF, "uharl", "UPWARDS HARPOON WITH BARB LEFTWARDS" },
-{ 0x21C0, "rharu", "RIGHTWARDS HARPOON WITH BARB UPWARDS" },
-{ 0x21C1, "rhard", "RIGHTWARDS HARPOON WITH BARB DOWNWARDS" },
-{ 0x21C2, "dharr", "DOWNWARDS HARPOON WITH BARB RIGHTWARDS" },
-{ 0x21C3, "dharl", "DOWNWARDS HARPOON WITH BARB LEFTWARDS" },
-{ 0x21C4, "rlarr2", "RIGHTWARDS ARROW OVER LEFTWARDS ARROW" },
-{ 0x21C6, "lrarr2", "LEFTWARDS ARROW OVER RIGHTWARDS ARROW" },
-{ 0x21C7, "larr2", "LEFTWARDS PAIRED ARROWS" },
-{ 0x21C8, "uarr2", "UPWARDS PAIRED ARROWS" },
-{ 0x21C9, "rarr2", "RIGHTWARDS PAIRED ARROWS" },
-{ 0x21CA, "darr2", "DOWNWARDS PAIRED ARROWS" },
-{ 0x21CB, "lrhar2", "LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON" },
-{ 0x21CC, "rlhar2", "RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON" },
-{ 0x21CD, "nlArr", "LEFTWARDS DOUBLE ARROW WITH STROKE" },
-{ 0x21CE, "nhArr", "LEFT RIGHT DOUBLE ARROW WITH STROKE" },
-{ 0x21CF, "nrArr", "RIGHTWARDS DOUBLE ARROW WITH STROKE" },
-{ 0x21D0, "lArr", "LEFTWARDS ARROW" },
-{ 0x21D0, "xlArr", "LEFTWARDS DOUBLE ARROW" },
-{ 0x21D1, "uArr", "UPWARDS DOUBLE ARROW" },
-{ 0x21D2, "rArr", "RIGHTWARDS ARROW" },
-{ 0x21D2, "xrArr", "RIGHTWARDS DOUBLE ARROW" },
-{ 0x21D3, "dArr", "DOWNWARDS DOUBLE ARROW" },
-{ 0x21D4, "hArr", "" },
-{ 0x21D4, "iff", "LEFT RIGHT DOUBLE ARROW" },
-{ 0x21D5, "vArr", "UP DOWN DOUBLE ARROW" },
-{ 0x21DA, "lAarr", "LEFTWARDS TRIPLE ARROW" },
-{ 0x21DB, "rAarr", "RIGHTWARDS TRIPLE ARROW" },
-{ 0x2200, "forall", "" },
-{ 0x2201, "comp", "COMPLEMENT" },
-{ 0x2202, "part", "" },
-{ 0x2203, "exist", "" },
-{ 0x2204, "nexist", "THERE DOES NOT EXIST" },
-{ 0x2205, "empty", "" },
-{ 0x2207, "nabla", "NABLA" },
-{ 0x2209, "notin", "" },
-{ 0x220A, "epsi", "" },
-{ 0x220A, "epsis", "" },
-{ 0x220A, "isin", "" },
-{ 0x220D, "bepsi", "SMALL CONTAINS AS MEMBER" },
-{ 0x220D, "ni", "" },
-{ 0x220F, "prod", "N-ARY PRODUCT" },
-{ 0x2210, "amalg", "N-ARY COPRODUCT" },
-{ 0x2210, "coprod", "N-ARY COPRODUCT" },
-{ 0x2210, "samalg", "" },
-{ 0x2211, "sum", "N-ARY SUMMATION" },
-{ 0x2212, "minus", "MINUS SIGN" },
-{ 0x2213, "mnplus", "" },
-{ 0x2214, "plusdo", "DOT PLUS" },
-{ 0x2216, "setmn", "SET MINUS" },
-{ 0x2216, "ssetmn", "SET MINUS" },
-{ 0x2217, "lowast", "ASTERISK OPERATOR" },
-{ 0x2218, "compfn", "RING OPERATOR" },
-{ 0x221A, "radic", "" },
-{ 0x221D, "prop", "" },
-{ 0x221D, "vprop", "" },
-{ 0x221E, "infin", "" },
-{ 0x221F, "ang90", "RIGHT ANGLE" },
-{ 0x2220, "ang", "ANGLE" },
-{ 0x2221, "angmsd", "MEASURED ANGLE" },
-{ 0x2222, "angsph", "" },
-{ 0x2223, "mid", "" },
-{ 0x2224, "nmid", "DOES NOT DIVIDE" },
-{ 0x2225, "par", "PARALLEL TO" },
-{ 0x2225, "spar", "PARALLEL TO" },
-{ 0x2226, "npar", "NOT PARALLEL TO" },
-{ 0x2226, "nspar", "NOT PARALLEL TO" },
-{ 0x2227, "and", "" },
-{ 0x2228, "or", "" },
-{ 0x2229, "cap", "" },
-{ 0x222A, "cup", "" },
-{ 0x222B, "int", "" },
-{ 0x222E, "conint", "" },
-{ 0x2234, "there4", "" },
-{ 0x2235, "becaus", "BECAUSE" },
-{ 0x223C, "sim", "" },
-{ 0x223C, "thksim", "TILDE OPERATOR" },
-{ 0x223D, "bsim", "" },
-{ 0x2240, "wreath", "WREATH PRODUCT" },
-{ 0x2241, "nsim", "" },
-{ 0x2243, "sime", "" },
-{ 0x2244, "nsime", "" },
-{ 0x2245, "cong", "" },
-{ 0x2247, "ncong", "NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO" },
-{ 0x2248, "ap", "" },
-{ 0x2248, "thkap", "ALMOST EQUAL TO" },
-{ 0x2249, "nap", "NOT ALMOST EQUAL TO" },
-{ 0x224A, "ape", "" },
-{ 0x224C, "bcong", "ALL EQUAL TO" },
-{ 0x224D, "asymp", "EQUIVALENT TO" },
-{ 0x224E, "bump", "" },
-{ 0x224F, "bumpe", "" },
-{ 0x2250, "esdot", "" },
-{ 0x2251, "eDot", "" },
-{ 0x2252, "efDot", "" },
-{ 0x2253, "erDot", "" },
-{ 0x2254, "colone", "" },
-{ 0x2255, "ecolon", "" },
-{ 0x2256, "ecir", "" },
-{ 0x2257, "cire", "" },
-{ 0x2259, "wedgeq", "ESTIMATES" },
-{ 0x225C, "trie", "" },
-{ 0x2260, "ne", "" },
-{ 0x2261, "equiv", "" },
-{ 0x2262, "nequiv", "NOT IDENTICAL TO" },
-{ 0x2264, "le", "" },
-{ 0x2264, "les", "LESS-THAN OR EQUAL TO" },
-{ 0x2265, "ge", "GREATER-THAN OR EQUAL TO" },
-{ 0x2265, "ges", "GREATER-THAN OR EQUAL TO" },
-{ 0x2266, "lE", "" },
-{ 0x2267, "gE", "" },
-{ 0x2268, "lnE", "" },
-{ 0x2268, "lne", "" },
-{ 0x2268, "lvnE", "LESS-THAN BUT NOT EQUAL TO" },
-{ 0x2269, "gnE", "" },
-{ 0x2269, "gne", "" },
-{ 0x2269, "gvnE", "GREATER-THAN BUT NOT EQUAL TO" },
-{ 0x226A, "Lt", "MUCH LESS-THAN" },
-{ 0x226B, "Gt", "MUCH GREATER-THAN" },
-{ 0x226C, "twixt", "BETWEEN" },
-{ 0x226E, "nlt", "NOT LESS-THAN" },
-{ 0x226F, "ngt", "NOT GREATER-THAN" },
-{ 0x2270, "nlE", "" },
-{ 0x2270, "nle", "NEITHER LESS-THAN NOR EQUAL TO" },
-{ 0x2270, "nles", "" },
-{ 0x2271, "ngE", "" },
-{ 0x2271, "nge", "NEITHER GREATER-THAN NOR EQUAL TO" },
-{ 0x2271, "nges", "" },
-{ 0x2272, "lap", "LESS-THAN OR EQUIVALENT TO" },
-{ 0x2272, "lsim", "LESS-THAN OR EQUIVALENT TO" },
-{ 0x2273, "gap", "GREATER-THAN OR EQUIVALENT TO" },
-{ 0x2273, "gsim", "GREATER-THAN OR EQUIVALENT TO" },
-{ 0x2276, "lg", "LESS-THAN OR GREATER-THAN" },
-{ 0x2277, "gl", "" },
-{ 0x227A, "pr", "" },
-{ 0x227B, "sc", "" },
-{ 0x227C, "cupre", "" },
-{ 0x227C, "pre", "" },
-{ 0x227D, "sccue", "" },
-{ 0x227D, "sce", "" },
-{ 0x227E, "prap", "" },
-{ 0x227E, "prsim", "" },
-{ 0x227F, "scap", "" },
-{ 0x227F, "scsim", "" },
-{ 0x2280, "npr", "DOES NOT PRECEDE" },
-{ 0x2281, "nsc", "DOES NOT SUCCEED" },
-{ 0x2282, "sub", "" },
-{ 0x2283, "sup", "" },
-{ 0x2284, "nsub", "NOT A SUBSET OF" },
-{ 0x2285, "nsup", "NOT A SUPERSET OF" },
-{ 0x2286, "subE", "" },
-{ 0x2286, "sube", "" },
-{ 0x2287, "supE", "" },
-{ 0x2287, "supe", "" },
-{ 0x2288, "nsubE", "" },
-{ 0x2288, "nsube", "" },
-{ 0x2289, "nsupE", "" },
-{ 0x2289, "nsupe", "" },
-{ 0x228A, "subne", "" },
-{ 0x228A, "subnE", "SUBSET OF WITH NOT EQUAL TO" },
-{ 0x228A, "vsubne", "SUBSET OF WITH NOT EQUAL TO" },
-{ 0x228B, "supnE", "" },
-{ 0x228B, "supne", "" },
-{ 0x228B, "vsupnE", "SUPERSET OF WITH NOT EQUAL TO" },
-{ 0x228B, "vsupne", "SUPERSET OF WITH NOT EQUAL TO" },
-{ 0x228E, "uplus", "MULTISET UNION" },
-{ 0x228F, "sqsub", "" },
-{ 0x2290, "sqsup", "" },
-{ 0x2291, "sqsube", "" },
-{ 0x2292, "sqsupe", "" },
-{ 0x2293, "sqcap", "SQUARE CAP" },
-{ 0x2294, "sqcup", "SQUARE CUP" },
-{ 0x2295, "oplus", "CIRCLED PLUS" },
-{ 0x2296, "ominus", "CIRCLED MINUS" },
-{ 0x2297, "otimes", "CIRCLED TIMES" },
-{ 0x2298, "osol", "CIRCLED DIVISION SLASH" },
-{ 0x2299, "odot", "CIRCLED DOT OPERATOR" },
-{ 0x229A, "ocir", "CIRCLED RING OPERATOR" },
-{ 0x229B, "oast", "CIRCLED ASTERISK OPERATOR" },
-{ 0x229D, "odash", "CIRCLED DASH" },
-{ 0x229E, "plusb", "SQUARED PLUS" },
-{ 0x229F, "minusb", "SQUARED MINUS" },
-{ 0x22A0, "timesb", "SQUARED TIMES" },
-{ 0x22A1, "sdotb", "SQUARED DOT OPERATOR" },
-{ 0x22A2, "vdash", "" },
-{ 0x22A3, "dashv", "" },
-{ 0x22A4, "top", "DOWN TACK" },
-{ 0x22A5, "bottom", "" },
-{ 0x22A5, "perp", "" },
-{ 0x22A7, "models", "MODELS" },
-{ 0x22A8, "vDash", "" },
-{ 0x22A9, "Vdash", "" },
-{ 0x22AA, "Vvdash", "" },
-{ 0x22AC, "nvdash", "DOES NOT PROVE" },
-{ 0x22AD, "nvDash", "NOT TRUE" },
-{ 0x22AE, "nVdash", "DOES NOT FORCE" },
-{ 0x22AF, "nVDash", "NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE" },
-{ 0x22B2, "vltri", "" },
-{ 0x22B3, "vrtri", "" },
-{ 0x22B4, "ltrie", "" },
-{ 0x22B5, "rtrie", "" },
-{ 0x22B8, "mumap", "MULTIMAP" },
-{ 0x22BA, "intcal", "INTERCALATE" },
-{ 0x22BB, "veebar", "" },
-{ 0x22BC, "barwed", "NAND" },
-{ 0x22C4, "diam", "DIAMOND OPERATOR" },
-{ 0x22C5, "sdot", "DOT OPERATOR" },
-{ 0x22C6, "sstarf", "STAR OPERATOR" },
-{ 0x22C6, "star", "STAR OPERATOR" },
-{ 0x22C7, "divonx", "DIVISION TIMES" },
-{ 0x22C8, "bowtie", "" },
-{ 0x22C9, "ltimes", "LEFT NORMAL FACTOR SEMIDIRECT PRODUCT" },
-{ 0x22CA, "rtimes", "RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT" },
-{ 0x22CB, "lthree", "LEFT SEMIDIRECT PRODUCT" },
-{ 0x22CC, "rthree", "RIGHT SEMIDIRECT PRODUCT" },
-{ 0x22CD, "bsime", "" },
-{ 0x22CE, "cuvee", "CURLY LOGICAL OR" },
-{ 0x22CF, "cuwed", "CURLY LOGICAL AND" },
-{ 0x22D0, "Sub", "" },
-{ 0x22D1, "Sup", "" },
-{ 0x22D2, "Cap", "DOUBLE INTERSECTION" },
-{ 0x22D3, "Cup", "DOUBLE UNION" },
-{ 0x22D4, "fork", "" },
-{ 0x22D6, "ldot", "" },
-{ 0x22D7, "gsdot", "" },
-{ 0x22D8, "Ll", "" },
-{ 0x22D9, "Gg", "VERY MUCH GREATER-THAN" },
-{ 0x22DA, "lEg", "" },
-{ 0x22DA, "leg", "" },
-{ 0x22DB, "gEl", "" },
-{ 0x22DB, "gel", "" },
-{ 0x22DC, "els", "" },
-{ 0x22DD, "egs", "" },
-{ 0x22DE, "cuepr", "" },
-{ 0x22DF, "cuesc", "" },
-{ 0x22E0, "npre", "DOES NOT PRECEDE OR EQUAL" },
-{ 0x22E1, "nsce", "DOES NOT SUCCEED OR EQUAL" },
-{ 0x22E6, "lnsim", "" },
-{ 0x22E7, "gnsim", "GREATER-THAN BUT NOT EQUIVALENT TO" },
-{ 0x22E8, "prnap", "" },
-{ 0x22E8, "prnsim", "" },
-{ 0x22E9, "scnap", "" },
-{ 0x22E9, "scnsim", "" },
-{ 0x22EA, "nltri", "NOT NORMAL SUBGROUP OF" },
-{ 0x22EB, "nrtri", "DOES NOT CONTAIN AS NORMAL SUBGROUP" },
-{ 0x22EC, "nltrie", "NOT NORMAL SUBGROUP OF OR EQUAL TO" },
-{ 0x22ED, "nrtrie", "DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL" },
-{ 0x22EE, "vellip", "" },
-{ 0x2306, "Barwed", "PERSPECTIVE" },
-{ 0x2308, "lceil", "LEFT CEILING" },
-{ 0x2309, "rceil", "RIGHT CEILING" },
-{ 0x230A, "lfloor", "LEFT FLOOR" },
-{ 0x230B, "rfloor", "RIGHT FLOOR" },
-{ 0x230C, "drcrop", "BOTTOM RIGHT CROP" },
-{ 0x230D, "dlcrop", "BOTTOM LEFT CROP" },
-{ 0x230E, "urcrop", "TOP RIGHT CROP" },
-{ 0x230F, "ulcrop", "TOP LEFT CROP" },
-{ 0x2315, "telrec", "TELEPHONE RECORDER" },
-{ 0x2316, "target", "POSITION INDICATOR" },
-{ 0x231C, "ulcorn", "TOP LEFT CORNER" },
-{ 0x231D, "urcorn", "TOP RIGHT CORNER" },
-{ 0x231E, "dlcorn", "BOTTOM LEFT CORNER" },
-{ 0x231F, "drcorn", "BOTTOM RIGHT CORNER" },
-{ 0x2322, "frown", "" },
-{ 0x2322, "sfrown", "FROWN" },
-{ 0x2323, "smile", "" },
-{ 0x2323, "ssmile", "SMILE" },
-{ 0x2423, "blank", "OPEN BOX" },
-{ 0x24C8, "oS", "CIRCLED LATIN CAPITAL LETTER S" },
-{ 0x2500, "boxh", "BOX DRAWINGS LIGHT HORIZONTAL" },
-{ 0x2502, "boxv", "BOX DRAWINGS LIGHT VERTICAL" },
-{ 0x250C, "boxdr", "BOX DRAWINGS LIGHT DOWN AND RIGHT" },
-{ 0x2510, "boxdl", "BOX DRAWINGS LIGHT DOWN AND LEFT" },
-{ 0x2514, "boxur", "BOX DRAWINGS LIGHT UP AND RIGHT" },
-{ 0x2518, "boxul", "BOX DRAWINGS LIGHT UP AND LEFT" },
-{ 0x251C, "boxvr", "BOX DRAWINGS LIGHT VERTICAL AND RIGHT" },
-{ 0x2524, "boxvl", "BOX DRAWINGS LIGHT VERTICAL AND LEFT" },
-{ 0x252C, "boxhd", "BOX DRAWINGS LIGHT DOWN AND HORIZONTAL" },
-{ 0x2534, "boxhu", "BOX DRAWINGS LIGHT UP AND HORIZONTAL" },
-{ 0x253C, "boxvh", "BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL" },
-{ 0x2550, "boxH", "BOX DRAWINGS DOUBLE HORIZONTAL" },
-{ 0x2551, "boxV", "BOX DRAWINGS DOUBLE VERTICAL" },
-{ 0x2552, "boxDR", "BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE" },
-{ 0x2553, "boxDr", "BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE" },
-{ 0x2554, "boxdR", "BOX DRAWINGS DOUBLE DOWN AND RIGHT" },
-{ 0x2555, "boxDL", "BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE" },
-{ 0x2556, "boxdL", "BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE" },
-{ 0x2557, "boxDl", "BOX DRAWINGS DOUBLE DOWN AND LEFT" },
-{ 0x2558, "boxUR", "BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE" },
-{ 0x2559, "boxuR", "BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE" },
-{ 0x255A, "boxUr", "BOX DRAWINGS DOUBLE UP AND RIGHT" },
-{ 0x255B, "boxUL", "BOX DRAWINGS UP SINGLE AND LEFT DOUBLE" },
-{ 0x255C, "boxUl", "BOX DRAWINGS UP DOUBLE AND LEFT SINGLE" },
-{ 0x255D, "boxuL", "BOX DRAWINGS DOUBLE UP AND LEFT" },
-{ 0x255E, "boxvR", "BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE" },
-{ 0x255F, "boxVR", "BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE" },
-{ 0x2560, "boxVr", "BOX DRAWINGS DOUBLE VERTICAL AND RIGHT" },
-{ 0x2561, "boxvL", "BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE" },
-{ 0x2562, "boxVL", "BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE" },
-{ 0x2563, "boxVl", "BOX DRAWINGS DOUBLE VERTICAL AND LEFT" },
-{ 0x2564, "boxhD", "BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE" },
-{ 0x2565, "boxHD", "BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE" },
-{ 0x2566, "boxHd", "BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL" },
-{ 0x2567, "boxhU", "BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE" },
-{ 0x2568, "boxHU", "BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE" },
-{ 0x2569, "boxHu", "BOX DRAWINGS DOUBLE UP AND HORIZONTAL" },
-{ 0x256A, "boxvH", "BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE" },
-{ 0x256B, "boxVH", "BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE" },
-{ 0x256C, "boxVh", "BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL" },
-{ 0x2580, "uhblk", "UPPER HALF BLOCK" },
-{ 0x2584, "lhblk", "LOWER HALF BLOCK" },
-{ 0x2588, "block", "FULL BLOCK" },
-{ 0x2591, "blk14", "LIGHT SHADE" },
-{ 0x2592, "blk12", "MEDIUM SHADE" },
-{ 0x2593, "blk34", "DARK SHADE" },
-{ 0x25A1, "square", "WHITE SQUARE" },
-{ 0x25A1, "squ", "WHITE SQUARE" },
-{ 0x25AA, "squf", "" },
-{ 0x25AD, "rect", "WHITE RECTANGLE" },
-{ 0x25AE, "marker", "BLACK VERTICAL RECTANGLE" },
-{ 0x25B3, "xutri", "WHITE UP-POINTING TRIANGLE" },
-{ 0x25B4, "utrif", "BLACK UP-POINTING TRIANGLE" },
-{ 0x25B5, "utri", "WHITE UP-POINTING TRIANGLE" },
-{ 0x25B8, "rtrif", "BLACK RIGHT-POINTING TRIANGLE" },
-{ 0x25B9, "rtri", "WHITE RIGHT-POINTING TRIANGLE" },
-{ 0x25BD, "xdtri", "WHITE DOWN-POINTING TRIANGLE" },
-{ 0x25BE, "dtrif", "BLACK DOWN-POINTING TRIANGLE" },
-{ 0x25BF, "dtri", "WHITE DOWN-POINTING TRIANGLE" },
-{ 0x25C2, "ltrif", "BLACK LEFT-POINTING TRIANGLE" },
-{ 0x25C3, "ltri", "WHITE LEFT-POINTING TRIANGLE" },
-{ 0x25CA, "loz", "LOZENGE" },
-{ 0x25CB, "cir", "WHITE CIRCLE" },
-{ 0x25CB, "xcirc", "WHITE CIRCLE" },
-{ 0x2605, "starf", "BLACK STAR" },
-{ 0x260E, "phone", "TELEPHONE SIGN" },
-{ 0x2640, "female", "" },
-{ 0x2642, "male", "MALE SIGN" },
-{ 0x2660, "spades", "BLACK SPADE SUIT" },
-{ 0x2663, "clubs", "BLACK CLUB SUIT" },
-{ 0x2665, "hearts", "BLACK HEART SUIT" },
-{ 0x2666, "diams", "BLACK DIAMOND SUIT" },
-{ 0x2669, "sung", "" },
-{ 0x266D, "flat", "MUSIC FLAT SIGN" },
-{ 0x266E, "natur", "MUSIC NATURAL SIGN" },
-{ 0x266F, "sharp", "MUSIC SHARP SIGN" },
-{ 0x2713, "check", "CHECK MARK" },
-{ 0x2717, "cross", "BALLOT X" },
-{ 0x2720, "malt", "MALTESE CROSS" },
-{ 0x2726, "lozf", "" },
-{ 0x2736, "sext", "SIX POINTED BLACK STAR" },
-{ 0x3008, "lang", "" },
-{ 0x3009, "rang", "" },
-{ 0xE291, "rpargt", "" },
-{ 0xE2A2, "lnap", "" },
-{ 0xE2AA, "nsmid", "" },
-{ 0xE2B3, "prnE", "" },
-{ 0xE2B5, "scnE", "" },
-{ 0xE2B8, "vsubnE", "" },
-{ 0xE301, "smid", "" },
-{ 0xE411, "gnap", "" },
-{ 0xFB00, "fflig", "" },
-{ 0xFB01, "filig", "" },
-{ 0xFB02, "fllig", "" },
-{ 0xFB03, "ffilig", "" },
-{ 0xFB04, "ffllig", "" },
-{ 0xFE68, "sbsol", "SMALL REVERSE SOLIDUS" },
-};
-
-/************************************************************************
- * *
- * Commodity functions to handle entities *
- * *
- ************************************************************************/
-
-/*
- * Macro used to grow the current buffer.
- */
-#define growBuffer(buffer) { \
- buffer##_size *= 2; \
- buffer = (xmlChar *) xmlRealloc(buffer, buffer##_size * sizeof(xmlChar)); \
- if (buffer == NULL) { \
- xmlGenericError(xmlGenericErrorContext, "realloc failed"); \
- return(NULL); \
- } \
-}
-
-/**
- * docbEntityLookup:
- * @name: the entity name
- *
- * Lookup the given entity in EntitiesTable
- *
- * TODO: the linear scan is really ugly, an hash table is really needed.
- *
- * Returns the associated docbEntityDescPtr if found, NULL otherwise.
- */
-static docbEntityDescPtr
-docbEntityLookup(const xmlChar *name) {
- unsigned int i;
-
- for (i = 0;i < (sizeof(docbookEntitiesTable)/
- sizeof(docbookEntitiesTable[0]));i++) {
- if (xmlStrEqual(name, BAD_CAST docbookEntitiesTable[i].name)) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"Found entity %s\n", name);
-#endif
- return(&docbookEntitiesTable[i]);
- }
- }
- return(NULL);
-}
-
-/**
- * docbEntityValueLookup:
- * @value: the entity's unicode value
- *
- * Lookup the given entity in EntitiesTable
- *
- * TODO: the linear scan is really ugly, an hash table is really needed.
- *
- * Returns the associated docbEntityDescPtr if found, NULL otherwise.
- */
-static docbEntityDescPtr
-docbEntityValueLookup(int value) {
- unsigned int i;
-#ifdef DEBUG
- int lv = 0;
-#endif
-
- for (i = 0;i < (sizeof(docbookEntitiesTable)/
- sizeof(docbookEntitiesTable[0]));i++) {
- if (docbookEntitiesTable[i].value >= value) {
- if (docbookEntitiesTable[i].value > value)
- break;
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"Found entity %s\n", docbookEntitiesTable[i].name);
-#endif
- return(&docbookEntitiesTable[i]);
- }
-#ifdef DEBUG
- if (lv > docbookEntitiesTable[i].value) {
- xmlGenericError(xmlGenericErrorContext,
- "docbookEntitiesTable[] is not sorted (%d > %d)!\n",
- lv, docbookEntitiesTable[i].value);
- }
- lv = docbookEntitiesTable[i].value;
-#endif
- }
- return(NULL);
-}
-
-#if 0
-/**
- * UTF8ToSgml:
- * @out: a pointer to an array of bytes to store the result
- * @outlen: the length of @out
- * @in: a pointer to an array of UTF-8 chars
- * @inlen: the length of @in
- *
- * Take a block of UTF-8 chars in and try to convert it to an ASCII
- * plus SGML entities block of chars out.
- *
- * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
- * The value of @inlen after return is the number of octets consumed
- * as the return value is positive, else unpredictable.
- * The value of @outlen after return is the number of octets consumed.
- */
-int
-UTF8ToSgml(unsigned char* out, int *outlen,
- const unsigned char* in, int *inlen) {
- const unsigned char* processed = in;
- const unsigned char* outend;
- const unsigned char* outstart = out;
- const unsigned char* instart = in;
- const unsigned char* inend;
- unsigned int c, d;
- int trailing;
-
- if (in == NULL) {
- /*
- * initialization nothing to do
- */
- *outlen = 0;
- *inlen = 0;
- return(0);
- }
- inend = in + (*inlen);
- outend = out + (*outlen);
- while (in < inend) {
- d = *in++;
- if (d < 0x80) { c= d; trailing= 0; }
- else if (d < 0xC0) {
- /* trailing byte in leading position */
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
- else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
- else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
- else {
- /* no chance for this in Ascii */
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- }
-
- if (inend - in < trailing) {
- break;
- }
-
- for ( ; trailing; trailing--) {
- if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
- break;
- c <<= 6;
- c |= d & 0x3F;
- }
-
- /* assertion: c is a single UTF-4 value */
- if (c < 0x80) {
- if (out + 1 >= outend)
- break;
- *out++ = c;
- } else {
- int len;
- docbEntityDescPtr ent;
-
- /*
- * Try to lookup a predefined SGML entity for it
- */
-
- ent = docbEntityValueLookup(c);
- if (ent == NULL) {
- /* no chance for this in Ascii */
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- }
- len = strlen(ent->name);
- if (out + 2 + len >= outend)
- break;
- *out++ = '&';
- memcpy(out, ent->name, len);
- out += len;
- *out++ = ';';
- }
- processed = in;
- }
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(0);
-}
-#endif
-
-/**
- * docbEncodeEntities:
- * @out: a pointer to an array of bytes to store the result
- * @outlen: the length of @out
- * @in: a pointer to an array of UTF-8 chars
- * @inlen: the length of @in
- * @quoteChar: the quote character to escape (' or ") or zero.
- *
- * Take a block of UTF-8 chars in and try to convert it to an ASCII
- * plus SGML entities block of chars out.
- *
- * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
- * The value of @inlen after return is the number of octets consumed
- * as the return value is positive, else unpredictable.
- * The value of @outlen after return is the number of octets consumed.
- */
-int
-docbEncodeEntities(unsigned char* out, int *outlen,
- const unsigned char* in, int *inlen, int quoteChar) {
- const unsigned char* processed = in;
- const unsigned char* outend = out + (*outlen);
- const unsigned char* outstart = out;
- const unsigned char* instart = in;
- const unsigned char* inend = in + (*inlen);
- unsigned int c, d;
- int trailing;
-
- while (in < inend) {
- d = *in++;
- if (d < 0x80) { c= d; trailing= 0; }
- else if (d < 0xC0) {
- /* trailing byte in leading position */
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
- else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
- else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
- else {
- /* no chance for this in Ascii */
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- }
-
- if (inend - in < trailing)
- break;
-
- while (trailing--) {
- if (((d= *in++) & 0xC0) != 0x80) {
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- }
- c <<= 6;
- c |= d & 0x3F;
- }
-
- /* assertion: c is a single UTF-4 value */
- if (c < 0x80 && c != (unsigned int) quoteChar && c != '&' && c != '<' && c != '>') {
- if (out >= outend)
- break;
- *out++ = c;
- } else {
- docbEntityDescPtr ent;
- const char *cp;
- char nbuf[16];
- int len;
-
- /*
- * Try to lookup a predefined SGML entity for it
- */
- ent = docbEntityValueLookup(c);
- if (ent == NULL) {
- snprintf(nbuf, sizeof(nbuf), "#%u", c);
- cp = nbuf;
- }
- else
- cp = ent->name;
- len = strlen(cp);
- if (out + 2 + len > outend)
- break;
- *out++ = '&';
- memcpy(out, cp, len);
- out += len;
- *out++ = ';';
- }
- processed = in;
- }
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(0);
-}
-
-
-/************************************************************************
- * *
- * Commodity functions to handle streams *
- * *
- ************************************************************************/
-
-/**
- * docbNewInputStream:
- * @ctxt: an SGML parser context
- *
- * Create a new input stream structure
- * Returns the new input stream or NULL
- */
-static docbParserInputPtr
-docbNewInputStream(docbParserCtxtPtr ctxt) {
- docbParserInputPtr input;
-
- input = (xmlParserInputPtr) xmlMalloc(sizeof(docbParserInput));
- if (input == NULL) {
- ctxt->errNo = XML_ERR_NO_MEMORY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "malloc: couldn't allocate a new input stream\n");
- return(NULL);
- }
- memset(input, 0, sizeof(docbParserInput));
- input->filename = NULL;
- input->directory = NULL;
- input->base = NULL;
- input->cur = NULL;
- input->buf = NULL;
- input->line = 1;
- input->col = 1;
- input->buf = NULL;
- input->free = NULL;
- input->version = NULL;
- input->consumed = 0;
- input->length = 0;
- return(input);
-}
-
-
-/************************************************************************
- * *
- * Commodity functions, cleanup needed ? *
- * *
- ************************************************************************/
-
-/**
- * areBlanks:
- * @ctxt: an SGML parser context
- * @str: a xmlChar *
- * @len: the size of @str
- *
- * Is this a sequence of blank chars that one can ignore ?
- *
- * Returns 1 if ignorable 0 otherwise.
- */
-
-static int areBlanks(docbParserCtxtPtr ctxt, const xmlChar *str, int len) {
- int i;
- xmlNodePtr lastChild;
-
- for (i = 0;i < len;i++)
- if (!(IS_BLANK(str[i]))) return(0);
-
- if (CUR == 0) return(1);
- if (CUR != '<') return(0);
- if (ctxt->name == NULL)
- return(1);
- if (ctxt->node == NULL) return(0);
- lastChild = xmlGetLastChild(ctxt->node);
- if (lastChild == NULL) {
- if ((ctxt->node->type != XML_ELEMENT_NODE) &&
- (ctxt->node->content != NULL)) return(0);
- } else if (xmlNodeIsText(lastChild))
- return(0);
- return(1);
-}
-
-/************************************************************************
- * *
- * External entities support *
- * *
- ************************************************************************/
-
-/**
- * docbParseCtxtExternalEntity:
- * @ctx: the existing parsing context
- * @URL: the URL for the entity to load
- * @ID: the System ID for the entity to load
- * @list: the return value for the set of parsed nodes
- *
- * Parse an external general entity within an existing parsing context
- *
- * Returns 0 if the entity is well formed, -1 in case of args problem and
- * the parser error code otherwise
- */
-
-static int
-docbParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
- const xmlChar *ID, xmlNodePtr *list) {
- xmlParserCtxtPtr ctxt;
- xmlDocPtr newDoc;
- xmlSAXHandlerPtr oldsax = NULL;
- int ret = 0;
-
- if (ctx->depth > 40) {
- return(XML_ERR_ENTITY_LOOP);
- }
-
- if (list != NULL)
- *list = NULL;
- if ((URL == NULL) && (ID == NULL))
- return(-1);
- if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
- return(-1);
-
-
- ctxt = xmlCreateEntityParserCtxt(URL, ID, ctx->myDoc->URL);
- if (ctxt == NULL) return(-1);
- ctxt->userData = ctxt;
- oldsax = ctxt->sax;
- ctxt->sax = ctx->sax;
- newDoc = xmlNewDoc(BAD_CAST "1.0");
- if (newDoc == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(-1);
- }
- if (ctx->myDoc != NULL) {
- newDoc->intSubset = ctx->myDoc->intSubset;
- newDoc->extSubset = ctx->myDoc->extSubset;
- }
- if (ctx->myDoc->URL != NULL) {
- newDoc->URL = xmlStrdup(ctx->myDoc->URL);
- }
- newDoc->children = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
- if (newDoc->children == NULL) {
- ctxt->sax = oldsax;
- xmlFreeParserCtxt(ctxt);
- newDoc->intSubset = NULL;
- newDoc->extSubset = NULL;
- xmlFreeDoc(newDoc);
- return(-1);
- }
- nodePush(ctxt, newDoc->children);
- if (ctx->myDoc == NULL) {
- ctxt->myDoc = newDoc;
- } else {
- ctxt->myDoc = ctx->myDoc;
- newDoc->children->doc = ctx->myDoc;
- }
-
- /*
- * Parse a possible text declaration first
- */
- GROW;
- if ((RAW == '<') && (NXT(1) == '?') &&
- (NXT(2) == 'x') && (NXT(3) == 'm') &&
- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
- xmlParseTextDecl(ctxt);
- }
-
- /*
- * Doing validity checking on chunk doesn't make sense
- */
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->validate = ctx->validate;
- ctxt->loadsubset = ctx->loadsubset;
- ctxt->depth = ctx->depth + 1;
- ctxt->replaceEntities = ctx->replaceEntities;
- if (ctxt->validate) {
- ctxt->vctxt.error = ctx->vctxt.error;
- ctxt->vctxt.warning = ctx->vctxt.warning;
- /* Allocate the Node stack */
- ctxt->vctxt.nodeTab = (xmlNodePtr *) xmlMalloc(4 * sizeof(xmlNodePtr));
- if (ctxt->vctxt.nodeTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "docbParseCtxtExternalEntity: out of memory\n");
- ctxt->validate = 0;
- ctxt->vctxt.error = NULL;
- ctxt->vctxt.warning = NULL;
- } else {
- ctxt->vctxt.nodeNr = 0;
- ctxt->vctxt.nodeMax = 4;
- ctxt->vctxt.node = NULL;
- }
- } else {
- ctxt->vctxt.error = NULL;
- ctxt->vctxt.warning = NULL;
- }
-
- docbParseContent(ctxt);
-
- if ((RAW == '<') && (NXT(1) == '/')) {
- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "chunk is not well balanced\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else if (RAW != 0) {
- ctxt->errNo = XML_ERR_EXTRA_CONTENT;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "extra content at the end of well balanced chunk\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- if (ctxt->node != newDoc->children) {
- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "chunk is not well balanced\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
- if (!ctxt->wellFormed) {
- if (ctxt->errNo == 0)
- ret = 1;
- else
- ret = ctxt->errNo;
- } else {
- if (list != NULL) {
- xmlNodePtr cur;
-
- /*
- * Return the newly created nodeset after unlinking it from
- * they pseudo parent.
- */
- cur = newDoc->children->children;
- *list = cur;
- while (cur != NULL) {
- cur->parent = NULL;
- cur = cur->next;
- }
- newDoc->children->children = NULL;
- }
- ret = 0;
- }
- ctxt->sax = oldsax;
- xmlFreeParserCtxt(ctxt);
- newDoc->intSubset = NULL;
- newDoc->extSubset = NULL;
- xmlFreeDoc(newDoc);
-
- return(ret);
-}
-
-/************************************************************************
- * *
- * The parser itself *
- * *
- ************************************************************************/
-
-/**
- * docbParseSGMLName:
- * @ctxt: an SGML parser context
- *
- * parse an SGML tag or attribute name, note that we convert it to lowercase
- * since SGML names are not case-sensitive.
- *
- * Returns the Tag Name parsed or NULL
- */
-
-static xmlChar *
-docbParseSGMLName(docbParserCtxtPtr ctxt) {
- xmlChar *ret = NULL;
- int i = 0;
- xmlChar loc[DOCB_PARSER_BUFFER_SIZE];
-
- if (!IS_LETTER(CUR) && (CUR != '_') &&
- (CUR != ':')) return(NULL);
-
- while ((i < DOCB_PARSER_BUFFER_SIZE) &&
- ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
- (CUR == ':') || (CUR == '_'))) {
- if ((CUR >= 'A') && (CUR <= 'Z')) loc[i] = CUR + 0x20;
- else loc[i] = CUR;
- i++;
-
- NEXT;
- }
-
- ret = xmlStrndup(loc, i);
-
- return(ret);
-}
-
-/**
- * docbParseName:
- * @ctxt: an SGML parser context
- *
- * parse an SGML name, this routine is case sensitive.
- *
- * Returns the Name parsed or NULL
- */
-
-static xmlChar *
-docbParseName(docbParserCtxtPtr ctxt) {
- xmlChar buf[DOCB_MAX_NAMELEN];
- int len = 0;
-
- GROW;
- if (!IS_LETTER(CUR) && (CUR != '_')) {
- return(NULL);
- }
-
- while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
- (CUR == '.') || (CUR == '-') ||
- (CUR == '_') || (CUR == ':') ||
- (IS_COMBINING(CUR)) ||
- (IS_EXTENDER(CUR))) {
- buf[len++] = CUR;
- NEXT;
- if (len >= DOCB_MAX_NAMELEN) {
- xmlGenericError(xmlGenericErrorContext,
- "docbParseName: reached DOCB_MAX_NAMELEN limit\n");
- while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
- (CUR == '.') || (CUR == '-') ||
- (CUR == '_') || (CUR == ':') ||
- (IS_COMBINING(CUR)) ||
- (IS_EXTENDER(CUR)))
- NEXT;
- break;
- }
- }
- return(xmlStrndup(buf, len));
-}
-
-/**
- * docbParseSGMLAttribute:
- * @ctxt: an SGML parser context
- * @stop: a char stop value
- *
- * parse an SGML attribute value till the stop (quote), if
- * stop is 0 then it stops at the first space
- *
- * Returns the attribute parsed or NULL
- */
-
-static xmlChar *
-docbParseSGMLAttribute(docbParserCtxtPtr ctxt, const xmlChar stop) {
- xmlChar *buffer = NULL;
- int buffer_size = 0;
- xmlChar *out = NULL;
- xmlChar *name = NULL;
-
- xmlChar *cur = NULL;
- xmlEntityPtr xent;
- docbEntityDescPtr ent;
-
- /*
- * allocate a translation buffer.
- */
- buffer_size = DOCB_PARSER_BIG_BUFFER_SIZE;
- buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
- if (buffer == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "docbParseSGMLAttribute: malloc failed");
- return(NULL);
- }
- out = buffer;
-
- /*
- * Ok loop until we reach one of the ending chars
- */
- while ((CUR != 0) && (CUR != stop) && (CUR != '>')) {
- if ((stop == 0) && (IS_BLANK(CUR))) break;
- if (CUR == '&') {
- if (NXT(1) == '#') {
- unsigned int c;
- int bits;
-
- c = docbParseCharRef(ctxt);
- if (c < 0x80)
- { *out++ = c; bits= -6; }
- else if (c < 0x800)
- { *out++ =((c >> 6) & 0x1F) | 0xC0; bits= 0; }
- else if (c < 0x10000)
- { *out++ =((c >> 12) & 0x0F) | 0xE0; bits= 6; }
- else
- { *out++ =((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
- for ( ; bits >= 0; bits-= 6) {
- *out++ = ((c >> bits) & 0x3F) | 0x80;
- }
- } else {
- xent = docbParseEntityRef(ctxt, &name);
- if (name == NULL) {
- *out++ = '&';
- if (out - buffer > buffer_size - 100) {
- int indx = out - buffer;
-
- growBuffer(buffer);
- out = &buffer[indx];
- }
- *out++ = '&';
- } else {
- ent = docbEntityLookup(name);
- if (ent == NULL) {
- *out++ = '&';
- cur = name;
- while (*cur != 0) {
- if (out - buffer > buffer_size - 100) {
- int indx = out - buffer;
-
- growBuffer(buffer);
- out = &buffer[indx];
- }
- *out++ = *cur++;
- }
- xmlFree(name);
- } else {
- unsigned int c;
- int bits;
-
- if (out - buffer > buffer_size - 100) {
- int indx = out - buffer;
-
- growBuffer(buffer);
- out = &buffer[indx];
- }
- c = (xmlChar)ent->value;
- if (c < 0x80)
- { *out++ = c; bits= -6; }
- else if (c < 0x800)
- { *out++ =((c >> 6) & 0x1F) | 0xC0; bits= 0; }
- else if (c < 0x10000)
- { *out++ =((c >> 12) & 0x0F) | 0xE0; bits= 6; }
- else
- { *out++ =((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
- for ( ; bits >= 0; bits-= 6) {
- *out++ = ((c >> bits) & 0x3F) | 0x80;
- }
- xmlFree(name);
- }
- }
- }
- } else {
- unsigned int c;
- int bits;
-
- if (out - buffer > buffer_size - 100) {
- int indx = out - buffer;
-
- growBuffer(buffer);
- out = &buffer[indx];
- }
- c = CUR;
- if (c < 0x80)
- { *out++ = c; bits= -6; }
- else if (c < 0x800)
- { *out++ =((c >> 6) & 0x1F) | 0xC0; bits= 0; }
- else if (c < 0x10000)
- { *out++ =((c >> 12) & 0x0F) | 0xE0; bits= 6; }
- else
- { *out++ =((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
- for ( ; bits >= 0; bits-= 6) {
- *out++ = ((c >> bits) & 0x3F) | 0x80;
- }
- NEXT;
- }
- }
- *out++ = 0;
- return(buffer);
-}
-
-
-/**
- * docbParseEntityRef:
- * @ctxt: an SGML parser context
- * @str: location to store the entity name
- *
- * parse an SGML ENTITY references
- *
- * [68] EntityRef ::= '&' Name ';'
- *
- * Returns the associated xmlEntityPtr if found, or NULL otherwise,
- * if non-NULL *str will have to be freed by the caller.
- */
-static xmlEntityPtr
-docbParseEntityRef(docbParserCtxtPtr ctxt, xmlChar **str) {
- xmlChar *name;
- xmlEntityPtr ent = NULL;
- *str = NULL;
-
- if (CUR == '&') {
- NEXT;
- name = docbParseName(ctxt);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "docbParseEntityRef: no name\n");
- ctxt->wellFormed = 0;
- } else {
- GROW;
- if (CUR == ';') {
- *str = name;
-
- /*
- * Ask first SAX for entity resolution, otherwise try the
- * predefined set.
- */
- if (ctxt->sax != NULL) {
- if (ctxt->sax->getEntity != NULL)
- ent = ctxt->sax->getEntity(ctxt->userData, name);
- if (ent == NULL)
- ent = xmlGetPredefinedEntity(name);
- }
- NEXT;
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "docbParseEntityRef: expecting ';'\n");
- *str = name;
- }
- }
- }
- return(ent);
-}
-
-/**
- * docbParseAttValue:
- * @ctxt: an SGML parser context
- *
- * parse a value for an attribute
- * Note: the parser won't do substitution of entities here, this
- * will be handled later in xmlStringGetNodeList, unless it was
- * asked for ctxt->replaceEntities != 0
- *
- * Returns the AttValue parsed or NULL.
- */
-
-static xmlChar *
-docbParseAttValue(docbParserCtxtPtr ctxt) {
- xmlChar *ret = NULL;
-
- if (CUR == '"') {
- NEXT;
- ret = docbParseSGMLAttribute(ctxt, '"');
- if (CUR != '"') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "AttValue: ' expected\n");
- ctxt->wellFormed = 0;
- } else
- NEXT;
- } else if (CUR == '\'') {
- NEXT;
- ret = docbParseSGMLAttribute(ctxt, '\'');
- if (CUR != '\'') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "AttValue: ' expected\n");
- ctxt->wellFormed = 0;
- } else
- NEXT;
- } else {
- /*
- * That's an SGMLism, the attribute value may not be quoted
- */
- ret = docbParseSGMLAttribute(ctxt, 0);
- if (ret == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "AttValue: no value found\n");
- ctxt->wellFormed = 0;
- }
- }
- return(ret);
-}
-
-/**
- * docbParseSystemLiteral:
- * @ctxt: an SGML parser context
- *
- * parse an SGML Literal
- *
- * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
- *
- * Returns the SystemLiteral parsed or NULL
- */
-
-static xmlChar *
-docbParseSystemLiteral(docbParserCtxtPtr ctxt) {
- const xmlChar *q;
- xmlChar *ret = NULL;
-
- if (CUR == '"') {
- NEXT;
- q = CUR_PTR;
- while ((IS_CHAR(CUR)) && (CUR != '"'))
- NEXT;
- if (!IS_CHAR(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Unfinished SystemLiteral\n");
- ctxt->wellFormed = 0;
- } else {
- ret = xmlStrndup(q, CUR_PTR - q);
- NEXT;
- }
- } else if (CUR == '\'') {
- NEXT;
- q = CUR_PTR;
- while ((IS_CHAR(CUR)) && (CUR != '\''))
- NEXT;
- if (!IS_CHAR(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Unfinished SystemLiteral\n");
- ctxt->wellFormed = 0;
- } else {
- ret = xmlStrndup(q, CUR_PTR - q);
- NEXT;
- }
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "SystemLiteral \" or ' expected\n");
- ctxt->wellFormed = 0;
- }
-
- return(ret);
-}
-
-/**
- * docbParsePubidLiteral:
- * @ctxt: an SGML parser context
- *
- * parse an SGML public literal
- *
- * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
- *
- * Returns the PubidLiteral parsed or NULL.
- */
-
-static xmlChar *
-docbParsePubidLiteral(docbParserCtxtPtr ctxt) {
- const xmlChar *q;
- xmlChar *ret = NULL;
- /*
- * Name ::= (Letter | '_') (NameChar)*
- */
- if (CUR == '"') {
- NEXT;
- q = CUR_PTR;
- while (IS_PUBIDCHAR(CUR)) NEXT;
- if (CUR != '"') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Unfinished PubidLiteral\n");
- ctxt->wellFormed = 0;
- } else {
- ret = xmlStrndup(q, CUR_PTR - q);
- NEXT;
- }
- } else if (CUR == '\'') {
- NEXT;
- q = CUR_PTR;
- while ((IS_LETTER(CUR)) && (CUR != '\''))
- NEXT;
- if (!IS_LETTER(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Unfinished PubidLiteral\n");
- ctxt->wellFormed = 0;
- } else {
- ret = xmlStrndup(q, CUR_PTR - q);
- NEXT;
- }
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "SystemLiteral \" or ' expected\n");
- ctxt->wellFormed = 0;
- }
-
- return(ret);
-}
-
-/**
- * docbParseCharData:
- * @ctxt: an SGML parser context
- * @cdata: int indicating whether we are within a CDATA section
- *
- * parse a CharData section.
- * if we are within a CDATA section ']]>' marks an end of section.
- *
- * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
- */
-
-static void
-docbParseCharData(docbParserCtxtPtr ctxt) {
- xmlChar buf[DOCB_PARSER_BIG_BUFFER_SIZE + 5];
- int nbchar = 0;
- int cur, l;
-
- SHRINK;
- cur = CUR_CHAR(l);
- while (((cur != '<') || (ctxt->token == '<')) &&
- ((cur != '&') || (ctxt->token == '&')) &&
- (IS_CHAR(cur))) {
- COPY_BUF(l,buf,nbchar,cur);
- if (nbchar >= DOCB_PARSER_BIG_BUFFER_SIZE) {
- /*
- * Ok the segment is to be consumed as chars.
- */
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
- if (areBlanks(ctxt, buf, nbchar)) {
- if (ctxt->sax->ignorableWhitespace != NULL)
- ctxt->sax->ignorableWhitespace(ctxt->userData,
- buf, nbchar);
- } else {
- if (ctxt->sax->characters != NULL)
- ctxt->sax->characters(ctxt->userData, buf, nbchar);
- }
- }
- nbchar = 0;
- }
- NEXTL(l);
- cur = CUR_CHAR(l);
- }
- if (nbchar != 0) {
- /*
- * Ok the segment is to be consumed as chars.
- */
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
- if (areBlanks(ctxt, buf, nbchar)) {
- if (ctxt->sax->ignorableWhitespace != NULL)
- ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
- } else {
- if (ctxt->sax->characters != NULL)
- ctxt->sax->characters(ctxt->userData, buf, nbchar);
- }
- }
- }
-}
-
-/**
- * docbParseExternalID:
- * @ctxt: an SGML parser context
- * @publicID: a xmlChar** receiving PubidLiteral
- *
- * Parse an External ID or a Public ID
- *
- * Returns the function returns SystemLiteral and in the second
- * case publicID receives PubidLiteral,
- * it is possible to return NULL and have publicID set.
- */
-
-static xmlChar *
-docbParseExternalID(docbParserCtxtPtr ctxt, xmlChar **publicID) {
- xmlChar *URI = NULL;
-
- if ((UPPER == 'S') && (UPP(1) == 'Y') &&
- (UPP(2) == 'S') && (UPP(3) == 'T') &&
- (UPP(4) == 'E') && (UPP(5) == 'M')) {
- SKIP(6);
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after 'SYSTEM'\n");
- ctxt->wellFormed = 0;
- }
- SKIP_BLANKS;
- URI = docbParseSystemLiteral(ctxt);
- if (URI == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "docbParseExternalID: SYSTEM, no URI\n");
- ctxt->wellFormed = 0;
- }
- } else if ((UPPER == 'P') && (UPP(1) == 'U') &&
- (UPP(2) == 'B') && (UPP(3) == 'L') &&
- (UPP(4) == 'I') && (UPP(5) == 'C')) {
- SKIP(6);
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after 'PUBLIC'\n");
- ctxt->wellFormed = 0;
- }
- SKIP_BLANKS;
- *publicID = docbParsePubidLiteral(ctxt);
- if (*publicID == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "docbParseExternalID: PUBLIC, no Public Identifier\n");
- ctxt->wellFormed = 0;
- }
- SKIP_BLANKS;
- if ((CUR == '"') || (CUR == '\'')) {
- URI = docbParseSystemLiteral(ctxt);
- }
- }
- return(URI);
-}
-
-/**
- * docbParsePI:
- * @ctxt: an XML parser context
- *
- * parse an XML Processing Instruction.
- *
- * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
- *
- * The processing is transfered to SAX once parsed.
- */
-
-static void
-docbParsePI(xmlParserCtxtPtr ctxt) {
- xmlChar *buf = NULL;
- int len = 0;
- int size = DOCB_PARSER_BUFFER_SIZE;
- int cur, l;
- xmlChar *target;
- xmlParserInputState state;
- int count = 0;
-
- if ((RAW == '<') && (NXT(1) == '?')) {
- xmlParserInputPtr input = ctxt->input;
- state = ctxt->instate;
- ctxt->instate = XML_PARSER_PI;
- /*
- * this is a Processing Instruction.
- */
- SKIP(2);
- SHRINK;
-
- /*
- * Parse the target name and check for special support like
- * namespace.
- */
- target = xmlParseName(ctxt);
- if (target != NULL) {
- xmlChar *encoding = NULL;
-
- if ((RAW == '?') && (NXT(1) == '>')) {
- if (input != ctxt->input) {
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "PI declaration doesn't start and stop in the same entity\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP(2);
-
- /*
- * SAX: PI detected.
- */
- if ((ctxt->sax) && (!ctxt->disableSAX) &&
- (ctxt->sax->processingInstruction != NULL))
- ctxt->sax->processingInstruction(ctxt->userData,
- target, NULL);
- ctxt->instate = state;
- xmlFree(target);
- return;
- }
- if (xmlStrEqual(target, BAD_CAST "sgml-declaration")) {
-
- encoding = xmlParseEncodingDecl(ctxt);
- if (encoding == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "sgml-declaration: failed to find/handle encoding\n");
-#ifdef DEBUG
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "switched to encoding %s\n", encoding);
-#endif
- }
-
- }
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %d byte failed\n", size);
- ctxt->instate = state;
- return;
- }
- cur = CUR;
- if (encoding != NULL) {
- len = snprintf((char *) buf, size - 1,
- " encoding = \"%s\"", encoding);
- if (len < 0)
- len = size;
- } else {
- if (!IS_BLANK(cur)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "docbParsePI: PI %s space expected\n", target);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- }
- cur = CUR_CHAR(l);
- while (IS_CHAR(cur) && /* checked */
- ((cur != '?') || (NXT(1) != '>'))) {
- if (len + 5 >= size) {
- size *= 2;
- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc of %d byte failed\n", size);
- ctxt->instate = state;
- return;
- }
- }
- count++;
- if (count > 50) {
- GROW;
- count = 0;
- }
- COPY_BUF(l,buf,len,cur);
- NEXTL(l);
- cur = CUR_CHAR(l);
- if (cur == 0) {
- SHRINK;
- GROW;
- cur = CUR_CHAR(l);
- }
- }
- buf[len] = 0;
- if (cur != '?') {
- ctxt->errNo = XML_ERR_PI_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "docbParsePI: PI %s never end ...\n", target);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- if (input != ctxt->input) {
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "PI declaration doesn't start and stop in the same entity\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP(2);
-
- /*
- * SAX: PI detected.
- */
- if ((ctxt->sax) && (!ctxt->disableSAX) &&
- (ctxt->sax->processingInstruction != NULL))
- ctxt->sax->processingInstruction(ctxt->userData,
- target, buf);
- }
- xmlFree(buf);
- xmlFree(target);
- } else {
- ctxt->errNo = XML_ERR_PI_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "docbParsePI : no target name\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- ctxt->instate = state;
- }
-}
-
-/**
- * docbParseComment:
- * @ctxt: an SGML parser context
- *
- * Parse an XML (SGML) comment <!-- .... -->
- *
- * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
- */
-static void
-docbParseComment(docbParserCtxtPtr ctxt) {
- xmlChar *buf = NULL;
- int len;
- int size = DOCB_PARSER_BUFFER_SIZE;
- int q, ql;
- int r, rl;
- int cur, l;
- xmlParserInputState state;
-
- /*
- * Check that there is a comment right here.
- */
- if ((RAW != '<') || (NXT(1) != '!') ||
- (NXT(2) != '-') || (NXT(3) != '-')) return;
-
- state = ctxt->instate;
- ctxt->instate = XML_PARSER_COMMENT;
- SHRINK;
- SKIP(4);
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %d byte failed\n", size);
- ctxt->instate = state;
- return;
- }
- q = CUR_CHAR(ql);
- NEXTL(ql);
- r = CUR_CHAR(rl);
- NEXTL(rl);
- cur = CUR_CHAR(l);
- len = 0;
- while (IS_CHAR(cur) &&
- ((cur != '>') ||
- (r != '-') || (q != '-'))) {
- if (len + 5 >= size) {
- size *= 2;
- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc of %d byte failed\n", size);
- ctxt->instate = state;
- return;
- }
- }
- COPY_BUF(ql,buf,len,q);
- q = r;
- ql = rl;
- r = cur;
- rl = l;
- NEXTL(l);
- cur = CUR_CHAR(l);
- if (cur == 0) {
- SHRINK;
- GROW;
- cur = CUR_CHAR(l);
- }
- }
- buf[len] = 0;
- if (!IS_CHAR(cur)) {
- ctxt->errNo = XML_ERR_COMMENT_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Comment not terminated \n<!--%.50s\n", buf);
- ctxt->wellFormed = 0;
- xmlFree(buf);
- } else {
- NEXT;
- if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->comment(ctxt->userData, buf);
- xmlFree(buf);
- }
- ctxt->instate = state;
-}
-
-/**
- * docbParseCharRef:
- * @ctxt: an SGML parser context
- *
- * parse Reference declarations
- *
- * [66] CharRef ::= '&#' [0-9]+ ';' |
- * '&#x' [0-9a-fA-F]+ ';'
- *
- * Returns the value parsed (as an int)
- */
-static int
-docbParseCharRef(docbParserCtxtPtr ctxt) {
- int val = 0;
-
- if ((CUR == '&') && (NXT(1) == '#') &&
- (NXT(2) == 'x')) {
- SKIP(3);
- while (CUR != ';') {
- if ((CUR >= '0') && (CUR <= '9'))
- val = val * 16 + (CUR - '0');
- else if ((CUR >= 'a') && (CUR <= 'f'))
- val = val * 16 + (CUR - 'a') + 10;
- else if ((CUR >= 'A') && (CUR <= 'F'))
- val = val * 16 + (CUR - 'A') + 10;
- else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "docbParseCharRef: invalid hexadecimal value\n");
- ctxt->wellFormed = 0;
- val = 0;
- break;
- }
- NEXT;
- }
- if (CUR == ';')
- NEXT;
- } else if ((CUR == '&') && (NXT(1) == '#')) {
- SKIP(2);
- while (CUR != ';') {
- if ((CUR >= '0') && (CUR <= '9'))
- val = val * 10 + (CUR - '0');
- else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "docbParseCharRef: invalid decimal value\n");
- ctxt->wellFormed = 0;
- val = 0;
- break;
- }
- NEXT;
- }
- if (CUR == ';')
- NEXT;
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "docbParseCharRef: invalid value\n");
- ctxt->wellFormed = 0;
- }
- /*
- * Check the value IS_CHAR ...
- */
- if (IS_CHAR(val)) {
- return(val);
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "docbParseCharRef: invalid xmlChar value %d\n",
- val);
- ctxt->wellFormed = 0;
- }
- return(0);
-}
-
-
-/**
- * docbParseDocTypeDecl:
- * @ctxt: an SGML parser context
- *
- * parse a DOCTYPE declaration
- *
- * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
- * ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
- */
-
-static void
-docbParseDocTypeDecl(docbParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlChar *ExternalID = NULL;
- xmlChar *URI = NULL;
-
- /*
- * We know that '<!DOCTYPE' has been detected.
- */
- SKIP(9);
-
- SKIP_BLANKS;
-
- /*
- * Parse the DOCTYPE name.
- */
- name = docbParseName(ctxt);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "docbParseDocTypeDecl : no DOCTYPE name !\n");
- ctxt->wellFormed = 0;
- }
- /*
- * Check that upper(name) == "SGML" !!!!!!!!!!!!!
- */
-
- SKIP_BLANKS;
-
- /*
- * Check for SystemID and ExternalID
- */
- URI = docbParseExternalID(ctxt, &ExternalID);
- SKIP_BLANKS;
-
- /*
- * Create or update the document accordingly to the DOCTYPE
- * But use the predefined PUBLIC and SYSTEM ID of DocBook XML
- */
- if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->internalSubset(ctxt->userData, name,
- XML_DOCBOOK_XML_PUBLIC,
- XML_DOCBOOK_XML_SYSTEM);
-
- if (RAW != '>') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "docbParseDocTypeDecl : internal subset not handled\n");
- } else {
- NEXT;
- }
-
- /*
- * Cleanup, since we don't use all those identifiers
- */
- if (URI != NULL) xmlFree(URI);
- if (ExternalID != NULL) xmlFree(ExternalID);
- if (name != NULL) xmlFree(name);
-}
-
-/**
- * docbParseAttribute:
- * @ctxt: an SGML parser context
- * @value: a xmlChar ** used to store the value of the attribute
- *
- * parse an attribute
- *
- * [41] Attribute ::= Name Eq AttValue
- *
- * [25] Eq ::= S? '=' S?
- *
- * With namespace:
- *
- * [NS 11] Attribute ::= QName Eq AttValue
- *
- * Also the case QName == xmlns:??? is handled independently as a namespace
- * definition.
- *
- * Returns the attribute name, and the value in *value.
- */
-
-static xmlChar *
-docbParseAttribute(docbParserCtxtPtr ctxt, xmlChar **value) {
- xmlChar *name, *val = NULL;
-
- *value = NULL;
- name = docbParseName(ctxt);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "error parsing attribute name\n");
- ctxt->wellFormed = 0;
- return(NULL);
- }
-
- /*
- * read the value
- */
- SKIP_BLANKS;
- if (CUR == '=') {
- NEXT;
- SKIP_BLANKS;
- val = docbParseAttValue(ctxt);
- /******
- } else {
- * TODO : some attribute must have values, some may not
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->warning(ctxt->userData,
- "No value for attribute %s\n", name); */
- }
-
- *value = val;
- return(name);
-}
-
-/**
- * docbCheckEncoding:
- * @ctxt: an SGML parser context
- * @attvalue: the attribute value
- *
- * Checks an http-equiv attribute from a Meta tag to detect
- * the encoding
- * If a new encoding is detected the parser is switched to decode
- * it and pass UTF8
- */
-static void
-docbCheckEncoding(docbParserCtxtPtr ctxt, const xmlChar *attvalue) {
- const xmlChar *encoding;
-
- if ((ctxt == NULL) || (attvalue == NULL))
- return;
-
- encoding = xmlStrstr(attvalue, BAD_CAST"charset=");
- if (encoding == NULL)
- encoding = xmlStrstr(attvalue, BAD_CAST"Charset=");
- if (encoding == NULL)
- encoding = xmlStrstr(attvalue, BAD_CAST"CHARSET=");
- if (encoding != NULL) {
- encoding += 8;
- } else {
- encoding = xmlStrstr(attvalue, BAD_CAST"charset =");
- if (encoding == NULL)
- encoding = xmlStrstr(attvalue, BAD_CAST"Charset =");
- if (encoding == NULL)
- encoding = xmlStrstr(attvalue, BAD_CAST"CHARSET =");
- if (encoding != NULL)
- encoding += 9;
- }
- /*
- * Restricted from 2.3.5 */
- if (encoding != NULL) {
- xmlCharEncoding enc;
-
- if (ctxt->input->encoding != NULL)
- xmlFree((xmlChar *) ctxt->input->encoding);
- ctxt->input->encoding = encoding;
-
- enc = xmlParseCharEncoding((const char *) encoding);
- if (enc == XML_CHAR_ENCODING_8859_1) {
- ctxt->charset = XML_CHAR_ENCODING_8859_1;
- } else if (enc != XML_CHAR_ENCODING_UTF8) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Unsupported encoding %s\n", encoding);
- /* xmlFree(encoding); */
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
- }
- }
-}
-
-/**
- * docbCheckMeta:
- * @ctxt: an SGML parser context
- * @atts: the attributes values
- *
- * Checks an attributes from a Meta tag
- */
-static void
-docbCheckMeta(docbParserCtxtPtr ctxt, const xmlChar **atts) {
- int i;
- const xmlChar *att, *value;
- int http = 0;
- const xmlChar *content = NULL;
-
- if ((ctxt == NULL) || (atts == NULL))
- return;
-
- i = 0;
- att = atts[i++];
- while (att != NULL) {
- value = atts[i++];
- if ((value != NULL) &&
- ((xmlStrEqual(att, BAD_CAST"http-equiv")) ||
- (xmlStrEqual(att, BAD_CAST"Http-Equiv")) ||
- (xmlStrEqual(att, BAD_CAST"HTTP-EQUIV"))) &&
- ((xmlStrEqual(value, BAD_CAST"Content-Type")) ||
- (xmlStrEqual(value, BAD_CAST"content-type")) ||
- (xmlStrEqual(value, BAD_CAST"CONTENT-TYPE"))))
- http = 1;
- else if ((value != NULL) &&
- ((xmlStrEqual(att, BAD_CAST"content")) ||
- (xmlStrEqual(att, BAD_CAST"Content")) ||
- (xmlStrEqual(att, BAD_CAST"CONTENT"))))
- content = value;
- att = atts[i++];
- }
- if ((http) && (content != NULL))
- docbCheckEncoding(ctxt, content);
-
-}
-
-/**
- * docbParseStartTag:
- * @ctxt: an SGML parser context
- *
- * parse a start of tag either for rule element or
- * EmptyElement. In both case we don't parse the tag closing chars.
- *
- * [40] STag ::= '<' Name (S Attribute)* S? '>'
- *
- * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
- *
- * With namespace:
- *
- * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
- *
- * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
- *
- */
-
-static void
-docbParseStartTag(docbParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlChar *attname;
- xmlChar *attvalue;
- const xmlChar **atts = NULL;
- int nbatts = 0;
- int maxatts = 0;
- int meta = 0;
- int i;
-
- if (CUR != '<') return;
- NEXT;
-
- GROW;
- name = docbParseSGMLName(ctxt);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "docbParseStartTag: invalid element name\n");
- ctxt->wellFormed = 0;
- return;
- }
- if (xmlStrEqual(name, BAD_CAST"meta"))
- meta = 1;
-
- /*
- * Check for auto-closure of SGML elements.
- */
- docbAutoClose(ctxt, name);
-
- /*
- * Now parse the attributes, it ends up with the ending
- *
- * (S Attribute)* S?
- */
- SKIP_BLANKS;
- while ((IS_CHAR(CUR)) &&
- (CUR != '>') &&
- ((CUR != '/') || (NXT(1) != '>'))) {
- long cons = ctxt->nbChars;
-
- GROW;
- attname = docbParseAttribute(ctxt, &attvalue);
- if (attname != NULL) {
-
- /*
- * Well formedness requires at most one declaration of an attribute
- */
- for (i = 0; i < nbatts;i += 2) {
- if (xmlStrEqual(atts[i], attname)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Attribute %s redefined\n",
- attname);
- ctxt->wellFormed = 0;
- xmlFree(attname);
- if (attvalue != NULL)
- xmlFree(attvalue);
- goto failed;
- }
- }
-
- /*
- * Add the pair to atts
- */
- if (atts == NULL) {
- maxatts = 10;
- atts = (const xmlChar **) xmlMalloc(maxatts * sizeof(xmlChar *));
- if (atts == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %ld byte failed\n",
- maxatts * (long)sizeof(xmlChar *));
- if (name != NULL) xmlFree(name);
- return;
- }
- } else if (nbatts + 4 > maxatts) {
- maxatts *= 2;
- atts = (const xmlChar **) xmlRealloc((void *)atts, maxatts * sizeof(xmlChar *));
- if (atts == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc of %ld byte failed\n",
- maxatts * (long)sizeof(xmlChar *));
- if (name != NULL) xmlFree(name);
- return;
- }
- }
- atts[nbatts++] = attname;
- atts[nbatts++] = attvalue;
- atts[nbatts] = NULL;
- atts[nbatts + 1] = NULL;
- }
-
-failed:
- SKIP_BLANKS;
- if (cons == ctxt->nbChars) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "docbParseStartTag: problem parsing attributes\n");
- ctxt->wellFormed = 0;
- break;
- }
- }
-
- /*
- * Handle specific association to the META tag
- */
- if (meta)
- docbCheckMeta(ctxt, atts);
-
- /*
- * SAX: Start of Element !
- */
- docbnamePush(ctxt, xmlStrdup(name));
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"Start of element %s: pushed %s\n", name, ctxt->name);
-#endif
- if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
- ctxt->sax->startElement(ctxt->userData, name, atts);
-
- if (atts != NULL) {
- for (i = 0;i < nbatts;i++) {
- if (atts[i] != NULL)
- xmlFree((xmlChar *) atts[i]);
- }
- xmlFree((void *) atts);
- }
- if (name != NULL) xmlFree(name);
-}
-
-/**
- * docbParseEndTag:
- * @ctxt: an SGML parser context
- *
- * parse an end of tag
- *
- * [42] ETag ::= '</' Name S? '>'
- *
- * With namespace
- *
- * [NS 9] ETag ::= '</' QName S? '>'
- */
-
-static void
-docbParseEndTag(docbParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlChar *oldname;
- int i;
-
- if ((CUR != '<') || (NXT(1) != '/')) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "docbParseEndTag: '</' not found\n");
- ctxt->wellFormed = 0;
- return;
- }
- SKIP(2);
-
- name = docbParseSGMLName(ctxt);
- if (name == NULL) {
- if (CUR == '>') {
- NEXT;
- oldname = docbnamePop(ctxt);
- if (oldname != NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
- ctxt->sax->endElement(ctxt->userData, name);
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"End of tag </>: popping out %s\n", oldname);
-#endif
- xmlFree(oldname);
-#ifdef DEBUG
- } else {
- xmlGenericError(xmlGenericErrorContext,"End of tag </>: stack empty !!!\n");
-#endif
- }
- return;
- } else
- return;
- }
-
- /*
- * We should definitely be at the ending "S? '>'" part
- */
- SKIP_BLANKS;
- if ((!IS_CHAR(CUR)) || (CUR != '>')) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "End tag : expected '>'\n");
- ctxt->wellFormed = 0;
- } else
- NEXT;
-
- /*
- * If the name read is not one of the element in the parsing stack
- * then return, it's just an error.
- */
- for (i = (ctxt->nameNr - 1);i >= 0;i--) {
- if (xmlStrEqual(name, ctxt->nameTab[i])) break;
- }
- if (i < 0) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Unexpected end tag : %s\n", name);
- xmlFree(name);
- ctxt->wellFormed = 0;
- return;
- }
-
-
- /*
- * Check for auto-closure of SGML elements.
- */
-
- docbAutoCloseOnClose(ctxt, name);
-
- /*
- * Well formedness constraints, opening and closing must match.
- * With the exception that the autoclose may have popped stuff out
- * of the stack.
- */
- if (((name[0] != '/') || (name[1] != 0)) &&
- (!xmlStrEqual(name, ctxt->name))) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"End of tag %s: expecting %s\n", name, ctxt->name);
-#endif
- if ((ctxt->name != NULL) &&
- (!xmlStrEqual(ctxt->name, name))) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Opening and ending tag mismatch: %s and %s\n",
- name, ctxt->name);
- ctxt->wellFormed = 0;
- }
- }
-
- /*
- * SAX: End of Tag
- */
- oldname = ctxt->name;
- if (((name[0] == '/') && (name[1] == 0)) ||
- ((oldname != NULL) && (xmlStrEqual(oldname, name)))) {
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
- ctxt->sax->endElement(ctxt->userData, name);
- oldname = docbnamePop(ctxt);
- if (oldname != NULL) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"End of tag %s: popping out %s\n", name, oldname);
-#endif
- xmlFree(oldname);
-#ifdef DEBUG
- } else {
- xmlGenericError(xmlGenericErrorContext,"End of tag %s: stack empty !!!\n", name);
-#endif
- }
- }
-
- if (name != NULL)
- xmlFree(name);
-
- return;
-}
-
-
-/**
- * docbParseReference:
- * @ctxt: an SGML parser context
- *
- * parse and handle entity references in content,
- * this will end-up in a call to character() since this is either a
- * CharRef, or a predefined entity.
- */
-static void
-docbParseReference(docbParserCtxtPtr ctxt) {
- docbEntityDescPtr ent;
- xmlEntityPtr xent;
- xmlChar out[6];
- xmlChar *name;
- if (CUR != '&') return;
-
- if (NXT(1) == '#') {
- unsigned int c;
- int bits, i = 0;
-
- c = docbParseCharRef(ctxt);
- if (c < 0x80) { out[i++]= c; bits= -6; }
- else if (c < 0x800) { out[i++]=((c >> 6) & 0x1F) | 0xC0; bits= 0; }
- else if (c < 0x10000) { out[i++]=((c >> 12) & 0x0F) | 0xE0; bits= 6; }
- else { out[i++]=((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
- for ( ; bits >= 0; bits-= 6) {
- out[i++]= ((c >> bits) & 0x3F) | 0x80;
- }
- out[i] = 0;
-
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
- ctxt->sax->characters(ctxt->userData, out, i);
- } else {
- /*
- * Lookup the entity in the table.
- */
- xent = docbParseEntityRef(ctxt, &name);
- if (xent != NULL) {
- if (((ctxt->replaceEntities) || (ctxt->loadsubset)) &&
- ((xent->children == NULL) &&
- (xent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))) {
- /*
- * we really need to fetch and parse the external entity
- */
- int parse;
- xmlNodePtr children = NULL;
-
- parse = docbParseCtxtExternalEntity(ctxt,
- xent->SystemID, xent->ExternalID, &children);
- xmlAddChildList((xmlNodePtr) xent, children);
- }
- if (ctxt->replaceEntities) {
- if ((ctxt->node != NULL) && (xent->children != NULL)) {
- /*
- * Seems we are generating the DOM content, do
- * a simple tree copy
- */
- xmlNodePtr new;
- new = xmlCopyNodeList(xent->children);
-
- xmlAddChildList(ctxt->node, new);
- /*
- * This is to avoid a nasty side effect, see
- * characters() in SAX.c
- */
- ctxt->nodemem = 0;
- ctxt->nodelen = 0;
- }
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
- (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
- /*
- * Create a node.
- */
- ctxt->sax->reference(ctxt->userData, xent->name);
- }
- }
- } else if (name != NULL) {
- ent = docbEntityLookup(name);
- if ((ent == NULL) || (ent->value <= 0)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL)) {
- ctxt->sax->characters(ctxt->userData, BAD_CAST "&", 1);
- ctxt->sax->characters(ctxt->userData, name, xmlStrlen(name));
- /* ctxt->sax->characters(ctxt->userData, BAD_CAST ";", 1); */
- }
- } else {
- unsigned int c;
- int bits, i = 0;
-
- c = ent->value;
- if (c < 0x80)
- { out[i++]= c; bits= -6; }
- else if (c < 0x800)
- { out[i++]=((c >> 6) & 0x1F) | 0xC0; bits= 0; }
- else if (c < 0x10000)
- { out[i++]=((c >> 12) & 0x0F) | 0xE0; bits= 6; }
- else
- { out[i++]=((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
- for ( ; bits >= 0; bits-= 6) {
- out[i++]= ((c >> bits) & 0x3F) | 0x80;
- }
- out[i] = 0;
-
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
- ctxt->sax->characters(ctxt->userData, out, i);
- }
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
- ctxt->sax->characters(ctxt->userData, BAD_CAST "&", 1);
- return;
- }
- if (name != NULL)
- xmlFree(name);
- }
-}
-
-/**
- * docbParseContent:
- * @ctxt: an SGML parser context
- * @name: the node name
- *
- * Parse a content: comment, sub-element, reference or text.
- *
- */
-static void
-docbParseContent(docbParserCtxtPtr ctxt)
-{
- xmlChar *currentNode;
- int depth;
-
- currentNode = xmlStrdup(ctxt->name);
- depth = ctxt->nameNr;
- while (1) {
- long cons = ctxt->nbChars;
-
- GROW;
- /*
- * Our tag or one of it's parent or children is ending.
- */
- if ((CUR == '<') && (NXT(1) == '/')) {
- docbParseEndTag(ctxt);
- if (currentNode != NULL)
- xmlFree(currentNode);
- return;
- }
-
- /*
- * Has this node been popped out during parsing of
- * the next element
- */
- if ((!xmlStrEqual(currentNode, ctxt->name)) &&
- (depth >= ctxt->nameNr)) {
- if (currentNode != NULL)
- xmlFree(currentNode);
- return;
- }
-
- /*
- * Sometimes DOCTYPE arrives in the middle of the document
- */
- if ((CUR == '<') && (NXT(1) == '!') &&
- (UPP(2) == 'D') && (UPP(3) == 'O') &&
- (UPP(4) == 'C') && (UPP(5) == 'T') &&
- (UPP(6) == 'Y') && (UPP(7) == 'P') && (UPP(8) == 'E')) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Misplaced DOCTYPE declaration\n");
- ctxt->wellFormed = 0;
- docbParseDocTypeDecl(ctxt);
- }
-
- /*
- * First case : a comment
- */
- if ((CUR == '<') && (NXT(1) == '!') &&
- (NXT(2) == '-') && (NXT(3) == '-')) {
- docbParseComment(ctxt);
- }
-
- /*
- * Second case : a PI
- */
- else if ((RAW == '<') && (NXT(1) == '?')) {
- docbParsePI(ctxt);
- }
-
- /*
- * Third case : a sub-element.
- */
- else if (CUR == '<') {
- docbParseElement(ctxt);
- }
-
- /*
- * Fourth case : a reference. If if has not been resolved,
- * parsing returns it's Name, create the node
- */
- else if (CUR == '&') {
- docbParseReference(ctxt);
- }
-
- /*
- * Fifth : end of the resource
- */
- else if (CUR == 0) {
- docbAutoClose(ctxt, NULL);
- if (ctxt->nameNr == 0)
- break;
- }
-
- /*
- * Last case, text. Note that References are handled directly.
- */
- else {
- docbParseCharData(ctxt);
- }
-
- if (cons == ctxt->nbChars) {
- if (ctxt->node != NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "detected an error in element content\n");
- ctxt->wellFormed = 0;
- }
- break;
- }
-
- GROW;
- }
- if (currentNode != NULL)
- xmlFree(currentNode);
-}
-
-/**
- * docbParseElement:
- * @ctxt: an SGML parser context
- *
- * parse an SGML element, this is highly recursive
- *
- * [39] element ::= EmptyElemTag | STag content ETag
- *
- * [41] Attribute ::= Name Eq AttValue
- */
-
-static void
-docbParseElement(docbParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlChar *currentNode = NULL;
- docbElemDescPtr info;
- docbParserNodeInfo node_info;
- xmlChar *oldname;
- int depth = ctxt->nameNr;
-
- /* Capture start position */
- if (ctxt->record_info) {
- node_info.begin_pos = ctxt->input->consumed +
- (CUR_PTR - ctxt->input->base);
- node_info.begin_line = ctxt->input->line;
- }
-
- oldname = xmlStrdup(ctxt->name);
- docbParseStartTag(ctxt);
- name = ctxt->name;
-#ifdef DEBUG
- if (oldname == NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Start of element %s\n", name);
- else if (name == NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Start of element failed, was %s\n", oldname);
- else
- xmlGenericError(xmlGenericErrorContext,
- "Start of element %s, was %s\n", name, oldname);
-#endif
- if (((depth == ctxt->nameNr) && (xmlStrEqual(oldname, ctxt->name))) ||
- (name == NULL)) {
- if (CUR == '>')
- NEXT;
- if (oldname != NULL)
- xmlFree(oldname);
- return;
- }
- if (oldname != NULL)
- xmlFree(oldname);
-
- /*
- * Lookup the info for that element.
- */
- info = docbTagLookup(name);
- if (info == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Tag %s unknown\n",
- name);
- ctxt->wellFormed = 0;
- } else if (info->depr) {
-/***************************
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData, "Tag %s is deprecated\n",
- name);
- ***************************/
- }
-
- /*
- * Check for an Empty Element labeled the XML/SGML way
- */
- if ((CUR == '/') && (NXT(1) == '>')) {
- SKIP(2);
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
- ctxt->sax->endElement(ctxt->userData, name);
- oldname = docbnamePop(ctxt);
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"End of tag the XML way: popping out %s\n", oldname);
-#endif
- if (oldname != NULL)
- xmlFree(oldname);
- return;
- }
-
- if (CUR == '>') {
- NEXT;
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Couldn't find end of Start Tag %s\n",
- name);
- ctxt->wellFormed = 0;
-
- /*
- * end of parsing of this node.
- */
- if (xmlStrEqual(name, ctxt->name)) {
- nodePop(ctxt);
- oldname = docbnamePop(ctxt);
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"End of start tag problem: popping out %s\n", oldname);
-#endif
- if (oldname != NULL)
- xmlFree(oldname);
- }
-
- /*
- * Capture end position and add node
- */
- if ( currentNode != NULL && ctxt->record_info ) {
- node_info.end_pos = ctxt->input->consumed +
- (CUR_PTR - ctxt->input->base);
- node_info.end_line = ctxt->input->line;
- node_info.node = ctxt->node;
- xmlParserAddNodeInfo(ctxt, &node_info);
- }
- return;
- }
-
- /*
- * Check for an Empty Element from DTD definition
- */
- if ((info != NULL) && (info->empty)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
- ctxt->sax->endElement(ctxt->userData, name);
- oldname = docbnamePop(ctxt);
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"End of empty tag %s : popping out %s\n", name, oldname);
-#endif
- if (oldname != NULL)
- xmlFree(oldname);
- return;
- }
-
- /*
- * Parse the content of the element:
- */
- currentNode = xmlStrdup(ctxt->name);
- depth = ctxt->nameNr;
- while (IS_CHAR(CUR)) {
- docbParseContent(ctxt);
- if (ctxt->nameNr < depth) break;
- }
-
- if (!IS_CHAR(CUR)) {
- /************
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Premature end of data in tag %s\n", currentNode);
- ctxt->wellFormed = 0;
- *************/
-
- /*
- * end of parsing of this node.
- */
- nodePop(ctxt);
- oldname = docbnamePop(ctxt);
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"Premature end of tag %s : popping out %s\n", name, oldname);
-#endif
- if (oldname != NULL)
- xmlFree(oldname);
- if (currentNode != NULL)
- xmlFree(currentNode);
- return;
- }
-
- /*
- * Capture end position and add node
- */
- if ( currentNode != NULL && ctxt->record_info ) {
- node_info.end_pos = ctxt->input->consumed +
- (CUR_PTR - ctxt->input->base);
- node_info.end_line = ctxt->input->line;
- node_info.node = ctxt->node;
- xmlParserAddNodeInfo(ctxt, &node_info);
- }
- if (currentNode != NULL)
- xmlFree(currentNode);
-}
-
-/**
- * docbParseEntityDecl:
- * @ctxt: an SGML parser context
- *
- * parse <!ENTITY declarations
- *
- */
-
-static void
-docbParseEntityDecl(xmlParserCtxtPtr ctxt) {
- xmlChar *name = NULL;
- xmlChar *value = NULL;
- xmlChar *URI = NULL, *literal = NULL;
- xmlChar *ndata = NULL;
- int isParameter = 0;
- xmlChar *orig = NULL;
-
- GROW;
- if ((RAW == '<') && (NXT(1) == '!') &&
- (UPP(2) == 'E') && (UPP(3) == 'N') &&
- (UPP(4) == 'T') && (UPP(5) == 'I') &&
- (UPP(6) == 'T') && (UPP(7) == 'Y')) {
- xmlParserInputPtr input = ctxt->input;
- ctxt->instate = XML_PARSER_ENTITY_DECL;
- SHRINK;
- SKIP(8);
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after '<!ENTITY'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
-
- if (RAW == '%') {
- NEXT;
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after '%'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- isParameter = 1;
- }
-
- name = xmlParseName(ctxt);
- if (name == NULL) {
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "sgmlarseEntityDecl: no name\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return;
- }
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after the entity name\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
-
- /*
- * handle the various case of definitions...
- */
- if (isParameter) {
- if ((RAW == '"') || (RAW == '\'')) {
- value = xmlParseEntityValue(ctxt, &orig);
- if (value) {
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
- ctxt->sax->entityDecl(ctxt->userData, name,
- XML_INTERNAL_PARAMETER_ENTITY,
- NULL, NULL, value);
- }
- } else {
- URI = xmlParseExternalID(ctxt, &literal, 1);
- if ((URI == NULL) && (literal == NULL)) {
- ctxt->errNo = XML_ERR_VALUE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity value required\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- if (URI) {
- xmlURIPtr uri;
-
- uri = xmlParseURI((const char *) URI);
- if (uri == NULL) {
- ctxt->errNo = XML_ERR_INVALID_URI;
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) &&
- (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Invalid URI: %s\n", URI);
- ctxt->wellFormed = 0;
- } else {
- if (uri->fragment != NULL) {
- ctxt->errNo = XML_ERR_URI_FRAGMENT;
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) &&
- (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Fragment not allowed: %s\n", URI);
- ctxt->wellFormed = 0;
- } else {
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) &&
- (ctxt->sax->entityDecl != NULL))
- ctxt->sax->entityDecl(ctxt->userData, name,
- XML_EXTERNAL_PARAMETER_ENTITY,
- literal, URI, NULL);
- }
- xmlFreeURI(uri);
- }
- }
- }
- } else {
- if ((RAW == '"') || (RAW == '\'')) {
- value = xmlParseEntityValue(ctxt, &orig);
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
- ctxt->sax->entityDecl(ctxt->userData, name,
- XML_INTERNAL_GENERAL_ENTITY,
- NULL, NULL, value);
- } else {
- URI = xmlParseExternalID(ctxt, &literal, 1);
- if ((URI == NULL) && (literal == NULL)) {
- ctxt->errNo = XML_ERR_VALUE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity value required\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- if (URI) {
- xmlURIPtr uri;
-
- uri = xmlParseURI((const char *)URI);
- if (uri == NULL) {
- ctxt->errNo = XML_ERR_INVALID_URI;
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) &&
- (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Invalid URI: %s\n", URI);
- ctxt->wellFormed = 0;
- } else {
- if (uri->fragment != NULL) {
- ctxt->errNo = XML_ERR_URI_FRAGMENT;
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) &&
- (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Fragment not allowed: %s\n", URI);
- ctxt->wellFormed = 0;
- }
- xmlFreeURI(uri);
- }
- }
- if ((RAW != '>') && (!IS_BLANK(CUR))) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required before content model\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
-
- /*
- * SGML specific: here we can get the content model
- */
- if (RAW != '>') {
- xmlChar *contmod;
-
- contmod = xmlParseName(ctxt);
-
- if (contmod == NULL) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Could not parse entity content model\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- if (xmlStrEqual(contmod, BAD_CAST"NDATA")) {
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after 'NDATA'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- ndata = xmlParseName(ctxt);
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
- (ctxt->sax->unparsedEntityDecl != NULL)) {
- ctxt->sax->unparsedEntityDecl(ctxt->userData,
- name, literal, URI, ndata);
- }
- } else if (xmlStrEqual(contmod, BAD_CAST"SUBDOC")) {
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "SUBDOC entities are not supported\n");
- SKIP_BLANKS;
- ndata = xmlParseName(ctxt);
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
- (ctxt->sax->unparsedEntityDecl != NULL)) {
- ctxt->sax->unparsedEntityDecl(ctxt->userData,
- name, literal, URI, ndata);
- }
- } else if (xmlStrEqual(contmod, BAD_CAST"CDATA")) {
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "CDATA entities are not supported\n");
- SKIP_BLANKS;
- ndata = xmlParseName(ctxt);
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
- (ctxt->sax->unparsedEntityDecl != NULL)) {
- ctxt->sax->unparsedEntityDecl(ctxt->userData,
- name, literal, URI, ndata);
- }
- }
- xmlFree(contmod);
- }
- } else {
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
- ctxt->sax->entityDecl(ctxt->userData, name,
- XML_EXTERNAL_GENERAL_PARSED_ENTITY,
- literal, URI, NULL);
- }
- }
- }
- SKIP_BLANKS;
- if (RAW != '>') {
- ctxt->errNo = XML_ERR_ENTITY_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "docbParseEntityDecl: entity %s not terminated\n", name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- if (input != ctxt->input) {
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
-"Entity declaration doesn't start and stop in the same entity\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- NEXT;
- }
- if (orig != NULL) {
- /*
- * Ugly mechanism to save the raw entity value.
- */
- xmlEntityPtr cur = NULL;
-
- if (isParameter) {
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->getParameterEntity != NULL))
- cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
- } else {
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->getEntity != NULL))
- cur = ctxt->sax->getEntity(ctxt->userData, name);
- }
- if (cur != NULL) {
- if (cur->orig != NULL)
- xmlFree(orig);
- else
- cur->orig = orig;
- } else
- xmlFree(orig);
- }
- if (name != NULL) xmlFree(name);
- if (value != NULL) xmlFree(value);
- if (URI != NULL) xmlFree(URI);
- if (literal != NULL) xmlFree(literal);
- if (ndata != NULL) xmlFree(ndata);
- }
-}
-
-/**
- * docbParseMarkupDecl:
- * @ctxt: an SGML parser context
- *
- * parse Markup declarations
- *
- * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
- * NotationDecl | PI | Comment
- */
-static void
-docbParseMarkupDecl(xmlParserCtxtPtr ctxt) {
- GROW;
- xmlParseElementDecl(ctxt);
- xmlParseAttributeListDecl(ctxt);
- docbParseEntityDecl(ctxt);
- xmlParseNotationDecl(ctxt);
- docbParsePI(ctxt);
- xmlParseComment(ctxt);
- /*
- * This is only for internal subset. On external entities,
- * the replacement is done before parsing stage
- */
- if ((ctxt->external == 0) && (ctxt->inputNr == 1))
- xmlParsePEReference(ctxt);
- ctxt->instate = XML_PARSER_DTD;
-}
-
-/**
- * docbParseInternalSubset:
- * @ctxt: an SGML parser context
- *
- * parse the internal subset declaration
- *
- * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
- */
-
-static void
-docbParseInternalSubset(xmlParserCtxtPtr ctxt) {
- /*
- * Is there any DTD definition ?
- */
- if (RAW == '[') {
- ctxt->instate = XML_PARSER_DTD;
- NEXT;
- /*
- * Parse the succession of Markup declarations and
- * PEReferences.
- * Subsequence (markupdecl | PEReference | S)*
- */
- while (RAW != ']') {
- const xmlChar *check = CUR_PTR;
- int cons = ctxt->input->consumed;
-
- SKIP_BLANKS;
- docbParseMarkupDecl(ctxt);
- xmlParsePEReference(ctxt);
-
- /*
- * Pop-up of finished entities.
- */
- while ((RAW == 0) && (ctxt->inputNr > 1))
- xmlPopInput(ctxt);
-
- if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "docbParseInternalSubset: error detected in Markup declaration\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- break;
- }
- }
- if (RAW == ']') {
- NEXT;
- SKIP_BLANKS;
- }
- }
-
- /*
- * We should be at the end of the DOCTYPE declaration.
- */
- if (RAW != '>') {
- ctxt->errNo = XML_ERR_DOCTYPE_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "DOCTYPE improperly terminated\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- NEXT;
-}
-
-/**
- * docbParseMisc:
- * @ctxt: an XML parser context
- *
- * parse an XML Misc* optional field.
- *
- * [27] Misc ::= Comment | PI | S
- */
-
-static void
-docbParseMisc(xmlParserCtxtPtr ctxt) {
- while (((RAW == '<') && (NXT(1) == '?')) ||
- ((RAW == '<') && (NXT(1) == '!') &&
- (NXT(2) == '-') && (NXT(3) == '-')) ||
- IS_BLANK(CUR)) {
- if ((RAW == '<') && (NXT(1) == '?')) {
- docbParsePI(ctxt);
- } else if (IS_BLANK(CUR)) {
- NEXT;
- } else
- xmlParseComment(ctxt);
- }
-}
-
-/**
- * docbParseDocument:
- * @ctxt: an SGML parser context
- *
- * parse an SGML document (and build a tree if using the standard SAX
- * interface).
- *
- * Returns 0, -1 in case of error. the parser context is augmented
- * as a result of the parsing.
- */
-
-int
-docbParseDocument(docbParserCtxtPtr ctxt) {
- xmlChar start[4];
- xmlCharEncoding enc;
- xmlDtdPtr dtd;
-
- docbDefaultSAXHandlerInit();
- ctxt->html = 2;
-
- GROW;
- /*
- * SAX: beginning of the document processing.
- */
- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
- ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
-
- /*
- * Get the 4 first bytes and decode the charset
- * if enc != XML_CHAR_ENCODING_NONE
- * plug some encoding conversion routines.
- */
- start[0] = RAW;
- start[1] = NXT(1);
- start[2] = NXT(2);
- start[3] = NXT(3);
- enc = xmlDetectCharEncoding(start, 4);
- if (enc != XML_CHAR_ENCODING_NONE) {
- xmlSwitchEncoding(ctxt, enc);
- }
-
- /*
- * Wipe out everything which is before the first '<'
- */
- SKIP_BLANKS;
- if (CUR == 0) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Document is empty\n");
- ctxt->wellFormed = 0;
- }
-
- if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
- ctxt->sax->startDocument(ctxt->userData);
-
-
- /*
- * The Misc part of the Prolog
- */
- GROW;
- docbParseMisc(ctxt);
-
- /*
- * Then possibly doc type declaration(s) and more Misc
- * (doctypedecl Misc*)?
- */
- GROW;
- if ((RAW == '<') && (NXT(1) == '!') &&
- (UPP(2) == 'D') && (UPP(3) == 'O') &&
- (UPP(4) == 'C') && (UPP(5) == 'T') &&
- (UPP(6) == 'Y') && (UPP(7) == 'P') &&
- (UPP(8) == 'E')) {
-
- ctxt->inSubset = 1;
- docbParseDocTypeDecl(ctxt);
- if (RAW == '[') {
- ctxt->instate = XML_PARSER_DTD;
- docbParseInternalSubset(ctxt);
- }
-
- /*
- * Create and update the external subset.
- */
- ctxt->inSubset = 2;
- if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->internalSubset(ctxt->userData, ctxt->intSubName,
- ctxt->extSubSystem, ctxt->extSubURI);
- ctxt->inSubset = 0;
-
-
- ctxt->instate = XML_PARSER_PROLOG;
- docbParseMisc(ctxt);
- }
-
- /*
- * Time to start parsing the tree itself
- */
- docbParseContent(ctxt);
-
- /*
- * autoclose
- */
- if (CUR == 0)
- docbAutoClose(ctxt, NULL);
-
-
- /*
- * SAX: end of the document processing.
- */
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
-
- if (ctxt->myDoc != NULL) {
- dtd = ctxt->myDoc->intSubset;
- ctxt->myDoc->standalone = -1;
- if (dtd == NULL)
- ctxt->myDoc->intSubset =
- xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "SGML",
- BAD_CAST "-//W3C//DTD SGML 4.0 Transitional//EN",
- BAD_CAST "http://www.w3.org/TR/REC-docbook/loose.dtd");
- }
- if (! ctxt->wellFormed) return(-1);
- return(0);
-}
-
-
-/************************************************************************
- * *
- * Parser contexts handling *
- * *
- ************************************************************************/
-
-/**
- * docbInitParserCtxt:
- * @ctxt: an SGML parser context
- *
- * Initialize a parser context
- */
-
-static void
-docbInitParserCtxt(docbParserCtxtPtr ctxt)
-{
- docbSAXHandler *sax;
-
- if (ctxt == NULL) return;
- memset(ctxt, 0, sizeof(docbParserCtxt));
-
- sax = (docbSAXHandler *) xmlMalloc(sizeof(docbSAXHandler));
- if (sax == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "docbInitParserCtxt: out of memory\n");
- }
- memset(sax, 0, sizeof(docbSAXHandler));
-
- /* Allocate the Input stack */
- ctxt->inputTab = (docbParserInputPtr *)
- xmlMalloc(5 * sizeof(docbParserInputPtr));
- if (ctxt->inputTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "docbInitParserCtxt: out of memory\n");
- }
- ctxt->inputNr = 0;
- ctxt->inputMax = 5;
- ctxt->input = NULL;
- ctxt->version = NULL;
- ctxt->encoding = NULL;
- ctxt->standalone = -1;
- ctxt->instate = XML_PARSER_START;
-
- /* Allocate the Node stack */
- ctxt->nodeTab = (docbNodePtr *) xmlMalloc(10 * sizeof(docbNodePtr));
- ctxt->nodeNr = 0;
- ctxt->nodeMax = 10;
- ctxt->node = NULL;
-
- /* Allocate the Name stack */
- ctxt->nameTab = (xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
- ctxt->nameNr = 0;
- ctxt->nameMax = 10;
- ctxt->name = NULL;
-
- if (sax == NULL) ctxt->sax = &docbDefaultSAXHandler;
- else {
- ctxt->sax = sax;
- memcpy(sax, &docbDefaultSAXHandler, sizeof(docbSAXHandler));
- }
- ctxt->userData = ctxt;
- ctxt->myDoc = NULL;
- ctxt->wellFormed = 1;
- ctxt->linenumbers = xmlLineNumbersDefaultValue;
- ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue;
- ctxt->html = 2;
- ctxt->record_info = 0;
- ctxt->validate = 0;
- ctxt->nbChars = 0;
- ctxt->checkIndex = 0;
- xmlInitNodeInfoSeq(&ctxt->node_seq);
-}
-
-/**
- * docbFreeParserCtxt:
- * @ctxt: an SGML parser context
- *
- * Free all the memory used by a parser context. However the parsed
- * document in ctxt->myDoc is not freed.
- */
-
-void
-docbFreeParserCtxt(docbParserCtxtPtr ctxt)
-{
- xmlFreeParserCtxt(ctxt);
-}
-
-/**
- * docbCreateDocParserCtxt:
- * @cur: a pointer to an array of xmlChar
- * @encoding: the SGML document encoding, or NULL
- *
- * Create a parser context for an SGML document.
- *
- * Returns the new parser context or NULL
- */
-static docbParserCtxtPtr
-docbCreateDocParserCtxt(xmlChar *cur, const char *encoding ATTRIBUTE_UNUSED) {
- docbParserCtxtPtr ctxt;
- docbParserInputPtr input;
- /* sgmlCharEncoding enc; */
-
- ctxt = (docbParserCtxtPtr) xmlMalloc(sizeof(docbParserCtxt));
- if (ctxt == NULL) {
- xmlGenericError(xmlGenericErrorContext, "malloc failed");
- return(NULL);
- }
- docbInitParserCtxt(ctxt);
- input = (docbParserInputPtr) xmlMalloc(sizeof(docbParserInput));
- if (input == NULL) {
- xmlGenericError(xmlGenericErrorContext, "malloc failed");
- xmlFree(ctxt);
- return(NULL);
- }
- memset(input, 0, sizeof(docbParserInput));
-
- input->line = 1;
- input->col = 1;
- input->base = cur;
- input->cur = cur;
-
- inputPush(ctxt, input);
- return(ctxt);
-}
-
-/************************************************************************
- * *
- * Progressive parsing interfaces *
- * *
- ************************************************************************/
-
-/**
- * docbParseLookupSequence:
- * @ctxt: an SGML parser context
- * @first: the first char to lookup
- * @next: the next char to lookup or zero
- * @third: the next char to lookup or zero
- *
- * Try to find if a sequence (first, next, third) or just (first next) or
- * (first) is available in the input stream.
- * This function has a side effect of (possibly) incrementing ctxt->checkIndex
- * to avoid rescanning sequences of bytes, it DOES change the state of the
- * parser, do not use liberally.
- * This is basically similar to xmlParseLookupSequence()
- *
- * Returns the index to the current parsing point if the full sequence
- * is available, -1 otherwise.
- */
-static int
-docbParseLookupSequence(docbParserCtxtPtr ctxt, xmlChar first,
- xmlChar next, xmlChar third) {
- int base, len;
- docbParserInputPtr in;
- const xmlChar *buf;
-
- in = ctxt->input;
- if (in == NULL) return(-1);
- base = in->cur - in->base;
- if (base < 0) return(-1);
- if (ctxt->checkIndex > base)
- base = ctxt->checkIndex;
- if (in->buf == NULL) {
- buf = in->base;
- len = in->length;
- } else {
- buf = in->buf->buffer->content;
- len = in->buf->buffer->use;
- }
- /* take into account the sequence length */
- if (third) len -= 2;
- else if (next) len --;
- for (;base < len;base++) {
- if (buf[base] == first) {
- if (third != 0) {
- if ((buf[base + 1] != next) ||
- (buf[base + 2] != third)) continue;
- } else if (next != 0) {
- if (buf[base + 1] != next) continue;
- }
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- if (next == 0)
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c' found at %d\n",
- first, base);
- else if (third == 0)
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c%c' found at %d\n",
- first, next, base);
- else
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c%c%c' found at %d\n",
- first, next, third, base);
-#endif
- return(base - (in->cur - in->base));
- }
- }
- ctxt->checkIndex = base;
-#ifdef DEBUG_PUSH
- if (next == 0)
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c' failed\n", first);
- else if (third == 0)
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c%c' failed\n", first, next);
- else
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c%c%c' failed\n", first, next, third);
-#endif
- return(-1);
-}
-
-/**
- * docbParseTryOrFinish:
- * @ctxt: an SGML parser context
- * @terminate: last chunk indicator
- *
- * Try to progress on parsing
- *
- * Returns zero if no parsing was possible
- */
-static int
-docbParseTryOrFinish(docbParserCtxtPtr ctxt, int terminate) {
- int ret = 0;
- docbParserInputPtr in;
- int avail = 0;
- xmlChar cur, next;
-
-#ifdef DEBUG_PUSH
- switch (ctxt->instate) {
- case XML_PARSER_EOF:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try EOF\n"); break;
- case XML_PARSER_START:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try START\n"); break;
- case XML_PARSER_MISC:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try MISC\n");break;
- case XML_PARSER_COMMENT:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try COMMENT\n");break;
- case XML_PARSER_PROLOG:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try PROLOG\n");break;
- case XML_PARSER_START_TAG:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try START_TAG\n");break;
- case XML_PARSER_CONTENT:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try CONTENT\n");break;
- case XML_PARSER_CDATA_SECTION:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try CDATA_SECTION\n");break;
- case XML_PARSER_END_TAG:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try END_TAG\n");break;
- case XML_PARSER_ENTITY_DECL:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try ENTITY_DECL\n");break;
- case XML_PARSER_ENTITY_VALUE:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try ENTITY_VALUE\n");break;
- case XML_PARSER_ATTRIBUTE_VALUE:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try ATTRIBUTE_VALUE\n");break;
- case XML_PARSER_DTD:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try DTD\n");break;
- case XML_PARSER_EPILOG:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try EPILOG\n");break;
- case XML_PARSER_PI:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try PI\n");break;
- }
-#endif
-
- while (1) {
-
- in = ctxt->input;
- if (in == NULL) break;
- if (in->buf == NULL)
- avail = in->length - (in->cur - in->base);
- else
- avail = in->buf->buffer->use - (in->cur - in->base);
- if ((avail == 0) && (terminate)) {
- docbAutoClose(ctxt, NULL);
- if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
- /*
- * SAX: end of the document processing.
- */
- ctxt->instate = XML_PARSER_EOF;
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
- }
- }
- if (avail < 1)
- goto done;
- switch (ctxt->instate) {
- case XML_PARSER_EOF:
- /*
- * Document parsing is done !
- */
- goto done;
- case XML_PARSER_START:
- /*
- * Very first chars read from the document flow.
- */
- cur = in->cur[0];
- if (IS_BLANK(cur)) {
- SKIP_BLANKS;
- if (in->buf == NULL)
- avail = in->length - (in->cur - in->base);
- else
- avail = in->buf->buffer->use - (in->cur - in->base);
- }
- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
- ctxt->sax->setDocumentLocator(ctxt->userData,
- &xmlDefaultSAXLocator);
- if ((ctxt->sax) && (ctxt->sax->startDocument) &&
- (!ctxt->disableSAX))
- ctxt->sax->startDocument(ctxt->userData);
-
- cur = in->cur[0];
- next = in->cur[1];
- if ((cur == '<') && (next == '!') &&
- (UPP(2) == 'D') && (UPP(3) == 'O') &&
- (UPP(4) == 'C') && (UPP(5) == 'T') &&
- (UPP(6) == 'Y') && (UPP(7) == 'P') &&
- (UPP(8) == 'E')) {
- if ((!terminate) &&
- (docbParseLookupSequence(ctxt, '>', 0, 0) < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: Parsing internal subset\n");
-#endif
- docbParseDocTypeDecl(ctxt);
- ctxt->instate = XML_PARSER_PROLOG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering PROLOG\n");
-#endif
- } else {
- ctxt->instate = XML_PARSER_MISC;
- }
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering MISC\n");
-#endif
- break;
- case XML_PARSER_MISC:
- SKIP_BLANKS;
- if (in->buf == NULL)
- avail = in->length - (in->cur - in->base);
- else
- avail = in->buf->buffer->use - (in->cur - in->base);
- if (avail < 2)
- goto done;
- cur = in->cur[0];
- next = in->cur[1];
- if ((cur == '<') && (next == '!') &&
- (in->cur[2] == '-') && (in->cur[3] == '-')) {
- if ((!terminate) &&
- (docbParseLookupSequence(ctxt, '-', '-', '>') < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: Parsing Comment\n");
-#endif
- docbParseComment(ctxt);
- ctxt->instate = XML_PARSER_MISC;
- } else if ((cur == '<') && (next == '!') &&
- (UPP(2) == 'D') && (UPP(3) == 'O') &&
- (UPP(4) == 'C') && (UPP(5) == 'T') &&
- (UPP(6) == 'Y') && (UPP(7) == 'P') &&
- (UPP(8) == 'E')) {
- if ((!terminate) &&
- (docbParseLookupSequence(ctxt, '>', 0, 0) < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: Parsing internal subset\n");
-#endif
- docbParseDocTypeDecl(ctxt);
- ctxt->instate = XML_PARSER_PROLOG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering PROLOG\n");
-#endif
- } else if ((cur == '<') && (next == '!') &&
- (avail < 9)) {
- goto done;
- } else {
- ctxt->instate = XML_PARSER_START_TAG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering START_TAG\n");
-#endif
- }
- break;
- case XML_PARSER_PROLOG:
- SKIP_BLANKS;
- if (in->buf == NULL)
- avail = in->length - (in->cur - in->base);
- else
- avail = in->buf->buffer->use - (in->cur - in->base);
- if (avail < 2)
- goto done;
- cur = in->cur[0];
- next = in->cur[1];
- if ((cur == '<') && (next == '!') &&
- (in->cur[2] == '-') && (in->cur[3] == '-')) {
- if ((!terminate) &&
- (docbParseLookupSequence(ctxt, '-', '-', '>') < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: Parsing Comment\n");
-#endif
- docbParseComment(ctxt);
- ctxt->instate = XML_PARSER_PROLOG;
- } else if ((cur == '<') && (next == '!') &&
- (avail < 4)) {
- goto done;
- } else {
- ctxt->instate = XML_PARSER_START_TAG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering START_TAG\n");
-#endif
- }
- break;
- case XML_PARSER_EPILOG:
- if (in->buf == NULL)
- avail = in->length - (in->cur - in->base);
- else
- avail = in->buf->buffer->use - (in->cur - in->base);
- if (avail < 1)
- goto done;
- cur = in->cur[0];
- if (IS_BLANK(cur)) {
- docbParseCharData(ctxt);
- goto done;
- }
- if (avail < 2)
- goto done;
- next = in->cur[1];
- if ((cur == '<') && (next == '!') &&
- (in->cur[2] == '-') && (in->cur[3] == '-')) {
- if ((!terminate) &&
- (docbParseLookupSequence(ctxt, '-', '-', '>') < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: Parsing Comment\n");
-#endif
- docbParseComment(ctxt);
- ctxt->instate = XML_PARSER_EPILOG;
- } else if ((cur == '<') && (next == '!') &&
- (avail < 4)) {
- goto done;
- } else {
- ctxt->errNo = XML_ERR_DOCUMENT_END;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Extra content at the end of the document\n");
- ctxt->wellFormed = 0;
- ctxt->instate = XML_PARSER_EOF;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering EOF\n");
-#endif
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
- goto done;
- }
- break;
- case XML_PARSER_START_TAG: {
- xmlChar *name, *oldname;
- int depth = ctxt->nameNr;
- docbElemDescPtr info;
-
- if (avail < 2)
- goto done;
- cur = in->cur[0];
- if (cur != '<') {
- ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- }
- if ((!terminate) &&
- (docbParseLookupSequence(ctxt, '>', 0, 0) < 0))
- goto done;
-
- oldname = xmlStrdup(ctxt->name);
- docbParseStartTag(ctxt);
- name = ctxt->name;
-#ifdef DEBUG
- if (oldname == NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Start of element %s\n", name);
- else if (name == NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Start of element failed, was %s\n",
- oldname);
- else
- xmlGenericError(xmlGenericErrorContext,
- "Start of element %s, was %s\n",
- name, oldname);
-#endif
- if (((depth == ctxt->nameNr) &&
- (xmlStrEqual(oldname, ctxt->name))) ||
- (name == NULL)) {
- if (CUR == '>')
- NEXT;
- if (oldname != NULL)
- xmlFree(oldname);
- break;
- }
- if (oldname != NULL)
- xmlFree(oldname);
-
- /*
- * Lookup the info for that element.
- */
- info = docbTagLookup(name);
- if (info == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Tag %s unknown\n",
- name);
- ctxt->wellFormed = 0;
- } else if (info->depr) {
- /***************************
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "Tag %s is deprecated\n",
- name);
- ***************************/
- }
-
- /*
- * Check for an Empty Element labeled the XML/SGML way
- */
- if ((CUR == '/') && (NXT(1) == '>')) {
- SKIP(2);
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
- ctxt->sax->endElement(ctxt->userData, name);
- oldname = docbnamePop(ctxt);
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"End of tag the XML way: popping out %s\n",
- oldname);
-#endif
- if (oldname != NULL)
- xmlFree(oldname);
- ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- }
-
- if (CUR == '>') {
- NEXT;
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Couldn't find end of Start Tag %s\n",
- name);
- ctxt->wellFormed = 0;
-
- /*
- * end of parsing of this node.
- */
- if (xmlStrEqual(name, ctxt->name)) {
- nodePop(ctxt);
- oldname = docbnamePop(ctxt);
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,
- "End of start tag problem: popping out %s\n", oldname);
-#endif
- if (oldname != NULL)
- xmlFree(oldname);
- }
-
- ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- }
-
- /*
- * Check for an Empty Element from DTD definition
- */
- if ((info != NULL) && (info->empty)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
- ctxt->sax->endElement(ctxt->userData, name);
- oldname = docbnamePop(ctxt);
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"End of empty tag %s : popping out %s\n", name, oldname);
-#endif
- if (oldname != NULL)
- xmlFree(oldname);
- }
- ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- }
- case XML_PARSER_CONTENT: {
- long cons;
- /*
- * Handle preparsed entities and charRef
- */
- if (ctxt->token != 0) {
- xmlChar chr[2] = { 0 , 0 } ;
-
- chr[0] = (xmlChar) ctxt->token;
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
- ctxt->sax->characters(ctxt->userData, chr, 1);
- ctxt->token = 0;
- ctxt->checkIndex = 0;
- }
- if ((avail == 1) && (terminate)) {
- cur = in->cur[0];
- if ((cur != '<') && (cur != '&')) {
- if (ctxt->sax != NULL) {
- if (IS_BLANK(cur)) {
- if (ctxt->sax->ignorableWhitespace != NULL)
- ctxt->sax->ignorableWhitespace(
- ctxt->userData, &cur, 1);
- } else {
- if (ctxt->sax->characters != NULL)
- ctxt->sax->characters(
- ctxt->userData, &cur, 1);
- }
- }
- ctxt->token = 0;
- ctxt->checkIndex = 0;
- NEXT;
- }
- break;
- }
- if (avail < 2)
- goto done;
- cur = in->cur[0];
- next = in->cur[1];
- cons = ctxt->nbChars;
- /*
- * Sometimes DOCTYPE arrives in the middle of the document
- */
- if ((cur == '<') && (next == '!') &&
- (UPP(2) == 'D') && (UPP(3) == 'O') &&
- (UPP(4) == 'C') && (UPP(5) == 'T') &&
- (UPP(6) == 'Y') && (UPP(7) == 'P') &&
- (UPP(8) == 'E')) {
- if ((!terminate) &&
- (docbParseLookupSequence(ctxt, '>', 0, 0) < 0))
- goto done;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Misplaced DOCTYPE declaration\n");
- ctxt->wellFormed = 0;
- docbParseDocTypeDecl(ctxt);
- } else if ((cur == '<') && (next == '!') &&
- (in->cur[2] == '-') && (in->cur[3] == '-')) {
- if ((!terminate) &&
- (docbParseLookupSequence(ctxt, '-', '-', '>') < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: Parsing Comment\n");
-#endif
- docbParseComment(ctxt);
- ctxt->instate = XML_PARSER_CONTENT;
- } else if ((cur == '<') && (next == '!') && (avail < 4)) {
- goto done;
- } else if ((cur == '<') && (next == '/')) {
- ctxt->instate = XML_PARSER_END_TAG;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering END_TAG\n");
-#endif
- break;
- } else if (cur == '<') {
- ctxt->instate = XML_PARSER_START_TAG;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering START_TAG\n");
-#endif
- break;
- } else if (cur == '&') {
- if ((!terminate) &&
- (docbParseLookupSequence(ctxt, ';', 0, 0) < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: Parsing Reference\n");
-#endif
- /* TODO: check generation of subtrees if noent !!! */
- docbParseReference(ctxt);
- } else {
- /* TODO Avoid the extra copy, handle directly !!!!!! */
- /*
- * Goal of the following test is:
- * - minimize calls to the SAX 'character' callback
- * when they are mergeable
- */
- if ((ctxt->inputNr == 1) &&
- (avail < DOCB_PARSER_BIG_BUFFER_SIZE)) {
- if ((!terminate) &&
- (docbParseLookupSequence(ctxt, '<', 0, 0) < 0))
- goto done;
- }
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: Parsing char data\n");
-#endif
- docbParseCharData(ctxt);
- }
- if (cons == ctxt->nbChars) {
- if (ctxt->node != NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "detected an error in element content\n");
- ctxt->wellFormed = 0;
- NEXT;
- }
- break;
- }
-
- break;
- }
- case XML_PARSER_END_TAG:
- if (avail < 2)
- goto done;
- if ((!terminate) &&
- (docbParseLookupSequence(ctxt, '>', 0, 0) < 0))
- goto done;
- docbParseEndTag(ctxt);
- if (ctxt->nameNr == 0) {
- ctxt->instate = XML_PARSER_EPILOG;
- } else {
- ctxt->instate = XML_PARSER_CONTENT;
- }
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- case XML_PARSER_CDATA_SECTION:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == CDATA\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- case XML_PARSER_DTD:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == DTD\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- case XML_PARSER_COMMENT:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == COMMENT\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- case XML_PARSER_PI:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == PI\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- case XML_PARSER_ENTITY_DECL:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == ENTITY_DECL\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- case XML_PARSER_ENTITY_VALUE:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == ENTITY_VALUE\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering DTD\n");
-#endif
- break;
- case XML_PARSER_ATTRIBUTE_VALUE:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == ATTRIBUTE_VALUE\n");
- ctxt->instate = XML_PARSER_START_TAG;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering START_TAG\n");
-#endif
- break;
- case XML_PARSER_SYSTEM_LITERAL:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == XML_PARSER_SYSTEM_LITERAL\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
-
- case XML_PARSER_IGNORE:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == XML_PARSER_IGNORE\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- case XML_PARSER_PUBLIC_LITERAL:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == XML_PARSER_LITERAL\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- }
- }
-done:
- if ((avail == 0) && (terminate)) {
- docbAutoClose(ctxt, NULL);
- if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
- /*
- * SAX: end of the document processing.
- */
- ctxt->instate = XML_PARSER_EOF;
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
- }
- }
- if ((ctxt->myDoc != NULL) &&
- ((terminate) || (ctxt->instate == XML_PARSER_EOF) ||
- (ctxt->instate == XML_PARSER_EPILOG))) {
- xmlDtdPtr dtd;
- dtd = ctxt->myDoc->intSubset;
- if (dtd == NULL)
- ctxt->myDoc->intSubset =
- xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "SGML",
- BAD_CAST "-//W3C//DTD SGML 4.0 Transitional//EN",
- BAD_CAST "http://www.w3.org/TR/REC-docbook/loose.dtd");
- }
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext, "HPP: done %d\n", ret);
-#endif
- return(ret);
-}
-
-/**
- * docbParseChunk:
- * @ctxt: an XML parser context
- * @chunk: an char array
- * @size: the size in byte of the chunk
- * @terminate: last chunk indicator
- *
- * Parse a Chunk of memory
- *
- * Returns zero if no error, the xmlParserErrors otherwise.
- */
-int
-docbParseChunk(docbParserCtxtPtr ctxt, const char *chunk, int size,
- int terminate) {
- if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
- (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF)) {
- int base = ctxt->input->base - ctxt->input->buf->buffer->content;
- int cur = ctxt->input->cur - ctxt->input->base;
-
- xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
- ctxt->input->base = ctxt->input->buf->buffer->content + base;
- ctxt->input->cur = ctxt->input->base + cur;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext, "HPP: pushed %d\n", size);
-#endif
-
- if ((terminate) || (ctxt->input->buf->buffer->use > 80))
- docbParseTryOrFinish(ctxt, terminate);
- } else if (ctxt->instate != XML_PARSER_EOF) {
- xmlParserInputBufferPush(ctxt->input->buf, 0, "");
- docbParseTryOrFinish(ctxt, terminate);
- }
- if (terminate) {
- if ((ctxt->instate != XML_PARSER_EOF) &&
- (ctxt->instate != XML_PARSER_EPILOG) &&
- (ctxt->instate != XML_PARSER_MISC)) {
- ctxt->errNo = XML_ERR_DOCUMENT_END;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Extra content at the end of the document\n");
- ctxt->wellFormed = 0;
- }
- if (ctxt->instate != XML_PARSER_EOF) {
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
- }
- ctxt->instate = XML_PARSER_EOF;
- }
- return((xmlParserErrors) ctxt->errNo);
-}
-
-/************************************************************************
- * *
- * User entry points *
- * *
- ************************************************************************/
-
-/**
- * docbCreatePushParserCtxt:
- * @sax: a SAX handler
- * @user_data: The user data returned on SAX callbacks
- * @chunk: a pointer to an array of chars
- * @size: number of chars in the array
- * @filename: an optional file name or URI
- * @enc: an optional encoding
- *
- * Create a parser context for using the DocBook SGML parser in push mode
- * To allow content encoding detection, @size should be >= 4
- * The value of @filename is used for fetching external entities
- * and error/warning reports.
- *
- * Returns the new parser context or NULL
- */
-docbParserCtxtPtr
-docbCreatePushParserCtxt(docbSAXHandlerPtr sax, void *user_data,
- const char *chunk, int size, const char *filename,
- xmlCharEncoding enc) {
- docbParserCtxtPtr ctxt;
- docbParserInputPtr inputStream;
- xmlParserInputBufferPtr buf;
-
- buf = xmlAllocParserInputBuffer(enc);
- if (buf == NULL) return(NULL);
-
- ctxt = (docbParserCtxtPtr) xmlMalloc(sizeof(docbParserCtxt));
- if (ctxt == NULL) {
- xmlFree(buf);
- return(NULL);
- }
- memset(ctxt, 0, sizeof(docbParserCtxt));
- docbInitParserCtxt(ctxt);
- if (sax != NULL) {
- if (ctxt->sax != &docbDefaultSAXHandler)
- xmlFree(ctxt->sax);
- ctxt->sax = (docbSAXHandlerPtr) xmlMalloc(sizeof(docbSAXHandler));
- if (ctxt->sax == NULL) {
- xmlFree(buf);
- xmlFree(ctxt);
- return(NULL);
- }
- memcpy(ctxt->sax, sax, sizeof(docbSAXHandler));
- if (user_data != NULL)
- ctxt->userData = user_data;
- }
- if (filename == NULL) {
- ctxt->directory = NULL;
- } else {
- ctxt->directory = xmlParserGetDirectory(filename);
- }
-
- inputStream = docbNewInputStream(ctxt);
- if (inputStream == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
-
- if (filename == NULL)
- inputStream->filename = NULL;
- else
- inputStream->filename = xmlMemStrdup(filename);
- inputStream->buf = buf;
- inputStream->base = inputStream->buf->buffer->content;
- inputStream->cur = inputStream->buf->buffer->content;
-
- inputPush(ctxt, inputStream);
-
- if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
- (ctxt->input->buf != NULL)) {
- xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext, "HPP: pushed %d\n", size);
-#endif
- }
-
- return(ctxt);
-}
-
-/**
- * docbSAXParseDoc:
- * @cur: a pointer to an array of xmlChar
- * @encoding: a free form C string describing the SGML document encoding, or NULL
- * @sax: the SAX handler block
- * @userData: if using SAX, this pointer will be provided on callbacks.
- *
- * parse an SGML in-memory document and build a tree.
- * It use the given SAX function block to handle the parsing callback.
- * If sax is NULL, fallback to the default DOM tree building routines.
- *
- * Returns the resulting document tree
- */
-
-docbDocPtr
-docbSAXParseDoc(xmlChar *cur, const char *encoding, docbSAXHandlerPtr sax, void *userData) {
- docbDocPtr ret;
- docbParserCtxtPtr ctxt;
-
- if (cur == NULL) return(NULL);
-
-
- ctxt = docbCreateDocParserCtxt(cur, encoding);
- if (ctxt == NULL) return(NULL);
- if (sax != NULL) {
- ctxt->sax = sax;
- ctxt->userData = userData;
- }
-
- docbParseDocument(ctxt);
- ret = ctxt->myDoc;
- if (sax != NULL) {
- ctxt->sax = NULL;
- ctxt->userData = NULL;
- }
- docbFreeParserCtxt(ctxt);
-
- return(ret);
-}
-
-/**
- * docbParseDoc:
- * @cur: a pointer to an array of xmlChar
- * @encoding: a free form C string describing the SGML document encoding, or NULL
- *
- * parse an SGML in-memory document and build a tree.
- *
- * Returns the resulting document tree
- */
-
-docbDocPtr
-docbParseDoc(xmlChar *cur, const char *encoding) {
- return(docbSAXParseDoc(cur, encoding, NULL, NULL));
-}
-
-
-/**
- * docbCreateFileParserCtxt:
- * @filename: the filename
- * @encoding: the SGML document encoding, or NULL
- *
- * Create a parser context for a file content.
- * Automatic support for ZLIB/Compress compressed document is provided
- * by default if found at compile-time.
- *
- * Returns the new parser context or NULL
- */
-docbParserCtxtPtr
-docbCreateFileParserCtxt(const char *filename,
- const char *encoding ATTRIBUTE_UNUSED)
-{
- docbParserCtxtPtr ctxt;
- docbParserInputPtr inputStream;
- xmlParserInputBufferPtr buf;
- /* sgmlCharEncoding enc; */
-
- buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
- if (buf == NULL) return(NULL);
-
- ctxt = (docbParserCtxtPtr) xmlMalloc(sizeof(docbParserCtxt));
- if (ctxt == NULL) {
- xmlGenericError(xmlGenericErrorContext, "malloc failed");
- return(NULL);
- }
- memset(ctxt, 0, sizeof(docbParserCtxt));
- docbInitParserCtxt(ctxt);
- inputStream = (docbParserInputPtr) xmlMalloc(sizeof(docbParserInput));
- if (inputStream == NULL) {
- xmlGenericError(xmlGenericErrorContext, "malloc failed");
- xmlFree(ctxt);
- return(NULL);
- }
- memset(inputStream, 0, sizeof(docbParserInput));
-
- inputStream->filename = (char *)
- xmlNormalizeWindowsPath((const xmlChar *)filename);
- inputStream->line = 1;
- inputStream->col = 1;
- inputStream->buf = buf;
- inputStream->directory = NULL;
-
- inputStream->base = inputStream->buf->buffer->content;
- inputStream->cur = inputStream->buf->buffer->content;
- inputStream->free = NULL;
-
- inputPush(ctxt, inputStream);
- return(ctxt);
-}
-
-/**
- * docbSAXParseFile:
- * @filename: the filename
- * @encoding: a free form C string describing the SGML document encoding, or NULL
- * @sax: the SAX handler block
- * @userData: if using SAX, this pointer will be provided on callbacks.
- *
- * parse an SGML file and build a tree. Automatic support for ZLIB/Compress
- * compressed document is provided by default if found at compile-time.
- * It use the given SAX function block to handle the parsing callback.
- * If sax is NULL, fallback to the default DOM tree building routines.
- *
- * Returns the resulting document tree
- */
-
-docbDocPtr
-docbSAXParseFile(const char *filename, const char *encoding, docbSAXHandlerPtr sax,
- void *userData) {
- docbDocPtr ret;
- docbParserCtxtPtr ctxt;
- docbSAXHandlerPtr oldsax = NULL;
-
- ctxt = docbCreateFileParserCtxt(filename, encoding);
- if (ctxt == NULL) return(NULL);
- if (sax != NULL) {
- oldsax = ctxt->sax;
- ctxt->sax = sax;
- ctxt->userData = userData;
- }
-
- docbParseDocument(ctxt);
-
- ret = ctxt->myDoc;
- if (sax != NULL) {
- ctxt->sax = oldsax;
- ctxt->userData = NULL;
- }
- docbFreeParserCtxt(ctxt);
-
- return(ret);
-}
-
-/**
- * docbParseFile:
- * @filename: the filename
- * @encoding: a free form C string describing document encoding, or NULL
- *
- * parse a Docbook SGML file and build a tree. Automatic support for
- * ZLIB/Compress compressed document is provided by default if found
- * at compile-time.
- *
- * Returns the resulting document tree
- */
-
-docbDocPtr
-docbParseFile(const char *filename, const char *encoding) {
- return(docbSAXParseFile(filename, encoding, NULL, NULL));
-}
-
-#endif /* LIBXML_DOCB_ENABLED */
diff --git a/bundle/libxml/HTMLparser.c b/bundle/libxml/HTMLparser.c
deleted file mode 100644
index 7db3e9e3a8..0000000000
--- a/bundle/libxml/HTMLparser.c
+++ /dev/null
@@ -1,5013 +0,0 @@
-/*
- * HTMLparser.c : an HTML 4.0 non-verifying parser
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-#ifdef LIBXML_HTML_ENABLED
-
-#include <string.h>
-#ifdef HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include <libxml/xmlmemory.h>
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/parserInternals.h>
-#include <libxml/xmlerror.h>
-#include <libxml/HTMLparser.h>
-#include <libxml/HTMLtree.h>
-#include <libxml/entities.h>
-#include <libxml/encoding.h>
-#include <libxml/valid.h>
-#include <libxml/xmlIO.h>
-#include <libxml/globals.h>
-
-#define HTML_MAX_NAMELEN 1000
-#define HTML_PARSER_BIG_BUFFER_SIZE 1000
-#define HTML_PARSER_BUFFER_SIZE 100
-
-/* #define DEBUG */
-/* #define DEBUG_PUSH */
-
-static int htmlOmittedDefaultValue = 1;
-
-xmlChar * htmlDecodeEntities(htmlParserCtxtPtr ctxt, int len,
- xmlChar end, xmlChar end2, xmlChar end3);
-static void htmlParseComment(htmlParserCtxtPtr ctxt);
-
-/************************************************************************
- * *
- * Parser stacks related functions and macros *
- * *
- ************************************************************************/
-
-/**
- * htmlnamePush:
- * @ctxt: an HTML parser context
- * @value: the element name
- *
- * Pushes a new element name on top of the name stack
- *
- * Returns 0 in case of error, the index in the stack otherwise
- */
-static int
-htmlnamePush(htmlParserCtxtPtr ctxt, xmlChar * value)
-{
- if (ctxt->nameNr >= ctxt->nameMax) {
- ctxt->nameMax *= 2;
- ctxt->nameTab =
- (xmlChar * *)xmlRealloc(ctxt->nameTab,
- ctxt->nameMax *
- sizeof(ctxt->nameTab[0]));
- if (ctxt->nameTab == NULL) {
- xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
- return (0);
- }
- }
- ctxt->nameTab[ctxt->nameNr] = value;
- ctxt->name = value;
- return (ctxt->nameNr++);
-}
-/**
- * htmlnamePop:
- * @ctxt: an HTML parser context
- *
- * Pops the top element name from the name stack
- *
- * Returns the name just removed
- */
-static xmlChar *
-htmlnamePop(htmlParserCtxtPtr ctxt)
-{
- xmlChar *ret;
-
- if (ctxt->nameNr <= 0)
- return (0);
- ctxt->nameNr--;
- if (ctxt->nameNr < 0)
- return (0);
- if (ctxt->nameNr > 0)
- ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
- else
- ctxt->name = NULL;
- ret = ctxt->nameTab[ctxt->nameNr];
- ctxt->nameTab[ctxt->nameNr] = 0;
- return (ret);
-}
-
-/*
- * Macros for accessing the content. Those should be used only by the parser,
- * and not exported.
- *
- * Dirty macros, i.e. one need to make assumption on the context to use them
- *
- * CUR_PTR return the current pointer to the xmlChar to be parsed.
- * CUR returns the current xmlChar value, i.e. a 8 bit value if compiled
- * in ISO-Latin or UTF-8, and the current 16 bit value if compiled
- * in UNICODE mode. This should be used internally by the parser
- * only to compare to ASCII values otherwise it would break when
- * running with UTF-8 encoding.
- * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only
- * to compare on ASCII based substring.
- * UPP(n) returns the n'th next xmlChar converted to uppercase. Same as CUR
- * it should be used only to compare on ASCII based substring.
- * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
- * strings within the parser.
- *
- * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
- *
- * CURRENT Returns the current char value, with the full decoding of
- * UTF-8 if we are using this mode. It returns an int.
- * NEXT Skip to the next character, this does the proper decoding
- * in UTF-8 mode. It also pop-up unfinished entities on the fly.
- * COPY(to) copy one char to *to, increment CUR_PTR and to accordingly
- */
-
-#define UPPER (toupper(*ctxt->input->cur))
-
-#define SKIP(val) ctxt->nbChars += (val),ctxt->input->cur += (val)
-
-#define NXT(val) ctxt->input->cur[(val)]
-
-#define UPP(val) (toupper(ctxt->input->cur[(val)]))
-
-#define CUR_PTR ctxt->input->cur
-
-#define SHRINK xmlParserInputShrink(ctxt->input)
-
-#define GROW xmlParserInputGrow(ctxt->input, INPUT_CHUNK)
-
-#define CURRENT ((int) (*ctxt->input->cur))
-
-#define SKIP_BLANKS htmlSkipBlankChars(ctxt)
-
-/* Inported from XML */
-
-/* #define CUR (ctxt->token ? ctxt->token : (int) (*ctxt->input->cur)) */
-#define CUR ((int) (*ctxt->input->cur))
-#define NEXT xmlNextChar(ctxt),ctxt->nbChars++
-
-#define RAW (ctxt->token ? -1 : (*ctxt->input->cur))
-#define NXT(val) ctxt->input->cur[(val)]
-#define CUR_PTR ctxt->input->cur
-
-
-#define NEXTL(l) do { \
- if (*(ctxt->input->cur) == '\n') { \
- ctxt->input->line++; ctxt->input->col = 1; \
- } else ctxt->input->col++; \
- ctxt->token = 0; ctxt->input->cur += l; ctxt->nbChars++; \
- } while (0)
-
-/************
- \
- if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
- if (*ctxt->input->cur == '&') xmlParserHandleReference(ctxt);
- ************/
-
-#define CUR_CHAR(l) htmlCurrentChar(ctxt, &l)
-#define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
-
-#define COPY_BUF(l,b,i,v) \
- if (l == 1) b[i++] = (xmlChar) v; \
- else i += xmlCopyChar(l,&b[i],v)
-
-/**
- * htmlCurrentChar:
- * @ctxt: the HTML parser context
- * @len: pointer to the length of the char read
- *
- * The current char value, if using UTF-8 this may actually span multiple
- * bytes in the input buffer. Implement the end of line normalization:
- * 2.11 End-of-Line Handling
- * If the encoding is unspecified, in the case we find an ISO-Latin-1
- * char, then the encoding converter is plugged in automatically.
- *
- * Returns the current char value and its length
- */
-
-static int
-htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
- if (ctxt->instate == XML_PARSER_EOF)
- return(0);
-
- if (ctxt->token != 0) {
- *len = 0;
- return(ctxt->token);
- }
- if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
- /*
- * We are supposed to handle UTF8, check it's valid
- * From rfc2044: encoding of the Unicode values on UTF-8:
- *
- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
- * 0000 0000-0000 007F 0xxxxxxx
- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
- *
- * Check for the 0x110000 limit too
- */
- const unsigned char *cur = ctxt->input->cur;
- unsigned char c;
- unsigned int val;
-
- c = *cur;
- if (c & 0x80) {
- if (cur[1] == 0)
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- if ((cur[1] & 0xc0) != 0x80)
- goto encoding_error;
- if ((c & 0xe0) == 0xe0) {
-
- if (cur[2] == 0)
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- if ((cur[2] & 0xc0) != 0x80)
- goto encoding_error;
- if ((c & 0xf0) == 0xf0) {
- if (cur[3] == 0)
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- if (((c & 0xf8) != 0xf0) ||
- ((cur[3] & 0xc0) != 0x80))
- goto encoding_error;
- /* 4-byte code */
- *len = 4;
- val = (cur[0] & 0x7) << 18;
- val |= (cur[1] & 0x3f) << 12;
- val |= (cur[2] & 0x3f) << 6;
- val |= cur[3] & 0x3f;
- } else {
- /* 3-byte code */
- *len = 3;
- val = (cur[0] & 0xf) << 12;
- val |= (cur[1] & 0x3f) << 6;
- val |= cur[2] & 0x3f;
- }
- } else {
- /* 2-byte code */
- *len = 2;
- val = (cur[0] & 0x1f) << 6;
- val |= cur[1] & 0x3f;
- }
- if (!IS_CHAR(val)) {
- ctxt->errNo = XML_ERR_INVALID_ENCODING;
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Char 0x%X out of allowed range\n", val);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- return(val);
- } else {
- /* 1-byte code */
- *len = 1;
- return((int) *ctxt->input->cur);
- }
- }
- /*
- * Assume it's a fixed length encoding (1) with
- * a compatible encoding for the ASCII set, since
- * XML constructs only use < 128 chars
- */
- *len = 1;
- if ((int) *ctxt->input->cur < 0x80)
- return((int) *ctxt->input->cur);
-
- /*
- * Humm this is bad, do an automatic flow conversion
- */
- xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1);
- ctxt->charset = XML_CHAR_ENCODING_UTF8;
- return(xmlCurrentChar(ctxt, len));
-
-encoding_error:
- /*
- * If we detect an UTF8 error that probably mean that the
- * input encoding didn't get properly advertized in the
- * declaration header. Report the error and switch the encoding
- * to ISO-Latin-1 (if you don't like this policy, just declare the
- * encoding !)
- */
- ctxt->errNo = XML_ERR_INVALID_ENCODING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
- ctxt->sax->error(ctxt->userData,
- "Input is not proper UTF-8, indicate encoding !\n");
- ctxt->sax->error(ctxt->userData, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
- ctxt->input->cur[0], ctxt->input->cur[1],
- ctxt->input->cur[2], ctxt->input->cur[3]);
- }
-
- ctxt->charset = XML_CHAR_ENCODING_8859_1;
- *len = 1;
- return((int) *ctxt->input->cur);
-}
-
-/**
- * htmlSkipBlankChars:
- * @ctxt: the HTML parser context
- *
- * skip all blanks character found at that point in the input streams.
- *
- * Returns the number of space chars skipped
- */
-
-static int
-htmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
- int res = 0;
-
- while (IS_BLANK(*(ctxt->input->cur))) {
- if ((*ctxt->input->cur == 0) &&
- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) {
- xmlPopInput(ctxt);
- } else {
- if (*(ctxt->input->cur) == '\n') {
- ctxt->input->line++; ctxt->input->col = 1;
- } else ctxt->input->col++;
- ctxt->input->cur++;
- ctxt->nbChars++;
- if (*ctxt->input->cur == 0)
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- }
- res++;
- }
- return(res);
-}
-
-
-
-/************************************************************************
- * *
- * The list of HTML elements and their properties *
- * *
- ************************************************************************/
-
-/*
- * Start Tag: 1 means the start tag can be ommited
- * End Tag: 1 means the end tag can be ommited
- * 2 means it's forbidden (empty elements)
- * 3 means the tag is stylistic and should be closed easily
- * Depr: this element is deprecated
- * DTD: 1 means that this element is valid only in the Loose DTD
- * 2 means that this element is valid only in the Frameset DTD
- *
- * Name,Start Tag,End Tag,Save End,Empty,Deprecated,DTD,inline,Description
- */
-static const htmlElemDesc
-html40ElementTable[] = {
-{ "a", 0, 0, 0, 0, 0, 0, 1, "anchor " },
-{ "abbr", 0, 0, 0, 0, 0, 0, 1, "abbreviated form" },
-{ "acronym", 0, 0, 0, 0, 0, 0, 1, "" },
-{ "address", 0, 0, 0, 0, 0, 0, 0, "information on author " },
-{ "applet", 0, 0, 0, 0, 1, 1, 2, "java applet " },
-{ "area", 0, 2, 2, 1, 0, 0, 0, "client-side image map area " },
-{ "b", 0, 3, 0, 0, 0, 0, 1, "bold text style" },
-{ "base", 0, 2, 2, 1, 0, 0, 0, "document base uri " },
-{ "basefont", 0, 2, 2, 1, 1, 1, 1, "base font size " },
-{ "bdo", 0, 0, 0, 0, 0, 0, 1, "i18n bidi over-ride " },
-{ "big", 0, 3, 0, 0, 0, 0, 1, "large text style" },
-{ "blockquote", 0, 0, 0, 0, 0, 0, 0, "long quotation " },
-{ "body", 1, 1, 0, 0, 0, 0, 0, "document body " },
-{ "br", 0, 2, 2, 1, 0, 0, 1, "forced line break " },
-{ "button", 0, 0, 0, 0, 0, 0, 2, "push button " },
-{ "caption", 0, 0, 0, 0, 0, 0, 0, "table caption " },
-{ "center", 0, 3, 0, 0, 1, 1, 0, "shorthand for div align=center " },
-{ "cite", 0, 0, 0, 0, 0, 0, 1, "citation" },
-{ "code", 0, 0, 0, 0, 0, 0, 1, "computer code fragment" },
-{ "col", 0, 2, 2, 1, 0, 0, 0, "table column " },
-{ "colgroup", 0, 1, 0, 0, 0, 0, 0, "table column group " },
-{ "dd", 0, 1, 0, 0, 0, 0, 0, "definition description " },
-{ "del", 0, 0, 0, 0, 0, 0, 2, "deleted text " },
-{ "dfn", 0, 0, 0, 0, 0, 0, 1, "instance definition" },
-{ "dir", 0, 0, 0, 0, 1, 1, 0, "directory list" },
-{ "div", 0, 0, 0, 0, 0, 0, 0, "generic language/style container"},
-{ "dl", 0, 0, 0, 0, 0, 0, 0, "definition list " },
-{ "dt", 0, 1, 0, 0, 0, 0, 0, "definition term " },
-{ "em", 0, 3, 0, 0, 0, 0, 1, "emphasis" },
-{ "fieldset", 0, 0, 0, 0, 0, 0, 0, "form control group " },
-{ "font", 0, 3, 0, 0, 1, 1, 1, "local change to font " },
-{ "form", 0, 0, 0, 0, 0, 0, 0, "interactive form " },
-{ "frame", 0, 2, 2, 1, 0, 2, 0, "subwindow " },
-{ "frameset", 0, 0, 0, 0, 0, 2, 0, "window subdivision" },
-{ "h1", 0, 0, 0, 0, 0, 0, 0, "heading " },
-{ "h2", 0, 0, 0, 0, 0, 0, 0, "heading " },
-{ "h3", 0, 0, 0, 0, 0, 0, 0, "heading " },
-{ "h4", 0, 0, 0, 0, 0, 0, 0, "heading " },
-{ "h5", 0, 0, 0, 0, 0, 0, 0, "heading " },
-{ "h6", 0, 0, 0, 0, 0, 0, 0, "heading " },
-{ "head", 1, 1, 0, 0, 0, 0, 0, "document head " },
-{ "hr", 0, 2, 2, 1, 0, 0, 0, "horizontal rule " },
-{ "html", 1, 1, 0, 0, 0, 0, 0, "document root element " },
-{ "i", 0, 3, 0, 0, 0, 0, 1, "italic text style" },
-{ "iframe", 0, 0, 0, 0, 0, 1, 2, "inline subwindow " },
-{ "img", 0, 2, 2, 1, 0, 0, 1, "embedded image " },
-{ "input", 0, 2, 2, 1, 0, 0, 1, "form control " },
-{ "ins", 0, 0, 0, 0, 0, 0, 2, "inserted text" },
-{ "isindex", 0, 2, 2, 1, 1, 1, 0, "single line prompt " },
-{ "kbd", 0, 0, 0, 0, 0, 0, 1, "text to be entered by the user" },
-{ "label", 0, 0, 0, 0, 0, 0, 1, "form field label text " },
-{ "legend", 0, 0, 0, 0, 0, 0, 0, "fieldset legend " },
-{ "li", 0, 1, 1, 0, 0, 0, 0, "list item " },
-{ "link", 0, 2, 2, 1, 0, 0, 0, "a media-independent link " },
-{ "map", 0, 0, 0, 0, 0, 0, 2, "client-side image map " },
-{ "menu", 0, 0, 0, 0, 1, 1, 0, "menu list " },
-{ "meta", 0, 2, 2, 1, 0, 0, 0, "generic metainformation " },
-{ "noframes", 0, 0, 0, 0, 0, 2, 0, "alternate content container for non frame-based rendering " },
-{ "noscript", 0, 0, 0, 0, 0, 0, 0, "alternate content container for non script-based rendering " },
-{ "object", 0, 0, 0, 0, 0, 0, 2, "generic embedded object " },
-{ "ol", 0, 0, 0, 0, 0, 0, 0, "ordered list " },
-{ "optgroup", 0, 0, 0, 0, 0, 0, 0, "option group " },
-{ "option", 0, 1, 0, 0, 0, 0, 0, "selectable choice " },
-{ "p", 0, 1, 0, 0, 0, 0, 0, "paragraph " },
-{ "param", 0, 2, 2, 1, 0, 0, 0, "named property value " },
-{ "pre", 0, 0, 0, 0, 0, 0, 0, "preformatted text " },
-{ "q", 0, 0, 0, 0, 0, 0, 1, "short inline quotation " },
-{ "s", 0, 3, 0, 0, 1, 1, 1, "strike-through text style" },
-{ "samp", 0, 0, 0, 0, 0, 0, 1, "sample program output, scripts, etc." },
-{ "script", 0, 0, 0, 0, 0, 0, 2, "script statements " },
-{ "select", 0, 0, 0, 0, 0, 0, 1, "option selector " },
-{ "small", 0, 3, 0, 0, 0, 0, 1, "small text style" },
-{ "span", 0, 0, 0, 0, 0, 0, 1, "generic language/style container " },
-{ "strike", 0, 3, 0, 0, 1, 1, 1, "strike-through text" },
-{ "strong", 0, 3, 0, 0, 0, 0, 1, "strong emphasis" },
-{ "style", 0, 0, 0, 0, 0, 0, 0, "style info " },
-{ "sub", 0, 3, 0, 0, 0, 0, 1, "subscript" },
-{ "sup", 0, 3, 0, 0, 0, 0, 1, "superscript " },
-{ "table", 0, 0, 0, 0, 0, 0, 0, "&#160;" },
-{ "tbody", 1, 0, 0, 0, 0, 0, 0, "table body " },
-{ "td", 0, 0, 0, 0, 0, 0, 0, "table data cell" },
-{ "textarea", 0, 0, 0, 0, 0, 0, 1, "multi-line text field " },
-{ "tfoot", 0, 1, 0, 0, 0, 0, 0, "table footer " },
-{ "th", 0, 1, 0, 0, 0, 0, 0, "table header cell" },
-{ "thead", 0, 1, 0, 0, 0, 0, 0, "table header " },
-{ "title", 0, 0, 0, 0, 0, 0, 0, "document title " },
-{ "tr", 0, 0, 0, 0, 0, 0, 0, "table row " },
-{ "tt", 0, 3, 0, 0, 0, 0, 1, "teletype or monospaced text style" },
-{ "u", 0, 3, 0, 0, 1, 1, 1, "underlined text style" },
-{ "ul", 0, 0, 0, 0, 0, 0, 0, "unordered list " },
-{ "var", 0, 0, 0, 0, 0, 0, 1, "instance of a variable or program argument" },
-};
-
-/*
- * start tags that imply the end of current element
- */
-static const char *htmlStartClose[] = {
-"form", "form", "p", "hr", "h1", "h2", "h3", "h4", "h5", "h6",
- "dl", "ul", "ol", "menu", "dir", "address", "pre",
- "listing", "xmp", "head", NULL,
-"head", "p", NULL,
-"title", "p", NULL,
-"body", "head", "style", "link", "title", "p", NULL,
-"li", "p", "h1", "h2", "h3", "h4", "h5", "h6", "dl", "address",
- "pre", "listing", "xmp", "head", "li", NULL,
-"hr", "p", "head", NULL,
-"h1", "p", "head", NULL,
-"h2", "p", "head", NULL,
-"h3", "p", "head", NULL,
-"h4", "p", "head", NULL,
-"h5", "p", "head", NULL,
-"h6", "p", "head", NULL,
-"dir", "p", "head", NULL,
-"address", "p", "head", "ul", NULL,
-"pre", "p", "head", "ul", NULL,
-"listing", "p", "head", NULL,
-"xmp", "p", "head", NULL,
-"blockquote", "p", "head", NULL,
-"dl", "p", "dt", "menu", "dir", "address", "pre", "listing",
- "xmp", "head", NULL,
-"dt", "p", "menu", "dir", "address", "pre", "listing", "xmp",
- "head", "dd", NULL,
-"dd", "p", "menu", "dir", "address", "pre", "listing", "xmp",
- "head", "dt", NULL,
-"ul", "p", "head", "ol", "menu", "dir", "address", "pre",
- "listing", "xmp", NULL,
-"ol", "p", "head", "ul", NULL,
-"menu", "p", "head", "ul", NULL,
-"p", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6", NULL,
-"div", "p", "head", NULL,
-"noscript", "p", "head", NULL,
-"center", "font", "b", "i", "p", "head", NULL,
-"a", "a", NULL,
-"caption", "p", NULL,
-"colgroup", "caption", "colgroup", "col", "p", NULL,
-"col", "caption", "col", "p", NULL,
-"table", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6", "pre",
- "listing", "xmp", "a", NULL,
-"th", "th", "td", "p", "span", "font", "a", "b", "i", "u", NULL,
-"td", "th", "td", "p", "span", "font", "a", "b", "i", "u", NULL,
-"tr", "th", "td", "tr", "caption", "col", "colgroup", "p", NULL,
-"thead", "caption", "col", "colgroup", NULL,
-"tfoot", "th", "td", "tr", "caption", "col", "colgroup", "thead",
- "tbody", "p", NULL,
-"tbody", "th", "td", "tr", "caption", "col", "colgroup", "thead",
- "tfoot", "tbody", "p", NULL,
-"optgroup", "option", NULL,
-"option", "option", NULL,
-"fieldset", "legend", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6",
- "pre", "listing", "xmp", "a", NULL,
-NULL
-};
-
-/*
- * The list of HTML elements which are supposed not to have
- * CDATA content and where a p element will be implied
- *
- * TODO: extend that list by reading the HTML SGML DTD on
- * implied paragraph
- */
-static const char *htmlNoContentElements[] = {
- "html",
- "head",
- "body",
- NULL
-};
-
-/*
- * The list of HTML attributes which are of content %Script;
- * NOTE: when adding ones, check htmlIsScriptAttribute() since
- * it assumes the name starts with 'on'
- */
-static const char *htmlScriptAttributes[] = {
- "onclick",
- "ondblclick",
- "onmousedown",
- "onmouseup",
- "onmouseover",
- "onmousemove",
- "onmouseout",
- "onkeypress",
- "onkeydown",
- "onkeyup",
- "onload",
- "onunload",
- "onfocus",
- "onblur",
- "onsubmit",
- "onrest",
- "onchange",
- "onselect"
-};
-
-/*
- * This table is used by the htmlparser to know what to do with
- * broken html pages. By assigning different priorities to different
- * elements the parser can decide how to handle extra endtags.
- * Endtags are only allowed to close elements with lower or equal
- * priority.
- */
-
-typedef struct {
- const char *name;
- int priority;
-} elementPriority;
-
-static const elementPriority htmlEndPriority[] = {
- {"div", 150},
- {"td", 160},
- {"th", 160},
- {"tr", 170},
- {"thead", 180},
- {"tbody", 180},
- {"tfoot", 180},
- {"table", 190},
- {"head", 200},
- {"body", 200},
- {"html", 220},
- {NULL, 100} /* Default priority */
-};
-
-static const char** htmlStartCloseIndex[100];
-static int htmlStartCloseIndexinitialized = 0;
-
-/************************************************************************
- * *
- * functions to handle HTML specific data *
- * *
- ************************************************************************/
-
-/**
- * htmlInitAutoClose:
- *
- * Initialize the htmlStartCloseIndex for fast lookup of closing tags names.
- * This is not reentrant. Call xmlInitParser() once before processing in
- * case of use in multithreaded programs.
- */
-void
-htmlInitAutoClose(void) {
- int indx, i = 0;
-
- if (htmlStartCloseIndexinitialized) return;
-
- for (indx = 0;indx < 100;indx ++) htmlStartCloseIndex[indx] = NULL;
- indx = 0;
- while ((htmlStartClose[i] != NULL) && (indx < 100 - 1)) {
- htmlStartCloseIndex[indx++] = &htmlStartClose[i];
- while (htmlStartClose[i] != NULL) i++;
- i++;
- }
- htmlStartCloseIndexinitialized = 1;
-}
-
-/**
- * htmlTagLookup:
- * @tag: The tag name in lowercase
- *
- * Lookup the HTML tag in the ElementTable
- *
- * Returns the related htmlElemDescPtr or NULL if not found.
- */
-const htmlElemDesc *
-htmlTagLookup(const xmlChar *tag) {
- unsigned int i;
-
- for (i = 0; i < (sizeof(html40ElementTable) /
- sizeof(html40ElementTable[0]));i++) {
- if (!xmlStrcasecmp(tag, BAD_CAST html40ElementTable[i].name))
- return((const htmlElemDescPtr) (const htmlElemDescPtr) (const htmlElemDescPtr) (const htmlElemDescPtr) (const htmlElemDescPtr) (const htmlElemDescPtr) (const htmlElemDescPtr) (const htmlElemDescPtr) (const htmlElemDescPtr) &html40ElementTable[i]);
- }
- return(NULL);
-}
-
-/**
- * htmlGetEndPriority:
- * @name: The name of the element to look up the priority for.
- *
- * Return value: The "endtag" priority.
- **/
-static int
-htmlGetEndPriority (const xmlChar *name) {
- int i = 0;
-
- while ((htmlEndPriority[i].name != NULL) &&
- (!xmlStrEqual((const xmlChar *)htmlEndPriority[i].name, name)))
- i++;
-
- return(htmlEndPriority[i].priority);
-}
-
-/**
- * htmlCheckAutoClose:
- * @newtag: The new tag name
- * @oldtag: The old tag name
- *
- * Checks whether the new tag is one of the registered valid tags for
- * closing old.
- * Initialize the htmlStartCloseIndex for fast lookup of closing tags names.
- *
- * Returns 0 if no, 1 if yes.
- */
-static int
-htmlCheckAutoClose(const xmlChar *newtag, const xmlChar *oldtag) {
- int i, indx;
- const char **closed = NULL;
-
- if (htmlStartCloseIndexinitialized == 0) htmlInitAutoClose();
-
- /* inefficient, but not a big deal */
- for (indx = 0; indx < 100;indx++) {
- closed = htmlStartCloseIndex[indx];
- if (closed == NULL) return(0);
- if (xmlStrEqual(BAD_CAST *closed, newtag)) break;
- }
-
- i = closed - htmlStartClose;
- i++;
- while (htmlStartClose[i] != NULL) {
- if (xmlStrEqual(BAD_CAST htmlStartClose[i], oldtag)) {
- return(1);
- }
- i++;
- }
- return(0);
-}
-
-/**
- * htmlAutoCloseOnClose:
- * @ctxt: an HTML parser context
- * @newtag: The new tag name
- * @force: force the tag closure
- *
- * The HTML DTD allows an ending tag to implicitly close other tags.
- */
-static void
-htmlAutoCloseOnClose(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
- const htmlElemDesc * info;
- xmlChar *oldname;
- int i, priority;
-
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"Close of %s stack: %d elements\n", newtag, ctxt->nameNr);
- for (i = 0;i < ctxt->nameNr;i++)
- xmlGenericError(xmlGenericErrorContext,"%d : %s\n", i, ctxt->nameTab[i]);
-#endif
-
- priority = htmlGetEndPriority (newtag);
-
- for (i = (ctxt->nameNr - 1);i >= 0;i--) {
-
- if (xmlStrEqual(newtag, ctxt->nameTab[i])) break;
- /*
- * A missplaced endtag can only close elements with lower
- * or equal priority, so if we find an element with higher
- * priority before we find an element with
- * matching name, we just ignore this endtag
- */
- if (htmlGetEndPriority (ctxt->nameTab[i]) > priority) return;
- }
- if (i < 0) return;
-
- while (!xmlStrEqual(newtag, ctxt->name)) {
- info = htmlTagLookup(ctxt->name);
- if ((info == NULL) || (info->endTag == 1)) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"htmlAutoCloseOnClose: %s closes %s\n", newtag, ctxt->name);
-#endif
- } else if (info->endTag == 3) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"End of tag %s: expecting %s\n", newtag, ctxt->name);
-
-#endif
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Opening and ending tag mismatch: %s and %s\n",
- newtag, ctxt->name);
- ctxt->wellFormed = 0;
- }
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
- ctxt->sax->endElement(ctxt->userData, ctxt->name);
- oldname = htmlnamePop(ctxt);
- if (oldname != NULL) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"htmlAutoCloseOnClose: popped %s\n", oldname);
-#endif
- xmlFree(oldname);
- }
- }
-}
-
-/**
- * htmlAutoCloseOnEnd:
- * @ctxt: an HTML parser context
- *
- * Close all remaining tags at the end of the stream
- */
-static void
-htmlAutoCloseOnEnd(htmlParserCtxtPtr ctxt) {
- xmlChar *oldname;
- int i;
-
- if (ctxt->nameNr == 0)
- return;
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"Close of stack: %d elements\n", ctxt->nameNr);
-#endif
-
- for (i = (ctxt->nameNr - 1);i >= 0;i--) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"%d : %s\n", i, ctxt->nameTab[i]);
-#endif
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
- ctxt->sax->endElement(ctxt->userData, ctxt->name);
- oldname = htmlnamePop(ctxt);
- if (oldname != NULL) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"htmlAutoCloseOnEnd: popped %s\n", oldname);
-#endif
- xmlFree(oldname);
- }
- }
-}
-
-/**
- * htmlAutoClose:
- * @ctxt: an HTML parser context
- * @newtag: The new tag name or NULL
- *
- * The HTML DTD allows a tag to implicitly close other tags.
- * The list is kept in htmlStartClose array. This function is
- * called when a new tag has been detected and generates the
- * appropriates closes if possible/needed.
- * If newtag is NULL this mean we are at the end of the resource
- * and we should check
- */
-static void
-htmlAutoClose(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
- xmlChar *oldname;
- while ((newtag != NULL) && (ctxt->name != NULL) &&
- (htmlCheckAutoClose(newtag, ctxt->name))) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"htmlAutoClose: %s closes %s\n", newtag, ctxt->name);
-#endif
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
- ctxt->sax->endElement(ctxt->userData, ctxt->name);
- oldname = htmlnamePop(ctxt);
- if (oldname != NULL) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"htmlAutoClose: popped %s\n", oldname);
-#endif
- xmlFree(oldname);
- }
- }
- if (newtag == NULL) {
- htmlAutoCloseOnEnd(ctxt);
- return;
- }
- while ((newtag == NULL) && (ctxt->name != NULL) &&
- ((xmlStrEqual(ctxt->name, BAD_CAST"head")) ||
- (xmlStrEqual(ctxt->name, BAD_CAST"body")) ||
- (xmlStrEqual(ctxt->name, BAD_CAST"html")))) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"htmlAutoClose: EOF closes %s\n", ctxt->name);
-#endif
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
- ctxt->sax->endElement(ctxt->userData, ctxt->name);
- oldname = htmlnamePop(ctxt);
- if (oldname != NULL) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"htmlAutoClose: popped %s\n", oldname);
-#endif
- xmlFree(oldname);
- }
- }
-
-}
-
-/**
- * htmlAutoCloseTag:
- * @doc: the HTML document
- * @name: The tag name
- * @elem: the HTML element
- *
- * The HTML DTD allows a tag to implicitly close other tags.
- * The list is kept in htmlStartClose array. This function checks
- * if the element or one of it's children would autoclose the
- * given tag.
- *
- * Returns 1 if autoclose, 0 otherwise
- */
-int
-htmlAutoCloseTag(htmlDocPtr doc, const xmlChar *name, htmlNodePtr elem) {
- htmlNodePtr child;
-
- if (elem == NULL) return(1);
- if (xmlStrEqual(name, elem->name)) return(0);
- if (htmlCheckAutoClose(elem->name, name)) return(1);
- child = elem->children;
- while (child != NULL) {
- if (htmlAutoCloseTag(doc, name, child)) return(1);
- child = child->next;
- }
- return(0);
-}
-
-/**
- * htmlIsAutoClosed:
- * @doc: the HTML document
- * @elem: the HTML element
- *
- * The HTML DTD allows a tag to implicitly close other tags.
- * The list is kept in htmlStartClose array. This function checks
- * if a tag is autoclosed by one of it's child
- *
- * Returns 1 if autoclosed, 0 otherwise
- */
-int
-htmlIsAutoClosed(htmlDocPtr doc, htmlNodePtr elem) {
- htmlNodePtr child;
-
- if (elem == NULL) return(1);
- child = elem->children;
- while (child != NULL) {
- if (htmlAutoCloseTag(doc, elem->name, child)) return(1);
- child = child->next;
- }
- return(0);
-}
-
-/**
- * htmlCheckImplied:
- * @ctxt: an HTML parser context
- * @newtag: The new tag name
- *
- * The HTML DTD allows a tag to exists only implicitly
- * called when a new tag has been detected and generates the
- * appropriates implicit tags if missing
- */
-static void
-htmlCheckImplied(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
- if (!htmlOmittedDefaultValue)
- return;
- if (xmlStrEqual(newtag, BAD_CAST"html"))
- return;
- if (ctxt->nameNr <= 0) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"Implied element html: pushed html\n");
-#endif
- htmlnamePush(ctxt, xmlStrdup(BAD_CAST"html"));
- if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
- ctxt->sax->startElement(ctxt->userData, BAD_CAST"html", NULL);
- }
- if ((xmlStrEqual(newtag, BAD_CAST"body")) || (xmlStrEqual(newtag, BAD_CAST"head")))
- return;
- if ((ctxt->nameNr <= 1) &&
- ((xmlStrEqual(newtag, BAD_CAST"script")) ||
- (xmlStrEqual(newtag, BAD_CAST"style")) ||
- (xmlStrEqual(newtag, BAD_CAST"meta")) ||
- (xmlStrEqual(newtag, BAD_CAST"link")) ||
- (xmlStrEqual(newtag, BAD_CAST"title")) ||
- (xmlStrEqual(newtag, BAD_CAST"base")))) {
- /*
- * dropped OBJECT ... i you put it first BODY will be
- * assumed !
- */
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"Implied element head: pushed head\n");
-#endif
- htmlnamePush(ctxt, xmlStrdup(BAD_CAST"head"));
- if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
- ctxt->sax->startElement(ctxt->userData, BAD_CAST"head", NULL);
- } else if ((!xmlStrEqual(newtag, BAD_CAST"noframes")) &&
- (!xmlStrEqual(newtag, BAD_CAST"frame")) &&
- (!xmlStrEqual(newtag, BAD_CAST"frameset"))) {
- int i;
- for (i = 0;i < ctxt->nameNr;i++) {
- if (xmlStrEqual(ctxt->nameTab[i], BAD_CAST"body")) {
- return;
- }
- if (xmlStrEqual(ctxt->nameTab[i], BAD_CAST"head")) {
- return;
- }
- }
-
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"Implied element body: pushed body\n");
-#endif
- htmlnamePush(ctxt, xmlStrdup(BAD_CAST"body"));
- if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
- ctxt->sax->startElement(ctxt->userData, BAD_CAST"body", NULL);
- }
-}
-
-/**
- * htmlCheckParagraph
- * @ctxt: an HTML parser context
- *
- * Check whether a p element need to be implied before inserting
- * characters in the current element.
- *
- * Returns 1 if a paragraph has been inserted, 0 if not and -1
- * in case of error.
- */
-
-static int
-htmlCheckParagraph(htmlParserCtxtPtr ctxt) {
- const xmlChar *tag;
- int i;
-
- if (ctxt == NULL)
- return(-1);
- tag = ctxt->name;
- if (tag == NULL) {
- htmlAutoClose(ctxt, BAD_CAST"p");
- htmlCheckImplied(ctxt, BAD_CAST"p");
- htmlnamePush(ctxt, xmlStrdup(BAD_CAST"p"));
- if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
- ctxt->sax->startElement(ctxt->userData, BAD_CAST"p", NULL);
- return(1);
- }
- if (!htmlOmittedDefaultValue)
- return(0);
- for (i = 0; htmlNoContentElements[i] != NULL; i++) {
- if (xmlStrEqual(tag, BAD_CAST htmlNoContentElements[i])) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"Implied element paragraph\n");
-#endif
- htmlAutoClose(ctxt, BAD_CAST"p");
- htmlCheckImplied(ctxt, BAD_CAST"p");
- htmlnamePush(ctxt, xmlStrdup(BAD_CAST"p"));
- if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
- ctxt->sax->startElement(ctxt->userData, BAD_CAST"p", NULL);
- return(1);
- }
- }
- return(0);
-}
-
-/**
- * htmlIsScriptAttribute:
- * @name: an attribute name
- *
- * Check if an attribute is of content type Script
- *
- * Returns 1 is the attribute is a script 0 otherwise
- */
-int
-htmlIsScriptAttribute(const xmlChar *name) {
- unsigned int i;
-
- if (name == NULL)
- return(0);
- /*
- * all script attributes start with 'on'
- */
- if ((name[0] != 'o') || (name[1] != 'n'))
- return(0);
- for (i = 0;
- i < sizeof(htmlScriptAttributes)/sizeof(htmlScriptAttributes[0]);
- i++) {
- if (xmlStrEqual(name, (const xmlChar *) htmlScriptAttributes[i]))
- return(1);
- }
- return(0);
-}
-
-/************************************************************************
- * *
- * The list of HTML predefined entities *
- * *
- ************************************************************************/
-
-
-static const htmlEntityDesc html40EntitiesTable[] = {
-/*
- * the 4 absolute ones, plus apostrophe.
- */
-{ 34, "quot", "quotation mark = APL quote, U+0022 ISOnum" },
-{ 38, "amp", "ampersand, U+0026 ISOnum" },
-{ 39, "apos", "single quote" },
-{ 60, "lt", "less-than sign, U+003C ISOnum" },
-{ 62, "gt", "greater-than sign, U+003E ISOnum" },
-
-/*
- * A bunch still in the 128-255 range
- * Replacing them depend really on the charset used.
- */
-{ 160, "nbsp", "no-break space = non-breaking space, U+00A0 ISOnum" },
-{ 161, "iexcl","inverted exclamation mark, U+00A1 ISOnum" },
-{ 162, "cent", "cent sign, U+00A2 ISOnum" },
-{ 163, "pound","pound sign, U+00A3 ISOnum" },
-{ 164, "curren","currency sign, U+00A4 ISOnum" },
-{ 165, "yen", "yen sign = yuan sign, U+00A5 ISOnum" },
-{ 166, "brvbar","broken bar = broken vertical bar, U+00A6 ISOnum" },
-{ 167, "sect", "section sign, U+00A7 ISOnum" },
-{ 168, "uml", "diaeresis = spacing diaeresis, U+00A8 ISOdia" },
-{ 169, "copy", "copyright sign, U+00A9 ISOnum" },
-{ 170, "ordf", "feminine ordinal indicator, U+00AA ISOnum" },
-{ 171, "laquo","left-pointing double angle quotation mark = left pointing guillemet, U+00AB ISOnum" },
-{ 172, "not", "not sign, U+00AC ISOnum" },
-{ 173, "shy", "soft hyphen = discretionary hyphen, U+00AD ISOnum" },
-{ 174, "reg", "registered sign = registered trade mark sign, U+00AE ISOnum" },
-{ 175, "macr", "macron = spacing macron = overline = APL overbar, U+00AF ISOdia" },
-{ 176, "deg", "degree sign, U+00B0 ISOnum" },
-{ 177, "plusmn","plus-minus sign = plus-or-minus sign, U+00B1 ISOnum" },
-{ 178, "sup2", "superscript two = superscript digit two = squared, U+00B2 ISOnum" },
-{ 179, "sup3", "superscript three = superscript digit three = cubed, U+00B3 ISOnum" },
-{ 180, "acute","acute accent = spacing acute, U+00B4 ISOdia" },
-{ 181, "micro","micro sign, U+00B5 ISOnum" },
-{ 182, "para", "pilcrow sign = paragraph sign, U+00B6 ISOnum" },
-{ 183, "middot","middle dot = Georgian comma Greek middle dot, U+00B7 ISOnum" },
-{ 184, "cedil","cedilla = spacing cedilla, U+00B8 ISOdia" },
-{ 185, "sup1", "superscript one = superscript digit one, U+00B9 ISOnum" },
-{ 186, "ordm", "masculine ordinal indicator, U+00BA ISOnum" },
-{ 187, "raquo","right-pointing double angle quotation mark right pointing guillemet, U+00BB ISOnum" },
-{ 188, "frac14","vulgar fraction one quarter = fraction one quarter, U+00BC ISOnum" },
-{ 189, "frac12","vulgar fraction one half = fraction one half, U+00BD ISOnum" },
-{ 190, "frac34","vulgar fraction three quarters = fraction three quarters, U+00BE ISOnum" },
-{ 191, "iquest","inverted question mark = turned question mark, U+00BF ISOnum" },
-{ 192, "Agrave","latin capital letter A with grave = latin capital letter A grave, U+00C0 ISOlat1" },
-{ 193, "Aacute","latin capital letter A with acute, U+00C1 ISOlat1" },
-{ 194, "Acirc","latin capital letter A with circumflex, U+00C2 ISOlat1" },
-{ 195, "Atilde","latin capital letter A with tilde, U+00C3 ISOlat1" },
-{ 196, "Auml", "latin capital letter A with diaeresis, U+00C4 ISOlat1" },
-{ 197, "Aring","latin capital letter A with ring above = latin capital letter A ring, U+00C5 ISOlat1" },
-{ 198, "AElig","latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1" },
-{ 199, "Ccedil","latin capital letter C with cedilla, U+00C7 ISOlat1" },
-{ 200, "Egrave","latin capital letter E with grave, U+00C8 ISOlat1" },
-{ 201, "Eacute","latin capital letter E with acute, U+00C9 ISOlat1" },
-{ 202, "Ecirc","latin capital letter E with circumflex, U+00CA ISOlat1" },
-{ 203, "Euml", "latin capital letter E with diaeresis, U+00CB ISOlat1" },
-{ 204, "Igrave","latin capital letter I with grave, U+00CC ISOlat1" },
-{ 205, "Iacute","latin capital letter I with acute, U+00CD ISOlat1" },
-{ 206, "Icirc","latin capital letter I with circumflex, U+00CE ISOlat1" },
-{ 207, "Iuml", "latin capital letter I with diaeresis, U+00CF ISOlat1" },
-{ 208, "ETH", "latin capital letter ETH, U+00D0 ISOlat1" },
-{ 209, "Ntilde","latin capital letter N with tilde, U+00D1 ISOlat1" },
-{ 210, "Ograve","latin capital letter O with grave, U+00D2 ISOlat1" },
-{ 211, "Oacute","latin capital letter O with acute, U+00D3 ISOlat1" },
-{ 212, "Ocirc","latin capital letter O with circumflex, U+00D4 ISOlat1" },
-{ 213, "Otilde","latin capital letter O with tilde, U+00D5 ISOlat1" },
-{ 214, "Ouml", "latin capital letter O with diaeresis, U+00D6 ISOlat1" },
-{ 215, "times","multiplication sign, U+00D7 ISOnum" },
-{ 216, "Oslash","latin capital letter O with stroke latin capital letter O slash, U+00D8 ISOlat1" },
-{ 217, "Ugrave","latin capital letter U with grave, U+00D9 ISOlat1" },
-{ 218, "Uacute","latin capital letter U with acute, U+00DA ISOlat1" },
-{ 219, "Ucirc","latin capital letter U with circumflex, U+00DB ISOlat1" },
-{ 220, "Uuml", "latin capital letter U with diaeresis, U+00DC ISOlat1" },
-{ 221, "Yacute","latin capital letter Y with acute, U+00DD ISOlat1" },
-{ 222, "THORN","latin capital letter THORN, U+00DE ISOlat1" },
-{ 223, "szlig","latin small letter sharp s = ess-zed, U+00DF ISOlat1" },
-{ 224, "agrave","latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1" },
-{ 225, "aacute","latin small letter a with acute, U+00E1 ISOlat1" },
-{ 226, "acirc","latin small letter a with circumflex, U+00E2 ISOlat1" },
-{ 227, "atilde","latin small letter a with tilde, U+00E3 ISOlat1" },
-{ 228, "auml", "latin small letter a with diaeresis, U+00E4 ISOlat1" },
-{ 229, "aring","latin small letter a with ring above = latin small letter a ring, U+00E5 ISOlat1" },
-{ 230, "aelig","latin small letter ae = latin small ligature ae, U+00E6 ISOlat1" },
-{ 231, "ccedil","latin small letter c with cedilla, U+00E7 ISOlat1" },
-{ 232, "egrave","latin small letter e with grave, U+00E8 ISOlat1" },
-{ 233, "eacute","latin small letter e with acute, U+00E9 ISOlat1" },
-{ 234, "ecirc","latin small letter e with circumflex, U+00EA ISOlat1" },
-{ 235, "euml", "latin small letter e with diaeresis, U+00EB ISOlat1" },
-{ 236, "igrave","latin small letter i with grave, U+00EC ISOlat1" },
-{ 237, "iacute","latin small letter i with acute, U+00ED ISOlat1" },
-{ 238, "icirc","latin small letter i with circumflex, U+00EE ISOlat1" },
-{ 239, "iuml", "latin small letter i with diaeresis, U+00EF ISOlat1" },
-{ 240, "eth", "latin small letter eth, U+00F0 ISOlat1" },
-{ 241, "ntilde","latin small letter n with tilde, U+00F1 ISOlat1" },
-{ 242, "ograve","latin small letter o with grave, U+00F2 ISOlat1" },
-{ 243, "oacute","latin small letter o with acute, U+00F3 ISOlat1" },
-{ 244, "ocirc","latin small letter o with circumflex, U+00F4 ISOlat1" },
-{ 245, "otilde","latin small letter o with tilde, U+00F5 ISOlat1" },
-{ 246, "ouml", "latin small letter o with diaeresis, U+00F6 ISOlat1" },
-{ 247, "divide","division sign, U+00F7 ISOnum" },
-{ 248, "oslash","latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1" },
-{ 249, "ugrave","latin small letter u with grave, U+00F9 ISOlat1" },
-{ 250, "uacute","latin small letter u with acute, U+00FA ISOlat1" },
-{ 251, "ucirc","latin small letter u with circumflex, U+00FB ISOlat1" },
-{ 252, "uuml", "latin small letter u with diaeresis, U+00FC ISOlat1" },
-{ 253, "yacute","latin small letter y with acute, U+00FD ISOlat1" },
-{ 254, "thorn","latin small letter thorn with, U+00FE ISOlat1" },
-{ 255, "yuml", "latin small letter y with diaeresis, U+00FF ISOlat1" },
-
-{ 338, "OElig","latin capital ligature OE, U+0152 ISOlat2" },
-{ 339, "oelig","latin small ligature oe, U+0153 ISOlat2" },
-{ 352, "Scaron","latin capital letter S with caron, U+0160 ISOlat2" },
-{ 353, "scaron","latin small letter s with caron, U+0161 ISOlat2" },
-{ 376, "Yuml", "latin capital letter Y with diaeresis, U+0178 ISOlat2" },
-
-/*
- * Anything below should really be kept as entities references
- */
-{ 402, "fnof", "latin small f with hook = function = florin, U+0192 ISOtech" },
-
-{ 710, "circ", "modifier letter circumflex accent, U+02C6 ISOpub" },
-{ 732, "tilde","small tilde, U+02DC ISOdia" },
-
-{ 913, "Alpha","greek capital letter alpha, U+0391" },
-{ 914, "Beta", "greek capital letter beta, U+0392" },
-{ 915, "Gamma","greek capital letter gamma, U+0393 ISOgrk3" },
-{ 916, "Delta","greek capital letter delta, U+0394 ISOgrk3" },
-{ 917, "Epsilon","greek capital letter epsilon, U+0395" },
-{ 918, "Zeta", "greek capital letter zeta, U+0396" },
-{ 919, "Eta", "greek capital letter eta, U+0397" },
-{ 920, "Theta","greek capital letter theta, U+0398 ISOgrk3" },
-{ 921, "Iota", "greek capital letter iota, U+0399" },
-{ 922, "Kappa","greek capital letter kappa, U+039A" },
-{ 923, "Lambda", "greek capital letter lambda, U+039B ISOgrk3" },
-{ 924, "Mu", "greek capital letter mu, U+039C" },
-{ 925, "Nu", "greek capital letter nu, U+039D" },
-{ 926, "Xi", "greek capital letter xi, U+039E ISOgrk3" },
-{ 927, "Omicron","greek capital letter omicron, U+039F" },
-{ 928, "Pi", "greek capital letter pi, U+03A0 ISOgrk3" },
-{ 929, "Rho", "greek capital letter rho, U+03A1" },
-{ 931, "Sigma","greek capital letter sigma, U+03A3 ISOgrk3" },
-{ 932, "Tau", "greek capital letter tau, U+03A4" },
-{ 933, "Upsilon","greek capital letter upsilon, U+03A5 ISOgrk3" },
-{ 934, "Phi", "greek capital letter phi, U+03A6 ISOgrk3" },
-{ 935, "Chi", "greek capital letter chi, U+03A7" },
-{ 936, "Psi", "greek capital letter psi, U+03A8 ISOgrk3" },
-{ 937, "Omega","greek capital letter omega, U+03A9 ISOgrk3" },
-
-{ 945, "alpha","greek small letter alpha, U+03B1 ISOgrk3" },
-{ 946, "beta", "greek small letter beta, U+03B2 ISOgrk3" },
-{ 947, "gamma","greek small letter gamma, U+03B3 ISOgrk3" },
-{ 948, "delta","greek small letter delta, U+03B4 ISOgrk3" },
-{ 949, "epsilon","greek small letter epsilon, U+03B5 ISOgrk3" },
-{ 950, "zeta", "greek small letter zeta, U+03B6 ISOgrk3" },
-{ 951, "eta", "greek small letter eta, U+03B7 ISOgrk3" },
-{ 952, "theta","greek small letter theta, U+03B8 ISOgrk3" },
-{ 953, "iota", "greek small letter iota, U+03B9 ISOgrk3" },
-{ 954, "kappa","greek small letter kappa, U+03BA ISOgrk3" },
-{ 955, "lambda","greek small letter lambda, U+03BB ISOgrk3" },
-{ 956, "mu", "greek small letter mu, U+03BC ISOgrk3" },
-{ 957, "nu", "greek small letter nu, U+03BD ISOgrk3" },
-{ 958, "xi", "greek small letter xi, U+03BE ISOgrk3" },
-{ 959, "omicron","greek small letter omicron, U+03BF NEW" },
-{ 960, "pi", "greek small letter pi, U+03C0 ISOgrk3" },
-{ 961, "rho", "greek small letter rho, U+03C1 ISOgrk3" },
-{ 962, "sigmaf","greek small letter final sigma, U+03C2 ISOgrk3" },
-{ 963, "sigma","greek small letter sigma, U+03C3 ISOgrk3" },
-{ 964, "tau", "greek small letter tau, U+03C4 ISOgrk3" },
-{ 965, "upsilon","greek small letter upsilon, U+03C5 ISOgrk3" },
-{ 966, "phi", "greek small letter phi, U+03C6 ISOgrk3" },
-{ 967, "chi", "greek small letter chi, U+03C7 ISOgrk3" },
-{ 968, "psi", "greek small letter psi, U+03C8 ISOgrk3" },
-{ 969, "omega","greek small letter omega, U+03C9 ISOgrk3" },
-{ 977, "thetasym","greek small letter theta symbol, U+03D1 NEW" },
-{ 978, "upsih","greek upsilon with hook symbol, U+03D2 NEW" },
-{ 982, "piv", "greek pi symbol, U+03D6 ISOgrk3" },
-
-{ 8194, "ensp", "en space, U+2002 ISOpub" },
-{ 8195, "emsp", "em space, U+2003 ISOpub" },
-{ 8201, "thinsp","thin space, U+2009 ISOpub" },
-{ 8204, "zwnj", "zero width non-joiner, U+200C NEW RFC 2070" },
-{ 8205, "zwj", "zero width joiner, U+200D NEW RFC 2070" },
-{ 8206, "lrm", "left-to-right mark, U+200E NEW RFC 2070" },
-{ 8207, "rlm", "right-to-left mark, U+200F NEW RFC 2070" },
-{ 8211, "ndash","en dash, U+2013 ISOpub" },
-{ 8212, "mdash","em dash, U+2014 ISOpub" },
-{ 8216, "lsquo","left single quotation mark, U+2018 ISOnum" },
-{ 8217, "rsquo","right single quotation mark, U+2019 ISOnum" },
-{ 8218, "sbquo","single low-9 quotation mark, U+201A NEW" },
-{ 8220, "ldquo","left double quotation mark, U+201C ISOnum" },
-{ 8221, "rdquo","right double quotation mark, U+201D ISOnum" },
-{ 8222, "bdquo","double low-9 quotation mark, U+201E NEW" },
-{ 8224, "dagger","dagger, U+2020 ISOpub" },
-{ 8225, "Dagger","double dagger, U+2021 ISOpub" },
-
-{ 8226, "bull", "bullet = black small circle, U+2022 ISOpub" },
-{ 8230, "hellip","horizontal ellipsis = three dot leader, U+2026 ISOpub" },
-
-{ 8240, "permil","per mille sign, U+2030 ISOtech" },
-
-{ 8242, "prime","prime = minutes = feet, U+2032 ISOtech" },
-{ 8243, "Prime","double prime = seconds = inches, U+2033 ISOtech" },
-
-{ 8249, "lsaquo","single left-pointing angle quotation mark, U+2039 ISO proposed" },
-{ 8250, "rsaquo","single right-pointing angle quotation mark, U+203A ISO proposed" },
-
-{ 8254, "oline","overline = spacing overscore, U+203E NEW" },
-{ 8260, "frasl","fraction slash, U+2044 NEW" },
-
-{ 8364, "euro", "euro sign, U+20AC NEW" },
-
-{ 8465, "image","blackletter capital I = imaginary part, U+2111 ISOamso" },
-{ 8472, "weierp","script capital P = power set = Weierstrass p, U+2118 ISOamso" },
-{ 8476, "real", "blackletter capital R = real part symbol, U+211C ISOamso" },
-{ 8482, "trade","trade mark sign, U+2122 ISOnum" },
-{ 8501, "alefsym","alef symbol = first transfinite cardinal, U+2135 NEW" },
-{ 8592, "larr", "leftwards arrow, U+2190 ISOnum" },
-{ 8593, "uarr", "upwards arrow, U+2191 ISOnum" },
-{ 8594, "rarr", "rightwards arrow, U+2192 ISOnum" },
-{ 8595, "darr", "downwards arrow, U+2193 ISOnum" },
-{ 8596, "harr", "left right arrow, U+2194 ISOamsa" },
-{ 8629, "crarr","downwards arrow with corner leftwards = carriage return, U+21B5 NEW" },
-{ 8656, "lArr", "leftwards double arrow, U+21D0 ISOtech" },
-{ 8657, "uArr", "upwards double arrow, U+21D1 ISOamsa" },
-{ 8658, "rArr", "rightwards double arrow, U+21D2 ISOtech" },
-{ 8659, "dArr", "downwards double arrow, U+21D3 ISOamsa" },
-{ 8660, "hArr", "left right double arrow, U+21D4 ISOamsa" },
-
-{ 8704, "forall","for all, U+2200 ISOtech" },
-{ 8706, "part", "partial differential, U+2202 ISOtech" },
-{ 8707, "exist","there exists, U+2203 ISOtech" },
-{ 8709, "empty","empty set = null set = diameter, U+2205 ISOamso" },
-{ 8711, "nabla","nabla = backward difference, U+2207 ISOtech" },
-{ 8712, "isin", "element of, U+2208 ISOtech" },
-{ 8713, "notin","not an element of, U+2209 ISOtech" },
-{ 8715, "ni", "contains as member, U+220B ISOtech" },
-{ 8719, "prod", "n-ary product = product sign, U+220F ISOamsb" },
-{ 8721, "sum", "n-ary summation, U+2211 ISOamsb" },
-{ 8722, "minus","minus sign, U+2212 ISOtech" },
-{ 8727, "lowast","asterisk operator, U+2217 ISOtech" },
-{ 8730, "radic","square root = radical sign, U+221A ISOtech" },
-{ 8733, "prop", "proportional to, U+221D ISOtech" },
-{ 8734, "infin","infinity, U+221E ISOtech" },
-{ 8736, "ang", "angle, U+2220 ISOamso" },
-{ 8743, "and", "logical and = wedge, U+2227 ISOtech" },
-{ 8744, "or", "logical or = vee, U+2228 ISOtech" },
-{ 8745, "cap", "intersection = cap, U+2229 ISOtech" },
-{ 8746, "cup", "union = cup, U+222A ISOtech" },
-{ 8747, "int", "integral, U+222B ISOtech" },
-{ 8756, "there4","therefore, U+2234 ISOtech" },
-{ 8764, "sim", "tilde operator = varies with = similar to, U+223C ISOtech" },
-{ 8773, "cong", "approximately equal to, U+2245 ISOtech" },
-{ 8776, "asymp","almost equal to = asymptotic to, U+2248 ISOamsr" },
-{ 8800, "ne", "not equal to, U+2260 ISOtech" },
-{ 8801, "equiv","identical to, U+2261 ISOtech" },
-{ 8804, "le", "less-than or equal to, U+2264 ISOtech" },
-{ 8805, "ge", "greater-than or equal to, U+2265 ISOtech" },
-{ 8834, "sub", "subset of, U+2282 ISOtech" },
-{ 8835, "sup", "superset of, U+2283 ISOtech" },
-{ 8836, "nsub", "not a subset of, U+2284 ISOamsn" },
-{ 8838, "sube", "subset of or equal to, U+2286 ISOtech" },
-{ 8839, "supe", "superset of or equal to, U+2287 ISOtech" },
-{ 8853, "oplus","circled plus = direct sum, U+2295 ISOamsb" },
-{ 8855, "otimes","circled times = vector product, U+2297 ISOamsb" },
-{ 8869, "perp", "up tack = orthogonal to = perpendicular, U+22A5 ISOtech" },
-{ 8901, "sdot", "dot operator, U+22C5 ISOamsb" },
-{ 8968, "lceil","left ceiling = apl upstile, U+2308 ISOamsc" },
-{ 8969, "rceil","right ceiling, U+2309 ISOamsc" },
-{ 8970, "lfloor","left floor = apl downstile, U+230A ISOamsc" },
-{ 8971, "rfloor","right floor, U+230B ISOamsc" },
-{ 9001, "lang", "left-pointing angle bracket = bra, U+2329 ISOtech" },
-{ 9002, "rang", "right-pointing angle bracket = ket, U+232A ISOtech" },
-{ 9674, "loz", "lozenge, U+25CA ISOpub" },
-
-{ 9824, "spades","black spade suit, U+2660 ISOpub" },
-{ 9827, "clubs","black club suit = shamrock, U+2663 ISOpub" },
-{ 9829, "hearts","black heart suit = valentine, U+2665 ISOpub" },
-{ 9830, "diams","black diamond suit, U+2666 ISOpub" },
-
-};
-
-/************************************************************************
- * *
- * Commodity functions to handle entities *
- * *
- ************************************************************************/
-
-/*
- * Macro used to grow the current buffer.
- */
-#define growBuffer(buffer) { \
- buffer##_size *= 2; \
- buffer = (xmlChar *) xmlRealloc(buffer, buffer##_size * sizeof(xmlChar)); \
- if (buffer == NULL) { \
- xmlGenericError(xmlGenericErrorContext, "realloc failed\n"); \
- return(NULL); \
- } \
-}
-
-/**
- * htmlEntityLookup:
- * @name: the entity name
- *
- * Lookup the given entity in EntitiesTable
- *
- * TODO: the linear scan is really ugly, an hash table is really needed.
- *
- * Returns the associated htmlEntityDescPtr if found, NULL otherwise.
- */
-const htmlEntityDesc *
-htmlEntityLookup(const xmlChar *name) {
- unsigned int i;
-
- for (i = 0;i < (sizeof(html40EntitiesTable)/
- sizeof(html40EntitiesTable[0]));i++) {
- if (xmlStrEqual(name, BAD_CAST html40EntitiesTable[i].name)) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"Found entity %s\n", name);
-#endif
- return((const htmlEntityDescPtr) &html40EntitiesTable[i]);
- }
- }
- return(NULL);
-}
-
-/**
- * htmlEntityValueLookup:
- * @value: the entity's unicode value
- *
- * Lookup the given entity in EntitiesTable
- *
- * TODO: the linear scan is really ugly, an hash table is really needed.
- *
- * Returns the associated htmlEntityDescPtr if found, NULL otherwise.
- */
-const htmlEntityDesc *
-htmlEntityValueLookup(unsigned int value) {
- unsigned int i;
-#ifdef DEBUG
- unsigned int lv = 0;
-#endif
-
- for (i = 0;i < (sizeof(html40EntitiesTable)/
- sizeof(html40EntitiesTable[0]));i++) {
- if (html40EntitiesTable[i].value >= value) {
- if (html40EntitiesTable[i].value > value)
- break;
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"Found entity %s\n", html40EntitiesTable[i].name);
-#endif
- return((const htmlEntityDescPtr) &html40EntitiesTable[i]);
- }
-#ifdef DEBUG
- if (lv > html40EntitiesTable[i].value) {
- xmlGenericError(xmlGenericErrorContext,
- "html40EntitiesTable[] is not sorted (%d > %d)!\n",
- lv, html40EntitiesTable[i].value);
- }
- lv = html40EntitiesTable[i].value;
-#endif
- }
- return(NULL);
-}
-
-/**
- * UTF8ToHtml:
- * @out: a pointer to an array of bytes to store the result
- * @outlen: the length of @out
- * @in: a pointer to an array of UTF-8 chars
- * @inlen: the length of @in
- *
- * Take a block of UTF-8 chars in and try to convert it to an ASCII
- * plus HTML entities block of chars out.
- *
- * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
- * The value of @inlen after return is the number of octets consumed
- * as the return value is positive, else unpredictable.
- * The value of @outlen after return is the number of octets consumed.
- */
-int
-UTF8ToHtml(unsigned char* out, int *outlen,
- const unsigned char* in, int *inlen) {
- const unsigned char* processed = in;
- const unsigned char* outend;
- const unsigned char* outstart = out;
- const unsigned char* instart = in;
- const unsigned char* inend;
- unsigned int c, d;
- int trailing;
-
- if (in == NULL) {
- /*
- * initialization nothing to do
- */
- *outlen = 0;
- *inlen = 0;
- return(0);
- }
- inend = in + (*inlen);
- outend = out + (*outlen);
- while (in < inend) {
- d = *in++;
- if (d < 0x80) { c= d; trailing= 0; }
- else if (d < 0xC0) {
- /* trailing byte in leading position */
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
- else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
- else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
- else {
- /* no chance for this in Ascii */
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- }
-
- if (inend - in < trailing) {
- break;
- }
-
- for ( ; trailing; trailing--) {
- if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
- break;
- c <<= 6;
- c |= d & 0x3F;
- }
-
- /* assertion: c is a single UTF-4 value */
- if (c < 0x80) {
- if (out + 1 >= outend)
- break;
- *out++ = c;
- } else {
- int len;
- const htmlEntityDesc * ent;
-
- /*
- * Try to lookup a predefined HTML entity for it
- */
-
- ent = htmlEntityValueLookup(c);
- if (ent == NULL) {
- /* no chance for this in Ascii */
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- }
- len = strlen(ent->name);
- if (out + 2 + len >= outend)
- break;
- *out++ = '&';
- memcpy(out, ent->name, len);
- out += len;
- *out++ = ';';
- }
- processed = in;
- }
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(0);
-}
-
-/**
- * htmlEncodeEntities:
- * @out: a pointer to an array of bytes to store the result
- * @outlen: the length of @out
- * @in: a pointer to an array of UTF-8 chars
- * @inlen: the length of @in
- * @quoteChar: the quote character to escape (' or ") or zero.
- *
- * Take a block of UTF-8 chars in and try to convert it to an ASCII
- * plus HTML entities block of chars out.
- *
- * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
- * The value of @inlen after return is the number of octets consumed
- * as the return value is positive, else unpredictable.
- * The value of @outlen after return is the number of octets consumed.
- */
-int
-htmlEncodeEntities(unsigned char* out, int *outlen,
- const unsigned char* in, int *inlen, int quoteChar) {
- const unsigned char* processed = in;
- const unsigned char* outend = out + (*outlen);
- const unsigned char* outstart = out;
- const unsigned char* instart = in;
- const unsigned char* inend = in + (*inlen);
- unsigned int c, d;
- int trailing;
-
- while (in < inend) {
- d = *in++;
- if (d < 0x80) { c= d; trailing= 0; }
- else if (d < 0xC0) {
- /* trailing byte in leading position */
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
- else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
- else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
- else {
- /* no chance for this in Ascii */
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- }
-
- if (inend - in < trailing)
- break;
-
- while (trailing--) {
- if (((d= *in++) & 0xC0) != 0x80) {
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- }
- c <<= 6;
- c |= d & 0x3F;
- }
-
- /* assertion: c is a single UTF-4 value */
- if ((c < 0x80) && (c != (unsigned int) quoteChar) &&
- (c != '&') && (c != '<') && (c != '>')) {
- if (out >= outend)
- break;
- *out++ = c;
- } else {
- const htmlEntityDesc * ent;
- const char *cp;
- char nbuf[16];
- int len;
-
- /*
- * Try to lookup a predefined HTML entity for it
- */
- ent = htmlEntityValueLookup(c);
- if (ent == NULL) {
- snprintf(nbuf, sizeof(nbuf), "#%u", c);
- cp = nbuf;
- }
- else
- cp = ent->name;
- len = strlen(cp);
- if (out + 2 + len > outend)
- break;
- *out++ = '&';
- memcpy(out, cp, len);
- out += len;
- *out++ = ';';
- }
- processed = in;
- }
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(0);
-}
-
-/**
- * htmlDecodeEntities:
- * @ctxt: the parser context
- * @len: the len to decode (in bytes !), -1 for no size limit
- * @end: an end marker xmlChar, 0 if none
- * @end2: an end marker xmlChar, 0 if none
- * @end3: an end marker xmlChar, 0 if none
- *
- * Substitute the HTML entities by their value
- *
- * DEPRECATED !!!!
- *
- * Returns A newly allocated string with the substitution done. The caller
- * must deallocate it !
- */
-xmlChar *
-htmlDecodeEntities(htmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED,
- xmlChar end ATTRIBUTE_UNUSED, xmlChar end2 ATTRIBUTE_UNUSED, xmlChar end3 ATTRIBUTE_UNUSED) {
- static int deprecated = 0;
- if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
- "htmlDecodeEntities() deprecated function reached\n");
- deprecated = 1;
- }
- return(NULL);
-}
-
-/************************************************************************
- * *
- * Commodity functions to handle streams *
- * *
- ************************************************************************/
-
-/**
- * htmlNewInputStream:
- * @ctxt: an HTML parser context
- *
- * Create a new input stream structure
- * Returns the new input stream or NULL
- */
-static htmlParserInputPtr
-htmlNewInputStream(htmlParserCtxtPtr ctxt) {
- htmlParserInputPtr input;
-
- input = (xmlParserInputPtr) xmlMalloc(sizeof(htmlParserInput));
- if (input == NULL) {
- ctxt->errNo = XML_ERR_NO_MEMORY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "malloc: couldn't allocate a new input stream\n");
- return(NULL);
- }
- memset(input, 0, sizeof(htmlParserInput));
- input->filename = NULL;
- input->directory = NULL;
- input->base = NULL;
- input->cur = NULL;
- input->buf = NULL;
- input->line = 1;
- input->col = 1;
- input->buf = NULL;
- input->free = NULL;
- input->version = NULL;
- input->consumed = 0;
- input->length = 0;
- return(input);
-}
-
-
-/************************************************************************
- * *
- * Commodity functions, cleanup needed ? *
- * *
- ************************************************************************/
-/*
- * all tags allowing pc data from the html 4.01 loose dtd
- * NOTE: it might be more apropriate to integrate this information
- * into the html40ElementTable array but I don't want to risk any
- * binary incomptibility
- */
-static const char *allowPCData[] = {
- "a", "abbr", "acronym", "address", "applet", "b", "bdo", "big",
- "blockquote", "body", "button", "caption", "center", "cite", "code",
- "dd", "del", "dfn", "div", "dt", "em", "font", "form", "h1", "h2",
- "h3", "h4", "h5", "h6", "i", "iframe", "ins", "kbd", "label", "legend",
- "li", "noframes", "noscript", "object", "p", "pre", "q", "s", "samp",
- "small", "span", "strike", "strong", "td", "th", "tt", "u", "var"
-};
-
-/**
- * areBlanks:
- * @ctxt: an HTML parser context
- * @str: a xmlChar *
- * @len: the size of @str
- *
- * Is this a sequence of blank chars that one can ignore ?
- *
- * Returns 1 if ignorable 0 otherwise.
- */
-
-static int areBlanks(htmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
- unsigned int i;
- int j;
- xmlNodePtr lastChild;
-
- for (j = 0;j < len;j++)
- if (!(IS_BLANK(str[j]))) return(0);
-
- if (CUR == 0) return(1);
- if (CUR != '<') return(0);
- if (ctxt->name == NULL)
- return(1);
- if (xmlStrEqual(ctxt->name, BAD_CAST"html"))
- return(1);
- if (xmlStrEqual(ctxt->name, BAD_CAST"head"))
- return(1);
- if (xmlStrEqual(ctxt->name, BAD_CAST"body"))
- return(1);
- if (ctxt->node == NULL) return(0);
- lastChild = xmlGetLastChild(ctxt->node);
- if (lastChild == NULL) {
- if ((ctxt->node->type != XML_ELEMENT_NODE) &&
- (ctxt->node->content != NULL)) return(0);
- /* keep ws in constructs like ...<b> </b>...
- for all tags "b" allowing PCDATA */
- for ( i = 0; i < sizeof(allowPCData)/sizeof(allowPCData[0]); i++ ) {
- if ( xmlStrEqual(ctxt->name, BAD_CAST allowPCData[i]) ) {
- return(0);
- }
- }
- } else if (xmlNodeIsText(lastChild)) {
- return(0);
- } else {
- /* keep ws in constructs like <p><b>xy</b> <i>z</i><p>
- for all tags "p" allowing PCDATA */
- for ( i = 0; i < sizeof(allowPCData)/sizeof(allowPCData[0]); i++ ) {
- if ( xmlStrEqual(lastChild->name, BAD_CAST allowPCData[i]) ) {
- return(0);
- }
- }
- }
- return(1);
-}
-
-/**
- * htmlNewDocNoDtD:
- * @URI: URI for the dtd, or NULL
- * @ExternalID: the external ID of the DTD, or NULL
- *
- * Creates a new HTML document without a DTD node if @URI and @ExternalID
- * are NULL
- *
- * Returns a new document, do not initialize the DTD if not provided
- */
-htmlDocPtr
-htmlNewDocNoDtD(const xmlChar *URI, const xmlChar *ExternalID) {
- xmlDocPtr cur;
-
- /*
- * Allocate a new document and fill the fields.
- */
- cur = (xmlDocPtr) xmlMalloc(sizeof(xmlDoc));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "htmlNewDocNoDtD : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlDoc));
-
- cur->type = XML_HTML_DOCUMENT_NODE;
- cur->version = NULL;
- cur->intSubset = NULL;
- cur->doc = cur;
- cur->name = NULL;
- cur->children = NULL;
- cur->extSubset = NULL;
- cur->oldNs = NULL;
- cur->encoding = NULL;
- cur->standalone = 1;
- cur->compression = 0;
- cur->ids = NULL;
- cur->refs = NULL;
- cur->_private = NULL;
- if ((ExternalID != NULL) ||
- (URI != NULL))
- xmlCreateIntSubset(cur, BAD_CAST "HTML", ExternalID, URI);
- return(cur);
-}
-
-/**
- * htmlNewDoc:
- * @URI: URI for the dtd, or NULL
- * @ExternalID: the external ID of the DTD, or NULL
- *
- * Creates a new HTML document
- *
- * Returns a new document
- */
-htmlDocPtr
-htmlNewDoc(const xmlChar *URI, const xmlChar *ExternalID) {
- if ((URI == NULL) && (ExternalID == NULL))
- return(htmlNewDocNoDtD(
- BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd",
- BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN"));
-
- return(htmlNewDocNoDtD(URI, ExternalID));
-}
-
-
-/************************************************************************
- * *
- * The parser itself *
- * Relates to http://www.w3.org/TR/html40 *
- * *
- ************************************************************************/
-
-/************************************************************************
- * *
- * The parser itself *
- * *
- ************************************************************************/
-
-/**
- * htmlParseHTMLName:
- * @ctxt: an HTML parser context
- *
- * parse an HTML tag or attribute name, note that we convert it to lowercase
- * since HTML names are not case-sensitive.
- *
- * Returns the Tag Name parsed or NULL
- */
-
-static xmlChar *
-htmlParseHTMLName(htmlParserCtxtPtr ctxt) {
- xmlChar *ret = NULL;
- int i = 0;
- xmlChar loc[HTML_PARSER_BUFFER_SIZE];
-
- if (!IS_LETTER(CUR) && (CUR != '_') &&
- (CUR != ':')) return(NULL);
-
- while ((i < HTML_PARSER_BUFFER_SIZE) &&
- ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
- (CUR == ':') || (CUR == '-') || (CUR == '_'))) {
- if ((CUR >= 'A') && (CUR <= 'Z')) loc[i] = CUR + 0x20;
- else loc[i] = CUR;
- i++;
-
- NEXT;
- }
-
- ret = xmlStrndup(loc, i);
-
- return(ret);
-}
-
-/**
- * htmlParseName:
- * @ctxt: an HTML parser context
- *
- * parse an HTML name, this routine is case sensitive.
- *
- * Returns the Name parsed or NULL
- */
-
-static xmlChar *
-htmlParseName(htmlParserCtxtPtr ctxt) {
- xmlChar buf[HTML_MAX_NAMELEN];
- int len = 0;
-
- GROW;
- if (!IS_LETTER(CUR) && (CUR != '_')) {
- return(NULL);
- }
-
- while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
- (CUR == '.') || (CUR == '-') ||
- (CUR == '_') || (CUR == ':') ||
- (IS_COMBINING(CUR)) ||
- (IS_EXTENDER(CUR))) {
- buf[len++] = CUR;
- NEXT;
- if (len >= HTML_MAX_NAMELEN) {
- xmlGenericError(xmlGenericErrorContext,
- "htmlParseName: reached HTML_MAX_NAMELEN limit\n");
- while ((IS_LETTER(CUR)) || (IS_DIGIT(CUR)) ||
- (CUR == '.') || (CUR == '-') ||
- (CUR == '_') || (CUR == ':') ||
- (IS_COMBINING(CUR)) ||
- (IS_EXTENDER(CUR)))
- NEXT;
- break;
- }
- }
- return(xmlStrndup(buf, len));
-}
-
-/**
- * htmlParseHTMLAttribute:
- * @ctxt: an HTML parser context
- * @stop: a char stop value
- *
- * parse an HTML attribute value till the stop (quote), if
- * stop is 0 then it stops at the first space
- *
- * Returns the attribute parsed or NULL
- */
-
-static xmlChar *
-htmlParseHTMLAttribute(htmlParserCtxtPtr ctxt, const xmlChar stop) {
- xmlChar *buffer = NULL;
- int buffer_size = 0;
- xmlChar *out = NULL;
- xmlChar *name = NULL;
-
- xmlChar *cur = NULL;
- const htmlEntityDesc * ent;
-
- /*
- * allocate a translation buffer.
- */
- buffer_size = HTML_PARSER_BUFFER_SIZE;
- buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
- if (buffer == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "htmlParseHTMLAttribute: malloc failed\n");
- return(NULL);
- }
- out = buffer;
-
- /*
- * Ok loop until we reach one of the ending chars
- */
- while ((CUR != 0) && (CUR != stop)) {
- if ((stop == 0) && (CUR == '>')) break;
- if ((stop == 0) && (IS_BLANK(CUR))) break;
- if (CUR == '&') {
- if (NXT(1) == '#') {
- unsigned int c;
- int bits;
-
- c = htmlParseCharRef(ctxt);
- if (c < 0x80)
- { *out++ = c; bits= -6; }
- else if (c < 0x800)
- { *out++ =((c >> 6) & 0x1F) | 0xC0; bits= 0; }
- else if (c < 0x10000)
- { *out++ =((c >> 12) & 0x0F) | 0xE0; bits= 6; }
- else
- { *out++ =((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
- for ( ; bits >= 0; bits-= 6) {
- *out++ = ((c >> bits) & 0x3F) | 0x80;
- }
-
- if (out - buffer > buffer_size - 100) {
- int indx = out - buffer;
-
- growBuffer(buffer);
- out = &buffer[indx];
- }
- } else {
- ent = htmlParseEntityRef(ctxt, &name);
- if (name == NULL) {
- *out++ = '&';
- if (out - buffer > buffer_size - 100) {
- int indx = out - buffer;
-
- growBuffer(buffer);
- out = &buffer[indx];
- }
- } else if (ent == NULL) {
- *out++ = '&';
- cur = name;
- while (*cur != 0) {
- if (out - buffer > buffer_size - 100) {
- int indx = out - buffer;
-
- growBuffer(buffer);
- out = &buffer[indx];
- }
- *out++ = *cur++;
- }
- xmlFree(name);
- } else {
- unsigned int c;
- int bits;
-
- if (out - buffer > buffer_size - 100) {
- int indx = out - buffer;
-
- growBuffer(buffer);
- out = &buffer[indx];
- }
- c = (xmlChar)ent->value;
- if (c < 0x80)
- { *out++ = c; bits= -6; }
- else if (c < 0x800)
- { *out++ =((c >> 6) & 0x1F) | 0xC0; bits= 0; }
- else if (c < 0x10000)
- { *out++ =((c >> 12) & 0x0F) | 0xE0; bits= 6; }
- else
- { *out++ =((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
- for ( ; bits >= 0; bits-= 6) {
- *out++ = ((c >> bits) & 0x3F) | 0x80;
- }
- xmlFree(name);
- }
- }
- } else {
- unsigned int c;
- int bits, l;
-
- if (out - buffer > buffer_size - 100) {
- int indx = out - buffer;
-
- growBuffer(buffer);
- out = &buffer[indx];
- }
- c = CUR_CHAR(l);
- if (c < 0x80)
- { *out++ = c; bits= -6; }
- else if (c < 0x800)
- { *out++ =((c >> 6) & 0x1F) | 0xC0; bits= 0; }
- else if (c < 0x10000)
- { *out++ =((c >> 12) & 0x0F) | 0xE0; bits= 6; }
- else
- { *out++ =((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
- for ( ; bits >= 0; bits-= 6) {
- *out++ = ((c >> bits) & 0x3F) | 0x80;
- }
- NEXT;
- }
- }
- *out++ = 0;
- return(buffer);
-}
-
-/**
- * htmlParseEntityRef:
- * @ctxt: an HTML parser context
- * @str: location to store the entity name
- *
- * parse an HTML ENTITY references
- *
- * [68] EntityRef ::= '&' Name ';'
- *
- * Returns the associated htmlEntityDescPtr if found, or NULL otherwise,
- * if non-NULL *str will have to be freed by the caller.
- */
-const htmlEntityDesc *
-htmlParseEntityRef(htmlParserCtxtPtr ctxt, xmlChar **str) {
- xmlChar *name;
- const htmlEntityDesc * ent = NULL;
- *str = NULL;
-
- if (CUR == '&') {
- NEXT;
- name = htmlParseName(ctxt);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "htmlParseEntityRef: no name\n");
- ctxt->wellFormed = 0;
- } else {
- GROW;
- if (CUR == ';') {
- *str = name;
-
- /*
- * Lookup the entity in the table.
- */
- ent = htmlEntityLookup(name);
- if (ent != NULL) /* OK that's ugly !!! */
- NEXT;
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "htmlParseEntityRef: expecting ';'\n");
- *str = name;
- }
- }
- }
- return(ent);
-}
-
-/**
- * htmlParseAttValue:
- * @ctxt: an HTML parser context
- *
- * parse a value for an attribute
- * Note: the parser won't do substitution of entities here, this
- * will be handled later in xmlStringGetNodeList, unless it was
- * asked for ctxt->replaceEntities != 0
- *
- * Returns the AttValue parsed or NULL.
- */
-
-static xmlChar *
-htmlParseAttValue(htmlParserCtxtPtr ctxt) {
- xmlChar *ret = NULL;
-
- if (CUR == '"') {
- NEXT;
- ret = htmlParseHTMLAttribute(ctxt, '"');
- if (CUR != '"') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "AttValue: ' expected\n");
- ctxt->wellFormed = 0;
- } else
- NEXT;
- } else if (CUR == '\'') {
- NEXT;
- ret = htmlParseHTMLAttribute(ctxt, '\'');
- if (CUR != '\'') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "AttValue: ' expected\n");
- ctxt->wellFormed = 0;
- } else
- NEXT;
- } else {
- /*
- * That's an HTMLism, the attribute value may not be quoted
- */
- ret = htmlParseHTMLAttribute(ctxt, 0);
- if (ret == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "AttValue: no value found\n");
- ctxt->wellFormed = 0;
- }
- }
- return(ret);
-}
-
-/**
- * htmlParseSystemLiteral:
- * @ctxt: an HTML parser context
- *
- * parse an HTML Literal
- *
- * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
- *
- * Returns the SystemLiteral parsed or NULL
- */
-
-static xmlChar *
-htmlParseSystemLiteral(htmlParserCtxtPtr ctxt) {
- const xmlChar *q;
- xmlChar *ret = NULL;
-
- if (CUR == '"') {
- NEXT;
- q = CUR_PTR;
- while ((IS_CHAR(CUR)) && (CUR != '"'))
- NEXT;
- if (!IS_CHAR(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Unfinished SystemLiteral\n");
- ctxt->wellFormed = 0;
- } else {
- ret = xmlStrndup(q, CUR_PTR - q);
- NEXT;
- }
- } else if (CUR == '\'') {
- NEXT;
- q = CUR_PTR;
- while ((IS_CHAR(CUR)) && (CUR != '\''))
- NEXT;
- if (!IS_CHAR(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Unfinished SystemLiteral\n");
- ctxt->wellFormed = 0;
- } else {
- ret = xmlStrndup(q, CUR_PTR - q);
- NEXT;
- }
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "SystemLiteral \" or ' expected\n");
- ctxt->wellFormed = 0;
- }
-
- return(ret);
-}
-
-/**
- * htmlParsePubidLiteral:
- * @ctxt: an HTML parser context
- *
- * parse an HTML public literal
- *
- * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
- *
- * Returns the PubidLiteral parsed or NULL.
- */
-
-static xmlChar *
-htmlParsePubidLiteral(htmlParserCtxtPtr ctxt) {
- const xmlChar *q;
- xmlChar *ret = NULL;
- /*
- * Name ::= (Letter | '_') (NameChar)*
- */
- if (CUR == '"') {
- NEXT;
- q = CUR_PTR;
- while (IS_PUBIDCHAR(CUR)) NEXT;
- if (CUR != '"') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Unfinished PubidLiteral\n");
- ctxt->wellFormed = 0;
- } else {
- ret = xmlStrndup(q, CUR_PTR - q);
- NEXT;
- }
- } else if (CUR == '\'') {
- NEXT;
- q = CUR_PTR;
- while ((IS_LETTER(CUR)) && (CUR != '\''))
- NEXT;
- if (!IS_LETTER(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Unfinished PubidLiteral\n");
- ctxt->wellFormed = 0;
- } else {
- ret = xmlStrndup(q, CUR_PTR - q);
- NEXT;
- }
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "SystemLiteral \" or ' expected\n");
- ctxt->wellFormed = 0;
- }
-
- return(ret);
-}
-
-/**
- * htmlParseScript:
- * @ctxt: an HTML parser context
- *
- * parse the content of an HTML SCRIPT or STYLE element
- * http://www.w3.org/TR/html4/sgml/dtd.html#Script
- * http://www.w3.org/TR/html4/sgml/dtd.html#StyleSheet
- * http://www.w3.org/TR/html4/types.html#type-script
- * http://www.w3.org/TR/html4/types.html#h-6.15
- * http://www.w3.org/TR/html4/appendix/notes.html#h-B.3.2.1
- *
- * Script data ( %Script; in the DTD) can be the content of the SCRIPT
- * element and the value of intrinsic event attributes. User agents must
- * not evaluate script data as HTML markup but instead must pass it on as
- * data to a script engine.
- * NOTES:
- * - The content is passed like CDATA
- * - the attributes for style and scripting "onXXX" are also described
- * as CDATA but SGML allows entities references in attributes so their
- * processing is identical as other attributes
- */
-static void
-htmlParseScript(htmlParserCtxtPtr ctxt) {
- xmlChar buf[HTML_PARSER_BIG_BUFFER_SIZE + 1];
- int nbchar = 0;
- xmlChar cur;
-
- SHRINK;
- cur = CUR;
- while (IS_CHAR(cur)) {
- if ((cur == '<') && (NXT(1) == '!') && (NXT(2) == '-') &&
- (NXT(3) == '-')) {
- if ((nbchar != 0) && (ctxt->sax != NULL) && (!ctxt->disableSAX)) {
- if (ctxt->sax->cdataBlock!= NULL) {
- /*
- * Insert as CDATA, which is the same as HTML_PRESERVE_NODE
- */
- ctxt->sax->cdataBlock(ctxt->userData, buf, nbchar);
- }
- }
- nbchar = 0;
- htmlParseComment(ctxt);
- cur = CUR;
- continue;
- } else if ((cur == '<') && (NXT(1) == '/')) {
- /*
- * One should break here, the specification is clear:
- * Authors should therefore escape "</" within the content.
- * Escape mechanisms are specific to each scripting or
- * style sheet language.
- */
- if (((NXT(2) >= 'A') && (NXT(2) <= 'Z')) ||
- ((NXT(2) >= 'a') && (NXT(2) <= 'z')))
- break; /* while */
- }
- buf[nbchar++] = cur;
- if (nbchar >= HTML_PARSER_BIG_BUFFER_SIZE) {
- if (ctxt->sax->cdataBlock!= NULL) {
- /*
- * Insert as CDATA, which is the same as HTML_PRESERVE_NODE
- */
- ctxt->sax->cdataBlock(ctxt->userData, buf, nbchar);
- }
- nbchar = 0;
- }
- NEXT;
- cur = CUR;
- }
- if (!(IS_CHAR(cur))) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Invalid char in CDATA 0x%X\n", cur);
- ctxt->wellFormed = 0;
- NEXT;
- }
-
- if ((nbchar != 0) && (ctxt->sax != NULL) && (!ctxt->disableSAX)) {
- if (ctxt->sax->cdataBlock!= NULL) {
- /*
- * Insert as CDATA, which is the same as HTML_PRESERVE_NODE
- */
- ctxt->sax->cdataBlock(ctxt->userData, buf, nbchar);
- }
- }
-}
-
-
-/**
- * htmlParseCharData:
- * @ctxt: an HTML parser context
- *
- * parse a CharData section.
- * if we are within a CDATA section ']]>' marks an end of section.
- *
- * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
- */
-
-static void
-htmlParseCharData(htmlParserCtxtPtr ctxt) {
- xmlChar buf[HTML_PARSER_BIG_BUFFER_SIZE + 5];
- int nbchar = 0;
- int cur, l;
-
- SHRINK;
- cur = CUR_CHAR(l);
- while (((cur != '<') || (ctxt->token == '<')) &&
- ((cur != '&') || (ctxt->token == '&')) &&
- (IS_CHAR(cur))) {
- COPY_BUF(l,buf,nbchar,cur);
- if (nbchar >= HTML_PARSER_BIG_BUFFER_SIZE) {
- /*
- * Ok the segment is to be consumed as chars.
- */
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
- if (areBlanks(ctxt, buf, nbchar)) {
- if (ctxt->sax->ignorableWhitespace != NULL)
- ctxt->sax->ignorableWhitespace(ctxt->userData,
- buf, nbchar);
- } else {
- htmlCheckParagraph(ctxt);
- if (ctxt->sax->characters != NULL)
- ctxt->sax->characters(ctxt->userData, buf, nbchar);
- }
- }
- nbchar = 0;
- }
- NEXTL(l);
- cur = CUR_CHAR(l);
- }
- if (nbchar != 0) {
- /*
- * Ok the segment is to be consumed as chars.
- */
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
- if (areBlanks(ctxt, buf, nbchar)) {
- if (ctxt->sax->ignorableWhitespace != NULL)
- ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
- } else {
- htmlCheckParagraph(ctxt);
- if (ctxt->sax->characters != NULL)
- ctxt->sax->characters(ctxt->userData, buf, nbchar);
- }
- }
- } else {
- /*
- * Loop detection
- */
- if (cur == 0)
- ctxt->instate = XML_PARSER_EOF;
- }
-}
-
-/**
- * htmlParseExternalID:
- * @ctxt: an HTML parser context
- * @publicID: a xmlChar** receiving PubidLiteral
- *
- * Parse an External ID or a Public ID
- *
- * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
- * | 'PUBLIC' S PubidLiteral S SystemLiteral
- *
- * [83] PublicID ::= 'PUBLIC' S PubidLiteral
- *
- * Returns the function returns SystemLiteral and in the second
- * case publicID receives PubidLiteral, is strict is off
- * it is possible to return NULL and have publicID set.
- */
-
-static xmlChar *
-htmlParseExternalID(htmlParserCtxtPtr ctxt, xmlChar **publicID) {
- xmlChar *URI = NULL;
-
- if ((UPPER == 'S') && (UPP(1) == 'Y') &&
- (UPP(2) == 'S') && (UPP(3) == 'T') &&
- (UPP(4) == 'E') && (UPP(5) == 'M')) {
- SKIP(6);
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after 'SYSTEM'\n");
- ctxt->wellFormed = 0;
- }
- SKIP_BLANKS;
- URI = htmlParseSystemLiteral(ctxt);
- if (URI == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "htmlParseExternalID: SYSTEM, no URI\n");
- ctxt->wellFormed = 0;
- }
- } else if ((UPPER == 'P') && (UPP(1) == 'U') &&
- (UPP(2) == 'B') && (UPP(3) == 'L') &&
- (UPP(4) == 'I') && (UPP(5) == 'C')) {
- SKIP(6);
- if (!IS_BLANK(CUR)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after 'PUBLIC'\n");
- ctxt->wellFormed = 0;
- }
- SKIP_BLANKS;
- *publicID = htmlParsePubidLiteral(ctxt);
- if (*publicID == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "htmlParseExternalID: PUBLIC, no Public Identifier\n");
- ctxt->wellFormed = 0;
- }
- SKIP_BLANKS;
- if ((CUR == '"') || (CUR == '\'')) {
- URI = htmlParseSystemLiteral(ctxt);
- }
- }
- return(URI);
-}
-
-/**
- * htmlParseComment:
- * @ctxt: an HTML parser context
- *
- * Parse an XML (SGML) comment <!-- .... -->
- *
- * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
- */
-static void
-htmlParseComment(htmlParserCtxtPtr ctxt) {
- xmlChar *buf = NULL;
- int len;
- int size = HTML_PARSER_BUFFER_SIZE;
- int q, ql;
- int r, rl;
- int cur, l;
- xmlParserInputState state;
-
- /*
- * Check that there is a comment right here.
- */
- if ((RAW != '<') || (NXT(1) != '!') ||
- (NXT(2) != '-') || (NXT(3) != '-')) return;
-
- state = ctxt->instate;
- ctxt->instate = XML_PARSER_COMMENT;
- SHRINK;
- SKIP(4);
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %d byte failed\n", size);
- ctxt->instate = state;
- return;
- }
- q = CUR_CHAR(ql);
- NEXTL(ql);
- r = CUR_CHAR(rl);
- NEXTL(rl);
- cur = CUR_CHAR(l);
- len = 0;
- while (IS_CHAR(cur) &&
- ((cur != '>') ||
- (r != '-') || (q != '-'))) {
- if (len + 5 >= size) {
- size *= 2;
- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc of %d byte failed\n", size);
- ctxt->instate = state;
- return;
- }
- }
- COPY_BUF(ql,buf,len,q);
- q = r;
- ql = rl;
- r = cur;
- rl = l;
- NEXTL(l);
- cur = CUR_CHAR(l);
- if (cur == 0) {
- SHRINK;
- GROW;
- cur = CUR_CHAR(l);
- }
- }
- buf[len] = 0;
- if (!IS_CHAR(cur)) {
- ctxt->errNo = XML_ERR_COMMENT_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Comment not terminated \n<!--%.50s\n", buf);
- ctxt->wellFormed = 0;
- xmlFree(buf);
- } else {
- NEXT;
- if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->comment(ctxt->userData, buf);
- xmlFree(buf);
- }
- ctxt->instate = state;
-}
-
-/**
- * htmlParseCharRef:
- * @ctxt: an HTML parser context
- *
- * parse Reference declarations
- *
- * [66] CharRef ::= '&#' [0-9]+ ';' |
- * '&#x' [0-9a-fA-F]+ ';'
- *
- * Returns the value parsed (as an int)
- */
-int
-htmlParseCharRef(htmlParserCtxtPtr ctxt) {
- int val = 0;
-
- if ((CUR == '&') && (NXT(1) == '#') &&
- (NXT(2) == 'x')) {
- SKIP(3);
- while (CUR != ';') {
- if ((CUR >= '0') && (CUR <= '9'))
- val = val * 16 + (CUR - '0');
- else if ((CUR >= 'a') && (CUR <= 'f'))
- val = val * 16 + (CUR - 'a') + 10;
- else if ((CUR >= 'A') && (CUR <= 'F'))
- val = val * 16 + (CUR - 'A') + 10;
- else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "htmlParseCharRef: invalid hexadecimal value\n");
- ctxt->wellFormed = 0;
- return(0);
- }
- NEXT;
- }
- if (CUR == ';')
- NEXT;
- } else if ((CUR == '&') && (NXT(1) == '#')) {
- SKIP(2);
- while (CUR != ';') {
- if ((CUR >= '0') && (CUR <= '9'))
- val = val * 10 + (CUR - '0');
- else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "htmlParseCharRef: invalid decimal value\n");
- ctxt->wellFormed = 0;
- return(0);
- }
- NEXT;
- }
- if (CUR == ';')
- NEXT;
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "htmlParseCharRef: invalid value\n");
- ctxt->wellFormed = 0;
- }
- /*
- * Check the value IS_CHAR ...
- */
- if (IS_CHAR(val)) {
- return(val);
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "htmlParseCharRef: invalid xmlChar value %d\n",
- val);
- ctxt->wellFormed = 0;
- }
- return(0);
-}
-
-
-/**
- * htmlParseDocTypeDecl:
- * @ctxt: an HTML parser context
- *
- * parse a DOCTYPE declaration
- *
- * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
- * ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
- */
-
-static void
-htmlParseDocTypeDecl(htmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlChar *ExternalID = NULL;
- xmlChar *URI = NULL;
-
- /*
- * We know that '<!DOCTYPE' has been detected.
- */
- SKIP(9);
-
- SKIP_BLANKS;
-
- /*
- * Parse the DOCTYPE name.
- */
- name = htmlParseName(ctxt);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "htmlParseDocTypeDecl : no DOCTYPE name !\n");
- ctxt->wellFormed = 0;
- }
- /*
- * Check that upper(name) == "HTML" !!!!!!!!!!!!!
- */
-
- SKIP_BLANKS;
-
- /*
- * Check for SystemID and ExternalID
- */
- URI = htmlParseExternalID(ctxt, &ExternalID);
- SKIP_BLANKS;
-
- /*
- * We should be at the end of the DOCTYPE declaration.
- */
- if (CUR != '>') {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "DOCTYPE improperly terminated\n");
- ctxt->wellFormed = 0;
- /* We shouldn't try to resynchronize ... */
- }
- NEXT;
-
- /*
- * Create or update the document accordingly to the DOCTYPE
- */
- if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
-
- /*
- * Cleanup, since we don't use all those identifiers
- */
- if (URI != NULL) xmlFree(URI);
- if (ExternalID != NULL) xmlFree(ExternalID);
- if (name != NULL) xmlFree(name);
-}
-
-/**
- * htmlParseAttribute:
- * @ctxt: an HTML parser context
- * @value: a xmlChar ** used to store the value of the attribute
- *
- * parse an attribute
- *
- * [41] Attribute ::= Name Eq AttValue
- *
- * [25] Eq ::= S? '=' S?
- *
- * With namespace:
- *
- * [NS 11] Attribute ::= QName Eq AttValue
- *
- * Also the case QName == xmlns:??? is handled independently as a namespace
- * definition.
- *
- * Returns the attribute name, and the value in *value.
- */
-
-static xmlChar *
-htmlParseAttribute(htmlParserCtxtPtr ctxt, xmlChar **value) {
- xmlChar *name, *val = NULL;
-
- *value = NULL;
- name = htmlParseHTMLName(ctxt);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "error parsing attribute name\n");
- ctxt->wellFormed = 0;
- return(NULL);
- }
-
- /*
- * read the value
- */
- SKIP_BLANKS;
- if (CUR == '=') {
- NEXT;
- SKIP_BLANKS;
- val = htmlParseAttValue(ctxt);
- /******
- } else {
- * TODO : some attribute must have values, some may not
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->warning(ctxt->userData,
- "No value for attribute %s\n", name); */
- }
-
- *value = val;
- return(name);
-}
-
-/**
- * htmlCheckEncoding:
- * @ctxt: an HTML parser context
- * @attvalue: the attribute value
- *
- * Checks an http-equiv attribute from a Meta tag to detect
- * the encoding
- * If a new encoding is detected the parser is switched to decode
- * it and pass UTF8
- */
-static void
-htmlCheckEncoding(htmlParserCtxtPtr ctxt, const xmlChar *attvalue) {
- const xmlChar *encoding;
-
- if ((ctxt == NULL) || (attvalue == NULL))
- return;
-
- /* do not change encoding */
- if (ctxt->input->encoding != NULL)
- return;
-
- encoding = xmlStrcasestr(attvalue, BAD_CAST"charset=");
- if (encoding != NULL) {
- encoding += 8;
- } else {
- encoding = xmlStrcasestr(attvalue, BAD_CAST"charset =");
- if (encoding != NULL)
- encoding += 9;
- }
- if (encoding != NULL) {
- xmlCharEncoding enc;
- xmlCharEncodingHandlerPtr handler;
-
- while ((*encoding == ' ') || (*encoding == '\t')) encoding++;
-
- if (ctxt->input->encoding != NULL)
- xmlFree((xmlChar *) ctxt->input->encoding);
- ctxt->input->encoding = xmlStrdup(encoding);
-
- enc = xmlParseCharEncoding((const char *) encoding);
- /*
- * registered set of known encodings
- */
- if (enc != XML_CHAR_ENCODING_ERROR) {
- xmlSwitchEncoding(ctxt, enc);
- ctxt->charset = XML_CHAR_ENCODING_UTF8;
- } else {
- /*
- * fallback for unknown encodings
- */
- handler = xmlFindCharEncodingHandler((const char *) encoding);
- if (handler != NULL) {
- xmlSwitchToEncoding(ctxt, handler);
- ctxt->charset = XML_CHAR_ENCODING_UTF8;
- } else {
- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
- }
- }
-
- if ((ctxt->input->buf != NULL) &&
- (ctxt->input->buf->encoder != NULL) &&
- (ctxt->input->buf->raw != NULL) &&
- (ctxt->input->buf->buffer != NULL)) {
- int nbchars;
- int processed;
-
- /*
- * convert as much as possible to the parser reading buffer.
- */
- processed = ctxt->input->cur - ctxt->input->base;
- xmlBufferShrink(ctxt->input->buf->buffer, processed);
- nbchars = xmlCharEncInFunc(ctxt->input->buf->encoder,
- ctxt->input->buf->buffer,
- ctxt->input->buf->raw);
- if (nbchars < 0) {
- ctxt->errNo = XML_ERR_INVALID_ENCODING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "htmlCheckEncoding: encoder error\n");
- }
- ctxt->input->base =
- ctxt->input->cur = ctxt->input->buf->buffer->content;
- }
- }
-}
-
-/**
- * htmlCheckMeta:
- * @ctxt: an HTML parser context
- * @atts: the attributes values
- *
- * Checks an attributes from a Meta tag
- */
-static void
-htmlCheckMeta(htmlParserCtxtPtr ctxt, const xmlChar **atts) {
- int i;
- const xmlChar *att, *value;
- int http = 0;
- const xmlChar *content = NULL;
-
- if ((ctxt == NULL) || (atts == NULL))
- return;
-
- i = 0;
- att = atts[i++];
- while (att != NULL) {
- value = atts[i++];
- if ((value != NULL) && (!xmlStrcasecmp(att, BAD_CAST"http-equiv"))
- && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
- http = 1;
- else if ((value != NULL) && (!xmlStrcasecmp(att, BAD_CAST"content")))
- content = value;
- att = atts[i++];
- }
- if ((http) && (content != NULL))
- htmlCheckEncoding(ctxt, content);
-
-}
-
-/**
- * htmlParseStartTag:
- * @ctxt: an HTML parser context
- *
- * parse a start of tag either for rule element or
- * EmptyElement. In both case we don't parse the tag closing chars.
- *
- * [40] STag ::= '<' Name (S Attribute)* S? '>'
- *
- * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
- *
- * With namespace:
- *
- * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
- *
- * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
- *
- */
-
-static void
-htmlParseStartTag(htmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlChar *attname;
- xmlChar *attvalue;
- const xmlChar **atts = NULL;
- int nbatts = 0;
- int maxatts = 0;
- int meta = 0;
- int i;
-
- if (CUR != '<') return;
- NEXT;
-
- GROW;
- name = htmlParseHTMLName(ctxt);
- if (name == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "htmlParseStartTag: invalid element name\n");
- ctxt->wellFormed = 0;
- /* Dump the bogus tag like browsers do */
- while ((IS_CHAR(CUR)) && (CUR != '>'))
- NEXT;
- return;
- }
- if (xmlStrEqual(name, BAD_CAST"meta"))
- meta = 1;
-
- /*
- * Check for auto-closure of HTML elements.
- */
- htmlAutoClose(ctxt, name);
-
- /*
- * Check for implied HTML elements.
- */
- htmlCheckImplied(ctxt, name);
-
- /*
- * Avoid html at any level > 0, head at any level != 1
- * or any attempt to recurse body
- */
- if ((ctxt->nameNr > 0) && (xmlStrEqual(name, BAD_CAST"html"))) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "htmlParseStartTag: misplaced <html> tag\n");
- ctxt->wellFormed = 0;
- xmlFree(name);
- return;
- }
- if ((ctxt->nameNr != 1) &&
- (xmlStrEqual(name, BAD_CAST"head"))) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "htmlParseStartTag: misplaced <head> tag\n");
- ctxt->wellFormed = 0;
- xmlFree(name);
- return;
- }
- if (xmlStrEqual(name, BAD_CAST"body")) {
- int indx;
- for (indx = 0;indx < ctxt->nameNr;indx++) {
- if (xmlStrEqual(ctxt->nameTab[indx], BAD_CAST"body")) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "htmlParseStartTag: misplaced <body> tag\n");
- ctxt->wellFormed = 0;
- xmlFree(name);
- return;
- }
- }
- }
-
- /*
- * Now parse the attributes, it ends up with the ending
- *
- * (S Attribute)* S?
- */
- SKIP_BLANKS;
- while ((IS_CHAR(CUR)) &&
- (CUR != '>') &&
- ((CUR != '/') || (NXT(1) != '>'))) {
- long cons = ctxt->nbChars;
-
- GROW;
- attname = htmlParseAttribute(ctxt, &attvalue);
- if (attname != NULL) {
-
- /*
- * Well formedness requires at most one declaration of an attribute
- */
- for (i = 0; i < nbatts;i += 2) {
- if (xmlStrEqual(atts[i], attname)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Attribute %s redefined\n",
- attname);
- ctxt->wellFormed = 0;
- xmlFree(attname);
- if (attvalue != NULL)
- xmlFree(attvalue);
- goto failed;
- }
- }
-
- /*
- * Add the pair to atts
- */
- if (atts == NULL) {
- maxatts = 10;
- atts = (const xmlChar **) xmlMalloc(maxatts * sizeof(xmlChar *));
- if (atts == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %ld byte failed\n",
- maxatts * (long)sizeof(xmlChar *));
- if (name != NULL) xmlFree(name);
- return;
- }
- } else if (nbatts + 4 > maxatts) {
- maxatts *= 2;
- atts = (const xmlChar **) xmlRealloc((void *) atts,
- maxatts * sizeof(xmlChar *));
- if (atts == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc of %ld byte failed\n",
- maxatts * (long)sizeof(xmlChar *));
- if (name != NULL) xmlFree(name);
- return;
- }
- }
- atts[nbatts++] = attname;
- atts[nbatts++] = attvalue;
- atts[nbatts] = NULL;
- atts[nbatts + 1] = NULL;
- }
- else {
- /* Dump the bogus attribute string up to the next blank or
- * the end of the tag. */
- while ((IS_CHAR(CUR)) && !(IS_BLANK(CUR)) && (CUR != '>')
- && ((CUR != '/') || (NXT(1) != '>')))
- NEXT;
- }
-
-failed:
- SKIP_BLANKS;
- if (cons == ctxt->nbChars) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "htmlParseStartTag: problem parsing attributes\n");
- ctxt->wellFormed = 0;
- break;
- }
- }
-
- /*
- * Handle specific association to the META tag
- */
- if (meta)
- htmlCheckMeta(ctxt, atts);
-
- /*
- * SAX: Start of Element !
- */
- htmlnamePush(ctxt, xmlStrdup(name));
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"Start of element %s: pushed %s\n", name, ctxt->name);
-#endif
- if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
- ctxt->sax->startElement(ctxt->userData, name, atts);
-
- if (atts != NULL) {
- for (i = 0;i < nbatts;i++) {
- if (atts[i] != NULL)
- xmlFree((xmlChar *) atts[i]);
- }
- xmlFree((void *) atts);
- }
- if (name != NULL) xmlFree(name);
-}
-
-/**
- * htmlParseEndTag:
- * @ctxt: an HTML parser context
- *
- * parse an end of tag
- *
- * [42] ETag ::= '</' Name S? '>'
- *
- * With namespace
- *
- * [NS 9] ETag ::= '</' QName S? '>'
- *
- * Returns 1 if the current level should be closed.
- */
-
-static int
-htmlParseEndTag(htmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlChar *oldname;
- int i, ret;
-
- if ((CUR != '<') || (NXT(1) != '/')) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "htmlParseEndTag: '</' not found\n");
- ctxt->wellFormed = 0;
- return(0);
- }
- SKIP(2);
-
- name = htmlParseHTMLName(ctxt);
- if (name == NULL) return(0);
-
- /*
- * We should definitely be at the ending "S? '>'" part
- */
- SKIP_BLANKS;
- if ((!IS_CHAR(CUR)) || (CUR != '>')) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "End tag : expected '>'\n");
- ctxt->wellFormed = 0;
- } else
- NEXT;
-
- /*
- * If the name read is not one of the element in the parsing stack
- * then return, it's just an error.
- */
- for (i = (ctxt->nameNr - 1);i >= 0;i--) {
- if (xmlStrEqual(name, ctxt->nameTab[i])) break;
- }
- if (i < 0) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Unexpected end tag : %s\n", name);
- xmlFree(name);
- ctxt->wellFormed = 0;
- return(0);
- }
-
-
- /*
- * Check for auto-closure of HTML elements.
- */
-
- htmlAutoCloseOnClose(ctxt, name);
-
- /*
- * Well formedness constraints, opening and closing must match.
- * With the exception that the autoclose may have popped stuff out
- * of the stack.
- */
- if (!xmlStrEqual(name, ctxt->name)) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"End of tag %s: expecting %s\n", name, ctxt->name);
-#endif
- if ((ctxt->name != NULL) &&
- (!xmlStrEqual(ctxt->name, name))) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Opening and ending tag mismatch: %s and %s\n",
- name, ctxt->name);
- ctxt->wellFormed = 0;
- }
- }
-
- /*
- * SAX: End of Tag
- */
- oldname = ctxt->name;
- if ((oldname != NULL) && (xmlStrEqual(oldname, name))) {
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
- ctxt->sax->endElement(ctxt->userData, name);
- oldname = htmlnamePop(ctxt);
- if (oldname != NULL) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"End of tag %s: popping out %s\n", name, oldname);
-#endif
- xmlFree(oldname);
-#ifdef DEBUG
- } else {
- xmlGenericError(xmlGenericErrorContext,"End of tag %s: stack empty !!!\n", name);
-#endif
- }
- ret = 1;
- } else {
- ret = 0;
- }
-
- if (name != NULL)
- xmlFree(name);
-
- return(ret);
-}
-
-
-/**
- * htmlParseReference:
- * @ctxt: an HTML parser context
- *
- * parse and handle entity references in content,
- * this will end-up in a call to character() since this is either a
- * CharRef, or a predefined entity.
- */
-static void
-htmlParseReference(htmlParserCtxtPtr ctxt) {
- const htmlEntityDesc * ent;
- xmlChar out[6];
- xmlChar *name;
- if (CUR != '&') return;
-
- if (NXT(1) == '#') {
- unsigned int c;
- int bits, i = 0;
-
- c = htmlParseCharRef(ctxt);
- if (c == 0)
- return;
-
- if (c < 0x80) { out[i++]= c; bits= -6; }
- else if (c < 0x800) { out[i++]=((c >> 6) & 0x1F) | 0xC0; bits= 0; }
- else if (c < 0x10000) { out[i++]=((c >> 12) & 0x0F) | 0xE0; bits= 6; }
- else { out[i++]=((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
- for ( ; bits >= 0; bits-= 6) {
- out[i++]= ((c >> bits) & 0x3F) | 0x80;
- }
- out[i] = 0;
-
- htmlCheckParagraph(ctxt);
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
- ctxt->sax->characters(ctxt->userData, out, i);
- } else {
- ent = htmlParseEntityRef(ctxt, &name);
- if (name == NULL) {
- htmlCheckParagraph(ctxt);
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
- ctxt->sax->characters(ctxt->userData, BAD_CAST "&", 1);
- return;
- }
- if ((ent == NULL) || !(ent->value > 0)) {
- htmlCheckParagraph(ctxt);
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL)) {
- ctxt->sax->characters(ctxt->userData, BAD_CAST "&", 1);
- ctxt->sax->characters(ctxt->userData, name, xmlStrlen(name));
- /* ctxt->sax->characters(ctxt->userData, BAD_CAST ";", 1); */
- }
- } else {
- unsigned int c;
- int bits, i = 0;
-
- c = ent->value;
- if (c < 0x80)
- { out[i++]= c; bits= -6; }
- else if (c < 0x800)
- { out[i++]=((c >> 6) & 0x1F) | 0xC0; bits= 0; }
- else if (c < 0x10000)
- { out[i++]=((c >> 12) & 0x0F) | 0xE0; bits= 6; }
- else
- { out[i++]=((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
- for ( ; bits >= 0; bits-= 6) {
- out[i++]= ((c >> bits) & 0x3F) | 0x80;
- }
- out[i] = 0;
-
- htmlCheckParagraph(ctxt);
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
- ctxt->sax->characters(ctxt->userData, out, i);
- }
- xmlFree(name);
- }
-}
-
-/**
- * htmlParseContent:
- * @ctxt: an HTML parser context
- * @name: the node name
- *
- * Parse a content: comment, sub-element, reference or text.
- *
- */
-
-static void
-htmlParseContent(htmlParserCtxtPtr ctxt) {
- xmlChar *currentNode;
- int depth;
-
- currentNode = xmlStrdup(ctxt->name);
- depth = ctxt->nameNr;
- while (1) {
- long cons = ctxt->nbChars;
-
- GROW;
- /*
- * Our tag or one of it's parent or children is ending.
- */
- if ((CUR == '<') && (NXT(1) == '/')) {
- if (htmlParseEndTag(ctxt) &&
- ((currentNode != NULL) || (ctxt->nameNr == 0))) {
- if (currentNode != NULL)
- xmlFree(currentNode);
- return;
- }
- continue; /* while */
- }
-
- /*
- * Has this node been popped out during parsing of
- * the next element
- */
- if ((ctxt->nameNr > 0) && (depth >= ctxt->nameNr) &&
- (!xmlStrEqual(currentNode, ctxt->name)))
- {
- if (currentNode != NULL) xmlFree(currentNode);
- return;
- }
-
- if ((CUR != 0) && ((xmlStrEqual(currentNode, BAD_CAST"script")) ||
- (xmlStrEqual(currentNode, BAD_CAST"style")))) {
- /*
- * Handle SCRIPT/STYLE separately
- */
- htmlParseScript(ctxt);
- } else {
- /*
- * Sometimes DOCTYPE arrives in the middle of the document
- */
- if ((CUR == '<') && (NXT(1) == '!') &&
- (UPP(2) == 'D') && (UPP(3) == 'O') &&
- (UPP(4) == 'C') && (UPP(5) == 'T') &&
- (UPP(6) == 'Y') && (UPP(7) == 'P') &&
- (UPP(8) == 'E')) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Misplaced DOCTYPE declaration\n");
- ctxt->wellFormed = 0;
- htmlParseDocTypeDecl(ctxt);
- }
-
- /*
- * First case : a comment
- */
- if ((CUR == '<') && (NXT(1) == '!') &&
- (NXT(2) == '-') && (NXT(3) == '-')) {
- htmlParseComment(ctxt);
- }
-
- /*
- * Second case : a sub-element.
- */
- else if (CUR == '<') {
- htmlParseElement(ctxt);
- }
-
- /*
- * Third case : a reference. If if has not been resolved,
- * parsing returns it's Name, create the node
- */
- else if (CUR == '&') {
- htmlParseReference(ctxt);
- }
-
- /*
- * Fourth : end of the resource
- */
- else if (CUR == 0) {
- htmlAutoCloseOnEnd(ctxt);
- break;
- }
-
- /*
- * Last case, text. Note that References are handled directly.
- */
- else {
- htmlParseCharData(ctxt);
- }
-
- if (cons == ctxt->nbChars) {
- if (ctxt->node != NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "detected an error in element content\n");
- ctxt->wellFormed = 0;
- }
- break;
- }
- }
- GROW;
- }
- if (currentNode != NULL) xmlFree(currentNode);
-}
-
-/**
- * htmlParseElement:
- * @ctxt: an HTML parser context
- *
- * parse an HTML element, this is highly recursive
- *
- * [39] element ::= EmptyElemTag | STag content ETag
- *
- * [41] Attribute ::= Name Eq AttValue
- */
-
-void
-htmlParseElement(htmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlChar *currentNode = NULL;
- const htmlElemDesc * info;
- htmlParserNodeInfo node_info;
- xmlChar *oldname;
- int depth = ctxt->nameNr;
- const xmlChar *oldptr;
-
- /* Capture start position */
- if (ctxt->record_info) {
- node_info.begin_pos = ctxt->input->consumed +
- (CUR_PTR - ctxt->input->base);
- node_info.begin_line = ctxt->input->line;
- }
-
- oldname = xmlStrdup(ctxt->name);
- htmlParseStartTag(ctxt);
- name = ctxt->name;
-#ifdef DEBUG
- if (oldname == NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Start of element %s\n", name);
- else if (name == NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Start of element failed, was %s\n", oldname);
- else
- xmlGenericError(xmlGenericErrorContext,
- "Start of element %s, was %s\n", name, oldname);
-#endif
- if (((depth == ctxt->nameNr) && (xmlStrEqual(oldname, ctxt->name))) ||
- (name == NULL)) {
- if (CUR == '>')
- NEXT;
- if (oldname != NULL)
- xmlFree(oldname);
- return;
- }
- if (oldname != NULL)
- xmlFree(oldname);
-
- /*
- * Lookup the info for that element.
- */
- info = htmlTagLookup(name);
- if (info == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Tag %s invalid\n",
- name);
- ctxt->wellFormed = 0;
- } else if (info->depr) {
-/***************************
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData, "Tag %s is deprecated\n",
- name);
- ***************************/
- }
-
- /*
- * Check for an Empty Element labeled the XML/SGML way
- */
- if ((CUR == '/') && (NXT(1) == '>')) {
- SKIP(2);
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
- ctxt->sax->endElement(ctxt->userData, name);
- oldname = htmlnamePop(ctxt);
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"End of tag the XML way: popping out %s\n", oldname);
-#endif
- if (oldname != NULL)
- xmlFree(oldname);
- return;
- }
-
- if (CUR == '>') {
- NEXT;
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Couldn't find end of Start Tag %s\n",
- name);
- ctxt->wellFormed = 0;
-
- /*
- * end of parsing of this node.
- */
- if (xmlStrEqual(name, ctxt->name)) {
- nodePop(ctxt);
- oldname = htmlnamePop(ctxt);
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"End of start tag problem: popping out %s\n", oldname);
-#endif
- if (oldname != NULL)
- xmlFree(oldname);
- }
-
- /*
- * Capture end position and add node
- */
- if ( currentNode != NULL && ctxt->record_info ) {
- node_info.end_pos = ctxt->input->consumed +
- (CUR_PTR - ctxt->input->base);
- node_info.end_line = ctxt->input->line;
- node_info.node = ctxt->node;
- xmlParserAddNodeInfo(ctxt, &node_info);
- }
- return;
- }
-
- /*
- * Check for an Empty Element from DTD definition
- */
- if ((info != NULL) && (info->empty)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
- ctxt->sax->endElement(ctxt->userData, name);
- oldname = htmlnamePop(ctxt);
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"End of empty tag %s : popping out %s\n", name, oldname);
-#endif
- if (oldname != NULL)
- xmlFree(oldname);
- return;
- }
-
- /*
- * Parse the content of the element:
- */
- currentNode = xmlStrdup(ctxt->name);
- depth = ctxt->nameNr;
- while (IS_CHAR(CUR)) {
- oldptr = ctxt->input->cur;
- htmlParseContent(ctxt);
- if (oldptr==ctxt->input->cur) break;
- if (ctxt->nameNr < depth) break;
- }
-
- /*
- * Capture end position and add node
- */
- if ( currentNode != NULL && ctxt->record_info ) {
- node_info.end_pos = ctxt->input->consumed +
- (CUR_PTR - ctxt->input->base);
- node_info.end_line = ctxt->input->line;
- node_info.node = ctxt->node;
- xmlParserAddNodeInfo(ctxt, &node_info);
- }
- if (!IS_CHAR(CUR)) {
- htmlAutoCloseOnEnd(ctxt);
- }
-
- if (currentNode != NULL)
- xmlFree(currentNode);
-}
-
-/**
- * htmlParseDocument:
- * @ctxt: an HTML parser context
- *
- * parse an HTML document (and build a tree if using the standard SAX
- * interface).
- *
- * Returns 0, -1 in case of error. the parser context is augmented
- * as a result of the parsing.
- */
-
-int
-htmlParseDocument(htmlParserCtxtPtr ctxt) {
- xmlDtdPtr dtd;
-
- xmlInitParser();
-
- htmlDefaultSAXHandlerInit();
- ctxt->html = 1;
-
- GROW;
- /*
- * SAX: beginning of the document processing.
- */
- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
- ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
-
- /*
- * Wipe out everything which is before the first '<'
- */
- SKIP_BLANKS;
- if (CUR == 0) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Document is empty\n");
- ctxt->wellFormed = 0;
- }
-
- if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
- ctxt->sax->startDocument(ctxt->userData);
-
-
- /*
- * Parse possible comments before any content
- */
- while ((CUR == '<') && (NXT(1) == '!') &&
- (NXT(2) == '-') && (NXT(3) == '-')) {
- htmlParseComment(ctxt);
- SKIP_BLANKS;
- }
-
-
- /*
- * Then possibly doc type declaration(s) and more Misc
- * (doctypedecl Misc*)?
- */
- if ((CUR == '<') && (NXT(1) == '!') &&
- (UPP(2) == 'D') && (UPP(3) == 'O') &&
- (UPP(4) == 'C') && (UPP(5) == 'T') &&
- (UPP(6) == 'Y') && (UPP(7) == 'P') &&
- (UPP(8) == 'E')) {
- htmlParseDocTypeDecl(ctxt);
- }
- SKIP_BLANKS;
-
- /*
- * Parse possible comments before any content
- */
- while ((CUR == '<') && (NXT(1) == '!') &&
- (NXT(2) == '-') && (NXT(3) == '-')) {
- htmlParseComment(ctxt);
- SKIP_BLANKS;
- }
-
- /*
- * Time to start parsing the tree itself
- */
- htmlParseContent(ctxt);
-
- /*
- * autoclose
- */
- if (CUR == 0)
- htmlAutoCloseOnEnd(ctxt);
-
-
- /*
- * SAX: end of the document processing.
- */
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
-
- if (ctxt->myDoc != NULL) {
- dtd = xmlGetIntSubset(ctxt->myDoc);
- if (dtd == NULL)
- ctxt->myDoc->intSubset =
- xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "HTML",
- BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN",
- BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd");
- }
- if (! ctxt->wellFormed) return(-1);
- return(0);
-}
-
-
-/************************************************************************
- * *
- * Parser contexts handling *
- * *
- ************************************************************************/
-
-/**
- * xmlInitParserCtxt:
- * @ctxt: an HTML parser context
- *
- * Initialize a parser context
- */
-
-static void
-htmlInitParserCtxt(htmlParserCtxtPtr ctxt)
-{
- htmlSAXHandler *sax;
-
- if (ctxt == NULL) return;
- memset(ctxt, 0, sizeof(htmlParserCtxt));
-
- sax = (htmlSAXHandler *) xmlMalloc(sizeof(htmlSAXHandler));
- if (sax == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "htmlInitParserCtxt: out of memory\n");
- }
- else
- memset(sax, 0, sizeof(htmlSAXHandler));
-
- /* Allocate the Input stack */
- ctxt->inputTab = (htmlParserInputPtr *)
- xmlMalloc(5 * sizeof(htmlParserInputPtr));
- if (ctxt->inputTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "htmlInitParserCtxt: out of memory\n");
- ctxt->inputNr = 0;
- ctxt->inputMax = 0;
- ctxt->input = NULL;
- return;
- }
- ctxt->inputNr = 0;
- ctxt->inputMax = 5;
- ctxt->input = NULL;
- ctxt->version = NULL;
- ctxt->encoding = NULL;
- ctxt->standalone = -1;
- ctxt->instate = XML_PARSER_START;
-
- /* Allocate the Node stack */
- ctxt->nodeTab = (htmlNodePtr *) xmlMalloc(10 * sizeof(htmlNodePtr));
- if (ctxt->nodeTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "htmlInitParserCtxt: out of memory\n");
- ctxt->nodeNr = 0;
- ctxt->nodeMax = 0;
- ctxt->node = NULL;
- ctxt->inputNr = 0;
- ctxt->inputMax = 0;
- ctxt->input = NULL;
- return;
- }
- ctxt->nodeNr = 0;
- ctxt->nodeMax = 10;
- ctxt->node = NULL;
-
- /* Allocate the Name stack */
- ctxt->nameTab = (xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
- if (ctxt->nameTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "htmlInitParserCtxt: out of memory\n");
- ctxt->nameNr = 0;
- ctxt->nameMax = 10;
- ctxt->name = NULL;
- ctxt->nodeNr = 0;
- ctxt->nodeMax = 0;
- ctxt->node = NULL;
- ctxt->inputNr = 0;
- ctxt->inputMax = 0;
- ctxt->input = NULL;
- return;
- }
- ctxt->nameNr = 0;
- ctxt->nameMax = 10;
- ctxt->name = NULL;
-
- if (sax == NULL) ctxt->sax = &htmlDefaultSAXHandler;
- else {
- ctxt->sax = sax;
- memcpy(sax, &htmlDefaultSAXHandler, sizeof(htmlSAXHandler));
- }
- ctxt->userData = ctxt;
- ctxt->myDoc = NULL;
- ctxt->wellFormed = 1;
- ctxt->replaceEntities = 0;
- ctxt->linenumbers = xmlLineNumbersDefaultValue;
- ctxt->html = 1;
- ctxt->record_info = 0;
- ctxt->validate = 0;
- ctxt->nbChars = 0;
- ctxt->checkIndex = 0;
- ctxt->catalogs = NULL;
- xmlInitNodeInfoSeq(&ctxt->node_seq);
-}
-
-/**
- * htmlFreeParserCtxt:
- * @ctxt: an HTML parser context
- *
- * Free all the memory used by a parser context. However the parsed
- * document in ctxt->myDoc is not freed.
- */
-
-void
-htmlFreeParserCtxt(htmlParserCtxtPtr ctxt)
-{
- xmlFreeParserCtxt(ctxt);
-}
-
-/**
- * htmlNewParserCtxt:
- *
- * Allocate and initialize a new parser context.
- *
- * Returns the xmlParserCtxtPtr or NULL
- */
-
-static htmlParserCtxtPtr
-htmlNewParserCtxt(void)
-{
- xmlParserCtxtPtr ctxt;
-
- ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
- if (ctxt == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewParserCtxt : cannot allocate context\n");
- return(NULL);
- }
- memset(ctxt, 0, sizeof(xmlParserCtxt));
- htmlInitParserCtxt(ctxt);
- return(ctxt);
-}
-
-/**
- * htmlCreateMemoryParserCtxt:
- * @buffer: a pointer to a char array
- * @size: the size of the array
- *
- * Create a parser context for an HTML in-memory document.
- *
- * Returns the new parser context or NULL
- */
-static htmlParserCtxtPtr
-htmlCreateMemoryParserCtxt(const char *buffer, int size) {
- xmlParserCtxtPtr ctxt;
- xmlParserInputPtr input;
- xmlParserInputBufferPtr buf;
-
- if (buffer == NULL)
- return(NULL);
- if (size <= 0)
- return(NULL);
-
- ctxt = htmlNewParserCtxt();
- if (ctxt == NULL)
- return(NULL);
-
- buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
- if (buf == NULL) return(NULL);
-
- input = xmlNewInputStream(ctxt);
- if (input == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
-
- input->filename = NULL;
- input->buf = buf;
- input->base = input->buf->buffer->content;
- input->cur = input->buf->buffer->content;
- input->end = &input->buf->buffer->content[input->buf->buffer->use];
-
- inputPush(ctxt, input);
- return(ctxt);
-}
-
-/**
- * htmlCreateDocParserCtxt:
- * @cur: a pointer to an array of xmlChar
- * @encoding: a free form C string describing the HTML document encoding, or NULL
- *
- * Create a parser context for an HTML document.
- *
- * TODO: check the need to add encoding handling there
- *
- * Returns the new parser context or NULL
- */
-static htmlParserCtxtPtr
-htmlCreateDocParserCtxt(xmlChar *cur, const char *encoding ATTRIBUTE_UNUSED) {
- int len;
-
- if (cur == NULL)
- return(NULL);
- len = xmlStrlen(cur);
- return(htmlCreateMemoryParserCtxt((char *)cur, len));
-}
-
-/************************************************************************
- * *
- * Progressive parsing interfaces *
- * *
- ************************************************************************/
-
-/**
- * htmlParseLookupSequence:
- * @ctxt: an HTML parser context
- * @first: the first char to lookup
- * @next: the next char to lookup or zero
- * @third: the next char to lookup or zero
- *
- * Try to find if a sequence (first, next, third) or just (first next) or
- * (first) is available in the input stream.
- * This function has a side effect of (possibly) incrementing ctxt->checkIndex
- * to avoid rescanning sequences of bytes, it DOES change the state of the
- * parser, do not use liberally.
- * This is basically similar to xmlParseLookupSequence()
- *
- * Returns the index to the current parsing point if the full sequence
- * is available, -1 otherwise.
- */
-static int
-htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first,
- xmlChar next, xmlChar third) {
- int base, len;
- htmlParserInputPtr in;
- const xmlChar *buf;
- int incomment = 0;
-
- in = ctxt->input;
- if (in == NULL) return(-1);
- base = in->cur - in->base;
- if (base < 0) return(-1);
- if (ctxt->checkIndex > base)
- base = ctxt->checkIndex;
- if (in->buf == NULL) {
- buf = in->base;
- len = in->length;
- } else {
- buf = in->buf->buffer->content;
- len = in->buf->buffer->use;
- }
- /* take into account the sequence length */
- if (third) len -= 2;
- else if (next) len --;
- for (;base < len;base++) {
- if (!incomment && (base + 4 < len)) {
- if ((buf[base] == '<') && (buf[base + 1] == '!') &&
- (buf[base + 2] == '-') && (buf[base + 3] == '-')) {
- incomment = 1;
- }
- /* do not increment base, some people use <!--> */
- }
- if (incomment) {
- if (base + 3 < len)
- return(-1);
- if ((buf[base] == '-') && (buf[base + 1] == '-') &&
- (buf[base + 2] == '>')) {
- incomment = 0;
- base += 2;
- }
- continue;
- }
- if (buf[base] == first) {
- if (third != 0) {
- if ((buf[base + 1] != next) ||
- (buf[base + 2] != third)) continue;
- } else if (next != 0) {
- if (buf[base + 1] != next) continue;
- }
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- if (next == 0)
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c' found at %d\n",
- first, base);
- else if (third == 0)
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c%c' found at %d\n",
- first, next, base);
- else
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c%c%c' found at %d\n",
- first, next, third, base);
-#endif
- return(base - (in->cur - in->base));
- }
- }
- ctxt->checkIndex = base;
-#ifdef DEBUG_PUSH
- if (next == 0)
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c' failed\n", first);
- else if (third == 0)
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c%c' failed\n", first, next);
- else
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c%c%c' failed\n", first, next, third);
-#endif
- return(-1);
-}
-
-/**
- * htmlParseTryOrFinish:
- * @ctxt: an HTML parser context
- * @terminate: last chunk indicator
- *
- * Try to progress on parsing
- *
- * Returns zero if no parsing was possible
- */
-static int
-htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
- int ret = 0;
- htmlParserInputPtr in;
- int avail = 0;
- xmlChar cur, next;
-
-#ifdef DEBUG_PUSH
- switch (ctxt->instate) {
- case XML_PARSER_EOF:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try EOF\n"); break;
- case XML_PARSER_START:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try START\n"); break;
- case XML_PARSER_MISC:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try MISC\n");break;
- case XML_PARSER_COMMENT:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try COMMENT\n");break;
- case XML_PARSER_PROLOG:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try PROLOG\n");break;
- case XML_PARSER_START_TAG:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try START_TAG\n");break;
- case XML_PARSER_CONTENT:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try CONTENT\n");break;
- case XML_PARSER_CDATA_SECTION:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try CDATA_SECTION\n");break;
- case XML_PARSER_END_TAG:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try END_TAG\n");break;
- case XML_PARSER_ENTITY_DECL:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try ENTITY_DECL\n");break;
- case XML_PARSER_ENTITY_VALUE:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try ENTITY_VALUE\n");break;
- case XML_PARSER_ATTRIBUTE_VALUE:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try ATTRIBUTE_VALUE\n");break;
- case XML_PARSER_DTD:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try DTD\n");break;
- case XML_PARSER_EPILOG:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try EPILOG\n");break;
- case XML_PARSER_PI:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try PI\n");break;
- case XML_PARSER_SYSTEM_LITERAL:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: try SYSTEM_LITERAL\n");break;
- }
-#endif
-
- while (1) {
-
- in = ctxt->input;
- if (in == NULL) break;
- if (in->buf == NULL)
- avail = in->length - (in->cur - in->base);
- else
- avail = in->buf->buffer->use - (in->cur - in->base);
- if ((avail == 0) && (terminate)) {
- htmlAutoCloseOnEnd(ctxt);
- if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
- /*
- * SAX: end of the document processing.
- */
- ctxt->instate = XML_PARSER_EOF;
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
- }
- }
- if (avail < 1)
- goto done;
- switch (ctxt->instate) {
- case XML_PARSER_EOF:
- /*
- * Document parsing is done !
- */
- goto done;
- case XML_PARSER_START:
- /*
- * Very first chars read from the document flow.
- */
- cur = in->cur[0];
- if (IS_BLANK(cur)) {
- SKIP_BLANKS;
- if (in->buf == NULL)
- avail = in->length - (in->cur - in->base);
- else
- avail = in->buf->buffer->use - (in->cur - in->base);
- }
- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
- ctxt->sax->setDocumentLocator(ctxt->userData,
- &xmlDefaultSAXLocator);
- if ((ctxt->sax) && (ctxt->sax->startDocument) &&
- (!ctxt->disableSAX))
- ctxt->sax->startDocument(ctxt->userData);
-
- cur = in->cur[0];
- next = in->cur[1];
- if ((cur == '<') && (next == '!') &&
- (UPP(2) == 'D') && (UPP(3) == 'O') &&
- (UPP(4) == 'C') && (UPP(5) == 'T') &&
- (UPP(6) == 'Y') && (UPP(7) == 'P') &&
- (UPP(8) == 'E')) {
- if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: Parsing internal subset\n");
-#endif
- htmlParseDocTypeDecl(ctxt);
- ctxt->instate = XML_PARSER_PROLOG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering PROLOG\n");
-#endif
- } else {
- ctxt->instate = XML_PARSER_MISC;
- }
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering MISC\n");
-#endif
- break;
- case XML_PARSER_MISC:
- SKIP_BLANKS;
- if (in->buf == NULL)
- avail = in->length - (in->cur - in->base);
- else
- avail = in->buf->buffer->use - (in->cur - in->base);
- if (avail < 2)
- goto done;
- cur = in->cur[0];
- next = in->cur[1];
- if ((cur == '<') && (next == '!') &&
- (in->cur[2] == '-') && (in->cur[3] == '-')) {
- if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: Parsing Comment\n");
-#endif
- htmlParseComment(ctxt);
- ctxt->instate = XML_PARSER_MISC;
- } else if ((cur == '<') && (next == '!') &&
- (UPP(2) == 'D') && (UPP(3) == 'O') &&
- (UPP(4) == 'C') && (UPP(5) == 'T') &&
- (UPP(6) == 'Y') && (UPP(7) == 'P') &&
- (UPP(8) == 'E')) {
- if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: Parsing internal subset\n");
-#endif
- htmlParseDocTypeDecl(ctxt);
- ctxt->instate = XML_PARSER_PROLOG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering PROLOG\n");
-#endif
- } else if ((cur == '<') && (next == '!') &&
- (avail < 9)) {
- goto done;
- } else {
- ctxt->instate = XML_PARSER_START_TAG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering START_TAG\n");
-#endif
- }
- break;
- case XML_PARSER_PROLOG:
- SKIP_BLANKS;
- if (in->buf == NULL)
- avail = in->length - (in->cur - in->base);
- else
- avail = in->buf->buffer->use - (in->cur - in->base);
- if (avail < 2)
- goto done;
- cur = in->cur[0];
- next = in->cur[1];
- if ((cur == '<') && (next == '!') &&
- (in->cur[2] == '-') && (in->cur[3] == '-')) {
- if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: Parsing Comment\n");
-#endif
- htmlParseComment(ctxt);
- ctxt->instate = XML_PARSER_PROLOG;
- } else if ((cur == '<') && (next == '!') &&
- (avail < 4)) {
- goto done;
- } else {
- ctxt->instate = XML_PARSER_START_TAG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering START_TAG\n");
-#endif
- }
- break;
- case XML_PARSER_EPILOG:
- if (in->buf == NULL)
- avail = in->length - (in->cur - in->base);
- else
- avail = in->buf->buffer->use - (in->cur - in->base);
- if (avail < 1)
- goto done;
- cur = in->cur[0];
- if (IS_BLANK(cur)) {
- htmlParseCharData(ctxt);
- goto done;
- }
- if (avail < 2)
- goto done;
- next = in->cur[1];
- if ((cur == '<') && (next == '!') &&
- (in->cur[2] == '-') && (in->cur[3] == '-')) {
- if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: Parsing Comment\n");
-#endif
- htmlParseComment(ctxt);
- ctxt->instate = XML_PARSER_EPILOG;
- } else if ((cur == '<') && (next == '!') &&
- (avail < 4)) {
- goto done;
- } else {
- ctxt->errNo = XML_ERR_DOCUMENT_END;
- ctxt->wellFormed = 0;
- ctxt->instate = XML_PARSER_EOF;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering EOF\n");
-#endif
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
- goto done;
- }
- break;
- case XML_PARSER_START_TAG: {
- xmlChar *name, *oldname;
- int depth = ctxt->nameNr;
- const htmlElemDesc * info;
-
- if (avail < 2)
- goto done;
- cur = in->cur[0];
- if (cur != '<') {
- ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- }
- if (in->cur[1] == '/') {
- ctxt->instate = XML_PARSER_END_TAG;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering END_TAG\n");
-#endif
- break;
- }
- if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
- goto done;
-
- oldname = xmlStrdup(ctxt->name);
- htmlParseStartTag(ctxt);
- name = ctxt->name;
-#ifdef DEBUG
- if (oldname == NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Start of element %s\n", name);
- else if (name == NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Start of element failed, was %s\n",
- oldname);
- else
- xmlGenericError(xmlGenericErrorContext,
- "Start of element %s, was %s\n",
- name, oldname);
-#endif
- if (((depth == ctxt->nameNr) &&
- (xmlStrEqual(oldname, ctxt->name))) ||
- (name == NULL)) {
- if (CUR == '>')
- NEXT;
- if (oldname != NULL)
- xmlFree(oldname);
- break;
- }
- if (oldname != NULL)
- xmlFree(oldname);
-
- /*
- * Lookup the info for that element.
- */
- info = htmlTagLookup(name);
- if (info == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Tag %s invalid\n",
- name);
- ctxt->wellFormed = 0;
- } else if (info->depr) {
- /***************************
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "Tag %s is deprecated\n",
- name);
- ***************************/
- }
-
- /*
- * Check for an Empty Element labeled the XML/SGML way
- */
- if ((CUR == '/') && (NXT(1) == '>')) {
- SKIP(2);
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
- ctxt->sax->endElement(ctxt->userData, name);
- oldname = htmlnamePop(ctxt);
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"End of tag the XML way: popping out %s\n",
- oldname);
-#endif
- if (oldname != NULL)
- xmlFree(oldname);
- ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- }
-
- if (CUR == '>') {
- NEXT;
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Couldn't find end of Start Tag %s\n",
- name);
- ctxt->wellFormed = 0;
-
- /*
- * end of parsing of this node.
- */
- if (xmlStrEqual(name, ctxt->name)) {
- nodePop(ctxt);
- oldname = htmlnamePop(ctxt);
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,
- "End of start tag problem: popping out %s\n", oldname);
-#endif
- if (oldname != NULL)
- xmlFree(oldname);
- }
-
- ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- }
-
- /*
- * Check for an Empty Element from DTD definition
- */
- if ((info != NULL) && (info->empty)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
- ctxt->sax->endElement(ctxt->userData, name);
- oldname = htmlnamePop(ctxt);
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,"End of empty tag %s : popping out %s\n", name, oldname);
-#endif
- if (oldname != NULL)
- xmlFree(oldname);
- }
- ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- }
- case XML_PARSER_CONTENT: {
- long cons;
- /*
- * Handle preparsed entities and charRef
- */
- if (ctxt->token != 0) {
- xmlChar chr[2] = { 0 , 0 } ;
-
- chr[0] = (xmlChar) ctxt->token;
- htmlCheckParagraph(ctxt);
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
- ctxt->sax->characters(ctxt->userData, chr, 1);
- ctxt->token = 0;
- ctxt->checkIndex = 0;
- }
- if ((avail == 1) && (terminate)) {
- cur = in->cur[0];
- if ((cur != '<') && (cur != '&')) {
- if (ctxt->sax != NULL) {
- if (IS_BLANK(cur)) {
- if (ctxt->sax->ignorableWhitespace != NULL)
- ctxt->sax->ignorableWhitespace(
- ctxt->userData, &cur, 1);
- } else {
- htmlCheckParagraph(ctxt);
- if (ctxt->sax->characters != NULL)
- ctxt->sax->characters(
- ctxt->userData, &cur, 1);
- }
- }
- ctxt->token = 0;
- ctxt->checkIndex = 0;
- in->cur++;
- break;
- }
- }
- if (avail < 2)
- goto done;
- cur = in->cur[0];
- next = in->cur[1];
- cons = ctxt->nbChars;
- if ((xmlStrEqual(ctxt->name, BAD_CAST"script")) ||
- (xmlStrEqual(ctxt->name, BAD_CAST"style"))) {
- /*
- * Handle SCRIPT/STYLE separately
- */
- if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '<', '/', 0) < 0))
- goto done;
- htmlParseScript(ctxt);
- if ((cur == '<') && (next == '/')) {
- ctxt->instate = XML_PARSER_END_TAG;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering END_TAG\n");
-#endif
- break;
- }
- } else {
- /*
- * Sometimes DOCTYPE arrives in the middle of the document
- */
- if ((cur == '<') && (next == '!') &&
- (UPP(2) == 'D') && (UPP(3) == 'O') &&
- (UPP(4) == 'C') && (UPP(5) == 'T') &&
- (UPP(6) == 'Y') && (UPP(7) == 'P') &&
- (UPP(8) == 'E')) {
- if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
- goto done;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Misplaced DOCTYPE declaration\n");
- ctxt->wellFormed = 0;
- htmlParseDocTypeDecl(ctxt);
- } else if ((cur == '<') && (next == '!') &&
- (in->cur[2] == '-') && (in->cur[3] == '-')) {
- if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: Parsing Comment\n");
-#endif
- htmlParseComment(ctxt);
- ctxt->instate = XML_PARSER_CONTENT;
- } else if ((cur == '<') && (next == '!') && (avail < 4)) {
- goto done;
- } else if ((cur == '<') && (next == '/')) {
- ctxt->instate = XML_PARSER_END_TAG;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering END_TAG\n");
-#endif
- break;
- } else if (cur == '<') {
- ctxt->instate = XML_PARSER_START_TAG;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering START_TAG\n");
-#endif
- break;
- } else if (cur == '&') {
- if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: Parsing Reference\n");
-#endif
- /* TODO: check generation of subtrees if noent !!! */
- htmlParseReference(ctxt);
- } else {
- /* TODO Avoid the extra copy, handle directly !!!!!! */
- /*
- * Goal of the following test is:
- * - minimize calls to the SAX 'character' callback
- * when they are mergeable
- */
- if ((ctxt->inputNr == 1) &&
- (avail < HTML_PARSER_BIG_BUFFER_SIZE)) {
- if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '<', 0, 0) < 0))
- goto done;
- }
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: Parsing char data\n");
-#endif
- htmlParseCharData(ctxt);
- }
- }
- if (cons == ctxt->nbChars) {
- if (ctxt->node != NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "detected an error in element content\n");
- ctxt->wellFormed = 0;
- }
- NEXT;
- break;
- }
-
- break;
- }
- case XML_PARSER_END_TAG:
- if (avail < 2)
- goto done;
- if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
- goto done;
- htmlParseEndTag(ctxt);
- if (ctxt->nameNr == 0) {
- ctxt->instate = XML_PARSER_EPILOG;
- } else {
- ctxt->instate = XML_PARSER_CONTENT;
- }
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- case XML_PARSER_CDATA_SECTION:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == CDATA\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- case XML_PARSER_DTD:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == DTD\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- case XML_PARSER_COMMENT:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == COMMENT\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- case XML_PARSER_PI:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == PI\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- case XML_PARSER_ENTITY_DECL:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == ENTITY_DECL\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- case XML_PARSER_ENTITY_VALUE:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == ENTITY_VALUE\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering DTD\n");
-#endif
- break;
- case XML_PARSER_ATTRIBUTE_VALUE:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == ATTRIBUTE_VALUE\n");
- ctxt->instate = XML_PARSER_START_TAG;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering START_TAG\n");
-#endif
- break;
- case XML_PARSER_SYSTEM_LITERAL:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == XML_PARSER_SYSTEM_LITERAL\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- case XML_PARSER_IGNORE:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == XML_PARSER_IGNORE\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
- case XML_PARSER_PUBLIC_LITERAL:
- xmlGenericError(xmlGenericErrorContext,
- "HPP: internal error, state == XML_PARSER_LITERAL\n");
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "HPP: entering CONTENT\n");
-#endif
- break;
-
- }
- }
-done:
- if ((avail == 0) && (terminate)) {
- htmlAutoCloseOnEnd(ctxt);
- if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
- /*
- * SAX: end of the document processing.
- */
- ctxt->instate = XML_PARSER_EOF;
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
- }
- }
- if ((ctxt->myDoc != NULL) &&
- ((terminate) || (ctxt->instate == XML_PARSER_EOF) ||
- (ctxt->instate == XML_PARSER_EPILOG))) {
- xmlDtdPtr dtd;
- dtd = xmlGetIntSubset(ctxt->myDoc);
- if (dtd == NULL)
- ctxt->myDoc->intSubset =
- xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "HTML",
- BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN",
- BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd");
- }
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext, "HPP: done %d\n", ret);
-#endif
- return(ret);
-}
-
-/**
- * htmlParseChunk:
- * @ctxt: an XML parser context
- * @chunk: an char array
- * @size: the size in byte of the chunk
- * @terminate: last chunk indicator
- *
- * Parse a Chunk of memory
- *
- * Returns zero if no error, the xmlParserErrors otherwise.
- */
-int
-htmlParseChunk(htmlParserCtxtPtr ctxt, const char *chunk, int size,
- int terminate) {
- if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
- (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF)) {
- int base = ctxt->input->base - ctxt->input->buf->buffer->content;
- int cur = ctxt->input->cur - ctxt->input->base;
-
- xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
- ctxt->input->base = ctxt->input->buf->buffer->content + base;
- ctxt->input->cur = ctxt->input->base + cur;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext, "HPP: pushed %d\n", size);
-#endif
-
- if ((terminate) || (ctxt->input->buf->buffer->use > 80))
- htmlParseTryOrFinish(ctxt, terminate);
- } else if (ctxt->instate != XML_PARSER_EOF) {
- xmlParserInputBufferPush(ctxt->input->buf, 0, "");
- htmlParseTryOrFinish(ctxt, terminate);
- }
- if (terminate) {
- if ((ctxt->instate != XML_PARSER_EOF) &&
- (ctxt->instate != XML_PARSER_EPILOG) &&
- (ctxt->instate != XML_PARSER_MISC)) {
- ctxt->errNo = XML_ERR_DOCUMENT_END;
- ctxt->wellFormed = 0;
- }
- if (ctxt->instate != XML_PARSER_EOF) {
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
- }
- ctxt->instate = XML_PARSER_EOF;
- }
- return((xmlParserErrors) ctxt->errNo);
-}
-
-/************************************************************************
- * *
- * User entry points *
- * *
- ************************************************************************/
-
-/**
- * htmlCreatePushParserCtxt:
- * @sax: a SAX handler
- * @user_data: The user data returned on SAX callbacks
- * @chunk: a pointer to an array of chars
- * @size: number of chars in the array
- * @filename: an optional file name or URI
- * @enc: an optional encoding
- *
- * Create a parser context for using the HTML parser in push mode
- * To allow content encoding detection, @size should be >= 4
- * The value of @filename is used for fetching external entities
- * and error/warning reports.
- *
- * Returns the new parser context or NULL
- */
-htmlParserCtxtPtr
-htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, void *user_data,
- const char *chunk, int size, const char *filename,
- xmlCharEncoding enc) {
- htmlParserCtxtPtr ctxt;
- htmlParserInputPtr inputStream;
- xmlParserInputBufferPtr buf;
-
- xmlInitParser();
-
- buf = xmlAllocParserInputBuffer(enc);
- if (buf == NULL) return(NULL);
-
- ctxt = (htmlParserCtxtPtr) xmlMalloc(sizeof(htmlParserCtxt));
- if (ctxt == NULL) {
- xmlFree(buf);
- return(NULL);
- }
- memset(ctxt, 0, sizeof(htmlParserCtxt));
- htmlInitParserCtxt(ctxt);
- if (sax != NULL) {
- if (ctxt->sax != &htmlDefaultSAXHandler)
- xmlFree(ctxt->sax);
- ctxt->sax = (htmlSAXHandlerPtr) xmlMalloc(sizeof(htmlSAXHandler));
- if (ctxt->sax == NULL) {
- xmlFree(buf);
- xmlFree(ctxt);
- return(NULL);
- }
- memcpy(ctxt->sax, sax, sizeof(htmlSAXHandler));
- if (user_data != NULL)
- ctxt->userData = user_data;
- }
- if (filename == NULL) {
- ctxt->directory = NULL;
- } else {
- ctxt->directory = xmlParserGetDirectory(filename);
- }
-
- inputStream = htmlNewInputStream(ctxt);
- if (inputStream == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
-
- if (filename == NULL)
- inputStream->filename = NULL;
- else
- inputStream->filename = xmlMemStrdup(filename);
- inputStream->buf = buf;
- inputStream->base = inputStream->buf->buffer->content;
- inputStream->cur = inputStream->buf->buffer->content;
-
- inputPush(ctxt, inputStream);
-
- if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
- (ctxt->input->buf != NULL)) {
- xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext, "HPP: pushed %d\n", size);
-#endif
- }
-
- return(ctxt);
-}
-
-/**
- * htmlSAXParseDoc:
- * @cur: a pointer to an array of xmlChar
- * @encoding: a free form C string describing the HTML document encoding, or NULL
- * @sax: the SAX handler block
- * @userData: if using SAX, this pointer will be provided on callbacks.
- *
- * Parse an HTML in-memory document. If sax is not NULL, use the SAX callbacks
- * to handle parse events. If sax is NULL, fallback to the default DOM
- * behavior and return a tree.
- *
- * Returns the resulting document tree unless SAX is NULL or the document is
- * not well formed.
- */
-
-htmlDocPtr
-htmlSAXParseDoc(xmlChar *cur, const char *encoding, htmlSAXHandlerPtr sax, void *userData) {
- htmlDocPtr ret;
- htmlParserCtxtPtr ctxt;
-
- xmlInitParser();
-
- if (cur == NULL) return(NULL);
-
-
- ctxt = htmlCreateDocParserCtxt(cur, encoding);
- if (ctxt == NULL) return(NULL);
- if (sax != NULL) {
- ctxt->sax = sax;
- ctxt->userData = userData;
- }
-
- htmlParseDocument(ctxt);
- ret = ctxt->myDoc;
- if (sax != NULL) {
- ctxt->sax = NULL;
- ctxt->userData = NULL;
- }
- htmlFreeParserCtxt(ctxt);
-
- return(ret);
-}
-
-/**
- * htmlParseDoc:
- * @cur: a pointer to an array of xmlChar
- * @encoding: a free form C string describing the HTML document encoding, or NULL
- *
- * parse an HTML in-memory document and build a tree.
- *
- * Returns the resulting document tree
- */
-
-htmlDocPtr
-htmlParseDoc(xmlChar *cur, const char *encoding) {
- return(htmlSAXParseDoc(cur, encoding, NULL, NULL));
-}
-
-
-/**
- * htmlCreateFileParserCtxt:
- * @filename: the filename
- * @encoding: a free form C string describing the HTML document encoding, or NULL
- *
- * Create a parser context for a file content.
- * Automatic support for ZLIB/Compress compressed document is provided
- * by default if found at compile-time.
- *
- * Returns the new parser context or NULL
- */
-htmlParserCtxtPtr
-htmlCreateFileParserCtxt(const char *filename, const char *encoding)
-{
- htmlParserCtxtPtr ctxt;
- htmlParserInputPtr inputStream;
- xmlParserInputBufferPtr buf;
- /* htmlCharEncoding enc; */
- xmlChar *content, *content_line = (xmlChar *) "charset=";
-
- buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
- if (buf == NULL) return(NULL);
-
- ctxt = (htmlParserCtxtPtr) xmlMalloc(sizeof(htmlParserCtxt));
- if (ctxt == NULL) {
- xmlGenericError(xmlGenericErrorContext, "malloc failed\n");
- return(NULL);
- }
- memset(ctxt, 0, sizeof(htmlParserCtxt));
- htmlInitParserCtxt(ctxt);
- inputStream = (htmlParserInputPtr) xmlMalloc(sizeof(htmlParserInput));
- if (inputStream == NULL) {
- xmlGenericError(xmlGenericErrorContext, "malloc failed\n");
- xmlFree(ctxt);
- return(NULL);
- }
- memset(inputStream, 0, sizeof(htmlParserInput));
-
- inputStream->filename = (char *)
- xmlNormalizeWindowsPath((xmlChar *)filename);
- inputStream->line = 1;
- inputStream->col = 1;
- inputStream->buf = buf;
- inputStream->directory = NULL;
-
- inputStream->base = inputStream->buf->buffer->content;
- inputStream->cur = inputStream->buf->buffer->content;
- inputStream->free = NULL;
-
- inputPush(ctxt, inputStream);
-
- /* set encoding */
- if (encoding) {
- content = xmlMalloc (xmlStrlen(content_line) + strlen(encoding) + 1);
- if (content) {
- strcpy ((char *)content, (char *)content_line);
- strcat ((char *)content, (char *)encoding);
- htmlCheckEncoding (ctxt, content);
- xmlFree (content);
- }
- }
-
- return(ctxt);
-}
-
-/**
- * htmlSAXParseFile:
- * @filename: the filename
- * @encoding: a free form C string describing the HTML document encoding, or NULL
- * @sax: the SAX handler block
- * @userData: if using SAX, this pointer will be provided on callbacks.
- *
- * parse an HTML file and build a tree. Automatic support for ZLIB/Compress
- * compressed document is provided by default if found at compile-time.
- * It use the given SAX function block to handle the parsing callback.
- * If sax is NULL, fallback to the default DOM tree building routines.
- *
- * Returns the resulting document tree unless SAX is NULL or the document is
- * not well formed.
- */
-
-htmlDocPtr
-htmlSAXParseFile(const char *filename, const char *encoding, htmlSAXHandlerPtr sax,
- void *userData) {
- htmlDocPtr ret;
- htmlParserCtxtPtr ctxt;
- htmlSAXHandlerPtr oldsax = NULL;
-
- xmlInitParser();
-
- ctxt = htmlCreateFileParserCtxt(filename, encoding);
- if (ctxt == NULL) return(NULL);
- if (sax != NULL) {
- oldsax = ctxt->sax;
- ctxt->sax = sax;
- ctxt->userData = userData;
- }
-
- htmlParseDocument(ctxt);
-
- ret = ctxt->myDoc;
- if (sax != NULL) {
- ctxt->sax = oldsax;
- ctxt->userData = NULL;
- }
- htmlFreeParserCtxt(ctxt);
-
- return(ret);
-}
-
-/**
- * htmlParseFile:
- * @filename: the filename
- * @encoding: a free form C string describing the HTML document encoding, or NULL
- *
- * parse an HTML file and build a tree. Automatic support for ZLIB/Compress
- * compressed document is provided by default if found at compile-time.
- *
- * Returns the resulting document tree
- */
-
-htmlDocPtr
-htmlParseFile(const char *filename, const char *encoding) {
- return(htmlSAXParseFile(filename, encoding, NULL, NULL));
-}
-
-/**
- * htmlHandleOmittedElem:
- * @val: int 0 or 1
- *
- * Set and return the previous value for handling HTML omitted tags.
- *
- * Returns the last value for 0 for no handling, 1 for auto insertion.
- */
-
-int
-htmlHandleOmittedElem(int val) {
- int old = htmlOmittedDefaultValue;
-
- htmlOmittedDefaultValue = val;
- return(old);
-}
-
-#endif /* LIBXML_HTML_ENABLED */
diff --git a/bundle/libxml/HTMLtree.c b/bundle/libxml/HTMLtree.c
deleted file mode 100644
index fe69b3dee9..0000000000
--- a/bundle/libxml/HTMLtree.c
+++ /dev/null
@@ -1,1099 +0,0 @@
-/*
- * HTMLtree.c : implementation of access function for an HTML tree.
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-
-#define IN_LIBXML
-#include "libxml.h"
-#ifdef LIBXML_HTML_ENABLED
-
-#include <string.h> /* for memset() only ! */
-
-#ifdef HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#include <libxml/xmlmemory.h>
-#include <libxml/HTMLparser.h>
-#include <libxml/HTMLtree.h>
-#include <libxml/entities.h>
-#include <libxml/valid.h>
-#include <libxml/xmlerror.h>
-#include <libxml/parserInternals.h>
-#include <libxml/globals.h>
-#include <libxml/uri.h>
-
-/************************************************************************
- * *
- * Getting/Setting encoding meta tags *
- * *
- ************************************************************************/
-
-/**
- * htmlGetMetaEncoding:
- * @doc: the document
- *
- * Encoding definition lookup in the Meta tags
- *
- * Returns the current encoding as flagged in the HTML source
- */
-const xmlChar *
-htmlGetMetaEncoding(htmlDocPtr doc) {
- htmlNodePtr cur;
- const xmlChar *content;
- const xmlChar *encoding;
-
- if (doc == NULL)
- return(NULL);
- cur = doc->children;
-
- /*
- * Search the html
- */
- while (cur != NULL) {
- if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
- if (xmlStrEqual(cur->name, BAD_CAST"html"))
- break;
- if (xmlStrEqual(cur->name, BAD_CAST"head"))
- goto found_head;
- if (xmlStrEqual(cur->name, BAD_CAST"meta"))
- goto found_meta;
- }
- cur = cur->next;
- }
- if (cur == NULL)
- return(NULL);
- cur = cur->children;
-
- /*
- * Search the head
- */
- while (cur != NULL) {
- if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
- if (xmlStrEqual(cur->name, BAD_CAST"head"))
- break;
- if (xmlStrEqual(cur->name, BAD_CAST"meta"))
- goto found_meta;
- }
- cur = cur->next;
- }
- if (cur == NULL)
- return(NULL);
-found_head:
- cur = cur->children;
-
- /*
- * Search the meta elements
- */
-found_meta:
- while (cur != NULL) {
- if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
- if (xmlStrEqual(cur->name, BAD_CAST"meta")) {
- xmlAttrPtr attr = cur->properties;
- int http;
- const xmlChar *value;
-
- content = NULL;
- http = 0;
- while (attr != NULL) {
- if ((attr->children != NULL) &&
- (attr->children->type == XML_TEXT_NODE) &&
- (attr->children->next == NULL)) {
- value = attr->children->content;
- if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv"))
- && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
- http = 1;
- else if ((value != NULL)
- && (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
- content = value;
- if ((http != 0) && (content != NULL))
- goto found_content;
- }
- attr = attr->next;
- }
- }
- }
- cur = cur->next;
- }
- return(NULL);
-
-found_content:
- encoding = xmlStrstr(content, BAD_CAST"charset=");
- if (encoding == NULL)
- encoding = xmlStrstr(content, BAD_CAST"Charset=");
- if (encoding == NULL)
- encoding = xmlStrstr(content, BAD_CAST"CHARSET=");
- if (encoding != NULL) {
- encoding += 8;
- } else {
- encoding = xmlStrstr(content, BAD_CAST"charset =");
- if (encoding == NULL)
- encoding = xmlStrstr(content, BAD_CAST"Charset =");
- if (encoding == NULL)
- encoding = xmlStrstr(content, BAD_CAST"CHARSET =");
- if (encoding != NULL)
- encoding += 9;
- }
- if (encoding != NULL) {
- while ((*encoding == ' ') || (*encoding == '\t')) encoding++;
- }
- return(encoding);
-}
-
-/**
- * htmlSetMetaEncoding:
- * @doc: the document
- * @encoding: the encoding string
- *
- * Sets the current encoding in the Meta tags
- * NOTE: this will not change the document content encoding, just
- * the META flag associated.
- *
- * Returns 0 in case of success and -1 in case of error
- */
-int
-htmlSetMetaEncoding(htmlDocPtr doc, const xmlChar *encoding) {
- htmlNodePtr cur, meta;
- const xmlChar *content;
- char newcontent[100];
-
-
- if (doc == NULL)
- return(-1);
-
- if (encoding != NULL) {
- snprintf(newcontent, sizeof(newcontent), "text/html; charset=%s",
- encoding);
- newcontent[sizeof(newcontent) - 1] = 0;
- }
-
- cur = doc->children;
-
- /*
- * Search the html
- */
- while (cur != NULL) {
- if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
- if (xmlStrcasecmp(cur->name, BAD_CAST"html") == 0)
- break;
- if (xmlStrcasecmp(cur->name, BAD_CAST"head") == 0)
- goto found_head;
- if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0)
- goto found_meta;
- }
- cur = cur->next;
- }
- if (cur == NULL)
- return(-1);
- cur = cur->children;
-
- /*
- * Search the head
- */
- while (cur != NULL) {
- if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
- if (xmlStrcasecmp(cur->name, BAD_CAST"head") == 0)
- break;
- if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0)
- goto found_meta;
- }
- cur = cur->next;
- }
- if (cur == NULL)
- return(-1);
-found_head:
- if (cur->children == NULL) {
- if (encoding == NULL)
- return(0);
- meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
- xmlAddChild(cur, meta);
- xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
- xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
- return(0);
- }
- cur = cur->children;
-
-found_meta:
- if (encoding != NULL) {
- /*
- * Create a new Meta element with the right attributes
- */
-
- meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
- xmlAddPrevSibling(cur, meta);
- xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
- xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
- }
-
- /*
- * Search and destroy all the remaining the meta elements carrying
- * encoding informations
- */
- while (cur != NULL) {
- if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
- if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) {
- xmlAttrPtr attr = cur->properties;
- int http;
- const xmlChar *value;
-
- content = NULL;
- http = 0;
- while (attr != NULL) {
- if ((attr->children != NULL) &&
- (attr->children->type == XML_TEXT_NODE) &&
- (attr->children->next == NULL)) {
- value = attr->children->content;
- if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv"))
- && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
- http = 1;
- else
- {
- if ((value != NULL) &&
- (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
- content = value;
- }
- if ((http != 0) && (content != NULL))
- break;
- }
- attr = attr->next;
- }
- if ((http != 0) && (content != NULL)) {
- meta = cur;
- cur = cur->next;
- xmlUnlinkNode(meta);
- xmlFreeNode(meta);
- continue;
- }
-
- }
- }
- cur = cur->next;
- }
- return(0);
-}
-
-/**
- * booleanHTMLAttrs:
- *
- * These are the HTML attributes which will be output
- * in minimized form, i.e. <option selected="selected"> will be
- * output as <option selected>, as per XSLT 1.0 16.2 "HTML Output Method"
- *
- */
-static const char* htmlBooleanAttrs[] = {
- "checked", "compact", "declare", "defer", "disabled", "ismap",
- "multiple", "nohref", "noresize", "noshade", "nowrap", "readonly",
- "selected", NULL
-};
-
-
-/**
- * htmlIsBooleanAttr:
- * @name: the name of the attribute to check
- *
- * Determine if a given attribute is a boolean attribute.
- *
- * returns: false if the attribute is not boolean, true otherwise.
- */
-int
-htmlIsBooleanAttr(const xmlChar *name)
-{
- int i = 0;
-
- while (htmlBooleanAttrs[i] != NULL) {
- if (xmlStrcasecmp((const xmlChar *)htmlBooleanAttrs[i], name) == 0)
- return 1;
- i++;
- }
- return 0;
-}
-
-/************************************************************************
- * *
- * Dumping HTML tree content to a simple buffer *
- * *
- ************************************************************************/
-
-static int
-htmlNodeDumpFormat(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
- int format);
-
-/**
- * htmlNodeDumpFormat:
- * @buf: the HTML buffer output
- * @doc: the document
- * @cur: the current node
- * @format: should formatting spaces been added
- *
- * Dump an HTML node, recursive behaviour,children are printed too.
- *
- * Returns the number of byte written or -1 in case of error
- */
-static int
-htmlNodeDumpFormat(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
- int format) {
- unsigned int use;
- int ret;
- xmlOutputBufferPtr outbuf;
-
- if (cur == NULL) {
- return (-1);
- }
- if (buf == NULL) {
- return (-1);
- }
- outbuf = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
- if (outbuf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "htmlNodeDumpFormat: out of memory!\n");
- return (-1);
- }
- memset(outbuf, 0, (size_t) sizeof(xmlOutputBuffer));
- outbuf->buffer = buf;
- outbuf->encoder = NULL;
- outbuf->writecallback = NULL;
- outbuf->closecallback = NULL;
- outbuf->context = NULL;
- outbuf->written = 0;
-
- use = buf->use;
- htmlNodeDumpFormatOutput(outbuf, doc, cur, NULL, format);
- xmlFree(outbuf);
- ret = buf->use - use;
- return (ret);
-}
-
-/**
- * htmlNodeDump:
- * @buf: the HTML buffer output
- * @doc: the document
- * @cur: the current node
- *
- * Dump an HTML node, recursive behaviour,children are printed too,
- * and formatting returns are added.
- *
- * Returns the number of byte written or -1 in case of error
- */
-int
-htmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur) {
- return(htmlNodeDumpFormat(buf, doc, cur, 1));
-}
-
-/**
- * htmlNodeDumpFileFormat:
- * @out: the FILE pointer
- * @doc: the document
- * @cur: the current node
- * @encoding: the document encoding
- * @format: should formatting spaces been added
- *
- * Dump an HTML node, recursive behaviour,children are printed too.
- *
- * TODO: if encoding == NULL try to save in the doc encoding
- *
- * returns: the number of byte written or -1 in case of failure.
- */
-int
-htmlNodeDumpFileFormat(FILE *out, xmlDocPtr doc,
- xmlNodePtr cur, const char *encoding, int format) {
- xmlOutputBufferPtr buf;
- xmlCharEncodingHandlerPtr handler = NULL;
- int ret;
-
- if (encoding != NULL) {
- xmlCharEncoding enc;
-
- enc = xmlParseCharEncoding(encoding);
- if (enc != XML_CHAR_ENCODING_UTF8) {
- handler = xmlFindCharEncodingHandler(encoding);
- if (handler == NULL)
- return(-1);
- }
- }
-
- /*
- * Fallback to HTML or ASCII when the encoding is unspecified
- */
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("HTML");
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("ascii");
-
- /*
- * save the content to a temp buffer.
- */
- buf = xmlOutputBufferCreateFile(out, handler);
- if (buf == NULL) return(0);
-
- htmlNodeDumpFormatOutput(buf, doc, cur, encoding, format);
-
- ret = xmlOutputBufferClose(buf);
- return(ret);
-}
-
-/**
- * htmlNodeDumpFile:
- * @out: the FILE pointer
- * @doc: the document
- * @cur: the current node
- *
- * Dump an HTML node, recursive behaviour,children are printed too,
- * and formatting returns are added.
- */
-void
-htmlNodeDumpFile(FILE *out, xmlDocPtr doc, xmlNodePtr cur) {
- htmlNodeDumpFileFormat(out, doc, cur, NULL, 1);
-}
-
-/**
- * htmlDocDumpMemory:
- * @cur: the document
- * @mem: OUT: the memory pointer
- * @size: OUT: the memory length
- *
- * Dump an HTML document in memory and return the xmlChar * and it's size.
- * It's up to the caller to free the memory.
- */
-void
-htmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
- xmlOutputBufferPtr buf;
- xmlCharEncodingHandlerPtr handler = NULL;
- const char *encoding;
-
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "htmlDocDumpMemory : document == NULL\n");
-#endif
- *mem = NULL;
- *size = 0;
- return;
- }
-
- encoding = (const char *) htmlGetMetaEncoding(cur);
-
- if (encoding != NULL) {
- xmlCharEncoding enc;
-
- enc = xmlParseCharEncoding(encoding);
- if (enc != cur->charset) {
- if (cur->charset != XML_CHAR_ENCODING_UTF8) {
- /*
- * Not supported yet
- */
- *mem = NULL;
- *size = 0;
- return;
- }
-
- handler = xmlFindCharEncodingHandler(encoding);
- if (handler == NULL) {
- *mem = NULL;
- *size = 0;
- return;
- }
- }
- }
-
- /*
- * Fallback to HTML or ASCII when the encoding is unspecified
- */
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("HTML");
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("ascii");
-
- buf = xmlAllocOutputBuffer(handler);
- if (buf == NULL) {
- *mem = NULL;
- *size = 0;
- return;
- }
-
- htmlDocContentDumpOutput(buf, cur, NULL);
- xmlOutputBufferFlush(buf);
- if (buf->conv != NULL) {
- *size = buf->conv->use;
- *mem = xmlStrndup(buf->conv->content, *size);
- } else {
- *size = buf->buffer->use;
- *mem = xmlStrndup(buf->buffer->content, *size);
- }
- (void)xmlOutputBufferClose(buf);
-}
-
-
-/************************************************************************
- * *
- * Dumping HTML tree content to an I/O output buffer *
- * *
- ************************************************************************/
-
-
-/**
- * htmlDtdDumpOutput:
- * @buf: the HTML buffer output
- * @doc: the document
- * @encoding: the encoding string
- *
- * TODO: check whether encoding is needed
- *
- * Dump the HTML document DTD, if any.
- */
-static void
-htmlDtdDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
- const char *encoding ATTRIBUTE_UNUSED) {
- xmlDtdPtr cur = doc->intSubset;
-
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "htmlDtdDumpOutput : no internal subset\n");
- return;
- }
- xmlOutputBufferWriteString(buf, "<!DOCTYPE ");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- if (cur->ExternalID != NULL) {
- xmlOutputBufferWriteString(buf, " PUBLIC ");
- xmlBufferWriteQuotedString(buf->buffer, cur->ExternalID);
- if (cur->SystemID != NULL) {
- xmlOutputBufferWriteString(buf, " ");
- xmlBufferWriteQuotedString(buf->buffer, cur->SystemID);
- }
- } else if (cur->SystemID != NULL) {
- xmlOutputBufferWriteString(buf, " SYSTEM ");
- xmlBufferWriteQuotedString(buf->buffer, cur->SystemID);
- }
- xmlOutputBufferWriteString(buf, ">\n");
-}
-
-/**
- * htmlAttrDumpOutput:
- * @buf: the HTML buffer output
- * @doc: the document
- * @cur: the attribute pointer
- * @encoding: the encoding string
- *
- * Dump an HTML attribute
- */
-static void
-htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur,
- const char *encoding ATTRIBUTE_UNUSED) {
- xmlChar *value;
-
- /*
- * TODO: The html output method should not escape a & character
- * occurring in an attribute value immediately followed by
- * a { character (see Section B.7.1 of the HTML 4.0 Recommendation).
- */
-
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "htmlAttrDumpOutput : property == NULL\n");
- return;
- }
- xmlOutputBufferWriteString(buf, " ");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- if ((cur->children != NULL) && (!htmlIsBooleanAttr(cur->name))) {
- value = xmlNodeListGetString(doc, cur->children, 0);
- if (value) {
- xmlOutputBufferWriteString(buf, "=");
- if ((!xmlStrcasecmp(cur->name, BAD_CAST "href")) ||
- (!xmlStrcasecmp(cur->name, BAD_CAST "src"))) {
- xmlChar *escaped;
- xmlChar *tmp = value;
-
- while (IS_BLANK(*tmp)) tmp++;
-
- escaped = xmlURIEscapeStr(tmp, BAD_CAST"@/:=?;#%&");
- if (escaped != NULL) {
- xmlBufferWriteQuotedString(buf->buffer, escaped);
- xmlFree(escaped);
- } else {
- xmlBufferWriteQuotedString(buf->buffer, value);
- }
- } else {
- xmlBufferWriteQuotedString(buf->buffer, value);
- }
- xmlFree(value);
- } else {
- xmlOutputBufferWriteString(buf, "=\"\"");
- }
- }
-}
-
-/**
- * htmlAttrListDumpOutput:
- * @buf: the HTML buffer output
- * @doc: the document
- * @cur: the first attribute pointer
- * @encoding: the encoding string
- *
- * Dump a list of HTML attributes
- */
-static void
-htmlAttrListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur, const char *encoding) {
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "htmlAttrListDumpOutput : property == NULL\n");
- return;
- }
- while (cur != NULL) {
- htmlAttrDumpOutput(buf, doc, cur, encoding);
- cur = cur->next;
- }
-}
-
-
-
-/**
- * htmlNodeListDumpOutput:
- * @buf: the HTML buffer output
- * @doc: the document
- * @cur: the first node
- * @encoding: the encoding string
- * @format: should formatting spaces been added
- *
- * Dump an HTML node list, recursive behaviour,children are printed too.
- */
-static void
-htmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
- xmlNodePtr cur, const char *encoding, int format) {
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "htmlNodeListDumpOutput : node == NULL\n");
- return;
- }
- while (cur != NULL) {
- htmlNodeDumpFormatOutput(buf, doc, cur, encoding, format);
- cur = cur->next;
- }
-}
-
-/**
- * htmlNodeDumpFormatOutput:
- * @buf: the HTML buffer output
- * @doc: the document
- * @cur: the current node
- * @encoding: the encoding string
- * @format: should formatting spaces been added
- *
- * Dump an HTML node, recursive behaviour,children are printed too.
- */
-void
-htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
- xmlNodePtr cur, const char *encoding, int format) {
- const htmlElemDesc * info;
-
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "htmlNodeDumpFormatOutput : node == NULL\n");
- return;
- }
- /*
- * Special cases.
- */
- if (cur->type == XML_DTD_NODE)
- return;
- if (cur->type == XML_HTML_DOCUMENT_NODE) {
- htmlDocContentDumpOutput(buf, (xmlDocPtr) cur, encoding);
- return;
- }
- if (cur->type == HTML_TEXT_NODE) {
- if (cur->content != NULL) {
- if (((cur->name == (const xmlChar *)xmlStringText) ||
- (cur->name != (const xmlChar *)xmlStringTextNoenc)) &&
- ((cur->parent == NULL) ||
- ((xmlStrcasecmp(cur->parent->name, BAD_CAST "script")) &&
- (xmlStrcasecmp(cur->parent->name, BAD_CAST "style"))))) {
- xmlChar *buffer;
-
- buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
- if (buffer != NULL) {
- xmlOutputBufferWriteString(buf, (const char *)buffer);
- xmlFree(buffer);
- }
- } else {
- xmlOutputBufferWriteString(buf, (const char *)cur->content);
- }
- }
- return;
- }
- if (cur->type == HTML_COMMENT_NODE) {
- if (cur->content != NULL) {
- xmlOutputBufferWriteString(buf, "<!--");
- xmlOutputBufferWriteString(buf, (const char *)cur->content);
- xmlOutputBufferWriteString(buf, "-->");
- }
- return;
- }
- if (cur->type == HTML_PI_NODE) {
- if (cur->name == NULL)
- return;
- xmlOutputBufferWriteString(buf, "<?");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- if (cur->content != NULL) {
- xmlOutputBufferWriteString(buf, " ");
- xmlOutputBufferWriteString(buf, (const char *)cur->content);
- }
- xmlOutputBufferWriteString(buf, ">");
- return;
- }
- if (cur->type == HTML_ENTITY_REF_NODE) {
- xmlOutputBufferWriteString(buf, "&");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- xmlOutputBufferWriteString(buf, ";");
- return;
- }
- if (cur->type == HTML_PRESERVE_NODE) {
- if (cur->content != NULL) {
- xmlOutputBufferWriteString(buf, (const char *)cur->content);
- }
- return;
- }
-
- /*
- * Get specific HTML info for that node.
- */
- info = htmlTagLookup(cur->name);
-
- xmlOutputBufferWriteString(buf, "<");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- if (cur->properties != NULL)
- htmlAttrListDumpOutput(buf, doc, cur->properties, encoding);
-
- if ((info != NULL) && (info->empty)) {
- xmlOutputBufferWriteString(buf, ">");
- if ((format) && (!info->isinline) && (cur->next != NULL)) {
- if ((cur->next->type != HTML_TEXT_NODE) &&
- (cur->next->type != HTML_ENTITY_REF_NODE) &&
- (cur->parent != NULL) &&
- (!xmlStrEqual(cur->parent->name, BAD_CAST "pre")))
- xmlOutputBufferWriteString(buf, "\n");
- }
- return;
- }
- if (((cur->type == XML_ELEMENT_NODE) || (cur->content == NULL)) &&
- (cur->children == NULL)) {
- if ((info != NULL) && (info->saveEndTag != 0) &&
- (xmlStrcmp(BAD_CAST info->name, BAD_CAST "html")) &&
- (xmlStrcmp(BAD_CAST info->name, BAD_CAST "body"))) {
- xmlOutputBufferWriteString(buf, ">");
- } else {
- xmlOutputBufferWriteString(buf, "></");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- xmlOutputBufferWriteString(buf, ">");
- }
- if ((format) && (cur->next != NULL) &&
- (info != NULL) && (!info->isinline)) {
- if ((cur->next->type != HTML_TEXT_NODE) &&
- (cur->next->type != HTML_ENTITY_REF_NODE) &&
- (cur->parent != NULL) &&
- (!xmlStrEqual(cur->parent->name, BAD_CAST "pre")))
- xmlOutputBufferWriteString(buf, "\n");
- }
- return;
- }
- xmlOutputBufferWriteString(buf, ">");
- if ((cur->type != XML_ELEMENT_NODE) &&
- (cur->content != NULL)) {
- /*
- * Uses the OutputBuffer property to automatically convert
- * invalids to charrefs
- */
-
- xmlOutputBufferWriteString(buf, (const char *) cur->content);
- }
- if (cur->children != NULL) {
- if ((format) && (info != NULL) && (!info->isinline) &&
- (cur->children->type != HTML_TEXT_NODE) &&
- (cur->children->type != HTML_ENTITY_REF_NODE) &&
- (cur->children != cur->last) &&
- (!xmlStrEqual(cur->name, BAD_CAST "pre")))
- xmlOutputBufferWriteString(buf, "\n");
- htmlNodeListDumpOutput(buf, doc, cur->children, encoding, format);
- if ((format) && (info != NULL) && (!info->isinline) &&
- (cur->last->type != HTML_TEXT_NODE) &&
- (cur->last->type != HTML_ENTITY_REF_NODE) &&
- (cur->children != cur->last) &&
- (!xmlStrEqual(cur->name, BAD_CAST "pre")))
- xmlOutputBufferWriteString(buf, "\n");
- }
- xmlOutputBufferWriteString(buf, "</");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- xmlOutputBufferWriteString(buf, ">");
- if ((format) && (info != NULL) && (!info->isinline) &&
- (cur->next != NULL)) {
- if ((cur->next->type != HTML_TEXT_NODE) &&
- (cur->next->type != HTML_ENTITY_REF_NODE) &&
- (cur->parent != NULL) &&
- (!xmlStrEqual(cur->parent->name, BAD_CAST "pre")))
- xmlOutputBufferWriteString(buf, "\n");
- }
-}
-
-/**
- * htmlNodeDumpOutput:
- * @buf: the HTML buffer output
- * @doc: the document
- * @cur: the current node
- * @encoding: the encoding string
- *
- * Dump an HTML node, recursive behaviour,children are printed too,
- * and formatting returns/spaces are added.
- */
-void
-htmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
- xmlNodePtr cur, const char *encoding) {
- htmlNodeDumpFormatOutput(buf, doc, cur, encoding, 1);
-}
-
-/**
- * htmlDocContentDumpFormatOutput:
- * @buf: the HTML buffer output
- * @cur: the document
- * @encoding: the encoding string
- * @format: should formatting spaces been added
- *
- * Dump an HTML document.
- */
-void
-htmlDocContentDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
- const char *encoding, int format) {
- int type;
-
- /*
- * force to output the stuff as HTML, especially for entities
- */
- type = cur->type;
- cur->type = XML_HTML_DOCUMENT_NODE;
- if (cur->intSubset != NULL) {
- htmlDtdDumpOutput(buf, cur, NULL);
- }
- if (cur->children != NULL) {
- htmlNodeListDumpOutput(buf, cur, cur->children, encoding, format);
- }
- xmlOutputBufferWriteString(buf, "\n");
- cur->type = (xmlElementType) type;
-}
-
-/**
- * htmlDocContentDumpOutput:
- * @buf: the HTML buffer output
- * @cur: the document
- * @encoding: the encoding string
- *
- * Dump an HTML document. Formating return/spaces are added.
- */
-void
-htmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
- const char *encoding) {
- htmlDocContentDumpFormatOutput(buf, cur, encoding, 1);
-}
-
-/************************************************************************
- * *
- * Saving functions front-ends *
- * *
- ************************************************************************/
-
-/**
- * htmlDocDump:
- * @f: the FILE*
- * @cur: the document
- *
- * Dump an HTML document to an open FILE.
- *
- * returns: the number of byte written or -1 in case of failure.
- */
-int
-htmlDocDump(FILE *f, xmlDocPtr cur) {
- xmlOutputBufferPtr buf;
- xmlCharEncodingHandlerPtr handler = NULL;
- const char *encoding;
- int ret;
-
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "htmlDocDump : document == NULL\n");
-#endif
- return(-1);
- }
-
- encoding = (const char *) htmlGetMetaEncoding(cur);
-
- if (encoding != NULL) {
- xmlCharEncoding enc;
-
- enc = xmlParseCharEncoding(encoding);
- if (enc != cur->charset) {
- if (cur->charset != XML_CHAR_ENCODING_UTF8) {
- /*
- * Not supported yet
- */
- return(-1);
- }
-
- handler = xmlFindCharEncodingHandler(encoding);
- if (handler == NULL)
- return(-1);
- }
- }
-
- /*
- * Fallback to HTML or ASCII when the encoding is unspecified
- */
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("HTML");
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("ascii");
-
- buf = xmlOutputBufferCreateFile(f, handler);
- if (buf == NULL) return(-1);
- htmlDocContentDumpOutput(buf, cur, NULL);
-
- ret = xmlOutputBufferClose(buf);
- return(ret);
-}
-
-/**
- * htmlSaveFile:
- * @filename: the filename (or URL)
- * @cur: the document
- *
- * Dump an HTML document to a file. If @filename is "-" the stdout file is
- * used.
- * returns: the number of byte written or -1 in case of failure.
- */
-int
-htmlSaveFile(const char *filename, xmlDocPtr cur) {
- xmlOutputBufferPtr buf;
- xmlCharEncodingHandlerPtr handler = NULL;
- const char *encoding;
- int ret;
-
- encoding = (const char *) htmlGetMetaEncoding(cur);
-
- if (encoding != NULL) {
- xmlCharEncoding enc;
-
- enc = xmlParseCharEncoding(encoding);
- if (enc != cur->charset) {
- if (cur->charset != XML_CHAR_ENCODING_UTF8) {
- /*
- * Not supported yet
- */
- return(-1);
- }
-
- handler = xmlFindCharEncodingHandler(encoding);
- if (handler == NULL)
- return(-1);
- }
- }
-
- /*
- * Fallback to HTML or ASCII when the encoding is unspecified
- */
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("HTML");
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("ascii");
-
- /*
- * save the content to a temp buffer.
- */
- buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
- if (buf == NULL) return(0);
-
- htmlDocContentDumpOutput(buf, cur, NULL);
-
- ret = xmlOutputBufferClose(buf);
- return(ret);
-}
-
-/**
- * htmlSaveFileFormat:
- * @filename: the filename
- * @cur: the document
- * @format: should formatting spaces been added
- * @encoding: the document encoding
- *
- * Dump an HTML document to a file using a given encoding.
- *
- * returns: the number of byte written or -1 in case of failure.
- */
-int
-htmlSaveFileFormat(const char *filename, xmlDocPtr cur,
- const char *encoding, int format) {
- xmlOutputBufferPtr buf;
- xmlCharEncodingHandlerPtr handler = NULL;
- int ret;
-
- if (encoding != NULL) {
- xmlCharEncoding enc;
-
- enc = xmlParseCharEncoding(encoding);
- if (enc != cur->charset) {
- if (cur->charset != XML_CHAR_ENCODING_UTF8) {
- /*
- * Not supported yet
- */
- return(-1);
- }
-
- handler = xmlFindCharEncodingHandler(encoding);
- if (handler == NULL)
- return(-1);
- htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
- }
- } else {
- htmlSetMetaEncoding(cur, (const xmlChar *) "UTF-8");
- }
-
- /*
- * Fallback to HTML or ASCII when the encoding is unspecified
- */
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("HTML");
- if (handler == NULL)
- handler = xmlFindCharEncodingHandler("ascii");
-
- /*
- * save the content to a temp buffer.
- */
- buf = xmlOutputBufferCreateFilename(filename, handler, 0);
- if (buf == NULL) return(0);
-
- htmlDocContentDumpFormatOutput(buf, cur, encoding, format);
-
- ret = xmlOutputBufferClose(buf);
- return(ret);
-}
-
-/**
- * htmlSaveFileEnc:
- * @filename: the filename
- * @cur: the document
- * @encoding: the document encoding
- *
- * Dump an HTML document to a file using a given encoding
- * and formatting returns/spaces are added.
- *
- * returns: the number of byte written or -1 in case of failure.
- */
-int
-htmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) {
- return(htmlSaveFileFormat(filename, cur, encoding, 1));
-}
-
-
-
-#endif /* LIBXML_HTML_ENABLED */
diff --git a/bundle/libxml/SAX.c b/bundle/libxml/SAX.c
deleted file mode 100644
index 785ea0ba8c..0000000000
--- a/bundle/libxml/SAX.c
+++ /dev/null
@@ -1,2015 +0,0 @@
-/*
- * SAX.c : Default SAX handler to build a tree.
- *
- * See Copyright for the status of this software.
- *
- * Daniel Veillard <daniel@veillard.com>
- */
-
-
-#define IN_LIBXML
-#include "libxml.h"
-#include <stdlib.h>
-#include <string.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/parserInternals.h>
-#include <libxml/valid.h>
-#include <libxml/entities.h>
-#include <libxml/xmlerror.h>
-#include <libxml/debugXML.h>
-#include <libxml/xmlIO.h>
-#include <libxml/SAX.h>
-#include <libxml/uri.h>
-#include <libxml/valid.h>
-#include <libxml/HTMLtree.h>
-#include <libxml/globals.h>
-
-/* #define DEBUG_SAX */
-/* #define DEBUG_SAX_TREE */
-
-/**
- * getPublicId:
- * @ctx: the user data (XML parser context)
- *
- * Provides the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
- *
- * Returns a xmlChar *
- */
-const xmlChar *
-getPublicId(void *ctx ATTRIBUTE_UNUSED)
-{
- /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
- return(NULL);
-}
-
-/**
- * getSystemId:
- * @ctx: the user data (XML parser context)
- *
- * Provides the system ID, basically URL or filename e.g.
- * http://www.sgmlsource.com/dtds/memo.dtd
- *
- * Returns a xmlChar *
- */
-const xmlChar *
-getSystemId(void *ctx)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- return((const xmlChar *) ctxt->input->filename);
-}
-
-/**
- * getLineNumber:
- * @ctx: the user data (XML parser context)
- *
- * Provide the line number of the current parsing point.
- *
- * Returns an int
- */
-int
-getLineNumber(void *ctx)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- return(ctxt->input->line);
-}
-
-/**
- * getColumnNumber:
- * @ctx: the user data (XML parser context)
- *
- * Provide the column number of the current parsing point.
- *
- * Returns an int
- */
-int
-getColumnNumber(void *ctx)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- return(ctxt->input->col);
-}
-
-/**
- * isStandalone:
- * @ctx: the user data (XML parser context)
- *
- * Is this document tagged standalone ?
- *
- * Returns 1 if true
- */
-int
-isStandalone(void *ctx)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- return(ctxt->myDoc->standalone == 1);
-}
-
-/**
- * hasInternalSubset:
- * @ctx: the user data (XML parser context)
- *
- * Does this document has an internal subset
- *
- * Returns 1 if true
- */
-int
-hasInternalSubset(void *ctx)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- return(ctxt->myDoc->intSubset != NULL);
-}
-
-/**
- * hasExternalSubset:
- * @ctx: the user data (XML parser context)
- *
- * Does this document has an external subset
- *
- * Returns 1 if true
- */
-int
-hasExternalSubset(void *ctx)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- return(ctxt->myDoc->extSubset != NULL);
-}
-
-/**
- * internalSubset:
- * @ctx: the user data (XML parser context)
- * @name: the root element name
- * @ExternalID: the external ID
- * @SystemID: the SYSTEM ID (e.g. filename or URL)
- *
- * Callback on internal subset declaration.
- */
-void
-internalSubset(void *ctx, const xmlChar *name,
- const xmlChar *ExternalID, const xmlChar *SystemID)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlDtdPtr dtd;
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.internalSubset(%s, %s, %s)\n",
- name, ExternalID, SystemID);
-#endif
-
- if (ctxt->myDoc == NULL)
- return;
- dtd = xmlGetIntSubset(ctxt->myDoc);
- if (dtd != NULL) {
- if (ctxt->html)
- return;
- xmlUnlinkNode((xmlNodePtr) dtd);
- xmlFreeDtd(dtd);
- ctxt->myDoc->intSubset = NULL;
- }
- ctxt->myDoc->intSubset =
- xmlCreateIntSubset(ctxt->myDoc, name, ExternalID, SystemID);
-}
-
-/**
- * externalSubset:
- * @ctx: the user data (XML parser context)
- * @name: the root element name
- * @ExternalID: the external ID
- * @SystemID: the SYSTEM ID (e.g. filename or URL)
- *
- * Callback on external subset declaration.
- */
-void
-externalSubset(void *ctx, const xmlChar *name,
- const xmlChar *ExternalID, const xmlChar *SystemID)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.externalSubset(%s, %s, %s)\n",
- name, ExternalID, SystemID);
-#endif
- if (((ExternalID != NULL) || (SystemID != NULL)) &&
- (((ctxt->validate) || (ctxt->loadsubset != 0)) &&
- (ctxt->wellFormed && ctxt->myDoc))) {
- /*
- * Try to fetch and parse the external subset.
- */
- xmlParserInputPtr oldinput;
- int oldinputNr;
- int oldinputMax;
- xmlParserInputPtr *oldinputTab;
- xmlParserInputPtr input = NULL;
- xmlCharEncoding enc;
- int oldcharset;
-
- /*
- * Ask the Entity resolver to load the damn thing
- */
- if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
- input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID,
- SystemID);
- if (input == NULL) {
- return;
- }
-
- xmlNewDtd(ctxt->myDoc, name, ExternalID, SystemID);
-
- /*
- * make sure we won't destroy the main document context
- */
- oldinput = ctxt->input;
- oldinputNr = ctxt->inputNr;
- oldinputMax = ctxt->inputMax;
- oldinputTab = ctxt->inputTab;
- oldcharset = ctxt->charset;
-
- ctxt->inputTab = (xmlParserInputPtr *)
- xmlMalloc(5 * sizeof(xmlParserInputPtr));
- if (ctxt->inputTab == NULL) {
- ctxt->errNo = XML_ERR_NO_MEMORY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "externalSubset: out of memory\n");
- ctxt->errNo = XML_ERR_NO_MEMORY;
- ctxt->input = oldinput;
- ctxt->inputNr = oldinputNr;
- ctxt->inputMax = oldinputMax;
- ctxt->inputTab = oldinputTab;
- ctxt->charset = oldcharset;
- return;
- }
- ctxt->inputNr = 0;
- ctxt->inputMax = 5;
- ctxt->input = NULL;
- xmlPushInput(ctxt, input);
-
- /*
- * On the fly encoding conversion if needed
- */
- enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
- xmlSwitchEncoding(ctxt, enc);
-
- if (input->filename == NULL)
- input->filename = (char *) xmlStrdup(SystemID);
- input->line = 1;
- input->col = 1;
- input->base = ctxt->input->cur;
- input->cur = ctxt->input->cur;
- input->free = NULL;
-
- /*
- * let's parse that entity knowing it's an external subset.
- */
- xmlParseExternalSubset(ctxt, ExternalID, SystemID);
-
- /*
- * Free up the external entities
- */
-
- while (ctxt->inputNr > 1)
- xmlPopInput(ctxt);
- xmlFreeInputStream(ctxt->input);
- xmlFree(ctxt->inputTab);
-
- /*
- * Restore the parsing context of the main entity
- */
- ctxt->input = oldinput;
- ctxt->inputNr = oldinputNr;
- ctxt->inputMax = oldinputMax;
- ctxt->inputTab = oldinputTab;
- ctxt->charset = oldcharset;
- /* ctxt->wellFormed = oldwellFormed; */
- }
-}
-
-/**
- * resolveEntity:
- * @ctx: the user data (XML parser context)
- * @publicId: The public ID of the entity
- * @systemId: The system ID of the entity
- *
- * The entity loader, to control the loading of external entities,
- * the application can either:
- * - override this resolveEntity() callback in the SAX block
- * - or better use the xmlSetExternalEntityLoader() function to
- * set up it's own entity resolution routine
- *
- * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
- */
-xmlParserInputPtr
-resolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlParserInputPtr ret;
- xmlChar *URI;
- const char *base = NULL;
-
- if (ctxt->input != NULL)
- base = ctxt->input->filename;
- if (base == NULL)
- base = ctxt->directory;
-
- URI = xmlBuildURI(systemId, (const xmlChar *) base);
-
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
-#endif
-
- ret = xmlLoadExternalEntity((const char *) URI,
- (const char *) publicId, ctxt);
- if (URI != NULL)
- xmlFree(URI);
- return(ret);
-}
-
-/**
- * getEntity:
- * @ctx: the user data (XML parser context)
- * @name: The entity name
- *
- * Get an entity by name
- *
- * Returns the xmlEntityPtr if found.
- */
-xmlEntityPtr
-getEntity(void *ctx, const xmlChar *name)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlEntityPtr ret;
-
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.getEntity(%s)\n", name);
-#endif
-
- if ((ctxt->myDoc != NULL) && (ctxt->myDoc->standalone == 1)) {
- if (ctxt->inSubset == 2) {
- ctxt->myDoc->standalone = 0;
- ret = xmlGetDocEntity(ctxt->myDoc, name);
- ctxt->myDoc->standalone = 1;
- } else {
- ret = xmlGetDocEntity(ctxt->myDoc, name);
- if (ret == NULL) {
- ctxt->myDoc->standalone = 0;
- ret = xmlGetDocEntity(ctxt->myDoc, name);
- if (ret != NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt,
- "Entity(%s) document marked standalone but require external subset\n",
- name);
- ctxt->valid = 0;
- ctxt->wellFormed = 0;
- }
- ctxt->myDoc->standalone = 1;
- }
- }
- } else {
- ret = xmlGetDocEntity(ctxt->myDoc, name);
- }
- if ((ret != NULL) && (ctxt->validate) && (ret->children == NULL) &&
- (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
- /*
- * for validation purposes we really need to fetch and
- * parse the external entity
- */
- xmlNodePtr children;
-
- xmlParseCtxtExternalEntity(ctxt, ret->URI, ret->ExternalID, &children);
- xmlAddChildList((xmlNodePtr) ret, children);
- }
- return(ret);
-}
-
-/**
- * getParameterEntity:
- * @ctx: the user data (XML parser context)
- * @name: The entity name
- *
- * Get a parameter entity by name
- *
- * Returns the xmlEntityPtr if found.
- */
-xmlEntityPtr
-getParameterEntity(void *ctx, const xmlChar *name)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlEntityPtr ret;
-
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.getParameterEntity(%s)\n", name);
-#endif
-
- ret = xmlGetParameterEntity(ctxt->myDoc, name);
- return(ret);
-}
-
-
-/**
- * entityDecl:
- * @ctx: the user data (XML parser context)
- * @name: the entity name
- * @type: the entity type
- * @publicId: The public ID of the entity
- * @systemId: The system ID of the entity
- * @content: the entity value (without processing).
- *
- * An entity definition has been parsed
- */
-void
-entityDecl(void *ctx, const xmlChar *name, int type,
- const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
-{
- xmlEntityPtr ent;
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
- name, type, publicId, systemId, content);
-#endif
- if (ctxt->inSubset == 1) {
- ent = xmlAddDocEntity(ctxt->myDoc, name, type, publicId,
- systemId, content);
- if ((ent == NULL) && (ctxt->pedantic) &&
- (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt,
- "Entity(%s) already defined in the internal subset\n", name);
- if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
- xmlChar *URI;
- const char *base = NULL;
-
- if (ctxt->input != NULL)
- base = ctxt->input->filename;
- if (base == NULL)
- base = ctxt->directory;
-
- URI = xmlBuildURI(systemId, (const xmlChar *) base);
- ent->URI = URI;
- }
- } else if (ctxt->inSubset == 2) {
- ent = xmlAddDtdEntity(ctxt->myDoc, name, type, publicId,
- systemId, content);
- if ((ent == NULL) && (ctxt->pedantic) &&
- (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt,
- "Entity(%s) already defined in the external subset\n", name);
- if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
- xmlChar *URI;
- const char *base = NULL;
-
- if (ctxt->input != NULL)
- base = ctxt->input->filename;
- if (base == NULL)
- base = ctxt->directory;
-
- URI = xmlBuildURI(systemId, (const xmlChar *) base);
- ent->URI = URI;
- }
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt,
- "SAX.entityDecl(%s) called while not in subset\n", name);
- }
-}
-
-/**
- * attributeDecl:
- * @ctx: the user data (XML parser context)
- * @elem: the name of the element
- * @fullname: the attribute name
- * @type: the attribute type
- * @def: the type of default value
- * @defaultValue: the attribute default value
- * @tree: the tree of enumerated value set
- *
- * An attribute definition has been parsed
- */
-void
-attributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
- int type, int def, const xmlChar *defaultValue,
- xmlEnumerationPtr tree)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlAttributePtr attr;
- xmlChar *name = NULL, *prefix = NULL;
-
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
- elem, fullname, type, def, defaultValue);
-#endif
- name = xmlSplitQName(ctxt, fullname, &prefix);
- ctxt->vctxt.valid = 1;
- if (ctxt->inSubset == 1)
- attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, elem,
- name, prefix, (xmlAttributeType) type,
- (xmlAttributeDefault) def, defaultValue, tree);
- else if (ctxt->inSubset == 2)
- attr = xmlAddAttributeDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, elem,
- name, prefix, (xmlAttributeType) type,
- (xmlAttributeDefault) def, defaultValue, tree);
- else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt,
- "SAX.attributeDecl(%s) called while not in subset\n", name);
- return;
- }
- if (ctxt->vctxt.valid == 0)
- ctxt->valid = 0;
- if ((attr != NULL) && (ctxt->validate) && (ctxt->wellFormed) &&
- (ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset != NULL))
- ctxt->valid &= xmlValidateAttributeDecl(&ctxt->vctxt, ctxt->myDoc,
- attr);
- if (prefix != NULL)
- xmlFree(prefix);
- if (name != NULL)
- xmlFree(name);
-}
-
-/**
- * elementDecl:
- * @ctx: the user data (XML parser context)
- * @name: the element name
- * @type: the element type
- * @content: the element value tree
- *
- * An element definition has been parsed
- */
-void
-elementDecl(void *ctx, const xmlChar * name, int type,
- xmlElementContentPtr content)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlElementPtr elem = NULL;
-
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.elementDecl(%s, %d, ...)\n", name, type);
-#endif
-
- if (ctxt->inSubset == 1)
- elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
- name, (xmlElementTypeVal) type, content);
- else if (ctxt->inSubset == 2)
- elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->extSubset,
- name, (xmlElementTypeVal) type, content);
- else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt,
- "SAX.elementDecl(%s) called while not in subset\n",
- name);
- return;
- }
- if (elem == NULL)
- ctxt->valid = 0;
- if (ctxt->validate && ctxt->wellFormed &&
- ctxt->myDoc && ctxt->myDoc->intSubset)
- ctxt->valid &=
- xmlValidateElementDecl(&ctxt->vctxt, ctxt->myDoc, elem);
-}
-
-/**
- * notationDecl:
- * @ctx: the user data (XML parser context)
- * @name: The name of the notation
- * @publicId: The public ID of the entity
- * @systemId: The system ID of the entity
- *
- * What to do when a notation declaration has been parsed.
- */
-void
-notationDecl(void *ctx, const xmlChar *name,
- const xmlChar *publicId, const xmlChar *systemId)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlNotationPtr nota = NULL;
-
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
-#endif
-
- if ((publicId == NULL) && (systemId == NULL)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt,
- "SAX.notationDecl(%s) externalID or PublicID missing\n", name);
- ctxt->valid = 0;
- ctxt->wellFormed = 0;
- return;
- } else if (ctxt->inSubset == 1)
- nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->intSubset, name,
- publicId, systemId);
- else if (ctxt->inSubset == 2)
- nota = xmlAddNotationDecl(&ctxt->vctxt, ctxt->myDoc->extSubset, name,
- publicId, systemId);
- else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt,
- "SAX.notationDecl(%s) called while not in subset\n", name);
- return;
- }
- if (nota == NULL) ctxt->valid = 0;
- if (ctxt->validate && ctxt->wellFormed &&
- ctxt->myDoc && ctxt->myDoc->intSubset)
- ctxt->valid &= xmlValidateNotationDecl(&ctxt->vctxt, ctxt->myDoc,
- nota);
-}
-
-/**
- * unparsedEntityDecl:
- * @ctx: the user data (XML parser context)
- * @name: The name of the entity
- * @publicId: The public ID of the entity
- * @systemId: The system ID of the entity
- * @notationName: the name of the notation
- *
- * What to do when an unparsed entity declaration is parsed
- */
-void
-unparsedEntityDecl(void *ctx, const xmlChar *name,
- const xmlChar *publicId, const xmlChar *systemId,
- const xmlChar *notationName)
-{
- xmlEntityPtr ent;
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
- name, publicId, systemId, notationName);
-#endif
-#if 0
- Done in xmlValidateDtdFinal now.
- if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc) {
- int ret;
- ret = xmlValidateNotationUse(&ctxt->vctxt, ctxt->myDoc,
- notationName);
- if (ret == 0) {
- ctxt->wellFormed = 0;
- ctxt->valid = 0;
- }
- }
-#endif
- if (ctxt->inSubset == 1) {
- ent = xmlAddDocEntity(ctxt->myDoc, name,
- XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
- publicId, systemId, notationName);
- if ((ent == NULL) && (ctxt->pedantic) &&
- (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt,
- "Entity(%s) already defined in the internal subset\n", name);
- if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
- xmlChar *URI;
- const char *base = NULL;
-
- if (ctxt->input != NULL)
- base = ctxt->input->filename;
- if (base == NULL)
- base = ctxt->directory;
-
- URI = xmlBuildURI(systemId, (const xmlChar *) base);
- ent->URI = URI;
- }
- } else if (ctxt->inSubset == 2) {
- ent = xmlAddDtdEntity(ctxt->myDoc, name,
- XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
- publicId, systemId, notationName);
- if ((ent == NULL) && (ctxt->pedantic) &&
- (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt,
- "Entity(%s) already defined in the external subset\n", name);
- if ((ent != NULL) && (ent->URI == NULL) && (systemId != NULL)) {
- xmlChar *URI;
- const char *base = NULL;
-
- if (ctxt->input != NULL)
- base = ctxt->input->filename;
- if (base == NULL)
- base = ctxt->directory;
-
- URI = xmlBuildURI(systemId, (const xmlChar *) base);
- ent->URI = URI;
- }
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt,
- "SAX.unparsedEntityDecl(%s) called while not in subset\n", name);
- }
-}
-
-/**
- * setDocumentLocator:
- * @ctx: the user data (XML parser context)
- * @loc: A SAX Locator
- *
- * Receive the document locator at startup, actually xmlDefaultSAXLocator
- * Everything is available on the context, so this is useless in our case.
- */
-void
-setDocumentLocator(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
-{
- /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.setDocumentLocator()\n");
-#endif
-}
-
-/**
- * startDocument:
- * @ctx: the user data (XML parser context)
- *
- * called when the document start being processed.
- */
-void
-startDocument(void *ctx)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlDocPtr doc;
-
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.startDocument()\n");
-#endif
- if (ctxt->html) {
- if (ctxt->myDoc == NULL)
-#ifdef LIBXML_HTML_ENABLED
- ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
-#else
- xmlGenericError(xmlGenericErrorContext,
- "libxml2 built without HTML support\n");
-#endif
- } else {
- doc = ctxt->myDoc = xmlNewDoc(ctxt->version);
- if (doc != NULL) {
- if (ctxt->encoding != NULL)
- doc->encoding = xmlStrdup(ctxt->encoding);
- else
- doc->encoding = NULL;
- doc->standalone = ctxt->standalone;
- }
- }
- if ((ctxt->myDoc != NULL) && (ctxt->myDoc->URL == NULL) &&
- (ctxt->input != NULL) && (ctxt->input->filename != NULL)) {
- ctxt->myDoc->URL = xmlStrdup((const xmlChar *) ctxt->input->filename);
- }
-}
-
-/**
- * endDocument:
- * @ctx: the user data (XML parser context)
- *
- * called when the document end has been detected.
- */
-void
-endDocument(void *ctx)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.endDocument()\n");
-#endif
- if (ctxt->validate && ctxt->wellFormed &&
- ctxt->myDoc && ctxt->myDoc->intSubset)
- ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
-
- /*
- * Grab the encoding if it was added on-the-fly
- */
- if ((ctxt->encoding != NULL) && (ctxt->myDoc != NULL) &&
- (ctxt->myDoc->encoding == NULL)) {
- ctxt->myDoc->encoding = ctxt->encoding;
- ctxt->encoding = NULL;
- }
- if ((ctxt->inputTab[0]->encoding != NULL) && (ctxt->myDoc != NULL) &&
- (ctxt->myDoc->encoding == NULL)) {
- ctxt->myDoc->encoding = xmlStrdup(ctxt->inputTab[0]->encoding);
- }
- if ((ctxt->charset != XML_CHAR_ENCODING_NONE) && (ctxt->myDoc != NULL) &&
- (ctxt->myDoc->charset == XML_CHAR_ENCODING_NONE)) {
- ctxt->myDoc->charset = ctxt->charset;
- }
-}
-
-/**
- * my_attribute:
- * @ctx: the user data (XML parser context)
- * @fullname: The attribute name, including namespace prefix
- * @value: The attribute value
- * @prefix: the prefix on the element node
- *
- * Handle an attribute that has been read by the parser.
- * The default handling is to convert the attribute into an
- * DOM subtree and past it in a new xmlAttr element added to
- * the element.
- */
-static void
-my_attribute(void *ctx, const xmlChar *fullname, const xmlChar *value,
- const xmlChar *prefix)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlAttrPtr ret;
- xmlChar *name;
- xmlChar *ns;
- xmlChar *nval;
- xmlNsPtr namespace;
-
-/****************
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.attribute(%s, %s)\n", fullname, value);
-#endif
- ****************/
- /*
- * Split the full name into a namespace prefix and the tag name
- */
- name = xmlSplitQName(ctxt, fullname, &ns);
-
- /*
- * Do the last stage of the attribute normalization
- * Needed for HTML too:
- * http://www.w3.org/TR/html4/types.html#h-6.2
- */
- ctxt->vctxt.valid = 1;
- nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt,
- ctxt->myDoc, ctxt->node,
- fullname, value);
- if (ctxt->vctxt.valid != 1) {
- ctxt->valid = 0;
- }
- if (nval != NULL)
- value = nval;
-
- /*
- * Check whether it's a namespace definition
- */
- if ((!ctxt->html) && (ns == NULL) &&
- (name[0] == 'x') && (name[1] == 'm') && (name[2] == 'l') &&
- (name[3] == 'n') && (name[4] == 's') && (name[5] == 0)) {
- xmlNsPtr nsret;
-
- if (value[0] != 0) {
- xmlURIPtr uri;
-
- uri = xmlParseURI((const char *)value);
- if (uri == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "nmlns: %s not a valid URI\n", value);
- } else {
- if (uri->scheme == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "nmlns: URI %s is not absolute\n", value);
- }
- xmlFreeURI(uri);
- }
- }
-
- /* a default namespace definition */
- nsret = xmlNewNs(ctxt->node, value, NULL);
-
- /*
- * Validate also for namespace decls, they are attributes from
- * an XML-1.0 perspective
- */
- if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
- ctxt->myDoc && ctxt->myDoc->intSubset)
- ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
- ctxt->node, prefix, nsret, value);
- if (name != NULL)
- xmlFree(name);
- if (nval != NULL)
- xmlFree(nval);
- return;
- }
- if ((!ctxt->html) &&
- (ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
- (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
- xmlNsPtr nsret;
-
- if (value[0] == 0) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Empty namespace name for prefix %s\n", name);
- }
- /* a standard namespace definition */
- nsret = xmlNewNs(ctxt->node, value, name);
- xmlFree(ns);
- /*
- * Validate also for namespace decls, they are attributes from
- * an XML-1.0 perspective
- */
- if (nsret != NULL && ctxt->validate && ctxt->wellFormed &&
- ctxt->myDoc && ctxt->myDoc->intSubset)
- ctxt->valid &= xmlValidateOneNamespace(&ctxt->vctxt, ctxt->myDoc,
- ctxt->node, prefix, nsret, value);
- if (name != NULL)
- xmlFree(name);
- if (nval != NULL)
- xmlFree(nval);
- return;
- }
-
- if (ns != NULL)
- namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
- else {
- namespace = NULL;
- }
-
- /* !!!!!! <a toto:arg="" xmlns:toto="http://toto.com"> */
- ret = xmlNewNsPropEatName(ctxt->node, namespace, name, NULL);
-
- if (ret != NULL) {
- if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
- xmlNodePtr tmp;
-
- ret->children = xmlStringGetNodeList(ctxt->myDoc, value);
- tmp = ret->children;
- while (tmp != NULL) {
- tmp->parent = (xmlNodePtr) ret;
- if (tmp->next == NULL)
- ret->last = tmp;
- tmp = tmp->next;
- }
- } else if (value != NULL) {
- ret->children = xmlNewDocText(ctxt->myDoc, value);
- ret->last = ret->children;
- if (ret->children != NULL)
- ret->children->parent = (xmlNodePtr) ret;
- }
- }
-
- if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
- ctxt->myDoc && ctxt->myDoc->intSubset) {
-
- /*
- * If we don't substitute entities, the validation should be
- * done on a value with replaced entities anyway.
- */
- if (!ctxt->replaceEntities) {
- xmlChar *val;
-
- ctxt->depth++;
- val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
- 0,0,0);
- ctxt->depth--;
-
- if (val == NULL)
- ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
- ctxt->myDoc, ctxt->node, ret, value);
- else {
- xmlChar *nvalnorm;
-
- /*
- * Do the last stage of the attribute normalization
- * It need to be done twice ... it's an extra burden related
- * to the ability to keep references in attributes
- */
- nvalnorm = xmlValidNormalizeAttributeValue(ctxt->myDoc,
- ctxt->node, fullname, val);
- if (nvalnorm != NULL) {
- xmlFree(val);
- val = nvalnorm;
- }
-
- ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
- ctxt->myDoc, ctxt->node, ret, val);
- xmlFree(val);
- }
- } else {
- ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
- ctxt->node, ret, value);
- }
- } else if (((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
- ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0))) {
- /*
- * when validating, the ID registration is done at the attribute
- * validation level. Otherwise we have to do specific handling here.
- */
- if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
- xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
- else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
- xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
- }
-
- if (nval != NULL)
- xmlFree(nval);
- if (ns != NULL)
- xmlFree(ns);
-}
-
-/**
- * attribute:
- * @ctx: the user data (XML parser context)
- * @fullname: The attribute name, including namespace prefix
- * @value: The attribute value
- *
- * Handle an attribute that has been read by the parser.
- * The default handling is to convert the attribute into an
- * DOM subtree and past it in a new xmlAttr element added to
- * the element.
- */
-void
-attribute(void *ctx, const xmlChar *fullname, const xmlChar *value)
-{
- my_attribute(ctx, fullname, value, NULL);
-}
-
-/*
- * xmlCheckDefaultedAttributes:
- *
- * Check defaulted attributes from the DTD
- */
-static void
-xmlCheckDefaultedAttributes(xmlParserCtxtPtr ctxt, const xmlChar *name,
- const xmlChar *prefix, const xmlChar **atts) {
- xmlElementPtr elemDecl;
- const xmlChar *att;
- int internal = 1;
- int i;
-
- elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->intSubset, name, prefix);
- if (elemDecl == NULL) {
- elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset, name, prefix);
- internal = 0;
- }
-
-process_external_subset:
-
- if (elemDecl != NULL) {
- xmlAttributePtr attr = elemDecl->attributes;
- /*
- * Check against defaulted attributes from the external subset
- * if the document is stamped as standalone
- */
- if ((ctxt->myDoc->standalone == 1) &&
- (ctxt->myDoc->extSubset != NULL) &&
- (ctxt->validate)) {
- while (attr != NULL) {
- if ((attr->defaultValue != NULL) &&
- (xmlGetDtdQAttrDesc(ctxt->myDoc->extSubset,
- attr->elem, attr->name,
- attr->prefix) == attr) &&
- (xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
- attr->elem, attr->name,
- attr->prefix) == NULL)) {
- xmlChar *fulln;
-
- if (attr->prefix != NULL) {
- fulln = xmlStrdup(attr->prefix);
- fulln = xmlStrcat(fulln, BAD_CAST ":");
- fulln = xmlStrcat(fulln, attr->name);
- } else {
- fulln = xmlStrdup(attr->name);
- }
-
- /*
- * Check that the attribute is not declared in the
- * serialization
- */
- att = NULL;
- if (atts != NULL) {
- i = 0;
- att = atts[i];
- while (att != NULL) {
- if (xmlStrEqual(att, fulln))
- break;
- i += 2;
- att = atts[i];
- }
- }
- if (att == NULL) {
- if (ctxt->vctxt.error != NULL)
- ctxt->vctxt.error(ctxt->vctxt.userData,
- "standalone: attribute %s on %s defaulted from external subset\n",
- fulln, attr->elem);
- ctxt->valid = 0;
- }
- }
- attr = attr->nexth;
- }
- }
-
- /*
- * Actually insert defaulted values when needed
- */
- attr = elemDecl->attributes;
- while (attr != NULL) {
- /*
- * Make sure that attributes redefinition occuring in the
- * internal subset are not overriden by definitions in the
- * external subset.
- */
- if (attr->defaultValue != NULL) {
- /*
- * the element should be instantiated in the tree if:
- * - this is a namespace prefix
- * - the user required for completion in the tree
- * like XSLT
- * - there isn't already an attribute definition
- * in the internal subset overriding it.
- */
- if (((attr->prefix != NULL) &&
- (xmlStrEqual(attr->prefix, BAD_CAST "xmlns"))) ||
- ((attr->prefix == NULL) &&
- (xmlStrEqual(attr->name, BAD_CAST "xmlns"))) ||
- (ctxt->loadsubset & XML_COMPLETE_ATTRS)) {
- xmlAttributePtr tst;
-
- tst = xmlGetDtdQAttrDesc(ctxt->myDoc->intSubset,
- attr->elem, attr->name,
- attr->prefix);
- if ((tst == attr) || (tst == NULL)) {
- xmlChar *fulln;
-
- if (attr->prefix != NULL) {
- fulln = xmlStrdup(attr->prefix);
- fulln = xmlStrcat(fulln, BAD_CAST ":");
- fulln = xmlStrcat(fulln, attr->name);
- } else {
- fulln = xmlStrdup(attr->name);
- }
-
- /*
- * Check that the attribute is not declared in the
- * serialization
- */
- att = NULL;
- if (atts != NULL) {
- i = 0;
- att = atts[i];
- while (att != NULL) {
- if (xmlStrEqual(att, fulln))
- break;
- i += 2;
- att = atts[i];
- }
- }
- if (att == NULL) {
- attribute(ctxt, fulln, attr->defaultValue);
- }
- xmlFree(fulln);
- }
- }
- }
- attr = attr->nexth;
- }
- if (internal == 1) {
- elemDecl = xmlGetDtdQElementDesc(ctxt->myDoc->extSubset,
- name, prefix);
- internal = 0;
- goto process_external_subset;
- }
- }
-}
-
-/**
- * startElement:
- * @ctx: the user data (XML parser context)
- * @fullname: The element name, including namespace prefix
- * @atts: An array of name/value attributes pairs, NULL terminated
- *
- * called when an opening tag has been processed.
- */
-void
-startElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlNodePtr ret;
- xmlNodePtr parent = ctxt->node;
- xmlNsPtr ns;
- xmlChar *name;
- xmlChar *prefix;
- const xmlChar *att;
- const xmlChar *value;
- int i;
-
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.startElement(%s)\n", fullname);
-#endif
-
- /*
- * First check on validity:
- */
- if (ctxt->validate && (ctxt->myDoc->extSubset == NULL) &&
- ((ctxt->myDoc->intSubset == NULL) ||
- ((ctxt->myDoc->intSubset->notations == NULL) &&
- (ctxt->myDoc->intSubset->elements == NULL) &&
- (ctxt->myDoc->intSubset->attributes == NULL) &&
- (ctxt->myDoc->intSubset->entities == NULL)))) {
- if (ctxt->vctxt.error != NULL) {
- ctxt->vctxt.error(ctxt->vctxt.userData,
- "Validation failed: no DTD found !\n");
- }
- ctxt->validate = 0;
- ctxt->valid = 0;
- ctxt->errNo = XML_ERR_NO_DTD;
- }
-
-
- /*
- * Split the full name into a namespace prefix and the tag name
- */
- name = xmlSplitQName(ctxt, fullname, &prefix);
-
-
- /*
- * Note : the namespace resolution is deferred until the end of the
- * attributes parsing, since local namespace can be defined as
- * an attribute at this level.
- */
- ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL, name, NULL);
- if (ret == NULL) return;
- if (ctxt->myDoc->children == NULL) {
-#ifdef DEBUG_SAX_TREE
- xmlGenericError(xmlGenericErrorContext, "Setting %s as root\n", name);
-#endif
- xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
- } else if (parent == NULL) {
- parent = ctxt->myDoc->children;
- }
- ctxt->nodemem = -1;
- if (ctxt->linenumbers) {
- if (ctxt->input != NULL)
- ret->content = (void *) (long) ctxt->input->line;
- }
-
- /*
- * We are parsing a new node.
- */
-#ifdef DEBUG_SAX_TREE
- xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name);
-#endif
- nodePush(ctxt, ret);
-
- /*
- * Link the child element
- */
- if (parent != NULL) {
- if (parent->type == XML_ELEMENT_NODE) {
-#ifdef DEBUG_SAX_TREE
- xmlGenericError(xmlGenericErrorContext,
- "adding child %s to %s\n", name, parent->name);
-#endif
- xmlAddChild(parent, ret);
- } else {
-#ifdef DEBUG_SAX_TREE
- xmlGenericError(xmlGenericErrorContext,
- "adding sibling %s to ", name);
- xmlDebugDumpOneNode(stderr, parent, 0);
-#endif
- xmlAddSibling(parent, ret);
- }
- }
-
- /*
- * Insert all the defaulted attributes from the DTD especially namespaces
- */
- if ((!ctxt->html) &&
- ((ctxt->myDoc->intSubset != NULL) ||
- (ctxt->myDoc->extSubset != NULL))) {
- xmlCheckDefaultedAttributes(ctxt, name, prefix, atts);
- }
-
- /*
- * process all the attributes whose name start with "xmlns"
- */
- if (atts != NULL) {
- i = 0;
- att = atts[i++];
- value = atts[i++];
- if (!ctxt->html) {
- while ((att != NULL) && (value != NULL)) {
- if ((att[0] == 'x') && (att[1] == 'm') && (att[2] == 'l') &&
- (att[3] == 'n') && (att[4] == 's'))
- my_attribute(ctxt, att, value, prefix);
-
- att = atts[i++];
- value = atts[i++];
- }
- }
- }
-
- /*
- * Search the namespace, note that since the attributes have been
- * processed, the local namespaces are available.
- */
- ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
- if ((ns == NULL) && (parent != NULL))
- ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
- if ((prefix != NULL) && (ns == NULL)) {
- ns = xmlNewNs(ret, NULL, prefix);
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "Namespace prefix %s is not defined\n", prefix);
- }
-
- /*
- * set the namespace node, making sure that if the default namspace
- * is unbound on a parent we simply kee it NULL
- */
- if ((ns != NULL) && (ns->href != NULL) &&
- ((ns->href[0] != 0) || (ns->prefix != NULL)))
- xmlSetNs(ret, ns);
-
- /*
- * process all the other attributes
- */
- if (atts != NULL) {
- i = 0;
- att = atts[i++];
- value = atts[i++];
- if (ctxt->html) {
- while (att != NULL) {
- attribute(ctxt, att, value);
- att = atts[i++];
- value = atts[i++];
- }
- } else {
- while ((att != NULL) && (value != NULL)) {
- if ((att[0] != 'x') || (att[1] != 'm') || (att[2] != 'l') ||
- (att[3] != 'n') || (att[4] != 's'))
- attribute(ctxt, att, value);
-
- /*
- * Next ones
- */
- att = atts[i++];
- value = atts[i++];
- }
- }
- }
-
- /*
- * If it's the Document root, finish the DTD validation and
- * check the document root element for validity
- */
- if ((ctxt->validate) && (ctxt->vctxt.finishDtd == 0)) {
- int chk;
-
- chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
- if (chk <= 0)
- ctxt->valid = 0;
- if (chk < 0)
- ctxt->wellFormed = 0;
- ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
- ctxt->vctxt.finishDtd = 1;
- }
-
- if (prefix != NULL)
- xmlFree(prefix);
-
-}
-
-/**
- * endElement:
- * @ctx: the user data (XML parser context)
- * @name: The element name
- *
- * called when the end of an element has been detected.
- */
-void
-endElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlParserNodeInfo node_info;
- xmlNodePtr cur = ctxt->node;
-
-#ifdef DEBUG_SAX
- if (name == NULL)
- xmlGenericError(xmlGenericErrorContext, "SAX.endElement(NULL)\n");
- else
- xmlGenericError(xmlGenericErrorContext, "SAX.endElement(%s)\n", name);
-#endif
-
- /* Capture end position and add node */
- if (cur != NULL && ctxt->record_info) {
- node_info.end_pos = ctxt->input->cur - ctxt->input->base;
- node_info.end_line = ctxt->input->line;
- node_info.node = cur;
- xmlParserAddNodeInfo(ctxt, &node_info);
- }
- ctxt->nodemem = -1;
-
- if (ctxt->validate && ctxt->wellFormed &&
- ctxt->myDoc && ctxt->myDoc->intSubset)
- ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
- cur);
-
-
- /*
- * end of parsing of this node.
- */
-#ifdef DEBUG_SAX_TREE
- xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name);
-#endif
- nodePop(ctxt);
-}
-
-/**
- * reference:
- * @ctx: the user data (XML parser context)
- * @name: The entity name
- *
- * called when an entity reference is detected.
- */
-void
-reference(void *ctx, const xmlChar *name)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlNodePtr ret;
-
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.reference(%s)\n", name);
-#endif
- if (name[0] == '#')
- ret = xmlNewCharRef(ctxt->myDoc, name);
- else
- ret = xmlNewReference(ctxt->myDoc, name);
-#ifdef DEBUG_SAX_TREE
- xmlGenericError(xmlGenericErrorContext,
- "add reference %s to %s \n", name, ctxt->node->name);
-#endif
- xmlAddChild(ctxt->node, ret);
-}
-
-/**
- * characters:
- * @ctx: the user data (XML parser context)
- * @ch: a xmlChar string
- * @len: the number of xmlChar
- *
- * receiving some chars from the parser.
- */
-void
-characters(void *ctx, const xmlChar *ch, int len)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlNodePtr lastChild;
-
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.characters(%.30s, %d)\n", ch, len);
-#endif
- /*
- * Handle the data if any. If there is no child
- * add it as content, otherwise if the last child is text,
- * concatenate it, else create a new node of type text.
- */
-
- if (ctxt->node == NULL) {
-#ifdef DEBUG_SAX_TREE
- xmlGenericError(xmlGenericErrorContext,
- "add chars: ctxt->node == NULL !\n");
-#endif
- return;
- }
- lastChild = xmlGetLastChild(ctxt->node);
-#ifdef DEBUG_SAX_TREE
- xmlGenericError(xmlGenericErrorContext,
- "add chars to %s \n", ctxt->node->name);
-#endif
-
- /*
- * Here we needed an accelerator mechanism in case of very large
- * elements. Use an attribute in the structure !!!
- */
- if (lastChild == NULL) {
- /* first node, first time */
- xmlNodeAddContentLen(ctxt->node, ch, len);
- if (ctxt->node->children != NULL) {
- ctxt->nodelen = len;
- ctxt->nodemem = len + 1;
- }
- } else {
- int coalesceText = (lastChild != NULL) &&
- (lastChild->type == XML_TEXT_NODE) &&
- (lastChild->name == xmlStringText);
- if ((coalesceText) && (ctxt->nodemem != 0)) {
- /*
- * The whole point of maintaining nodelen and nodemem,
- * xmlTextConcat is too costly, i.e. compute length,
- * reallocate a new buffer, move data, append ch. Here
- * We try to minimaze realloc() uses and avoid copying
- * and recomputing length over and over.
- */
- if (ctxt->nodelen + len >= ctxt->nodemem) {
- xmlChar *newbuf;
- int size;
-
- size = ctxt->nodemem + len;
- size *= 2;
- newbuf = (xmlChar *) xmlRealloc(lastChild->content,size);
- if (newbuf == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "SAX.characters(): out of memory\n");
- return;
- }
- ctxt->nodemem = size;
- lastChild->content = newbuf;
- }
- memcpy(&lastChild->content[ctxt->nodelen], ch, len);
- ctxt->nodelen += len;
- lastChild->content[ctxt->nodelen] = 0;
- } else if (coalesceText) {
- xmlTextConcat(lastChild, ch, len);
- if (ctxt->node->children != NULL) {
- ctxt->nodelen = xmlStrlen(lastChild->content);
- ctxt->nodemem = ctxt->nodelen + 1;
- }
- } else {
- /* Mixed content, first time */
- lastChild = xmlNewTextLen(ch, len);
- xmlAddChild(ctxt->node, lastChild);
- if (ctxt->node->children != NULL) {
- ctxt->nodelen = len;
- ctxt->nodemem = len + 1;
- }
- }
- }
-}
-
-/**
- * ignorableWhitespace:
- * @ctx: the user data (XML parser context)
- * @ch: a xmlChar string
- * @len: the number of xmlChar
- *
- * receiving some ignorable whitespaces from the parser.
- * UNUSED: by default the DOM building will use characters
- */
-void
-ignorableWhitespace(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED)
-{
- /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.ignorableWhitespace(%.30s, %d)\n", ch, len);
-#endif
-}
-
-/**
- * processingInstruction:
- * @ctx: the user data (XML parser context)
- * @target: the target name
- * @data: the PI data's
- *
- * A processing instruction has been parsed.
- */
-void
-processingInstruction(void *ctx, const xmlChar *target,
- const xmlChar *data)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlNodePtr ret;
- xmlNodePtr parent = ctxt->node;
-
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.processingInstruction(%s, %s)\n", target, data);
-#endif
-
- ret = xmlNewPI(target, data);
- if (ret == NULL) return;
- parent = ctxt->node;
-
- if (ctxt->inSubset == 1) {
- xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
- return;
- } else if (ctxt->inSubset == 2) {
- xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
- return;
- }
- if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
-#ifdef DEBUG_SAX_TREE
- xmlGenericError(xmlGenericErrorContext,
- "Setting PI %s as root\n", target);
-#endif
- xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
- return;
- }
- if (parent->type == XML_ELEMENT_NODE) {
-#ifdef DEBUG_SAX_TREE
- xmlGenericError(xmlGenericErrorContext,
- "adding PI %s child to %s\n", target, parent->name);
-#endif
- xmlAddChild(parent, ret);
- } else {
-#ifdef DEBUG_SAX_TREE
- xmlGenericError(xmlGenericErrorContext,
- "adding PI %s sibling to ", target);
- xmlDebugDumpOneNode(stderr, parent, 0);
-#endif
- xmlAddSibling(parent, ret);
- }
-}
-
-/**
- * globalNamespace:
- * @ctx: the user data (XML parser context)
- * @href: the namespace associated URN
- * @prefix: the namespace prefix
- *
- * An old global namespace has been parsed.
- */
-void
-globalNamespace(void *ctx, const xmlChar *href, const xmlChar *prefix)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.globalNamespace(%s, %s)\n", href, prefix);
-#endif
- xmlNewGlobalNs(ctxt->myDoc, href, prefix);
-}
-
-/**
- * setNamespace:
- * @ctx: the user data (XML parser context)
- * @name: the namespace prefix
- *
- * Set the current element namespace.
- */
-
-void
-setNamespace(void *ctx, const xmlChar *name)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlNsPtr ns;
- xmlNodePtr parent;
-
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext, "SAX.setNamespace(%s)\n", name);
-#endif
- ns = xmlSearchNs(ctxt->myDoc, ctxt->node, name);
- if (ns == NULL) { /* ctxt->node may not have a parent yet ! */
- if (ctxt->nodeNr >= 2) {
- parent = ctxt->nodeTab[ctxt->nodeNr - 2];
- if (parent != NULL)
- ns = xmlSearchNs(ctxt->myDoc, parent, name);
- }
- }
- xmlSetNs(ctxt->node, ns);
-}
-
-/**
- * getNamespace:
- * @ctx: the user data (XML parser context)
- *
- * Get the current element namespace.
- *
- * Returns the xmlNsPtr or NULL if none
- */
-
-xmlNsPtr
-getNamespace(void *ctx)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlNsPtr ret;
-
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext, "SAX.getNamespace()\n");
-#endif
- ret = ctxt->node->ns;
- return(ret);
-}
-
-/**
- * checkNamespace:
- * @ctx: the user data (XML parser context)
- * @namespace: the namespace to check against
- *
- * Check that the current element namespace is the same as the
- * one read upon parsing.
- *
- * Returns 1 if true 0 otherwise
- */
-
-int
-checkNamespace(void *ctx, xmlChar *namespace)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlNodePtr cur = ctxt->node;
-
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.checkNamespace(%s)\n", namespace);
-#endif
-
- /*
- * Check that the Name in the ETag is the same as in the STag.
- */
- if (namespace == NULL) {
- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt,
- "End tags for %s don't hold the namespace %s\n",
- cur->name, cur->ns->prefix);
- ctxt->wellFormed = 0;
- }
- } else {
- if ((cur->ns == NULL) || (cur->ns->prefix == NULL)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt,
- "End tags %s holds a prefix %s not used by the open tag\n",
- cur->name, namespace);
- ctxt->wellFormed = 0;
- } else if (!xmlStrEqual(namespace, cur->ns->prefix)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt,
- "Start and End tags for %s don't use the same namespaces: %s and %s\n",
- cur->name, cur->ns->prefix, namespace);
- ctxt->wellFormed = 0;
- } else
- return(1);
- }
- return(0);
-}
-
-/**
- * namespaceDecl:
- * @ctx: the user data (XML parser context)
- * @href: the namespace associated URN
- * @prefix: the namespace prefix
- *
- * A namespace has been parsed.
- */
-void
-namespaceDecl(void *ctx, const xmlChar *href, const xmlChar *prefix)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-#ifdef DEBUG_SAX
- if (prefix == NULL)
- xmlGenericError(xmlGenericErrorContext,
- "SAX.namespaceDecl(%s, NULL)\n", href);
- else
- xmlGenericError(xmlGenericErrorContext,
- "SAX.namespaceDecl(%s, %s)\n", href, prefix);
-#endif
- xmlNewNs(ctxt->node, href, prefix);
-}
-
-/**
- * comment:
- * @ctx: the user data (XML parser context)
- * @value: the comment content
- *
- * A comment has been parsed.
- */
-void
-comment(void *ctx, const xmlChar *value)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlNodePtr ret;
- xmlNodePtr parent = ctxt->node;
-
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext, "SAX.comment(%s)\n", value);
-#endif
- ret = xmlNewDocComment(ctxt->myDoc, value);
- if (ret == NULL) return;
-
- if (ctxt->inSubset == 1) {
- xmlAddChild((xmlNodePtr) ctxt->myDoc->intSubset, ret);
- return;
- } else if (ctxt->inSubset == 2) {
- xmlAddChild((xmlNodePtr) ctxt->myDoc->extSubset, ret);
- return;
- }
- if ((ctxt->myDoc->children == NULL) || (parent == NULL)) {
-#ifdef DEBUG_SAX_TREE
- xmlGenericError(xmlGenericErrorContext,
- "Setting comment as root\n");
-#endif
- xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
- return;
- }
- if (parent->type == XML_ELEMENT_NODE) {
-#ifdef DEBUG_SAX_TREE
- xmlGenericError(xmlGenericErrorContext,
- "adding comment child to %s\n", parent->name);
-#endif
- xmlAddChild(parent, ret);
- } else {
-#ifdef DEBUG_SAX_TREE
- xmlGenericError(xmlGenericErrorContext,
- "adding comment sibling to ");
- xmlDebugDumpOneNode(stderr, parent, 0);
-#endif
- xmlAddSibling(parent, ret);
- }
-}
-
-/**
- * cdataBlock:
- * @ctx: the user data (XML parser context)
- * @value: The pcdata content
- * @len: the block length
- *
- * called when a pcdata block has been parsed
- */
-void
-cdataBlock(void *ctx, const xmlChar *value, int len)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlNodePtr ret, lastChild;
-
-#ifdef DEBUG_SAX
- xmlGenericError(xmlGenericErrorContext,
- "SAX.pcdata(%.10s, %d)\n", value, len);
-#endif
- lastChild = xmlGetLastChild(ctxt->node);
-#ifdef DEBUG_SAX_TREE
- xmlGenericError(xmlGenericErrorContext,
- "add chars to %s \n", ctxt->node->name);
-#endif
- if ((lastChild != NULL) &&
- (lastChild->type == XML_CDATA_SECTION_NODE)) {
- xmlTextConcat(lastChild, value, len);
- } else {
- ret = xmlNewCDataBlock(ctxt->myDoc, value, len);
- xmlAddChild(ctxt->node, ret);
- }
-}
-
-/**
- * initxmlDefaultSAXHandler:
- * @hdlr: the SAX handler
- * @warning: flag if non-zero sets the handler warning procedure
- *
- * Initialize the default XML SAX handler
- */
-void
-initxmlDefaultSAXHandler(xmlSAXHandler *hdlr, int warning)
-{
- if(hdlr->initialized == 1)
- return;
-
- hdlr->internalSubset = internalSubset;
- hdlr->externalSubset = externalSubset;
- hdlr->isStandalone = isStandalone;
- hdlr->hasInternalSubset = hasInternalSubset;
- hdlr->hasExternalSubset = hasExternalSubset;
- hdlr->resolveEntity = resolveEntity;
- hdlr->getEntity = getEntity;
- hdlr->getParameterEntity = getParameterEntity;
- hdlr->entityDecl = entityDecl;
- hdlr->attributeDecl = attributeDecl;
- hdlr->elementDecl = elementDecl;
- hdlr->notationDecl = notationDecl;
- hdlr->unparsedEntityDecl = unparsedEntityDecl;
- hdlr->setDocumentLocator = setDocumentLocator;
- hdlr->startDocument = startDocument;
- hdlr->endDocument = endDocument;
- hdlr->startElement = startElement;
- hdlr->endElement = endElement;
- hdlr->reference = reference;
- hdlr->characters = characters;
- hdlr->cdataBlock = cdataBlock;
- hdlr->ignorableWhitespace = characters;
- hdlr->processingInstruction = processingInstruction;
- hdlr->comment = comment;
- /* if (xmlGetWarningsDefaultValue == 0) */
- if (warning == 0)
- hdlr->warning = NULL;
- else
- hdlr->warning = xmlParserWarning;
- hdlr->error = xmlParserError;
- hdlr->fatalError = xmlParserError;
-
- hdlr->initialized = 1;
-}
-
-/**
- * xmlDefaultSAXHandlerInit:
- *
- * Initialize the default SAX handler
- */
-void
-xmlDefaultSAXHandlerInit(void)
-{
- initxmlDefaultSAXHandler(&xmlDefaultSAXHandler, xmlGetWarningsDefaultValue);
-}
-
-#ifdef LIBXML_HTML_ENABLED
-
-/**
- * inithtmlDefaultSAXHandler:
- * @hdlr: the SAX handler
- *
- * Initialize the default HTML SAX handler
- */
-void
-inithtmlDefaultSAXHandler(xmlSAXHandler *hdlr)
-{
- if(hdlr->initialized == 1)
- return;
-
- hdlr->internalSubset = internalSubset;
- hdlr->externalSubset = NULL;
- hdlr->isStandalone = NULL;
- hdlr->hasInternalSubset = NULL;
- hdlr->hasExternalSubset = NULL;
- hdlr->resolveEntity = NULL;
- hdlr->getEntity = getEntity;
- hdlr->getParameterEntity = NULL;
- hdlr->entityDecl = NULL;
- hdlr->attributeDecl = NULL;
- hdlr->elementDecl = NULL;
- hdlr->notationDecl = NULL;
- hdlr->unparsedEntityDecl = NULL;
- hdlr->setDocumentLocator = setDocumentLocator;
- hdlr->startDocument = startDocument;
- hdlr->endDocument = endDocument;
- hdlr->startElement = startElement;
- hdlr->endElement = endElement;
- hdlr->reference = NULL;
- hdlr->characters = characters;
- hdlr->cdataBlock = cdataBlock;
- hdlr->ignorableWhitespace = ignorableWhitespace;
- hdlr->processingInstruction = NULL;
- hdlr->comment = comment;
- hdlr->warning = xmlParserWarning;
- hdlr->error = xmlParserError;
- hdlr->fatalError = xmlParserError;
-
- hdlr->initialized = 1;
-}
-
-/**
- * htmlDefaultSAXHandlerInit:
- *
- * Initialize the default SAX handler
- */
-void
-htmlDefaultSAXHandlerInit(void)
-{
- inithtmlDefaultSAXHandler(&htmlDefaultSAXHandler);
-}
-
-#endif /* LIBXML_HTML_ENABLED */
-
-#ifdef LIBXML_DOCB_ENABLED
-
-/**
- * initdocbDefaultSAXHandler:
- * @hdlr: the SAX handler
- *
- * Initialize the default DocBook SAX handler
- */
-void
-initdocbDefaultSAXHandler(xmlSAXHandler *hdlr)
-{
- if(hdlr->initialized == 1)
- return;
-
- hdlr->internalSubset = internalSubset;
- hdlr->externalSubset = NULL;
- hdlr->isStandalone = isStandalone;
- hdlr->hasInternalSubset = hasInternalSubset;
- hdlr->hasExternalSubset = hasExternalSubset;
- hdlr->resolveEntity = resolveEntity;
- hdlr->getEntity = getEntity;
- hdlr->getParameterEntity = NULL;
- hdlr->entityDecl = entityDecl;
- hdlr->attributeDecl = NULL;
- hdlr->elementDecl = NULL;
- hdlr->notationDecl = NULL;
- hdlr->unparsedEntityDecl = NULL;
- hdlr->setDocumentLocator = setDocumentLocator;
- hdlr->startDocument = startDocument;
- hdlr->endDocument = endDocument;
- hdlr->startElement = startElement;
- hdlr->endElement = endElement;
- hdlr->reference = reference;
- hdlr->characters = characters;
- hdlr->cdataBlock = NULL;
- hdlr->ignorableWhitespace = ignorableWhitespace;
- hdlr->processingInstruction = NULL;
- hdlr->comment = comment;
- hdlr->warning = xmlParserWarning;
- hdlr->error = xmlParserError;
- hdlr->fatalError = xmlParserError;
-
- hdlr->initialized = 1;
-}
-
-/**
- * docbDefaultSAXHandlerInit:
- *
- * Initialize the default SAX handler
- */
-void
-docbDefaultSAXHandlerInit(void)
-{
- initdocbDefaultSAXHandler(&docbDefaultSAXHandler);
-}
-
-#endif /* LIBXML_DOCB_ENABLED */
diff --git a/bundle/libxml/c14n.c b/bundle/libxml/c14n.c
deleted file mode 100644
index cd410ccf1f..0000000000
--- a/bundle/libxml/c14n.c
+++ /dev/null
@@ -1,1930 +0,0 @@
-/*
- * "Canonical XML" implementation
- * http://www.w3.org/TR/xml-c14n
- *
- * "Exclusive XML Canonicalization" implementation
- * http://www.w3.org/TR/xml-exc-c14n
- *
- * See Copyright for the status of this software.
- *
- * Author: Aleksey Sanin <aleksey@aleksey.com>
- */
-#define IN_LIBXML
-#include "libxml.h"
-#ifdef LIBXML_C14N_ENABLED
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <string.h>
-
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/uri.h>
-#include <libxml/xmlerror.h>
-#include <libxml/globals.h>
-#include <libxml/xpathInternals.h>
-#include <libxml/c14n.h>
-
-/************************************************************************
- * *
- * Some declaration better left private ATM *
- * *
- ************************************************************************/
-
-typedef enum {
- XMLC14N_BEFORE_DOCUMENT_ELEMENT = 0,
- XMLC14N_INSIDE_DOCUMENT_ELEMENT = 1,
- XMLC14N_AFTER_DOCUMENT_ELEMENT = 2
-} xmlC14NPosition;
-
-typedef struct _xmlC14NVisibleNsStack {
- int nsCurEnd; /* number of nodes in the set */
- int nsPrevStart; /* the begginning of the stack for previous visible node */
- int nsPrevEnd; /* the end of the stack for previous visible node */
- int nsMax; /* size of the array as allocated */
- xmlNsPtr *nsTab; /* array of ns in no particular order */
- xmlNodePtr *nodeTab;/* array of nodes in no particular order */
-} xmlC14NVisibleNsStack, *xmlC14NVisibleNsStackPtr;
-
-typedef struct _xmlC14NCtx {
- /* input parameters */
- xmlDocPtr doc;
- xmlC14NIsVisibleCallback is_visible_callback;
- void* user_data;
- int with_comments;
- xmlOutputBufferPtr buf;
-
- /* position in the XML document */
- xmlC14NPosition pos;
- int parent_is_doc;
- xmlC14NVisibleNsStackPtr ns_rendered;
-
- /* exclusive canonicalization */
- int exclusive;
- xmlChar **inclusive_ns_prefixes;
-} xmlC14NCtx, *xmlC14NCtxPtr;
-
-static xmlC14NVisibleNsStackPtr xmlC14NVisibleNsStackCreate (void);
-static void xmlC14NVisibleNsStackDestroy (xmlC14NVisibleNsStackPtr cur);
-static void xmlC14NVisibleNsStackAdd (xmlC14NVisibleNsStackPtr cur,
- xmlNsPtr ns,
- xmlNodePtr node);
-static void xmlC14NVisibleNsStackSave (xmlC14NVisibleNsStackPtr cur,
- xmlC14NVisibleNsStackPtr state);
-static void xmlC14NVisibleNsStackRestore (xmlC14NVisibleNsStackPtr cur,
- xmlC14NVisibleNsStackPtr state);
-static void xmlC14NVisibleNsStackShift (xmlC14NVisibleNsStackPtr cur);
-static int xmlC14NVisibleNsStackFind (xmlC14NVisibleNsStackPtr cur,
- xmlNsPtr ns);
-static int xmlExcC14NVisibleNsStackFind (xmlC14NVisibleNsStackPtr cur,
- xmlNsPtr ns,
- xmlC14NCtxPtr ctx);
-
-static int xmlC14NIsNodeInNodeset (xmlNodeSetPtr nodes,
- xmlNodePtr node,
- xmlNodePtr parent);
-
-
-
-static int xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur);
-static int xmlC14NProcessNodeList(xmlC14NCtxPtr ctx, xmlNodePtr cur);
-typedef enum {
- XMLC14N_NORMALIZE_ATTR = 0,
- XMLC14N_NORMALIZE_COMMENT = 1,
- XMLC14N_NORMALIZE_PI = 2,
- XMLC14N_NORMALIZE_TEXT = 3
-} xmlC14NNormalizationMode;
-
-static xmlChar *xmlC11NNormalizeString(const xmlChar * input,
- xmlC14NNormalizationMode mode);
-
-#define xmlC11NNormalizeAttr( a ) \
- xmlC11NNormalizeString((a), XMLC14N_NORMALIZE_ATTR)
-#define xmlC11NNormalizeComment( a ) \
- xmlC11NNormalizeString((a), XMLC14N_NORMALIZE_COMMENT)
-#define xmlC11NNormalizePI( a ) \
- xmlC11NNormalizeString((a), XMLC14N_NORMALIZE_PI)
-#define xmlC11NNormalizeText( a ) \
- xmlC11NNormalizeString((a), XMLC14N_NORMALIZE_TEXT)
-
-#define xmlC14NIsVisible( ctx, node, parent ) \
- (((ctx)->is_visible_callback != NULL) ? \
- (ctx)->is_visible_callback((ctx)->user_data, \
- (xmlNodePtr)(node), (xmlNodePtr)(parent)) : 1)
-/************************************************************************
- * *
- * The implementation internals *
- * *
- ************************************************************************/
-#define XML_NAMESPACES_DEFAULT 16
-
-static int
-xmlC14NIsNodeInNodeset(xmlNodeSetPtr nodes, xmlNodePtr node, xmlNodePtr parent) {
- if((nodes != NULL) && (node != NULL)) {
- if(node->type != XML_NAMESPACE_DECL) {
- return(xmlXPathNodeSetContains(nodes, node));
- } else {
- xmlNs ns;
-
- memcpy(&ns, node, sizeof(ns));
- ns.next = (xmlNsPtr)parent; /* this is a libxml hack! check xpath.c for details */
-
- /*
- * If the input is an XPath node-set, then the node-set must explicitly
- * contain every node to be rendered to the canonical form.
- */
- return(xmlXPathNodeSetContains(nodes, (xmlNodePtr)&ns));
- }
- }
- return(1);
-}
-
-static xmlC14NVisibleNsStackPtr
-xmlC14NVisibleNsStackCreate(void) {
- xmlC14NVisibleNsStackPtr ret;
-
- ret = (xmlC14NVisibleNsStackPtr) xmlMalloc(sizeof(xmlC14NVisibleNsStack));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NVisibleNsStackCreate: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlC14NVisibleNsStack));
- return(ret);
-}
-
-static void
-xmlC14NVisibleNsStackDestroy(xmlC14NVisibleNsStackPtr cur) {
- if(cur == NULL) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NVisibleNsStackDestroy: cur is null.\n");
-#endif
- return;
- }
- if(cur->nsTab != NULL) {
- memset(cur->nsTab, 0, cur->nsMax * sizeof(xmlNsPtr));
- xmlFree(cur->nsTab);
- }
- if(cur->nodeTab != NULL) {
- memset(cur->nodeTab, 0, cur->nsMax * sizeof(xmlNodePtr));
- xmlFree(cur->nodeTab);
- }
- memset(cur, 0, sizeof(xmlC14NVisibleNsStack));
- xmlFree(cur);
-
-}
-
-static void
-xmlC14NVisibleNsStackAdd(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns, xmlNodePtr node) {
- if((cur == NULL) ||
- ((cur->nsTab == NULL) && (cur->nodeTab != NULL)) ||
- ((cur->nsTab != NULL) && (cur->nodeTab == NULL))) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NVisibleNsStackAdd: cur is null.\n");
-#endif
- return;
- }
-
- if ((cur->nsTab == NULL) && (cur->nodeTab == NULL)) {
- cur->nsTab = (xmlNsPtr*) xmlMalloc(XML_NAMESPACES_DEFAULT * sizeof(xmlNsPtr));
- cur->nodeTab = (xmlNodePtr*) xmlMalloc(XML_NAMESPACES_DEFAULT * sizeof(xmlNodePtr));
- if ((cur->nsTab == NULL) || (cur->nodeTab == NULL)) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NVisibleNsStackAdd: out of memory\n");
- return;
- }
- memset(cur->nsTab, 0 , XML_NAMESPACES_DEFAULT * sizeof(xmlNsPtr));
- memset(cur->nodeTab, 0 , XML_NAMESPACES_DEFAULT * sizeof(xmlNodePtr));
- cur->nsMax = XML_NAMESPACES_DEFAULT;
- } else if(cur->nsMax == cur->nsCurEnd) {
- void *tmp;
- int tmpSize;
-
- tmpSize = 2 * cur->nsMax;
- tmp = xmlRealloc(cur->nsTab, tmpSize * sizeof(xmlNsPtr));
- if (tmp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NVisibleNsStackAdd: out of memory\n");
- return;
- }
- cur->nsTab = (xmlNsPtr*)tmp;
-
- tmp = xmlRealloc(cur->nodeTab, tmpSize * sizeof(xmlNodePtr));
- if (tmp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NVisibleNsStackAdd: out of memory\n");
- return;
- }
- cur->nodeTab = (xmlNodePtr*)tmp;
-
- cur->nsMax = tmpSize;
- }
- cur->nsTab[cur->nsCurEnd] = ns;
- cur->nodeTab[cur->nsCurEnd] = node;
-
- ++cur->nsCurEnd;
-}
-
-static void
-xmlC14NVisibleNsStackSave(xmlC14NVisibleNsStackPtr cur, xmlC14NVisibleNsStackPtr state) {
- if((cur == NULL) || (state == NULL)) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NVisibleNsStackSave: cur or state is null.\n");
-#endif
- return;
- }
-
- state->nsCurEnd = cur->nsCurEnd;
- state->nsPrevStart = cur->nsPrevStart;
- state->nsPrevEnd = cur->nsPrevEnd;
-}
-
-static void
-xmlC14NVisibleNsStackRestore(xmlC14NVisibleNsStackPtr cur, xmlC14NVisibleNsStackPtr state) {
- if((cur == NULL) || (state == NULL)) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NVisibleNsStackRestore: cur or state is null.\n");
-#endif
- return;
- }
- cur->nsCurEnd = state->nsCurEnd;
- cur->nsPrevStart = state->nsPrevStart;
- cur->nsPrevEnd = state->nsPrevEnd;
-}
-
-static void
-xmlC14NVisibleNsStackShift(xmlC14NVisibleNsStackPtr cur) {
- if(cur == NULL) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NVisibleNsStackRestore: cur is null.\n");
-#endif
- return;
- }
- cur->nsPrevStart = cur->nsPrevEnd;
- cur->nsPrevEnd = cur->nsCurEnd;
-}
-
-static int
-xmlC14NStrEqual(const xmlChar *str1, const xmlChar *str2) {
- if (str1 == str2) return(1);
- if (str1 == NULL) return((*str2) == '\0');
- if (str2 == NULL) return((*str1) == '\0');
- do {
- if (*str1++ != *str2) return(0);
- } while (*str2++);
- return(1);
-}
-
-/**
- * xmlC14NVisibleNsStackFind:
- * @ctx: the C14N context
- * @ns: the namespace to check
- *
- * Checks whether the given namespace was already rendered or not
- *
- * Returns 1 if we already wrote this namespace or 0 otherwise
- */
-static int
-xmlC14NVisibleNsStackFind(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns)
-{
- int i;
- const xmlChar *prefix;
- const xmlChar *href;
- int has_empty_ns;
-
- if(cur == NULL) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NVisibleNsStackFind: cur is null.\n");
-#endif
- return (0);
- }
-
- /*
- * if the default namespace xmlns="" is not defined yet then
- * we do not want to print it out
- */
- prefix = ((ns == NULL) || (ns->prefix == NULL)) ? BAD_CAST "" : ns->prefix;
- href = ((ns == NULL) || (ns->href == NULL)) ? BAD_CAST "" : ns->href;
- has_empty_ns = (xmlC14NStrEqual(prefix, NULL) && xmlC14NStrEqual(href, NULL));
-
- if (cur->nsTab != NULL) {
- int start = (has_empty_ns) ? 0 : cur->nsPrevStart;
- for (i = cur->nsCurEnd - 1; i >= start; --i) {
- xmlNsPtr ns1 = cur->nsTab[i];
-
- if(xmlC14NStrEqual(prefix, (ns1 != NULL) ? ns1->prefix : NULL)) {
- return(xmlC14NStrEqual(href, (ns1 != NULL) ? ns1->href : NULL));
- }
- }
- }
- return(has_empty_ns);
-}
-
-static int
-xmlExcC14NVisibleNsStackFind(xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns, xmlC14NCtxPtr ctx) {
- int i;
- const xmlChar *prefix;
- const xmlChar *href;
- int has_empty_ns;
-
- if(cur == NULL) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlExcC14NVisibleNsStackFind: cur is null.\n");
-#endif
- return (0);
- }
-
- /*
- * if the default namespace xmlns="" is not defined yet then
- * we do not want to print it out
- */
- prefix = ((ns == NULL) || (ns->prefix == NULL)) ? BAD_CAST "" : ns->prefix;
- href = ((ns == NULL) || (ns->href == NULL)) ? BAD_CAST "" : ns->href;
- has_empty_ns = (xmlC14NStrEqual(prefix, NULL) && xmlC14NStrEqual(href, NULL));
-
- if (cur->nsTab != NULL) {
- int start = 0;
- for (i = cur->nsCurEnd - 1; i >= start; --i) {
- xmlNsPtr ns1 = cur->nsTab[i];
-
- if(xmlC14NStrEqual(prefix, (ns1 != NULL) ? ns1->prefix : NULL)) {
- if(xmlC14NStrEqual(href, (ns1 != NULL) ? ns1->href : NULL)) {
- return(xmlC14NIsVisible(ctx, ns1, cur->nodeTab[i]));
- } else {
- return(0);
- }
- }
- }
- }
- return(has_empty_ns);
-}
-
-
-
-
-/**
- * xmlC14NIsXmlNs:
- * @ns: the namespace to check
- *
- * Checks whether the given namespace is a default "xml:" namespace
- * with href="http://www.w3.org/XML/1998/namespace"
- *
- * Returns 1 if the node is default or 0 otherwise
- */
-
-/* todo: make it a define? */
-static int
-xmlC14NIsXmlNs(xmlNsPtr ns)
-{
- return ((ns != NULL) &&
- (xmlStrEqual(ns->prefix, BAD_CAST "xml")) &&
- (xmlStrEqual(ns->href,
- BAD_CAST
- "http://www.w3.org/XML/1998/namespace")));
-}
-
-
-/**
- * xmlC14NNsCompare:
- * @ns1: the pointer to first namespace
- * @ns2: the pointer to second namespace
- *
- * Compares the namespaces by names (prefixes).
- *
- * Returns -1 if ns1 < ns2, 0 if ns1 == ns2 or 1 if ns1 > ns2.
- */
-static int
-xmlC14NNsCompare(xmlNsPtr ns1, xmlNsPtr ns2)
-{
- if (ns1 == ns2)
- return (0);
- if (ns1 == NULL)
- return (-1);
- if (ns2 == NULL)
- return (1);
-
- return (xmlStrcmp(ns1->prefix, ns2->prefix));
-}
-
-
-/**
- * xmlC14NPrintNamespaces:
- * @ns: the pointer to namespace
- * @ctx: the C14N context
- *
- * Prints the given namespace to the output buffer from C14N context.
- *
- * Returns 1 on success or 0 on fail.
- */
-static int
-xmlC14NPrintNamespaces(const xmlNsPtr ns, xmlC14NCtxPtr ctx)
-{
-
- if ((ns == NULL) || (ctx == NULL)) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NPrintNamespace: namespace or context pointer is null\n");
-#endif
- return 0;
- }
-
- if (ns->prefix != NULL) {
- xmlOutputBufferWriteString(ctx->buf, " xmlns:");
- xmlOutputBufferWriteString(ctx->buf, (const char *) ns->prefix);
- xmlOutputBufferWriteString(ctx->buf, "=\"");
- } else {
- xmlOutputBufferWriteString(ctx->buf, " xmlns=\"");
- }
- if(ns->href != NULL) {
- xmlOutputBufferWriteString(ctx->buf, (const char *) ns->href);
- }
- xmlOutputBufferWriteString(ctx->buf, "\"");
- return (1);
-}
-
-/**
- * xmlC14NProcessNamespacesAxis:
- * @ctx: the C14N context
- * @node: the current node
- *
- * Prints out canonical namespace axis of the current node to the
- * buffer from C14N context as follows
- *
- * Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n)
- *
- * Namespace Axis
- * Consider a list L containing only namespace nodes in the
- * axis and in the node-set in lexicographic order (ascending). To begin
- * processing L, if the first node is not the default namespace node (a node
- * with no namespace URI and no local name), then generate a space followed
- * by xmlns="" if and only if the following conditions are met:
- * - the element E that owns the axis is in the node-set
- * - The nearest ancestor element of E in the node-set has a default
- * namespace node in the node-set (default namespace nodes always
- * have non-empty values in XPath)
- * The latter condition eliminates unnecessary occurrences of xmlns="" in
- * the canonical form since an element only receives an xmlns="" if its
- * default namespace is empty and if it has an immediate parent in the
- * canonical form that has a non-empty default namespace. To finish
- * processing L, simply process every namespace node in L, except omit
- * namespace node with local name xml, which defines the xml prefix,
- * if its string value is http://www.w3.org/XML/1998/namespace.
- *
- * Exclusive XML Canonicalization v 1.0 (http://www.w3.org/TR/xml-exc-c14n)
- * Canonical XML applied to a document subset requires the search of the
- * ancestor nodes of each orphan element node for attributes in the xml
- * namespace, such as xml:lang and xml:space. These are copied into the
- * element node except if a declaration of the same attribute is already
- * in the attribute axis of the element (whether or not it is included in
- * the document subset). This search and copying are omitted from the
- * Exclusive XML Canonicalization method.
- *
- * Returns 0 on success or -1 on fail.
- */
-static int
-xmlC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
-{
- xmlNodePtr n;
- xmlNsPtr ns, tmp;
- xmlListPtr list;
- int already_rendered;
- int has_empty_ns = 0;
-
- if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessNamespacesAxis: Null context or node pointer or type != XML_ELEMENT_NODE.\n");
-#endif
- return (-1);
- }
-
- /*
- * Create a sorted list to store element namespaces
- */
- list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NNsCompare);
- if (list == NULL) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessNamespacesAxis: list creation failed\n");
-#endif
- return (-1);
- }
-
- /* check all namespaces */
- for(n = cur; n != NULL; n = n->parent) {
- for(ns = n->nsDef; ns != NULL; ns = ns->next) {
- tmp = xmlSearchNs(cur->doc, cur, ns->prefix);
-
- if((tmp == ns) && !xmlC14NIsXmlNs(ns) && xmlC14NIsVisible(ctx, ns, cur)) {
- already_rendered = xmlC14NVisibleNsStackFind(ctx->ns_rendered, ns);
- if(visible) {
- xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur);
- }
- if(!already_rendered) {
- xmlListInsert(list, ns);
- }
- if(xmlStrlen(ns->prefix) == 0) {
- has_empty_ns = 1;
- }
- }
- }
- }
-
- /**
- * if the first node is not the default namespace node (a node with no
- * namespace URI and no local name), then generate a space followed by
- * xmlns="" if and only if the following conditions are met:
- * - the element E that owns the axis is in the node-set
- * - the nearest ancestor element of E in the node-set has a default
- * namespace node in the node-set (default namespace nodes always
- * have non-empty values in XPath)
- */
- if(visible && !has_empty_ns) {
- static xmlNs ns_default;
-
- memset(&ns_default, 0, sizeof(ns_default));
- if(!xmlC14NVisibleNsStackFind(ctx->ns_rendered, &ns_default)) {
- xmlC14NPrintNamespaces(&ns_default, ctx);
- }
- }
-
-
- /*
- * print out all elements from list
- */
- xmlListWalk(list, (xmlListWalker) xmlC14NPrintNamespaces, (const void *) ctx);
-
- /*
- * Cleanup
- */
- xmlListDelete(list);
- return (0);
-}
-
-
-/**
- * xmlExcC14NProcessNamespacesAxis:
- * @ctx: the C14N context
- * @node: the current node
- *
- * Prints out exclusive canonical namespace axis of the current node to the
- * buffer from C14N context as follows
- *
- * Exclusive XML Canonicalization
- * http://www.w3.org/TR/xml-exc-c14n
- *
- * If the element node is in the XPath subset then output the node in
- * accordance with Canonical XML except for namespace nodes which are
- * rendered as follows:
- *
- * 1. Render each namespace node iff:
- * * it is visibly utilized by the immediate parent element or one of
- * its attributes, or is present in InclusiveNamespaces PrefixList, and
- * * its prefix and value do not appear in ns_rendered. ns_rendered is
- * obtained by popping the state stack in order to obtain a list of
- * prefixes and their values which have already been rendered by
- * an output ancestor of the namespace node's parent element.
- * 2. Append the rendered namespace node to the list ns_rendered of namespace
- * nodes rendered by output ancestors. Push ns_rendered on state stack and
- * recurse.
- * 3. After the recursion returns, pop thestate stack.
- *
- *
- * Returns 0 on success or -1 on fail.
- */
-static int
-xmlExcC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
-{
- xmlNsPtr ns;
- xmlListPtr list;
- xmlAttrPtr attr;
- int already_rendered;
- int has_empty_ns = 0;
- int has_visibly_utilized_empty_ns = 0;
- int has_empty_ns_in_inclusive_list = 0;
-
- if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlExcC14NProcessNamespacesAxis: Null context or node pointer or type != XML_ELEMENT_NODE.\n");
-#endif
- return (-1);
- }
-
- if(!ctx->exclusive) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlExcC14NProcessNamespacesAxis: called for non-exclusive canonization or rendered stack is NULL.\n");
-#endif
- return (-1);
-
- }
-
- /*
- * Create a sorted list to store element namespaces
- */
- list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NNsCompare);
- if (list == NULL) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlExcC14NProcessNamespacesAxis: list creation failed\n");
-#endif
- return (-1);
- }
-
- /*
- * process inclusive namespaces:
- * All namespace nodes appearing on inclusive ns list are
- * handled as provided in Canonical XML
- */
- if(ctx->inclusive_ns_prefixes != NULL) {
- xmlChar *prefix;
- int i;
-
- for (i = 0; ctx->inclusive_ns_prefixes[i] != NULL; ++i) {
- prefix = ctx->inclusive_ns_prefixes[i];
- /*
- * Special values for namespace with empty prefix
- */
- if (xmlStrEqual(prefix, BAD_CAST "#default")
- || xmlStrEqual(prefix, BAD_CAST "")) {
- prefix = NULL;
- has_empty_ns_in_inclusive_list = 1;
- }
-
- ns = xmlSearchNs(cur->doc, cur, prefix);
- if((ns != NULL) && !xmlC14NIsXmlNs(ns) && xmlC14NIsVisible(ctx, ns, cur)) {
- already_rendered = xmlC14NVisibleNsStackFind(ctx->ns_rendered, ns);
- if(visible) {
- xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur);
- }
- if(!already_rendered) {
- xmlListInsert(list, ns);
- }
- if(xmlStrlen(ns->prefix) == 0) {
- has_empty_ns = 1;
- }
- }
- }
- }
-
- /* add node namespace */
- if(cur->ns != NULL) {
- ns = cur->ns;
- } else {
- ns = xmlSearchNs(cur->doc, cur, NULL);
- has_visibly_utilized_empty_ns = 1;
- }
- if((ns != NULL) && !xmlC14NIsXmlNs(ns)) {
- if(visible && xmlC14NIsVisible(ctx, ns, cur)) {
- if(!xmlExcC14NVisibleNsStackFind(ctx->ns_rendered, ns, ctx)) {
- xmlListInsert(list, ns);
- }
- }
- if(visible) {
- xmlC14NVisibleNsStackAdd(ctx->ns_rendered, ns, cur);
- }
- if(xmlStrlen(ns->prefix) == 0) {
- has_empty_ns = 1;
- }
- }
-
-
- /* add attributes */
- for(attr = cur->properties; attr != NULL; attr = attr->next) {
- /*
- * we need to check that attribute is visible and has non
- * default namespace (XML Namespaces: "default namespaces
- * do not apply directly to attributes")
- */
- if((attr->ns != NULL) && xmlC14NIsVisible(ctx, attr, cur)) {
- already_rendered = xmlExcC14NVisibleNsStackFind(ctx->ns_rendered, attr->ns, ctx);
- xmlC14NVisibleNsStackAdd(ctx->ns_rendered, attr->ns, (xmlNodePtr)attr);
- if(!already_rendered && visible) {
- xmlListInsert(list, attr->ns);
- }
- if(xmlStrlen(attr->ns->prefix) == 0) {
- has_empty_ns = 1;
- }
- } else if(attr->ns == NULL) {
- has_visibly_utilized_empty_ns = 1;
- }
- }
-
- /*
- * Process xmlns=""
- */
- if(visible && has_visibly_utilized_empty_ns &&
- !has_empty_ns && !has_empty_ns_in_inclusive_list) {
- static xmlNs ns_default;
-
- memset(&ns_default, 0, sizeof(ns_default));
-
- already_rendered = xmlExcC14NVisibleNsStackFind(ctx->ns_rendered, &ns_default, ctx);
- if(!already_rendered) {
- xmlC14NPrintNamespaces(&ns_default, ctx);
- }
- } else if(visible && !has_empty_ns && has_empty_ns_in_inclusive_list) {
- static xmlNs ns_default;
-
- memset(&ns_default, 0, sizeof(ns_default));
- if(!xmlC14NVisibleNsStackFind(ctx->ns_rendered, &ns_default)) {
- xmlC14NPrintNamespaces(&ns_default, ctx);
- }
- }
-
-
-
- /*
- * print out all elements from list
- */
- xmlListWalk(list, (xmlListWalker) xmlC14NPrintNamespaces, (const void *) ctx);
-
- /*
- * Cleanup
- */
- xmlListDelete(list);
- return (0);
-}
-
-
-/**
- * xmlC14NAttrsCompare:
- * @attr1: the pointer tls o first attr
- * @attr2: the pointer to second attr
- *
- * Prints the given attribute to the output buffer from C14N context.
- *
- * Returns -1 if attr1 < attr2, 0 if attr1 == attr2 or 1 if attr1 > attr2.
- */
-static int
-xmlC14NAttrsCompare(xmlAttrPtr attr1, xmlAttrPtr attr2)
-{
- int ret = 0;
-
- /*
- * Simple cases
- */
- if (attr1 == attr2)
- return (0);
- if (attr1 == NULL)
- return (-1);
- if (attr2 == NULL)
- return (1);
- if (attr1->ns == attr2->ns) {
- return (xmlStrcmp(attr1->name, attr2->name));
- }
-
- /*
- * Attributes in the default namespace are first
- * because the default namespace is not applied to
- * unqualified attributes
- */
- if (attr1->ns == NULL)
- return (-1);
- if (attr2->ns == NULL)
- return (1);
- if (attr1->ns->prefix == NULL)
- return (-1);
- if (attr2->ns->prefix == NULL)
- return (1);
-
- ret = xmlStrcmp(attr1->ns->href, attr2->ns->href);
- if (ret == 0) {
- ret = xmlStrcmp(attr1->name, attr2->name);
- }
- return (ret);
-}
-
-
-/**
- * xmlC14NPrintAttrs:
- * @attr: the pointer to attr
- * @ctx: the C14N context
- *
- * Prints out canonical attribute urrent node to the
- * buffer from C14N context as follows
- *
- * Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n)
- *
- * Returns 1 on success or 0 on fail.
- */
-static int
-xmlC14NPrintAttrs(const xmlAttrPtr attr, xmlC14NCtxPtr ctx)
-{
- xmlChar *value;
- xmlChar *buffer;
-
- if ((attr == NULL) || (ctx == NULL)) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NPrintAttrs: attr == NULL or ctx == NULL\n");
-#endif
- return (0);
- }
-
- xmlOutputBufferWriteString(ctx->buf, " ");
- if (attr->ns != NULL && xmlStrlen(attr->ns->prefix) > 0) {
- xmlOutputBufferWriteString(ctx->buf,
- (const char *) attr->ns->prefix);
- xmlOutputBufferWriteString(ctx->buf, ":");
- }
- xmlOutputBufferWriteString(ctx->buf, (const char *) attr->name);
- xmlOutputBufferWriteString(ctx->buf, "=\"");
-
- value = xmlNodeListGetString(attr->doc, attr->children, 1);
- /* todo: should we log an error if value==NULL ? */
- if (value != NULL) {
- buffer = xmlC11NNormalizeAttr(value);
- xmlFree(value);
- if (buffer != NULL) {
- xmlOutputBufferWriteString(ctx->buf, (const char *) buffer);
- xmlFree(buffer);
- } else {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NPrintAttrs: xmlC11NNormalizeAttr failed\n");
-#endif
- return (0);
- }
- }
- xmlOutputBufferWriteString(ctx->buf, "\"");
- return (1);
-}
-
-/**
- * xmlC14NProcessAttrsAxis:
- * @ctx: the C14N context
- * @cur: the current node
- *
- * Prints out canonical attribute axis of the current node to the
- * buffer from C14N context as follows
- *
- * Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n)
- *
- * Attribute Axis
- * In lexicographic order (ascending), process each node that
- * is in the element's attribute axis and in the node-set.
- *
- * The processing of an element node E MUST be modified slightly
- * when an XPath node-set is given as input and the element's
- * parent is omitted from the node-set.
- *
- *
- * Exclusive XML Canonicalization v 1.0 (http://www.w3.org/TR/xml-exc-c14n)
- *
- * Canonical XML applied to a document subset requires the search of the
- * ancestor nodes of each orphan element node for attributes in the xml
- * namespace, such as xml:lang and xml:space. These are copied into the
- * element node except if a declaration of the same attribute is already
- * in the attribute axis of the element (whether or not it is included in
- * the document subset). This search and copying are omitted from the
- * Exclusive XML Canonicalization method.
- *
- * Returns 0 on success or -1 on fail.
- */
-static int
-xmlC14NProcessAttrsAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur)
-{
- xmlAttrPtr attr;
- xmlListPtr list;
-
- if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessAttrsAxis: Null context or node pointer or type != XML_ELEMENT_NODE.\n");
-#endif
- return (-1);
- }
-
- /*
- * Create a sorted list to store element attributes
- */
- list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NAttrsCompare);
- if (list == NULL) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessAttrsAxis: list creation failed\n");
-#endif
- return (-1);
- }
-
- /*
- * Add all visible attributes from current node.
- */
- attr = cur->properties;
- while (attr != NULL) {
- /* check that attribute is visible */
- if (xmlC14NIsVisible(ctx, attr, cur)) {
- xmlListInsert(list, attr);
- }
- attr = attr->next;
- }
-
- /*
- * include attributes in "xml" namespace defined in ancestors
- * (only for non-exclusive XML Canonicalization)
- */
- if ((!ctx->exclusive) && (cur->parent != NULL)
- && (!xmlC14NIsVisible(ctx, cur->parent, cur->parent->parent))) {
- /*
- * If XPath node-set is not specified then the parent is always
- * visible!
- */
- cur = cur->parent;
- while (cur != NULL) {
- attr = cur->properties;
- while (attr != NULL) {
- if ((attr->ns != NULL)
- && (xmlStrEqual(attr->ns->prefix, BAD_CAST "xml"))) {
- if (xmlListSearch(list, attr) == NULL) {
- xmlListInsert(list, attr);
- }
- }
- attr = attr->next;
- }
- cur = cur->parent;
- }
- }
-
- /*
- * print out all elements from list
- */
- xmlListWalk(list, (xmlListWalker) xmlC14NPrintAttrs, (const void *) ctx);
-
- /*
- * Cleanup
- */
- xmlListDelete(list);
- return (0);
-}
-
-/**
- * xmlC14NCheckForRelativeNamespaces:
- * @ctx: the C14N context
- * @cur: the current element node
- *
- * Checks that current element node has no relative namespaces defined
- *
- * Returns 0 if the node has no relative namespaces or -1 otherwise.
- */
-static int
-xmlC14NCheckForRelativeNamespaces(xmlC14NCtxPtr ctx, xmlNodePtr cur)
-{
- xmlNsPtr ns;
-
- if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NCheckForRelativeNamespaces: Null context or node pointer or type != XML_ELEMENT_NODE.\n");
-#endif
- return (-1);
- }
-
- ns = cur->nsDef;
- while (ns != NULL) {
- if (xmlStrlen(ns->href) > 0) {
- xmlURIPtr uri;
-
- uri = xmlParseURI((const char *) ns->href);
- if (uri == NULL) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NCheckForRelativeNamespaces: unable to parse uri=\"%s\".\n",
- ns->href);
-#endif
- return (-1);
- }
- if (xmlStrlen((const xmlChar *) uri->scheme) == 0) {
- xmlFreeURI(uri);
- return (-1);
- }
- if ((!xmlStrEqual
- ((const xmlChar *) uri->scheme, BAD_CAST "urn"))
- && (xmlStrlen((const xmlChar *) uri->server) == 0)) {
- xmlFreeURI(uri);
- return (-1);
- }
- xmlFreeURI(uri);
- }
- ns = ns->next;
- }
- return (0);
-}
-
-/**
- * xmlC14NProcessElementNode:
- * @ctx: the pointer to C14N context object
- * @cur: the node to process
- *
- * Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n)
- *
- * Element Nodes
- * If the element is not in the node-set, then the result is obtained
- * by processing the namespace axis, then the attribute axis, then
- * processing the child nodes of the element that are in the node-set
- * (in document order). If the element is in the node-set, then the result
- * is an open angle bracket (<), the element QName, the result of
- * processing the namespace axis, the result of processing the attribute
- * axis, a close angle bracket (>), the result of processing the child
- * nodes of the element that are in the node-set (in document order), an
- * open angle bracket, a forward slash (/), the element QName, and a close
- * angle bracket.
- *
- * Returns non-negative value on success or negative value on fail
- */
-static int
-xmlC14NProcessElementNode(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible)
-{
- int ret;
- xmlC14NVisibleNsStack state;
- int parent_is_doc = 0;
-
- if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessElementNode: Null context or node pointer or type != XML_ELEMENT_NODE.\n");
-#endif
- return (-1);
- }
-
- /*
- * Check relative relative namespaces:
- * implementations of XML canonicalization MUST report an operation
- * failure on documents containing relative namespace URIs.
- */
- if (xmlC14NCheckForRelativeNamespaces(ctx, cur) < 0) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessElementNode: xmlC14NCheckForRelativeNamespaces failed.\n");
-#endif
- return (-1);
- }
-
-
- /*
- * Save ns_rendered stack position
- */
- xmlC14NVisibleNsStackSave(ctx->ns_rendered, &state);
-
- if (visible) {
- if (ctx->parent_is_doc) {
- /* save this flag into the stack */
- parent_is_doc = ctx->parent_is_doc;
- ctx->parent_is_doc = 0;
- ctx->pos = XMLC14N_INSIDE_DOCUMENT_ELEMENT;
- }
- xmlOutputBufferWriteString(ctx->buf, "<");
-
- if ((cur->ns != NULL) && (xmlStrlen(cur->ns->prefix) > 0)) {
- xmlOutputBufferWriteString(ctx->buf,
- (const char *) cur->ns->prefix);
- xmlOutputBufferWriteString(ctx->buf, ":");
- }
- xmlOutputBufferWriteString(ctx->buf, (const char *) cur->name);
- }
-
- if (!ctx->exclusive) {
- ret = xmlC14NProcessNamespacesAxis(ctx, cur, visible);
- } else {
- ret = xmlExcC14NProcessNamespacesAxis(ctx, cur, visible);
- }
- if (ret < 0) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessElementNode: xmlC14NProcessNamespacesAxis failed.\n");
-#endif
- return (-1);
- }
- /* todo: shouldn't this go to "visible only"? */
- if(visible) {
- xmlC14NVisibleNsStackShift(ctx->ns_rendered);
- }
-
- if(visible) {
- ret = xmlC14NProcessAttrsAxis(ctx, cur);
- if (ret < 0) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessElementNode: xmlC14NProcessAttrsAxis failed.\n");
-#endif
- return (-1);
- }
- }
-
- if (visible) {
- xmlOutputBufferWriteString(ctx->buf, ">");
- }
- if (cur->children != NULL) {
- ret = xmlC14NProcessNodeList(ctx, cur->children);
- if (ret < 0) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessElementNode: xmlC14NProcessNodeList failed.\n");
-#endif
- return (-1);
- }
- }
- if (visible) {
- xmlOutputBufferWriteString(ctx->buf, "</");
- if ((cur->ns != NULL) && (xmlStrlen(cur->ns->prefix) > 0)) {
- xmlOutputBufferWriteString(ctx->buf,
- (const char *) cur->ns->prefix);
- xmlOutputBufferWriteString(ctx->buf, ":");
- }
- xmlOutputBufferWriteString(ctx->buf, (const char *) cur->name);
- xmlOutputBufferWriteString(ctx->buf, ">");
- if (parent_is_doc) {
- /* restore this flag from the stack for next node */
- ctx->parent_is_doc = parent_is_doc;
- ctx->pos = XMLC14N_AFTER_DOCUMENT_ELEMENT;
- }
- }
-
- /*
- * Restore ns_rendered stack position
- */
- xmlC14NVisibleNsStackRestore(ctx->ns_rendered, &state);
- return (0);
-}
-
-/**
- * xmlC14NProcessNode:
- * @ctx: the pointer to C14N context object
- * @cur: the node to process
- *
- * Processes the given node
- *
- * Returns non-negative value on success or negative value on fail
- */
-static int
-xmlC14NProcessNode(xmlC14NCtxPtr ctx, xmlNodePtr cur)
-{
- int ret = 0;
- int visible;
-
- if ((ctx == NULL) || (cur == NULL)) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessNode: Null context or node pointer.\n");
-#endif
- return (-1);
- }
-
- visible = xmlC14NIsVisible(ctx, cur, cur->parent);
- switch (cur->type) {
- case XML_ELEMENT_NODE:
- ret = xmlC14NProcessElementNode(ctx, cur, visible);
- break;
- case XML_CDATA_SECTION_NODE:
- case XML_TEXT_NODE:
- /*
- * Text Nodes
- * the string value, except all ampersands are replaced
- * by &amp;, all open angle brackets (<) are replaced by &lt;, all closing
- * angle brackets (>) are replaced by &gt;, and all #xD characters are
- * replaced by &#xD;.
- */
- /* cdata sections are processed as text nodes */
- /* todo: verify that cdata sections are included in XPath nodes set */
- if ((visible) && (cur->content != NULL)) {
- xmlChar *buffer;
-
- buffer = xmlC11NNormalizeText(cur->content);
- if (buffer != NULL) {
- xmlOutputBufferWriteString(ctx->buf,
- (const char *) buffer);
- xmlFree(buffer);
- } else {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessNode: xmlC11NNormalizeText() failed\n");
-#endif
- return (-1);
- }
- }
- break;
- case XML_PI_NODE:
- /*
- * Processing Instruction (PI) Nodes-
- * The opening PI symbol (<?), the PI target name of the node,
- * a leading space and the string value if it is not empty, and
- * the closing PI symbol (?>). If the string value is empty,
- * then the leading space is not added. Also, a trailing #xA is
- * rendered after the closing PI symbol for PI children of the
- * root node with a lesser document order than the document
- * element, and a leading #xA is rendered before the opening PI
- * symbol of PI children of the root node with a greater document
- * order than the document element.
- */
- if (visible) {
- if (ctx->pos == XMLC14N_AFTER_DOCUMENT_ELEMENT) {
- xmlOutputBufferWriteString(ctx->buf, "\x0A<?");
- } else {
- xmlOutputBufferWriteString(ctx->buf, "<?");
- }
-
- xmlOutputBufferWriteString(ctx->buf,
- (const char *) cur->name);
- if ((cur->content != NULL) && (*(cur->content) != '\0')) {
- xmlChar *buffer;
-
- xmlOutputBufferWriteString(ctx->buf, " ");
-
- /* todo: do we need to normalize pi? */
- buffer = xmlC11NNormalizePI(cur->content);
- if (buffer != NULL) {
- xmlOutputBufferWriteString(ctx->buf,
- (const char *) buffer);
- xmlFree(buffer);
- } else {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessNode: xmlC11NNormalizePI() failed\n");
-#endif
- return (-1);
- }
- }
-
- if (ctx->pos == XMLC14N_BEFORE_DOCUMENT_ELEMENT) {
- xmlOutputBufferWriteString(ctx->buf, "?>\x0A");
- } else {
- xmlOutputBufferWriteString(ctx->buf, "?>");
- }
- }
- break;
- case XML_COMMENT_NODE:
- /*
- * Comment Nodes
- * Nothing if generating canonical XML without comments. For
- * canonical XML with comments, generate the opening comment
- * symbol (<!--), the string value of the node, and the
- * closing comment symbol (-->). Also, a trailing #xA is rendered
- * after the closing comment symbol for comment children of the
- * root node with a lesser document order than the document
- * element, and a leading #xA is rendered before the opening
- * comment symbol of comment children of the root node with a
- * greater document order than the document element. (Comment
- * children of the root node represent comments outside of the
- * top-level document element and outside of the document type
- * declaration).
- */
- if (visible && ctx->with_comments) {
- if (ctx->pos == XMLC14N_AFTER_DOCUMENT_ELEMENT) {
- xmlOutputBufferWriteString(ctx->buf, "\x0A<!--");
- } else {
- xmlOutputBufferWriteString(ctx->buf, "<!--");
- }
-
- if (cur->content != NULL) {
- xmlChar *buffer;
-
- /* todo: do we need to normalize comment? */
- buffer = xmlC11NNormalizeComment(cur->content);
- if (buffer != NULL) {
- xmlOutputBufferWriteString(ctx->buf,
- (const char *) buffer);
- xmlFree(buffer);
- } else {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessNode: xmlC11NNormalizeComment() failed\n");
-#endif
- return (-1);
- }
- }
-
- if (ctx->pos == XMLC14N_BEFORE_DOCUMENT_ELEMENT) {
- xmlOutputBufferWriteString(ctx->buf, "-->\x0A");
- } else {
- xmlOutputBufferWriteString(ctx->buf, "-->");
- }
- }
- break;
- case XML_DOCUMENT_NODE:
- case XML_DOCUMENT_FRAG_NODE: /* should be processed as document? */
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE: /* should be processed as document? */
-#endif
-#ifdef LIBXML_HTML_ENABLED
- case XML_HTML_DOCUMENT_NODE: /* should be processed as document? */
-#endif
- if (cur->children != NULL) {
- ctx->pos = XMLC14N_BEFORE_DOCUMENT_ELEMENT;
- ctx->parent_is_doc = 1;
- ret = xmlC14NProcessNodeList(ctx, cur->children);
- }
- break;
-
- case XML_ATTRIBUTE_NODE:
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessNode: XML_ATTRIBUTE_NODE is illegal here\n");
- return (-1);
- case XML_NAMESPACE_DECL:
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessNode: XML_NAMESPACE_DECL is illegal here\n");
- return (-1);
- case XML_ENTITY_REF_NODE:
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessNode: XML_ENTITY_REF_NODE is illegal here\n");
- return (-1);
- case XML_ENTITY_NODE:
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessNode: XML_ENTITY_NODE is illegal here\n");
- return (-1);
-
- case XML_DOCUMENT_TYPE_NODE:
- case XML_NOTATION_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
-#ifdef LIBXML_XINCLUDE_ENABLED
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
-#endif
- /*
- * should be ignored according to "W3C Canonical XML"
- */
- break;
- default:
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessNode: unknown node type = %d\n",
- cur->type);
-#endif
- return (-1);
- }
-
- return (ret);
-}
-
-/**
- * xmlC14NProcessNodeList:
- * @ctx: the pointer to C14N context object
- * @cur: the node to start from
- *
- * Processes all nodes in the row starting from cur.
- *
- * Returns non-negative value on success or negative value on fail
- */
-static int
-xmlC14NProcessNodeList(xmlC14NCtxPtr ctx, xmlNodePtr cur)
-{
- int ret;
-
- if (ctx == NULL) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NProcessNodeList: Null context pointer.\n");
-#endif
- return (-1);
- }
-
- for (ret = 0; cur != NULL && ret >= 0; cur = cur->next) {
- ret = xmlC14NProcessNode(ctx, cur);
- }
- return (ret);
-}
-
-
-/**
- * xmlC14NFreeCtx:
- * @ctx: the pointer to C14N context object
- *
- * Cleanups the C14N context object.
- */
-
-static void
-xmlC14NFreeCtx(xmlC14NCtxPtr ctx)
-{
- if (ctx == NULL) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NFreeCtx: ctx == NULL\n");
-#endif
- return;
- }
-
- if (ctx->ns_rendered != NULL) {
- xmlC14NVisibleNsStackDestroy(ctx->ns_rendered);
- }
- xmlFree(ctx);
-}
-
-/**
- * xmlC14NNewCtx:
- * @doc: the XML document for canonization
- * @is_visible_callback:the function to use to determine is node visible
- * or not
- * @user_data: the first parameter for @is_visible_callback function
- * (in most cases, it is nodes set)
- * @inclusive_ns_prefixe the list of inclusive namespace prefixes
- * ended with a NULL or NULL if there is no
- * inclusive namespaces (only for exclusive
- * canonicalization)
- * @with_comments: include comments in the result (!=0) or not (==0)
- * @buf: the output buffer to store canonical XML; this
- * buffer MUST have encoder==NULL because C14N requires
- * UTF-8 output
- *
- * Creates new C14N context object to store C14N parameters.
- *
- * Returns pointer to newly created object (success) or NULL (fail)
- */
-static xmlC14NCtxPtr
-xmlC14NNewCtx(xmlDocPtr doc,
- xmlC14NIsVisibleCallback is_visible_callback, void* user_data,
- int exclusive, xmlChar ** inclusive_ns_prefixes,
- int with_comments, xmlOutputBufferPtr buf)
-{
- xmlC14NCtxPtr ctx;
-
- if ((doc == NULL) || (buf == NULL)) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NNewCtx: pointer to document or output buffer is NULL\n");
-#endif
- return (NULL);
- }
-
- /*
- * Validate the encoding output buffer encoding
- */
- if (buf->encoder != NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NNewCtx: output buffer encoder != NULL but C14N requires UTF8 output\n");
- return (NULL);
- }
-
- /*
- * Validate the XML document encoding value, if provided.
- */
- if (doc->charset != XML_CHAR_ENCODING_UTF8) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NNewCtx: source document not in UTF8\n");
- return (NULL);
- }
-
- /*
- * Allocate a new xmlC14NCtxPtr and fill the fields.
- */
- ctx = (xmlC14NCtxPtr) xmlMalloc(sizeof(xmlC14NCtx));
- if (ctx == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NNewCtx: malloc failed\n");
- return (NULL);
- }
- memset(ctx, 0, sizeof(xmlC14NCtx));
-
- /*
- * initialize C14N context
- */
- ctx->doc = doc;
- ctx->with_comments = with_comments;
- ctx->is_visible_callback = is_visible_callback;
- ctx->user_data = user_data;
- ctx->buf = buf;
- ctx->parent_is_doc = 1;
- ctx->pos = XMLC14N_BEFORE_DOCUMENT_ELEMENT;
- ctx->ns_rendered = xmlC14NVisibleNsStackCreate();
-
- if(ctx->ns_rendered == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NNewCtx: xmlC14NVisibleNsStackCreate failed\n");
- xmlC14NFreeCtx(ctx);
- return (NULL);
- }
-
- /*
- * Set "exclusive" flag, create a nodes set for namespaces
- * stack and remember list of incluseve prefixes
- */
- if (exclusive) {
- ctx->exclusive = 1;
- ctx->inclusive_ns_prefixes = inclusive_ns_prefixes;
- }
- return (ctx);
-}
-
-/**
- * xmlC14NExecute:
- * @doc: the XML document for canonization
- * @is_visible_callback:the function to use to determine is node visible
- * or not
- * @user_data: the first parameter for @is_visible_callback function
- * (in most cases, it is nodes set)
- * @exclusive: the exclusive flag (0 - non-exclusive canonicalization;
- * otherwise - exclusive canonicalization)
- * @inclusive_ns_prefixes: the list of inclusive namespace prefixes
- * ended with a NULL or NULL if there is no
- * inclusive namespaces (only for exclusive
- * canonicalization, ignored otherwise)
- * @with_comments: include comments in the result (!=0) or not (==0)
- * @buf: the output buffer to store canonical XML; this
- * buffer MUST have encoder==NULL because C14N requires
- * UTF-8 output
- *
- * Dumps the canonized image of given XML document into the provided buffer.
- * For details see "Canonical XML" (http://www.w3.org/TR/xml-c14n) or
- * "Exclusive XML Canonicalization" (http://www.w3.org/TR/xml-exc-c14n)
- *
- * Returns non-negative value on success or a negative value on fail
- */
-int
-xmlC14NExecute(xmlDocPtr doc, xmlC14NIsVisibleCallback is_visible_callback,
- void* user_data, int exclusive, xmlChar **inclusive_ns_prefixes,
- int with_comments, xmlOutputBufferPtr buf) {
-
- xmlC14NCtxPtr ctx;
- int ret;
-
- if ((buf == NULL) || (doc == NULL)) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NExecute: null return buffer or doc pointer\n");
-#endif
- return (-1);
- }
-
- /*
- * Validate the encoding output buffer encoding
- */
- if (buf->encoder != NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NExecute: output buffer encoder != NULL but C14N requires UTF8 output\n");
- return (-1);
- }
-
- ctx = xmlC14NNewCtx(doc, is_visible_callback, user_data,
- exclusive, inclusive_ns_prefixes,
- with_comments, buf);
- if (ctx == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NExecute: unable to create C14N context\n");
- return (-1);
- }
-
-
-
- /*
- * Root Node
- * The root node is the parent of the top-level document element. The
- * result of processing each of its child nodes that is in the node-set
- * in document order. The root node does not generate a byte order mark,
- * XML declaration, nor anything from within the document type
- * declaration.
- */
- if (doc->children != NULL) {
- ret = xmlC14NProcessNodeList(ctx, doc->children);
- if (ret < 0) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NExecute: process childrens' list failed.\n");
-#endif
- xmlC14NFreeCtx(ctx);
- return (-1);
- }
- }
-
- /*
- * Flush buffer to get number of bytes written
- */
- ret = xmlOutputBufferFlush(buf);
- if (ret < 0) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NExecute: buffer flush failed.\n");
-#endif
- xmlC14NFreeCtx(ctx);
- return (-1);
- }
-
- /*
- * Cleanup
- */
- xmlC14NFreeCtx(ctx);
- return (ret);
-}
-
-/**
- * xmlC14NDocSaveTo:
- * @doc: the XML document for canonization
- * @nodes: the nodes set to be included in the canonized image
- * or NULL if all document nodes should be included
- * @exclusive: the exclusive flag (0 - non-exclusive canonicalization;
- * otherwise - exclusive canonicalization)
- * @inclusive_ns_prefixes: the list of inclusive namespace prefixes
- * ended with a NULL or NULL if there is no
- * inclusive namespaces (only for exclusive
- * canonicalization, ignored otherwise)
- * @with_comments: include comments in the result (!=0) or not (==0)
- * @buf: the output buffer to store canonical XML; this
- * buffer MUST have encoder==NULL because C14N requires
- * UTF-8 output
- *
- * Dumps the canonized image of given XML document into the provided buffer.
- * For details see "Canonical XML" (http://www.w3.org/TR/xml-c14n) or
- * "Exclusive XML Canonicalization" (http://www.w3.org/TR/xml-exc-c14n)
- *
- * Returns non-negative value on success or a negative value on fail
- */
-int
-xmlC14NDocSaveTo(xmlDocPtr doc, xmlNodeSetPtr nodes,
- int exclusive, xmlChar ** inclusive_ns_prefixes,
- int with_comments, xmlOutputBufferPtr buf) {
- return(xmlC14NExecute(doc,
- (xmlC14NIsVisibleCallback)xmlC14NIsNodeInNodeset,
- nodes,
- exclusive,
- inclusive_ns_prefixes,
- with_comments,
- buf));
-}
-
-
-/**
- * xmlC14NDocDumpMemory:
- * @doc: the XML document for canonization
- * @nodes: the nodes set to be included in the canonized image
- * or NULL if all document nodes should be included
- * @exclusive: the exclusive flag (0 - non-exclusive canonicalization;
- * otherwise - exclusive canonicalization)
- * @inclusive_ns_prefixes: the list of inclusive namespace prefixes
- * ended with a NULL or NULL if there is no
- * inclusive namespaces (only for exclusive
- * canonicalization, ignored otherwise)
- * @with_comments: include comments in the result (!=0) or not (==0)
- * @doc_txt_ptr: the memory pointer for allocated canonical XML text;
- * the caller of this functions is responsible for calling
- * xmlFree() to free allocated memory
- *
- * Dumps the canonized image of given XML document into memory.
- * For details see "Canonical XML" (http://www.w3.org/TR/xml-c14n) or
- * "Exclusive XML Canonicalization" (http://www.w3.org/TR/xml-exc-c14n)
- *
- * Returns the number of bytes written on success or a negative value on fail
- */
-int
-xmlC14NDocDumpMemory(xmlDocPtr doc, xmlNodeSetPtr nodes,
- int exclusive, xmlChar ** inclusive_ns_prefixes,
- int with_comments, xmlChar ** doc_txt_ptr)
-{
- int ret;
- xmlOutputBufferPtr buf;
-
- if (doc_txt_ptr == NULL) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NDocDumpMemory: null return buffer pointer\n");
-#endif
- return (-1);
- }
-
- *doc_txt_ptr = NULL;
-
- /*
- * create memory buffer with UTF8 (default) encoding
- */
- buf = xmlAllocOutputBuffer(NULL);
- if (buf == NULL) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NDocDumpMemory: failed to allocate output buffer.\n");
-#endif
- return (-1);
- }
-
- /*
- * canonize document and write to buffer
- */
- ret = xmlC14NDocSaveTo(doc, nodes, exclusive, inclusive_ns_prefixes,
- with_comments, buf);
- if (ret < 0) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NDocDumpMemory: xmlC14NDocSaveTo failed.\n");
-#endif
- (void) xmlOutputBufferClose(buf);
- return (-1);
- }
-
- ret = buf->buffer->use;
- if (ret > 0) {
- *doc_txt_ptr = xmlStrndup(buf->buffer->content, ret);
- }
- (void) xmlOutputBufferClose(buf);
-
- if ((*doc_txt_ptr == NULL) && (ret > 0)) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NDocDumpMemory: failed to allocate memory for document text representation\n");
-#endif
- return (-1);
- }
- return (ret);
-}
-
-/**
- * xmlC14NDocSave:
- * @doc: the XML document for canonization
- * @nodes: the nodes set to be included in the canonized image
- * or NULL if all document nodes should be included
- * @exclusive: the exclusive flag (0 - non-exclusive canonicalization;
- * otherwise - exclusive canonicalization)
- * @inclusive_ns_prefixes: the list of inclusive namespace prefixes
- * ended with a NULL or NULL if there is no
- * inclusive namespaces (only for exclusive
- * canonicalization, ignored otherwise)
- * @with_comments: include comments in the result (!=0) or not (==0)
- * @filename: the filename to store canonical XML image
- * @compression: the compression level (zlib requred):
- * -1 - libxml default,
- * 0 - uncompressed,
- * >0 - compression level
- *
- * Dumps the canonized image of given XML document into the file.
- * For details see "Canonical XML" (http://www.w3.org/TR/xml-c14n) or
- * "Exclusive XML Canonicalization" (http://www.w3.org/TR/xml-exc-c14n)
- *
- * Returns the number of bytes written success or a negative value on fail
- */
-int
-xmlC14NDocSave(xmlDocPtr doc, xmlNodeSetPtr nodes,
- int exclusive, xmlChar ** inclusive_ns_prefixes,
- int with_comments, const char *filename, int compression)
-{
- xmlOutputBufferPtr buf;
- int ret;
-
- if (filename == NULL) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NDocSave: filename is NULL\n");
-#endif
- return (-1);
- }
-#ifdef HAVE_ZLIB_H
- if (compression < 0)
- compression = xmlGetCompressMode();
-#endif
-
- /*
- * save the content to a temp buffer, use default UTF8 encoding.
- */
- buf = xmlOutputBufferCreateFilename(filename, NULL, compression);
- if (buf == NULL) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NDocSave: unable to create buffer for file=\"%s\" with compressin=%d\n",
- filename, compression);
-#endif
- return (-1);
- }
-
- /*
- * canonize document and write to buffer
- */
- ret = xmlC14NDocSaveTo(doc, nodes, exclusive, inclusive_ns_prefixes,
- with_comments, buf);
- if (ret < 0) {
-#ifdef DEBUG_C14N
- xmlGenericError(xmlGenericErrorContext,
- "xmlC14NDocSave: xmlC14NDocSaveTo failed.\n");
-#endif
- (void) xmlOutputBufferClose(buf);
- return (-1);
- }
-
- /*
- * get the numbers of bytes written
- */
- ret = xmlOutputBufferClose(buf);
- return (ret);
-}
-
-
-
-/*
- * Macro used to grow the current buffer.
- */
-#define growBufferReentrant() { \
- buffer_size *= 2; \
- buffer = (xmlChar *) \
- xmlRealloc(buffer, buffer_size * sizeof(xmlChar)); \
- if (buffer == NULL) { \
- xmlGenericError(xmlGenericErrorContext, "realloc failed"); \
- return(NULL); \
- } \
-}
-
-/**
- * xmlC11NNormalizeString:
- * @input: the input string
- * @mode: the normalization mode (attribute, comment, PI or text)
- *
- * Converts a string to a canonical (normalized) format. The code is stolen
- * from xmlEncodeEntitiesReentrant(). Added normalization of \x09, \x0a, \x0A
- * and the @mode parameter
- *
- * Returns a normalized string (caller is responsible for calling xmlFree())
- * or NULL if an error occurs
- */
-static xmlChar *
-xmlC11NNormalizeString(const xmlChar * input,
- xmlC14NNormalizationMode mode)
-{
- const xmlChar *cur = input;
- xmlChar *buffer = NULL;
- xmlChar *out = NULL;
- int buffer_size = 0;
-
- if (input == NULL)
- return (NULL);
-
- /*
- * allocate an translation buffer.
- */
- buffer_size = 1000;
- buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
- if (buffer == NULL) {
- xmlGenericError(xmlGenericErrorContext, "malloc failed");
- return (NULL);
- }
- out = buffer;
-
- while (*cur != '\0') {
- if ((out - buffer) > (buffer_size - 10)) {
- int indx = out - buffer;
-
- growBufferReentrant();
- out = &buffer[indx];
- }
-
- if ((*cur == '<') && ((mode == XMLC14N_NORMALIZE_ATTR) ||
- (mode == XMLC14N_NORMALIZE_TEXT))) {
- *out++ = '&';
- *out++ = 'l';
- *out++ = 't';
- *out++ = ';';
- } else if ((*cur == '>') && (mode == XMLC14N_NORMALIZE_TEXT)) {
- *out++ = '&';
- *out++ = 'g';
- *out++ = 't';
- *out++ = ';';
- } else if ((*cur == '&') && ((mode == XMLC14N_NORMALIZE_ATTR) ||
- (mode == XMLC14N_NORMALIZE_TEXT))) {
- *out++ = '&';
- *out++ = 'a';
- *out++ = 'm';
- *out++ = 'p';
- *out++ = ';';
- } else if ((*cur == '"') && (mode == XMLC14N_NORMALIZE_ATTR)) {
- *out++ = '&';
- *out++ = 'q';
- *out++ = 'u';
- *out++ = 'o';
- *out++ = 't';
- *out++ = ';';
- } else if ((*cur == '\x09') && (mode == XMLC14N_NORMALIZE_ATTR)) {
- *out++ = '&';
- *out++ = '#';
- *out++ = 'x';
- *out++ = '9';
- *out++ = ';';
- } else if ((*cur == '\x0A') && (mode == XMLC14N_NORMALIZE_ATTR)) {
- *out++ = '&';
- *out++ = '#';
- *out++ = 'x';
- *out++ = 'A';
- *out++ = ';';
- } else if ((*cur == '\x0D') && ((mode == XMLC14N_NORMALIZE_ATTR) ||
- (mode == XMLC14N_NORMALIZE_TEXT) ||
- (mode == XMLC14N_NORMALIZE_COMMENT) ||
- (mode == XMLC14N_NORMALIZE_PI))) {
- *out++ = '&';
- *out++ = '#';
- *out++ = 'x';
- *out++ = 'D';
- *out++ = ';';
- } else {
- /*
- * Works because on UTF-8, all extended sequences cannot
- * result in bytes in the ASCII range.
- */
- *out++ = *cur;
- }
- cur++;
- }
- *out++ = 0;
- return (buffer);
-}
-#endif /* LIBXML_C14N_ENABLED */
diff --git a/bundle/libxml/catalog.c b/bundle/libxml/catalog.c
deleted file mode 100644
index e0159e2b9f..0000000000
--- a/bundle/libxml/catalog.c
+++ /dev/null
@@ -1,3502 +0,0 @@
-/**
- * catalog.c: set of generic Catalog related routines
- *
- * Reference: SGML Open Technical Resolution TR9401:1997.
- * http://www.jclark.com/sp/catalog.htm
- *
- * XML Catalogs Working Draft 06 August 2001
- * http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
- *
- * See Copyright for the status of this software.
- *
- * Daniel.Veillard@imag.fr
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#ifdef LIBXML_CATALOG_ENABLED
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <string.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/hash.h>
-#include <libxml/uri.h>
-#include <libxml/parserInternals.h>
-#include <libxml/catalog.h>
-#include <libxml/xmlerror.h>
-#include <libxml/threads.h>
-#include <libxml/globals.h>
-
-#define MAX_DELEGATE 50
-
-/**
- * TODO:
- *
- * macro to flag unimplemented blocks
- */
-#define TODO \
- xmlGenericError(xmlGenericErrorContext, \
- "Unimplemented block at %s:%d\n", \
- __FILE__, __LINE__);
-
-#define XML_URN_PUBID "urn:publicid:"
-#define XML_CATAL_BREAK ((xmlChar *) -1)
-#ifndef XML_XML_DEFAULT_CATALOG
-#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
-#endif
-#ifndef XML_SGML_DEFAULT_CATALOG
-#define XML_SGML_DEFAULT_CATALOG "file:///etc/sgml/catalog"
-#endif
-
-static int xmlExpandCatalog(xmlCatalogPtr catal, const char *filename);
-
-/************************************************************************
- * *
- * Types, all private *
- * *
- ************************************************************************/
-
-typedef enum {
- XML_CATA_REMOVED = -1,
- XML_CATA_NONE = 0,
- XML_CATA_CATALOG,
- XML_CATA_BROKEN_CATALOG,
- XML_CATA_NEXT_CATALOG,
- XML_CATA_PUBLIC,
- XML_CATA_SYSTEM,
- XML_CATA_REWRITE_SYSTEM,
- XML_CATA_DELEGATE_PUBLIC,
- XML_CATA_DELEGATE_SYSTEM,
- XML_CATA_URI,
- XML_CATA_REWRITE_URI,
- XML_CATA_DELEGATE_URI,
- SGML_CATA_SYSTEM,
- SGML_CATA_PUBLIC,
- SGML_CATA_ENTITY,
- SGML_CATA_PENTITY,
- SGML_CATA_DOCTYPE,
- SGML_CATA_LINKTYPE,
- SGML_CATA_NOTATION,
- SGML_CATA_DELEGATE,
- SGML_CATA_BASE,
- SGML_CATA_CATALOG,
- SGML_CATA_DOCUMENT,
- SGML_CATA_SGMLDECL
-} xmlCatalogEntryType;
-
-typedef struct _xmlCatalogEntry xmlCatalogEntry;
-typedef xmlCatalogEntry *xmlCatalogEntryPtr;
-struct _xmlCatalogEntry {
- struct _xmlCatalogEntry *next;
- struct _xmlCatalogEntry *parent;
- struct _xmlCatalogEntry *children;
- xmlCatalogEntryType type;
- xmlChar *name;
- xmlChar *value;
- xmlChar *URL; /* The expanded URL using the base */
- xmlCatalogPrefer prefer;
- int dealloc;
-};
-
-typedef enum {
- XML_XML_CATALOG_TYPE = 1,
- XML_SGML_CATALOG_TYPE
-} xmlCatalogType;
-
-#define XML_MAX_SGML_CATA_DEPTH 10
-struct _xmlCatalog {
- xmlCatalogType type; /* either XML or SGML */
-
- /*
- * SGML Catalogs are stored as a simple hash table of catalog entries
- * Catalog stack to check against overflows when building the
- * SGML catalog
- */
- char *catalTab[XML_MAX_SGML_CATA_DEPTH]; /* stack of catals */
- int catalNr; /* Number of current catal streams */
- int catalMax; /* Max number of catal streams */
- xmlHashTablePtr sgml;
-
- /*
- * XML Catalogs are stored as a tree of Catalog entries
- */
- xmlCatalogPrefer prefer;
- xmlCatalogEntryPtr xml;
-};
-
-/************************************************************************
- * *
- * Global variables *
- * *
- ************************************************************************/
-
-/*
- * Those are preferences
- */
-static int xmlDebugCatalogs = 0; /* used for debugging */
-static xmlCatalogAllow xmlCatalogDefaultAllow = XML_CATA_ALLOW_ALL;
-static xmlCatalogPrefer xmlCatalogDefaultPrefer = XML_CATA_PREFER_PUBLIC;
-
-/*
- * Hash table containing all the trees of XML catalogs parsed by
- * the application.
- */
-static xmlHashTablePtr xmlCatalogXMLFiles = NULL;
-
-/*
- * The default catalog in use by the application
- */
-static xmlCatalogPtr xmlDefaultCatalog = NULL;
-
-/*
- * A mutex for modifying the shared global catalog(s)
- * xmlDefaultCatalog tree.
- * It also protects xmlCatalogXMLFiles
- * The core of this readers/writer scheme is in xmlFetchXMLCatalogFile()
- */
-static xmlRMutexPtr xmlCatalogMutex = NULL;
-
-/*
- * Whether the catalog support was initialized.
- */
-static int xmlCatalogInitialized = 0;
-
-
-/************************************************************************
- * *
- * Allocation and Freeing *
- * *
- ************************************************************************/
-
-/**
- * xmlNewCatalogEntry:
- * @type: type of entry
- * @name: name of the entry
- * @value: value of the entry
- * @prefer: the PUBLIC vs. SYSTEM current preference value
- *
- * create a new Catalog entry, this type is shared both by XML and
- * SGML catalogs, but the acceptable types values differs.
- *
- * Returns the xmlCatalogEntryPtr or NULL in case of error
- */
-static xmlCatalogEntryPtr
-xmlNewCatalogEntry(xmlCatalogEntryType type, const xmlChar *name,
- const xmlChar *value, const xmlChar *URL, xmlCatalogPrefer prefer) {
- xmlCatalogEntryPtr ret;
-
- ret = (xmlCatalogEntryPtr) xmlMalloc(sizeof(xmlCatalogEntry));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %d byte failed\n", sizeof(xmlCatalogEntry));
- return(NULL);
- }
- ret->next = NULL;
- ret->parent = NULL;
- ret->children = NULL;
- ret->type = type;
- if (name != NULL)
- ret->name = xmlStrdup(name);
- else
- ret->name = NULL;
- if (value != NULL)
- ret->value = xmlStrdup(value);
- else
- ret->value = NULL;
- if (URL == NULL)
- URL = value;
- if (URL != NULL)
- ret->URL = xmlStrdup(URL);
- else
- ret->URL = NULL;
- ret->prefer = prefer;
- ret->dealloc = 0;
- return(ret);
-}
-
-static void
-xmlFreeCatalogEntryList(xmlCatalogEntryPtr ret);
-
-/**
- * xmlFreeCatalogEntry:
- * @ret: a Catalog entry
- *
- * Free the memory allocated to a Catalog entry
- */
-static void
-xmlFreeCatalogEntry(xmlCatalogEntryPtr ret) {
- if (ret == NULL)
- return;
- /*
- * Entries stored in the file hash must be deallocated
- * only by the file hash cleaner !
- */
- if (ret->dealloc == 1)
- return;
-
- if (xmlDebugCatalogs) {
- if (ret->name != NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Free catalog entry %s\n", ret->name);
- else if (ret->value != NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Free catalog entry %s\n", ret->value);
- else
- xmlGenericError(xmlGenericErrorContext,
- "Free catalog entry\n");
- }
-
- if (ret->name != NULL)
- xmlFree(ret->name);
- if (ret->value != NULL)
- xmlFree(ret->value);
- if (ret->URL != NULL)
- xmlFree(ret->URL);
- xmlFree(ret);
-}
-
-/**
- * xmlFreeCatalogEntryList:
- * @ret: a Catalog entry list
- *
- * Free the memory allocated to a full chained list of Catalog entries
- */
-static void
-xmlFreeCatalogEntryList(xmlCatalogEntryPtr ret) {
- xmlCatalogEntryPtr next;
-
- while (ret != NULL) {
- next = ret->next;
- xmlFreeCatalogEntry(ret);
- ret = next;
- }
-}
-
-/**
- * xmlFreeCatalogHashEntryList:
- * @ret: a Catalog entry list
- *
- * Free the memory allocated to list of Catalog entries from the
- * catalog file hash.
- */
-static void
-xmlFreeCatalogHashEntryList(xmlCatalogEntryPtr catal) {
- xmlCatalogEntryPtr children, next;
-
- if (catal == NULL)
- return;
-
- children = catal->children;
- while (children != NULL) {
- next = children->next;
- children->dealloc = 0;
- children->children = NULL;
- xmlFreeCatalogEntry(children);
- children = next;
- }
- catal->dealloc = 0;
- xmlFreeCatalogEntry(catal);
-}
-
-/**
- * xmlCreateNewCatalog:
- * @type: type of catalog
- * @prefer: the PUBLIC vs. SYSTEM current preference value
- *
- * create a new Catalog, this type is shared both by XML and
- * SGML catalogs, but the acceptable types values differs.
- *
- * Returns the xmlCatalogPtr or NULL in case of error
- */
-static xmlCatalogPtr
-xmlCreateNewCatalog(xmlCatalogType type, xmlCatalogPrefer prefer) {
- xmlCatalogPtr ret;
-
- ret = (xmlCatalogPtr) xmlMalloc(sizeof(xmlCatalog));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %d byte failed\n", sizeof(xmlCatalog));
- return(NULL);
- }
- memset(ret, 0, sizeof(xmlCatalog));
- ret->type = type;
- ret->catalNr = 0;
- ret->catalMax = XML_MAX_SGML_CATA_DEPTH;
- ret->prefer = prefer;
- if (ret->type == XML_SGML_CATALOG_TYPE)
- ret->sgml = xmlHashCreate(10);
- return(ret);
-}
-
-/**
- * xmlFreeCatalog:
- * @catal: a Catalog entry
- *
- * Free the memory allocated to a Catalog
- */
-void
-xmlFreeCatalog(xmlCatalogPtr catal) {
- if (catal == NULL)
- return;
- if (catal->xml != NULL)
- xmlFreeCatalogEntryList(catal->xml);
- if (catal->sgml != NULL)
- xmlHashFree(catal->sgml,
- (xmlHashDeallocator) xmlFreeCatalogEntry);
- xmlFree(catal);
-}
-
-/************************************************************************
- * *
- * Serializing Catalogs *
- * *
- ************************************************************************/
-
-/**
- * xmlCatalogDumpEntry:
- * @entry: the
- * @out: the file.
- *
- * Serialize an SGML Catalog entry
- */
-static void
-xmlCatalogDumpEntry(xmlCatalogEntryPtr entry, FILE *out) {
- if ((entry == NULL) || (out == NULL))
- return;
- switch (entry->type) {
- case SGML_CATA_ENTITY:
- fprintf(out, "ENTITY "); break;
- case SGML_CATA_PENTITY:
- fprintf(out, "ENTITY %%"); break;
- case SGML_CATA_DOCTYPE:
- fprintf(out, "DOCTYPE "); break;
- case SGML_CATA_LINKTYPE:
- fprintf(out, "LINKTYPE "); break;
- case SGML_CATA_NOTATION:
- fprintf(out, "NOTATION "); break;
- case SGML_CATA_PUBLIC:
- fprintf(out, "PUBLIC "); break;
- case SGML_CATA_SYSTEM:
- fprintf(out, "SYSTEM "); break;
- case SGML_CATA_DELEGATE:
- fprintf(out, "DELEGATE "); break;
- case SGML_CATA_BASE:
- fprintf(out, "BASE "); break;
- case SGML_CATA_CATALOG:
- fprintf(out, "CATALOG "); break;
- case SGML_CATA_DOCUMENT:
- fprintf(out, "DOCUMENT "); break;
- case SGML_CATA_SGMLDECL:
- fprintf(out, "SGMLDECL "); break;
- default:
- return;
- }
- switch (entry->type) {
- case SGML_CATA_ENTITY:
- case SGML_CATA_PENTITY:
- case SGML_CATA_DOCTYPE:
- case SGML_CATA_LINKTYPE:
- case SGML_CATA_NOTATION:
- fprintf(out, "%s", entry->name); break;
- case SGML_CATA_PUBLIC:
- case SGML_CATA_SYSTEM:
- case SGML_CATA_SGMLDECL:
- case SGML_CATA_DOCUMENT:
- case SGML_CATA_CATALOG:
- case SGML_CATA_BASE:
- case SGML_CATA_DELEGATE:
- fprintf(out, "\"%s\"", entry->name); break;
- default:
- break;
- }
- switch (entry->type) {
- case SGML_CATA_ENTITY:
- case SGML_CATA_PENTITY:
- case SGML_CATA_DOCTYPE:
- case SGML_CATA_LINKTYPE:
- case SGML_CATA_NOTATION:
- case SGML_CATA_PUBLIC:
- case SGML_CATA_SYSTEM:
- case SGML_CATA_DELEGATE:
- fprintf(out, " \"%s\"", entry->value); break;
- default:
- break;
- }
- fprintf(out, "\n");
-}
-
-static int
-xmlDumpXMLCatalog(FILE *out, xmlCatalogEntryPtr catal) {
- int ret;
- xmlDocPtr doc;
- xmlNsPtr ns;
- xmlDtdPtr dtd;
- xmlNodePtr node, catalog;
- xmlOutputBufferPtr buf;
- xmlCatalogEntryPtr cur;
-
- /*
- * Rebuild a catalog
- */
- doc = xmlNewDoc(NULL);
- if (doc == NULL)
- return(-1);
- dtd = xmlNewDtd(doc, BAD_CAST "catalog",
- BAD_CAST "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN",
-BAD_CAST "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd");
-
- xmlAddChild((xmlNodePtr) doc, (xmlNodePtr) dtd);
-
- ns = xmlNewNs(NULL, XML_CATALOGS_NAMESPACE, NULL);
- if (ns == NULL) {
- xmlFreeDoc(doc);
- return(-1);
- }
- catalog = xmlNewDocNode(doc, ns, BAD_CAST "catalog", NULL);
- if (catalog == NULL) {
- xmlFreeNs(ns);
- xmlFreeDoc(doc);
- return(-1);
- }
- catalog->nsDef = ns;
- xmlAddChild((xmlNodePtr) doc, catalog);
-
- /*
- * add all the catalog entries
- */
- cur = catal;
- while (cur != NULL) {
- switch (cur->type) {
- case XML_CATA_REMOVED:
- break;
- case XML_CATA_BROKEN_CATALOG:
- case XML_CATA_CATALOG:
- if (cur == catal) {
- cur = cur->children;
- continue;
- }
- break;
- case XML_CATA_NEXT_CATALOG:
- node = xmlNewDocNode(doc, ns, BAD_CAST "nextCatalog", NULL);
- xmlSetProp(node, BAD_CAST "catalog", cur->value);
- xmlAddChild(catalog, node);
- break;
- case XML_CATA_NONE:
- break;
- case XML_CATA_PUBLIC:
- node = xmlNewDocNode(doc, ns, BAD_CAST "public", NULL);
- xmlSetProp(node, BAD_CAST "publicId", cur->name);
- xmlSetProp(node, BAD_CAST "uri", cur->value);
- xmlAddChild(catalog, node);
- break;
- case XML_CATA_SYSTEM:
- node = xmlNewDocNode(doc, ns, BAD_CAST "system", NULL);
- xmlSetProp(node, BAD_CAST "systemId", cur->name);
- xmlSetProp(node, BAD_CAST "uri", cur->value);
- xmlAddChild(catalog, node);
- break;
- case XML_CATA_REWRITE_SYSTEM:
- node = xmlNewDocNode(doc, ns, BAD_CAST "rewriteSystem", NULL);
- xmlSetProp(node, BAD_CAST "systemIdStartString", cur->name);
- xmlSetProp(node, BAD_CAST "rewritePrefix", cur->value);
- xmlAddChild(catalog, node);
- break;
- case XML_CATA_DELEGATE_PUBLIC:
- node = xmlNewDocNode(doc, ns, BAD_CAST "delegatePublic", NULL);
- xmlSetProp(node, BAD_CAST "publicIdStartString", cur->name);
- xmlSetProp(node, BAD_CAST "catalog", cur->value);
- xmlAddChild(catalog, node);
- break;
- case XML_CATA_DELEGATE_SYSTEM:
- node = xmlNewDocNode(doc, ns, BAD_CAST "delegateSystem", NULL);
- xmlSetProp(node, BAD_CAST "systemIdStartString", cur->name);
- xmlSetProp(node, BAD_CAST "catalog", cur->value);
- xmlAddChild(catalog, node);
- break;
- case XML_CATA_URI:
- node = xmlNewDocNode(doc, ns, BAD_CAST "uri", NULL);
- xmlSetProp(node, BAD_CAST "name", cur->name);
- xmlSetProp(node, BAD_CAST "uri", cur->value);
- xmlAddChild(catalog, node);
- break;
- case XML_CATA_REWRITE_URI:
- node = xmlNewDocNode(doc, ns, BAD_CAST "rewriteURI", NULL);
- xmlSetProp(node, BAD_CAST "uriStartString", cur->name);
- xmlSetProp(node, BAD_CAST "rewritePrefix", cur->value);
- xmlAddChild(catalog, node);
- break;
- case XML_CATA_DELEGATE_URI:
- node = xmlNewDocNode(doc, ns, BAD_CAST "delegateURI", NULL);
- xmlSetProp(node, BAD_CAST "uriStartString", cur->name);
- xmlSetProp(node, BAD_CAST "catalog", cur->value);
- xmlAddChild(catalog, node);
- break;
- case SGML_CATA_SYSTEM:
- case SGML_CATA_PUBLIC:
- case SGML_CATA_ENTITY:
- case SGML_CATA_PENTITY:
- case SGML_CATA_DOCTYPE:
- case SGML_CATA_LINKTYPE:
- case SGML_CATA_NOTATION:
- case SGML_CATA_DELEGATE:
- case SGML_CATA_BASE:
- case SGML_CATA_CATALOG:
- case SGML_CATA_DOCUMENT:
- case SGML_CATA_SGMLDECL:
- break;
- }
- cur = cur->next;
- }
-
- /*
- * reserialize it
- */
- buf = xmlOutputBufferCreateFile(out, NULL);
- if (buf == NULL) {
- xmlFreeDoc(doc);
- return(-1);
- }
- ret = xmlSaveFormatFileTo(buf, doc, NULL, 1);
-
- /*
- * Free it
- */
- xmlFreeDoc(doc);
-
- return(ret);
-}
-
-/************************************************************************
- * *
- * Converting SGML Catalogs to XML *
- * *
- ************************************************************************/
-
-/**
- * xmlCatalogConvertEntry:
- * @entry: the entry
- * @catal: pointer to the catalog being converted
- *
- * Convert one entry from the catalog
- */
-static void
-xmlCatalogConvertEntry(xmlCatalogEntryPtr entry, xmlCatalogPtr catal) {
- if ((entry == NULL) || (catal == NULL) || (catal->sgml == NULL) ||
- (catal->xml == NULL))
- return;
- switch (entry->type) {
- case SGML_CATA_ENTITY:
- entry->type = XML_CATA_PUBLIC;
- break;
- case SGML_CATA_PENTITY:
- entry->type = XML_CATA_PUBLIC;
- break;
- case SGML_CATA_DOCTYPE:
- entry->type = XML_CATA_PUBLIC;
- break;
- case SGML_CATA_LINKTYPE:
- entry->type = XML_CATA_PUBLIC;
- break;
- case SGML_CATA_NOTATION:
- entry->type = XML_CATA_PUBLIC;
- break;
- case SGML_CATA_PUBLIC:
- entry->type = XML_CATA_PUBLIC;
- break;
- case SGML_CATA_SYSTEM:
- entry->type = XML_CATA_SYSTEM;
- break;
- case SGML_CATA_DELEGATE:
- entry->type = XML_CATA_DELEGATE_PUBLIC;
- break;
- case SGML_CATA_CATALOG:
- entry->type = XML_CATA_CATALOG;
- break;
- default:
- xmlHashRemoveEntry(catal->sgml, entry->name,
- (xmlHashDeallocator) xmlFreeCatalogEntry);
- return;
- }
- /*
- * Conversion successful, remove from the SGML catalog
- * and add it to the default XML one
- */
- xmlHashRemoveEntry(catal->sgml, entry->name, NULL);
- entry->parent = catal->xml;
- entry->next = NULL;
- if (catal->xml->children == NULL)
- catal->xml->children = entry;
- else {
- xmlCatalogEntryPtr prev;
-
- prev = catal->xml->children;
- while (prev->next != NULL)
- prev = prev->next;
- prev->next = entry;
- }
-}
-
-/**
- * xmlConvertSGMLCatalog:
- * @catal: the catalog
- *
- * Convert all the SGML catalog entries as XML ones
- *
- * Returns the number of entries converted if successful, -1 otherwise
- */
-int
-xmlConvertSGMLCatalog(xmlCatalogPtr catal) {
-
- if ((catal == NULL) || (catal->type != XML_SGML_CATALOG_TYPE))
- return(-1);
-
- if (xmlDebugCatalogs) {
- xmlGenericError(xmlGenericErrorContext,
- "Converting SGML catalog to XML\n");
- }
- xmlHashScan(catal->sgml,
- (xmlHashScanner) xmlCatalogConvertEntry,
- &catal);
- return(0);
-}
-
-/************************************************************************
- * *
- * Helper function *
- * *
- ************************************************************************/
-
-/**
- * xmlCatalogUnWrapURN:
- * @urn: an "urn:publicid:" to unwrap
- *
- * Expand the URN into the equivalent Public Identifier
- *
- * Returns the new identifier or NULL, the string must be deallocated
- * by the caller.
- */
-static xmlChar *
-xmlCatalogUnWrapURN(const xmlChar *urn) {
- xmlChar result[2000];
- unsigned int i = 0;
-
- if (xmlStrncmp(urn, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1))
- return(NULL);
- urn += sizeof(XML_URN_PUBID) - 1;
-
- while (*urn != 0) {
- if (i > sizeof(result) - 3)
- break;
- if (*urn == '+') {
- result[i++] = ' ';
- urn++;
- } else if (*urn == ':') {
- result[i++] = '/';
- result[i++] = '/';
- urn++;
- } else if (*urn == ';') {
- result[i++] = ':';
- result[i++] = ':';
- urn++;
- } else if (*urn == '%') {
- if ((urn[1] == '2') && (urn[1] == 'B'))
- result[i++] = '+';
- else if ((urn[1] == '3') && (urn[1] == 'A'))
- result[i++] = ':';
- else if ((urn[1] == '2') && (urn[1] == 'F'))
- result[i++] = '/';
- else if ((urn[1] == '3') && (urn[1] == 'B'))
- result[i++] = ';';
- else if ((urn[1] == '2') && (urn[1] == '7'))
- result[i++] = '\'';
- else if ((urn[1] == '3') && (urn[1] == 'F'))
- result[i++] = '?';
- else if ((urn[1] == '2') && (urn[1] == '3'))
- result[i++] = '#';
- else if ((urn[1] == '2') && (urn[1] == '5'))
- result[i++] = '%';
- else {
- result[i++] = *urn;
- urn++;
- continue;
- }
- urn += 3;
- } else {
- result[i++] = *urn;
- urn++;
- }
- }
- result[i] = 0;
-
- return(xmlStrdup(result));
-}
-
-/**
- * xmlParseCatalogFile:
- * @filename: the filename
- *
- * parse an XML file and build a tree. It's like xmlParseFile()
- * except it bypass all catalog lookups.
- *
- * Returns the resulting document tree or NULL in case of error
- */
-
-xmlDocPtr
-xmlParseCatalogFile(const char *filename) {
- xmlDocPtr ret;
- xmlParserCtxtPtr ctxt;
- char *directory = NULL;
- xmlParserInputPtr inputStream;
- xmlParserInputBufferPtr buf;
-
- ctxt = xmlNewParserCtxt();
- if (ctxt == NULL) {
- if (xmlDefaultSAXHandler.error != NULL) {
- xmlDefaultSAXHandler.error(NULL, "out of memory\n");
- }
- return(NULL);
- }
-
- buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
- if (buf == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
-
- inputStream = xmlNewInputStream(ctxt);
- if (inputStream == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
-
- inputStream->filename = xmlMemStrdup(filename);
- inputStream->buf = buf;
- inputStream->base = inputStream->buf->buffer->content;
- inputStream->cur = inputStream->buf->buffer->content;
- inputStream->end =
- &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
-
- inputPush(ctxt, inputStream);
- if ((ctxt->directory == NULL) && (directory == NULL))
- directory = xmlParserGetDirectory(filename);
- if ((ctxt->directory == NULL) && (directory != NULL))
- ctxt->directory = directory;
- ctxt->valid = 0;
- ctxt->validate = 0;
- ctxt->loadsubset = 0;
- ctxt->pedantic = 0;
-
- xmlParseDocument(ctxt);
-
- if (ctxt->wellFormed)
- ret = ctxt->myDoc;
- else {
- ret = NULL;
- xmlFreeDoc(ctxt->myDoc);
- ctxt->myDoc = NULL;
- }
- xmlFreeParserCtxt(ctxt);
-
- return(ret);
-}
-
-/**
- * xmlLoadFileContent:
- * @filename: a file path
- *
- * Load a file content into memory.
- *
- * Returns a pointer to the 0 terminated string or NULL in case of error
- */
-static xmlChar *
-xmlLoadFileContent(const char *filename)
-{
-#ifdef HAVE_STAT
- int fd;
-#else
- FILE *fd;
-#endif
- int len;
- long size;
-
-#ifdef HAVE_STAT
- struct stat info;
-#endif
- xmlChar *content;
-
- if (filename == NULL)
- return (NULL);
-
-#ifdef HAVE_STAT
- if (stat(filename, &info) < 0)
- return (NULL);
-#endif
-
-#ifdef HAVE_STAT
- if ((fd = open(filename, O_RDONLY)) < 0)
-#else
- if ((fd = fopen(filename, "rb")) == NULL)
-#endif
- {
- return (NULL);
- }
-#ifdef HAVE_STAT
- size = info.st_size;
-#else
- if (fseek(fd, 0, SEEK_END) || (size = ftell(fd)) == EOF || fseek(fd, 0, SEEK_SET)) { /* File operations denied? ok, just close and return failure */
- fclose(fd);
- return (NULL);
- }
-#endif
- content = xmlMalloc(size + 10);
- if (content == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %d byte failed\n", size + 10);
- return (NULL);
- }
-#ifdef HAVE_STAT
- len = read(fd, content, size);
-#else
- len = fread(content, 1, size, fd);
-#endif
- if (len < 0) {
- xmlFree(content);
- return (NULL);
- }
-#ifdef HAVE_STAT
- close(fd);
-#else
- fclose(fd);
-#endif
- content[len] = 0;
-
- return(content);
-}
-
-/************************************************************************
- * *
- * The XML Catalog parser *
- * *
- ************************************************************************/
-
-static xmlCatalogEntryPtr
-xmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename);
-static void
-xmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer,
- xmlCatalogEntryPtr parent);
-static xmlChar *
-xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
- const xmlChar *sysID);
-static xmlChar *
-xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI);
-
-
-/**
- * xmlGetXMLCatalogEntryType:
- * @name: the name
- *
- * lookup the internal type associated to an XML catalog entry name
- *
- * Returns the type associate with that name
- */
-static xmlCatalogEntryType
-xmlGetXMLCatalogEntryType(const xmlChar *name) {
- xmlCatalogEntryType type = XML_CATA_NONE;
- if (xmlStrEqual(name, (const xmlChar *) "system"))
- type = XML_CATA_SYSTEM;
- else if (xmlStrEqual(name, (const xmlChar *) "public"))
- type = XML_CATA_PUBLIC;
- else if (xmlStrEqual(name, (const xmlChar *) "rewriteSystem"))
- type = XML_CATA_REWRITE_SYSTEM;
- else if (xmlStrEqual(name, (const xmlChar *) "delegatePublic"))
- type = XML_CATA_DELEGATE_PUBLIC;
- else if (xmlStrEqual(name, (const xmlChar *) "delegateSystem"))
- type = XML_CATA_DELEGATE_SYSTEM;
- else if (xmlStrEqual(name, (const xmlChar *) "uri"))
- type = XML_CATA_URI;
- else if (xmlStrEqual(name, (const xmlChar *) "rewriteURI"))
- type = XML_CATA_REWRITE_URI;
- else if (xmlStrEqual(name, (const xmlChar *) "delegateURI"))
- type = XML_CATA_DELEGATE_URI;
- else if (xmlStrEqual(name, (const xmlChar *) "nextCatalog"))
- type = XML_CATA_NEXT_CATALOG;
- else if (xmlStrEqual(name, (const xmlChar *) "catalog"))
- type = XML_CATA_CATALOG;
- return(type);
-}
-
-/**
- * xmlParseXMLCatalogOneNode:
- * @cur: the XML node
- * @type: the type of Catalog entry
- * @name: the name of the node
- * @attrName: the attribute holding the value
- * @uriAttrName: the attribute holding the URI-Reference
- * @prefer: the PUBLIC vs. SYSTEM current preference value
- *
- * Finishes the examination of an XML tree node of a catalog and build
- * a Catalog entry from it.
- *
- * Returns the new Catalog entry node or NULL in case of error.
- */
-static xmlCatalogEntryPtr
-xmlParseXMLCatalogOneNode(xmlNodePtr cur, xmlCatalogEntryType type,
- const xmlChar *name, const xmlChar *attrName,
- const xmlChar *uriAttrName, xmlCatalogPrefer prefer) {
- int ok = 1;
- xmlChar *uriValue;
- xmlChar *nameValue = NULL;
- xmlChar *base = NULL;
- xmlChar *URL = NULL;
- xmlCatalogEntryPtr ret = NULL;
-
- if (attrName != NULL) {
- nameValue = xmlGetProp(cur, attrName);
- if (nameValue == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "%s entry lacks '%s'\n", name, attrName);
- ok = 0;
- }
- }
- uriValue = xmlGetProp(cur, uriAttrName);
- if (uriValue == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "%s entry lacks '%s'\n", name, uriAttrName);
- ok = 0;
- }
- if (!ok) {
- if (nameValue != NULL)
- xmlFree(nameValue);
- if (uriValue != NULL)
- xmlFree(uriValue);
- return(NULL);
- }
-
- base = xmlNodeGetBase(cur->doc, cur);
- URL = xmlBuildURI(uriValue, base);
- if (URL != NULL) {
- if (xmlDebugCatalogs > 1) {
- if (nameValue != NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Found %s: '%s' '%s'\n", name, nameValue, URL);
- else
- xmlGenericError(xmlGenericErrorContext,
- "Found %s: '%s'\n", name, URL);
- }
- ret = xmlNewCatalogEntry(type, nameValue, uriValue, URL, prefer);
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "%s entry '%s' broken ?: %s\n", name, uriAttrName, uriValue);
- }
- if (nameValue != NULL)
- xmlFree(nameValue);
- if (uriValue != NULL)
- xmlFree(uriValue);
- if (base != NULL)
- xmlFree(base);
- if (URL != NULL)
- xmlFree(URL);
- return(ret);
-}
-
-/**
- * xmlParseXMLCatalogNode:
- * @cur: the XML node
- * @prefer: the PUBLIC vs. SYSTEM current preference value
- * @parent: the parent Catalog entry
- *
- * Examines an XML tree node of a catalog and build
- * a Catalog entry from it adding it to its parent. The examination can
- * be recursive.
- */
-static void
-xmlParseXMLCatalogNode(xmlNodePtr cur, xmlCatalogPrefer prefer,
- xmlCatalogEntryPtr parent)
-{
- xmlChar *uri = NULL;
- xmlChar *URL = NULL;
- xmlChar *base = NULL;
- xmlCatalogEntryPtr entry = NULL;
-
- if (cur == NULL)
- return;
- if (xmlStrEqual(cur->name, BAD_CAST "group")) {
- xmlChar *prop;
-
- prop = xmlGetProp(cur, BAD_CAST "prefer");
- if (prop != NULL) {
- if (xmlStrEqual(prop, BAD_CAST "system")) {
- prefer = XML_CATA_PREFER_SYSTEM;
- } else if (xmlStrEqual(prop, BAD_CAST "public")) {
- prefer = XML_CATA_PREFER_PUBLIC;
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "Invalid value for prefer: '%s'\n", prop);
- }
- xmlFree(prop);
- }
- /*
- * Recurse to propagate prefer to the subtree
- * (xml:base handling is automated)
- */
- xmlParseXMLCatalogNodeList(cur->children, prefer, parent);
- } else if (xmlStrEqual(cur->name, BAD_CAST "public")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_PUBLIC,
- BAD_CAST "public", BAD_CAST "publicId", BAD_CAST "uri", prefer);
- } else if (xmlStrEqual(cur->name, BAD_CAST "system")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_SYSTEM,
- BAD_CAST "system", BAD_CAST "systemId", BAD_CAST "uri", prefer);
- } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteSystem")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_SYSTEM,
- BAD_CAST "rewriteSystem", BAD_CAST "systemIdStartString",
- BAD_CAST "rewritePrefix", prefer);
- } else if (xmlStrEqual(cur->name, BAD_CAST "delegatePublic")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_PUBLIC,
- BAD_CAST "delegatePublic", BAD_CAST "publicIdStartString",
- BAD_CAST "catalog", prefer);
- } else if (xmlStrEqual(cur->name, BAD_CAST "delegateSystem")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_SYSTEM,
- BAD_CAST "delegateSystem", BAD_CAST "systemIdStartString",
- BAD_CAST "catalog", prefer);
- } else if (xmlStrEqual(cur->name, BAD_CAST "uri")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_URI,
- BAD_CAST "uri", BAD_CAST "name",
- BAD_CAST "uri", prefer);
- } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteURI")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_URI,
- BAD_CAST "rewriteURI", BAD_CAST "uriStartString",
- BAD_CAST "rewritePrefix", prefer);
- } else if (xmlStrEqual(cur->name, BAD_CAST "delegateURI")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_URI,
- BAD_CAST "delegateURI", BAD_CAST "uriStartString",
- BAD_CAST "catalog", prefer);
- } else if (xmlStrEqual(cur->name, BAD_CAST "nextCatalog")) {
- entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_NEXT_CATALOG,
- BAD_CAST "nextCatalog", NULL,
- BAD_CAST "catalog", prefer);
- }
- if ((entry != NULL) && (parent != NULL)) {
- entry->parent = parent;
- if (parent->children == NULL)
- parent->children = entry;
- else {
- xmlCatalogEntryPtr prev;
-
- prev = parent->children;
- while (prev->next != NULL)
- prev = prev->next;
- prev->next = entry;
- }
- }
- if (base != NULL)
- xmlFree(base);
- if (uri != NULL)
- xmlFree(uri);
- if (URL != NULL)
- xmlFree(URL);
-}
-
-/**
- * xmlParseXMLCatalogNodeList:
- * @cur: the XML node list of siblings
- * @prefer: the PUBLIC vs. SYSTEM current preference value
- * @parent: the parent Catalog entry
- *
- * Examines a list of XML sibling nodes of a catalog and build
- * a list of Catalog entry from it adding it to the parent.
- * The examination will recurse to examine node subtrees.
- */
-static void
-xmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer,
- xmlCatalogEntryPtr parent) {
- while (cur != NULL) {
- if ((cur->ns != NULL) && (cur->ns->href != NULL) &&
- (xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {
- xmlParseXMLCatalogNode(cur, prefer, parent);
- }
- cur = cur->next;
- }
- /* TODO: sort the list according to REWRITE lengths and prefer value */
-}
-
-/**
- * xmlParseXMLCatalogFile:
- * @prefer: the PUBLIC vs. SYSTEM current preference value
- * @filename: the filename for the catalog
- *
- * Parses the catalog file to extract the XML tree and then analyze the
- * tree to build a list of Catalog entries corresponding to this catalog
- *
- * Returns the resulting Catalog entries list
- */
-static xmlCatalogEntryPtr
-xmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename) {
- xmlDocPtr doc;
- xmlNodePtr cur;
- xmlChar *prop;
- xmlCatalogEntryPtr parent = NULL;
-
- if (filename == NULL)
- return(NULL);
-
- doc = xmlParseCatalogFile((const char *) filename);
- if (doc == NULL) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Failed to parse catalog %s\n", filename);
- return(NULL);
- }
-
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "%d Parsing catalog %s\n", xmlGetThreadId(), filename);
-
- cur = xmlDocGetRootElement(doc);
- if ((cur != NULL) && (xmlStrEqual(cur->name, BAD_CAST "catalog")) &&
- (cur->ns != NULL) && (cur->ns->href != NULL) &&
- (xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {
-
- parent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
- (const xmlChar *)filename, NULL, prefer);
- if (parent == NULL) {
- xmlFreeDoc(doc);
- return(NULL);
- }
-
- prop = xmlGetProp(cur, BAD_CAST "prefer");
- if (prop != NULL) {
- if (xmlStrEqual(prop, BAD_CAST "system")) {
- prefer = XML_CATA_PREFER_SYSTEM;
- } else if (xmlStrEqual(prop, BAD_CAST "public")) {
- prefer = XML_CATA_PREFER_PUBLIC;
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "Invalid value for prefer: '%s'\n",
- prop);
- }
- xmlFree(prop);
- }
- cur = cur->children;
- xmlParseXMLCatalogNodeList(cur, prefer, parent);
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "File %s is not an XML Catalog\n", filename);
- xmlFreeDoc(doc);
- return(NULL);
- }
- xmlFreeDoc(doc);
- return(parent);
-}
-
-/**
- * xmlFetchXMLCatalogFile:
- * @catal: an existing but incomplete catalog entry
- *
- * Fetch and parse the subcatalog referenced by an entry
- *
- * Returns 0 in case of success, -1 otherwise
- */
-static int
-xmlFetchXMLCatalogFile(xmlCatalogEntryPtr catal) {
- xmlCatalogEntryPtr doc;
-
- if (catal == NULL)
- return(-1);
- if (catal->URL == NULL)
- return(-1);
- if (catal->children != NULL)
- return(-1);
-
- /*
- * lock the whole catalog for modification
- */
- xmlRMutexLock(xmlCatalogMutex);
- if (catal->children != NULL) {
- /* Okay someone else did it in the meantime */
- xmlRMutexUnlock(xmlCatalogMutex);
- return(0);
- }
-
- if (xmlCatalogXMLFiles != NULL) {
- doc = (xmlCatalogEntryPtr)
- xmlHashLookup(xmlCatalogXMLFiles, catal->URL);
- if (doc != NULL) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Found %s in file hash\n", catal->URL);
-
- if (catal->type == XML_CATA_CATALOG)
- catal->children = doc->children;
- else
- catal->children = doc;
- catal->dealloc = 0;
- xmlRMutexUnlock(xmlCatalogMutex);
- return(0);
- }
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "%s not found in file hash\n", catal->URL);
- }
-
- /*
- * Fetch and parse. Note that xmlParseXMLCatalogFile does not
- * use the existing catalog, there is no recursion allowed at
- * that level.
- */
- doc = xmlParseXMLCatalogFile(catal->prefer, catal->URL);
- if (doc == NULL) {
- catal->type = XML_CATA_BROKEN_CATALOG;
- xmlRMutexUnlock(xmlCatalogMutex);
- return(-1);
- }
-
- if (catal->type == XML_CATA_CATALOG)
- catal->children = doc->children;
- else
- catal->children = doc;
-
- doc->dealloc = 1;
-
- if (xmlCatalogXMLFiles == NULL)
- xmlCatalogXMLFiles = xmlHashCreate(10);
- if (xmlCatalogXMLFiles != NULL) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "%s added to file hash\n", catal->URL);
- xmlHashAddEntry(xmlCatalogXMLFiles, catal->URL, doc);
- }
- xmlRMutexUnlock(xmlCatalogMutex);
- return(0);
-}
-
-/************************************************************************
- * *
- * XML Catalog handling *
- * *
- ************************************************************************/
-
-/**
- * xmlAddXMLCatalog:
- * @catal: top of an XML catalog
- * @type: the type of record to add to the catalog
- * @orig: the system, public or prefix to match (or NULL)
- * @replace: the replacement value for the match
- *
- * Add an entry in the XML catalog, it may overwrite existing but
- * different entries.
- *
- * Returns 0 if successful, -1 otherwise
- */
-static int
-xmlAddXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *type,
- const xmlChar *orig, const xmlChar *replace) {
- xmlCatalogEntryPtr cur;
- xmlCatalogEntryType typ;
- int doregister = 0;
-
- if ((catal == NULL) ||
- ((catal->type != XML_CATA_CATALOG) &&
- (catal->type != XML_CATA_BROKEN_CATALOG)))
- return(-1);
- if (catal->children == NULL) {
- xmlFetchXMLCatalogFile(catal);
- }
- if (catal->children == NULL)
- doregister = 1;
-
- typ = xmlGetXMLCatalogEntryType(type);
- if (typ == XML_CATA_NONE) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Failed to add unknown element %s to catalog\n", type);
- return(-1);
- }
-
- cur = catal->children;
- /*
- * Might be a simple "update in place"
- */
- if (cur != NULL) {
- while (cur != NULL) {
- if ((orig != NULL) && (cur->type == typ) &&
- (xmlStrEqual(orig, cur->name))) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Updating element %s to catalog\n", type);
- if (cur->value != NULL)
- xmlFree(cur->value);
- if (cur->URL != NULL)
- xmlFree(cur->URL);
- cur->value = xmlStrdup(replace);
- cur->URL = xmlStrdup(replace);
- return(0);
- }
- if (cur->next == NULL)
- break;
- cur = cur->next;
- }
- }
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Adding element %s to catalog\n", type);
- if (cur == NULL)
- catal->children = xmlNewCatalogEntry(typ, orig, replace,
- NULL, catal->prefer);
- else
- cur->next = xmlNewCatalogEntry(typ, orig, replace,
- NULL, catal->prefer);
- if (doregister) {
- cur = xmlHashLookup(xmlCatalogXMLFiles, catal->URL);
- if (cur != NULL)
- cur->children = catal->children;
- }
-
- return(0);
-}
-
-/**
- * xmlDelXMLCatalog:
- * @catal: top of an XML catalog
- * @value: the value to remove from the catalog
- *
- * Remove entries in the XML catalog where the value or the URI
- * is equal to @value
- *
- * Returns the number of entries removed if successful, -1 otherwise
- */
-static int
-xmlDelXMLCatalog(xmlCatalogEntryPtr catal, const xmlChar *value) {
- xmlCatalogEntryPtr cur;
- int ret = 0;
-
- if ((catal == NULL) ||
- ((catal->type != XML_CATA_CATALOG) &&
- (catal->type != XML_CATA_BROKEN_CATALOG)))
- return(-1);
- if (value == NULL)
- return(-1);
- if (catal->children == NULL) {
- xmlFetchXMLCatalogFile(catal);
- }
-
- /*
- * Scan the children
- */
- cur = catal->children;
- while (cur != NULL) {
- if (((cur->name != NULL) && (xmlStrEqual(value, cur->name))) ||
- (xmlStrEqual(value, cur->value))) {
- if (xmlDebugCatalogs) {
- if (cur->name != NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Removing element %s from catalog\n", cur->name);
- else
- xmlGenericError(xmlGenericErrorContext,
- "Removing element %s from catalog\n", cur->value);
- }
- cur->type = XML_CATA_REMOVED;
- }
- cur = cur->next;
- }
- return(ret);
-}
-
-/**
- * xmlCatalogXMLResolve:
- * @catal: a catalog list
- * @pubId: the public ID string
- * @sysId: the system ID string
- *
- * Do a complete resolution lookup of an External Identifier for a
- * list of catalog entries.
- *
- * Implements (or tries to) 7.1. External Identifier Resolution
- * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
- *
- * Returns the URI of the resource or NULL if not found
- */
-static xmlChar *
-xmlCatalogXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
- const xmlChar *sysID) {
- xmlChar *ret = NULL;
- xmlCatalogEntryPtr cur;
- int haveDelegate = 0;
- int haveNext = 0;
-
- /*
- * First tries steps 2/ 3/ 4/ if a system ID is provided.
- */
- if (sysID != NULL) {
- xmlCatalogEntryPtr rewrite = NULL;
- int lenrewrite = 0, len;
- cur = catal;
- haveDelegate = 0;
- while (cur != NULL) {
- switch (cur->type) {
- case XML_CATA_SYSTEM:
- if (xmlStrEqual(sysID, cur->name)) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Found system match %s\n", cur->name);
- return(xmlStrdup(cur->URL));
- }
- break;
- case XML_CATA_REWRITE_SYSTEM:
- len = xmlStrlen(cur->name);
- if ((len > lenrewrite) &&
- (!xmlStrncmp(sysID, cur->name, len))) {
- lenrewrite = len;
- rewrite = cur;
- }
- break;
- case XML_CATA_DELEGATE_SYSTEM:
- if (!xmlStrncmp(sysID, cur->name, xmlStrlen(cur->name)))
- haveDelegate++;
- break;
- case XML_CATA_NEXT_CATALOG:
- haveNext++;
- break;
- default:
- break;
- }
- cur = cur->next;
- }
- if (rewrite != NULL) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Using rewriting rule %s\n", rewrite->name);
- ret = xmlStrdup(rewrite->URL);
- if (ret != NULL)
- ret = xmlStrcat(ret, &sysID[lenrewrite]);
- return(ret);
- }
- if (haveDelegate) {
- const xmlChar *delegates[MAX_DELEGATE];
- int nbList = 0, i;
-
- /*
- * Assume the entries have been sorted by decreasing substring
- * matches when the list was produced.
- */
- cur = catal;
- while (cur != NULL) {
- if ((cur->type == XML_CATA_DELEGATE_SYSTEM) &&
- (!xmlStrncmp(sysID, cur->name, xmlStrlen(cur->name)))) {
- for (i = 0;i < nbList;i++)
- if (xmlStrEqual(cur->URL, delegates[i]))
- break;
- if (i < nbList) {
- cur = cur->next;
- continue;
- }
- if (nbList < MAX_DELEGATE)
- delegates[nbList++] = cur->URL;
-
- if (cur->children == NULL) {
- xmlFetchXMLCatalogFile(cur);
- }
- if (cur->children != NULL) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Trying system delegate %s\n", cur->URL);
- ret = xmlCatalogListXMLResolve(
- cur->children, NULL, sysID);
- if (ret != NULL)
- return(ret);
- }
- }
- cur = cur->next;
- }
- /*
- * Apply the cut algorithm explained in 4/
- */
- return(XML_CATAL_BREAK);
- }
- }
- /*
- * Then tries 5/ 6/ if a public ID is provided
- */
- if (pubID != NULL) {
- cur = catal;
- haveDelegate = 0;
- while (cur != NULL) {
- switch (cur->type) {
- case XML_CATA_PUBLIC:
- if (xmlStrEqual(pubID, cur->name)) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Found public match %s\n", cur->name);
- return(xmlStrdup(cur->URL));
- }
- break;
- case XML_CATA_DELEGATE_PUBLIC:
- if (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)) &&
- (cur->prefer == XML_CATA_PREFER_PUBLIC))
- haveDelegate++;
- break;
- case XML_CATA_NEXT_CATALOG:
- if (sysID == NULL)
- haveNext++;
- break;
- default:
- break;
- }
- cur = cur->next;
- }
- if (haveDelegate) {
- const xmlChar *delegates[MAX_DELEGATE];
- int nbList = 0, i;
-
- /*
- * Assume the entries have been sorted by decreasing substring
- * matches when the list was produced.
- */
- cur = catal;
- while (cur != NULL) {
- if ((cur->type == XML_CATA_DELEGATE_PUBLIC) &&
- (cur->prefer == XML_CATA_PREFER_PUBLIC) &&
- (!xmlStrncmp(pubID, cur->name, xmlStrlen(cur->name)))) {
-
- for (i = 0;i < nbList;i++)
- if (xmlStrEqual(cur->URL, delegates[i]))
- break;
- if (i < nbList) {
- cur = cur->next;
- continue;
- }
- if (nbList < MAX_DELEGATE)
- delegates[nbList++] = cur->URL;
-
- if (cur->children == NULL) {
- xmlFetchXMLCatalogFile(cur);
- }
- if (cur->children != NULL) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Trying public delegate %s\n", cur->URL);
- ret = xmlCatalogListXMLResolve(
- cur->children, pubID, NULL);
- if (ret != NULL)
- return(ret);
- }
- }
- cur = cur->next;
- }
- /*
- * Apply the cut algorithm explained in 4/
- */
- return(XML_CATAL_BREAK);
- }
- }
- if (haveNext) {
- cur = catal;
- while (cur != NULL) {
- if (cur->type == XML_CATA_NEXT_CATALOG) {
- if (cur->children == NULL) {
- xmlFetchXMLCatalogFile(cur);
- }
- if (cur->children != NULL) {
- ret = xmlCatalogListXMLResolve(cur->children, pubID, sysID);
- if (ret != NULL)
- return(ret);
- }
- }
- cur = cur->next;
- }
- }
-
- return(NULL);
-}
-
-/**
- * xmlCatalogXMLResolveURI:
- * @catal: a catalog list
- * @URI: the URI
- * @sysId: the system ID string
- *
- * Do a complete resolution lookup of an External Identifier for a
- * list of catalog entries.
- *
- * Implements (or tries to) 7.2.2. URI Resolution
- * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
- *
- * Returns the URI of the resource or NULL if not found
- */
-static xmlChar *
-xmlCatalogXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
- xmlChar *ret = NULL;
- xmlCatalogEntryPtr cur;
- int haveDelegate = 0;
- int haveNext = 0;
- xmlCatalogEntryPtr rewrite = NULL;
- int lenrewrite = 0, len;
-
- if (catal == NULL)
- return(NULL);
-
- if (URI == NULL)
- return(NULL);
-
- /*
- * First tries steps 2/ 3/ 4/ if a system ID is provided.
- */
- cur = catal;
- haveDelegate = 0;
- while (cur != NULL) {
- switch (cur->type) {
- case XML_CATA_URI:
- if (xmlStrEqual(URI, cur->name)) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Found URI match %s\n", cur->name);
- return(xmlStrdup(cur->URL));
- }
- break;
- case XML_CATA_REWRITE_URI:
- len = xmlStrlen(cur->name);
- if ((len > lenrewrite) &&
- (!xmlStrncmp(URI, cur->name, len))) {
- lenrewrite = len;
- rewrite = cur;
- }
- break;
- case XML_CATA_DELEGATE_URI:
- if (!xmlStrncmp(URI, cur->name, xmlStrlen(cur->name)))
- haveDelegate++;
- break;
- case XML_CATA_NEXT_CATALOG:
- haveNext++;
- break;
- default:
- break;
- }
- cur = cur->next;
- }
- if (rewrite != NULL) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Using rewriting rule %s\n", rewrite->name);
- ret = xmlStrdup(rewrite->URL);
- if (ret != NULL)
- ret = xmlStrcat(ret, &URI[lenrewrite]);
- return(ret);
- }
- if (haveDelegate) {
- const xmlChar *delegates[MAX_DELEGATE];
- int nbList = 0, i;
-
- /*
- * Assume the entries have been sorted by decreasing substring
- * matches when the list was produced.
- */
- cur = catal;
- while (cur != NULL) {
- if ((cur->type == XML_CATA_DELEGATE_SYSTEM) &&
- (!xmlStrncmp(URI, cur->name, xmlStrlen(cur->name)))) {
- for (i = 0;i < nbList;i++)
- if (xmlStrEqual(cur->URL, delegates[i]))
- break;
- if (i < nbList) {
- cur = cur->next;
- continue;
- }
- if (nbList < MAX_DELEGATE)
- delegates[nbList++] = cur->URL;
-
- if (cur->children == NULL) {
- xmlFetchXMLCatalogFile(cur);
- }
- if (cur->children != NULL) {
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Trying URI delegate %s\n", cur->URL);
- ret = xmlCatalogListXMLResolveURI(
- cur->children, URI);
- if (ret != NULL)
- return(ret);
- }
- }
- cur = cur->next;
- }
- /*
- * Apply the cut algorithm explained in 4/
- */
- return(XML_CATAL_BREAK);
- }
- if (haveNext) {
- cur = catal;
- while (cur != NULL) {
- if (cur->type == XML_CATA_NEXT_CATALOG) {
- if (cur->children == NULL) {
- xmlFetchXMLCatalogFile(cur);
- }
- if (cur->children != NULL) {
- ret = xmlCatalogListXMLResolveURI(cur->children, URI);
- if (ret != NULL)
- return(ret);
- }
- }
- cur = cur->next;
- }
- }
-
- return(NULL);
-}
-
-/**
- * xmlCatalogListXMLResolve:
- * @catal: a catalog list
- * @pubId: the public ID string
- * @sysId: the system ID string
- *
- * Do a complete resolution lookup of an External Identifier for a
- * list of catalogs
- *
- * Implements (or tries to) 7.1. External Identifier Resolution
- * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
- *
- * Returns the URI of the resource or NULL if not found
- */
-static xmlChar *
-xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,
- const xmlChar *sysID) {
- xmlChar *ret = NULL;
- xmlChar *urnID = NULL;
-
- if (catal == NULL)
- return(NULL);
- if ((pubID == NULL) && (sysID == NULL))
- return(NULL);
-
- if (!xmlStrncmp(pubID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
- urnID = xmlCatalogUnWrapURN(pubID);
- if (xmlDebugCatalogs) {
- if (urnID == NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Public URN ID %s expanded to NULL\n", pubID);
- else
- xmlGenericError(xmlGenericErrorContext,
- "Public URN ID expanded to %s\n", urnID);
- }
- ret = xmlCatalogListXMLResolve(catal, urnID, sysID);
- if (urnID != NULL)
- xmlFree(urnID);
- return(ret);
- }
- if (!xmlStrncmp(sysID, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
- urnID = xmlCatalogUnWrapURN(sysID);
- if (xmlDebugCatalogs) {
- if (urnID == NULL)
- xmlGenericError(xmlGenericErrorContext,
- "System URN ID %s expanded to NULL\n", sysID);
- else
- xmlGenericError(xmlGenericErrorContext,
- "System URN ID expanded to %s\n", urnID);
- }
- if (pubID == NULL)
- ret = xmlCatalogListXMLResolve(catal, urnID, NULL);
- else if (xmlStrEqual(pubID, urnID))
- ret = xmlCatalogListXMLResolve(catal, pubID, NULL);
- else {
- ret = xmlCatalogListXMLResolve(catal, pubID, NULL);
- }
- if (urnID != NULL)
- xmlFree(urnID);
- return(ret);
- }
- while (catal != NULL) {
- if (catal->type == XML_CATA_CATALOG) {
- if (catal->children == NULL) {
- xmlFetchXMLCatalogFile(catal);
- }
- if (catal->children != NULL) {
- ret = xmlCatalogXMLResolve(catal->children, pubID, sysID);
- if (ret != NULL)
- return(ret);
- }
- }
- catal = catal->next;
- }
- return(ret);
-}
-
-/**
- * xmlCatalogListXMLResolveURI:
- * @catal: a catalog list
- * @URI: the URI
- *
- * Do a complete resolution lookup of an URI for a list of catalogs
- *
- * Implements (or tries to) 7.2. URI Resolution
- * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
- *
- * Returns the URI of the resource or NULL if not found
- */
-static xmlChar *
-xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI) {
- xmlChar *ret = NULL;
- xmlChar *urnID = NULL;
-
- if (catal == NULL)
- return(NULL);
- if (URI == NULL)
- return(NULL);
-
- if (!xmlStrncmp(URI, BAD_CAST XML_URN_PUBID, sizeof(XML_URN_PUBID) - 1)) {
- urnID = xmlCatalogUnWrapURN(URI);
- if (xmlDebugCatalogs) {
- if (urnID == NULL)
- xmlGenericError(xmlGenericErrorContext,
- "URN ID %s expanded to NULL\n", URI);
- else
- xmlGenericError(xmlGenericErrorContext,
- "URN ID expanded to %s\n", urnID);
- }
- ret = xmlCatalogListXMLResolve(catal, urnID, NULL);
- if (urnID != NULL)
- xmlFree(urnID);
- return(ret);
- }
- while (catal != NULL) {
- if (catal->type == XML_CATA_CATALOG) {
- if (catal->children == NULL) {
- xmlFetchXMLCatalogFile(catal);
- }
- if (catal->children != NULL) {
- ret = xmlCatalogXMLResolveURI(catal->children, URI);
- if (ret != NULL)
- return(ret);
- }
- }
- catal = catal->next;
- }
- return(ret);
-}
-
-/************************************************************************
- * *
- * The SGML Catalog parser *
- * *
- ************************************************************************/
-
-
-#define RAW *cur
-#define NEXT cur++;
-#define SKIP(x) cur += x;
-
-#define SKIP_BLANKS while (IS_BLANK(*cur)) NEXT;
-
-/**
- * xmlParseSGMLCatalogComment:
- * @cur: the current character
- *
- * Skip a comment in an SGML catalog
- *
- * Returns new current character
- */
-static const xmlChar *
-xmlParseSGMLCatalogComment(const xmlChar *cur) {
- if ((cur[0] != '-') || (cur[1] != '-'))
- return(cur);
- SKIP(2);
- while ((cur[0] != 0) && ((cur[0] != '-') || ((cur[1] != '-'))))
- NEXT;
- if (cur[0] == 0) {
- return(NULL);
- }
- return(cur + 2);
-}
-
-/**
- * xmlParseSGMLCatalogPubid:
- * @cur: the current character
- * @id: the return location
- *
- * Parse an SGML catalog ID
- *
- * Returns new current character and store the value in @id
- */
-static const xmlChar *
-xmlParseSGMLCatalogPubid(const xmlChar *cur, xmlChar **id) {
- xmlChar *buf = NULL;
- int len = 0;
- int size = 50;
- xmlChar stop;
- int count = 0;
-
- *id = NULL;
-
- if (RAW == '"') {
- NEXT;
- stop = '"';
- } else if (RAW == '\'') {
- NEXT;
- stop = '\'';
- } else {
- stop = ' ';
- }
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %d byte failed\n", size);
- return(NULL);
- }
- while (xmlIsPubidChar(*cur) || (*cur == '?')) {
- if ((*cur == stop) && (stop != ' '))
- break;
- if ((stop == ' ') && (IS_BLANK(*cur)))
- break;
- if (len + 1 >= size) {
- size *= 2;
- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc of %d byte failed\n", size);
- return(NULL);
- }
- }
- buf[len++] = *cur;
- count++;
- NEXT;
- }
- buf[len] = 0;
- if (stop == ' ') {
- if (!IS_BLANK(*cur)) {
- xmlFree(buf);
- return(NULL);
- }
- } else {
- if (*cur != stop) {
- xmlFree(buf);
- return(NULL);
- }
- NEXT;
- }
- *id = buf;
- return(cur);
-}
-
-/**
- * xmlParseSGMLCatalogName:
- * @cur: the current character
- * @name: the return location
- *
- * Parse an SGML catalog name
- *
- * Returns new current character and store the value in @name
- */
-static const xmlChar *
-xmlParseSGMLCatalogName(const xmlChar *cur, xmlChar **name) {
- xmlChar buf[XML_MAX_NAMELEN + 5];
- int len = 0;
- int c;
-
- *name = NULL;
-
- /*
- * Handler for more complex cases
- */
- c = *cur;
- if ((!IS_LETTER(c) && (c != '_') && (c != ':'))) {
- return(NULL);
- }
-
- while (((IS_LETTER(c)) || (IS_DIGIT(c)) ||
- (c == '.') || (c == '-') ||
- (c == '_') || (c == ':'))) {
- buf[len++] = c;
- cur++;
- c = *cur;
- if (len >= XML_MAX_NAMELEN)
- return(NULL);
- }
- *name = xmlStrndup(buf, len);
- return(cur);
-}
-
-/**
- * xmlGetSGMLCatalogEntryType:
- * @name: the entry name
- *
- * Get the Catalog entry type for a given SGML Catalog name
- *
- * Returns Catalog entry type
- */
-static xmlCatalogEntryType
-xmlGetSGMLCatalogEntryType(const xmlChar *name) {
- xmlCatalogEntryType type = XML_CATA_NONE;
- if (xmlStrEqual(name, (const xmlChar *) "SYSTEM"))
- type = SGML_CATA_SYSTEM;
- else if (xmlStrEqual(name, (const xmlChar *) "PUBLIC"))
- type = SGML_CATA_PUBLIC;
- else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
- type = SGML_CATA_DELEGATE;
- else if (xmlStrEqual(name, (const xmlChar *) "ENTITY"))
- type = SGML_CATA_ENTITY;
- else if (xmlStrEqual(name, (const xmlChar *) "DOCTYPE"))
- type = SGML_CATA_DOCTYPE;
- else if (xmlStrEqual(name, (const xmlChar *) "LINKTYPE"))
- type = SGML_CATA_LINKTYPE;
- else if (xmlStrEqual(name, (const xmlChar *) "NOTATION"))
- type = SGML_CATA_NOTATION;
- else if (xmlStrEqual(name, (const xmlChar *) "SGMLDECL"))
- type = SGML_CATA_SGMLDECL;
- else if (xmlStrEqual(name, (const xmlChar *) "DOCUMENT"))
- type = SGML_CATA_DOCUMENT;
- else if (xmlStrEqual(name, (const xmlChar *) "CATALOG"))
- type = SGML_CATA_CATALOG;
- else if (xmlStrEqual(name, (const xmlChar *) "BASE"))
- type = SGML_CATA_BASE;
- else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
- type = SGML_CATA_DELEGATE;
- return(type);
-}
-
-/**
- * xmlParseSGMLCatalog:
- * @catal: the SGML Catalog
- * @value: the content of the SGML Catalog serialization
- * @file: the filepath for the catalog
- * @super: should this be handled as a Super Catalog in which case
- * parsing is not recursive
- *
- * Parse an SGML catalog content and fill up the @catal hash table with
- * the new entries found.
- *
- * Returns 0 in case of success, -1 in case of error.
- */
-static int
-xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value,
- const char *file, int super) {
- const xmlChar *cur = value;
- xmlChar *base = NULL;
- int res;
-
- if ((cur == NULL) || (file == NULL))
- return(-1);
- base = xmlStrdup((const xmlChar *) file);
-
- while ((cur != NULL) && (cur[0] != 0)) {
- SKIP_BLANKS;
- if (cur[0] == 0)
- break;
- if ((cur[0] == '-') && (cur[1] == '-')) {
- cur = xmlParseSGMLCatalogComment(cur);
- if (cur == NULL) {
- /* error */
- break;
- }
- } else {
- xmlChar *sysid = NULL;
- xmlChar *name = NULL;
- xmlCatalogEntryType type = XML_CATA_NONE;
-
- cur = xmlParseSGMLCatalogName(cur, &name);
- if (name == NULL) {
- /* error */
- break;
- }
- if (!IS_BLANK(*cur)) {
- /* error */
- break;
- }
- SKIP_BLANKS;
- if (xmlStrEqual(name, (const xmlChar *) "SYSTEM"))
- type = SGML_CATA_SYSTEM;
- else if (xmlStrEqual(name, (const xmlChar *) "PUBLIC"))
- type = SGML_CATA_PUBLIC;
- else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
- type = SGML_CATA_DELEGATE;
- else if (xmlStrEqual(name, (const xmlChar *) "ENTITY"))
- type = SGML_CATA_ENTITY;
- else if (xmlStrEqual(name, (const xmlChar *) "DOCTYPE"))
- type = SGML_CATA_DOCTYPE;
- else if (xmlStrEqual(name, (const xmlChar *) "LINKTYPE"))
- type = SGML_CATA_LINKTYPE;
- else if (xmlStrEqual(name, (const xmlChar *) "NOTATION"))
- type = SGML_CATA_NOTATION;
- else if (xmlStrEqual(name, (const xmlChar *) "SGMLDECL"))
- type = SGML_CATA_SGMLDECL;
- else if (xmlStrEqual(name, (const xmlChar *) "DOCUMENT"))
- type = SGML_CATA_DOCUMENT;
- else if (xmlStrEqual(name, (const xmlChar *) "CATALOG"))
- type = SGML_CATA_CATALOG;
- else if (xmlStrEqual(name, (const xmlChar *) "BASE"))
- type = SGML_CATA_BASE;
- else if (xmlStrEqual(name, (const xmlChar *) "DELEGATE"))
- type = SGML_CATA_DELEGATE;
- else if (xmlStrEqual(name, (const xmlChar *) "OVERRIDE")) {
- xmlFree(name);
- cur = xmlParseSGMLCatalogName(cur, &name);
- if (name == NULL) {
- /* error */
- break;
- }
- xmlFree(name);
- continue;
- }
- xmlFree(name);
- name = NULL;
-
- switch(type) {
- case SGML_CATA_ENTITY:
- if (*cur == '%')
- type = SGML_CATA_PENTITY;
- case SGML_CATA_PENTITY:
- case SGML_CATA_DOCTYPE:
- case SGML_CATA_LINKTYPE:
- case SGML_CATA_NOTATION:
- cur = xmlParseSGMLCatalogName(cur, &name);
- if (cur == NULL) {
- /* error */
- break;
- }
- if (!IS_BLANK(*cur)) {
- /* error */
- break;
- }
- SKIP_BLANKS;
- cur = xmlParseSGMLCatalogPubid(cur, &sysid);
- if (cur == NULL) {
- /* error */
- break;
- }
- break;
- case SGML_CATA_PUBLIC:
- case SGML_CATA_SYSTEM:
- case SGML_CATA_DELEGATE:
- cur = xmlParseSGMLCatalogPubid(cur, &name);
- if (cur == NULL) {
- /* error */
- break;
- }
- if (!IS_BLANK(*cur)) {
- /* error */
- break;
- }
- SKIP_BLANKS;
- cur = xmlParseSGMLCatalogPubid(cur, &sysid);
- if (cur == NULL) {
- /* error */
- break;
- }
- break;
- case SGML_CATA_BASE:
- case SGML_CATA_CATALOG:
- case SGML_CATA_DOCUMENT:
- case SGML_CATA_SGMLDECL:
- cur = xmlParseSGMLCatalogPubid(cur, &sysid);
- if (cur == NULL) {
- /* error */
- break;
- }
- break;
- default:
- break;
- }
- if (cur == NULL) {
- if (name != NULL)
- xmlFree(name);
- if (sysid != NULL)
- xmlFree(sysid);
- break;
- } else if (type == SGML_CATA_BASE) {
- if (base != NULL)
- xmlFree(base);
- base = xmlStrdup(sysid);
- } else if ((type == SGML_CATA_PUBLIC) ||
- (type == SGML_CATA_SYSTEM)) {
- xmlChar *filename;
-
- filename = xmlBuildURI(sysid, base);
- if (filename != NULL) {
- xmlCatalogEntryPtr entry;
-
- entry = xmlNewCatalogEntry(type, name, filename,
- NULL, XML_CATA_PREFER_NONE);
- res = xmlHashAddEntry(catal->sgml, name, entry);
- if (res < 0) {
- xmlFreeCatalogEntry(entry);
- }
- xmlFree(filename);
- }
-
- } else if (type == SGML_CATA_CATALOG) {
- if (super) {
- xmlCatalogEntryPtr entry;
-
- entry = xmlNewCatalogEntry(type, sysid, NULL, NULL,
- XML_CATA_PREFER_NONE);
- res = xmlHashAddEntry(catal->sgml, sysid, entry);
- if (res < 0) {
- xmlFreeCatalogEntry(entry);
- }
- } else {
- xmlChar *filename;
-
- filename = xmlBuildURI(sysid, base);
- if (filename != NULL) {
- xmlExpandCatalog(catal, (const char *)filename);
- xmlFree(filename);
- }
- }
- }
- /*
- * drop anything else we won't handle it
- */
- if (name != NULL)
- xmlFree(name);
- if (sysid != NULL)
- xmlFree(sysid);
- }
- }
- if (base != NULL)
- xmlFree(base);
- if (cur == NULL)
- return(-1);
- return(0);
-}
-
-/************************************************************************
- * *
- * SGML Catalog handling *
- * *
- ************************************************************************/
-
-/**
- * xmlCatalogGetSGMLPublic:
- * @catal: an SGML catalog hash
- * @pubId: the public ID string
- *
- * Try to lookup the system ID associated to a public ID
- *
- * Returns the system ID if found or NULL otherwise.
- */
-static const xmlChar *
-xmlCatalogGetSGMLPublic(xmlHashTablePtr catal, const xmlChar *pubID) {
- xmlCatalogEntryPtr entry;
-
- if (catal == NULL)
- return(NULL);
-
- entry = (xmlCatalogEntryPtr) xmlHashLookup(catal, pubID);
- if (entry == NULL)
- return(NULL);
- if (entry->type == SGML_CATA_PUBLIC)
- return(entry->URL);
- return(NULL);
-}
-
-/**
- * xmlCatalogGetSGMLSystem:
- * @catal: an SGML catalog hash
- * @sysId: the public ID string
- *
- * Try to lookup the catalog local reference for a system ID
- *
- * Returns the system ID if found or NULL otherwise.
- */
-static const xmlChar *
-xmlCatalogGetSGMLSystem(xmlHashTablePtr catal, const xmlChar *sysID) {
- xmlCatalogEntryPtr entry;
-
- if (catal == NULL)
- return(NULL);
-
- entry = (xmlCatalogEntryPtr) xmlHashLookup(catal, sysID);
- if (entry == NULL)
- return(NULL);
- if (entry->type == SGML_CATA_SYSTEM)
- return(entry->URL);
- return(NULL);
-}
-
-/**
- * xmlCatalogSGMLResolve:
- * @catal: the SGML catalog
- * @pubId: the public ID string
- * @sysId: the system ID string
- *
- * Do a complete resolution lookup of an External Identifier
- *
- * Returns the URI of the resource or NULL if not found
- */
-static const xmlChar *
-xmlCatalogSGMLResolve(xmlCatalogPtr catal, const xmlChar *pubID,
- const xmlChar *sysID) {
- const xmlChar *ret = NULL;
-
- if (catal->sgml == NULL)
- return(NULL);
-
- if (pubID != NULL)
- ret = xmlCatalogGetSGMLPublic(catal->sgml, pubID);
- if (ret != NULL)
- return(ret);
- if (sysID != NULL)
- ret = xmlCatalogGetSGMLSystem(catal->sgml, sysID);
- return(NULL);
-}
-
-/************************************************************************
- * *
- * Specific Public interfaces *
- * *
- ************************************************************************/
-
-/**
- * xmlLoadSGMLSuperCatalog:
- * @filename: a file path
- *
- * Load an SGML super catalog. It won't expand CATALOG or DELEGATE
- * references. This is only needed for manipulating SGML Super Catalogs
- * like adding and removing CATALOG or DELEGATE entries.
- *
- * Returns the catalog parsed or NULL in case of error
- */
-xmlCatalogPtr
-xmlLoadSGMLSuperCatalog(const char *filename)
-{
- xmlChar *content;
- xmlCatalogPtr catal;
- int ret;
-
- content = xmlLoadFileContent(filename);
- if (content == NULL)
- return(NULL);
-
- catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
- if (catal == NULL) {
- xmlFree(content);
- return(NULL);
- }
-
- ret = xmlParseSGMLCatalog(catal, content, filename, 1);
- xmlFree(content);
- if (ret < 0) {
- xmlFreeCatalog(catal);
- return(NULL);
- }
- return (catal);
-}
-
-/**
- * xmlLoadACatalog:
- * @filename: a file path
- *
- * Load the catalog and build the associated data structures.
- * This can be either an XML Catalog or an SGML Catalog
- * It will recurse in SGML CATALOG entries. On the other hand XML
- * Catalogs are not handled recursively.
- *
- * Returns the catalog parsed or NULL in case of error
- */
-xmlCatalogPtr
-xmlLoadACatalog(const char *filename)
-{
- xmlChar *content;
- xmlChar *first;
- xmlCatalogPtr catal;
- int ret;
-
- content = xmlLoadFileContent(filename);
- if (content == NULL)
- return(NULL);
-
-
- first = content;
-
- while ((*first != 0) && (*first != '-') && (*first != '<') &&
- (!(((*first >= 'A') && (*first <= 'Z')) ||
- ((*first >= 'a') && (*first <= 'z')))))
- first++;
-
- if (*first != '<') {
- catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
- if (catal == NULL) {
- xmlFree(content);
- return(NULL);
- }
- ret = xmlParseSGMLCatalog(catal, content, filename, 0);
- if (ret < 0) {
- xmlFreeCatalog(catal);
- xmlFree(content);
- return(NULL);
- }
- } else {
- catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE, xmlCatalogDefaultPrefer);
- if (catal == NULL) {
- xmlFree(content);
- return(NULL);
- }
- catal->xml = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
- NULL, BAD_CAST filename, xmlCatalogDefaultPrefer);
- }
- xmlFree(content);
- return (catal);
-}
-
-/**
- * xmlExpandCatalog:
- * @catal: a catalog
- * @filename: a file path
- *
- * Load the catalog and expand the existing catal structure.
- * This can be either an XML Catalog or an SGML Catalog
- *
- * Returns 0 in case of success, -1 in case of error
- */
-static int
-xmlExpandCatalog(xmlCatalogPtr catal, const char *filename)
-{
- int ret;
-
- if ((catal == NULL) || (filename == NULL))
- return(-1);
-
-
- if (catal->type == XML_SGML_CATALOG_TYPE) {
- xmlChar *content;
-
- content = xmlLoadFileContent(filename);
- if (content == NULL)
- return(-1);
-
- ret = xmlParseSGMLCatalog(catal, content, filename, 0);
- if (ret < 0) {
- xmlFree(content);
- return(-1);
- }
- xmlFree(content);
- } else {
- xmlCatalogEntryPtr tmp, cur;
- tmp = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
- NULL, BAD_CAST filename, xmlCatalogDefaultPrefer);
-
- cur = catal->xml;
- if (cur == NULL) {
- catal->xml = tmp;
- } else {
- while (cur->next != NULL) cur = cur->next;
- cur->next = tmp;
- }
- }
- return (0);
-}
-
-/**
- * xmlACatalogResolveSystem:
- * @catal: a Catalog
- * @sysID: the public ID string
- *
- * Try to lookup the catalog resource for a system ID
- *
- * Returns the system ID if found or NULL otherwise, the value returned
- * must be freed by the caller.
- */
-xmlChar *
-xmlACatalogResolveSystem(xmlCatalogPtr catal, const xmlChar *sysID) {
- xmlChar *ret = NULL;
-
- if ((sysID == NULL) || (catal == NULL))
- return(NULL);
-
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Resolve sysID %s\n", sysID);
-
- if (catal->type == XML_XML_CATALOG_TYPE) {
- ret = xmlCatalogListXMLResolve(catal->xml, NULL, sysID);
- if (ret == XML_CATAL_BREAK)
- ret = NULL;
- } else {
- const xmlChar *sgml;
-
- sgml = xmlCatalogGetSGMLSystem(catal->sgml, sysID);
- if (sgml != NULL)
- ret = xmlStrdup(sgml);
- }
- return(ret);
-}
-
-/**
- * xmlACatalogResolvePublic:
- * @catal: a Catalog
- * @pubID: the public ID string
- *
- * Try to lookup the system ID associated to a public ID in that catalog
- *
- * Returns the system ID if found or NULL otherwise, the value returned
- * must be freed by the caller.
- */
-xmlChar *
-xmlACatalogResolvePublic(xmlCatalogPtr catal, const xmlChar *pubID) {
- xmlChar *ret = NULL;
-
- if ((pubID == NULL) || (catal == NULL))
- return(NULL);
-
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Resolve pubID %s\n", pubID);
-
- if (catal->type == XML_XML_CATALOG_TYPE) {
- ret = xmlCatalogListXMLResolve(catal->xml, pubID, NULL);
- if (ret == XML_CATAL_BREAK)
- ret = NULL;
- } else {
- const xmlChar *sgml;
-
- sgml = xmlCatalogGetSGMLPublic(catal->sgml, pubID);
- if (sgml != NULL)
- ret = xmlStrdup(sgml);
- }
- return(ret);
-}
-
-/**
- * xmlACatalogResolve:
- * @catal: a Catalog
- * @pubID: the public ID string
- * @sysID: the system ID string
- *
- * Do a complete resolution lookup of an External Identifier
- *
- * Returns the URI of the resource or NULL if not found, it must be freed
- * by the caller.
- */
-xmlChar *
-xmlACatalogResolve(xmlCatalogPtr catal, const xmlChar * pubID,
- const xmlChar * sysID)
-{
- xmlChar *ret = NULL;
-
- if (((pubID == NULL) && (sysID == NULL)) || (catal == NULL))
- return (NULL);
-
- if (xmlDebugCatalogs) {
- if (pubID != NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Resolve: pubID %s\n", pubID);
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "Resolve: sysID %s\n", sysID);
- }
- }
-
- if (catal->type == XML_XML_CATALOG_TYPE) {
- ret = xmlCatalogListXMLResolve(catal->xml, pubID, sysID);
- if (ret == XML_CATAL_BREAK)
- ret = NULL;
- } else {
- const xmlChar *sgml;
-
- sgml = xmlCatalogSGMLResolve(catal, pubID, sysID);
- if (sgml != NULL)
- ret = xmlStrdup(sgml);
- }
- return (ret);
-}
-
-/**
- * xmlACatalogResolveURI:
- * @catal: a Catalog
- * @URI: the URI
- *
- * Do a complete resolution lookup of an URI
- *
- * Returns the URI of the resource or NULL if not found, it must be freed
- * by the caller.
- */
-xmlChar *
-xmlACatalogResolveURI(xmlCatalogPtr catal, const xmlChar *URI) {
- xmlChar *ret = NULL;
-
- if ((URI == NULL) || (catal == NULL))
- return(NULL);
-
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Resolve URI %s\n", URI);
-
- if (catal->type == XML_XML_CATALOG_TYPE) {
- ret = xmlCatalogListXMLResolveURI(catal->xml, URI);
- if (ret == XML_CATAL_BREAK)
- ret = NULL;
- } else {
- const xmlChar *sgml;
-
- sgml = xmlCatalogSGMLResolve(catal, NULL, URI);
- if (sgml != NULL)
- sgml = xmlStrdup(sgml);
- }
- return(ret);
-}
-
-/**
- * xmlACatalogDump:
- * @catal: a Catalog
- * @out: the file.
- *
- * Free up all the memory associated with catalogs
- */
-void
-xmlACatalogDump(xmlCatalogPtr catal, FILE *out) {
- if ((out == NULL) || (catal == NULL))
- return;
-
- if (catal->type == XML_XML_CATALOG_TYPE) {
- xmlDumpXMLCatalog(out, catal->xml);
- } else {
- xmlHashScan(catal->sgml,
- (xmlHashScanner) xmlCatalogDumpEntry, out);
- }
-}
-
-/**
- * xmlACatalogAdd:
- * @catal: a Catalog
- * @type: the type of record to add to the catalog
- * @orig: the system, public or prefix to match
- * @replace: the replacement value for the match
- *
- * Add an entry in the catalog, it may overwrite existing but
- * different entries.
- *
- * Returns 0 if successful, -1 otherwise
- */
-int
-xmlACatalogAdd(xmlCatalogPtr catal, const xmlChar * type,
- const xmlChar * orig, const xmlChar * replace)
-{
- int res = -1;
-
- if (catal == NULL)
- return(-1);
-
- if (catal->type == XML_XML_CATALOG_TYPE) {
- res = xmlAddXMLCatalog(catal->xml, type, orig, replace);
- } else {
- xmlCatalogEntryType cattype;
-
- cattype = xmlGetSGMLCatalogEntryType(type);
- if (cattype != XML_CATA_NONE) {
- xmlCatalogEntryPtr entry;
-
- entry = xmlNewCatalogEntry(cattype, orig, replace, NULL,
- XML_CATA_PREFER_NONE);
- if (catal->sgml == NULL)
- catal->sgml = xmlHashCreate(10);
- res = xmlHashAddEntry(catal->sgml, orig, entry);
- }
- }
- return (res);
-}
-
-/**
- * xmlACatalogRemove:
- * @catal: a Catalog
- * @value: the value to remove
- *
- * Remove an entry from the catalog
- *
- * Returns the number of entries removed if successful, -1 otherwise
- */
-int
-xmlACatalogRemove(xmlCatalogPtr catal, const xmlChar *value) {
- int res = -1;
-
- if ((catal == NULL) || (value == NULL))
- return(-1);
-
- if (catal->type == XML_XML_CATALOG_TYPE) {
- res = xmlDelXMLCatalog(catal->xml, value);
- } else {
- res = xmlHashRemoveEntry(catal->sgml, value,
- (xmlHashDeallocator) xmlFreeCatalogEntry);
- if (res == 0)
- res = 1;
- }
- return(res);
-}
-
-/**
- * xmlNewCatalog:
- * @sgml: should this create an SGML catalog
- *
- * create a new Catalog.
- *
- * Returns the xmlCatalogPtr or NULL in case of error
- */
-xmlCatalogPtr
-xmlNewCatalog(int sgml) {
- xmlCatalogPtr catal = NULL;
-
- if (sgml) {
- catal = xmlCreateNewCatalog(XML_SGML_CATALOG_TYPE,
- xmlCatalogDefaultPrefer);
- if ((catal != NULL) && (catal->sgml == NULL))
- catal->sgml = xmlHashCreate(10);
- } else
- catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
- xmlCatalogDefaultPrefer);
- return(catal);
-}
-
-/**
- * xmlCatalogIsEmpty:
- * @catal: should this create an SGML catalog
- *
- * Check is a catalog is empty
- *
- * Returns 1 if the catalog is empty, 0 if not, amd -1 in case of error.
- */
-int
-xmlCatalogIsEmpty(xmlCatalogPtr catal) {
- if (catal == NULL)
- return(-1);
-
- if (catal->type == XML_XML_CATALOG_TYPE) {
- if (catal->xml == NULL)
- return(1);
- if ((catal->xml->type != XML_CATA_CATALOG) &&
- (catal->xml->type != XML_CATA_BROKEN_CATALOG))
- return(-1);
- if (catal->xml->children == NULL)
- return(1);
- return(0);
- } else {
- int res;
-
- if (catal->sgml == NULL)
- return(1);
- res = xmlHashSize(catal->sgml);
- if (res == 0)
- return(1);
- if (res < 0)
- return(-1);
- }
- return(0);
-}
-
-/************************************************************************
- * *
- * Public interfaces manipulating the global shared default catalog *
- * *
- ************************************************************************/
-
-/**
- * xmlInitializeCatalogData:
- *
- * Do the catalog initialization only of global data, doesn't try to load
- * any catalog actually.
- * this function is not thread safe, catalog initialization should
- * preferably be done once at startup
- */
-static void
-xmlInitializeCatalogData(void) {
- if (xmlCatalogInitialized != 0)
- return;
-
- if (getenv("XML_DEBUG_CATALOG"))
- xmlDebugCatalogs = 1;
- xmlCatalogMutex = xmlNewRMutex();
-
- xmlCatalogInitialized = 1;
-}
-/**
- * xmlInitializeCatalog:
- *
- * Do the catalog initialization.
- * this function is not thread safe, catalog initialization should
- * preferably be done once at startup
- */
-void
-xmlInitializeCatalog(void) {
- if (xmlCatalogInitialized != 0)
- return;
-
- xmlInitializeCatalogData();
- xmlRMutexLock(xmlCatalogMutex);
-
- if (getenv("XML_DEBUG_CATALOG"))
- xmlDebugCatalogs = 1;
-
- if (xmlDefaultCatalog == NULL) {
- const char *catalogs;
- char *path;
- const char *cur, *paths;
- xmlCatalogPtr catal;
- xmlCatalogEntryPtr *nextent;
-
- catalogs = (const char *) getenv("XML_CATALOG_FILES");
- if (catalogs == NULL)
- catalogs = XML_XML_DEFAULT_CATALOG;
-
- catal = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
- xmlCatalogDefaultPrefer);
- if (catal != NULL) {
- /* the XML_CATALOG_FILES envvar is allowed to contain a
- space-separated list of entries. */
- cur = catalogs;
- nextent = &catal->xml;
- while (*cur != '\0') {
- while (IS_BLANK(*cur))
- cur++;
- if (*cur != 0) {
- paths = cur;
- while ((*cur != 0) && (!IS_BLANK(*cur)))
- cur++;
- path = (char *) xmlStrndup((const xmlChar *)paths, cur - paths);
- if (path != NULL) {
- *nextent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
- NULL, BAD_CAST path, xmlCatalogDefaultPrefer);
- if (*nextent != NULL)
- nextent = &((*nextent)->next);
- xmlFree(path);
- }
- }
- }
- xmlDefaultCatalog = catal;
- }
- }
-
- xmlRMutexUnlock(xmlCatalogMutex);
-}
-
-
-/**
- * xmlLoadCatalog:
- * @filename: a file path
- *
- * Load the catalog and makes its definitions effective for the default
- * external entity loader. It will recurse in SGML CATALOG entries.
- * this function is not thread safe, catalog initialization should
- * preferably be done once at startup
- *
- * Returns 0 in case of success -1 in case of error
- */
-int
-xmlLoadCatalog(const char *filename)
-{
- int ret;
- xmlCatalogPtr catal;
-
- if (!xmlCatalogInitialized)
- xmlInitializeCatalogData();
-
- xmlRMutexLock(xmlCatalogMutex);
-
- if (xmlDefaultCatalog == NULL) {
- catal = xmlLoadACatalog(filename);
- if (catal == NULL)
- return(-1);
-
- xmlDefaultCatalog = catal;
- xmlRMutexUnlock(xmlCatalogMutex);
- return(0);
- }
-
- ret = xmlExpandCatalog(xmlDefaultCatalog, filename);
- xmlRMutexUnlock(xmlCatalogMutex);
- return(ret);
-}
-
-/**
- * xmlLoadCatalogs:
- * @pathss: a list of directories separated by a colon or a space.
- *
- * Load the catalogs and makes their definitions effective for the default
- * external entity loader.
- * this function is not thread safe, catalog initialization should
- * preferably be done once at startup
- */
-void
-xmlLoadCatalogs(const char *pathss) {
- const char *cur;
- const char *paths;
- xmlChar *path;
-
- if (pathss == NULL)
- return;
-
- cur = pathss;
- while ((cur != NULL) && (*cur != 0)) {
- while (IS_BLANK(*cur)) cur++;
- if (*cur != 0) {
- paths = cur;
- while ((*cur != 0) && (*cur != ':') && (!IS_BLANK(*cur)))
- cur++;
- path = xmlStrndup((const xmlChar *)paths, cur - paths);
- if (path != NULL) {
- xmlLoadCatalog((const char *) path);
- xmlFree(path);
- }
- }
- while (*cur == ':')
- cur++;
- }
-}
-
-/**
- * xmlCatalogCleanup:
- *
- * Free up all the memory associated with catalogs
- */
-void
-xmlCatalogCleanup(void) {
- if (xmlCatalogInitialized == 0)
- return;
-
- xmlRMutexLock(xmlCatalogMutex);
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Catalogs cleanup\n");
- if (xmlCatalogXMLFiles != NULL)
- xmlHashFree(xmlCatalogXMLFiles,
- (xmlHashDeallocator)xmlFreeCatalogHashEntryList);
- xmlCatalogXMLFiles = NULL;
- if (xmlDefaultCatalog != NULL)
- xmlFreeCatalog(xmlDefaultCatalog);
- xmlDefaultCatalog = NULL;
- xmlDebugCatalogs = 0;
- xmlCatalogInitialized = 0;
- xmlRMutexUnlock(xmlCatalogMutex);
- xmlFreeRMutex(xmlCatalogMutex);
-}
-
-/**
- * xmlCatalogResolveSystem:
- * @sysID: the public ID string
- *
- * Try to lookup the catalog resource for a system ID
- *
- * Returns the system ID if found or NULL otherwise, the value returned
- * must be freed by the caller.
- */
-xmlChar *
-xmlCatalogResolveSystem(const xmlChar *sysID) {
- xmlChar *ret;
-
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
-
- ret = xmlACatalogResolveSystem(xmlDefaultCatalog, sysID);
- return(ret);
-}
-
-/**
- * xmlCatalogResolvePublic:
- * @pubID: the public ID string
- *
- * Try to lookup the system ID associated to a public ID
- *
- * Returns the system ID if found or NULL otherwise, the value returned
- * must be freed by the caller.
- */
-xmlChar *
-xmlCatalogResolvePublic(const xmlChar *pubID) {
- xmlChar *ret;
-
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
-
- ret = xmlACatalogResolvePublic(xmlDefaultCatalog, pubID);
- return(ret);
-}
-
-/**
- * xmlCatalogResolve:
- * @pubID: the public ID string
- * @sysID: the system ID string
- *
- * Do a complete resolution lookup of an External Identifier
- *
- * Returns the URI of the resource or NULL if not found, it must be freed
- * by the caller.
- */
-xmlChar *
-xmlCatalogResolve(const xmlChar *pubID, const xmlChar *sysID) {
- xmlChar *ret;
-
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
-
- ret = xmlACatalogResolve(xmlDefaultCatalog, pubID, sysID);
- return(ret);
-}
-
-/**
- * xmlCatalogResolveURI:
- * @URI: the URI
- *
- * Do a complete resolution lookup of an URI
- *
- * Returns the URI of the resource or NULL if not found, it must be freed
- * by the caller.
- */
-xmlChar *
-xmlCatalogResolveURI(const xmlChar *URI) {
- xmlChar *ret;
-
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
-
- ret = xmlACatalogResolveURI(xmlDefaultCatalog, URI);
- return(ret);
-}
-
-/**
- * xmlCatalogDump:
- * @out: the file.
- *
- * Free up all the memory associated with catalogs
- */
-void
-xmlCatalogDump(FILE *out) {
- if (out == NULL)
- return;
-
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
-
- xmlACatalogDump(xmlDefaultCatalog, out);
-}
-
-/**
- * xmlCatalogAdd:
- * @type: the type of record to add to the catalog
- * @orig: the system, public or prefix to match
- * @replace: the replacement value for the match
- *
- * Add an entry in the catalog, it may overwrite existing but
- * different entries.
- * If called before any other catalog routine, allows to override the
- * default shared catalog put in place by xmlInitializeCatalog();
- *
- * Returns 0 if successful, -1 otherwise
- */
-int
-xmlCatalogAdd(const xmlChar *type, const xmlChar *orig, const xmlChar *replace) {
- int res = -1;
-
- if (!xmlCatalogInitialized)
- xmlInitializeCatalogData();
-
- xmlRMutexLock(xmlCatalogMutex);
- /*
- * Specific case where one want to override the default catalog
- * put in place by xmlInitializeCatalog();
- */
- if ((xmlDefaultCatalog == NULL) &&
- (xmlStrEqual(type, BAD_CAST "catalog"))) {
- xmlDefaultCatalog = xmlCreateNewCatalog(XML_XML_CATALOG_TYPE,
- xmlCatalogDefaultPrefer);
- xmlDefaultCatalog->xml = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,
- orig, NULL, xmlCatalogDefaultPrefer);
-
- xmlRMutexUnlock(xmlCatalogMutex);
- return(0);
- }
-
- res = xmlACatalogAdd(xmlDefaultCatalog, type, orig, replace);
- xmlRMutexUnlock(xmlCatalogMutex);
- return(res);
-}
-
-/**
- * xmlCatalogRemove:
- * @value: the value to remove
- *
- * Remove an entry from the catalog
- *
- * Returns the number of entries removed if successful, -1 otherwise
- */
-int
-xmlCatalogRemove(const xmlChar *value) {
- int res;
-
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
-
- xmlRMutexLock(xmlCatalogMutex);
- res = xmlACatalogRemove(xmlDefaultCatalog, value);
- xmlRMutexUnlock(xmlCatalogMutex);
- return(res);
-}
-
-/**
- * xmlCatalogConvert:
- *
- * Convert all the SGML catalog entries as XML ones
- *
- * Returns the number of entries converted if successful, -1 otherwise
- */
-int
-xmlCatalogConvert(void) {
- int res = -1;
-
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
-
- xmlRMutexLock(xmlCatalogMutex);
- res = xmlConvertSGMLCatalog(xmlDefaultCatalog);
- xmlRMutexUnlock(xmlCatalogMutex);
- return(res);
-}
-
-/************************************************************************
- * *
- * Public interface manipulating the common preferences *
- * *
- ************************************************************************/
-
-/**
- * xmlCatalogGetDefaults:
- *
- * Used to get the user preference w.r.t. to what catalogs should
- * be accepted
- *
- * Returns the current xmlCatalogAllow value
- */
-xmlCatalogAllow
-xmlCatalogGetDefaults(void) {
- return(xmlCatalogDefaultAllow);
-}
-
-/**
- * xmlCatalogSetDefaults:
- * @allow: what catalogs should be accepted
- *
- * Used to set the user preference w.r.t. to what catalogs should
- * be accepted
- */
-void
-xmlCatalogSetDefaults(xmlCatalogAllow allow) {
- if (xmlDebugCatalogs) {
- switch (allow) {
- case XML_CATA_ALLOW_NONE:
- xmlGenericError(xmlGenericErrorContext,
- "Disabling catalog usage\n");
- break;
- case XML_CATA_ALLOW_GLOBAL:
- xmlGenericError(xmlGenericErrorContext,
- "Allowing only global catalogs\n");
- break;
- case XML_CATA_ALLOW_DOCUMENT:
- xmlGenericError(xmlGenericErrorContext,
- "Allowing only catalogs from the document\n");
- break;
- case XML_CATA_ALLOW_ALL:
- xmlGenericError(xmlGenericErrorContext,
- "Allowing all catalogs\n");
- break;
- }
- }
- xmlCatalogDefaultAllow = allow;
-}
-
-/**
- * xmlCatalogSetDefaultPrefer:
- * @prefer: the default preference for delegation
- *
- * Allows to set the preference between public and system for deletion
- * in XML Catalog resolution. C.f. section 4.1.1 of the spec
- * Values accepted are XML_CATA_PREFER_PUBLIC or XML_CATA_PREFER_SYSTEM
- *
- * Returns the previous value of the default preference for delegation
- */
-xmlCatalogPrefer
-xmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer) {
- xmlCatalogPrefer ret = xmlCatalogDefaultPrefer;
-
- if (prefer == XML_CATA_PREFER_NONE)
- return(ret);
-
- if (xmlDebugCatalogs) {
- switch (prefer) {
- case XML_CATA_PREFER_PUBLIC:
- xmlGenericError(xmlGenericErrorContext,
- "Setting catalog preference to PUBLIC\n");
- break;
- case XML_CATA_PREFER_SYSTEM:
- xmlGenericError(xmlGenericErrorContext,
- "Setting catalog preference to SYSTEM\n");
- break;
- case XML_CATA_PREFER_NONE:
- break;
- }
- }
- xmlCatalogDefaultPrefer = prefer;
- return(ret);
-}
-
-/**
- * xmlCatalogSetDebug:
- * @level: the debug level of catalogs required
- *
- * Used to set the debug level for catalog operation, 0 disable
- * debugging, 1 enable it
- *
- * Returns the previous value of the catalog debugging level
- */
-int
-xmlCatalogSetDebug(int level) {
- int ret = xmlDebugCatalogs;
-
- if (level <= 0)
- xmlDebugCatalogs = 0;
- else
- xmlDebugCatalogs = level;
- return(ret);
-}
-
-/************************************************************************
- * *
- * Minimal interfaces used for per-document catalogs by the parser *
- * *
- ************************************************************************/
-
-/**
- * xmlCatalogFreeLocal:
- * @catalogs: a document's list of catalogs
- *
- * Free up the memory associated to the catalog list
- */
-void
-xmlCatalogFreeLocal(void *catalogs) {
- xmlCatalogEntryPtr catal;
-
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
-
- catal = (xmlCatalogEntryPtr) catalogs;
- if (catal != NULL)
- xmlFreeCatalogEntryList(catal);
-}
-
-
-/**
- * xmlCatalogAddLocal:
- * @catalogs: a document's list of catalogs
- * @URL: the URL to a new local catalog
- *
- * Add the new entry to the catalog list
- *
- * Returns the updated list
- */
-void *
-xmlCatalogAddLocal(void *catalogs, const xmlChar *URL) {
- xmlCatalogEntryPtr catal, add;
-
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
-
- if (URL == NULL)
- return(catalogs);
-
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Adding document catalog %s\n", URL);
-
- add = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL, URL, NULL,
- xmlCatalogDefaultPrefer);
- if (add == NULL)
- return(catalogs);
-
- catal = (xmlCatalogEntryPtr) catalogs;
- if (catal == NULL)
- return((void *) add);
-
- while (catal->next != NULL)
- catal = catal->next;
- catal->next = add;
- return(catalogs);
-}
-
-/**
- * xmlCatalogLocalResolve:
- * @catalogs: a document's list of catalogs
- * @pubID: the public ID string
- * @sysID: the system ID string
- *
- * Do a complete resolution lookup of an External Identifier using a
- * document's private catalog list
- *
- * Returns the URI of the resource or NULL if not found, it must be freed
- * by the caller.
- */
-xmlChar *
-xmlCatalogLocalResolve(void *catalogs, const xmlChar *pubID,
- const xmlChar *sysID) {
- xmlCatalogEntryPtr catal;
- xmlChar *ret;
-
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
-
- if ((pubID == NULL) && (sysID == NULL))
- return(NULL);
-
- if (xmlDebugCatalogs) {
- if (pubID != NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Local resolve: pubID %s\n", pubID);
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "Local resolve: sysID %s\n", sysID);
- }
- }
-
- catal = (xmlCatalogEntryPtr) catalogs;
- if (catal == NULL)
- return(NULL);
- ret = xmlCatalogListXMLResolve(catal, pubID, sysID);
- if ((ret != NULL) && (ret != XML_CATAL_BREAK))
- return(ret);
- return(NULL);
-}
-
-/**
- * xmlCatalogLocalResolveURI:
- * @catalogs: a document's list of catalogs
- * @URI: the URI
- *
- * Do a complete resolution lookup of an URI using a
- * document's private catalog list
- *
- * Returns the URI of the resource or NULL if not found, it must be freed
- * by the caller.
- */
-xmlChar *
-xmlCatalogLocalResolveURI(void *catalogs, const xmlChar *URI) {
- xmlCatalogEntryPtr catal;
- xmlChar *ret;
-
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
-
- if (URI == NULL)
- return(NULL);
-
- if (xmlDebugCatalogs)
- xmlGenericError(xmlGenericErrorContext,
- "Resolve URI %s\n", URI);
-
- catal = (xmlCatalogEntryPtr) catalogs;
- if (catal == NULL)
- return(NULL);
- ret = xmlCatalogListXMLResolveURI(catal, URI);
- if ((ret != NULL) && (ret != XML_CATAL_BREAK))
- return(ret);
- return(NULL);
-}
-
-/************************************************************************
- * *
- * Deprecated interfaces *
- * *
- ************************************************************************/
-/**
- * xmlCatalogGetSystem:
- * @sysID: the system ID string
- *
- * Try to lookup the system ID associated to a public ID
- * DEPRECATED, use xmlCatalogResolveSystem()
- *
- * Returns the system ID if found or NULL otherwise.
- */
-const xmlChar *
-xmlCatalogGetSystem(const xmlChar *sysID) {
- xmlChar *ret;
- static xmlChar result[1000];
- static int msg = 0;
-
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
-
- if (msg == 0) {
- xmlGenericError(xmlGenericErrorContext,
- "Use of deprecated xmlCatalogGetSystem() call\n");
- msg++;
- }
-
- if (sysID == NULL)
- return(NULL);
-
- /*
- * Check first the XML catalogs
- */
- if (xmlDefaultCatalog != NULL) {
- ret = xmlCatalogListXMLResolve(xmlDefaultCatalog->xml, NULL, sysID);
- if ((ret != NULL) && (ret != XML_CATAL_BREAK)) {
- snprintf((char *) result, sizeof(result) - 1, "%s", (char *) ret);
- result[sizeof(result) - 1] = 0;
- return(result);
- }
- }
-
- if (xmlDefaultCatalog != NULL)
- return(xmlCatalogGetSGMLSystem(xmlDefaultCatalog->sgml, sysID));
- return(NULL);
-}
-
-/**
- * xmlCatalogGetPublic:
- * @pubID: the public ID string
- *
- * Try to lookup the system ID associated to a public ID
- * DEPRECATED, use xmlCatalogResolvePublic()
- *
- * Returns the system ID if found or NULL otherwise.
- */
-const xmlChar *
-xmlCatalogGetPublic(const xmlChar *pubID) {
- xmlChar *ret;
- static xmlChar result[1000];
- static int msg = 0;
-
- if (!xmlCatalogInitialized)
- xmlInitializeCatalog();
-
- if (msg == 0) {
- xmlGenericError(xmlGenericErrorContext,
- "Use of deprecated xmlCatalogGetPublic() call\n");
- msg++;
- }
-
- if (pubID == NULL)
- return(NULL);
-
- /*
- * Check first the XML catalogs
- */
- if (xmlDefaultCatalog != NULL) {
- ret = xmlCatalogListXMLResolve(xmlDefaultCatalog->xml, pubID, NULL);
- if ((ret != NULL) && (ret != XML_CATAL_BREAK)) {
- snprintf((char *) result, sizeof(result) - 1, "%s", (char *) ret);
- result[sizeof(result) - 1] = 0;
- return(result);
- }
- }
-
- if (xmlDefaultCatalog != NULL)
- return(xmlCatalogGetSGMLPublic(xmlDefaultCatalog->sgml, pubID));
- return(NULL);
-}
-
-#endif /* LIBXML_CATALOG_ENABLED */
diff --git a/bundle/libxml/config.m4 b/bundle/libxml/config.m4
deleted file mode 100644
index 4faadda0ac..0000000000
--- a/bundle/libxml/config.m4
+++ /dev/null
@@ -1,80 +0,0 @@
-dnl
-dnl $Id$
-dnl
-
-PHP_ARG_BUNDLE(bundle-libxml, Whether to bundle the libxml2 library,
-[ --without-bundle-libxml Disable the bundled libxml2 library], yes)
-
-AC_DEFUN(PHP_LIBXML_CHECK_VERSION,[
- old_CPPFLAGS=$CPPFLAGS
- CPPFLAGS=-I$LIBXML_DIR/include$LIBXML_ADD
- AC_MSG_CHECKING(for libxml version)
- AC_EGREP_CPP(yes,[
-#include <libxml/xmlversion.h>
-#if LIBXML_VERSION >= 20414
- yes
-#endif
- ],[
- AC_MSG_RESULT(>= 2.4.14)
- ],[
- AC_MSG_ERROR(libxml version 2.4.14 or greater required.)
- ])
- CPPFLAGS=$old_CPPFLAGS
-])
-
-if test "$PHP_BUNDLE_LIBXML" = "yes"; then
- AC_DEFINE(HAVE_LIBXML, 1, [ ])
- AC_DEFINE(HAVE_LIBXML_BUNDLED, 1, [ ])
- PHP_ADD_SOURCES(bundle/libxml, DOCBparser.c encoding.c nanohttp.c valid.c xmlreader.c \
- HTMLparser.c entities.c parser.c threads.c xinclude.c xmlregexp.c \
- HTMLtree.c error.c parserInternals.c tree.c xlink.c xmlschemas.c \
- SAX.c globals.c trio.c xmlIO.c xmlschemastypes.c \
- c14n.c hash.c trionan.c xmlunicode.c debugXML.c \
- catalog.c list.c triostr.c xpath.c \
- nanoftp.c uri.c xmlmemory.c xpointer.c)
- PHP_ADD_INCLUDE(bundle/libxml/include/)
- PHP_ADD_INCLUDE(bundle/libxml/)
-elif test "$PHP_BUNDLE_LIBXML" != "no"; then
- for i in $PHP_BUNDLE_LIBXML; do
- if test -r $i/include/libxml/tree.h; then
- LIBXML_DIR=$i
- elif test -r $i/include/libxml2/libxml/tree.h; then
- LIBXML_DIR=$i
- LIBXML_ADD="/libxml2"
- fi
- done
-
- if test -z "$LIBXML_DIR"; then
- AC_MSG_RESULT(not found)
- AC_MSG_ERROR(Please reinstall the libxml >= 2.4.14 distribution)
- fi
-
- PHP_LIBXML_CHECK_VERSION
-
- if test -r $LIBXML_DIR/lib/libxml2.a -o -f $LIBXML_DIR/lib/libxml2.$SHLIB_SUFFIX_NAMEE; then
- LIBXML_LIBNAME=xml2
- else
- LIBXML_LIBNAME=xml
- fi
-
- XML2_CONFIG=$LIBXML_DIR/bin/xml2-config
-
- if test -x $XML2_CONFIG; then
- LIBXML_LIBS=`$XML2_CONFIG --libs`
- PHP_EVAL_LIBLINE($LIBXML_LIBS, LIBXML_SHARED_LIBADD)
- else
- PHP_ADD_LIBRARY_WITH_PATH($LIBXML_LIBNAME, $LIBXML_DIR/lib, LIBXML_SHARED_LIBADD)
- fi
-
- PHP_ADD_INCLUDE($LIBXML_DIR/include$LIBXML_ADD)
-
- if test "$PHP_ZLIB_DIR" = "no"; then
- AC_MSG_ERROR(libxml requires zlib. Use --with-zlib-dir=<DIR>)
- else
- PHP_ADD_LIBRARY_WITH_PATH(z, $PHP_ZLIB_DIR/lib, LIBXML_SHARED_LIBADD)
- fi
-
- AC_DEFINE(HAVE_LIBXML, 1, [ ])
- PHP_SUBST(LIBXML_SHARED_LIBADD)
-fi
-
diff --git a/bundle/libxml/debugXML.c b/bundle/libxml/debugXML.c
deleted file mode 100644
index 07a016861a..0000000000
--- a/bundle/libxml/debugXML.c
+++ /dev/null
@@ -1,2480 +0,0 @@
-/*
- * debugXML.c : This is a set of routines used for debugging the tree
- * produced by the XML parser.
- *
- * See Copyright for the status of this software.
- *
- * Daniel Veillard <daniel@veillard.com>
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-#ifdef LIBXML_DEBUG_ENABLED
-
-#include <string.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#include <libxml/xmlmemory.h>
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/parserInternals.h>
-#include <libxml/valid.h>
-#include <libxml/debugXML.h>
-#include <libxml/HTMLtree.h>
-#include <libxml/HTMLparser.h>
-#include <libxml/xmlerror.h>
-#include <libxml/globals.h>
-#include <libxml/xpathInternals.h>
-
-/**
- * xmlDebugDumpString:
- * @output: the FILE * for the output
- * @str: the string
- *
- * Dumps informations about the string, shorten it if necessary
- */
-void
-xmlDebugDumpString(FILE * output, const xmlChar * str)
-{
- int i;
-
- if (output == NULL)
- output = stdout;
- if (str == NULL) {
- fprintf(output, "(NULL)");
- return;
- }
- for (i = 0; i < 40; i++)
- if (str[i] == 0)
- return;
- else if (IS_BLANK(str[i]))
- fputc(' ', output);
- else if (str[i] >= 0x80)
- fprintf(output, "#%X", str[i]);
- else
- fputc(str[i], output);
- fprintf(output, "...");
-}
-
-static void
-xmlDebugDumpDtdNode(FILE *output, xmlDtdPtr dtd, int depth) {
- int i;
- char shift[100];
-
- for (i = 0;((i < depth) && (i < 25));i++)
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i] = shift[2 * i + 1] = 0;
-
- fprintf(output, shift);
-
- if (dtd == NULL) {
- fprintf(output, "DTD node is NULL\n");
- return;
- }
-
- if (dtd->type != XML_DTD_NODE) {
- fprintf(output, "PBM: not a DTD\n");
- return;
- }
- if (dtd->name != NULL)
- fprintf(output, "DTD(%s)", dtd->name);
- else
- fprintf(output, "DTD");
- if (dtd->ExternalID != NULL)
- fprintf(output, ", PUBLIC %s", dtd->ExternalID);
- if (dtd->SystemID != NULL)
- fprintf(output, ", SYSTEM %s", dtd->SystemID);
- fprintf(output, "\n");
- /*
- * Do a bit of checking
- */
- if (dtd->parent == NULL)
- fprintf(output, "PBM: DTD has no parent\n");
- if (dtd->doc == NULL)
- fprintf(output, "PBM: DTD has no doc\n");
- if ((dtd->parent != NULL) && (dtd->doc != dtd->parent->doc))
- fprintf(output, "PBM: DTD doc differs from parent's one\n");
- if (dtd->prev == NULL) {
- if ((dtd->parent != NULL) && (dtd->parent->children != (xmlNodePtr)dtd))
- fprintf(output, "PBM: DTD has no prev and not first of list\n");
- } else {
- if (dtd->prev->next != (xmlNodePtr) dtd)
- fprintf(output, "PBM: DTD prev->next : back link wrong\n");
- }
- if (dtd->next == NULL) {
- if ((dtd->parent != NULL) && (dtd->parent->last != (xmlNodePtr) dtd))
- fprintf(output, "PBM: DTD has no next and not last of list\n");
- } else {
- if (dtd->next->prev != (xmlNodePtr) dtd)
- fprintf(output, "PBM: DTD next->prev : forward link wrong\n");
- }
-}
-
-static void
-xmlDebugDumpAttrDecl(FILE *output, xmlAttributePtr attr, int depth) {
- int i;
- char shift[100];
-
- for (i = 0;((i < depth) && (i < 25));i++)
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i] = shift[2 * i + 1] = 0;
-
- fprintf(output, shift);
-
- if (attr == NULL) {
- fprintf(output, "Attribute declaration is NULL\n");
- return;
- }
- if (attr->type != XML_ATTRIBUTE_DECL) {
- fprintf(output, "PBM: not a Attr\n");
- return;
- }
- if (attr->name != NULL)
- fprintf(output, "ATTRDECL(%s)", attr->name);
- else
- fprintf(output, "PBM ATTRDECL noname!!!");
- if (attr->elem != NULL)
- fprintf(output, " for %s", attr->elem);
- else
- fprintf(output, " PBM noelem!!!");
- switch (attr->atype) {
- case XML_ATTRIBUTE_CDATA:
- fprintf(output, " CDATA");
- break;
- case XML_ATTRIBUTE_ID:
- fprintf(output, " ID");
- break;
- case XML_ATTRIBUTE_IDREF:
- fprintf(output, " IDREF");
- break;
- case XML_ATTRIBUTE_IDREFS:
- fprintf(output, " IDREFS");
- break;
- case XML_ATTRIBUTE_ENTITY:
- fprintf(output, " ENTITY");
- break;
- case XML_ATTRIBUTE_ENTITIES:
- fprintf(output, " ENTITIES");
- break;
- case XML_ATTRIBUTE_NMTOKEN:
- fprintf(output, " NMTOKEN");
- break;
- case XML_ATTRIBUTE_NMTOKENS:
- fprintf(output, " NMTOKENS");
- break;
- case XML_ATTRIBUTE_ENUMERATION:
- fprintf(output, " ENUMERATION");
- break;
- case XML_ATTRIBUTE_NOTATION:
- fprintf(output, " NOTATION ");
- break;
- }
- if (attr->tree != NULL) {
- int indx;
- xmlEnumerationPtr cur = attr->tree;
-
- for (indx = 0;indx < 5; indx++) {
- if (indx != 0)
- fprintf(output, "|%s", cur->name);
- else
- fprintf(output, " (%s", cur->name);
- cur = cur->next;
- if (cur == NULL) break;
- }
- if (cur == NULL)
- fprintf(output, ")");
- else
- fprintf(output, "...)");
- }
- switch (attr->def) {
- case XML_ATTRIBUTE_NONE:
- break;
- case XML_ATTRIBUTE_REQUIRED:
- fprintf(output, " REQUIRED");
- break;
- case XML_ATTRIBUTE_IMPLIED:
- fprintf(output, " IMPLIED");
- break;
- case XML_ATTRIBUTE_FIXED:
- fprintf(output, " FIXED");
- break;
- }
- if (attr->defaultValue != NULL) {
- fprintf(output, "\"");
- xmlDebugDumpString(output, attr->defaultValue);
- fprintf(output, "\"");
- }
- fprintf(output, "\n");
-
- /*
- * Do a bit of checking
- */
- if (attr->parent == NULL)
- fprintf(output, "PBM: Attr has no parent\n");
- if (attr->doc == NULL)
- fprintf(output, "PBM: Attr has no doc\n");
- if ((attr->parent != NULL) && (attr->doc != attr->parent->doc))
- fprintf(output, "PBM: Attr doc differs from parent's one\n");
- if (attr->prev == NULL) {
- if ((attr->parent != NULL) && (attr->parent->children != (xmlNodePtr)attr))
- fprintf(output, "PBM: Attr has no prev and not first of list\n");
- } else {
- if (attr->prev->next != (xmlNodePtr) attr)
- fprintf(output, "PBM: Attr prev->next : back link wrong\n");
- }
- if (attr->next == NULL) {
- if ((attr->parent != NULL) && (attr->parent->last != (xmlNodePtr) attr))
- fprintf(output, "PBM: Attr has no next and not last of list\n");
- } else {
- if (attr->next->prev != (xmlNodePtr) attr)
- fprintf(output, "PBM: Attr next->prev : forward link wrong\n");
- }
-}
-
-static void
-xmlDebugDumpElemDecl(FILE *output, xmlElementPtr elem, int depth) {
- int i;
- char shift[100];
-
- for (i = 0;((i < depth) && (i < 25));i++)
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i] = shift[2 * i + 1] = 0;
-
- fprintf(output, shift);
-
- if (elem == NULL) {
- fprintf(output, "Element declaration is NULL\n");
- return;
- }
- if (elem->type != XML_ELEMENT_DECL) {
- fprintf(output, "PBM: not a Elem\n");
- return;
- }
- if (elem->name != NULL) {
- fprintf(output, "ELEMDECL(");
- xmlDebugDumpString(output, elem->name);
- fprintf(output, ")");
- } else
- fprintf(output, "PBM ELEMDECL noname!!!");
- switch (elem->etype) {
- case XML_ELEMENT_TYPE_UNDEFINED:
- fprintf(output, ", UNDEFINED");
- break;
- case XML_ELEMENT_TYPE_EMPTY:
- fprintf(output, ", EMPTY");
- break;
- case XML_ELEMENT_TYPE_ANY:
- fprintf(output, ", ANY");
- break;
- case XML_ELEMENT_TYPE_MIXED:
- fprintf(output, ", MIXED ");
- break;
- case XML_ELEMENT_TYPE_ELEMENT:
- fprintf(output, ", MIXED ");
- break;
- }
- if ((elem->type != XML_ELEMENT_NODE) &&
- (elem->content != NULL)) {
- char buf[5001];
-
- buf[0] = 0;
- xmlSnprintfElementContent(buf, 5000, elem->content, 1);
- buf[5000] = 0;
- fprintf(output, "%s", buf);
- }
- fprintf(output, "\n");
-
- /*
- * Do a bit of checking
- */
- if (elem->parent == NULL)
- fprintf(output, "PBM: Elem has no parent\n");
- if (elem->doc == NULL)
- fprintf(output, "PBM: Elem has no doc\n");
- if ((elem->parent != NULL) && (elem->doc != elem->parent->doc))
- fprintf(output, "PBM: Elem doc differs from parent's one\n");
- if (elem->prev == NULL) {
- if ((elem->parent != NULL) && (elem->parent->children != (xmlNodePtr)elem))
- fprintf(output, "PBM: Elem has no prev and not first of list\n");
- } else {
- if (elem->prev->next != (xmlNodePtr) elem)
- fprintf(output, "PBM: Elem prev->next : back link wrong\n");
- }
- if (elem->next == NULL) {
- if ((elem->parent != NULL) && (elem->parent->last != (xmlNodePtr) elem))
- fprintf(output, "PBM: Elem has no next and not last of list\n");
- } else {
- if (elem->next->prev != (xmlNodePtr) elem)
- fprintf(output, "PBM: Elem next->prev : forward link wrong\n");
- }
-}
-
-static void
-xmlDebugDumpEntityDecl(FILE *output, xmlEntityPtr ent, int depth) {
- int i;
- char shift[100];
-
- for (i = 0;((i < depth) && (i < 25));i++)
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i] = shift[2 * i + 1] = 0;
-
- fprintf(output, shift);
-
- if (ent == NULL) {
- fprintf(output, "Entity declaration is NULL\n");
- return;
- }
- if (ent->type != XML_ENTITY_DECL) {
- fprintf(output, "PBM: not a Entity decl\n");
- return;
- }
- if (ent->name != NULL) {
- fprintf(output, "ENTITYDECL(");
- xmlDebugDumpString(output, ent->name);
- fprintf(output, ")");
- } else
- fprintf(output, "PBM ENTITYDECL noname!!!");
- switch (ent->etype) {
- case XML_INTERNAL_GENERAL_ENTITY:
- fprintf(output, ", internal\n");
- break;
- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
- fprintf(output, ", external parsed\n");
- break;
- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
- fprintf(output, ", unparsed\n");
- break;
- case XML_INTERNAL_PARAMETER_ENTITY:
- fprintf(output, ", parameter\n");
- break;
- case XML_EXTERNAL_PARAMETER_ENTITY:
- fprintf(output, ", external parameter\n");
- break;
- case XML_INTERNAL_PREDEFINED_ENTITY:
- fprintf(output, ", predefined\n");
- break;
- }
- if (ent->ExternalID) {
- fprintf(output, shift);
- fprintf(output, " ExternalID=%s\n", ent->ExternalID);
- }
- if (ent->SystemID) {
- fprintf(output, shift);
- fprintf(output, " SystemID=%s\n", ent->SystemID);
- }
- if (ent->URI != NULL) {
- fprintf(output, shift);
- fprintf(output, " URI=%s\n", ent->URI);
- }
- if (ent->content) {
- fprintf(output, shift);
- fprintf(output, " content=");
- xmlDebugDumpString(output, ent->content);
- fprintf(output, "\n");
- }
-
- /*
- * Do a bit of checking
- */
- if (ent->parent == NULL)
- fprintf(output, "PBM: Ent has no parent\n");
- if (ent->doc == NULL)
- fprintf(output, "PBM: Ent has no doc\n");
- if ((ent->parent != NULL) && (ent->doc != ent->parent->doc))
- fprintf(output, "PBM: Ent doc differs from parent's one\n");
- if (ent->prev == NULL) {
- if ((ent->parent != NULL) && (ent->parent->children != (xmlNodePtr)ent))
- fprintf(output, "PBM: Ent has no prev and not first of list\n");
- } else {
- if (ent->prev->next != (xmlNodePtr) ent)
- fprintf(output, "PBM: Ent prev->next : back link wrong\n");
- }
- if (ent->next == NULL) {
- if ((ent->parent != NULL) && (ent->parent->last != (xmlNodePtr) ent))
- fprintf(output, "PBM: Ent has no next and not last of list\n");
- } else {
- if (ent->next->prev != (xmlNodePtr) ent)
- fprintf(output, "PBM: Ent next->prev : forward link wrong\n");
- }
-}
-
-static void
-xmlDebugDumpNamespace(FILE *output, xmlNsPtr ns, int depth) {
- int i;
- char shift[100];
-
- for (i = 0;((i < depth) && (i < 25));i++)
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i] = shift[2 * i + 1] = 0;
-
- fprintf(output, shift);
-
- if (ns == NULL) {
- fprintf(output, "namespace node is NULL\n");
- return;
- }
- if (ns->type != XML_NAMESPACE_DECL) {
- fprintf(output, "invalid namespace node %d\n", ns->type);
- return;
- }
- if (ns->href == NULL) {
- if (ns->prefix != NULL)
- fprintf(output, "incomplete namespace %s href=NULL\n", ns->prefix);
- else
- fprintf(output, "incomplete default namespace href=NULL\n");
- } else {
- if (ns->prefix != NULL)
- fprintf(output, "namespace %s href=", ns->prefix);
- else
- fprintf(output, "default namespace href=");
-
- xmlDebugDumpString(output, ns->href);
- fprintf(output, "\n");
- }
-}
-
-static void
-xmlDebugDumpNamespaceList(FILE *output, xmlNsPtr ns, int depth) {
- while (ns != NULL) {
- xmlDebugDumpNamespace(output, ns, depth);
- ns = ns->next;
- }
-}
-
-static void
-xmlDebugDumpEntity(FILE *output, xmlEntityPtr ent, int depth) {
- int i;
- char shift[100];
-
- for (i = 0;((i < depth) && (i < 25));i++)
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i] = shift[2 * i + 1] = 0;
-
- fprintf(output, shift);
-
- if (ent == NULL) {
- fprintf(output, "Entity is NULL\n");
- return;
- }
- switch (ent->etype) {
- case XML_INTERNAL_GENERAL_ENTITY:
- fprintf(output, "INTERNAL_GENERAL_ENTITY ");
- break;
- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
- fprintf(output, "EXTERNAL_GENERAL_PARSED_ENTITY ");
- break;
- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
- fprintf(output, "EXTERNAL_GENERAL_UNPARSED_ENTITY ");
- break;
- case XML_INTERNAL_PARAMETER_ENTITY:
- fprintf(output, "INTERNAL_PARAMETER_ENTITY ");
- break;
- case XML_EXTERNAL_PARAMETER_ENTITY:
- fprintf(output, "EXTERNAL_PARAMETER_ENTITY ");
- break;
- default:
- fprintf(output, "ENTITY_%d ! ", ent->etype);
- }
- fprintf(output, "%s\n", ent->name);
- if (ent->ExternalID) {
- fprintf(output, shift);
- fprintf(output, "ExternalID=%s\n", ent->ExternalID);
- }
- if (ent->SystemID) {
- fprintf(output, shift);
- fprintf(output, "SystemID=%s\n", ent->SystemID);
- }
- if (ent->URI) {
- fprintf(output, shift);
- fprintf(output, "URI=%s\n", ent->URI);
- }
- if (ent->content) {
- fprintf(output, shift);
- fprintf(output, "content=");
- xmlDebugDumpString(output, ent->content);
- fprintf(output, "\n");
- }
-}
-
-/**
- * xmlDebugDumpAttr:
- * @output: the FILE * for the output
- * @attr: the attribute
- * @depth: the indentation level.
- *
- * Dumps debug information for the attribute
- */
-void
-xmlDebugDumpAttr(FILE *output, xmlAttrPtr attr, int depth) {
- int i;
- char shift[100];
-
- for (i = 0;((i < depth) && (i < 25));i++)
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i] = shift[2 * i + 1] = 0;
-
- fprintf(output, shift);
-
- if (attr == NULL) {
- fprintf(output, "Attr is NULL");
- return;
- }
- fprintf(output, "ATTRIBUTE ");
- xmlDebugDumpString(output, attr->name);
- fprintf(output, "\n");
- if (attr->children != NULL)
- xmlDebugDumpNodeList(output, attr->children, depth + 1);
-
- /*
- * Do a bit of checking
- */
- if (attr->parent == NULL)
- fprintf(output, "PBM: Attr has no parent\n");
- if (attr->doc == NULL)
- fprintf(output, "PBM: Attr has no doc\n");
- if ((attr->parent != NULL) && (attr->doc != attr->parent->doc))
- fprintf(output, "PBM: Attr doc differs from parent's one\n");
- if (attr->prev == NULL) {
- if ((attr->parent != NULL) && (attr->parent->properties != attr))
- fprintf(output, "PBM: Attr has no prev and not first of list\n");
- } else {
- if (attr->prev->next != attr)
- fprintf(output, "PBM: Attr prev->next : back link wrong\n");
- }
- if (attr->next != NULL) {
- if (attr->next->prev != attr)
- fprintf(output, "PBM: Attr next->prev : forward link wrong\n");
- }
-}
-
-/**
- * xmlDebugDumpAttrList:
- * @output: the FILE * for the output
- * @attr: the attribute list
- * @depth: the indentation level.
- *
- * Dumps debug information for the attribute list
- */
-void
-xmlDebugDumpAttrList(FILE * output, xmlAttrPtr attr, int depth)
-{
- if (output == NULL)
- output = stdout;
- while (attr != NULL) {
- xmlDebugDumpAttr(output, attr, depth);
- attr = attr->next;
- }
-}
-
-/**
- * xmlDebugDumpOneNode:
- * @output: the FILE * for the output
- * @node: the node
- * @depth: the indentation level.
- *
- * Dumps debug information for the element node, it is not recursive
- */
-void
-xmlDebugDumpOneNode(FILE * output, xmlNodePtr node, int depth)
-{
- int i;
- char shift[100];
-
- if (output == NULL)
- output = stdout;
- for (i = 0; ((i < depth) && (i < 25)); i++)
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i] = shift[2 * i + 1] = 0;
-
- if (node == NULL) {
- fprintf(output, shift);
- fprintf(output, "node is NULL\n");
- return;
- }
- switch (node->type) {
- case XML_ELEMENT_NODE:
- fprintf(output, shift);
- fprintf(output, "ELEMENT ");
- if ((node->ns != NULL) && (node->ns->prefix != NULL)) {
- xmlDebugDumpString(output, node->ns->prefix);
- fprintf(output, ":");
- }
- xmlDebugDumpString(output, node->name);
- fprintf(output, "\n");
- break;
- case XML_ATTRIBUTE_NODE:
- fprintf(output, shift);
- fprintf(output, "Error, ATTRIBUTE found here\n");
- break;
- case XML_TEXT_NODE:
- fprintf(output, shift);
- if (node->name == (const xmlChar *) xmlStringTextNoenc)
- fprintf(output, "TEXT no enc\n");
- else
- fprintf(output, "TEXT\n");
- break;
- case XML_CDATA_SECTION_NODE:
- fprintf(output, shift);
- fprintf(output, "CDATA_SECTION\n");
- break;
- case XML_ENTITY_REF_NODE:
- fprintf(output, shift);
- fprintf(output, "ENTITY_REF(%s)\n", node->name);
- break;
- case XML_ENTITY_NODE:
- fprintf(output, shift);
- fprintf(output, "ENTITY\n");
- break;
- case XML_PI_NODE:
- fprintf(output, shift);
- fprintf(output, "PI %s\n", node->name);
- break;
- case XML_COMMENT_NODE:
- fprintf(output, shift);
- fprintf(output, "COMMENT\n");
- break;
- case XML_DOCUMENT_NODE:
- case XML_HTML_DOCUMENT_NODE:
- fprintf(output, shift);
- fprintf(output, "Error, DOCUMENT found here\n");
- break;
- case XML_DOCUMENT_TYPE_NODE:
- fprintf(output, shift);
- fprintf(output, "DOCUMENT_TYPE\n");
- break;
- case XML_DOCUMENT_FRAG_NODE:
- fprintf(output, shift);
- fprintf(output, "DOCUMENT_FRAG\n");
- break;
- case XML_NOTATION_NODE:
- fprintf(output, shift);
- fprintf(output, "NOTATION\n");
- break;
- case XML_DTD_NODE:
- xmlDebugDumpDtdNode(output, (xmlDtdPtr) node, depth);
- return;
- case XML_ELEMENT_DECL:
- xmlDebugDumpElemDecl(output, (xmlElementPtr) node, depth);
- return;
- case XML_ATTRIBUTE_DECL:
- xmlDebugDumpAttrDecl(output, (xmlAttributePtr) node, depth);
- return;
- case XML_ENTITY_DECL:
- xmlDebugDumpEntityDecl(output, (xmlEntityPtr) node, depth);
- return;
- case XML_NAMESPACE_DECL:
- xmlDebugDumpNamespace(output, (xmlNsPtr) node, depth);
- return;
- case XML_XINCLUDE_START:
- fprintf(output, shift);
- fprintf(output, "INCLUDE START\n");
- return;
- case XML_XINCLUDE_END:
- fprintf(output, shift);
- fprintf(output, "INCLUDE END\n");
- return;
- default:
- fprintf(output, shift);
- fprintf(output, "NODE_%d !!!\n", node->type);
- return;
- }
- if (node->doc == NULL) {
- fprintf(output, shift);
- fprintf(output, "doc == NULL !!!\n");
- }
- if (node->nsDef != NULL)
- xmlDebugDumpNamespaceList(output, node->nsDef, depth + 1);
- if (node->properties != NULL)
- xmlDebugDumpAttrList(output, node->properties, depth + 1);
- if (node->type != XML_ENTITY_REF_NODE) {
- if ((node->type != XML_ELEMENT_NODE) && (node->content != NULL)) {
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i + 2] = shift[2 * i + 3] = 0;
- fprintf(output, shift);
- fprintf(output, "content=");
- xmlDebugDumpString(output, node->content);
- fprintf(output, "\n");
- }
- } else {
- xmlEntityPtr ent;
-
- ent = xmlGetDocEntity(node->doc, node->name);
- if (ent != NULL)
- xmlDebugDumpEntity(output, ent, depth + 1);
- }
- /*
- * Do a bit of checking
- */
- if (node->parent == NULL)
- fprintf(output, "PBM: Node has no parent\n");
- if (node->doc == NULL)
- fprintf(output, "PBM: Node has no doc\n");
- if ((node->parent != NULL) && (node->doc != node->parent->doc))
- fprintf(output, "PBM: Node doc differs from parent's one\n");
- if (node->prev == NULL) {
- if ((node->parent != NULL) && (node->parent->children != node))
- fprintf(output,
- "PBM: Node has no prev and not first of list\n");
- } else {
- if (node->prev->next != node)
- fprintf(output, "PBM: Node prev->next : back link wrong\n");
- }
- if (node->next == NULL) {
- if ((node->parent != NULL) && (node->parent->last != node))
- fprintf(output,
- "PBM: Node has no next and not last of list\n");
- } else {
- if (node->next->prev != node)
- fprintf(output, "PBM: Node next->prev : forward link wrong\n");
- }
-}
-
-/**
- * xmlDebugDumpNode:
- * @output: the FILE * for the output
- * @node: the node
- * @depth: the indentation level.
- *
- * Dumps debug information for the element node, it is recursive
- */
-void
-xmlDebugDumpNode(FILE * output, xmlNodePtr node, int depth)
-{
- if (output == NULL)
- output = stdout;
- if (node == NULL) {
- int i;
- char shift[100];
-
- for (i = 0; ((i < depth) && (i < 25)); i++)
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i] = shift[2 * i + 1] = 0;
-
- fprintf(output, shift);
- fprintf(output, "node is NULL\n");
- return;
- }
- xmlDebugDumpOneNode(output, node, depth);
- if ((node->children != NULL) && (node->type != XML_ENTITY_REF_NODE))
- xmlDebugDumpNodeList(output, node->children, depth + 1);
-}
-
-/**
- * xmlDebugDumpNodeList:
- * @output: the FILE * for the output
- * @node: the node list
- * @depth: the indentation level.
- *
- * Dumps debug information for the list of element node, it is recursive
- */
-void
-xmlDebugDumpNodeList(FILE * output, xmlNodePtr node, int depth)
-{
- if (output == NULL)
- output = stdout;
- while (node != NULL) {
- xmlDebugDumpNode(output, node, depth);
- node = node->next;
- }
-}
-
-
-/**
- * xmlDebugDumpDocumentHead:
- * @output: the FILE * for the output
- * @doc: the document
- *
- * Dumps debug information cncerning the document, not recursive
- */
-void
-xmlDebugDumpDocumentHead(FILE * output, xmlDocPtr doc)
-{
- if (output == NULL)
- output = stdout;
- if (doc == NULL) {
- fprintf(output, "DOCUMENT == NULL !\n");
- return;
- }
-
- switch (doc->type) {
- case XML_ELEMENT_NODE:
- fprintf(output, "Error, ELEMENT found here ");
- break;
- case XML_ATTRIBUTE_NODE:
- fprintf(output, "Error, ATTRIBUTE found here\n");
- break;
- case XML_TEXT_NODE:
- fprintf(output, "Error, TEXT\n");
- break;
- case XML_CDATA_SECTION_NODE:
- fprintf(output, "Error, CDATA_SECTION\n");
- break;
- case XML_ENTITY_REF_NODE:
- fprintf(output, "Error, ENTITY_REF\n");
- break;
- case XML_ENTITY_NODE:
- fprintf(output, "Error, ENTITY\n");
- break;
- case XML_PI_NODE:
- fprintf(output, "Error, PI\n");
- break;
- case XML_COMMENT_NODE:
- fprintf(output, "Error, COMMENT\n");
- break;
- case XML_DOCUMENT_NODE:
- fprintf(output, "DOCUMENT\n");
- break;
- case XML_HTML_DOCUMENT_NODE:
- fprintf(output, "HTML DOCUMENT\n");
- break;
- case XML_DOCUMENT_TYPE_NODE:
- fprintf(output, "Error, DOCUMENT_TYPE\n");
- break;
- case XML_DOCUMENT_FRAG_NODE:
- fprintf(output, "Error, DOCUMENT_FRAG\n");
- break;
- case XML_NOTATION_NODE:
- fprintf(output, "Error, NOTATION\n");
- break;
- default:
- fprintf(output, "NODE_%d\n", doc->type);
- }
- if (doc->name != NULL) {
- fprintf(output, "name=");
- xmlDebugDumpString(output, BAD_CAST doc->name);
- fprintf(output, "\n");
- }
- if (doc->version != NULL) {
- fprintf(output, "version=");
- xmlDebugDumpString(output, doc->version);
- fprintf(output, "\n");
- }
- if (doc->encoding != NULL) {
- fprintf(output, "encoding=");
- xmlDebugDumpString(output, doc->encoding);
- fprintf(output, "\n");
- }
- if (doc->URL != NULL) {
- fprintf(output, "URL=");
- xmlDebugDumpString(output, doc->URL);
- fprintf(output, "\n");
- }
- if (doc->standalone)
- fprintf(output, "standalone=true\n");
- if (doc->oldNs != NULL)
- xmlDebugDumpNamespaceList(output, doc->oldNs, 0);
-}
-
-/**
- * xmlDebugDumpDocument:
- * @output: the FILE * for the output
- * @doc: the document
- *
- * Dumps debug information for the document, it's recursive
- */
-void
-xmlDebugDumpDocument(FILE * output, xmlDocPtr doc)
-{
- if (output == NULL)
- output = stdout;
- if (doc == NULL) {
- fprintf(output, "DOCUMENT == NULL !\n");
- return;
- }
- xmlDebugDumpDocumentHead(output, doc);
- if (((doc->type == XML_DOCUMENT_NODE) ||
- (doc->type == XML_HTML_DOCUMENT_NODE)) && (doc->children != NULL))
- xmlDebugDumpNodeList(output, doc->children, 1);
-}
-
-/**
- * xmlDebugDumpDTD:
- * @output: the FILE * for the output
- * @dtd: the DTD
- *
- * Dumps debug information for the DTD
- */
-void
-xmlDebugDumpDTD(FILE * output, xmlDtdPtr dtd)
-{
- if (output == NULL)
- output = stdout;
- if (dtd == NULL) {
- fprintf(output, "DTD is NULL\n");
- return;
- }
- if (dtd->type != XML_DTD_NODE) {
- fprintf(output, "PBM: not a DTD\n");
- return;
- }
- if (dtd->name != NULL)
- fprintf(output, "DTD(%s)", dtd->name);
- else
- fprintf(output, "DTD");
- if (dtd->ExternalID != NULL)
- fprintf(output, ", PUBLIC %s", dtd->ExternalID);
- if (dtd->SystemID != NULL)
- fprintf(output, ", SYSTEM %s", dtd->SystemID);
- fprintf(output, "\n");
- /*
- * Do a bit of checking
- */
- if ((dtd->parent != NULL) && (dtd->doc != dtd->parent->doc))
- fprintf(output, "PBM: DTD doc differs from parent's one\n");
- if (dtd->prev == NULL) {
- if ((dtd->parent != NULL)
- && (dtd->parent->children != (xmlNodePtr) dtd))
- fprintf(output,
- "PBM: DTD has no prev and not first of list\n");
- } else {
- if (dtd->prev->next != (xmlNodePtr) dtd)
- fprintf(output, "PBM: DTD prev->next : back link wrong\n");
- }
- if (dtd->next == NULL) {
- if ((dtd->parent != NULL)
- && (dtd->parent->last != (xmlNodePtr) dtd))
- fprintf(output, "PBM: DTD has no next and not last of list\n");
- } else {
- if (dtd->next->prev != (xmlNodePtr) dtd)
- fprintf(output, "PBM: DTD next->prev : forward link wrong\n");
- }
- if (dtd->children == NULL)
- fprintf(output, " DTD is empty\n");
- else
- xmlDebugDumpNodeList(output, dtd->children, 1);
-}
-
-static void
-xmlDebugDumpEntityCallback(xmlEntityPtr cur, FILE *output) {
- if (cur == NULL) {
- fprintf(output, "Entity is NULL");
- return;
- }
- fprintf(output, "%s : ", cur->name);
- switch (cur->etype) {
- case XML_INTERNAL_GENERAL_ENTITY:
- fprintf(output, "INTERNAL GENERAL, ");
- break;
- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
- fprintf(output, "EXTERNAL PARSED, ");
- break;
- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
- fprintf(output, "EXTERNAL UNPARSED, ");
- break;
- case XML_INTERNAL_PARAMETER_ENTITY:
- fprintf(output, "INTERNAL PARAMETER, ");
- break;
- case XML_EXTERNAL_PARAMETER_ENTITY:
- fprintf(output, "EXTERNAL PARAMETER, ");
- break;
- default:
- fprintf(output, "UNKNOWN TYPE %d",
- cur->etype);
- }
- if (cur->ExternalID != NULL)
- fprintf(output, "ID \"%s\"", cur->ExternalID);
- if (cur->SystemID != NULL)
- fprintf(output, "SYSTEM \"%s\"", cur->SystemID);
- if (cur->orig != NULL)
- fprintf(output, "\n orig \"%s\"", cur->orig);
- if ((cur->type != XML_ELEMENT_NODE) &&
- (cur->content != NULL))
- fprintf(output, "\n content \"%s\"", cur->content);
- fprintf(output, "\n");
-}
-
-/**
- * xmlDebugDumpEntities:
- * @output: the FILE * for the output
- * @doc: the document
- *
- * Dumps debug information for all the entities in use by the document
- */
-void
-xmlDebugDumpEntities(FILE * output, xmlDocPtr doc)
-{
- if (output == NULL)
- output = stdout;
- if (doc == NULL) {
- fprintf(output, "DOCUMENT == NULL !\n");
- return;
- }
-
- switch (doc->type) {
- case XML_ELEMENT_NODE:
- fprintf(output, "Error, ELEMENT found here ");
- break;
- case XML_ATTRIBUTE_NODE:
- fprintf(output, "Error, ATTRIBUTE found here\n");
- break;
- case XML_TEXT_NODE:
- fprintf(output, "Error, TEXT\n");
- break;
- case XML_CDATA_SECTION_NODE:
- fprintf(output, "Error, CDATA_SECTION\n");
- break;
- case XML_ENTITY_REF_NODE:
- fprintf(output, "Error, ENTITY_REF\n");
- break;
- case XML_ENTITY_NODE:
- fprintf(output, "Error, ENTITY\n");
- break;
- case XML_PI_NODE:
- fprintf(output, "Error, PI\n");
- break;
- case XML_COMMENT_NODE:
- fprintf(output, "Error, COMMENT\n");
- break;
- case XML_DOCUMENT_NODE:
- fprintf(output, "DOCUMENT\n");
- break;
- case XML_HTML_DOCUMENT_NODE:
- fprintf(output, "HTML DOCUMENT\n");
- break;
- case XML_DOCUMENT_TYPE_NODE:
- fprintf(output, "Error, DOCUMENT_TYPE\n");
- break;
- case XML_DOCUMENT_FRAG_NODE:
- fprintf(output, "Error, DOCUMENT_FRAG\n");
- break;
- case XML_NOTATION_NODE:
- fprintf(output, "Error, NOTATION\n");
- break;
- default:
- fprintf(output, "NODE_%d\n", doc->type);
- }
- if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
- xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
- doc->intSubset->entities;
-
- fprintf(output, "Entities in internal subset\n");
- xmlHashScan(table, (xmlHashScanner) xmlDebugDumpEntityCallback,
- output);
- } else
- fprintf(output, "No entities in internal subset\n");
- if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
- xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
- doc->extSubset->entities;
-
- fprintf(output, "Entities in external subset\n");
- xmlHashScan(table, (xmlHashScanner) xmlDebugDumpEntityCallback,
- output);
- } else
- fprintf(output, "No entities in external subset\n");
-}
-
-/**
- * xmlLsCountNode:
- * @node: the node to count
- *
- * Count the children of @node.
- *
- * Returns the number of children of @node.
- */
-int
-xmlLsCountNode(xmlNodePtr node) {
- int ret = 0;
- xmlNodePtr list = NULL;
-
- if (node == NULL)
- return(0);
-
- switch (node->type) {
- case XML_ELEMENT_NODE:
- list = node->children;
- break;
- case XML_DOCUMENT_NODE:
- case XML_HTML_DOCUMENT_NODE:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- list = ((xmlDocPtr) node)->children;
- break;
- case XML_ATTRIBUTE_NODE:
- list = ((xmlAttrPtr) node)->children;
- break;
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- if (node->content != NULL) {
- ret = xmlStrlen(node->content);
- }
- break;
- case XML_ENTITY_REF_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_ENTITY_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_NOTATION_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_NAMESPACE_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- ret = 1;
- break;
- }
- for (;list != NULL;ret++)
- list = list->next;
- return(ret);
-}
-
-/**
- * xmlLsOneNode:
- * @output: the FILE * for the output
- * @node: the node to dump
- *
- * Dump to @output the type and name of @node.
- */
-void
-xmlLsOneNode(FILE *output, xmlNodePtr node) {
- if (node == NULL) {
- fprintf(output, "NULL\n");
- return;
- }
- switch (node->type) {
- case XML_ELEMENT_NODE:
- fprintf(output, "-");
- break;
- case XML_ATTRIBUTE_NODE:
- fprintf(output, "a");
- break;
- case XML_TEXT_NODE:
- fprintf(output, "t");
- break;
- case XML_CDATA_SECTION_NODE:
- fprintf(output, "C");
- break;
- case XML_ENTITY_REF_NODE:
- fprintf(output, "e");
- break;
- case XML_ENTITY_NODE:
- fprintf(output, "E");
- break;
- case XML_PI_NODE:
- fprintf(output, "p");
- break;
- case XML_COMMENT_NODE:
- fprintf(output, "c");
- break;
- case XML_DOCUMENT_NODE:
- fprintf(output, "d");
- break;
- case XML_HTML_DOCUMENT_NODE:
- fprintf(output, "h");
- break;
- case XML_DOCUMENT_TYPE_NODE:
- fprintf(output, "T");
- break;
- case XML_DOCUMENT_FRAG_NODE:
- fprintf(output, "F");
- break;
- case XML_NOTATION_NODE:
- fprintf(output, "N");
- break;
- case XML_NAMESPACE_DECL:
- fprintf(output, "n");
- break;
- default:
- fprintf(output, "?");
- }
- if (node->type != XML_NAMESPACE_DECL) {
- if (node->properties != NULL)
- fprintf(output, "a");
- else
- fprintf(output, "-");
- if (node->nsDef != NULL)
- fprintf(output, "n");
- else
- fprintf(output, "-");
- }
-
- fprintf(output, " %8d ", xmlLsCountNode(node));
-
- switch (node->type) {
- case XML_ELEMENT_NODE:
- if (node->name != NULL)
- fprintf(output, "%s", node->name);
- break;
- case XML_ATTRIBUTE_NODE:
- if (node->name != NULL)
- fprintf(output, "%s", node->name);
- break;
- case XML_TEXT_NODE:
- if (node->content != NULL) {
- xmlDebugDumpString(output, node->content);
- }
- break;
- case XML_CDATA_SECTION_NODE:
- break;
- case XML_ENTITY_REF_NODE:
- if (node->name != NULL)
- fprintf(output, "%s", node->name);
- break;
- case XML_ENTITY_NODE:
- if (node->name != NULL)
- fprintf(output, "%s", node->name);
- break;
- case XML_PI_NODE:
- if (node->name != NULL)
- fprintf(output, "%s", node->name);
- break;
- case XML_COMMENT_NODE:
- break;
- case XML_DOCUMENT_NODE:
- break;
- case XML_HTML_DOCUMENT_NODE:
- break;
- case XML_DOCUMENT_TYPE_NODE:
- break;
- case XML_DOCUMENT_FRAG_NODE:
- break;
- case XML_NOTATION_NODE:
- break;
- case XML_NAMESPACE_DECL: {
- xmlNsPtr ns = (xmlNsPtr) node;
-
- if (ns->prefix == NULL)
- fprintf(output, "default -> %s", ns->href);
- else
- fprintf(output, "%s -> %s", ns->prefix, ns->href);
- break;
- }
- default:
- if (node->name != NULL)
- fprintf(output, "%s", node->name);
- }
- fprintf(output, "\n");
-}
-
-/**
- * xmlBoolToText:
- * @boolval: a bool to turn into text
- *
- * Convenient way to turn bool into text
- *
- * Returns a pointer to either "True" or "False"
- */
-const char *
-xmlBoolToText(int boolval)
-{
- if (boolval)
- return("True");
- else
- return("False");
-}
-
-/****************************************************************
- * *
- * The XML shell related functions *
- * *
- ****************************************************************/
-
-
-
-/*
- * TODO: Improvement/cleanups for the XML shell
- * - allow to shell out an editor on a subpart
- * - cleanup function registrations (with help) and calling
- * - provide registration routines
- */
-
-/**
- * xmlShellPrintXPathError:
- * @errorType: valid xpath error id
- * @arg: the argument that cause xpath to fail
- *
- * Print the xpath error to libxml default error channel
- */
-void
-xmlShellPrintXPathError(int errorType, const char *arg)
-{
- const char *default_arg = "Result";
-
- if (!arg)
- arg = default_arg;
-
- switch (errorType) {
- case XPATH_UNDEFINED:
- xmlGenericError(xmlGenericErrorContext,
- "%s: no such node\n", arg);
- break;
-
- case XPATH_BOOLEAN:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a Boolean\n", arg);
- break;
- case XPATH_NUMBER:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a number\n", arg);
- break;
- case XPATH_STRING:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a string\n", arg);
- break;
- case XPATH_POINT:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a point\n", arg);
- break;
- case XPATH_RANGE:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a range\n", arg);
- break;
- case XPATH_LOCATIONSET:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a range\n", arg);
- break;
- case XPATH_USERS:
- xmlGenericError(xmlGenericErrorContext,
- "%s is user-defined\n", arg);
- break;
- case XPATH_XSLT_TREE:
- xmlGenericError(xmlGenericErrorContext,
- "%s is an XSLT value tree\n", arg);
- break;
- }
- xmlGenericError(xmlGenericErrorContext,
- "Try casting the result string function (xpath builtin)\n",
- arg);
-}
-
-
-/**
- * xmlShellPrintNodeCtxt:
- * @ctxt : a non-null shell context
- * @node : a non-null node to print to the output FILE
- *
- * Print node to the output FILE
- */
-static void
-xmlShellPrintNodeCtxt(xmlShellCtxtPtr ctxt,xmlNodePtr node)
-{
- FILE *fp;
-
- if (!node)
- return;
- if (ctxt == NULL)
- fp = stdout;
- else
- fp = ctxt->output;
-
- if (node->type == XML_DOCUMENT_NODE)
- xmlDocDump(fp, (xmlDocPtr) node);
- else if (node->type == XML_ATTRIBUTE_NODE)
- xmlDebugDumpAttrList(fp, (xmlAttrPtr) node, 0);
- else
- xmlElemDump(fp, node->doc, node);
-
- fprintf(fp, "\n");
-}
-
-/**
- * xmlShellPrintNode:
- * @node : a non-null node to print to the output FILE
- *
- * Print node to the output FILE
- */
-void
-xmlShellPrintNode(xmlNodePtr node)
-{
- xmlShellPrintNodeCtxt(NULL, node);
-}
-
-/**
- * xmlShellPrintXPathResultCtxt:
- * @ctxt: a valid shell context
- * @list: a valid result generated by an xpath evaluation
- *
- * Prints result to the output FILE
- */
-static void
-xmlShellPrintXPathResultCtxt(xmlShellCtxtPtr ctxt,xmlXPathObjectPtr list)
-{
- int i = 0;
- if (!ctxt)
- return;
-
- if (list != NULL) {
- switch (list->type) {
- case XPATH_NODESET:{
- int indx;
-
- if (list->nodesetval) {
- for (indx = 0; indx < list->nodesetval->nodeNr;
- indx++) {
- if (i > 0)
- fprintf(stderr, " -------\n");
- xmlShellPrintNodeCtxt(ctxt,
- list->nodesetval->nodeTab[indx]);
- }
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "Empty node set\n");
- }
- break;
- }
- case XPATH_BOOLEAN:
- xmlGenericError(xmlGenericErrorContext,
- "Is a Boolean:%s\n",
- xmlBoolToText(list->boolval));
- break;
- case XPATH_NUMBER:
- xmlGenericError(xmlGenericErrorContext,
- "Is a number:%0g\n", list->floatval);
- break;
- case XPATH_STRING:
- xmlGenericError(xmlGenericErrorContext,
- "Is a string:%s\n", list->stringval);
- break;
-
- default:
- xmlShellPrintXPathError(list->type, NULL);
- }
- }
-}
-
-/**
- * xmlShellPrintXPathResult:
- * @list: a valid result generated by an xpath evaluation
- *
- * Prints result to the output FILE
- */
-void
-xmlShellPrintXPathResult(xmlXPathObjectPtr list)
-{
- xmlShellPrintXPathResultCtxt(NULL, list);
-}
-
-/**
- * xmlShellList:
- * @ctxt: the shell context
- * @arg: unused
- * @node: a node
- * @node2: unused
- *
- * Implements the XML shell function "ls"
- * Does an Unix like listing of the given node (like a directory)
- *
- * Returns 0
- */
-int
-xmlShellList(xmlShellCtxtPtr ctxt,
- char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
- xmlNodePtr node2 ATTRIBUTE_UNUSED)
-{
- xmlNodePtr cur;
- if (!ctxt)
- return (0);
- if (node == NULL) {
- fprintf(ctxt->output, "NULL\n");
- return (0);
- }
- if ((node->type == XML_DOCUMENT_NODE) ||
- (node->type == XML_HTML_DOCUMENT_NODE)) {
- cur = ((xmlDocPtr) node)->children;
- } else if (node->type == XML_NAMESPACE_DECL) {
- xmlLsOneNode(ctxt->output, node);
- return (0);
- } else if (node->children != NULL) {
- cur = node->children;
- } else {
- xmlLsOneNode(ctxt->output, node);
- return (0);
- }
- while (cur != NULL) {
- xmlLsOneNode(ctxt->output, cur);
- cur = cur->next;
- }
- return (0);
-}
-
-/**
- * xmlShellBase:
- * @ctxt: the shell context
- * @arg: unused
- * @node: a node
- * @node2: unused
- *
- * Implements the XML shell function "base"
- * dumps the current XML base of the node
- *
- * Returns 0
- */
-int
-xmlShellBase(xmlShellCtxtPtr ctxt,
- char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
- xmlNodePtr node2 ATTRIBUTE_UNUSED)
-{
- xmlChar *base;
- if (!ctxt)
- return 0;
- if (node == NULL) {
- fprintf(ctxt->output, "NULL\n");
- return (0);
- }
-
- base = xmlNodeGetBase(node->doc, node);
-
- if (base == NULL) {
- fprintf(ctxt->output, " No base found !!!\n");
- } else {
- fprintf(ctxt->output, "%s\n", base);
- xmlFree(base);
- }
- return (0);
-}
-
-/**
- * xmlShellSetBase:
- * @ctxt: the shell context
- * @arg: the new base
- * @node: a node
- * @node2: unused
- *
- * Implements the XML shell function "setbase"
- * change the current XML base of the node
- *
- * Returns 0
- */
-static int
-xmlShellSetBase(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
- char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
- xmlNodePtr node2 ATTRIBUTE_UNUSED)
-{
- xmlNodeSetBase(node, (xmlChar*) arg);
- return (0);
-}
-
-/**
- * xmlShellGrep:
- * @ctxt: the shell context
- * @arg: the string or regular expression to find
- * @node: a node
- * @node2: unused
- *
- * Implements the XML shell function "grep"
- * dumps informations about the node (namespace, attributes, content).
- *
- * Returns 0
- */
-static int
-xmlShellGrep(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
- char *arg, xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED)
-{
- if (!ctxt)
- return (0);
- if (node == NULL)
- return (0);
- if (arg == NULL)
- return (0);
-#ifdef LIBXML_REGEXP_ENABLED
- if ((xmlStrchr((xmlChar *) arg, '?')) ||
- (xmlStrchr((xmlChar *) arg, '*')) ||
- (xmlStrchr((xmlChar *) arg, '.')) ||
- (xmlStrchr((xmlChar *) arg, '['))) {
- }
-#endif
- while (node != NULL) {
- if (node->type == XML_COMMENT_NODE) {
- if (xmlStrstr(node->content, (xmlChar *) arg)) {
-
- fprintf(ctxt->output, "%s : ", xmlGetNodePath(node));
- xmlShellList(ctxt, NULL, node, NULL);
- }
- } else if (node->type == XML_TEXT_NODE) {
- if (xmlStrstr(node->content, (xmlChar *) arg)) {
-
- fprintf(ctxt->output, "%s : ", xmlGetNodePath(node->parent));
- xmlShellList(ctxt, NULL, node->parent, NULL);
- }
- }
-
- /*
- * Browse the full subtree, deep first
- */
-
- if ((node->type == XML_DOCUMENT_NODE) ||
- (node->type == XML_HTML_DOCUMENT_NODE)) {
- node = ((xmlDocPtr) node)->children;
- } else if ((node->children != NULL)
- && (node->type != XML_ENTITY_REF_NODE)) {
- /* deep first */
- node = node->children;
- } else if (node->next != NULL) {
- /* then siblings */
- node = node->next;
- } else {
- /* go up to parents->next if needed */
- while (node != NULL) {
- if (node->parent != NULL) {
- node = node->parent;
- }
- if (node->next != NULL) {
- node = node->next;
- break;
- }
- if (node->parent == NULL) {
- node = NULL;
- break;
- }
- }
- }
- }
- return (0);
-}
-
-/**
- * xmlShellDir:
- * @ctxt: the shell context
- * @arg: unused
- * @node: a node
- * @node2: unused
- *
- * Implements the XML shell function "dir"
- * dumps informations about the node (namespace, attributes, content).
- *
- * Returns 0
- */
-int
-xmlShellDir(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED,
- char *arg ATTRIBUTE_UNUSED, xmlNodePtr node,
- xmlNodePtr node2 ATTRIBUTE_UNUSED)
-{
- if (!ctxt)
- return (0);
- if (node == NULL) {
- fprintf(ctxt->output, "NULL\n");
- return (0);
- }
- if ((node->type == XML_DOCUMENT_NODE) ||
- (node->type == XML_HTML_DOCUMENT_NODE)) {
- xmlDebugDumpDocumentHead(ctxt->output, (xmlDocPtr) node);
- } else if (node->type == XML_ATTRIBUTE_NODE) {
- xmlDebugDumpAttr(ctxt->output, (xmlAttrPtr) node, 0);
- } else {
- xmlDebugDumpOneNode(ctxt->output, node, 0);
- }
- return (0);
-}
-
-/**
- * xmlShellCat:
- * @ctxt: the shell context
- * @arg: unused
- * @node: a node
- * @node2: unused
- *
- * Implements the XML shell function "cat"
- * dumps the serialization node content (XML or HTML).
- *
- * Returns 0
- */
-int
-xmlShellCat(xmlShellCtxtPtr ctxt, char *arg ATTRIBUTE_UNUSED,
- xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED)
-{
- if (!ctxt)
- return (0);
- if (node == NULL) {
- fprintf(ctxt->output, "NULL\n");
- return (0);
- }
- if (ctxt->doc->type == XML_HTML_DOCUMENT_NODE) {
-#ifdef LIBXML_HTML_ENABLED
- if (node->type == XML_HTML_DOCUMENT_NODE)
- htmlDocDump(ctxt->output, (htmlDocPtr) node);
- else
- htmlNodeDumpFile(ctxt->output, ctxt->doc, node);
-#else
- if (node->type == XML_DOCUMENT_NODE)
- xmlDocDump(ctxt->output, (xmlDocPtr) node);
- else
- xmlElemDump(ctxt->output, ctxt->doc, node);
-#endif /* LIBXML_HTML_ENABLED */
- } else {
- if (node->type == XML_DOCUMENT_NODE)
- xmlDocDump(ctxt->output, (xmlDocPtr) node);
- else
- xmlElemDump(ctxt->output, ctxt->doc, node);
- }
- fprintf(ctxt->output, "\n");
- return (0);
-}
-
-/**
- * xmlShellLoad:
- * @ctxt: the shell context
- * @filename: the file name
- * @node: unused
- * @node2: unused
- *
- * Implements the XML shell function "load"
- * loads a new document specified by the filename
- *
- * Returns 0 or -1 if loading failed
- */
-int
-xmlShellLoad(xmlShellCtxtPtr ctxt, char *filename,
- xmlNodePtr node ATTRIBUTE_UNUSED,
- xmlNodePtr node2 ATTRIBUTE_UNUSED)
-{
- xmlDocPtr doc;
- int html = 0;
-
- if (ctxt->doc != NULL)
- html = (ctxt->doc->type == XML_HTML_DOCUMENT_NODE);
-
- if (html) {
-#ifdef LIBXML_HTML_ENABLED
- doc = htmlParseFile(filename, NULL);
-#else
- fprintf(ctxt->output, "HTML support not compiled in\n");
- doc = NULL;
-#endif /* LIBXML_HTML_ENABLED */
- } else {
- doc = xmlParseFile(filename);
- }
- if (doc != NULL) {
- if (ctxt->loaded == 1) {
- xmlFreeDoc(ctxt->doc);
- }
- ctxt->loaded = 1;
-#ifdef LIBXML_XPATH_ENABLED
- xmlXPathFreeContext(ctxt->pctxt);
-#endif /* LIBXML_XPATH_ENABLED */
- xmlFree(ctxt->filename);
- ctxt->doc = doc;
- ctxt->node = (xmlNodePtr) doc;
-#ifdef LIBXML_XPATH_ENABLED
- ctxt->pctxt = xmlXPathNewContext(doc);
-#endif /* LIBXML_XPATH_ENABLED */
- ctxt->filename = (char *) xmlStrdup((xmlChar *) filename);
- } else
- return (-1);
- return (0);
-}
-
-/**
- * xmlShellWrite:
- * @ctxt: the shell context
- * @filename: the file name
- * @node: a node in the tree
- * @node2: unused
- *
- * Implements the XML shell function "write"
- * Write the current node to the filename, it saves the serialization
- * of the subtree under the @node specified
- *
- * Returns 0 or -1 in case of error
- */
-int
-xmlShellWrite(xmlShellCtxtPtr ctxt, char *filename, xmlNodePtr node,
- xmlNodePtr node2 ATTRIBUTE_UNUSED)
-{
- if (node == NULL)
- return (-1);
- if ((filename == NULL) || (filename[0] == 0)) {
- xmlGenericError(xmlGenericErrorContext,
- "Write command requires a filename argument\n");
- return (-1);
- }
-#ifdef W_OK
- if (access((char *) filename, W_OK)) {
- xmlGenericError(xmlGenericErrorContext,
- "Cannot write to %s\n", filename);
- return (-1);
- }
-#endif
- switch (node->type) {
- case XML_DOCUMENT_NODE:
- if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
- xmlGenericError(xmlGenericErrorContext,
- "Failed to write to %s\n", filename);
- return (-1);
- }
- break;
- case XML_HTML_DOCUMENT_NODE:
-#ifdef LIBXML_HTML_ENABLED
- if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "Failed to write to %s\n", filename);
- return (-1);
- }
-#else
- if (xmlSaveFile((char *) filename, ctxt->doc) < -1) {
- xmlGenericError(xmlGenericErrorContext,
- "Failed to write to %s\n", filename);
- return (-1);
- }
-#endif /* LIBXML_HTML_ENABLED */
- break;
- default:{
- FILE *f;
-
- f = fopen((char *) filename, "w");
- if (f == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Failed to write to %s\n", filename);
- return (-1);
- }
- xmlElemDump(f, ctxt->doc, node);
- fclose(f);
- }
- }
- return (0);
-}
-
-/**
- * xmlShellSave:
- * @ctxt: the shell context
- * @filename: the file name (optional)
- * @node: unused
- * @node2: unused
- *
- * Implements the XML shell function "save"
- * Write the current document to the filename, or it's original name
- *
- * Returns 0 or -1 in case of error
- */
-int
-xmlShellSave(xmlShellCtxtPtr ctxt, char *filename,
- xmlNodePtr node ATTRIBUTE_UNUSED,
- xmlNodePtr node2 ATTRIBUTE_UNUSED)
-{
- if (ctxt->doc == NULL)
- return (-1);
- if ((filename == NULL) || (filename[0] == 0))
- filename = ctxt->filename;
-#ifdef W_OK
- if (access((char *) filename, W_OK)) {
- xmlGenericError(xmlGenericErrorContext,
- "Cannot save to %s\n", filename);
- return (-1);
- }
-#endif
- switch (ctxt->doc->type) {
- case XML_DOCUMENT_NODE:
- if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "Failed to save to %s\n", filename);
- }
- break;
- case XML_HTML_DOCUMENT_NODE:
-#ifdef LIBXML_HTML_ENABLED
- if (htmlSaveFile((char *) filename, ctxt->doc) < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "Failed to save to %s\n", filename);
- }
-#else
- if (xmlSaveFile((char *) filename, ctxt->doc) < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "Failed to save to %s\n", filename);
- }
-#endif /* LIBXML_HTML_ENABLED */
- break;
- default:
- xmlGenericError(xmlGenericErrorContext,
- "To save to subparts of a document use the 'write' command\n");
- return (-1);
-
- }
- return (0);
-}
-
-/**
- * xmlShellValidate:
- * @ctxt: the shell context
- * @dtd: the DTD URI (optional)
- * @node: unused
- * @node2: unused
- *
- * Implements the XML shell function "validate"
- * Validate the document, if a DTD path is provided, then the validation
- * is done against the given DTD.
- *
- * Returns 0 or -1 in case of error
- */
-int
-xmlShellValidate(xmlShellCtxtPtr ctxt, char *dtd,
- xmlNodePtr node ATTRIBUTE_UNUSED,
- xmlNodePtr node2 ATTRIBUTE_UNUSED)
-{
- xmlValidCtxt vctxt;
- int res = -1;
-
- vctxt.userData = stderr;
- vctxt.error = (xmlValidityErrorFunc) fprintf;
- vctxt.warning = (xmlValidityWarningFunc) fprintf;
-
- if ((dtd == NULL) || (dtd[0] == 0)) {
- res = xmlValidateDocument(&vctxt, ctxt->doc);
- } else {
- xmlDtdPtr subset;
-
- subset = xmlParseDTD(NULL, (xmlChar *) dtd);
- if (subset != NULL) {
- res = xmlValidateDtd(&vctxt, ctxt->doc, subset);
-
- xmlFreeDtd(subset);
- }
- }
- return (res);
-}
-
-/**
- * xmlShellDu:
- * @ctxt: the shell context
- * @arg: unused
- * @tree: a node defining a subtree
- * @node2: unused
- *
- * Implements the XML shell function "du"
- * show the structure of the subtree under node @tree
- * If @tree is null, the command works on the current node.
- *
- * Returns 0 or -1 in case of error
- */
-int
-xmlShellDu(xmlShellCtxtPtr ctxt,
- char *arg ATTRIBUTE_UNUSED, xmlNodePtr tree,
- xmlNodePtr node2 ATTRIBUTE_UNUSED)
-{
- xmlNodePtr node;
- int indent = 0, i;
-
- if (!ctxt)
- return (-1);
-
- if (tree == NULL)
- return (-1);
- node = tree;
- while (node != NULL) {
- if ((node->type == XML_DOCUMENT_NODE) ||
- (node->type == XML_HTML_DOCUMENT_NODE)) {
- fprintf(ctxt->output, "/\n");
- } else if (node->type == XML_ELEMENT_NODE) {
- for (i = 0; i < indent; i++)
- fprintf(ctxt->output, " ");
- fprintf(ctxt->output, "%s\n", node->name);
- } else {
- }
-
- /*
- * Browse the full subtree, deep first
- */
-
- if ((node->type == XML_DOCUMENT_NODE) ||
- (node->type == XML_HTML_DOCUMENT_NODE)) {
- node = ((xmlDocPtr) node)->children;
- } else if ((node->children != NULL)
- && (node->type != XML_ENTITY_REF_NODE)) {
- /* deep first */
- node = node->children;
- indent++;
- } else if ((node != tree) && (node->next != NULL)) {
- /* then siblings */
- node = node->next;
- } else if (node != tree) {
- /* go up to parents->next if needed */
- while (node != tree) {
- if (node->parent != NULL) {
- node = node->parent;
- indent--;
- }
- if ((node != tree) && (node->next != NULL)) {
- node = node->next;
- break;
- }
- if (node->parent == NULL) {
- node = NULL;
- break;
- }
- if (node == tree) {
- node = NULL;
- break;
- }
- }
- /* exit condition */
- if (node == tree)
- node = NULL;
- } else
- node = NULL;
- }
- return (0);
-}
-
-/**
- * xmlShellPwd:
- * @ctxt: the shell context
- * @buffer: the output buffer
- * @node: a node
- * @node2: unused
- *
- * Implements the XML shell function "pwd"
- * Show the full path from the root to the node, if needed building
- * thumblers when similar elements exists at a given ancestor level.
- * The output is compatible with XPath commands.
- *
- * Returns 0 or -1 in case of error
- */
-int
-xmlShellPwd(xmlShellCtxtPtr ctxt ATTRIBUTE_UNUSED, char *buffer,
- xmlNodePtr node, xmlNodePtr node2 ATTRIBUTE_UNUSED)
-{
- xmlChar *path;
-
- if (node == NULL)
- return (-1);
-
- path = xmlGetNodePath(node);
- if (path == NULL)
- return (-1);
-
- /*
- * This test prevents buffer overflow, because this routine
- * is only called by xmlShell, in which the second argument is
- * 500 chars long.
- * It is a dirty hack before a cleaner solution is found.
- * Documentation should mention that the second argument must
- * be at least 500 chars long, and could be stripped if too long.
- */
- snprintf(buffer, 499, "%s", path);
- buffer[499] = '0';
- xmlFree(path);
-
- return (0);
-}
-
-/**
- * xmlShell:
- * @doc: the initial document
- * @filename: the output buffer
- * @input: the line reading function
- * @output: the output FILE*, defaults to stdout if NULL
- *
- * Implements the XML shell
- * This allow to load, validate, view, modify and save a document
- * using a environment similar to a UNIX commandline.
- */
-void
-xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input,
- FILE * output)
-{
- char prompt[500] = "/ > ";
- char *cmdline = NULL, *cur;
- int nbargs;
- char command[100];
- char arg[400];
- int i;
- xmlShellCtxtPtr ctxt;
- xmlXPathObjectPtr list;
-
- if (doc == NULL)
- return;
- if (filename == NULL)
- return;
- if (input == NULL)
- return;
- if (output == NULL)
- output = stdout;
- ctxt = (xmlShellCtxtPtr) xmlMalloc(sizeof(xmlShellCtxt));
- if (ctxt == NULL)
- return;
- ctxt->loaded = 0;
- ctxt->doc = doc;
- ctxt->input = input;
- ctxt->output = output;
- ctxt->filename = (char *) xmlStrdup((xmlChar *) filename);
- ctxt->node = (xmlNodePtr) ctxt->doc;
-
-#ifdef LIBXML_XPATH_ENABLED
- ctxt->pctxt = xmlXPathNewContext(ctxt->doc);
- if (ctxt->pctxt == NULL) {
- xmlFree(ctxt);
- return;
- }
-#endif /* LIBXML_XPATH_ENABLED */
- while (1) {
- if (ctxt->node == (xmlNodePtr) ctxt->doc)
- snprintf(prompt, sizeof(prompt), "%s > ", "/");
- else if (ctxt->node->name)
- snprintf(prompt, sizeof(prompt), "%s > ", ctxt->node->name);
- else
- snprintf(prompt, sizeof(prompt), "? > ");
- prompt[sizeof(prompt) - 1] = 0;
-
- /*
- * Get a new command line
- */
- cmdline = ctxt->input(prompt);
- if (cmdline == NULL)
- break;
-
- /*
- * Parse the command itself
- */
- cur = cmdline;
- nbargs = 0;
- while ((*cur == ' ') || (*cur == '\t'))
- cur++;
- i = 0;
- while ((*cur != ' ') && (*cur != '\t') &&
- (*cur != '\n') && (*cur != '\r')) {
- if (*cur == 0)
- break;
- command[i++] = *cur++;
- }
- command[i] = 0;
- if (i == 0)
- continue;
- nbargs++;
-
- /*
- * Parse the argument
- */
- while ((*cur == ' ') || (*cur == '\t'))
- cur++;
- i = 0;
- while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) {
- if (*cur == 0)
- break;
- arg[i++] = *cur++;
- }
- arg[i] = 0;
- if (i != 0)
- nbargs++;
-
- /*
- * start interpreting the command
- */
- if (!strcmp(command, "exit"))
- break;
- if (!strcmp(command, "quit"))
- break;
- if (!strcmp(command, "bye"))
- break;
- if (!strcmp(command, "help")) {
- fprintf(ctxt->output, "\tbase display XML base of the node\n");
- fprintf(ctxt->output, "\tsetbase URI change the XML base of the node\n");
- fprintf(ctxt->output, "\tbye leave shell\n");
- fprintf(ctxt->output, "\tcat [node] display node or current node\n");
- fprintf(ctxt->output, "\tcd [path] change directory to path or to root\n");
- fprintf(ctxt->output, "\tdir [path] dumps informations about the node (namespace, attributes, content)\n");
- fprintf(ctxt->output, "\tdu [path] show the structure of the subtree under path or the current node\n");
- fprintf(ctxt->output, "\texit leave shell\n");
- fprintf(ctxt->output, "\thelp display this help\n");
- fprintf(ctxt->output, "\tfree display memory usage\n");
- fprintf(ctxt->output, "\tload [name] load a new document with name\n");
- fprintf(ctxt->output, "\tls [path] list contents of path or the current directory\n");
-#ifdef LIBXML_XPATH_ENABLED
- fprintf(ctxt->output, "\txpath expr evaluate the XPath expression in that context and print the result\n");
-#endif /* LIBXML_XPATH_ENABLED */
- fprintf(ctxt->output, "\tpwd display current working directory\n");
- fprintf(ctxt->output, "\tquit leave shell\n");
- fprintf(ctxt->output, "\tsave [name] save this document to name or the original name\n");
- fprintf(ctxt->output, "\tvalidate check the document for errors\n");
- fprintf(ctxt->output, "\twrite [name] write the current node to the filename\n");
- fprintf(ctxt->output, "\tgrep string search for a string in the subtree\n");
- } else if (!strcmp(command, "validate")) {
- xmlShellValidate(ctxt, arg, NULL, NULL);
- } else if (!strcmp(command, "load")) {
- xmlShellLoad(ctxt, arg, NULL, NULL);
- } else if (!strcmp(command, "save")) {
- xmlShellSave(ctxt, arg, NULL, NULL);
- } else if (!strcmp(command, "write")) {
- xmlShellWrite(ctxt, arg, NULL, NULL);
- } else if (!strcmp(command, "grep")) {
- xmlShellGrep(ctxt, arg, ctxt->node, NULL);
- } else if (!strcmp(command, "free")) {
- if (arg[0] == 0) {
- xmlMemShow(ctxt->output, 0);
- } else {
- int len = 0;
-
- sscanf(arg, "%d", &len);
- xmlMemShow(ctxt->output, len);
- }
- } else if (!strcmp(command, "pwd")) {
- char dir[500];
-
- if (!xmlShellPwd(ctxt, dir, ctxt->node, NULL))
- fprintf(ctxt->output, "%s\n", dir);
- } else if (!strcmp(command, "du")) {
- xmlShellDu(ctxt, NULL, ctxt->node, NULL);
- } else if (!strcmp(command, "base")) {
- xmlShellBase(ctxt, NULL, ctxt->node, NULL);
-#ifdef LIBXML_XPATH_ENABLED
- } else if (!strcmp(command, "xpath")) {
- if (arg[0] == 0) {
- xmlGenericError(xmlGenericErrorContext,
- "xpath: expression required\n");
- } else {
- ctxt->pctxt->node = ctxt->node;
- list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
- xmlXPathDebugDumpObject(ctxt->output, list, 0);
- xmlXPathFreeObject(list);
- }
-#endif /* LIBXML_XPATH_ENABLED */
- } else if (!strcmp(command, "setbase")) {
- xmlShellSetBase(ctxt, arg, ctxt->node, NULL);
- } else if ((!strcmp(command, "ls")) || (!strcmp(command, "dir"))) {
- int dir = (!strcmp(command, "dir"));
-
- if (arg[0] == 0) {
- if (dir)
- xmlShellDir(ctxt, NULL, ctxt->node, NULL);
- else
- xmlShellList(ctxt, NULL, ctxt->node, NULL);
- } else {
- ctxt->pctxt->node = ctxt->node;
-#ifdef LIBXML_XPATH_ENABLED
- ctxt->pctxt->node = ctxt->node;
- list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
-#else
- list = NULL;
-#endif /* LIBXML_XPATH_ENABLED */
- if (list != NULL) {
- switch (list->type) {
- case XPATH_UNDEFINED:
- xmlGenericError(xmlGenericErrorContext,
- "%s: no such node\n", arg);
- break;
- case XPATH_NODESET:{
- int indx;
-
- if (list->nodesetval == NULL)
- break;
-
- for (indx = 0;
- indx < list->nodesetval->nodeNr;
- indx++) {
- if (dir)
- xmlShellDir(ctxt, NULL,
- list->nodesetval->
- nodeTab[indx], NULL);
- else
- xmlShellList(ctxt, NULL,
- list->nodesetval->
- nodeTab[indx], NULL);
- }
- break;
- }
- case XPATH_BOOLEAN:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a Boolean\n", arg);
- break;
- case XPATH_NUMBER:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a number\n", arg);
- break;
- case XPATH_STRING:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a string\n", arg);
- break;
- case XPATH_POINT:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a point\n", arg);
- break;
- case XPATH_RANGE:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a range\n", arg);
- break;
- case XPATH_LOCATIONSET:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a range\n", arg);
- break;
- case XPATH_USERS:
- xmlGenericError(xmlGenericErrorContext,
- "%s is user-defined\n", arg);
- break;
- case XPATH_XSLT_TREE:
- xmlGenericError(xmlGenericErrorContext,
- "%s is an XSLT value tree\n",
- arg);
- break;
- }
-#ifdef LIBXML_XPATH_ENABLED
- xmlXPathFreeObject(list);
-#endif
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "%s: no such node\n", arg);
- }
- ctxt->pctxt->node = NULL;
- }
- } else if (!strcmp(command, "cd")) {
- if (arg[0] == 0) {
- ctxt->node = (xmlNodePtr) ctxt->doc;
- } else {
-#ifdef LIBXML_XPATH_ENABLED
- ctxt->pctxt->node = ctxt->node;
- list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
-#else
- list = NULL;
-#endif /* LIBXML_XPATH_ENABLED */
- if (list != NULL) {
- switch (list->type) {
- case XPATH_UNDEFINED:
- xmlGenericError(xmlGenericErrorContext,
- "%s: no such node\n", arg);
- break;
- case XPATH_NODESET:
- if (list->nodesetval != NULL) {
- if (list->nodesetval->nodeNr == 1) {
- ctxt->node = list->nodesetval->nodeTab[0];
- } else
- xmlGenericError(xmlGenericErrorContext,
- "%s is a %d Node Set\n",
- arg,
- list->nodesetval->nodeNr);
- } else
- xmlGenericError(xmlGenericErrorContext,
- "%s is an empty Node Set\n",
- arg);
- break;
- case XPATH_BOOLEAN:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a Boolean\n", arg);
- break;
- case XPATH_NUMBER:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a number\n", arg);
- break;
- case XPATH_STRING:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a string\n", arg);
- break;
- case XPATH_POINT:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a point\n", arg);
- break;
- case XPATH_RANGE:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a range\n", arg);
- break;
- case XPATH_LOCATIONSET:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a range\n", arg);
- break;
- case XPATH_USERS:
- xmlGenericError(xmlGenericErrorContext,
- "%s is user-defined\n", arg);
- break;
- case XPATH_XSLT_TREE:
- xmlGenericError(xmlGenericErrorContext,
- "%s is an XSLT value tree\n",
- arg);
- break;
- }
-#ifdef LIBXML_XPATH_ENABLED
- xmlXPathFreeObject(list);
-#endif
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "%s: no such node\n", arg);
- }
- ctxt->pctxt->node = NULL;
- }
- } else if (!strcmp(command, "cat")) {
- if (arg[0] == 0) {
- xmlShellCat(ctxt, NULL, ctxt->node, NULL);
- } else {
- ctxt->pctxt->node = ctxt->node;
-#ifdef LIBXML_XPATH_ENABLED
- ctxt->pctxt->node = ctxt->node;
- list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
-#else
- list = NULL;
-#endif /* LIBXML_XPATH_ENABLED */
- if (list != NULL) {
- switch (list->type) {
- case XPATH_UNDEFINED:
- xmlGenericError(xmlGenericErrorContext,
- "%s: no such node\n", arg);
- break;
- case XPATH_NODESET:{
- int indx;
-
- if (list->nodesetval == NULL)
- break;
-
- for (indx = 0;
- indx < list->nodesetval->nodeNr;
- indx++) {
- if (i > 0)
- fprintf(ctxt->output, " -------\n");
- xmlShellCat(ctxt, NULL,
- list->nodesetval->
- nodeTab[indx], NULL);
- }
- break;
- }
- case XPATH_BOOLEAN:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a Boolean\n", arg);
- break;
- case XPATH_NUMBER:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a number\n", arg);
- break;
- case XPATH_STRING:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a string\n", arg);
- break;
- case XPATH_POINT:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a point\n", arg);
- break;
- case XPATH_RANGE:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a range\n", arg);
- break;
- case XPATH_LOCATIONSET:
- xmlGenericError(xmlGenericErrorContext,
- "%s is a range\n", arg);
- break;
- case XPATH_USERS:
- xmlGenericError(xmlGenericErrorContext,
- "%s is user-defined\n", arg);
- break;
- case XPATH_XSLT_TREE:
- xmlGenericError(xmlGenericErrorContext,
- "%s is an XSLT value tree\n",
- arg);
- break;
- }
-#ifdef LIBXML_XPATH_ENABLED
- xmlXPathFreeObject(list);
-#endif
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "%s: no such node\n", arg);
- }
- ctxt->pctxt->node = NULL;
- }
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "Unknown command %s\n", command);
- }
- free(cmdline); /* not xmlFree here ! */
- }
-#ifdef LIBXML_XPATH_ENABLED
- xmlXPathFreeContext(ctxt->pctxt);
-#endif /* LIBXML_XPATH_ENABLED */
- if (ctxt->loaded) {
- xmlFreeDoc(ctxt->doc);
- }
- if (ctxt->filename != NULL)
- xmlFree(ctxt->filename);
- xmlFree(ctxt);
- if (cmdline != NULL)
- free(cmdline); /* not xmlFree here ! */
-}
-
-#endif /* LIBXML_DEBUG_ENABLED */
diff --git a/bundle/libxml/encoding.c b/bundle/libxml/encoding.c
deleted file mode 100644
index 69d67cd6b9..0000000000
--- a/bundle/libxml/encoding.c
+++ /dev/null
@@ -1,2340 +0,0 @@
-/*
- * encoding.c : implements the encoding conversion functions needed for XML
- *
- * Related specs:
- * rfc2044 (UTF-8 and UTF-16) F. Yergeau Alis Technologies
- * rfc2781 UTF-16, an encoding of ISO 10646, P. Hoffman, F. Yergeau
- * [ISO-10646] UTF-8 and UTF-16 in Annexes
- * [ISO-8859-1] ISO Latin-1 characters codes.
- * [UNICODE] The Unicode Consortium, "The Unicode Standard --
- * Worldwide Character Encoding -- Version 1.0", Addison-
- * Wesley, Volume 1, 1991, Volume 2, 1992. UTF-8 is
- * described in Unicode Technical Report #4.
- * [US-ASCII] Coded Character Set--7-bit American Standard Code for
- * Information Interchange, ANSI X3.4-1986.
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- *
- * UTF8 string routines from:
- * "William M. Brack" <wbrack@mmm.com.hk>
- *
- * Original code for IsoLatin1 and UTF-16 by "Martin J. Duerst" <duerst@w3.org>
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#include <string.h>
-
-#ifdef HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef LIBXML_ICONV_ENABLED
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#endif
-#include <libxml/encoding.h>
-#include <libxml/xmlmemory.h>
-#ifdef LIBXML_HTML_ENABLED
-#include <libxml/HTMLparser.h>
-#endif
-#include <libxml/globals.h>
-#include <libxml/xmlerror.h>
-
-static xmlCharEncodingHandlerPtr xmlUTF16LEHandler = NULL;
-static xmlCharEncodingHandlerPtr xmlUTF16BEHandler = NULL;
-
-typedef struct _xmlCharEncodingAlias xmlCharEncodingAlias;
-typedef xmlCharEncodingAlias *xmlCharEncodingAliasPtr;
-struct _xmlCharEncodingAlias {
- const char *name;
- const char *alias;
-};
-
-static xmlCharEncodingAliasPtr xmlCharEncodingAliases = NULL;
-static int xmlCharEncodingAliasesNb = 0;
-static int xmlCharEncodingAliasesMax = 0;
-
-#ifdef LIBXML_ICONV_ENABLED
-#if 0
-#define DEBUG_ENCODING /* Define this to get encoding traces */
-#endif
-#endif
-
-static int xmlLittleEndian = 1;
-
-/************************************************************************
- * *
- * Generic UTF8 handling routines *
- * *
- * From rfc2044: encoding of the Unicode values on UTF-8: *
- * *
- * UCS-4 range (hex.) UTF-8 octet sequence (binary) *
- * 0000 0000-0000 007F 0xxxxxxx *
- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx *
- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx *
- * *
- * I hope we won't use values > 0xFFFF anytime soon ! *
- * *
- ************************************************************************/
-
-/**
- * xmlUTF8Strlen:
- * @utf: a sequence of UTF-8 encoded bytes
- *
- * compute the length of an UTF8 string, it doesn't do a full UTF8
- * checking of the content of the string.
- *
- * Returns the number of characters in the string or -1 in case of error
- */
-int
-xmlUTF8Strlen(const xmlChar *utf) {
- int ret = 0;
-
- if (utf == NULL)
- return(-1);
-
- while (*utf != 0) {
- if (utf[0] & 0x80) {
- if ((utf[1] & 0xc0) != 0x80)
- return(-1);
- if ((utf[0] & 0xe0) == 0xe0) {
- if ((utf[2] & 0xc0) != 0x80)
- return(-1);
- if ((utf[0] & 0xf0) == 0xf0) {
- if ((utf[0] & 0xf8) != 0xf0 || (utf[3] & 0xc0) != 0x80)
- return(-1);
- utf += 4;
- } else {
- utf += 3;
- }
- } else {
- utf += 2;
- }
- } else {
- utf++;
- }
- ret++;
- }
- return(ret);
-}
-
-/**
- * xmlGetUTF8Char:
- * @utf: a sequence of UTF-8 encoded bytes
- * @len: a pointer to @bytes len
- *
- * Read one UTF8 Char from @utf
- *
- * Returns the char value or -1 in case of error and update @len with the
- * number of bytes used
- */
-int
-xmlGetUTF8Char(const unsigned char *utf, int *len) {
- unsigned int c;
-
- if (utf == NULL)
- goto error;
- if (len == NULL)
- goto error;
- if (*len < 1)
- goto error;
-
- c = utf[0];
- if (c & 0x80) {
- if (*len < 2)
- goto error;
- if ((utf[1] & 0xc0) != 0x80)
- goto error;
- if ((c & 0xe0) == 0xe0) {
- if (*len < 3)
- goto error;
- if ((utf[2] & 0xc0) != 0x80)
- goto error;
- if ((c & 0xf0) == 0xf0) {
- if (*len < 4)
- goto error;
- if ((c & 0xf8) != 0xf0 || (utf[3] & 0xc0) != 0x80)
- goto error;
- *len = 4;
- /* 4-byte code */
- c = (utf[0] & 0x7) << 18;
- c |= (utf[1] & 0x3f) << 12;
- c |= (utf[2] & 0x3f) << 6;
- c |= utf[3] & 0x3f;
- } else {
- /* 3-byte code */
- *len = 3;
- c = (utf[0] & 0xf) << 12;
- c |= (utf[1] & 0x3f) << 6;
- c |= utf[2] & 0x3f;
- }
- } else {
- /* 2-byte code */
- *len = 2;
- c = (utf[0] & 0x1f) << 6;
- c |= utf[1] & 0x3f;
- }
- } else {
- /* 1-byte code */
- *len = 1;
- }
- return(c);
-
-error:
- *len = 0;
- return(-1);
-}
-
-/**
- * xmlCheckUTF8:
- * @utf: Pointer to putative utf-8 encoded string.
- *
- * Checks @utf for being valid utf-8. @utf is assumed to be
- * null-terminated. This function is not super-strict, as it will
- * allow longer utf-8 sequences than necessary. Note that Java is
- * capable of producing these sequences if provoked. Also note, this
- * routine checks for the 4-byte maximum size, but does not check for
- * 0x10ffff maximum value.
- *
- * Return value: true if @utf is valid.
- **/
-int
-xmlCheckUTF8(const unsigned char *utf)
-{
- int ix;
- unsigned char c;
-
- for (ix = 0; (c = utf[ix]);) {
- if (c & 0x80) {
- if ((utf[ix + 1] & 0xc0) != 0x80)
- return(0);
- if ((c & 0xe0) == 0xe0) {
- if ((utf[ix + 2] & 0xc0) != 0x80)
- return(0);
- if ((c & 0xf0) == 0xf0) {
- if ((c & 0xf8) != 0xf0 || (utf[ix + 3] & 0xc0) != 0x80)
- return(0);
- ix += 4;
- /* 4-byte code */
- } else
- /* 3-byte code */
- ix += 3;
- } else
- /* 2-byte code */
- ix += 2;
- } else
- /* 1-byte code */
- ix++;
- }
- return(1);
-}
-
-/**
- * xmlUTF8Strsize:
- * @utf: a sequence of UTF-8 encoded bytes
- * @len: the number of characters in the array
- *
- * storage size of an UTF8 string
- *
- * Returns the storage size of
- * the first 'len' characters of ARRAY
- *
- */
-
-int
-xmlUTF8Strsize(const xmlChar *utf, int len) {
- const xmlChar *ptr=utf;
- xmlChar ch;
-
- if (len <= 0)
- return(0);
-
- while ( len-- > 0) {
- if ( !*ptr )
- break;
- if ( (ch = *ptr++) & 0x80)
- while ( (ch<<=1) & 0x80 )
- ptr++;
- }
- return (ptr - utf);
-}
-
-
-/**
- * xmlUTF8Strndup:
- * @utf: the input UTF8 *
- * @len: the len of @utf (in chars)
- *
- * a strndup for array of UTF8's
- *
- * Returns a new UTF8 * or NULL
- */
-xmlChar *
-xmlUTF8Strndup(const xmlChar *utf, int len) {
- xmlChar *ret;
- int i;
-
- if ((utf == NULL) || (len < 0)) return(NULL);
- i = xmlUTF8Strsize(utf, len);
- ret = (xmlChar *) xmlMalloc((i + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %ld byte failed\n",
- (len + 1) * (long)sizeof(xmlChar));
- return(NULL);
- }
- memcpy(ret, utf, i * sizeof(xmlChar));
- ret[i] = 0;
- return(ret);
-}
-
-/**
- * xmlUTF8Strpos:
- * @utf: the input UTF8 *
- * @pos: the position of the desired UTF8 char (in chars)
- *
- * a function to provide the equivalent of fetching a
- * character from a string array
- *
- * Returns a pointer to the UTF8 character or NULL
- */
-xmlChar *
-xmlUTF8Strpos(const xmlChar *utf, int pos) {
- xmlChar ch;
-
- if (utf == NULL) return(NULL);
- if ( (pos < 0) || (pos >= xmlUTF8Strlen(utf)) )
- return(NULL);
- while (pos--) {
- if ((ch=*utf++) == 0) return(NULL);
- if ( ch & 0x80 ) {
- /* if not simple ascii, verify proper format */
- if ( (ch & 0xc0) != 0xc0 )
- return(NULL);
- /* then skip over remaining bytes for this char */
- while ( (ch <<= 1) & 0x80 )
- if ( (*utf++ & 0xc0) != 0x80 )
- return(NULL);
- }
- }
- return((xmlChar *)utf);
-}
-
-/**
- * xmlUTF8Strloc:
- * @utf: the input UTF8 *
- * @utfchar: the UTF8 character to be found
- *
- * a function to provide relative location of a UTF8 char
- *
- * Returns the relative character position of the desired char
- * or -1 if not found
- */
-int
-xmlUTF8Strloc(const xmlChar *utf, const xmlChar *utfchar) {
- int i, size;
- xmlChar ch;
-
- if (utf==NULL || utfchar==NULL) return -1;
- size = xmlUTF8Strsize(utfchar, 1);
- for(i=0; (ch=*utf) != 0; i++) {
- if (xmlStrncmp(utf, utfchar, size)==0)
- return(i);
- utf++;
- if ( ch & 0x80 ) {
- /* if not simple ascii, verify proper format */
- if ( (ch & 0xc0) != 0xc0 )
- return(-1);
- /* then skip over remaining bytes for this char */
- while ( (ch <<= 1) & 0x80 )
- if ( (*utf++ & 0xc0) != 0x80 )
- return(-1);
- }
- }
-
- return(-1);
-}
-/**
- * xmlUTF8Strsub:
- * @utf: a sequence of UTF-8 encoded bytes
- * @start: relative pos of first char
- * @len: total number to copy
- *
- * Note: positions are given in units of UTF-8 chars
- *
- * Returns a pointer to a newly created string
- * or NULL if any problem
- */
-
-xmlChar *
-xmlUTF8Strsub(const xmlChar *utf, int start, int len) {
- int i;
- xmlChar ch;
-
- if (utf == NULL) return(NULL);
- if (start < 0) return(NULL);
- if (len < 0) return(NULL);
-
- /*
- * Skip over any leading chars
- */
- for (i = 0;i < start;i++) {
- if ((ch=*utf++) == 0) return(NULL);
- if ( ch & 0x80 ) {
- /* if not simple ascii, verify proper format */
- if ( (ch & 0xc0) != 0xc0 )
- return(NULL);
- /* then skip over remaining bytes for this char */
- while ( (ch <<= 1) & 0x80 )
- if ( (*utf++ & 0xc0) != 0x80 )
- return(NULL);
- }
- }
-
- return(xmlUTF8Strndup(utf, len));
-}
-
-/************************************************************************
- * *
- * Conversions To/From UTF8 encoding *
- * *
- ************************************************************************/
-
-/**
- * asciiToUTF8:
- * @out: a pointer to an array of bytes to store the result
- * @outlen: the length of @out
- * @in: a pointer to an array of ASCII chars
- * @inlen: the length of @in
- *
- * Take a block of ASCII chars in and try to convert it to an UTF-8
- * block of chars out.
- * Returns 0 if success, or -1 otherwise
- * The value of @inlen after return is the number of octets consumed
- * as the return value is positive, else unpredictable.
- * The value of @outlen after return is the number of ocetes consumed.
- */
-static int
-asciiToUTF8(unsigned char* out, int *outlen,
- const unsigned char* in, int *inlen) {
- unsigned char* outstart = out;
- const unsigned char* base = in;
- const unsigned char* processed = in;
- unsigned char* outend = out + *outlen;
- const unsigned char* inend;
- unsigned int c;
- int bits;
-
- inend = in + (*inlen);
- while ((in < inend) && (out - outstart + 5 < *outlen)) {
- c= *in++;
-
- /* assertion: c is a single UTF-4 value */
- if (out >= outend)
- break;
- if (c < 0x80) { *out++= c; bits= -6; }
- else {
- *outlen = out - outstart;
- *inlen = processed - base;
- return(-1);
- }
-
- for ( ; bits >= 0; bits-= 6) {
- if (out >= outend)
- break;
- *out++= ((c >> bits) & 0x3F) | 0x80;
- }
- processed = (const unsigned char*) in;
- }
- *outlen = out - outstart;
- *inlen = processed - base;
- return(0);
-}
-
-/**
- * UTF8Toascii:
- * @out: a pointer to an array of bytes to store the result
- * @outlen: the length of @out
- * @in: a pointer to an array of UTF-8 chars
- * @inlen: the length of @in
- *
- * Take a block of UTF-8 chars in and try to convert it to an ASCII
- * block of chars out.
- *
- * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
- * The value of @inlen after return is the number of octets consumed
- * as the return value is positive, else unpredictable.
- * The value of @outlen after return is the number of ocetes consumed.
- */
-static int
-UTF8Toascii(unsigned char* out, int *outlen,
- const unsigned char* in, int *inlen) {
- const unsigned char* processed = in;
- const unsigned char* outend;
- const unsigned char* outstart = out;
- const unsigned char* instart = in;
- const unsigned char* inend;
- unsigned int c, d;
- int trailing;
-
- if (in == NULL) {
- /*
- * initialization nothing to do
- */
- *outlen = 0;
- *inlen = 0;
- return(0);
- }
- inend = in + (*inlen);
- outend = out + (*outlen);
- while (in < inend) {
- d = *in++;
- if (d < 0x80) { c= d; trailing= 0; }
- else if (d < 0xC0) {
- /* trailing byte in leading position */
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
- else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
- else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
- else {
- /* no chance for this in Ascii */
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- }
-
- if (inend - in < trailing) {
- break;
- }
-
- for ( ; trailing; trailing--) {
- if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
- break;
- c <<= 6;
- c |= d & 0x3F;
- }
-
- /* assertion: c is a single UTF-4 value */
- if (c < 0x80) {
- if (out >= outend)
- break;
- *out++ = c;
- } else {
- /* no chance for this in Ascii */
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- }
- processed = in;
- }
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(0);
-}
-
-/**
- * isolat1ToUTF8:
- * @out: a pointer to an array of bytes to store the result
- * @outlen: the length of @out
- * @in: a pointer to an array of ISO Latin 1 chars
- * @inlen: the length of @in
- *
- * Take a block of ISO Latin 1 chars in and try to convert it to an UTF-8
- * block of chars out.
- * Returns 0 if success, or -1 otherwise
- * The value of @inlen after return is the number of octets consumed
- * as the return value is positive, else unpredictable.
- * The value of @outlen after return is the number of ocetes consumed.
- */
-int
-isolat1ToUTF8(unsigned char* out, int *outlen,
- const unsigned char* in, int *inlen) {
- unsigned char* outstart = out;
- const unsigned char* base = in;
- unsigned char* outend = out + *outlen;
- const unsigned char* inend;
- const unsigned char* instop;
- xmlChar c = *in;
-
- inend = in + (*inlen);
- instop = inend;
-
- while (in < inend && out < outend - 1) {
- if (c >= 0x80) {
- *out++= ((c >> 6) & 0x1F) | 0xC0;
- *out++= (c & 0x3F) | 0x80;
- ++in;
- c = *in;
- }
- if (instop - in > outend - out) instop = in + (outend - out);
- while (c < 0x80 && in < instop) {
- *out++ = c;
- ++in;
- c = *in;
- }
- }
- if (in < inend && out < outend && c < 0x80) {
- *out++ = c;
- ++in;
- }
- *outlen = out - outstart;
- *inlen = in - base;
- return(0);
-}
-
-
-/**
- * UTF8Toisolat1:
- * @out: a pointer to an array of bytes to store the result
- * @outlen: the length of @out
- * @in: a pointer to an array of UTF-8 chars
- * @inlen: the length of @in
- *
- * Take a block of UTF-8 chars in and try to convert it to an ISO Latin 1
- * block of chars out.
- *
- * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
- * The value of @inlen after return is the number of octets consumed
- * as the return value is positive, else unpredictable.
- * The value of @outlen after return is the number of ocetes consumed.
- */
-int
-UTF8Toisolat1(unsigned char* out, int *outlen,
- const unsigned char* in, int *inlen) {
- const unsigned char* processed = in;
- const unsigned char* outend;
- const unsigned char* outstart = out;
- const unsigned char* instart = in;
- const unsigned char* inend;
- unsigned int c, d;
- int trailing;
-
- if (in == NULL) {
- /*
- * initialization nothing to do
- */
- *outlen = 0;
- *inlen = 0;
- return(0);
- }
- inend = in + (*inlen);
- outend = out + (*outlen);
- while (in < inend) {
- d = *in++;
- if (d < 0x80) { c= d; trailing= 0; }
- else if (d < 0xC0) {
- /* trailing byte in leading position */
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
- else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
- else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
- else {
- /* no chance for this in IsoLat1 */
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- }
-
- if (inend - in < trailing) {
- break;
- }
-
- for ( ; trailing; trailing--) {
- if (in >= inend)
- break;
- if (((d= *in++) & 0xC0) != 0x80) {
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- }
- c <<= 6;
- c |= d & 0x3F;
- }
-
- /* assertion: c is a single UTF-4 value */
- if (c <= 0xFF) {
- if (out >= outend)
- break;
- *out++ = c;
- } else {
- /* no chance for this in IsoLat1 */
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(-2);
- }
- processed = in;
- }
- *outlen = out - outstart;
- *inlen = processed - instart;
- return(0);
-}
-
-/**
- * UTF16LEToUTF8:
- * @out: a pointer to an array of bytes to store the result
- * @outlen: the length of @out
- * @inb: a pointer to an array of UTF-16LE passwd as a byte array
- * @inlenb: the length of @in in UTF-16LE chars
- *
- * Take a block of UTF-16LE ushorts in and try to convert it to an UTF-8
- * block of chars out. This function assume the endian property
- * is the same between the native type of this machine and the
- * inputed one.
- *
- * Returns the number of byte written, or -1 by lack of space, or -2
- * if the transcoding fails (for *in is not valid utf16 string)
- * The value of *inlen after return is the number of octets consumed
- * as the return value is positive, else unpredictable.
- */
-static int
-UTF16LEToUTF8(unsigned char* out, int *outlen,
- const unsigned char* inb, int *inlenb)
-{
- unsigned char* outstart = out;
- const unsigned char* processed = inb;
- unsigned char* outend = out + *outlen;
- unsigned short* in = (unsigned short*) inb;
- unsigned short* inend;
- unsigned int c, d, inlen;
- unsigned char *tmp;
- int bits;
-
- if ((*inlenb % 2) == 1)
- (*inlenb)--;
- inlen = *inlenb / 2;
- inend = in + inlen;
- while ((in < inend) && (out - outstart + 5 < *outlen)) {
- if (xmlLittleEndian) {
- c= *in++;
- } else {
- tmp = (unsigned char *) in;
- c = *tmp++;
- c = c | (((unsigned int)*tmp) << 8);
- in++;
- }
- if ((c & 0xFC00) == 0xD800) { /* surrogates */
- if (in >= inend) { /* (in > inend) shouldn't happens */
- break;
- }
- if (xmlLittleEndian) {
- d = *in++;
- } else {
- tmp = (unsigned char *) in;
- d = *tmp++;
- d = d | (((unsigned int)*tmp) << 8);
- in++;
- }
- if ((d & 0xFC00) == 0xDC00) {
- c &= 0x03FF;
- c <<= 10;
- c |= d & 0x03FF;
- c += 0x10000;
- }
- else {
- *outlen = out - outstart;
- *inlenb = processed - inb;
- return(-2);
- }
- }
-
- /* assertion: c is a single UTF-4 value */
- if (out >= outend)
- break;
- if (c < 0x80) { *out++= c; bits= -6; }
- else if (c < 0x800) { *out++= ((c >> 6) & 0x1F) | 0xC0; bits= 0; }
- else if (c < 0x10000) { *out++= ((c >> 12) & 0x0F) | 0xE0; bits= 6; }
- else { *out++= ((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
- for ( ; bits >= 0; bits-= 6) {
- if (out >= outend)
- break;
- *out++= ((c >> bits) & 0x3F) | 0x80;
- }
- processed = (const unsigned char*) in;
- }
- *outlen = out - outstart;
- *inlenb = processed - inb;
- return(0);
-}
-
-/**
- * UTF8ToUTF16LE:
- * @outb: a pointer to an array of bytes to store the result
- * @outlen: the length of @outb
- * @in: a pointer to an array of UTF-8 chars
- * @inlen: the length of @in
- *
- * Take a block of UTF-8 chars in and try to convert it to an UTF-16LE
- * block of chars out.
- *
- * Returns the number of byte written, or -1 by lack of space, or -2
- * if the transcoding failed.
- */
-static int
-UTF8ToUTF16LE(unsigned char* outb, int *outlen,
- const unsigned char* in, int *inlen)
-{
- unsigned short* out = (unsigned short*) outb;
- const unsigned char* processed = in;
- unsigned short* outstart= out;
- unsigned short* outend;
- const unsigned char* inend= in+*inlen;
- unsigned int c, d;
- int trailing;
- unsigned char *tmp;
- unsigned short tmp1, tmp2;
-
- if (in == NULL) {
- /*
- * initialization, add the Byte Order Mark
- */
- if (*outlen >= 2) {
- outb[0] = 0xFF;
- outb[1] = 0xFE;
- *outlen = 2;
- *inlen = 0;
-#ifdef DEBUG_ENCODING
- xmlGenericError(xmlGenericErrorContext,
- "Added FFFE Byte Order Mark\n");
-#endif
- return(2);
- }
- *outlen = 0;
- *inlen = 0;
- return(0);
- }
- outend = out + (*outlen / 2);
- while (in < inend) {
- d= *in++;
- if (d < 0x80) { c= d; trailing= 0; }
- else if (d < 0xC0) {
- /* trailing byte in leading position */
- *outlen = (out - outstart) * 2;
- *inlen = processed - in;
- return(-2);
- } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
- else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
- else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
- else {
- /* no chance for this in UTF-16 */
- *outlen = (out - outstart) * 2;
- *inlen = processed - in;
- return(-2);
- }
-
- if (inend - in < trailing) {
- break;
- }
-
- for ( ; trailing; trailing--) {
- if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
- break;
- c <<= 6;
- c |= d & 0x3F;
- }
-
- /* assertion: c is a single UTF-4 value */
- if (c < 0x10000) {
- if (out >= outend)
- break;
- if (xmlLittleEndian) {
- *out++ = c;
- } else {
- tmp = (unsigned char *) out;
- *tmp = c ;
- *(tmp + 1) = c >> 8 ;
- out++;
- }
- }
- else if (c < 0x110000) {
- if (out+1 >= outend)
- break;
- c -= 0x10000;
- if (xmlLittleEndian) {
- *out++ = 0xD800 | (c >> 10);
- *out++ = 0xDC00 | (c & 0x03FF);
- } else {
- tmp1 = 0xD800 | (c >> 10);
- tmp = (unsigned char *) out;
- *tmp = (unsigned char) tmp1;
- *(tmp + 1) = tmp1 >> 8;
- out++;
-
- tmp2 = 0xDC00 | (c & 0x03FF);
- tmp = (unsigned char *) out;
- *tmp = (unsigned char) tmp2;
- *(tmp + 1) = tmp2 >> 8;
- out++;
- }
- }
- else
- break;
- processed = in;
- }
- *outlen = (out - outstart) * 2;
- *inlen = processed - in;
- return(0);
-}
-
-/**
- * UTF16BEToUTF8:
- * @out: a pointer to an array of bytes to store the result
- * @outlen: the length of @out
- * @inb: a pointer to an array of UTF-16 passwd as a byte array
- * @inlenb: the length of @in in UTF-16 chars
- *
- * Take a block of UTF-16 ushorts in and try to convert it to an UTF-8
- * block of chars out. This function assume the endian property
- * is the same between the native type of this machine and the
- * inputed one.
- *
- * Returns the number of byte written, or -1 by lack of space, or -2
- * if the transcoding fails (for *in is not valid utf16 string)
- * The value of *inlen after return is the number of octets consumed
- * as the return value is positive, else unpredictable.
- */
-static int
-UTF16BEToUTF8(unsigned char* out, int *outlen,
- const unsigned char* inb, int *inlenb)
-{
- unsigned char* outstart = out;
- const unsigned char* processed = inb;
- unsigned char* outend = out + *outlen;
- unsigned short* in = (unsigned short*) inb;
- unsigned short* inend;
- unsigned int c, d, inlen;
- unsigned char *tmp;
- int bits;
-
- if ((*inlenb % 2) == 1)
- (*inlenb)--;
- inlen = *inlenb / 2;
- inend= in + inlen;
- while (in < inend) {
- if (xmlLittleEndian) {
- tmp = (unsigned char *) in;
- c = *tmp++;
- c = c << 8;
- c = c | (unsigned int) *tmp;
- in++;
- } else {
- c= *in++;
- }
- if ((c & 0xFC00) == 0xD800) { /* surrogates */
- if (in >= inend) { /* (in > inend) shouldn't happens */
- *outlen = out - outstart;
- *inlenb = processed - inb;
- return(-2);
- }
- if (xmlLittleEndian) {
- tmp = (unsigned char *) in;
- d = *tmp++;
- d = d << 8;
- d = d | (unsigned int) *tmp;
- in++;
- } else {
- d= *in++;
- }
- if ((d & 0xFC00) == 0xDC00) {
- c &= 0x03FF;
- c <<= 10;
- c |= d & 0x03FF;
- c += 0x10000;
- }
- else {
- *outlen = out - outstart;
- *inlenb = processed - inb;
- return(-2);
- }
- }
-
- /* assertion: c is a single UTF-4 value */
- if (out >= outend)
- break;
- if (c < 0x80) { *out++= c; bits= -6; }
- else if (c < 0x800) { *out++= ((c >> 6) & 0x1F) | 0xC0; bits= 0; }
- else if (c < 0x10000) { *out++= ((c >> 12) & 0x0F) | 0xE0; bits= 6; }
- else { *out++= ((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
- for ( ; bits >= 0; bits-= 6) {
- if (out >= outend)
- break;
- *out++= ((c >> bits) & 0x3F) | 0x80;
- }
- processed = (const unsigned char*) in;
- }
- *outlen = out - outstart;
- *inlenb = processed - inb;
- return(0);
-}
-
-/**
- * UTF8ToUTF16BE:
- * @outb: a pointer to an array of bytes to store the result
- * @outlen: the length of @outb
- * @in: a pointer to an array of UTF-8 chars
- * @inlen: the length of @in
- *
- * Take a block of UTF-8 chars in and try to convert it to an UTF-16BE
- * block of chars out.
- *
- * Returns the number of byte written, or -1 by lack of space, or -2
- * if the transcoding failed.
- */
-static int
-UTF8ToUTF16BE(unsigned char* outb, int *outlen,
- const unsigned char* in, int *inlen)
-{
- unsigned short* out = (unsigned short*) outb;
- const unsigned char* processed = in;
- unsigned short* outstart= out;
- unsigned short* outend;
- const unsigned char* inend= in+*inlen;
- unsigned int c, d;
- int trailing;
- unsigned char *tmp;
- unsigned short tmp1, tmp2;
-
- if (in == NULL) {
- /*
- * initialization, add the Byte Order Mark
- */
- if (*outlen >= 2) {
- outb[0] = 0xFE;
- outb[1] = 0xFF;
- *outlen = 2;
- *inlen = 0;
-#ifdef DEBUG_ENCODING
- xmlGenericError(xmlGenericErrorContext,
- "Added FEFF Byte Order Mark\n");
-#endif
- return(2);
- }
- *outlen = 0;
- *inlen = 0;
- return(0);
- }
- outend = out + (*outlen / 2);
- while (in < inend) {
- d= *in++;
- if (d < 0x80) { c= d; trailing= 0; }
- else if (d < 0xC0) {
- /* trailing byte in leading position */
- *outlen = out - outstart;
- *inlen = processed - in;
- return(-2);
- } else if (d < 0xE0) { c= d & 0x1F; trailing= 1; }
- else if (d < 0xF0) { c= d & 0x0F; trailing= 2; }
- else if (d < 0xF8) { c= d & 0x07; trailing= 3; }
- else {
- /* no chance for this in UTF-16 */
- *outlen = out - outstart;
- *inlen = processed - in;
- return(-2);
- }
-
- if (inend - in < trailing) {
- break;
- }
-
- for ( ; trailing; trailing--) {
- if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80)) break;
- c <<= 6;
- c |= d & 0x3F;
- }
-
- /* assertion: c is a single UTF-4 value */
- if (c < 0x10000) {
- if (out >= outend) break;
- if (xmlLittleEndian) {
- tmp = (unsigned char *) out;
- *tmp = c >> 8;
- *(tmp + 1) = c;
- out++;
- } else {
- *out++ = c;
- }
- }
- else if (c < 0x110000) {
- if (out+1 >= outend) break;
- c -= 0x10000;
- if (xmlLittleEndian) {
- tmp1 = 0xD800 | (c >> 10);
- tmp = (unsigned char *) out;
- *tmp = tmp1 >> 8;
- *(tmp + 1) = (unsigned char) tmp1;
- out++;
-
- tmp2 = 0xDC00 | (c & 0x03FF);
- tmp = (unsigned char *) out;
- *tmp = tmp2 >> 8;
- *(tmp + 1) = (unsigned char) tmp2;
- out++;
- } else {
- *out++ = 0xD800 | (c >> 10);
- *out++ = 0xDC00 | (c & 0x03FF);
- }
- }
- else
- break;
- processed = in;
- }
- *outlen = (out - outstart) * 2;
- *inlen = processed - in;
- return(0);
-}
-
-/************************************************************************
- * *
- * Generic encoding handling routines *
- * *
- ************************************************************************/
-
-/**
- * xmlDetectCharEncoding:
- * @in: a pointer to the first bytes of the XML entity, must be at least
- * 4 bytes long.
- * @len: pointer to the length of the buffer
- *
- * Guess the encoding of the entity using the first bytes of the entity content
- * accordingly of the non-normative appendix F of the XML-1.0 recommendation.
- *
- * Returns one of the XML_CHAR_ENCODING_... values.
- */
-xmlCharEncoding
-xmlDetectCharEncoding(const unsigned char* in, int len)
-{
- if (len >= 4) {
- if ((in[0] == 0x00) && (in[1] == 0x00) &&
- (in[2] == 0x00) && (in[3] == 0x3C))
- return(XML_CHAR_ENCODING_UCS4BE);
- if ((in[0] == 0x3C) && (in[1] == 0x00) &&
- (in[2] == 0x00) && (in[3] == 0x00))
- return(XML_CHAR_ENCODING_UCS4LE);
- if ((in[0] == 0x00) && (in[1] == 0x00) &&
- (in[2] == 0x3C) && (in[3] == 0x00))
- return(XML_CHAR_ENCODING_UCS4_2143);
- if ((in[0] == 0x00) && (in[1] == 0x3C) &&
- (in[2] == 0x00) && (in[3] == 0x00))
- return(XML_CHAR_ENCODING_UCS4_3412);
- if ((in[0] == 0x4C) && (in[1] == 0x6F) &&
- (in[2] == 0xA7) && (in[3] == 0x94))
- return(XML_CHAR_ENCODING_EBCDIC);
- if ((in[0] == 0x3C) && (in[1] == 0x3F) &&
- (in[2] == 0x78) && (in[3] == 0x6D))
- return(XML_CHAR_ENCODING_UTF8);
- }
- if (len >= 3) {
- /*
- * Errata on XML-1.0 June 20 2001
- * We now allow an UTF8 encoded BOM
- */
- if ((in[0] == 0xEF) && (in[1] == 0xBB) &&
- (in[2] == 0xBF))
- return(XML_CHAR_ENCODING_UTF8);
- }
- if (len >= 2) {
- if ((in[0] == 0xFE) && (in[1] == 0xFF))
- return(XML_CHAR_ENCODING_UTF16BE);
- if ((in[0] == 0xFF) && (in[1] == 0xFE))
- return(XML_CHAR_ENCODING_UTF16LE);
- }
- return(XML_CHAR_ENCODING_NONE);
-}
-
-/**
- * xmlCleanupEncodingAliases:
- *
- * Unregisters all aliases
- */
-void
-xmlCleanupEncodingAliases(void) {
- int i;
-
- if (xmlCharEncodingAliases == NULL)
- return;
-
- for (i = 0;i < xmlCharEncodingAliasesNb;i++) {
- if (xmlCharEncodingAliases[i].name != NULL)
- xmlFree((char *) xmlCharEncodingAliases[i].name);
- if (xmlCharEncodingAliases[i].alias != NULL)
- xmlFree((char *) xmlCharEncodingAliases[i].alias);
- }
- xmlCharEncodingAliasesNb = 0;
- xmlCharEncodingAliasesMax = 0;
- xmlFree(xmlCharEncodingAliases);
- xmlCharEncodingAliases = NULL;
-}
-
-/**
- * xmlGetEncodingAlias:
- * @alias: the alias name as parsed, in UTF-8 format (ASCII actually)
- *
- * Lookup an encoding name for the given alias.
- *
- * Returns NULL if not found the original name otherwise
- */
-const char *
-xmlGetEncodingAlias(const char *alias) {
- int i;
- char upper[100];
-
- if (alias == NULL)
- return(NULL);
-
- if (xmlCharEncodingAliases == NULL)
- return(NULL);
-
- for (i = 0;i < 99;i++) {
- upper[i] = toupper(alias[i]);
- if (upper[i] == 0) break;
- }
- upper[i] = 0;
-
- /*
- * Walk down the list looking for a definition of the alias
- */
- for (i = 0;i < xmlCharEncodingAliasesNb;i++) {
- if (!strcmp(xmlCharEncodingAliases[i].alias, upper)) {
- return(xmlCharEncodingAliases[i].name);
- }
- }
- return(NULL);
-}
-
-/**
- * xmlAddEncodingAlias:
- * @name: the encoding name as parsed, in UTF-8 format (ASCII actually)
- * @alias: the alias name as parsed, in UTF-8 format (ASCII actually)
- *
- * Registers and alias @alias for an encoding named @name. Existing alias
- * will be overwritten.
- *
- * Returns 0 in case of success, -1 in case of error
- */
-int
-xmlAddEncodingAlias(const char *name, const char *alias) {
- int i;
- char upper[100];
-
- if ((name == NULL) || (alias == NULL))
- return(-1);
-
- for (i = 0;i < 99;i++) {
- upper[i] = toupper(alias[i]);
- if (upper[i] == 0) break;
- }
- upper[i] = 0;
-
- if (xmlCharEncodingAliases == NULL) {
- xmlCharEncodingAliasesNb = 0;
- xmlCharEncodingAliasesMax = 20;
- xmlCharEncodingAliases = (xmlCharEncodingAliasPtr)
- xmlMalloc(xmlCharEncodingAliasesMax * sizeof(xmlCharEncodingAlias));
- if (xmlCharEncodingAliases == NULL)
- return(-1);
- } else if (xmlCharEncodingAliasesNb >= xmlCharEncodingAliasesMax) {
- xmlCharEncodingAliasesMax *= 2;
- xmlCharEncodingAliases = (xmlCharEncodingAliasPtr)
- xmlRealloc(xmlCharEncodingAliases,
- xmlCharEncodingAliasesMax * sizeof(xmlCharEncodingAlias));
- }
- /*
- * Walk down the list looking for a definition of the alias
- */
- for (i = 0;i < xmlCharEncodingAliasesNb;i++) {
- if (!strcmp(xmlCharEncodingAliases[i].alias, upper)) {
- /*
- * Replace the definition.
- */
- xmlFree((char *) xmlCharEncodingAliases[i].name);
- xmlCharEncodingAliases[i].name = xmlMemStrdup(name);
- return(0);
- }
- }
- /*
- * Add the definition
- */
- xmlCharEncodingAliases[xmlCharEncodingAliasesNb].name = xmlMemStrdup(name);
- xmlCharEncodingAliases[xmlCharEncodingAliasesNb].alias = xmlMemStrdup(upper);
- xmlCharEncodingAliasesNb++;
- return(0);
-}
-
-/**
- * xmlDelEncodingAlias:
- * @alias: the alias name as parsed, in UTF-8 format (ASCII actually)
- *
- * Unregisters an encoding alias @alias
- *
- * Returns 0 in case of success, -1 in case of error
- */
-int
-xmlDelEncodingAlias(const char *alias) {
- int i;
-
- if (alias == NULL)
- return(-1);
-
- if (xmlCharEncodingAliases == NULL)
- return(-1);
- /*
- * Walk down the list looking for a definition of the alias
- */
- for (i = 0;i < xmlCharEncodingAliasesNb;i++) {
- if (!strcmp(xmlCharEncodingAliases[i].alias, alias)) {
- xmlFree((char *) xmlCharEncodingAliases[i].name);
- xmlFree((char *) xmlCharEncodingAliases[i].alias);
- xmlCharEncodingAliasesNb--;
- memmove(&xmlCharEncodingAliases[i], &xmlCharEncodingAliases[i + 1],
- sizeof(xmlCharEncodingAlias) * (xmlCharEncodingAliasesNb - i));
- return(0);
- }
- }
- return(-1);
-}
-
-/**
- * xmlParseCharEncoding:
- * @name: the encoding name as parsed, in UTF-8 format (ASCII actually)
- *
- * Compare the string to the known encoding schemes already known. Note
- * that the comparison is case insensitive accordingly to the section
- * [XML] 4.3.3 Character Encoding in Entities.
- *
- * Returns one of the XML_CHAR_ENCODING_... values or XML_CHAR_ENCODING_NONE
- * if not recognized.
- */
-xmlCharEncoding
-xmlParseCharEncoding(const char* name)
-{
- const char *alias;
- char upper[500];
- int i;
-
- if (name == NULL)
- return(XML_CHAR_ENCODING_NONE);
-
- /*
- * Do the alias resolution
- */
- alias = xmlGetEncodingAlias(name);
- if (alias != NULL)
- name = alias;
-
- for (i = 0;i < 499;i++) {
- upper[i] = toupper(name[i]);
- if (upper[i] == 0) break;
- }
- upper[i] = 0;
-
- if (!strcmp(upper, "")) return(XML_CHAR_ENCODING_NONE);
- if (!strcmp(upper, "UTF-8")) return(XML_CHAR_ENCODING_UTF8);
- if (!strcmp(upper, "UTF8")) return(XML_CHAR_ENCODING_UTF8);
-
- /*
- * NOTE: if we were able to parse this, the endianness of UTF16 is
- * already found and in use
- */
- if (!strcmp(upper, "UTF-16")) return(XML_CHAR_ENCODING_UTF16LE);
- if (!strcmp(upper, "UTF16")) return(XML_CHAR_ENCODING_UTF16LE);
-
- if (!strcmp(upper, "ISO-10646-UCS-2")) return(XML_CHAR_ENCODING_UCS2);
- if (!strcmp(upper, "UCS-2")) return(XML_CHAR_ENCODING_UCS2);
- if (!strcmp(upper, "UCS2")) return(XML_CHAR_ENCODING_UCS2);
-
- /*
- * NOTE: if we were able to parse this, the endianness of UCS4 is
- * already found and in use
- */
- if (!strcmp(upper, "ISO-10646-UCS-4")) return(XML_CHAR_ENCODING_UCS4LE);
- if (!strcmp(upper, "UCS-4")) return(XML_CHAR_ENCODING_UCS4LE);
- if (!strcmp(upper, "UCS4")) return(XML_CHAR_ENCODING_UCS4LE);
-
-
- if (!strcmp(upper, "ISO-8859-1")) return(XML_CHAR_ENCODING_8859_1);
- if (!strcmp(upper, "ISO-LATIN-1")) return(XML_CHAR_ENCODING_8859_1);
- if (!strcmp(upper, "ISO LATIN 1")) return(XML_CHAR_ENCODING_8859_1);
-
- if (!strcmp(upper, "ISO-8859-2")) return(XML_CHAR_ENCODING_8859_2);
- if (!strcmp(upper, "ISO-LATIN-2")) return(XML_CHAR_ENCODING_8859_2);
- if (!strcmp(upper, "ISO LATIN 2")) return(XML_CHAR_ENCODING_8859_2);
-
- if (!strcmp(upper, "ISO-8859-3")) return(XML_CHAR_ENCODING_8859_3);
- if (!strcmp(upper, "ISO-8859-4")) return(XML_CHAR_ENCODING_8859_4);
- if (!strcmp(upper, "ISO-8859-5")) return(XML_CHAR_ENCODING_8859_5);
- if (!strcmp(upper, "ISO-8859-6")) return(XML_CHAR_ENCODING_8859_6);
- if (!strcmp(upper, "ISO-8859-7")) return(XML_CHAR_ENCODING_8859_7);
- if (!strcmp(upper, "ISO-8859-8")) return(XML_CHAR_ENCODING_8859_8);
- if (!strcmp(upper, "ISO-8859-9")) return(XML_CHAR_ENCODING_8859_9);
-
- if (!strcmp(upper, "ISO-2022-JP")) return(XML_CHAR_ENCODING_2022_JP);
- if (!strcmp(upper, "SHIFT_JIS")) return(XML_CHAR_ENCODING_SHIFT_JIS);
- if (!strcmp(upper, "EUC-JP")) return(XML_CHAR_ENCODING_EUC_JP);
-
-#ifdef DEBUG_ENCODING
- xmlGenericError(xmlGenericErrorContext, "Unknown encoding %s\n", name);
-#endif
- return(XML_CHAR_ENCODING_ERROR);
-}
-
-/**
- * xmlGetCharEncodingName:
- * @enc: the encoding
- *
- * The "canonical" name for XML encoding.
- * C.f. http://www.w3.org/TR/REC-xml#charencoding
- * Section 4.3.3 Character Encoding in Entities
- *
- * Returns the canonical name for the given encoding
- */
-
-const char*
-xmlGetCharEncodingName(xmlCharEncoding enc) {
- switch (enc) {
- case XML_CHAR_ENCODING_ERROR:
- return(NULL);
- case XML_CHAR_ENCODING_NONE:
- return(NULL);
- case XML_CHAR_ENCODING_UTF8:
- return("UTF-8");
- case XML_CHAR_ENCODING_UTF16LE:
- return("UTF-16");
- case XML_CHAR_ENCODING_UTF16BE:
- return("UTF-16");
- case XML_CHAR_ENCODING_EBCDIC:
- return("EBCDIC");
- case XML_CHAR_ENCODING_UCS4LE:
- return("ISO-10646-UCS-4");
- case XML_CHAR_ENCODING_UCS4BE:
- return("ISO-10646-UCS-4");
- case XML_CHAR_ENCODING_UCS4_2143:
- return("ISO-10646-UCS-4");
- case XML_CHAR_ENCODING_UCS4_3412:
- return("ISO-10646-UCS-4");
- case XML_CHAR_ENCODING_UCS2:
- return("ISO-10646-UCS-2");
- case XML_CHAR_ENCODING_8859_1:
- return("ISO-8859-1");
- case XML_CHAR_ENCODING_8859_2:
- return("ISO-8859-2");
- case XML_CHAR_ENCODING_8859_3:
- return("ISO-8859-3");
- case XML_CHAR_ENCODING_8859_4:
- return("ISO-8859-4");
- case XML_CHAR_ENCODING_8859_5:
- return("ISO-8859-5");
- case XML_CHAR_ENCODING_8859_6:
- return("ISO-8859-6");
- case XML_CHAR_ENCODING_8859_7:
- return("ISO-8859-7");
- case XML_CHAR_ENCODING_8859_8:
- return("ISO-8859-8");
- case XML_CHAR_ENCODING_8859_9:
- return("ISO-8859-9");
- case XML_CHAR_ENCODING_2022_JP:
- return("ISO-2022-JP");
- case XML_CHAR_ENCODING_SHIFT_JIS:
- return("Shift-JIS");
- case XML_CHAR_ENCODING_EUC_JP:
- return("EUC-JP");
- case XML_CHAR_ENCODING_ASCII:
- return(NULL);
- }
- return(NULL);
-}
-
-/************************************************************************
- * *
- * Char encoding handlers *
- * *
- ************************************************************************/
-
-
-/* the size should be growable, but it's not a big deal ... */
-#define MAX_ENCODING_HANDLERS 50
-static xmlCharEncodingHandlerPtr *handlers = NULL;
-static int nbCharEncodingHandler = 0;
-
-/*
- * The default is UTF-8 for XML, that's also the default used for the
- * parser internals, so the default encoding handler is NULL
- */
-
-static xmlCharEncodingHandlerPtr xmlDefaultCharEncodingHandler = NULL;
-
-/**
- * xmlNewCharEncodingHandler:
- * @name: the encoding name, in UTF-8 format (ASCII actually)
- * @input: the xmlCharEncodingInputFunc to read that encoding
- * @output: the xmlCharEncodingOutputFunc to write that encoding
- *
- * Create and registers an xmlCharEncodingHandler.
- *
- * Returns the xmlCharEncodingHandlerPtr created (or NULL in case of error).
- */
-xmlCharEncodingHandlerPtr
-xmlNewCharEncodingHandler(const char *name,
- xmlCharEncodingInputFunc input,
- xmlCharEncodingOutputFunc output) {
- xmlCharEncodingHandlerPtr handler;
- const char *alias;
- char upper[500];
- int i;
- char *up = 0;
-
- /*
- * Do the alias resolution
- */
- alias = xmlGetEncodingAlias(name);
- if (alias != NULL)
- name = alias;
-
- /*
- * Keep only the uppercase version of the encoding.
- */
- if (name == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewCharEncodingHandler : no name !\n");
- return(NULL);
- }
- for (i = 0;i < 499;i++) {
- upper[i] = toupper(name[i]);
- if (upper[i] == 0) break;
- }
- upper[i] = 0;
- up = xmlMemStrdup(upper);
- if (up == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewCharEncodingHandler : out of memory !\n");
- return(NULL);
- }
-
- /*
- * allocate and fill-up an handler block.
- */
- handler = (xmlCharEncodingHandlerPtr)
- xmlMalloc(sizeof(xmlCharEncodingHandler));
- if (handler == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewCharEncodingHandler : out of memory !\n");
- return(NULL);
- }
- handler->input = input;
- handler->output = output;
- handler->name = up;
-
-#ifdef LIBXML_ICONV_ENABLED
- handler->iconv_in = NULL;
- handler->iconv_out = NULL;
-#endif /* LIBXML_ICONV_ENABLED */
-
- /*
- * registers and returns the handler.
- */
- xmlRegisterCharEncodingHandler(handler);
-#ifdef DEBUG_ENCODING
- xmlGenericError(xmlGenericErrorContext,
- "Registered encoding handler for %s\n", name);
-#endif
- return(handler);
-}
-
-/**
- * xmlInitCharEncodingHandlers:
- *
- * Initialize the char encoding support, it registers the default
- * encoding supported.
- * NOTE: while public, this function usually doesn't need to be called
- * in normal processing.
- */
-void
-xmlInitCharEncodingHandlers(void) {
- unsigned short int tst = 0x1234;
- unsigned char *ptr = (unsigned char *) &tst;
-
- if (handlers != NULL) return;
-
- handlers = (xmlCharEncodingHandlerPtr *)
- xmlMalloc(MAX_ENCODING_HANDLERS * sizeof(xmlCharEncodingHandlerPtr));
-
- if (*ptr == 0x12) xmlLittleEndian = 0;
- else if (*ptr == 0x34) xmlLittleEndian = 1;
- else xmlGenericError(xmlGenericErrorContext,
- "Odd problem at endianness detection\n");
-
- if (handlers == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlInitCharEncodingHandlers : out of memory !\n");
- return;
- }
- xmlNewCharEncodingHandler("UTF-8", NULL, NULL);
- xmlUTF16LEHandler =
- xmlNewCharEncodingHandler("UTF-16LE", UTF16LEToUTF8, UTF8ToUTF16LE);
- xmlUTF16BEHandler =
- xmlNewCharEncodingHandler("UTF-16BE", UTF16BEToUTF8, UTF8ToUTF16BE);
- xmlNewCharEncodingHandler("ISO-8859-1", isolat1ToUTF8, UTF8Toisolat1);
- xmlNewCharEncodingHandler("ASCII", asciiToUTF8, UTF8Toascii);
- xmlNewCharEncodingHandler("US-ASCII", asciiToUTF8, UTF8Toascii);
-#ifdef LIBXML_HTML_ENABLED
- xmlNewCharEncodingHandler("HTML", NULL, UTF8ToHtml);
-#endif
-}
-
-/**
- * xmlCleanupCharEncodingHandlers:
- *
- * Cleanup the memory allocated for the char encoding support, it
- * unregisters all the encoding handlers and the aliases.
- */
-void
-xmlCleanupCharEncodingHandlers(void) {
- xmlCleanupEncodingAliases();
-
- if (handlers == NULL) return;
-
- for (;nbCharEncodingHandler > 0;) {
- nbCharEncodingHandler--;
- if (handlers[nbCharEncodingHandler] != NULL) {
- if (handlers[nbCharEncodingHandler]->name != NULL)
- xmlFree(handlers[nbCharEncodingHandler]->name);
- xmlFree(handlers[nbCharEncodingHandler]);
- }
- }
- xmlFree(handlers);
- handlers = NULL;
- nbCharEncodingHandler = 0;
- xmlDefaultCharEncodingHandler = NULL;
-}
-
-/**
- * xmlRegisterCharEncodingHandler:
- * @handler: the xmlCharEncodingHandlerPtr handler block
- *
- * Register the char encoding handler, surprising, isn't it ?
- */
-void
-xmlRegisterCharEncodingHandler(xmlCharEncodingHandlerPtr handler) {
- if (handlers == NULL) xmlInitCharEncodingHandlers();
- if (handler == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlRegisterCharEncodingHandler: NULL handler !\n");
- return;
- }
-
- if (nbCharEncodingHandler >= MAX_ENCODING_HANDLERS) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlRegisterCharEncodingHandler: Too many handler registered\n");
- xmlGenericError(xmlGenericErrorContext,
- "\tincrease MAX_ENCODING_HANDLERS : %s\n", __FILE__);
- return;
- }
- handlers[nbCharEncodingHandler++] = handler;
-}
-
-/**
- * xmlGetCharEncodingHandler:
- * @enc: an xmlCharEncoding value.
- *
- * Search in the registered set the handler able to read/write that encoding.
- *
- * Returns the handler or NULL if not found
- */
-xmlCharEncodingHandlerPtr
-xmlGetCharEncodingHandler(xmlCharEncoding enc) {
- xmlCharEncodingHandlerPtr handler;
-
- if (handlers == NULL) xmlInitCharEncodingHandlers();
- switch (enc) {
- case XML_CHAR_ENCODING_ERROR:
- return(NULL);
- case XML_CHAR_ENCODING_NONE:
- return(NULL);
- case XML_CHAR_ENCODING_UTF8:
- return(NULL);
- case XML_CHAR_ENCODING_UTF16LE:
- return(xmlUTF16LEHandler);
- case XML_CHAR_ENCODING_UTF16BE:
- return(xmlUTF16BEHandler);
- case XML_CHAR_ENCODING_EBCDIC:
- handler = xmlFindCharEncodingHandler("EBCDIC");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("ebcdic");
- if (handler != NULL) return(handler);
- break;
- case XML_CHAR_ENCODING_UCS4BE:
- handler = xmlFindCharEncodingHandler("ISO-10646-UCS-4");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("UCS-4");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("UCS4");
- if (handler != NULL) return(handler);
- break;
- case XML_CHAR_ENCODING_UCS4LE:
- handler = xmlFindCharEncodingHandler("ISO-10646-UCS-4");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("UCS-4");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("UCS4");
- if (handler != NULL) return(handler);
- break;
- case XML_CHAR_ENCODING_UCS4_2143:
- break;
- case XML_CHAR_ENCODING_UCS4_3412:
- break;
- case XML_CHAR_ENCODING_UCS2:
- handler = xmlFindCharEncodingHandler("ISO-10646-UCS-2");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("UCS-2");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("UCS2");
- if (handler != NULL) return(handler);
- break;
-
- /*
- * We used to keep ISO Latin encodings native in the
- * generated data. This led to so many problems that
- * this has been removed. One can still change this
- * back by registering no-ops encoders for those
- */
- case XML_CHAR_ENCODING_8859_1:
- handler = xmlFindCharEncodingHandler("ISO-8859-1");
- if (handler != NULL) return(handler);
- break;
- case XML_CHAR_ENCODING_8859_2:
- handler = xmlFindCharEncodingHandler("ISO-8859-2");
- if (handler != NULL) return(handler);
- break;
- case XML_CHAR_ENCODING_8859_3:
- handler = xmlFindCharEncodingHandler("ISO-8859-3");
- if (handler != NULL) return(handler);
- break;
- case XML_CHAR_ENCODING_8859_4:
- handler = xmlFindCharEncodingHandler("ISO-8859-4");
- if (handler != NULL) return(handler);
- break;
- case XML_CHAR_ENCODING_8859_5:
- handler = xmlFindCharEncodingHandler("ISO-8859-5");
- if (handler != NULL) return(handler);
- break;
- case XML_CHAR_ENCODING_8859_6:
- handler = xmlFindCharEncodingHandler("ISO-8859-6");
- if (handler != NULL) return(handler);
- break;
- case XML_CHAR_ENCODING_8859_7:
- handler = xmlFindCharEncodingHandler("ISO-8859-7");
- if (handler != NULL) return(handler);
- break;
- case XML_CHAR_ENCODING_8859_8:
- handler = xmlFindCharEncodingHandler("ISO-8859-8");
- if (handler != NULL) return(handler);
- break;
- case XML_CHAR_ENCODING_8859_9:
- handler = xmlFindCharEncodingHandler("ISO-8859-9");
- if (handler != NULL) return(handler);
- break;
-
-
- case XML_CHAR_ENCODING_2022_JP:
- handler = xmlFindCharEncodingHandler("ISO-2022-JP");
- if (handler != NULL) return(handler);
- break;
- case XML_CHAR_ENCODING_SHIFT_JIS:
- handler = xmlFindCharEncodingHandler("SHIFT-JIS");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("SHIFT_JIS");
- if (handler != NULL) return(handler);
- handler = xmlFindCharEncodingHandler("Shift_JIS");
- if (handler != NULL) return(handler);
- break;
- case XML_CHAR_ENCODING_EUC_JP:
- handler = xmlFindCharEncodingHandler("EUC-JP");
- if (handler != NULL) return(handler);
- break;
- default:
- break;
- }
-
-#ifdef DEBUG_ENCODING
- xmlGenericError(xmlGenericErrorContext,
- "No handler found for encoding %d\n", enc);
-#endif
- return(NULL);
-}
-
-/**
- * xmlFindCharEncodingHandler:
- * @name: a string describing the char encoding.
- *
- * Search in the registered set the handler able to read/write that encoding.
- *
- * Returns the handler or NULL if not found
- */
-xmlCharEncodingHandlerPtr
-xmlFindCharEncodingHandler(const char *name) {
- const char *nalias;
- const char *norig;
- xmlCharEncoding alias;
-#ifdef LIBXML_ICONV_ENABLED
- xmlCharEncodingHandlerPtr enc;
- iconv_t icv_in, icv_out;
-#endif /* LIBXML_ICONV_ENABLED */
- char upper[100];
- int i;
-
- if (handlers == NULL) xmlInitCharEncodingHandlers();
- if (name == NULL) return(xmlDefaultCharEncodingHandler);
- if (name[0] == 0) return(xmlDefaultCharEncodingHandler);
-
- /*
- * Do the alias resolution
- */
- norig = name;
- nalias = xmlGetEncodingAlias(name);
- if (nalias != NULL)
- name = nalias;
-
- /*
- * Check first for directly registered encoding names
- */
- for (i = 0;i < 99;i++) {
- upper[i] = toupper(name[i]);
- if (upper[i] == 0) break;
- }
- upper[i] = 0;
-
- for (i = 0;i < nbCharEncodingHandler; i++)
- if (!strcmp(upper, handlers[i]->name)) {
-#ifdef DEBUG_ENCODING
- xmlGenericError(xmlGenericErrorContext,
- "Found registered handler for encoding %s\n", name);
-#endif
- return(handlers[i]);
- }
-
-#ifdef LIBXML_ICONV_ENABLED
- /* check whether iconv can handle this */
- icv_in = iconv_open("UTF-8", name);
- icv_out = iconv_open(name, "UTF-8");
- if ((icv_in != (iconv_t) -1) && (icv_out != (iconv_t) -1)) {
- enc = (xmlCharEncodingHandlerPtr)
- xmlMalloc(sizeof(xmlCharEncodingHandler));
- if (enc == NULL) {
- iconv_close(icv_in);
- iconv_close(icv_out);
- return(NULL);
- }
- enc->name = xmlMemStrdup(name);
- enc->input = NULL;
- enc->output = NULL;
- enc->iconv_in = icv_in;
- enc->iconv_out = icv_out;
-#ifdef DEBUG_ENCODING
- xmlGenericError(xmlGenericErrorContext,
- "Found iconv handler for encoding %s\n", name);
-#endif
- return enc;
- } else if ((icv_in != (iconv_t) -1) || icv_out != (iconv_t) -1) {
- xmlGenericError(xmlGenericErrorContext,
- "iconv : problems with filters for '%s'\n", name);
- }
-#endif /* LIBXML_ICONV_ENABLED */
-
-#ifdef DEBUG_ENCODING
- xmlGenericError(xmlGenericErrorContext,
- "No handler found for encoding %s\n", name);
-#endif
-
- /*
- * Fallback using the canonical names
- */
- alias = xmlParseCharEncoding(norig);
- if (alias != XML_CHAR_ENCODING_ERROR) {
- const char* canon;
- canon = xmlGetCharEncodingName(alias);
- if ((canon != NULL) && (strcmp(name, canon))) {
- return(xmlFindCharEncodingHandler(canon));
- }
- }
-
- return(NULL);
-}
-
-/************************************************************************
- * *
- * ICONV based generic conversion functions *
- * *
- ************************************************************************/
-
-#ifdef LIBXML_ICONV_ENABLED
-/**
- * xmlIconvWrapper:
- * @cd: iconv converter data structure
- * @out: a pointer to an array of bytes to store the result
- * @outlen: the length of @out
- * @in: a pointer to an array of ISO Latin 1 chars
- * @inlen: the length of @in
- *
- * Returns 0 if success, or
- * -1 by lack of space, or
- * -2 if the transcoding fails (for *in is not valid utf8 string or
- * the result of transformation can't fit into the encoding we want), or
- * -3 if there the last byte can't form a single output char.
- *
- * The value of @inlen after return is the number of octets consumed
- * as the return value is positive, else unpredictable.
- * The value of @outlen after return is the number of ocetes consumed.
- */
-static int
-xmlIconvWrapper(iconv_t cd,
- unsigned char *out, int *outlen,
- const unsigned char *in, int *inlen) {
-
- size_t icv_inlen = *inlen, icv_outlen = *outlen;
- const char *icv_in = (const char *) in;
- char *icv_out = (char *) out;
- int ret;
-
- ret = iconv(cd, (char **) &icv_in, &icv_inlen, &icv_out, &icv_outlen);
- if (in != NULL) {
- *inlen -= icv_inlen;
- *outlen -= icv_outlen;
- } else {
- *inlen = 0;
- *outlen = 0;
- }
- if ((icv_inlen != 0) || (ret == -1)) {
-#ifdef EILSEQ
- if (errno == EILSEQ) {
- return -2;
- } else
-#endif
-#ifdef E2BIG
- if (errno == E2BIG) {
- return -1;
- } else
-#endif
-#ifdef EINVAL
- if (errno == EINVAL) {
- return -3;
- } else
-#endif
- {
- return -3;
- }
- }
- return 0;
-}
-#endif /* LIBXML_ICONV_ENABLED */
-
-/************************************************************************
- * *
- * The real API used by libxml for on-the-fly conversion *
- * *
- ************************************************************************/
-
-/**
- * xmlCharEncFirstLine:
- * @handler: char enconding transformation data structure
- * @out: an xmlBuffer for the output.
- * @in: an xmlBuffer for the input
- *
- * Front-end for the encoding handler input function, but handle only
- * the very first line, i.e. limit itself to 45 chars.
- *
- * Returns the number of byte written if success, or
- * -1 general error
- * -2 if the transcoding fails (for *in is not valid utf8 string or
- * the result of transformation can't fit into the encoding we want), or
- */
-int
-xmlCharEncFirstLine(xmlCharEncodingHandler *handler, xmlBufferPtr out,
- xmlBufferPtr in) {
- int ret = -2;
- int written;
- int toconv;
-
- if (handler == NULL) return(-1);
- if (out == NULL) return(-1);
- if (in == NULL) return(-1);
-
- written = out->size - out->use;
- toconv = in->use;
- if (toconv * 2 >= written) {
- xmlBufferGrow(out, toconv);
- written = out->size - out->use - 1;
- }
-
- /*
- * echo '<?xml version="1.0" encoding="UCS4"?>' | wc -c => 38
- * 45 chars should be sufficient to reach the end of the encoding
- * declaration without going too far inside the document content.
- */
- written = 45;
-
- if (handler->input != NULL) {
- ret = handler->input(&out->content[out->use], &written,
- in->content, &toconv);
- xmlBufferShrink(in, toconv);
- out->use += written;
- out->content[out->use] = 0;
- }
-#ifdef LIBXML_ICONV_ENABLED
- else if (handler->iconv_in != NULL) {
- ret = xmlIconvWrapper(handler->iconv_in, &out->content[out->use],
- &written, in->content, &toconv);
- xmlBufferShrink(in, toconv);
- out->use += written;
- out->content[out->use] = 0;
- if (ret == -1) ret = -3;
- }
-#endif /* LIBXML_ICONV_ENABLED */
-#ifdef DEBUG_ENCODING
- switch (ret) {
- case 0:
- xmlGenericError(xmlGenericErrorContext,
- "converted %d bytes to %d bytes of input\n",
- toconv, written);
- break;
- case -1:
- xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of input, %d left\n",
- toconv, written, in->use);
- break;
- case -2:
- xmlGenericError(xmlGenericErrorContext,
- "input conversion failed due to input error\n");
- break;
- case -3:
- xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of input, %d left\n",
- toconv, written, in->use);
- break;
- default:
- xmlGenericError(xmlGenericErrorContext,"Unknown input conversion failed %d\n", ret);
- }
-#endif /* DEBUG_ENCODING */
- /*
- * Ignore when input buffer is not on a boundary
- */
- if (ret == -3) ret = 0;
- if (ret == -1) ret = 0;
- return(ret);
-}
-
-/**
- * xmlCharEncInFunc:
- * @handler: char encoding transformation data structure
- * @out: an xmlBuffer for the output.
- * @in: an xmlBuffer for the input
- *
- * Generic front-end for the encoding handler input function
- *
- * Returns the number of byte written if success, or
- * -1 general error
- * -2 if the transcoding fails (for *in is not valid utf8 string or
- * the result of transformation can't fit into the encoding we want), or
- */
-int
-xmlCharEncInFunc(xmlCharEncodingHandler * handler, xmlBufferPtr out,
- xmlBufferPtr in)
-{
- int ret = -2;
- int written;
- int toconv;
-
- if (handler == NULL)
- return (-1);
- if (out == NULL)
- return (-1);
- if (in == NULL)
- return (-1);
-
- toconv = in->use;
- if (toconv == 0)
- return (0);
- written = out->size - out->use;
- if (toconv * 2 >= written) {
- xmlBufferGrow(out, out->size + toconv * 2);
- written = out->size - out->use - 1;
- }
- if (handler->input != NULL) {
- ret = handler->input(&out->content[out->use], &written,
- in->content, &toconv);
- xmlBufferShrink(in, toconv);
- out->use += written;
- out->content[out->use] = 0;
- }
-#ifdef LIBXML_ICONV_ENABLED
- else if (handler->iconv_in != NULL) {
- ret = xmlIconvWrapper(handler->iconv_in, &out->content[out->use],
- &written, in->content, &toconv);
- xmlBufferShrink(in, toconv);
- out->use += written;
- out->content[out->use] = 0;
- if (ret == -1)
- ret = -3;
- }
-#endif /* LIBXML_ICONV_ENABLED */
- switch (ret) {
- case 0:
-#ifdef DEBUG_ENCODING
- xmlGenericError(xmlGenericErrorContext,
- "converted %d bytes to %d bytes of input\n",
- toconv, written);
-#endif
- break;
- case -1:
-#ifdef DEBUG_ENCODING
- xmlGenericError(xmlGenericErrorContext,
- "converted %d bytes to %d bytes of input, %d left\n",
- toconv, written, in->use);
-#endif
- break;
- case -3:
-#ifdef DEBUG_ENCODING
- xmlGenericError(xmlGenericErrorContext,
- "converted %d bytes to %d bytes of input, %d left\n",
- toconv, written, in->use);
-#endif
- break;
- case -2:
- xmlGenericError(xmlGenericErrorContext,
- "input conversion failed due to input error\n");
- xmlGenericError(xmlGenericErrorContext,
- "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
- in->content[0], in->content[1],
- in->content[2], in->content[3]);
- }
- /*
- * Ignore when input buffer is not on a boundary
- */
- if (ret == -3)
- ret = 0;
- return (written);
-}
-
-/**
- * xmlCharEncOutFunc:
- * @handler: char enconding transformation data structure
- * @out: an xmlBuffer for the output.
- * @in: an xmlBuffer for the input
- *
- * Generic front-end for the encoding handler output function
- * a first call with @in == NULL has to be made firs to initiate the
- * output in case of non-stateless encoding needing to initiate their
- * state or the output (like the BOM in UTF16).
- * In case of UTF8 sequence conversion errors for the given encoder,
- * the content will be automatically remapped to a CharRef sequence.
- *
- * Returns the number of byte written if success, or
- * -1 general error
- * -2 if the transcoding fails (for *in is not valid utf8 string or
- * the result of transformation can't fit into the encoding we want), or
- */
-int
-xmlCharEncOutFunc(xmlCharEncodingHandler *handler, xmlBufferPtr out,
- xmlBufferPtr in) {
- int ret = -2;
- int written;
- int writtentot = 0;
- int toconv;
- int output = 0;
-
- if (handler == NULL) return(-1);
- if (out == NULL) return(-1);
-
-retry:
-
- written = out->size - out->use;
-
- /*
- * First specific handling of in = NULL, i.e. the initialization call
- */
- if (in == NULL) {
- toconv = 0;
- if (handler->output != NULL) {
- ret = handler->output(&out->content[out->use], &written,
- NULL, &toconv);
- out->use += written;
- out->content[out->use] = 0;
- }
-#ifdef LIBXML_ICONV_ENABLED
- else if (handler->iconv_out != NULL) {
- ret = xmlIconvWrapper(handler->iconv_out, &out->content[out->use],
- &written, NULL, &toconv);
- out->use += written;
- out->content[out->use] = 0;
- }
-#endif /* LIBXML_ICONV_ENABLED */
-#ifdef DEBUG_ENCODING
- xmlGenericError(xmlGenericErrorContext,
- "initialized encoder\n");
-#endif
- return(0);
- }
-
- /*
- * Conversion itself.
- */
- toconv = in->use;
- if (toconv == 0)
- return(0);
- if (toconv * 2 >= written) {
- xmlBufferGrow(out, toconv * 2);
- written = out->size - out->use - 1;
- }
- if (handler->output != NULL) {
- ret = handler->output(&out->content[out->use], &written,
- in->content, &toconv);
- xmlBufferShrink(in, toconv);
- out->use += written;
- writtentot += written;
- out->content[out->use] = 0;
- }
-#ifdef LIBXML_ICONV_ENABLED
- else if (handler->iconv_out != NULL) {
- ret = xmlIconvWrapper(handler->iconv_out, &out->content[out->use],
- &written, in->content, &toconv);
- xmlBufferShrink(in, toconv);
- out->use += written;
- writtentot += written;
- out->content[out->use] = 0;
- if (ret == -1) {
- if (written > 0) {
- /*
- * Can be a limitation of iconv
- */
- goto retry;
- }
- ret = -3;
- }
- }
-#endif /* LIBXML_ICONV_ENABLED */
- else {
- xmlGenericError(xmlGenericErrorContext,
- "xmlCharEncOutFunc: no output function !\n");
- return(-1);
- }
-
- if (ret >= 0) output += ret;
-
- /*
- * Attempt to handle error cases
- */
- switch (ret) {
- case 0:
-#ifdef DEBUG_ENCODING
- xmlGenericError(xmlGenericErrorContext,
- "converted %d bytes to %d bytes of output\n",
- toconv, written);
-#endif
- break;
- case -1:
-#ifdef DEBUG_ENCODING
- xmlGenericError(xmlGenericErrorContext,
- "output conversion failed by lack of space\n");
-#endif
- break;
- case -3:
- xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of output %d left\n",
- toconv, written, in->use);
- break;
- case -2: {
- int len = in->use;
- const xmlChar *utf = (const xmlChar *) in->content;
- int cur;
-
- cur = xmlGetUTF8Char(utf, &len);
- if (cur > 0) {
- xmlChar charref[20];
-
-#ifdef DEBUG_ENCODING
- xmlGenericError(xmlGenericErrorContext,
- "handling output conversion error\n");
- xmlGenericError(xmlGenericErrorContext,
- "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
- in->content[0], in->content[1],
- in->content[2], in->content[3]);
-#endif
- /*
- * Removes the UTF8 sequence, and replace it by a charref
- * and continue the transcoding phase, hoping the error
- * did not mangle the encoder state.
- */
- snprintf((char *) charref, sizeof(charref), "&#%d;", cur);
- xmlBufferShrink(in, len);
- xmlBufferAddHead(in, charref, -1);
-
- goto retry;
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "output conversion failed due to conv error\n");
- xmlGenericError(xmlGenericErrorContext,
- "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
- in->content[0], in->content[1],
- in->content[2], in->content[3]);
- in->content[0] = ' ';
- }
- break;
- }
- }
- return(ret);
-}
-
-/**
- * xmlCharEncCloseFunc:
- * @handler: char enconding transformation data structure
- *
- * Generic front-end for encoding handler close function
- *
- * Returns 0 if success, or -1 in case of error
- */
-int
-xmlCharEncCloseFunc(xmlCharEncodingHandler *handler) {
- int ret = 0;
- if (handler == NULL) return(-1);
- if (handler->name == NULL) return(-1);
-#ifdef LIBXML_ICONV_ENABLED
- /*
- * Iconv handlers can be used only once, free the whole block.
- * and the associated icon resources.
- */
- if ((handler->iconv_out != NULL) || (handler->iconv_in != NULL)) {
- if (handler->name != NULL)
- xmlFree(handler->name);
- handler->name = NULL;
- if (handler->iconv_out != NULL) {
- if (iconv_close(handler->iconv_out))
- ret = -1;
- handler->iconv_out = NULL;
- }
- if (handler->iconv_in != NULL) {
- if (iconv_close(handler->iconv_in))
- ret = -1;
- handler->iconv_in = NULL;
- }
- xmlFree(handler);
- }
-#endif /* LIBXML_ICONV_ENABLED */
-#ifdef DEBUG_ENCODING
- if (ret)
- xmlGenericError(xmlGenericErrorContext,
- "failed to close the encoding handler\n");
- else
- xmlGenericError(xmlGenericErrorContext,
- "closed the encoding handler\n");
-#endif
-
- return(ret);
-}
-
diff --git a/bundle/libxml/entities.c b/bundle/libxml/entities.c
deleted file mode 100644
index dbdf9ebf32..0000000000
--- a/bundle/libxml/entities.c
+++ /dev/null
@@ -1,1006 +0,0 @@
-/*
- * entities.c : implementation for the XML entities handling
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#include <string.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <libxml/xmlmemory.h>
-#include <libxml/hash.h>
-#include <libxml/entities.h>
-#include <libxml/parser.h>
-#include <libxml/xmlerror.h>
-#include <libxml/globals.h>
-
-/*
- * The XML predefined entities.
- */
-
-struct xmlPredefinedEntityValue {
- const char *name;
- const char *value;
-};
-static struct xmlPredefinedEntityValue xmlPredefinedEntityValues[] = {
- { "lt", "<" },
- { "gt", ">" },
- { "apos", "'" },
- { "quot", "\"" },
- { "amp", "&" }
-};
-
-/*
- * TODO: This is GROSS, allocation of a 256 entry hash for
- * a fixed number of 4 elements !
- */
-static xmlHashTablePtr xmlPredefinedEntities = NULL;
-
-/*
- * xmlFreeEntity : clean-up an entity record.
- */
-static void xmlFreeEntity(xmlEntityPtr entity) {
- if (entity == NULL) return;
-
- if ((entity->children) &&
- (entity == (xmlEntityPtr) entity->children->parent))
- xmlFreeNodeList(entity->children);
- if (entity->name != NULL)
- xmlFree((char *) entity->name);
- if (entity->ExternalID != NULL)
- xmlFree((char *) entity->ExternalID);
- if (entity->SystemID != NULL)
- xmlFree((char *) entity->SystemID);
- if (entity->URI != NULL)
- xmlFree((char *) entity->URI);
- if (entity->content != NULL)
- xmlFree((char *) entity->content);
- if (entity->orig != NULL)
- xmlFree((char *) entity->orig);
- xmlFree(entity);
-}
-
-/*
- * xmlAddEntity : register a new entity for an entities table.
- */
-static xmlEntityPtr
-xmlAddEntity(xmlDtdPtr dtd, const xmlChar *name, int type,
- const xmlChar *ExternalID, const xmlChar *SystemID,
- const xmlChar *content) {
- xmlEntitiesTablePtr table = NULL;
- xmlEntityPtr ret;
-
- if (name == NULL)
- return(NULL);
- switch (type) {
- case XML_INTERNAL_GENERAL_ENTITY:
- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
- if (dtd->entities == NULL)
- dtd->entities = xmlHashCreate(0);
- table = dtd->entities;
- break;
- case XML_INTERNAL_PARAMETER_ENTITY:
- case XML_EXTERNAL_PARAMETER_ENTITY:
- if (dtd->pentities == NULL)
- dtd->pentities = xmlHashCreate(0);
- table = dtd->pentities;
- break;
- case XML_INTERNAL_PREDEFINED_ENTITY:
- if (xmlPredefinedEntities == NULL)
- xmlPredefinedEntities = xmlHashCreate(8);
- table = xmlPredefinedEntities;
- }
- if (table == NULL)
- return(NULL);
- ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddEntity: out of memory\n");
- return(NULL);
- }
- memset(ret, 0, sizeof(xmlEntity));
- ret->type = XML_ENTITY_DECL;
-
- /*
- * fill the structure.
- */
- ret->name = xmlStrdup(name);
- ret->etype = (xmlEntityType) type;
- if (ExternalID != NULL)
- ret->ExternalID = xmlStrdup(ExternalID);
- if (SystemID != NULL)
- ret->SystemID = xmlStrdup(SystemID);
- if (content != NULL) {
- ret->length = xmlStrlen(content);
- ret->content = xmlStrndup(content, ret->length);
- } else {
- ret->length = 0;
- ret->content = NULL;
- }
- ret->URI = NULL; /* to be computed by the layer knowing
- the defining entity */
- ret->orig = NULL;
-
- if (xmlHashAddEntry(table, name, ret)) {
- /*
- * entity was already defined at another level.
- */
- xmlFreeEntity(ret);
- return(NULL);
- }
- return(ret);
-}
-
-/**
- * xmlInitializePredefinedEntities:
- *
- * Set up the predefined entities.
- */
-void xmlInitializePredefinedEntities(void) {
- unsigned int i;
- xmlChar name[50];
- xmlChar value[50];
- const char *in;
- xmlChar *out;
-
- if (xmlPredefinedEntities != NULL) return;
-
- xmlPredefinedEntities = xmlCreateEntitiesTable();
- for (i = 0;i < sizeof(xmlPredefinedEntityValues) /
- sizeof(xmlPredefinedEntityValues[0]);i++) {
- in = xmlPredefinedEntityValues[i].name;
- out = &name[0];
- for (;(*out++ = (xmlChar) *in);)in++;
- in = xmlPredefinedEntityValues[i].value;
- out = &value[0];
- for (;(*out++ = (xmlChar) *in);)in++;
-
- xmlAddEntity(NULL, (const xmlChar *) &name[0],
- XML_INTERNAL_PREDEFINED_ENTITY, NULL, NULL,
- &value[0]);
- }
-}
-
-/**
- * xmlCleanupPredefinedEntities:
- *
- * Cleanup up the predefined entities table.
- */
-void xmlCleanupPredefinedEntities(void) {
- if (xmlPredefinedEntities == NULL) return;
-
- xmlFreeEntitiesTable(xmlPredefinedEntities);
- xmlPredefinedEntities = NULL;
-}
-
-/**
- * xmlGetPredefinedEntity:
- * @name: the entity name
- *
- * Check whether this name is an predefined entity.
- *
- * Returns NULL if not, otherwise the entity
- */
-xmlEntityPtr
-xmlGetPredefinedEntity(const xmlChar *name) {
- if (xmlPredefinedEntities == NULL)
- xmlInitializePredefinedEntities();
- return((xmlEntityPtr) xmlHashLookup(xmlPredefinedEntities, name));
-}
-
-/**
- * xmlAddDtdEntity:
- * @doc: the document
- * @name: the entity name
- * @type: the entity type XML_xxx_yyy_ENTITY
- * @ExternalID: the entity external ID if available
- * @SystemID: the entity system ID if available
- * @content: the entity content
- *
- * Register a new entity for this document DTD external subset.
- *
- * Returns a pointer to the entity or NULL in case of error
- */
-xmlEntityPtr
-xmlAddDtdEntity(xmlDocPtr doc, const xmlChar *name, int type,
- const xmlChar *ExternalID, const xmlChar *SystemID,
- const xmlChar *content) {
- xmlEntityPtr ret;
- xmlDtdPtr dtd;
-
- if (doc == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddDtdEntity: doc == NULL !\n");
- return(NULL);
- }
- if (doc->extSubset == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddDtdEntity: document without external subset !\n");
- return(NULL);
- }
- dtd = doc->extSubset;
- ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content);
- if (ret == NULL) return(NULL);
-
- /*
- * Link it to the DTD
- */
- ret->parent = dtd;
- ret->doc = dtd->doc;
- if (dtd->last == NULL) {
- dtd->children = dtd->last = (xmlNodePtr) ret;
- } else {
- dtd->last->next = (xmlNodePtr) ret;
- ret->prev = dtd->last;
- dtd->last = (xmlNodePtr) ret;
- }
- return(ret);
-}
-
-/**
- * xmlAddDocEntity:
- * @doc: the document
- * @name: the entity name
- * @type: the entity type XML_xxx_yyy_ENTITY
- * @ExternalID: the entity external ID if available
- * @SystemID: the entity system ID if available
- * @content: the entity content
- *
- * Register a new entity for this document.
- *
- * Returns a pointer to the entity or NULL in case of error
- */
-xmlEntityPtr
-xmlAddDocEntity(xmlDocPtr doc, const xmlChar *name, int type,
- const xmlChar *ExternalID, const xmlChar *SystemID,
- const xmlChar *content) {
- xmlEntityPtr ret;
- xmlDtdPtr dtd;
-
- if (doc == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddDocEntity: document is NULL !\n");
- return(NULL);
- }
- if (doc->intSubset == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddDocEntity: document without internal subset !\n");
- return(NULL);
- }
- dtd = doc->intSubset;
- ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content);
- if (ret == NULL) return(NULL);
-
- /*
- * Link it to the DTD
- */
- ret->parent = dtd;
- ret->doc = dtd->doc;
- if (dtd->last == NULL) {
- dtd->children = dtd->last = (xmlNodePtr) ret;
- } else {
- dtd->last->next = (xmlNodePtr) ret;
- ret->prev = dtd->last;
- dtd->last = (xmlNodePtr) ret;
- }
- return(ret);
-}
-
-/**
- * xmlGetEntityFromTable:
- * @table: an entity table
- * @name: the entity name
- * @parameter: look for parameter entities
- *
- * Do an entity lookup in the table.
- * returns the corresponding parameter entity, if found.
- *
- * Returns A pointer to the entity structure or NULL if not found.
- */
-static xmlEntityPtr
-xmlGetEntityFromTable(xmlEntitiesTablePtr table, const xmlChar *name) {
- return((xmlEntityPtr) xmlHashLookup(table, name));
-}
-
-/**
- * xmlGetParameterEntity:
- * @doc: the document referencing the entity
- * @name: the entity name
- *
- * Do an entity lookup in the internal and external subsets and
- * returns the corresponding parameter entity, if found.
- *
- * Returns A pointer to the entity structure or NULL if not found.
- */
-xmlEntityPtr
-xmlGetParameterEntity(xmlDocPtr doc, const xmlChar *name) {
- xmlEntitiesTablePtr table;
- xmlEntityPtr ret;
-
- if (doc == NULL)
- return(NULL);
- if ((doc->intSubset != NULL) && (doc->intSubset->pentities != NULL)) {
- table = (xmlEntitiesTablePtr) doc->intSubset->pentities;
- ret = xmlGetEntityFromTable(table, name);
- if (ret != NULL)
- return(ret);
- }
- if ((doc->extSubset != NULL) && (doc->extSubset->pentities != NULL)) {
- table = (xmlEntitiesTablePtr) doc->extSubset->pentities;
- return(xmlGetEntityFromTable(table, name));
- }
- return(NULL);
-}
-
-/**
- * xmlGetDtdEntity:
- * @doc: the document referencing the entity
- * @name: the entity name
- *
- * Do an entity lookup in the DTD entity hash table and
- * returns the corresponding entity, if found.
- * Note: the first argument is the document node, not the DTD node.
- *
- * Returns A pointer to the entity structure or NULL if not found.
- */
-xmlEntityPtr
-xmlGetDtdEntity(xmlDocPtr doc, const xmlChar *name) {
- xmlEntitiesTablePtr table;
-
- if (doc == NULL)
- return(NULL);
- if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
- table = (xmlEntitiesTablePtr) doc->extSubset->entities;
- return(xmlGetEntityFromTable(table, name));
- }
- return(NULL);
-}
-
-/**
- * xmlGetDocEntity:
- * @doc: the document referencing the entity
- * @name: the entity name
- *
- * Do an entity lookup in the document entity hash table and
- * returns the corresponding entity, otherwise a lookup is done
- * in the predefined entities too.
- *
- * Returns A pointer to the entity structure or NULL if not found.
- */
-xmlEntityPtr
-xmlGetDocEntity(xmlDocPtr doc, const xmlChar *name) {
- xmlEntityPtr cur;
- xmlEntitiesTablePtr table;
-
- if (doc != NULL) {
- if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
- table = (xmlEntitiesTablePtr) doc->intSubset->entities;
- cur = xmlGetEntityFromTable(table, name);
- if (cur != NULL)
- return(cur);
- }
- if (doc->standalone != 1) {
- if ((doc->extSubset != NULL) &&
- (doc->extSubset->entities != NULL)) {
- table = (xmlEntitiesTablePtr) doc->extSubset->entities;
- cur = xmlGetEntityFromTable(table, name);
- if (cur != NULL)
- return(cur);
- }
- }
- }
- if (xmlPredefinedEntities == NULL)
- xmlInitializePredefinedEntities();
- table = xmlPredefinedEntities;
- return(xmlGetEntityFromTable(table, name));
-}
-
-/*
- * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
- * | [#x10000-#x10FFFF]
- * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
- */
-#define IS_CHAR(c) \
- (((c) == 0x09) || ((c) == 0x0a) || ((c) == 0x0d) || \
- (((c) >= 0x20) && ((c) != 0xFFFE) && ((c) != 0xFFFF)))
-
-/*
- * A buffer used for converting entities to their equivalent and back.
- */
-static int static_buffer_size = 0;
-static xmlChar *static_buffer = NULL;
-
-static int growBuffer(void) {
- static_buffer_size *= 2;
- static_buffer = (xmlChar *) xmlRealloc(static_buffer,
- static_buffer_size * sizeof(xmlChar));
- if (static_buffer == NULL) {
- xmlGenericError(xmlGenericErrorContext, "malloc failed\n");
- return(-1);
- }
- return(0);
-}
-
-
-/**
- * xmlEncodeEntities:
- * @doc: the document containing the string
- * @input: A string to convert to XML.
- *
- * Do a global encoding of a string, replacing the predefined entities
- * and non ASCII values with their entities and CharRef counterparts.
- *
- * TODO: remove xmlEncodeEntities, once we are not afraid of breaking binary
- * compatibility
- *
- * People must migrate their code to xmlEncodeEntitiesReentrant !
- * This routine will issue a warning when encountered.
- *
- * Returns A newly allocated string with the substitution done.
- */
-const xmlChar *
-xmlEncodeEntities(xmlDocPtr doc, const xmlChar *input) {
- const xmlChar *cur = input;
- xmlChar *out = static_buffer;
- static int warning = 1;
- int html = 0;
-
-
- if (warning) {
- xmlGenericError(xmlGenericErrorContext,
- "Deprecated API xmlEncodeEntities() used\n");
- xmlGenericError(xmlGenericErrorContext,
- " change code to use xmlEncodeEntitiesReentrant()\n");
- warning = 0;
- }
-
- if (input == NULL) return(NULL);
- if (doc != NULL)
- html = (doc->type == XML_HTML_DOCUMENT_NODE);
-
- if (static_buffer == NULL) {
- static_buffer_size = 1000;
- static_buffer = (xmlChar *)
- xmlMalloc(static_buffer_size * sizeof(xmlChar));
- if (static_buffer == NULL) {
- xmlGenericError(xmlGenericErrorContext, "malloc failed\n");
- return(NULL);
- }
- out = static_buffer;
- }
- while (*cur != '\0') {
- if (out - static_buffer > static_buffer_size - 100) {
- int indx = out - static_buffer;
-
- growBuffer();
- out = &static_buffer[indx];
- }
-
- /*
- * By default one have to encode at least '<', '>', '"' and '&' !
- */
- if (*cur == '<') {
- *out++ = '&';
- *out++ = 'l';
- *out++ = 't';
- *out++ = ';';
- } else if (*cur == '>') {
- *out++ = '&';
- *out++ = 'g';
- *out++ = 't';
- *out++ = ';';
- } else if (*cur == '&') {
- *out++ = '&';
- *out++ = 'a';
- *out++ = 'm';
- *out++ = 'p';
- *out++ = ';';
- } else if (*cur == '"') {
- *out++ = '&';
- *out++ = 'q';
- *out++ = 'u';
- *out++ = 'o';
- *out++ = 't';
- *out++ = ';';
- } else if ((*cur == '\'') && (!html)) {
- *out++ = '&';
- *out++ = 'a';
- *out++ = 'p';
- *out++ = 'o';
- *out++ = 's';
- *out++ = ';';
- } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
- (*cur == '\n') || (*cur == '\r') || (*cur == '\t')) {
- /*
- * default case, just copy !
- */
- *out++ = *cur;
-#ifndef USE_UTF_8
- } else if ((sizeof(xmlChar) == 1) && (*cur >= 0x80)) {
- char buf[10], *ptr;
-
- snprintf(buf, sizeof(buf), "&#%d;", *cur);
- buf[sizeof(buf) - 1] = 0;
- ptr = buf;
- while (*ptr != 0) *out++ = *ptr++;
-#endif
- } else if (IS_CHAR(*cur)) {
- char buf[10], *ptr;
-
- snprintf(buf, sizeof(buf), "&#%d;", *cur);
- buf[sizeof(buf) - 1] = 0;
- ptr = buf;
- while (*ptr != 0) *out++ = *ptr++;
- }
-#if 0
- else {
- /*
- * default case, this is not a valid char !
- * Skip it...
- */
- xmlGenericError(xmlGenericErrorContext,
- "xmlEncodeEntities: invalid char %d\n", (int) *cur);
- }
-#endif
- cur++;
- }
- *out++ = 0;
- return(static_buffer);
-}
-
-/*
- * Macro used to grow the current buffer.
- */
-#define growBufferReentrant() { \
- buffer_size *= 2; \
- buffer = (xmlChar *) \
- xmlRealloc(buffer, buffer_size * sizeof(xmlChar)); \
- if (buffer == NULL) { \
- xmlGenericError(xmlGenericErrorContext, "realloc failed\n"); \
- return(NULL); \
- } \
-}
-
-
-/**
- * xmlEncodeEntitiesReentrant:
- * @doc: the document containing the string
- * @input: A string to convert to XML.
- *
- * Do a global encoding of a string, replacing the predefined entities
- * and non ASCII values with their entities and CharRef counterparts.
- * Contrary to xmlEncodeEntities, this routine is reentrant, and result
- * must be deallocated.
- *
- * Returns A newly allocated string with the substitution done.
- */
-xmlChar *
-xmlEncodeEntitiesReentrant(xmlDocPtr doc, const xmlChar *input) {
- const xmlChar *cur = input;
- xmlChar *buffer = NULL;
- xmlChar *out = NULL;
- int buffer_size = 0;
- int html = 0;
-
- if (input == NULL) return(NULL);
- if (doc != NULL)
- html = (doc->type == XML_HTML_DOCUMENT_NODE);
-
- /*
- * allocate an translation buffer.
- */
- buffer_size = 1000;
- buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
- if (buffer == NULL) {
- xmlGenericError(xmlGenericErrorContext, "malloc failed\n");
- return(NULL);
- }
- out = buffer;
-
- while (*cur != '\0') {
- if (out - buffer > buffer_size - 100) {
- int indx = out - buffer;
-
- growBufferReentrant();
- out = &buffer[indx];
- }
-
- /*
- * By default one have to encode at least '<', '>', '"' and '&' !
- */
- if (*cur == '<') {
- *out++ = '&';
- *out++ = 'l';
- *out++ = 't';
- *out++ = ';';
- } else if (*cur == '>') {
- *out++ = '&';
- *out++ = 'g';
- *out++ = 't';
- *out++ = ';';
- } else if (*cur == '&') {
- *out++ = '&';
- *out++ = 'a';
- *out++ = 'm';
- *out++ = 'p';
- *out++ = ';';
- } else if (*cur == '"') {
- *out++ = '&';
- *out++ = 'q';
- *out++ = 'u';
- *out++ = 'o';
- *out++ = 't';
- *out++ = ';';
-#if 0
- } else if ((*cur == '\'') && (!html)) {
- *out++ = '&';
- *out++ = 'a';
- *out++ = 'p';
- *out++ = 'o';
- *out++ = 's';
- *out++ = ';';
-#endif
- } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
- (*cur == '\n') || (*cur == '\r') || (*cur == '\t')) {
- /*
- * default case, just copy !
- */
- *out++ = *cur;
- } else if (*cur >= 0x80) {
- if (((doc != NULL) && (doc->encoding != NULL)) || (html)) {
- /*
- * Bjørn Reese <br@sseusa.com> provided the patch
- xmlChar xc;
- xc = (*cur & 0x3F) << 6;
- if (cur[1] != 0) {
- xc += *(++cur) & 0x3F;
- *out++ = xc;
- } else
- */
- *out++ = *cur;
- } else {
- /*
- * We assume we have UTF-8 input.
- */
- char buf[10], *ptr;
- int val = 0, l = 1;
-
- if (*cur < 0xC0) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlEncodeEntitiesReentrant : input not UTF-8\n");
- if (doc != NULL)
- doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
- snprintf(buf, sizeof(buf), "&#%d;", *cur);
- buf[sizeof(buf) - 1] = 0;
- ptr = buf;
- while (*ptr != 0) *out++ = *ptr++;
- cur++;
- continue;
- } else if (*cur < 0xE0) {
- val = (cur[0]) & 0x1F;
- val <<= 6;
- val |= (cur[1]) & 0x3F;
- l = 2;
- } else if (*cur < 0xF0) {
- val = (cur[0]) & 0x0F;
- val <<= 6;
- val |= (cur[1]) & 0x3F;
- val <<= 6;
- val |= (cur[2]) & 0x3F;
- l = 3;
- } else if (*cur < 0xF8) {
- val = (cur[0]) & 0x07;
- val <<= 6;
- val |= (cur[1]) & 0x3F;
- val <<= 6;
- val |= (cur[2]) & 0x3F;
- val <<= 6;
- val |= (cur[3]) & 0x3F;
- l = 4;
- }
- if ((l == 1) || (!IS_CHAR(val))) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlEncodeEntitiesReentrant : char out of range\n");
- if (doc != NULL)
- doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
- snprintf(buf, sizeof(buf), "&#%d;", *cur);
- buf[sizeof(buf) - 1] = 0;
- ptr = buf;
- while (*ptr != 0) *out++ = *ptr++;
- cur++;
- continue;
- }
- /*
- * We could do multiple things here. Just save as a char ref
- */
- if (html)
- snprintf(buf, sizeof(buf), "&#%d;", val);
- else
- snprintf(buf, sizeof(buf), "&#x%X;", val);
- buf[sizeof(buf) - 1] = 0;
- ptr = buf;
- while (*ptr != 0) *out++ = *ptr++;
- cur += l;
- continue;
- }
- } else if (IS_CHAR(*cur)) {
- char buf[10], *ptr;
-
- snprintf(buf, sizeof(buf), "&#%d;", *cur);
- buf[sizeof(buf) - 1] = 0;
- ptr = buf;
- while (*ptr != 0) *out++ = *ptr++;
- }
-#if 0
- else {
- /*
- * default case, this is not a valid char !
- * Skip it...
- */
- xmlGenericError(xmlGenericErrorContext,
- "xmlEncodeEntities: invalid char %d\n", (int) *cur);
- }
-#endif
- cur++;
- }
- *out++ = 0;
- return(buffer);
-}
-
-/**
- * xmlEncodeSpecialChars:
- * @doc: the document containing the string
- * @input: A string to convert to XML.
- *
- * Do a global encoding of a string, replacing the predefined entities
- * this routine is reentrant, and result must be deallocated.
- *
- * Returns A newly allocated string with the substitution done.
- */
-xmlChar *
-xmlEncodeSpecialChars(xmlDocPtr doc, const xmlChar *input) {
- const xmlChar *cur = input;
- xmlChar *buffer = NULL;
- xmlChar *out = NULL;
- int buffer_size = 0;
- int html = 0;
-
- if (input == NULL) return(NULL);
- if (doc != NULL)
- html = (doc->type == XML_HTML_DOCUMENT_NODE);
-
- /*
- * allocate an translation buffer.
- */
- buffer_size = 1000;
- buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
- if (buffer == NULL) {
- xmlGenericError(xmlGenericErrorContext, "malloc failed\n");
- return(NULL);
- }
- out = buffer;
-
- while (*cur != '\0') {
- if (out - buffer > buffer_size - 10) {
- int indx = out - buffer;
-
- growBufferReentrant();
- out = &buffer[indx];
- }
-
- /*
- * By default one have to encode at least '<', '>', '"' and '&' !
- */
- if (*cur == '<') {
- *out++ = '&';
- *out++ = 'l';
- *out++ = 't';
- *out++ = ';';
- } else if (*cur == '>') {
- *out++ = '&';
- *out++ = 'g';
- *out++ = 't';
- *out++ = ';';
- } else if (*cur == '&') {
- *out++ = '&';
- *out++ = 'a';
- *out++ = 'm';
- *out++ = 'p';
- *out++ = ';';
- } else if (*cur == '"') {
- *out++ = '&';
- *out++ = 'q';
- *out++ = 'u';
- *out++ = 'o';
- *out++ = 't';
- *out++ = ';';
- } else {
- /*
- * Works because on UTF-8, all extended sequences cannot
- * result in bytes in the ASCII range.
- */
- *out++ = *cur;
- }
- cur++;
- }
- *out++ = 0;
- return(buffer);
-}
-
-/**
- * xmlCreateEntitiesTable:
- *
- * create and initialize an empty entities hash table.
- *
- * Returns the xmlEntitiesTablePtr just created or NULL in case of error.
- */
-xmlEntitiesTablePtr
-xmlCreateEntitiesTable(void) {
- return((xmlEntitiesTablePtr) xmlHashCreate(0));
-}
-
-/**
- * xmlFreeEntitiesTable:
- * @table: An entity table
- *
- * Deallocate the memory used by an entities hash table.
- */
-void
-xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
- xmlHashFree(table, (xmlHashDeallocator) xmlFreeEntity);
-}
-
-/**
- * xmlCopyEntity:
- * @ent: An entity
- *
- * Build a copy of an entity
- *
- * Returns the new xmlEntitiesPtr or NULL in case of error.
- */
-static xmlEntityPtr
-xmlCopyEntity(xmlEntityPtr ent) {
- xmlEntityPtr cur;
-
- cur = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlCopyEntity: out of memory !\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlEntity));
- cur->type = XML_ENTITY_DECL;
-
- cur->etype = ent->etype;
- if (ent->name != NULL)
- cur->name = xmlStrdup(ent->name);
- if (ent->ExternalID != NULL)
- cur->ExternalID = xmlStrdup(ent->ExternalID);
- if (ent->SystemID != NULL)
- cur->SystemID = xmlStrdup(ent->SystemID);
- if (ent->content != NULL)
- cur->content = xmlStrdup(ent->content);
- if (ent->orig != NULL)
- cur->orig = xmlStrdup(ent->orig);
- if (ent->URI != NULL)
- cur->URI = xmlStrdup(ent->URI);
- return(cur);
-}
-
-/**
- * xmlCopyEntitiesTable:
- * @table: An entity table
- *
- * Build a copy of an entity table.
- *
- * Returns the new xmlEntitiesTablePtr or NULL in case of error.
- */
-xmlEntitiesTablePtr
-xmlCopyEntitiesTable(xmlEntitiesTablePtr table) {
- return(xmlHashCopy(table, (xmlHashCopier) xmlCopyEntity));
-}
-
-/**
- * xmlDumpEntityDecl:
- * @buf: An XML buffer.
- * @ent: An entity table
- *
- * This will dump the content of the entity table as an XML DTD definition
- */
-void
-xmlDumpEntityDecl(xmlBufferPtr buf, xmlEntityPtr ent) {
- switch (ent->etype) {
- case XML_INTERNAL_GENERAL_ENTITY:
- xmlBufferWriteChar(buf, "<!ENTITY ");
- xmlBufferWriteCHAR(buf, ent->name);
- xmlBufferWriteChar(buf, " ");
- if (ent->orig != NULL)
- xmlBufferWriteQuotedString(buf, ent->orig);
- else
- xmlBufferWriteQuotedString(buf, ent->content);
- xmlBufferWriteChar(buf, ">\n");
- break;
- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
- xmlBufferWriteChar(buf, "<!ENTITY ");
- xmlBufferWriteCHAR(buf, ent->name);
- if (ent->ExternalID != NULL) {
- xmlBufferWriteChar(buf, " PUBLIC ");
- xmlBufferWriteQuotedString(buf, ent->ExternalID);
- xmlBufferWriteChar(buf, " ");
- xmlBufferWriteQuotedString(buf, ent->SystemID);
- } else {
- xmlBufferWriteChar(buf, " SYSTEM ");
- xmlBufferWriteQuotedString(buf, ent->SystemID);
- }
- xmlBufferWriteChar(buf, ">\n");
- break;
- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
- xmlBufferWriteChar(buf, "<!ENTITY ");
- xmlBufferWriteCHAR(buf, ent->name);
- if (ent->ExternalID != NULL) {
- xmlBufferWriteChar(buf, " PUBLIC ");
- xmlBufferWriteQuotedString(buf, ent->ExternalID);
- xmlBufferWriteChar(buf, " ");
- xmlBufferWriteQuotedString(buf, ent->SystemID);
- } else {
- xmlBufferWriteChar(buf, " SYSTEM ");
- xmlBufferWriteQuotedString(buf, ent->SystemID);
- }
- if (ent->content != NULL) { /* Should be true ! */
- xmlBufferWriteChar(buf, " NDATA ");
- if (ent->orig != NULL)
- xmlBufferWriteCHAR(buf, ent->orig);
- else
- xmlBufferWriteCHAR(buf, ent->content);
- }
- xmlBufferWriteChar(buf, ">\n");
- break;
- case XML_INTERNAL_PARAMETER_ENTITY:
- xmlBufferWriteChar(buf, "<!ENTITY % ");
- xmlBufferWriteCHAR(buf, ent->name);
- xmlBufferWriteChar(buf, " ");
- if (ent->orig == NULL)
- xmlBufferWriteQuotedString(buf, ent->content);
- else
- xmlBufferWriteQuotedString(buf, ent->orig);
- xmlBufferWriteChar(buf, ">\n");
- break;
- case XML_EXTERNAL_PARAMETER_ENTITY:
- xmlBufferWriteChar(buf, "<!ENTITY % ");
- xmlBufferWriteCHAR(buf, ent->name);
- if (ent->ExternalID != NULL) {
- xmlBufferWriteChar(buf, " PUBLIC ");
- xmlBufferWriteQuotedString(buf, ent->ExternalID);
- xmlBufferWriteChar(buf, " ");
- xmlBufferWriteQuotedString(buf, ent->SystemID);
- } else {
- xmlBufferWriteChar(buf, " SYSTEM ");
- xmlBufferWriteQuotedString(buf, ent->SystemID);
- }
- xmlBufferWriteChar(buf, ">\n");
- break;
- default:
- xmlGenericError(xmlGenericErrorContext,
- "xmlDumpEntitiesDecl: internal: unknown type %d\n",
- ent->etype);
- }
-}
-
-/**
- * xmlDumpEntitiesTable:
- * @buf: An XML buffer.
- * @table: An entity table
- *
- * This will dump the content of the entity table as an XML DTD definition
- */
-void
-xmlDumpEntitiesTable(xmlBufferPtr buf, xmlEntitiesTablePtr table) {
- xmlHashScan(table, (xmlHashScanner)xmlDumpEntityDecl, buf);
-}
diff --git a/bundle/libxml/error.c b/bundle/libxml/error.c
deleted file mode 100644
index d6266af051..0000000000
--- a/bundle/libxml/error.c
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * error.c: module displaying/handling XML parser errors
- *
- * See Copyright for the status of this software.
- *
- * Daniel Veillard <daniel@veillard.com>
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#include <stdarg.h>
-#include <libxml/parser.h>
-#include <libxml/xmlerror.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/globals.h>
-
-void xmlGenericErrorDefaultFunc (void *ctx ATTRIBUTE_UNUSED,
- const char *msg,
- ...);
-
-#define XML_GET_VAR_STR(msg, str) { \
- int size; \
- int chars; \
- char *larger; \
- va_list ap; \
- \
- str = (char *) xmlMalloc(150); \
- if (str == NULL) \
- return; \
- \
- size = 150; \
- \
- while (1) { \
- va_start(ap, msg); \
- chars = vsnprintf(str, size, msg, ap); \
- va_end(ap); \
- if ((chars > -1) && (chars < size)) \
- break; \
- if (chars > -1) \
- size += chars + 1; \
- else \
- size += 100; \
- if ((larger = (char *) xmlRealloc(str, size)) == NULL) {\
- xmlFree(str); \
- return; \
- } \
- str = larger; \
- } \
-}
-
-/************************************************************************
- * *
- * Handling of out of context errors *
- * *
- ************************************************************************/
-
-/**
- * xmlGenericErrorDefaultFunc:
- * @ctx: an error context
- * @msg: the message to display/transmit
- * @...: extra parameters for the message display
- *
- * Default handler for out of context error messages.
- */
-void
-xmlGenericErrorDefaultFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
- va_list args;
-
- if (xmlGenericErrorContext == NULL)
- xmlGenericErrorContext = (void *) stderr;
-
- va_start(args, msg);
- vfprintf((FILE *)xmlGenericErrorContext, msg, args);
- va_end(args);
-}
-
-/**
- * initGenericErrorDefaultFunc:
- * @handler: the handler
- *
- * Set or reset (if NULL) the default handler for generic errors
- */
-void
-initGenericErrorDefaultFunc(xmlGenericErrorFunc * handler)
-{
- if (handler == NULL)
- xmlGenericError = xmlGenericErrorDefaultFunc;
- else
- (*handler) = xmlGenericErrorDefaultFunc;
-}
-
-/**
- * xmlSetGenericErrorFunc:
- * @ctx: the new error handling context
- * @handler: the new handler function
- *
- * Function to reset the handler and the error context for out of
- * context error messages.
- * This simply means that @handler will be called for subsequent
- * error messages while not parsing nor validating. And @ctx will
- * be passed as first argument to @handler
- * One can simply force messages to be emitted to another FILE * than
- * stderr by setting @ctx to this file handle and @handler to NULL.
- */
-void
-xmlSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {
- xmlGenericErrorContext = ctx;
- if (handler != NULL)
- xmlGenericError = handler;
- else
- xmlGenericError = xmlGenericErrorDefaultFunc;
-}
-
-/************************************************************************
- * *
- * Handling of parsing errors *
- * *
- ************************************************************************/
-
-/**
- * xmlParserPrintFileInfo:
- * @input: an xmlParserInputPtr input
- *
- * Displays the associated file and line informations for the current input
- */
-
-void
-xmlParserPrintFileInfo(xmlParserInputPtr input) {
- if (input != NULL) {
- if (input->filename)
- xmlGenericError(xmlGenericErrorContext,
- "%s:%d: ", input->filename,
- input->line);
- else
- xmlGenericError(xmlGenericErrorContext,
- "Entity: line %d: ", input->line);
- }
-}
-
-/**
- * xmlParserPrintFileContext:
- * @input: an xmlParserInputPtr input
- *
- * Displays current context within the input content for error tracking
- */
-
-void
-xmlParserPrintFileContext(xmlParserInputPtr input) {
- const xmlChar *cur, *base;
- int n;
- xmlChar content[81];
- xmlChar *ctnt;
-
- if (input == NULL) return;
- cur = input->cur;
- base = input->base;
- /* skip backwards over any end-of-lines */
- while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
- cur--;
- }
- n = 0;
- /* search backwards for beginning-of-line maximum 80 characters */
- while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
- cur--;
- if ((*cur == '\n') || (*cur == '\r')) cur++;
- /* search forward for end-of-line maximum 80 characters */
- n = 0;
- ctnt = content;
- while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
- *ctnt++ = *cur++;
- n++;
- }
- *ctnt = 0;
- xmlGenericError(xmlGenericErrorContext,"%s\n", content);
- /* create blank line with problem pointer */
- cur = input->cur;
- while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
- cur--;
- }
- n = 0;
- ctnt = content;
- while ((n++ < 79) && (cur > base) && (*cur != '\n') && (*cur != '\r')) {
- *ctnt++ = ' ';
- cur--;
- }
- if (ctnt > content) {
- *(--ctnt) = '^';
- *(++ctnt) = 0;
- } else {
- *ctnt = '^';
- *(++ctnt) = 0;
- }
- xmlGenericError(xmlGenericErrorContext,"%s\n", content);
-}
-
-#if 0
-/**
- * xmlGetVarStr:
- * @msg: the message format
- * @args: a va_list argument list
- *
- * SGS contribution
- * Get an arbitrary-sized string for an error argument
- * The caller must free() the returned string
- */
-static char *
-xmlGetVarStr(const char * msg, va_list args) {
- int size;
- int length;
- int chars, left;
- char *str, *larger;
- va_list ap;
-
- str = (char *) xmlMalloc(150);
- if (str == NULL)
- return(NULL);
-
- size = 150;
- length = 0;
-
- while (1) {
- left = size - length;
- /* Try to print in the allocated space. */
- va_start(msg, ap);
- chars = vsnprintf(str + length, left, msg, ap);
- va_end(ap);
- /* If that worked, we're done. */
- if ((chars > -1) && (chars < left ))
- break;
- /* Else try again with more space. */
- if (chars > -1) /* glibc 2.1 */
- size += chars + 1; /* precisely what is needed */
- else /* glibc 2.0 */
- size += 100;
- if ((larger = (char *) xmlRealloc(str, size)) == NULL) {
- xmlFree(str);
- return(NULL);
- }
- str = larger;
- }
- return(str);
-}
-#endif
-
-/**
- * xmlParserError:
- * @ctx: an XML parser context
- * @msg: the message to display/transmit
- * @...: extra parameters for the message display
- *
- * Display and format an error messages, gives file, line, position and
- * extra parameters.
- */
-void
-xmlParserError(void *ctx, const char *msg, ...)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlParserInputPtr input = NULL;
- xmlParserInputPtr cur = NULL;
- char * str;
-
- if (ctxt != NULL) {
- input = ctxt->input;
- if ((input != NULL) && (input->filename == NULL) &&
- (ctxt->inputNr > 1)) {
- cur = input;
- input = ctxt->inputTab[ctxt->inputNr - 2];
- }
- xmlParserPrintFileInfo(input);
- }
-
- xmlGenericError(xmlGenericErrorContext, "error: ");
- XML_GET_VAR_STR(msg, str);
- xmlGenericError(xmlGenericErrorContext, "%s", str);
- if (str != NULL)
- xmlFree(str);
-
- if (ctxt != NULL) {
- xmlParserPrintFileContext(input);
- if (cur != NULL) {
- xmlParserPrintFileInfo(cur);
- xmlGenericError(xmlGenericErrorContext, "\n");
- xmlParserPrintFileContext(cur);
- }
- }
-}
-
-/**
- * xmlParserWarning:
- * @ctx: an XML parser context
- * @msg: the message to display/transmit
- * @...: extra parameters for the message display
- *
- * Display and format a warning messages, gives file, line, position and
- * extra parameters.
- */
-void
-xmlParserWarning(void *ctx, const char *msg, ...)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlParserInputPtr input = NULL;
- xmlParserInputPtr cur = NULL;
- char * str;
-
- if (ctxt != NULL) {
- input = ctxt->input;
- if ((input != NULL) && (input->filename == NULL) &&
- (ctxt->inputNr > 1)) {
- cur = input;
- input = ctxt->inputTab[ctxt->inputNr - 2];
- }
- xmlParserPrintFileInfo(input);
- }
-
- xmlGenericError(xmlGenericErrorContext, "warning: ");
- XML_GET_VAR_STR(msg, str);
- xmlGenericError(xmlGenericErrorContext, "%s", str);
- if (str != NULL)
- xmlFree(str);
-
- if (ctxt != NULL) {
- xmlParserPrintFileContext(input);
- if (cur != NULL) {
- xmlParserPrintFileInfo(cur);
- xmlGenericError(xmlGenericErrorContext, "\n");
- xmlParserPrintFileContext(cur);
- }
- }
-}
-
-/************************************************************************
- * *
- * Handling of validation errors *
- * *
- ************************************************************************/
-
-/**
- * xmlParserValidityError:
- * @ctx: an XML parser context
- * @msg: the message to display/transmit
- * @...: extra parameters for the message display
- *
- * Display and format an validity error messages, gives file,
- * line, position and extra parameters.
- */
-void
-xmlParserValidityError(void *ctx, const char *msg, ...)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlParserInputPtr input = NULL;
- char * str;
- int len = xmlStrlen((const xmlChar *) msg);
- static int had_info = 0;
- int need_context = 0;
-
- if ((len > 1) && (msg[len - 2] != ':')) {
- if (ctxt != NULL) {
- input = ctxt->input;
- if ((input->filename == NULL) && (ctxt->inputNr > 1))
- input = ctxt->inputTab[ctxt->inputNr - 2];
-
- if (had_info == 0) {
- xmlParserPrintFileInfo(input);
- }
- }
- xmlGenericError(xmlGenericErrorContext, "validity error: ");
- need_context = 1;
- had_info = 0;
- } else {
- had_info = 1;
- }
-
- XML_GET_VAR_STR(msg, str);
- xmlGenericError(xmlGenericErrorContext, "%s", str);
- if (str != NULL)
- xmlFree(str);
-
- if ((ctxt != NULL) && (input != NULL)) {
- xmlParserPrintFileContext(input);
- }
-}
-
-/**
- * xmlParserValidityWarning:
- * @ctx: an XML parser context
- * @msg: the message to display/transmit
- * @...: extra parameters for the message display
- *
- * Display and format a validity warning messages, gives file, line,
- * position and extra parameters.
- */
-void
-xmlParserValidityWarning(void *ctx, const char *msg, ...)
-{
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlParserInputPtr input = NULL;
- char * str;
- int len = xmlStrlen((const xmlChar *) msg);
-
- if ((ctxt != NULL) && (len != 0) && (msg[len - 1] != ':')) {
- input = ctxt->input;
- if ((input->filename == NULL) && (ctxt->inputNr > 1))
- input = ctxt->inputTab[ctxt->inputNr - 2];
-
- xmlParserPrintFileInfo(input);
- }
-
- xmlGenericError(xmlGenericErrorContext, "validity warning: ");
- XML_GET_VAR_STR(msg, str);
- xmlGenericError(xmlGenericErrorContext, "%s", str);
- if (str != NULL)
- xmlFree(str);
-
- if (ctxt != NULL) {
- xmlParserPrintFileContext(input);
- }
-}
-
-
diff --git a/bundle/libxml/globals.c b/bundle/libxml/globals.c
deleted file mode 100644
index 72865c323a..0000000000
--- a/bundle/libxml/globals.c
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * globals.c: definition and handling of the set of global variables
- * of the library
- *
- * The bottom of this file is automatically generated by build_glob.py
- * based on the description file global.data
- *
- * See Copyright for the status of this software.
- *
- * Gary Pennington <Gary.Pennington@uk.sun.com>
- * daniel@veillard.com
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#include <string.h>
-
-#include <libxml/globals.h>
-#include <libxml/xmlmemory.h>
-
-/* #define DEBUG_GLOBALS */
-
-/*
- * Helpful Macro
- */
-#ifdef LIBXML_THREAD_ENABLED
-#define IS_MAIN_THREAD (xmlIsMainThread())
-#else
-#define IS_MAIN_THREAD 1
-#endif
-
-/************************************************************************
- * *
- * All the user accessible global variables of the library *
- * *
- ************************************************************************/
-
-/*
- * Memory allocation routines
- */
-#if defined(DEBUG_MEMORY_LOCATION) || defined(DEBUG_MEMORY)
-extern void xmlMemFree(void *ptr);
-extern void * xmlMemMalloc(size_t size);
-extern void * xmlMemRealloc(void *ptr,size_t size);
-extern char * xmlMemoryStrdup(const char *str);
-
-xmlFreeFunc xmlFree = (xmlFreeFunc) xmlMemFree;
-xmlMallocFunc xmlMalloc = (xmlMallocFunc) xmlMemMalloc;
-xmlReallocFunc xmlRealloc = (xmlReallocFunc) xmlMemRealloc;
-xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup;
-#else
-/**
- * xmlFree:
- * @mem: an already allocated block of memory
- *
- * The variable holding the libxml free() implementation
- */
-xmlFreeFunc xmlFree = (xmlFreeFunc) free;
-/**
- * xmlMalloc:
- * @size: the size requested in bytes
- *
- * The variable holding the libxml malloc() implementation
- *
- * Returns a pointer to the newly allocated block or NULL in case of error
- */
-xmlMallocFunc xmlMalloc = (xmlMallocFunc) malloc;
-/**
- * xmlRealloc:
- * @mem: an already allocated block of memory
- * @size: the new size requested in bytes
- *
- * The variable holding the libxml realloc() implementation
- *
- * Returns a pointer to the newly reallocated block or NULL in case of error
- */
-xmlReallocFunc xmlRealloc = (xmlReallocFunc) realloc;
-/**
- * xmlMemStrdup:
- * @str: a zero terminated string
- *
- * The variable holding the libxml strdup() implementation
- *
- * Returns the copy of the string or NULL in case of error
- */
-xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlStrdup;
-#endif
-
-#include <libxml/threads.h>
-#include <libxml/globals.h>
-#include <libxml/SAX.h>
-
-#undef docbDefaultSAXHandler
-#undef htmlDefaultSAXHandler
-#undef oldXMLWDcompatibility
-#undef xmlBufferAllocScheme
-#undef xmlDefaultBufferSize
-#undef xmlDefaultSAXHandler
-#undef xmlDefaultSAXLocator
-#undef xmlDoValidityCheckingDefaultValue
-#undef xmlGenericError
-#undef xmlGenericErrorContext
-#undef xmlGetWarningsDefaultValue
-#undef xmlIndentTreeOutput
-#undef xmlTreeIndentString
-#undef xmlKeepBlanksDefaultValue
-#undef xmlLineNumbersDefaultValue
-#undef xmlLoadExtDtdDefaultValue
-#undef xmlParserDebugEntities
-#undef xmlParserVersion
-#undef xmlPedanticParserDefaultValue
-#undef xmlSaveNoEmptyTags
-#undef xmlSubstituteEntitiesDefaultValue
-
-#undef xmlFree
-#undef xmlMalloc
-#undef xmlMemStrdup
-#undef xmlRealloc
-
-/**
- * xmlParserVersion:
- *
- * Constant string describing the internal version of the library
- */
-const char *xmlParserVersion = LIBXML_VERSION_STRING;
-
-/**
- * xmlBufferAllocScheme:
- *
- * Global setting, default allocation policy for buffers, default is
- * XML_BUFFER_ALLOC_EXACT
- */
-xmlBufferAllocationScheme xmlBufferAllocScheme = XML_BUFFER_ALLOC_EXACT;
-/**
- * xmlDefaultBufferSize:
- *
- * Global setting, default buffer size. Default value is BASE_BUFFER_SIZE
- */
-int xmlDefaultBufferSize = BASE_BUFFER_SIZE;
-
-/*
- * Parser defaults
- */
-
-/**
- * oldXMLWDcompatibility:
- *
- * Global setting, DEPRECATED.
- */
-int oldXMLWDcompatibility = 0; /* DEPRECATED */
-/**
- * xmlParserDebugEntities:
- *
- * Global setting, asking the parser to print out debugging informations.
- * while handling entities.
- * Disabled by default
- */
-int xmlParserDebugEntities = 0;
-/**
- * xmlDoValidityCheckingDefaultValue:
- *
- * Global setting, indicate that the parser should work in validating mode.
- * Disabled by default.
- */
-int xmlDoValidityCheckingDefaultValue = 0;
-/**
- * xmlGetWarningsDefaultValue:
- *
- * Global setting, indicate that the parser should provide warnings.
- * Activated by default.
- */
-int xmlGetWarningsDefaultValue = 1;
-/**
- * xmlLoadExtDtdDefaultValue:
- *
- * Global setting, indicate that the parser should load DTD while not
- * validating.
- * Disabled by default.
- */
-int xmlLoadExtDtdDefaultValue = 0;
-/**
- * xmlPedanticParserDefaultValue:
- *
- * Global setting, indicate that the parser be pedantic
- * Disabled by default.
- */
-int xmlPedanticParserDefaultValue = 0;
-/**
- * xmlLineNumbersDefaultValue:
- *
- * Global setting, indicate that the parser should store the line number
- * in the content field of elements in the DOM tree.
- * Disabled by default since this may not be safe for old classes of
- * applicaton.
- */
-int xmlLineNumbersDefaultValue = 0;
-/**
- * xmlKeepBlanksDefaultValue:
- *
- * Global setting, indicate that the parser should keep all blanks
- * nodes found in the content
- * Activated by default, this is actually needed to have the parser
- * conformant to the XML Recommendation, however the option is kept
- * for some applications since this was libxml1 default behaviour.
- */
-int xmlKeepBlanksDefaultValue = 1;
-/**
- * xmlSubstituteEntitiesDefaultValue:
- *
- * Global setting, indicate that the parser should not generate entity
- * references but replace them with the actual content of the entity
- * Disabled by default, this should be activated when using XPath since
- * the XPath data model requires entities replacement and the XPath
- * engine does not handle entities references transparently.
- */
-int xmlSubstituteEntitiesDefaultValue = 0;
-
-/*
- * Error handling
- */
-
-/* xmlGenericErrorFunc xmlGenericError = xmlGenericErrorDefaultFunc; */
-/* Must initialize xmlGenericError in xmlInitParser */
-void xmlGenericErrorDefaultFunc (void *ctx ATTRIBUTE_UNUSED,
- const char *msg,
- ...);
-/**
- * xmlGenericError:
- *
- * Global setting: function used for generic error callbacks
- */
-xmlGenericErrorFunc xmlGenericError = xmlGenericErrorDefaultFunc;
-/**
- * xmlGenericErrorContext:
- *
- * Global setting passed to generic error callbacks
- */
-void *xmlGenericErrorContext = NULL;
-
-/*
- * output defaults
- */
-/**
- * xmlIndentTreeOutput:
- *
- * Global setting, asking the serializer to indent the output tree by default
- * Enabled by default
- */
-int xmlIndentTreeOutput = 1;
-
-/**
- * xmlTreeIndentString:
- *
- * The string used to do one-level indent. By default is equal to " " (two spaces)
- */
-const char *xmlTreeIndentString = " ";
-
-/**
- * xmlSaveNoEmptyTags:
- *
- * Global setting, asking the serializer to not output empty tags
- * as <empty/> but <empty></empty>. those two forms are undistinguishable
- * once parsed.
- * Disabled by default
- */
-int xmlSaveNoEmptyTags = 0;
-
-/**
- * xmlDefaultSAXHandler:
- *
- * Default handler for XML, builds the DOM tree
- */
-xmlSAXHandler xmlDefaultSAXHandler = {
- internalSubset,
- isStandalone,
- hasInternalSubset,
- hasExternalSubset,
- resolveEntity,
- getEntity,
- entityDecl,
- notationDecl,
- attributeDecl,
- elementDecl,
- unparsedEntityDecl,
- setDocumentLocator,
- startDocument,
- endDocument,
- startElement,
- endElement,
- reference,
- characters,
- characters,
- processingInstruction,
- comment,
- xmlParserWarning,
- xmlParserError,
- xmlParserError,
- getParameterEntity,
- cdataBlock,
- externalSubset,
- 0
-};
-
-/**
- * xmlDefaultSAXLocator:
- *
- * The default SAX Locator
- * { getPublicId, getSystemId, getLineNumber, getColumnNumber}
- */
-xmlSAXLocator xmlDefaultSAXLocator = {
- getPublicId, getSystemId, getLineNumber, getColumnNumber
-};
-
-#ifdef LIBXML_HTML_ENABLED
-/**
- * htmlDefaultSAXHandler:
- *
- * Default handler for HTML, builds the DOM tree
- */
-xmlSAXHandler htmlDefaultSAXHandler = {
- internalSubset,
- NULL,
- NULL,
- NULL,
- NULL,
- getEntity,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- setDocumentLocator,
- startDocument,
- endDocument,
- startElement,
- endElement,
- NULL,
- characters,
- ignorableWhitespace,
- NULL,
- comment,
- xmlParserWarning,
- xmlParserError,
- xmlParserError,
- getParameterEntity,
- cdataBlock,
- NULL,
- 0
-};
-#endif /* LIBXML_HTML_ENABLED */
-
-#ifdef LIBXML_DOCB_ENABLED
-/**
- * docbDefaultSAXHandler:
- *
- * Default handler for SGML DocBook, builds the DOM tree
- */
-xmlSAXHandler docbDefaultSAXHandler = {
- internalSubset,
- isStandalone,
- hasInternalSubset,
- hasExternalSubset,
- resolveEntity,
- getEntity,
- entityDecl,
- NULL,
- NULL,
- NULL,
- NULL,
- setDocumentLocator,
- startDocument,
- endDocument,
- startElement,
- endElement,
- reference,
- characters,
- ignorableWhitespace,
- NULL,
- comment,
- xmlParserWarning,
- xmlParserError,
- xmlParserError,
- getParameterEntity,
- NULL,
- NULL,
- 0
-};
-#endif /* LIBXML_DOCB_ENABLED */
-
-/**
- * xmlInitializeGlobalState:
- * @gs: a pointer to a newly allocated global state
- *
- * xmlInitializeGlobalState() initialize a global state with all the
- * default values of the library.
- */
-void
-xmlInitializeGlobalState(xmlGlobalStatePtr gs)
-{
-#ifdef DEBUG_GLOBALS
- fprintf(stderr, "Initializing globals at %lu for thread %d\n",
- (unsigned long) gs, xmlGetThreadId());
-#endif
-
- /*
- * Perform initialization as required by libxml
- */
-
-#ifdef LIBXML_DOCB_ENABLED
- initdocbDefaultSAXHandler(&gs->docbDefaultSAXHandler);
-#endif
-#ifdef LIBXML_HTML_ENABLED
- inithtmlDefaultSAXHandler(&gs->htmlDefaultSAXHandler);
-#endif
- initGenericErrorDefaultFunc(&gs->xmlGenericError);
-
- gs->oldXMLWDcompatibility = 0;
- gs->xmlBufferAllocScheme = XML_BUFFER_ALLOC_EXACT;
- gs->xmlDefaultBufferSize = BASE_BUFFER_SIZE;
- initxmlDefaultSAXHandler(&gs->xmlDefaultSAXHandler, 1);
- gs->xmlDefaultSAXLocator.getPublicId = getPublicId;
- gs->xmlDefaultSAXLocator.getSystemId = getSystemId;
- gs->xmlDefaultSAXLocator.getLineNumber = getLineNumber;
- gs->xmlDefaultSAXLocator.getColumnNumber = getColumnNumber;
- gs->xmlDoValidityCheckingDefaultValue = 0;
-#if defined(DEBUG_MEMORY_LOCATION) | defined(DEBUG_MEMORY)
- gs->xmlFree = (xmlFreeFunc) xmlMemFree;
- gs->xmlMalloc = (xmlMallocFunc) xmlMemMalloc;
- gs->xmlRealloc = (xmlReallocFunc) xmlMemRealloc;
- gs->xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup;
-#else
- gs->xmlFree = (xmlFreeFunc) free;
- gs->xmlMalloc = (xmlMallocFunc) malloc;
- gs->xmlRealloc = (xmlReallocFunc) realloc;
- gs->xmlMemStrdup = (xmlStrdupFunc) xmlStrdup;
-#endif
- gs->xmlGenericErrorContext = NULL;
- gs->xmlGetWarningsDefaultValue = 1;
- gs->xmlIndentTreeOutput = 1;
- gs->xmlTreeIndentString = " ";
- gs->xmlKeepBlanksDefaultValue = 1;
- gs->xmlLineNumbersDefaultValue = 0;
- gs->xmlLoadExtDtdDefaultValue = 0;
- gs->xmlParserDebugEntities = 0;
- gs->xmlParserVersion = LIBXML_VERSION_STRING;
- gs->xmlPedanticParserDefaultValue = 0;
- gs->xmlSaveNoEmptyTags = 0;
- gs->xmlSubstituteEntitiesDefaultValue = 0;
-}
-
-#ifdef LIBXML_DOCB_ENABLED
-#undef docbDefaultSAXHandler
-xmlSAXHandler *
-__docbDefaultSAXHandler(void) {
- if (IS_MAIN_THREAD)
- return (&docbDefaultSAXHandler);
- else
- return (&xmlGetGlobalState()->docbDefaultSAXHandler);
-}
-#endif
-
-#ifdef LIBXML_HTML_ENABLED
-#undef htmlDefaultSAXHandler
-xmlSAXHandler *
-__htmlDefaultSAXHandler(void) {
- if (IS_MAIN_THREAD)
- return (&htmlDefaultSAXHandler);
- else
- return (&xmlGetGlobalState()->htmlDefaultSAXHandler);
-}
-#endif
-
-/*
- * Everything starting from the line below is
- * Automatically generated by build_glob.py.
- * Do not modify the previous line.
- */
-
-
-#undef oldXMLWDcompatibility
-int *
-__oldXMLWDcompatibility(void) {
- if (IS_MAIN_THREAD)
- return (&oldXMLWDcompatibility);
- else
- return (&xmlGetGlobalState()->oldXMLWDcompatibility);
-}
-
-#undef xmlBufferAllocScheme
-xmlBufferAllocationScheme *
-__xmlBufferAllocScheme(void) {
- if (IS_MAIN_THREAD)
- return (&xmlBufferAllocScheme);
- else
- return (&xmlGetGlobalState()->xmlBufferAllocScheme);
-}
-
-#undef xmlDefaultBufferSize
-int *
-__xmlDefaultBufferSize(void) {
- if (IS_MAIN_THREAD)
- return (&xmlDefaultBufferSize);
- else
- return (&xmlGetGlobalState()->xmlDefaultBufferSize);
-}
-
-#undef xmlDefaultSAXHandler
-xmlSAXHandler *
-__xmlDefaultSAXHandler(void) {
- if (IS_MAIN_THREAD)
- return (&xmlDefaultSAXHandler);
- else
- return (&xmlGetGlobalState()->xmlDefaultSAXHandler);
-}
-
-#undef xmlDefaultSAXLocator
-xmlSAXLocator *
-__xmlDefaultSAXLocator(void) {
- if (IS_MAIN_THREAD)
- return (&xmlDefaultSAXLocator);
- else
- return (&xmlGetGlobalState()->xmlDefaultSAXLocator);
-}
-
-#undef xmlDoValidityCheckingDefaultValue
-int *
-__xmlDoValidityCheckingDefaultValue(void) {
- if (IS_MAIN_THREAD)
- return (&xmlDoValidityCheckingDefaultValue);
- else
- return (&xmlGetGlobalState()->xmlDoValidityCheckingDefaultValue);
-}
-
-#undef xmlGenericError
-xmlGenericErrorFunc *
-__xmlGenericError(void) {
- if (IS_MAIN_THREAD)
- return (&xmlGenericError);
- else
- return (&xmlGetGlobalState()->xmlGenericError);
-}
-
-#undef xmlGenericErrorContext
-void * *
-__xmlGenericErrorContext(void) {
- if (IS_MAIN_THREAD)
- return (&xmlGenericErrorContext);
- else
- return (&xmlGetGlobalState()->xmlGenericErrorContext);
-}
-
-#undef xmlGetWarningsDefaultValue
-int *
-__xmlGetWarningsDefaultValue(void) {
- if (IS_MAIN_THREAD)
- return (&xmlGetWarningsDefaultValue);
- else
- return (&xmlGetGlobalState()->xmlGetWarningsDefaultValue);
-}
-
-#undef xmlIndentTreeOutput
-int *
-__xmlIndentTreeOutput(void) {
- if (IS_MAIN_THREAD)
- return (&xmlIndentTreeOutput);
- else
- return (&xmlGetGlobalState()->xmlIndentTreeOutput);
-}
-
-#undef xmlTreeIndentString
-const char * *
-__xmlTreeIndentString(void) {
- if (IS_MAIN_THREAD)
- return (&xmlTreeIndentString);
- else
- return (&xmlGetGlobalState()->xmlTreeIndentString);
-}
-
-#undef xmlKeepBlanksDefaultValue
-int *
-__xmlKeepBlanksDefaultValue(void) {
- if (IS_MAIN_THREAD)
- return (&xmlKeepBlanksDefaultValue);
- else
- return (&xmlGetGlobalState()->xmlKeepBlanksDefaultValue);
-}
-
-#undef xmlLineNumbersDefaultValue
-int *
-__xmlLineNumbersDefaultValue(void) {
- if (IS_MAIN_THREAD)
- return (&xmlLineNumbersDefaultValue);
- else
- return (&xmlGetGlobalState()->xmlLineNumbersDefaultValue);
-}
-
-#undef xmlLoadExtDtdDefaultValue
-int *
-__xmlLoadExtDtdDefaultValue(void) {
- if (IS_MAIN_THREAD)
- return (&xmlLoadExtDtdDefaultValue);
- else
- return (&xmlGetGlobalState()->xmlLoadExtDtdDefaultValue);
-}
-
-#undef xmlParserDebugEntities
-int *
-__xmlParserDebugEntities(void) {
- if (IS_MAIN_THREAD)
- return (&xmlParserDebugEntities);
- else
- return (&xmlGetGlobalState()->xmlParserDebugEntities);
-}
-
-#undef xmlParserVersion
-const char * *
-__xmlParserVersion(void) {
- if (IS_MAIN_THREAD)
- return (&xmlParserVersion);
- else
- return (&xmlGetGlobalState()->xmlParserVersion);
-}
-
-#undef xmlPedanticParserDefaultValue
-int *
-__xmlPedanticParserDefaultValue(void) {
- if (IS_MAIN_THREAD)
- return (&xmlPedanticParserDefaultValue);
- else
- return (&xmlGetGlobalState()->xmlPedanticParserDefaultValue);
-}
-
-#undef xmlSaveNoEmptyTags
-int *
-__xmlSaveNoEmptyTags(void) {
- if (IS_MAIN_THREAD)
- return (&xmlSaveNoEmptyTags);
- else
- return (&xmlGetGlobalState()->xmlSaveNoEmptyTags);
-}
-
-#undef xmlSubstituteEntitiesDefaultValue
-int *
-__xmlSubstituteEntitiesDefaultValue(void) {
- if (IS_MAIN_THREAD)
- return (&xmlSubstituteEntitiesDefaultValue);
- else
- return (&xmlGetGlobalState()->xmlSubstituteEntitiesDefaultValue);
-}
diff --git a/bundle/libxml/hash.c b/bundle/libxml/hash.c
deleted file mode 100644
index 2a4d000872..0000000000
--- a/bundle/libxml/hash.c
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
- * hash.c: chained hash tables
- *
- * Reference: Your favorite introductory book on algorithms
- *
- * Copyright (C) 2000 Bjorn Reese and Daniel Veillard.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- * Author: breese@users.sourceforge.net
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#include <string.h>
-#include <libxml/hash.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include <libxml/xmlerror.h>
-#include <libxml/globals.h>
-
-#define MAX_HASH_LEN 8
-
-/* #define DEBUG_GROW */
-
-/*
- * A single entry in the hash table
- */
-typedef struct _xmlHashEntry xmlHashEntry;
-typedef xmlHashEntry *xmlHashEntryPtr;
-struct _xmlHashEntry {
- struct _xmlHashEntry *next;
- xmlChar *name;
- xmlChar *name2;
- xmlChar *name3;
- void *payload;
- int valid;
-};
-
-/*
- * The entire hash table
- */
-struct _xmlHashTable {
- struct _xmlHashEntry *table;
- int size;
- int nbElems;
-};
-
-/*
- * xmlHashComputeKey:
- * Calculate the hash key
- */
-static unsigned long
-xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, const xmlChar *name3) {
- unsigned long value = 0L;
- char ch;
-
- if (name != NULL) {
- value += 30 * (*name);
- while ((ch = *name++) != 0) {
- value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
- }
- }
- if (name2 != NULL) {
- while ((ch = *name2++) != 0) {
- value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
- }
- }
- if (name3 != NULL) {
- while ((ch = *name3++) != 0) {
- value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
- }
- }
- return (value % table->size);
-}
-
-/**
- * xmlHashCreate:
- * @size: the size of the hash table
- *
- * Create a new xmlHashTablePtr.
- *
- * Returns the newly created object, or NULL if an error occured.
- */
-xmlHashTablePtr
-xmlHashCreate(int size) {
- xmlHashTablePtr table;
-
- if (size <= 0)
- size = 256;
-
- table = xmlMalloc(sizeof(xmlHashTable));
- if (table) {
- table->size = size;
- table->nbElems = 0;
- table->table = xmlMalloc(size * sizeof(xmlHashEntry));
- if (table->table) {
- memset(table->table, 0, size * sizeof(xmlHashEntry));
- return(table);
- }
- xmlFree(table);
- }
- return(NULL);
-}
-
-/**
- * xmlHashGrow:
- * @table: the hash table
- * @size: the new size of the hash table
- *
- * resize the hash table
- *
- * Returns 0 in case of success, -1 in case of failure
- */
-static int
-xmlHashGrow(xmlHashTablePtr table, int size) {
- unsigned long key;
- int oldsize, i;
- xmlHashEntryPtr iter, next;
- struct _xmlHashEntry *oldtable;
-#ifdef DEBUG_GROW
- unsigned long nbElem = 0;
-#endif
-
- if (table == NULL)
- return(-1);
- if (size < 8)
- return(-1);
- if (size > 8 * 2048)
- return(-1);
-
- oldsize = table->size;
- oldtable = table->table;
- if (oldtable == NULL)
- return(-1);
-
- table->table = xmlMalloc(size * sizeof(xmlHashEntry));
- if (table->table == NULL) {
- table->table = oldtable;
- return(-1);
- }
- memset(table->table, 0, size * sizeof(xmlHashEntry));
- table->size = size;
-
- /* If the two loops are merged, there would be situations where
- a new entry needs to allocated and data copied into it from
- the main table. So instead, we run through the array twice, first
- copying all the elements in the main array (where we can't get
- conflicts) and then the rest, so we only free (and don't allocate)
- */
- for (i = 0; i < oldsize; i++) {
- if (oldtable[i].valid == 0)
- continue;
- key = xmlHashComputeKey(table, oldtable[i].name, oldtable[i].name2,
- oldtable[i].name3);
- memcpy(&(table->table[key]), &(oldtable[i]), sizeof(xmlHashEntry));
- table->table[key].next = NULL;
- }
-
- for (i = 0; i < oldsize; i++) {
- iter = oldtable[i].next;
- while (iter) {
- next = iter->next;
-
- /*
- * put back the entry in the new table
- */
-
- key = xmlHashComputeKey(table, iter->name, iter->name2,
- iter->name3);
- if (table->table[key].valid == 0) {
- memcpy(&(table->table[key]), iter, sizeof(xmlHashEntry));
- table->table[key].next = NULL;
- xmlFree(iter);
- } else {
- iter->next = table->table[key].next;
- table->table[key].next = iter;
- }
-
-#ifdef DEBUG_GROW
- nbElem++;
-#endif
-
- iter = next;
- }
- }
-
- xmlFree(oldtable);
-
-#ifdef DEBUG_GROW
- xmlGenericError(xmlGenericErrorContext,
- "xmlHashGrow : from %d to %d, %d elems\n", oldsize, size, nbElem);
-#endif
-
- return(0);
-}
-
-/**
- * xmlHashFree:
- * @table: the hash table
- * @f: the deallocator function for items in the hash
- *
- * Free the hash @table and its contents. The userdata is
- * deallocated with @f if provided.
- */
-void
-xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) {
- int i;
- xmlHashEntryPtr iter;
- xmlHashEntryPtr next;
- int inside_table = 0;
-
- if (table == NULL)
- return;
- if (table->table) {
- for(i = 0; i < table->size; i++) {
- iter = &(table->table[i]);
- if (iter->valid == 0)
- continue;
- inside_table = 1;
- while (iter) {
- next = iter->next;
- if (f)
- f(iter->payload, iter->name);
- if (iter->name)
- xmlFree(iter->name);
- if (iter->name2)
- xmlFree(iter->name2);
- if (iter->name3)
- xmlFree(iter->name3);
- iter->payload = NULL;
- if (!inside_table)
- xmlFree(iter);
- inside_table = 0;
- iter = next;
- }
- inside_table = 0;
- }
- xmlFree(table->table);
- }
- xmlFree(table);
-}
-
-/**
- * xmlHashAddEntry:
- * @table: the hash table
- * @name: the name of the userdata
- * @userdata: a pointer to the userdata
- *
- * Add the @userdata to the hash @table. This can later be retrieved
- * by using the @name. Duplicate names generate errors.
- *
- * Returns 0 the addition succeeded and -1 in case of error.
- */
-int
-xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata) {
- return(xmlHashAddEntry3(table, name, NULL, NULL, userdata));
-}
-
-/**
- * xmlHashAddEntry2:
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
- * @userdata: a pointer to the userdata
- *
- * Add the @userdata to the hash @table. This can later be retrieved
- * by using the (@name, @name2) tuple. Duplicate tuples generate errors.
- *
- * Returns 0 the addition succeeded and -1 in case of error.
- */
-int
-xmlHashAddEntry2(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, void *userdata) {
- return(xmlHashAddEntry3(table, name, name2, NULL, userdata));
-}
-
-/**
- * xmlHashUpdateEntry:
- * @table: the hash table
- * @name: the name of the userdata
- * @userdata: a pointer to the userdata
- * @f: the deallocator function for replaced item (if any)
- *
- * Add the @userdata to the hash @table. This can later be retrieved
- * by using the @name. Existing entry for this @name will be removed
- * and freed with @f if found.
- *
- * Returns 0 the addition succeeded and -1 in case of error.
- */
-int
-xmlHashUpdateEntry(xmlHashTablePtr table, const xmlChar *name,
- void *userdata, xmlHashDeallocator f) {
- return(xmlHashUpdateEntry3(table, name, NULL, NULL, userdata, f));
-}
-
-/**
- * xmlHashUpdateEntry2:
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
- * @userdata: a pointer to the userdata
- * @f: the deallocator function for replaced item (if any)
- *
- * Add the @userdata to the hash @table. This can later be retrieved
- * by using the (@name, @name2) tuple. Existing entry for this tuple will
- * be removed and freed with @f if found.
- *
- * Returns 0 the addition succeeded and -1 in case of error.
- */
-int
-xmlHashUpdateEntry2(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, void *userdata,
- xmlHashDeallocator f) {
- return(xmlHashUpdateEntry3(table, name, name2, NULL, userdata, f));
-}
-
-/**
- * xmlHashLookup:
- * @table: the hash table
- * @name: the name of the userdata
- *
- * Find the userdata specified by the @name.
- *
- * Returns the pointer to the userdata
- */
-void *
-xmlHashLookup(xmlHashTablePtr table, const xmlChar *name) {
- return(xmlHashLookup3(table, name, NULL, NULL));
-}
-
-/**
- * xmlHashLookup2:
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
- *
- * Find the userdata specified by the (@name, @name2) tuple.
- *
- * Returns the pointer to the userdata
- */
-void *
-xmlHashLookup2(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2) {
- return(xmlHashLookup3(table, name, name2, NULL));
-}
-
-/**
- * xmlHashAddEntry3:
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
- * @name3: a third name of the userdata
- * @userdata: a pointer to the userdata
- *
- * Add the @userdata to the hash @table. This can later be retrieved
- * by using the tuple (@name, @name2, @name3). Duplicate entries generate
- * errors.
- *
- * Returns 0 the addition succeeded and -1 in case of error.
- */
-int
-xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, const xmlChar *name3,
- void *userdata) {
- unsigned long key, len = 0;
- xmlHashEntryPtr entry;
- xmlHashEntryPtr insert;
-
- if ((table == NULL) || name == NULL)
- return(-1);
-
- /*
- * Check for duplicate and insertion location.
- */
- key = xmlHashComputeKey(table, name, name2, name3);
- if (table->table[key].valid == 0) {
- insert = NULL;
- } else {
- for (insert = &(table->table[key]); insert->next != NULL;
- insert = insert->next) {
- if ((xmlStrEqual(insert->name, name)) &&
- (xmlStrEqual(insert->name2, name2)) &&
- (xmlStrEqual(insert->name3, name3)))
- return(-1);
- len++;
- }
- if ((xmlStrEqual(insert->name, name)) &&
- (xmlStrEqual(insert->name2, name2)) &&
- (xmlStrEqual(insert->name3, name3)))
- return(-1);
- }
-
- if (insert == NULL) {
- entry = &(table->table[key]);
- } else {
- entry = xmlMalloc(sizeof(xmlHashEntry));
- if (entry == NULL)
- return(-1);
- }
-
- entry->name = xmlStrdup(name);
- entry->name2 = xmlStrdup(name2);
- entry->name3 = xmlStrdup(name3);
- entry->payload = userdata;
- entry->next = NULL;
- entry->valid = 1;
-
-
- if (insert != NULL)
- insert->next = entry;
-
- table->nbElems++;
-
- if (len > MAX_HASH_LEN)
- xmlHashGrow(table, MAX_HASH_LEN * table->size);
-
- return(0);
-}
-
-/**
- * xmlHashUpdateEntry3:
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
- * @name3: a third name of the userdata
- * @userdata: a pointer to the userdata
- * @f: the deallocator function for replaced item (if any)
- *
- * Add the @userdata to the hash @table. This can later be retrieved
- * by using the tuple (@name, @name2, @name3). Existing entry for this tuple
- * will be removed and freed with @f if found.
- *
- * Returns 0 the addition succeeded and -1 in case of error.
- */
-int
-xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, const xmlChar *name3,
- void *userdata, xmlHashDeallocator f) {
- unsigned long key;
- xmlHashEntryPtr entry;
- xmlHashEntryPtr insert;
-
- if ((table == NULL) || name == NULL)
- return(-1);
-
- /*
- * Check for duplicate and insertion location.
- */
- key = xmlHashComputeKey(table, name, name2, name3);
- if (table->table[key].valid == 0) {
- insert = NULL;
- } else {
- for (insert = &(table->table[key]); insert->next != NULL;
- insert = insert->next) {
- if ((xmlStrEqual(insert->name, name)) &&
- (xmlStrEqual(insert->name2, name2)) &&
- (xmlStrEqual(insert->name3, name3))) {
- if (f)
- f(insert->payload, insert->name);
- insert->payload = userdata;
- return(0);
- }
- }
- if ((xmlStrEqual(insert->name, name)) &&
- (xmlStrEqual(insert->name2, name2)) &&
- (xmlStrEqual(insert->name3, name3))) {
- if (f)
- f(insert->payload, insert->name);
- insert->payload = userdata;
- return(0);
- }
- }
-
- if (insert == NULL) {
- entry = &(table->table[key]);
- } else {
- entry = xmlMalloc(sizeof(xmlHashEntry));
- if (entry == NULL)
- return(-1);
- }
-
- entry->name = xmlStrdup(name);
- entry->name2 = xmlStrdup(name2);
- entry->name3 = xmlStrdup(name3);
- entry->payload = userdata;
- entry->next = NULL;
- entry->valid = 1;
- table->nbElems++;
-
-
- if (insert != NULL) {
- insert->next = entry;
- }
- return(0);
-}
-
-/**
- * xmlHashLookup3:
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
- * @name3: a third name of the userdata
- *
- * Find the userdata specified by the (@name, @name2, @name3) tuple.
- *
- * Returns the a pointer to the userdata
- */
-void *
-xmlHashLookup3(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, const xmlChar *name3) {
- unsigned long key;
- xmlHashEntryPtr entry;
-
- if (table == NULL)
- return(NULL);
- if (name == NULL)
- return(NULL);
- key = xmlHashComputeKey(table, name, name2, name3);
- if (table->table[key].valid == 0)
- return(NULL);
- for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
- if ((xmlStrEqual(entry->name, name)) &&
- (xmlStrEqual(entry->name2, name2)) &&
- (xmlStrEqual(entry->name3, name3)))
- return(entry->payload);
- }
- return(NULL);
-}
-
-typedef struct {
- xmlHashScanner hashscanner;
- void *data;
-} stubData;
-
-static void
-stubHashScannerFull (void *payload, void *data, const xmlChar *name,
- const xmlChar *name2 ATTRIBUTE_UNUSED,
- const xmlChar *name3 ATTRIBUTE_UNUSED) {
- stubData *stubdata = (stubData *) data;
- stubdata->hashscanner (payload, stubdata->data, (xmlChar *) name);
-}
-
-/**
- * xmlHashScan:
- * @table: the hash table
- * @f: the scanner function for items in the hash
- * @data: extra data passed to f
- *
- * Scan the hash @table and applied @f to each value.
- */
-void
-xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data) {
- stubData stubdata;
- stubdata.data = data;
- stubdata.hashscanner = f;
- xmlHashScanFull (table, stubHashScannerFull, &stubdata);
-}
-
-/**
- * xmlHashScanFull:
- * @table: the hash table
- * @f: the scanner function for items in the hash
- * @data: extra data passed to f
- *
- * Scan the hash @table and applied @f to each value.
- */
-void
-xmlHashScanFull(xmlHashTablePtr table, xmlHashScannerFull f, void *data) {
- int i;
- xmlHashEntryPtr iter;
- xmlHashEntryPtr next;
-
- if (table == NULL)
- return;
- if (f == NULL)
- return;
-
- if (table->table) {
- for(i = 0; i < table->size; i++) {
- if (table->table[i].valid == 0)
- continue;
- iter = &(table->table[i]);
- while (iter) {
- next = iter->next;
- if (f)
- f(iter->payload, data, iter->name,
- iter->name2, iter->name3);
- iter = next;
- }
- }
- }
-}
-
-/**
- * xmlHashScan3:
- * @table: the hash table
- * @name: the name of the userdata or NULL
- * @name2: a second name of the userdata or NULL
- * @name3: a third name of the userdata or NULL
- * @f: the scanner function for items in the hash
- * @data: extra data passed to f
- *
- * Scan the hash @table and applied @f to each value matching
- * (@name, @name2, @name3) tuple. If one of the names is null,
- * the comparison is considered to match.
- */
-void
-xmlHashScan3(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, const xmlChar *name3,
- xmlHashScanner f, void *data) {
- xmlHashScanFull3 (table, name, name2, name3,
- (xmlHashScannerFull) f, data);
-}
-
-/**
- * xmlHashScanFull3:
- * @table: the hash table
- * @name: the name of the userdata or NULL
- * @name2: a second name of the userdata or NULL
- * @name3: a third name of the userdata or NULL
- * @f: the scanner function for items in the hash
- * @data: extra data passed to f
- *
- * Scan the hash @table and applied @f to each value matching
- * (@name, @name2, @name3) tuple. If one of the names is null,
- * the comparison is considered to match.
- */
-void
-xmlHashScanFull3(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, const xmlChar *name3,
- xmlHashScannerFull f, void *data) {
- int i;
- xmlHashEntryPtr iter;
- xmlHashEntryPtr next;
-
- if (table == NULL)
- return;
- if (f == NULL)
- return;
-
- if (table->table) {
- for(i = 0; i < table->size; i++) {
- if (table->table[i].valid == 0)
- continue;
- iter = &(table->table[i]);
- while (iter) {
- next = iter->next;
- if (((name == NULL) || (xmlStrEqual(name, iter->name))) &&
- ((name2 == NULL) || (xmlStrEqual(name2, iter->name2))) &&
- ((name3 == NULL) || (xmlStrEqual(name3, iter->name3)))) {
- f(iter->payload, data, iter->name,
- iter->name2, iter->name3);
- }
- iter = next;
- }
- }
- }
-}
-
-/**
- * xmlHashCopy:
- * @table: the hash table
- * @f: the copier function for items in the hash
- *
- * Scan the hash @table and applied @f to each value.
- *
- * Returns the new table or NULL in case of error.
- */
-xmlHashTablePtr
-xmlHashCopy(xmlHashTablePtr table, xmlHashCopier f) {
- int i;
- xmlHashEntryPtr iter;
- xmlHashEntryPtr next;
- xmlHashTablePtr ret;
-
- if (table == NULL)
- return(NULL);
- if (f == NULL)
- return(NULL);
-
- ret = xmlHashCreate(table->size);
- if (table->table) {
- for(i = 0; i < table->size; i++) {
- if (table->table[i].valid == 0)
- continue;
- iter = &(table->table[i]);
- while (iter) {
- next = iter->next;
- xmlHashAddEntry3(ret, iter->name, iter->name2,
- iter->name3, f(iter->payload, iter->name));
- iter = next;
- }
- }
- }
- ret->nbElems = table->nbElems;
- return(ret);
-}
-
-/**
- * xmlHashSize:
- * @table: the hash table
- *
- * Query the number of elements installed in the hash @table.
- *
- * Returns the number of elements in the hash table or
- * -1 in case of error
- */
-int
-xmlHashSize(xmlHashTablePtr table) {
- if (table == NULL)
- return(-1);
- return(table->nbElems);
-}
-
-/**
- * xmlHashRemoveEntry:
- * @table: the hash table
- * @name: the name of the userdata
- * @f: the deallocator function for removed item (if any)
- *
- * Find the userdata specified by the @name and remove
- * it from the hash @table. Existing userdata for this tuple will be removed
- * and freed with @f.
- *
- * Returns 0 if the removal succeeded and -1 in case of error or not found.
- */
-int xmlHashRemoveEntry(xmlHashTablePtr table, const xmlChar *name,
- xmlHashDeallocator f) {
- return(xmlHashRemoveEntry3(table, name, NULL, NULL, f));
-}
-
-/**
- * xmlHashRemoveEntry2:
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
- * @f: the deallocator function for removed item (if any)
- *
- * Find the userdata specified by the (@name, @name2) tuple and remove
- * it from the hash @table. Existing userdata for this tuple will be removed
- * and freed with @f.
- *
- * Returns 0 if the removal succeeded and -1 in case of error or not found.
- */
-int
-xmlHashRemoveEntry2(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, xmlHashDeallocator f) {
- return(xmlHashRemoveEntry3(table, name, name2, NULL, f));
-}
-
-/**
- * xmlHashRemoveEntry3:
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
- * @name3: a third name of the userdata
- * @f: the deallocator function for removed item (if any)
- *
- * Find the userdata specified by the (@name, @name2, @name3) tuple and remove
- * it from the hash @table. Existing userdata for this tuple will be removed
- * and freed with @f.
- *
- * Returns 0 if the removal succeeded and -1 in case of error or not found.
- */
-int
-xmlHashRemoveEntry3(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, const xmlChar *name3, xmlHashDeallocator f) {
- unsigned long key;
- xmlHashEntryPtr entry;
- xmlHashEntryPtr prev = NULL;
-
- if (table == NULL || name == NULL)
- return(-1);
-
- key = xmlHashComputeKey(table, name, name2, name3);
- if (table->table[key].valid == 0) {
- return(-1);
- } else {
- for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
- if (xmlStrEqual(entry->name, name) &&
- xmlStrEqual(entry->name2, name2) &&
- xmlStrEqual(entry->name3, name3)) {
- if(f)
- f(entry->payload, entry->name);
- entry->payload = NULL;
- if(entry->name)
- xmlFree(entry->name);
- if(entry->name2)
- xmlFree(entry->name2);
- if(entry->name3)
- xmlFree(entry->name3);
- if(prev) {
- prev->next = entry->next;
- xmlFree(entry);
- } else {
- if (entry->next == NULL) {
- entry->valid = 0;
- } else {
- entry = entry->next;
- memcpy(&(table->table[key]), entry, sizeof(xmlHashEntry));
- xmlFree(entry);
- }
- }
- table->nbElems--;
- return(0);
- }
- prev = entry;
- }
- return(-1);
- }
-}
-
diff --git a/bundle/libxml/include/libxml/DOCBparser.h b/bundle/libxml/include/libxml/DOCBparser.h
deleted file mode 100644
index 4b7230f17d..0000000000
--- a/bundle/libxml/include/libxml/DOCBparser.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * DOCBparser.h : interface for a DocBook SGML non-verifying parser
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#ifndef __DOCB_PARSER_H__
-#define __DOCB_PARSER_H__
-#include <libxml/parser.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Most of the back-end structures from XML and SGML are shared.
- */
-typedef xmlParserCtxt docbParserCtxt;
-typedef xmlParserCtxtPtr docbParserCtxtPtr;
-typedef xmlParserNodeInfo docbParserNodeInfo;
-typedef xmlSAXHandler docbSAXHandler;
-typedef xmlSAXHandlerPtr docbSAXHandlerPtr;
-typedef xmlParserInput docbParserInput;
-typedef xmlParserInputPtr docbParserInputPtr;
-typedef xmlDocPtr docbDocPtr;
-typedef xmlNodePtr docbNodePtr;
-
-/*
- * There is only few public functions.
- */
-int docbEncodeEntities(unsigned char *out,
- int *outlen,
- const unsigned char *in,
- int *inlen, int quoteChar);
-
-docbDocPtr docbSAXParseDoc (xmlChar *cur,
- const char *encoding,
- docbSAXHandlerPtr sax,
- void *userData);
-docbDocPtr docbParseDoc (xmlChar *cur,
- const char *encoding);
-docbDocPtr docbSAXParseFile(const char *filename,
- const char *encoding,
- docbSAXHandlerPtr sax,
- void *userData);
-docbDocPtr docbParseFile (const char *filename,
- const char *encoding);
-
-/**
- * Interfaces for the Push mode.
- */
-void docbFreeParserCtxt (docbParserCtxtPtr ctxt);
-docbParserCtxtPtr docbCreatePushParserCtxt(docbSAXHandlerPtr sax,
- void *user_data,
- const char *chunk,
- int size,
- const char *filename,
- xmlCharEncoding enc);
-int docbParseChunk (docbParserCtxtPtr ctxt,
- const char *chunk,
- int size,
- int terminate);
-docbParserCtxtPtr docbCreateFileParserCtxt(const char *filename,
- const char *encoding);
-int docbParseDocument (docbParserCtxtPtr ctxt);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __DOCB_PARSER_H__ */
diff --git a/bundle/libxml/include/libxml/HTMLparser.h b/bundle/libxml/include/libxml/HTMLparser.h
deleted file mode 100644
index f09213711e..0000000000
--- a/bundle/libxml/include/libxml/HTMLparser.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * HTMLparser.h : interface for an HTML 4.0 non-verifying parser
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#ifndef __HTML_PARSER_H__
-#define __HTML_PARSER_H__
-#include <libxml/parser.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Most of the back-end structures from XML and HTML are shared.
- */
-typedef xmlParserCtxt htmlParserCtxt;
-typedef xmlParserCtxtPtr htmlParserCtxtPtr;
-typedef xmlParserNodeInfo htmlParserNodeInfo;
-typedef xmlSAXHandler htmlSAXHandler;
-typedef xmlSAXHandlerPtr htmlSAXHandlerPtr;
-typedef xmlParserInput htmlParserInput;
-typedef xmlParserInputPtr htmlParserInputPtr;
-typedef xmlDocPtr htmlDocPtr;
-typedef xmlNodePtr htmlNodePtr;
-
-/*
- * Internal description of an HTML element.
- */
-typedef struct _htmlElemDesc htmlElemDesc;
-typedef htmlElemDesc *htmlElemDescPtr;
-struct _htmlElemDesc {
- const char *name; /* The tag name */
- char startTag; /* Whether the start tag can be implied */
- char endTag; /* Whether the end tag can be implied */
- char saveEndTag; /* Whether the end tag should be saved */
- char empty; /* Is this an empty element ? */
- char depr; /* Is this a deprecated element ? */
- char dtd; /* 1: only in Loose DTD, 2: only Frameset one */
- char isinline; /* is this a block 0 or inline 1 element */
- const char *desc; /* the description */
-};
-
-/*
- * Internal description of an HTML entity.
- */
-typedef struct _htmlEntityDesc htmlEntityDesc;
-typedef htmlEntityDesc *htmlEntityDescPtr;
-struct _htmlEntityDesc {
- unsigned int value; /* the UNICODE value for the character */
- const char *name; /* The entity name */
- const char *desc; /* the description */
-};
-
-/*
- * There is only few public functions.
- */
-const htmlElemDesc * htmlTagLookup (const xmlChar *tag);
-const htmlEntityDesc * htmlEntityLookup(const xmlChar *name);
-const htmlEntityDesc * htmlEntityValueLookup(unsigned int value);
-
-int htmlIsAutoClosed(htmlDocPtr doc,
- htmlNodePtr elem);
-int htmlAutoCloseTag(htmlDocPtr doc,
- const xmlChar *name,
- htmlNodePtr elem);
-const htmlEntityDesc * htmlParseEntityRef(htmlParserCtxtPtr ctxt,
- xmlChar **str);
-int htmlParseCharRef(htmlParserCtxtPtr ctxt);
-void htmlParseElement(htmlParserCtxtPtr ctxt);
-
-int htmlParseDocument(htmlParserCtxtPtr ctxt);
-htmlDocPtr htmlSAXParseDoc (xmlChar *cur,
- const char *encoding,
- htmlSAXHandlerPtr sax,
- void *userData);
-htmlDocPtr htmlParseDoc (xmlChar *cur,
- const char *encoding);
-htmlDocPtr htmlSAXParseFile(const char *filename,
- const char *encoding,
- htmlSAXHandlerPtr sax,
- void *userData);
-htmlDocPtr htmlParseFile (const char *filename,
- const char *encoding);
-int UTF8ToHtml (unsigned char *out,
- int *outlen,
- const unsigned char *in,
- int *inlen);
-int htmlEncodeEntities(unsigned char *out,
- int *outlen,
- const unsigned char *in,
- int *inlen, int quoteChar);
-int htmlIsScriptAttribute(const xmlChar *name);
-int htmlHandleOmittedElem(int val);
-
-/**
- * Interfaces for the Push mode.
- */
-void htmlFreeParserCtxt (htmlParserCtxtPtr ctxt);
-htmlParserCtxtPtr htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax,
- void *user_data,
- const char *chunk,
- int size,
- const char *filename,
- xmlCharEncoding enc);
-int htmlParseChunk (htmlParserCtxtPtr ctxt,
- const char *chunk,
- int size,
- int terminate);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __HTML_PARSER_H__ */
diff --git a/bundle/libxml/include/libxml/HTMLtree.h b/bundle/libxml/include/libxml/HTMLtree.h
deleted file mode 100644
index 3a441c4b5c..0000000000
--- a/bundle/libxml/include/libxml/HTMLtree.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * HTMLtree.h : describes the structures found in an tree resulting
- * from an XML parsing.
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#ifndef __HTML_TREE_H__
-#define __HTML_TREE_H__
-
-#include <stdio.h>
-#include <libxml/tree.h>
-#include <libxml/HTMLparser.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/**
- * HTML_TEXT_NODE:
- *
- * Macro. A text node in a HTML document is really implemented
- * the same way as a text node in an XML document.
- */
-#define HTML_TEXT_NODE XML_TEXT_NODE
-/**
- * HTML_ENTITY_REF_NODE:
- *
- * Macro. An entity reference in a HTML document is really implemented
- * the same way as an entity reference in an XML document.
- */
-#define HTML_ENTITY_REF_NODE XML_ENTITY_REF_NODE
-/**
- * HTML_COMMENT_NODE:
- *
- * Macro. A comment in a HTML document is really implemented
- * the same way as a comment in an XML document.
- */
-#define HTML_COMMENT_NODE XML_COMMENT_NODE
-/**
- * HTML_PRESERVE_NODE:
- *
- * Macro. A preserved node in a HTML document is really implemented
- * the same way as a CDATA section in an XML document.
- */
-#define HTML_PRESERVE_NODE XML_CDATA_SECTION_NODE
-/**
- * HTML_PI_NODE:
- *
- * Macro. A processing instruction in a HTML document is really implemented
- * the same way as a processing instruction in an XML document.
- */
-#define HTML_PI_NODE XML_PI_NODE
-
-htmlDocPtr htmlNewDoc (const xmlChar *URI,
- const xmlChar *ExternalID);
-htmlDocPtr htmlNewDocNoDtD (const xmlChar *URI,
- const xmlChar *ExternalID);
-const xmlChar * htmlGetMetaEncoding (htmlDocPtr doc);
-int htmlSetMetaEncoding (htmlDocPtr doc,
- const xmlChar *encoding);
-void htmlDocDumpMemory (xmlDocPtr cur,
- xmlChar **mem,
- int *size);
-int htmlDocDump (FILE *f,
- xmlDocPtr cur);
-int htmlSaveFile (const char *filename,
- xmlDocPtr cur);
-int htmlNodeDump (xmlBufferPtr buf,
- xmlDocPtr doc,
- xmlNodePtr cur);
-void htmlNodeDumpFile (FILE *out,
- xmlDocPtr doc,
- xmlNodePtr cur);
-int htmlNodeDumpFileFormat (FILE *out,
- xmlDocPtr doc,
- xmlNodePtr cur,
- const char *encoding,
- int format);
-int htmlSaveFileEnc (const char *filename,
- xmlDocPtr cur,
- const char *encoding);
-int htmlSaveFileFormat (const char *filename,
- xmlDocPtr cur,
- const char *encoding,
- int format);
-
-void htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf,
- xmlDocPtr doc,
- xmlNodePtr cur,
- const char *encoding,
- int format);
-void htmlDocContentDumpOutput(xmlOutputBufferPtr buf,
- xmlDocPtr cur,
- const char *encoding);
-void htmlDocContentDumpFormatOutput(xmlOutputBufferPtr buf,
- xmlDocPtr cur,
- const char *encoding,
- int format);
-
-int htmlIsBooleanAttr (const xmlChar *name);
-void htmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
- xmlNodePtr cur, const char *encoding);
-
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __HTML_TREE_H__ */
-
diff --git a/bundle/libxml/include/libxml/Makefile.am b/bundle/libxml/include/libxml/Makefile.am
deleted file mode 100644
index 3a50bc1fcb..0000000000
--- a/bundle/libxml/include/libxml/Makefile.am
+++ /dev/null
@@ -1,46 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-xmlincdir = $(includedir)/libxml2/libxml
-
-xmlinc_HEADERS = \
- SAX.h \
- entities.h \
- encoding.h \
- parser.h \
- parserInternals.h \
- xmlerror.h \
- HTMLparser.h \
- HTMLtree.h \
- debugXML.h \
- tree.h \
- list.h \
- hash.h \
- xpath.h \
- xpathInternals.h \
- xpointer.h \
- xinclude.h \
- xmlIO.h \
- xmlmemory.h \
- nanohttp.h \
- nanoftp.h \
- uri.h \
- valid.h \
- xlink.h \
- xmlversion.h \
- DOCBparser.h \
- catalog.h \
- threads.h \
- globals.h \
- c14n.h \
- xmlautomata.h \
- xmlregexp.h \
- xmlschemas.h \
- schemasInternals.h \
- xmlschemastypes.h \
- xmlunicode.h \
- xmlreader.h
-
-install-exec-hook:
- $(mkinstalldirs) $(DESTDIR)$(xmlincdir)
-
-EXTRA_DIST = xmlversion.h.in
diff --git a/bundle/libxml/include/libxml/Makefile.in b/bundle/libxml/include/libxml/Makefile.in
deleted file mode 100644
index af1022c53a..0000000000
--- a/bundle/libxml/include/libxml/Makefile.in
+++ /dev/null
@@ -1,335 +0,0 @@
-# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
-
-# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-
-SHELL = @SHELL@
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-VPATH = @srcdir@
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-
-bindir = @bindir@
-sbindir = @sbindir@
-libexecdir = @libexecdir@
-datadir = @datadir@
-sysconfdir = @sysconfdir@
-sharedstatedir = @sharedstatedir@
-localstatedir = @localstatedir@
-libdir = @libdir@
-infodir = @infodir@
-mandir = @mandir@
-includedir = @includedir@
-oldincludedir = /usr/include
-
-DESTDIR =
-
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-
-top_builddir = ../..
-
-ACLOCAL = @ACLOCAL@
-AUTOCONF = @AUTOCONF@
-AUTOMAKE = @AUTOMAKE@
-AUTOHEADER = @AUTOHEADER@
-
-INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-transform = @program_transform_name@
-
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-host_alias = @host_alias@
-host_triplet = @host@
-AS = @AS@
-C14N_OBJ = @C14N_OBJ@
-CATALOG_OBJ = @CATALOG_OBJ@
-CC = @CC@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-DEBUG_OBJ = @DEBUG_OBJ@
-DLLTOOL = @DLLTOOL@
-DOCB_OBJ = @DOCB_OBJ@
-ECHO = @ECHO@
-EXEEXT = @EXEEXT@
-FTP_OBJ = @FTP_OBJ@
-HAVE_ISINF = @HAVE_ISINF@
-HAVE_ISNAN = @HAVE_ISNAN@
-HTML_DIR = @HTML_DIR@
-HTML_OBJ = @HTML_OBJ@
-HTTP_OBJ = @HTTP_OBJ@
-ICONV_LIBS = @ICONV_LIBS@
-LIBTOOL = @LIBTOOL@
-LIBXML_MAJOR_VERSION = @LIBXML_MAJOR_VERSION@
-LIBXML_MICRO_VERSION = @LIBXML_MICRO_VERSION@
-LIBXML_MINOR_VERSION = @LIBXML_MINOR_VERSION@
-LIBXML_VERSION = @LIBXML_VERSION@
-LIBXML_VERSION_INFO = @LIBXML_VERSION_INFO@
-LIBXML_VERSION_NUMBER = @LIBXML_VERSION_NUMBER@
-LN_S = @LN_S@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MV = @MV@
-M_LIBS = @M_LIBS@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-PACKAGE = @PACKAGE@
-PYTHON = @PYTHON@
-PYTHON_INCLUDES = @PYTHON_INCLUDES@
-PYTHON_SITE_PACKAGES = @PYTHON_SITE_PACKAGES@
-PYTHON_SUBDIR = @PYTHON_SUBDIR@
-PYTHON_VERSION = @PYTHON_VERSION@
-RANLIB = @RANLIB@
-RDL_LIBS = @RDL_LIBS@
-RELDATE = @RELDATE@
-RM = @RM@
-STRIP = @STRIP@
-TAR = @TAR@
-TEST_REGEXPS = @TEST_REGEXPS@
-TEST_SCHEMAS = @TEST_SCHEMAS@
-TEST_THREADS = @TEST_THREADS@
-THREAD_CFLAGS = @THREAD_CFLAGS@
-THREAD_LIBS = @THREAD_LIBS@
-U = @U@
-VERSION = @VERSION@
-WITH_C14N = @WITH_C14N@
-WITH_CATALOG = @WITH_CATALOG@
-WITH_DEBUG = @WITH_DEBUG@
-WITH_DOCB = @WITH_DOCB@
-WITH_FTP = @WITH_FTP@
-WITH_HTML = @WITH_HTML@
-WITH_HTTP = @WITH_HTTP@
-WITH_ICONV = @WITH_ICONV@
-WITH_MEM_DEBUG = @WITH_MEM_DEBUG@
-WITH_REGEXPS = @WITH_REGEXPS@
-WITH_SCHEMAS = @WITH_SCHEMAS@
-WITH_THREADS = @WITH_THREADS@
-WITH_TRIO = @WITH_TRIO@
-WITH_XINCLUDE = @WITH_XINCLUDE@
-WITH_XPATH = @WITH_XPATH@
-WITH_XPTR = @WITH_XPTR@
-XINCLUDE_OBJ = @XINCLUDE_OBJ@
-XML_CFLAGS = @XML_CFLAGS@
-XML_INCLUDEDIR = @XML_INCLUDEDIR@
-XML_LIBDIR = @XML_LIBDIR@
-XML_LIBS = @XML_LIBS@
-XPATH_OBJ = @XPATH_OBJ@
-XPTR_OBJ = @XPTR_OBJ@
-Z_CFLAGS = @Z_CFLAGS@
-Z_LIBS = @Z_LIBS@
-
-xmlincdir = $(includedir)/libxml2/libxml
-
-xmlinc_HEADERS = \
- SAX.h \
- entities.h \
- encoding.h \
- parser.h \
- parserInternals.h \
- xmlerror.h \
- HTMLparser.h \
- HTMLtree.h \
- debugXML.h \
- tree.h \
- list.h \
- hash.h \
- xpath.h \
- xpathInternals.h \
- xpointer.h \
- xinclude.h \
- xmlIO.h \
- xmlmemory.h \
- nanohttp.h \
- nanoftp.h \
- uri.h \
- valid.h \
- xlink.h \
- xmlversion.h \
- DOCBparser.h \
- catalog.h \
- threads.h \
- globals.h \
- c14n.h \
- xmlautomata.h \
- xmlregexp.h \
- xmlschemas.h \
- schemasInternals.h \
- xmlschemastypes.h \
- xmlunicode.h \
- xmlreader.h
-
-
-EXTRA_DIST = xmlversion.h.in
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_HEADER = ../../config.h
-CONFIG_CLEAN_FILES = xmlversion.h
-HEADERS = $(xmlinc_HEADERS)
-
-DIST_COMMON = Makefile.am Makefile.in xmlversion.h.in
-
-
-DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
-
-GZIP_ENV = --best
-all: all-redirect
-.SUFFIXES:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
- cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps include/libxml/Makefile
-
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- cd $(top_builddir) \
- && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-
-xmlversion.h: $(top_builddir)/config.status xmlversion.h.in
- cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
-
-install-xmlincHEADERS: $(xmlinc_HEADERS)
- @$(NORMAL_INSTALL)
- $(mkinstalldirs) $(DESTDIR)$(xmlincdir)
- @list='$(xmlinc_HEADERS)'; for p in $$list; do \
- if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
- echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(xmlincdir)/$$p"; \
- $(INSTALL_DATA) $$d$$p $(DESTDIR)$(xmlincdir)/$$p; \
- done
-
-uninstall-xmlincHEADERS:
- @$(NORMAL_UNINSTALL)
- list='$(xmlinc_HEADERS)'; for p in $$list; do \
- rm -f $(DESTDIR)$(xmlincdir)/$$p; \
- done
-
-tags: TAGS
-
-ID: $(HEADERS) $(SOURCES) $(LISP)
- list='$(SOURCES) $(HEADERS)'; \
- unique=`for i in $$list; do echo $$i; done | \
- awk ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
- here=`pwd` && cd $(srcdir) \
- && mkid -f$$here/ID $$unique $(LISP)
-
-TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
- tags=; \
- here=`pwd`; \
- list='$(SOURCES) $(HEADERS)'; \
- unique=`for i in $$list; do echo $$i; done | \
- awk ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
- test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
- || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
-
-mostlyclean-tags:
-
-clean-tags:
-
-distclean-tags:
- -rm -f TAGS ID
-
-maintainer-clean-tags:
-
-distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
-
-subdir = include/libxml
-
-distdir: $(DISTFILES)
- @for file in $(DISTFILES); do \
- d=$(srcdir); \
- if test -d $$d/$$file; then \
- cp -pr $$d/$$file $(distdir)/$$file; \
- else \
- test -f $(distdir)/$$file \
- || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
- || cp -p $$d/$$file $(distdir)/$$file || :; \
- fi; \
- done
-info-am:
-info: info-am
-dvi-am:
-dvi: dvi-am
-check-am: all-am
-check: check-am
-installcheck-am:
-installcheck: installcheck-am
-install-exec-am:
- @$(NORMAL_INSTALL)
- $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
-install-exec: install-exec-am
-
-install-data-am: install-xmlincHEADERS
-install-data: install-data-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-install: install-am
-uninstall-am: uninstall-xmlincHEADERS
-uninstall: uninstall-am
-all-am: Makefile $(HEADERS)
-all-redirect: all-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
-installdirs:
- $(mkinstalldirs) $(DESTDIR)$(xmlincdir)
-
-
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -rm -f Makefile $(CONFIG_CLEAN_FILES)
- -rm -f config.cache config.log stamp-h stamp-h[0-9]*
-
-maintainer-clean-generic:
-mostlyclean-am: mostlyclean-tags mostlyclean-generic
-
-mostlyclean: mostlyclean-am
-
-clean-am: clean-tags clean-generic mostlyclean-am
-
-clean: clean-am
-
-distclean-am: distclean-tags distclean-generic clean-am
- -rm -f libtool
-
-distclean: distclean-am
-
-maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
- distclean-am
- @echo "This command is intended for maintainers to use;"
- @echo "it deletes files that may require special tools to rebuild."
-
-maintainer-clean: maintainer-clean-am
-
-.PHONY: uninstall-xmlincHEADERS install-xmlincHEADERS tags \
-mostlyclean-tags distclean-tags clean-tags maintainer-clean-tags \
-distdir info-am info dvi-am dvi check check-am installcheck-am \
-installcheck install-exec-am install-exec install-data-am install-data \
-install-am install uninstall-am uninstall all-redirect all-am all \
-installdirs mostlyclean-generic distclean-generic clean-generic \
-maintainer-clean-generic clean mostlyclean distclean maintainer-clean
-
-
-install-exec-hook:
- $(mkinstalldirs) $(DESTDIR)$(xmlincdir)
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/bundle/libxml/include/libxml/SAX.h b/bundle/libxml/include/libxml/SAX.h
deleted file mode 100644
index d96d9e9596..0000000000
--- a/bundle/libxml/include/libxml/SAX.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * SAX.h : Default SAX handler interfaces.
- *
- * See Copyright for the status of this software.
- *
- * Daniel Veillard <daniel@veillard.com>
- */
-
-
-#ifndef __XML_SAX_H__
-#define __XML_SAX_H__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <libxml/parser.h>
-#include <libxml/xlink.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-const xmlChar * getPublicId (void *ctx);
-const xmlChar * getSystemId (void *ctx);
-void setDocumentLocator (void *ctx,
- xmlSAXLocatorPtr loc);
-
-int getLineNumber (void *ctx);
-int getColumnNumber (void *ctx);
-
-int isStandalone (void *ctx);
-int hasInternalSubset (void *ctx);
-int hasExternalSubset (void *ctx);
-
-void internalSubset (void *ctx,
- const xmlChar *name,
- const xmlChar *ExternalID,
- const xmlChar *SystemID);
-void externalSubset (void *ctx,
- const xmlChar *name,
- const xmlChar *ExternalID,
- const xmlChar *SystemID);
-xmlEntityPtr getEntity (void *ctx,
- const xmlChar *name);
-xmlEntityPtr getParameterEntity (void *ctx,
- const xmlChar *name);
-xmlParserInputPtr resolveEntity (void *ctx,
- const xmlChar *publicId,
- const xmlChar *systemId);
-
-void entityDecl (void *ctx,
- const xmlChar *name,
- int type,
- const xmlChar *publicId,
- const xmlChar *systemId,
- xmlChar *content);
-void attributeDecl (void *ctx,
- const xmlChar *elem,
- const xmlChar *fullname,
- int type,
- int def,
- const xmlChar *defaultValue,
- xmlEnumerationPtr tree);
-void elementDecl (void *ctx,
- const xmlChar *name,
- int type,
- xmlElementContentPtr content);
-void notationDecl (void *ctx,
- const xmlChar *name,
- const xmlChar *publicId,
- const xmlChar *systemId);
-void unparsedEntityDecl (void *ctx,
- const xmlChar *name,
- const xmlChar *publicId,
- const xmlChar *systemId,
- const xmlChar *notationName);
-
-void startDocument (void *ctx);
-void endDocument (void *ctx);
-void attribute (void *ctx,
- const xmlChar *fullname,
- const xmlChar *value);
-void startElement (void *ctx,
- const xmlChar *fullname,
- const xmlChar **atts);
-void endElement (void *ctx,
- const xmlChar *name);
-void reference (void *ctx,
- const xmlChar *name);
-void characters (void *ctx,
- const xmlChar *ch,
- int len);
-void ignorableWhitespace (void *ctx,
- const xmlChar *ch,
- int len);
-void processingInstruction (void *ctx,
- const xmlChar *target,
- const xmlChar *data);
-void globalNamespace (void *ctx,
- const xmlChar *href,
- const xmlChar *prefix);
-void setNamespace (void *ctx,
- const xmlChar *name);
-xmlNsPtr getNamespace (void *ctx);
-int checkNamespace (void *ctx,
- xmlChar *nameSpace);
-void namespaceDecl (void *ctx,
- const xmlChar *href,
- const xmlChar *prefix);
-void comment (void *ctx,
- const xmlChar *value);
-void cdataBlock (void *ctx,
- const xmlChar *value,
- int len);
-
-void initxmlDefaultSAXHandler (xmlSAXHandler *hdlr,
- int warning);
-#ifdef LIBXML_HTML_ENABLED
-void inithtmlDefaultSAXHandler (xmlSAXHandler *hdlr);
-#endif
-#ifdef LIBXML_DOCB_ENABLED
-void initdocbDefaultSAXHandler (xmlSAXHandler *hdlr);
-#endif
-void xmlDefaultSAXHandlerInit (void);
-void htmlDefaultSAXHandlerInit (void);
-void docbDefaultSAXHandlerInit (void);
-#ifdef __cplusplus
-}
-#endif
-#endif /* __XML_SAX_H__ */
diff --git a/bundle/libxml/include/libxml/c14n.h b/bundle/libxml/include/libxml/c14n.h
deleted file mode 100644
index 75ace8a4a4..0000000000
--- a/bundle/libxml/include/libxml/c14n.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * "Canonical XML" implementation
- * http://www.w3.org/TR/xml-c14n
- *
- * "Exclusive XML Canonicalization" implementation
- * http://www.w3.org/TR/xml-exc-c14n
-
- * See Copyright for the status of this software.
- *
- * Author: Aleksey Sanin <aleksey@aleksey.com>
- */
-#ifndef __XML_C14N_H__
-#define __XML_C14N_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#include <libxml/tree.h>
-#include <libxml/xpath.h>
-
-/*
- * XML Canonicazation
- * http://www.w3.org/TR/xml-c14n
- *
- * Exclusive XML Canonicazation
- * http://www.w3.org/TR/xml-exc-c14n
- *
- * Canonical form of an XML document could be created if and only if
- * a) default attributes (if any) are added to all nodes
- * b) all character and parsed entity references are resolved
- * In order to achive this in libxml2 the document MUST be loaded with
- * following global setings:
- *
- * xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
- * xmlSubstituteEntitiesDefault(1);
- *
- * or corresponding parser context setting:
- * xmlParserCtxtPtr ctxt;
- *
- * ...
- * ctxt->loadsubset = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
- * ctxt->replaceEntities = 1;
- * ...
- */
-
-
-int xmlC14NDocSaveTo (xmlDocPtr doc,
- xmlNodeSetPtr nodes,
- int exclusive,
- xmlChar **inclusive_ns_prefixes,
- int with_comments,
- xmlOutputBufferPtr buf);
-
-int xmlC14NDocDumpMemory (xmlDocPtr doc,
- xmlNodeSetPtr nodes,
- int exclusive,
- xmlChar **inclusive_ns_prefixes,
- int with_comments,
- xmlChar **doc_txt_ptr);
-
-int xmlC14NDocSave (xmlDocPtr doc,
- xmlNodeSetPtr nodes,
- int exclusive,
- xmlChar **inclusive_ns_prefixes,
- int with_comments,
- const char* filename,
- int compression);
-
-
-/**
- * This is the core C14N function
- */
-typedef int (*xmlC14NIsVisibleCallback) (void* user_data,
- xmlNodePtr node,
- xmlNodePtr parent);
-
-int xmlC14NExecute (xmlDocPtr doc,
- xmlC14NIsVisibleCallback is_visible_callback,
- void* user_data,
- int exclusive,
- xmlChar **inclusive_ns_prefixes,
- int with_comments,
- xmlOutputBufferPtr buf);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __XML_C14N_H__ */
-
diff --git a/bundle/libxml/include/libxml/catalog.h b/bundle/libxml/include/libxml/catalog.h
deleted file mode 100644
index 037e7e80e0..0000000000
--- a/bundle/libxml/include/libxml/catalog.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
- * catalog.h: interfaces of the Catalog handling system
- *
- * Reference: SGML Open Technical Resolution TR9401:1997.
- * http://www.jclark.com/sp/catalog.htm
- *
- * XML Catalogs Working Draft 12 Jun 2001
- * http://www.oasis-open.org/committees/entity/spec-2001-06-12.html
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#ifndef __XML_CATALOG_H__
-#define __XML_CATALOG_H__
-
-#include <stdio.h>
-
-#include <libxml/xmlversion.h>
-
-#ifdef LIBXML_CATALOG_ENABLED
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * XML_CATALOGS_NAMESPACE:
- *
- * The namespace for the XML Catalogs elements.
- */
-#define XML_CATALOGS_NAMESPACE \
- (const xmlChar *) "urn:oasis:names:tc:entity:xmlns:xml:catalog"
-/**
- * XML_CATALOG_PI:
- *
- * The specific XML Catalog Processing Instuction name.
- */
-#define XML_CATALOG_PI \
- (const xmlChar *) "oasis-xml-catalog"
-
-/*
- * The API is voluntarily limited to general cataloging.
- */
-typedef enum {
- XML_CATA_PREFER_NONE = 0,
- XML_CATA_PREFER_PUBLIC = 1,
- XML_CATA_PREFER_SYSTEM
-} xmlCatalogPrefer;
-
-typedef enum {
- XML_CATA_ALLOW_NONE = 0,
- XML_CATA_ALLOW_GLOBAL = 1,
- XML_CATA_ALLOW_DOCUMENT = 2,
- XML_CATA_ALLOW_ALL = 3
-} xmlCatalogAllow;
-
-typedef struct _xmlCatalog xmlCatalog;
-typedef xmlCatalog *xmlCatalogPtr;
-
-/*
- * Operations on a given catalog.
- */
-xmlCatalogPtr xmlNewCatalog (int sgml);
-xmlCatalogPtr xmlLoadACatalog (const char *filename);
-xmlCatalogPtr xmlLoadSGMLSuperCatalog (const char *filename);
-int xmlConvertSGMLCatalog (xmlCatalogPtr catal);
-int xmlACatalogAdd (xmlCatalogPtr catal,
- const xmlChar *type,
- const xmlChar *orig,
- const xmlChar *replace);
-int xmlACatalogRemove (xmlCatalogPtr catal,
- const xmlChar *value);
-xmlChar * xmlACatalogResolve (xmlCatalogPtr catal,
- const xmlChar *pubID,
- const xmlChar *sysID);
-xmlChar * xmlACatalogResolveSystem(xmlCatalogPtr catal,
- const xmlChar *sysID);
-xmlChar * xmlACatalogResolvePublic(xmlCatalogPtr catal,
- const xmlChar *pubID);
-xmlChar * xmlACatalogResolveURI (xmlCatalogPtr catal,
- const xmlChar *URI);
-void xmlACatalogDump (xmlCatalogPtr catal,
- FILE *out);
-void xmlFreeCatalog (xmlCatalogPtr catal);
-int xmlCatalogIsEmpty (xmlCatalogPtr catal);
-
-/*
- * Global operations.
- */
-void xmlInitializeCatalog (void);
-int xmlLoadCatalog (const char *filename);
-void xmlLoadCatalogs (const char *paths);
-void xmlCatalogCleanup (void);
-void xmlCatalogDump (FILE *out);
-xmlChar * xmlCatalogResolve (const xmlChar *pubID,
- const xmlChar *sysID);
-xmlChar * xmlCatalogResolveSystem (const xmlChar *sysID);
-xmlChar * xmlCatalogResolvePublic (const xmlChar *pubID);
-xmlChar * xmlCatalogResolveURI (const xmlChar *URI);
-int xmlCatalogAdd (const xmlChar *type,
- const xmlChar *orig,
- const xmlChar *replace);
-int xmlCatalogRemove (const xmlChar *value);
-xmlDocPtr xmlParseCatalogFile (const char *filename);
-int xmlCatalogConvert (void);
-
-/*
- * Strictly minimal interfaces for per-document catalogs used
- * by the parser.
- */
-void xmlCatalogFreeLocal (void *catalogs);
-void * xmlCatalogAddLocal (void *catalogs,
- const xmlChar *URL);
-xmlChar * xmlCatalogLocalResolve (void *catalogs,
- const xmlChar *pubID,
- const xmlChar *sysID);
-xmlChar * xmlCatalogLocalResolveURI(void *catalogs,
- const xmlChar *URI);
-/*
- * Preference settings.
- */
-int xmlCatalogSetDebug (int level);
-xmlCatalogPrefer xmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer);
-void xmlCatalogSetDefaults (xmlCatalogAllow allow);
-xmlCatalogAllow xmlCatalogGetDefaults (void);
-
-
-/* DEPRECATED interfaces */
-const xmlChar * xmlCatalogGetSystem (const xmlChar *sysID);
-const xmlChar * xmlCatalogGetPublic (const xmlChar *pubID);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* LIBXML_CATALOG_ENABLED */
-#endif /* __XML_CATALOG_H__ */
diff --git a/bundle/libxml/include/libxml/debugXML.h b/bundle/libxml/include/libxml/debugXML.h
deleted file mode 100644
index cf017a4a73..0000000000
--- a/bundle/libxml/include/libxml/debugXML.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * debugXML.h : Interfaces to a set of routines used for debugging the tree
- * produced by the XML parser.
- *
- * Daniel Veillard <daniel@veillard.com>
- */
-
-#ifndef __DEBUG_XML__
-#define __DEBUG_XML__
-#include <stdio.h>
-#include <libxml/tree.h>
-
-#ifdef LIBXML_DEBUG_ENABLED
-
-#include <libxml/xpath.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * The standard Dump routines.
- */
-void xmlDebugDumpString (FILE *output,
- const xmlChar *str);
-void xmlDebugDumpAttr (FILE *output,
- xmlAttrPtr attr,
- int depth);
-void xmlDebugDumpAttrList (FILE *output,
- xmlAttrPtr attr,
- int depth);
-void xmlDebugDumpOneNode (FILE *output,
- xmlNodePtr node,
- int depth);
-void xmlDebugDumpNode (FILE *output,
- xmlNodePtr node,
- int depth);
-void xmlDebugDumpNodeList (FILE *output,
- xmlNodePtr node,
- int depth);
-void xmlDebugDumpDocumentHead(FILE *output,
- xmlDocPtr doc);
-void xmlDebugDumpDocument (FILE *output,
- xmlDocPtr doc);
-void xmlDebugDumpDTD (FILE *output,
- xmlDtdPtr dtd);
-void xmlDebugDumpEntities (FILE *output,
- xmlDocPtr doc);
-
-void xmlLsOneNode (FILE *output, xmlNodePtr node);
-int xmlLsCountNode (xmlNodePtr node);
-
-LIBXML_DLL_IMPORT const char *xmlBoolToText (int boolval);
-
-/****************************************************************
- * *
- * The XML shell related structures and functions *
- * *
- ****************************************************************/
-
-/**
- * xmlShellReadlineFunc:
- * @prompt: a string prompt
- *
- * This is a generic signature for the XML shell input function.
- *
- * Returns a string which will be freed by the Shell.
- */
-typedef char * (* xmlShellReadlineFunc)(char *prompt);
-
-/**
- * xmlShellCtxt:
- *
- * A debugging shell context.
- * TODO: add the defined function tables.
- */
-typedef struct _xmlShellCtxt xmlShellCtxt;
-typedef xmlShellCtxt *xmlShellCtxtPtr;
-struct _xmlShellCtxt {
- char *filename;
- xmlDocPtr doc;
- xmlNodePtr node;
- xmlXPathContextPtr pctxt;
- int loaded;
- FILE *output;
- xmlShellReadlineFunc input;
-};
-
-/**
- * xmlShellCmd:
- * @ctxt: a shell context
- * @arg: a string argument
- * @node: a first node
- * @node2: a second node
- *
- * This is a generic signature for the XML shell functions.
- *
- * Returns an int, negative returns indicating errors.
- */
-typedef int (* xmlShellCmd) (xmlShellCtxtPtr ctxt,
- char *arg,
- xmlNodePtr node,
- xmlNodePtr node2);
-
-void xmlShellPrintXPathError (int errorType,
- const char *arg);
-void xmlShellPrintNode (xmlNodePtr node);
-void xmlShellPrintXPathResult(xmlXPathObjectPtr list);
-int xmlShellList (xmlShellCtxtPtr ctxt,
- char *arg,
- xmlNodePtr node,
- xmlNodePtr node2);
-int xmlShellBase (xmlShellCtxtPtr ctxt,
- char *arg,
- xmlNodePtr node,
- xmlNodePtr node2);
-int xmlShellDir (xmlShellCtxtPtr ctxt,
- char *arg,
- xmlNodePtr node,
- xmlNodePtr node2);
-int xmlShellCat (xmlShellCtxtPtr ctxt,
- char *arg,
- xmlNodePtr node,
- xmlNodePtr node2);
-int xmlShellLoad (xmlShellCtxtPtr ctxt,
- char *filename,
- xmlNodePtr node,
- xmlNodePtr node2);
-int xmlShellWrite (xmlShellCtxtPtr ctxt,
- char *filename,
- xmlNodePtr node,
- xmlNodePtr node2);
-int xmlShellSave (xmlShellCtxtPtr ctxt,
- char *filename,
- xmlNodePtr node,
- xmlNodePtr node2);
-int xmlShellValidate (xmlShellCtxtPtr ctxt,
- char *dtd,
- xmlNodePtr node,
- xmlNodePtr node2);
-int xmlShellDu (xmlShellCtxtPtr ctxt,
- char *arg,
- xmlNodePtr tree,
- xmlNodePtr node2);
-int xmlShellPwd (xmlShellCtxtPtr ctxt,
- char *buffer,
- xmlNodePtr node,
- xmlNodePtr node2);
-
-/*
- * The Shell interface.
- */
-void xmlShell (xmlDocPtr doc,
- char *filename,
- xmlShellReadlineFunc input,
- FILE *output);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LIBXML_DEBUG_ENABLED */
-#endif /* __DEBUG_XML__ */
diff --git a/bundle/libxml/include/libxml/encoding.h b/bundle/libxml/include/libxml/encoding.h
deleted file mode 100644
index 3c0fbb91ff..0000000000
--- a/bundle/libxml/include/libxml/encoding.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * encoding.h : interface for the encoding conversion functions needed for
- * XML
- *
- * Related specs:
- * rfc2044 (UTF-8 and UTF-16) F. Yergeau Alis Technologies
- * [ISO-10646] UTF-8 and UTF-16 in Annexes
- * [ISO-8859-1] ISO Latin-1 characters codes.
- * [UNICODE] The Unicode Consortium, "The Unicode Standard --
- * Worldwide Character Encoding -- Version 1.0", Addison-
- * Wesley, Volume 1, 1991, Volume 2, 1992. UTF-8 is
- * described in Unicode Technical Report #4.
- * [US-ASCII] Coded Character Set--7-bit American Standard Code for
- * Information Interchange, ANSI X3.4-1986.
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#ifndef __XML_CHAR_ENCODING_H__
-#define __XML_CHAR_ENCODING_H__
-
-#include <libxml/xmlversion.h>
-
-#ifdef LIBXML_ICONV_ENABLED
-#include <iconv.h>
-#endif
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * xmlCharEncoding:
- *
- * Predefined values for some standard encodings.
- * Libxml don't do beforehand translation on UTF8, ISOLatinX.
- * It also support UTF16 (LE and BE) by default.
- *
- * Anything else would have to be translated to UTF8 before being
- * given to the parser itself. The BOM for UTF16 and the encoding
- * declaration are looked at and a converter is looked for at that
- * point. If not found the parser stops here as asked by the XML REC
- * Converter can be registered by the user using xmlRegisterCharEncodingHandler
- * but the current form doesn't allow stateful transcoding (a serious
- * problem agreed !). If iconv has been found it will be used
- * automatically and allow stateful transcoding, the simplest is then
- * to be sure to enable icon and to provide iconv libs for the encoding
- * support needed.
- */
-typedef enum {
- XML_CHAR_ENCODING_ERROR= -1, /* No char encoding detected */
- XML_CHAR_ENCODING_NONE= 0, /* No char encoding detected */
- XML_CHAR_ENCODING_UTF8= 1, /* UTF-8 */
- XML_CHAR_ENCODING_UTF16LE= 2, /* UTF-16 little endian */
- XML_CHAR_ENCODING_UTF16BE= 3, /* UTF-16 big endian */
- XML_CHAR_ENCODING_UCS4LE= 4, /* UCS-4 little endian */
- XML_CHAR_ENCODING_UCS4BE= 5, /* UCS-4 big endian */
- XML_CHAR_ENCODING_EBCDIC= 6, /* EBCDIC uh! */
- XML_CHAR_ENCODING_UCS4_2143=7, /* UCS-4 unusual ordering */
- XML_CHAR_ENCODING_UCS4_3412=8, /* UCS-4 unusual ordering */
- XML_CHAR_ENCODING_UCS2= 9, /* UCS-2 */
- XML_CHAR_ENCODING_8859_1= 10,/* ISO-8859-1 ISO Latin 1 */
- XML_CHAR_ENCODING_8859_2= 11,/* ISO-8859-2 ISO Latin 2 */
- XML_CHAR_ENCODING_8859_3= 12,/* ISO-8859-3 */
- XML_CHAR_ENCODING_8859_4= 13,/* ISO-8859-4 */
- XML_CHAR_ENCODING_8859_5= 14,/* ISO-8859-5 */
- XML_CHAR_ENCODING_8859_6= 15,/* ISO-8859-6 */
- XML_CHAR_ENCODING_8859_7= 16,/* ISO-8859-7 */
- XML_CHAR_ENCODING_8859_8= 17,/* ISO-8859-8 */
- XML_CHAR_ENCODING_8859_9= 18,/* ISO-8859-9 */
- XML_CHAR_ENCODING_2022_JP= 19,/* ISO-2022-JP */
- XML_CHAR_ENCODING_SHIFT_JIS=20,/* Shift_JIS */
- XML_CHAR_ENCODING_EUC_JP= 21,/* EUC-JP */
- XML_CHAR_ENCODING_ASCII= 22 /* pure ASCII */
-} xmlCharEncoding;
-
-/**
- * xmlCharEncodingInputFunc:
- * @out: a pointer to an array of bytes to store the UTF-8 result
- * @outlen: the length of @out
- * @in: a pointer to an array of chars in the original encoding
- * @inlen: the length of @in
- *
- * Take a block of chars in the original encoding and try to convert
- * it to an UTF-8 block of chars out.
- *
- * Returns the number of byte written, or -1 by lack of space, or -2
- * if the transcoding failed.
- * The value of @inlen after return is the number of octets consumed
- * as the return value is positive, else unpredictiable.
- * The value of @outlen after return is the number of octets consumed.
- */
-typedef int (* xmlCharEncodingInputFunc)(unsigned char *out, int *outlen,
- const unsigned char *in, int *inlen);
-
-
-/**
- * xmlCharEncodingOutputFunc:
- * @out: a pointer to an array of bytes to store the result
- * @outlen: the length of @out
- * @in: a pointer to an array of UTF-8 chars
- * @inlen: the length of @in
- *
- * Take a block of UTF-8 chars in and try to convert it to an other
- * encoding.
- * Note: a first call designed to produce heading info is called with
- * in = NULL. If stateful this should also initialize the encoder state.
- *
- * Returns the number of byte written, or -1 by lack of space, or -2
- * if the transcoding failed.
- * The value of @inlen after return is the number of octets consumed
- * as the return value is positive, else unpredictiable.
- * The value of @outlen after return is the number of ocetes consumed.
- */
-typedef int (* xmlCharEncodingOutputFunc)(unsigned char *out, int *outlen,
- const unsigned char *in, int *inlen);
-
-
-/*
- * Block defining the handlers for non UTF-8 encodings.
- * If iconv is supported, there is two extra fields.
- */
-
-typedef struct _xmlCharEncodingHandler xmlCharEncodingHandler;
-typedef xmlCharEncodingHandler *xmlCharEncodingHandlerPtr;
-struct _xmlCharEncodingHandler {
- char *name;
- xmlCharEncodingInputFunc input;
- xmlCharEncodingOutputFunc output;
-#ifdef LIBXML_ICONV_ENABLED
- iconv_t iconv_in;
- iconv_t iconv_out;
-#endif /* LIBXML_ICONV_ENABLED */
-};
-
-#ifdef __cplusplus
-}
-#endif
-#include <libxml/tree.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Interfaces for encoding handlers.
- */
-void xmlInitCharEncodingHandlers (void);
-void xmlCleanupCharEncodingHandlers (void);
-void xmlRegisterCharEncodingHandler (xmlCharEncodingHandlerPtr handler);
-xmlCharEncodingHandlerPtr
- xmlGetCharEncodingHandler (xmlCharEncoding enc);
-xmlCharEncodingHandlerPtr
- xmlFindCharEncodingHandler (const char *name);
-xmlCharEncodingHandlerPtr
- xmlNewCharEncodingHandler (const char *name,
- xmlCharEncodingInputFunc input,
- xmlCharEncodingOutputFunc output);
-
-/*
- * Interfaces for encoding names and aliases.
- */
-int xmlAddEncodingAlias (const char *name,
- const char *alias);
-int xmlDelEncodingAlias (const char *alias);
-const char *
- xmlGetEncodingAlias (const char *alias);
-void xmlCleanupEncodingAliases (void);
-xmlCharEncoding
- xmlParseCharEncoding (const char *name);
-const char *
- xmlGetCharEncodingName (xmlCharEncoding enc);
-
-/*
- * Interfaces directly used by the parsers.
- */
-xmlCharEncoding
- xmlDetectCharEncoding (const unsigned char *in,
- int len);
-
-int xmlCharEncOutFunc (xmlCharEncodingHandler *handler,
- xmlBufferPtr out,
- xmlBufferPtr in);
-
-int xmlCharEncInFunc (xmlCharEncodingHandler *handler,
- xmlBufferPtr out,
- xmlBufferPtr in);
-int xmlCharEncFirstLine (xmlCharEncodingHandler *handler,
- xmlBufferPtr out,
- xmlBufferPtr in);
-int xmlCharEncCloseFunc (xmlCharEncodingHandler *handler);
-
-/*
- * Export a few useful functions
- */
-int UTF8Toisolat1 (unsigned char *out,
- int *outlen,
- const unsigned char *in,
- int *inlen);
-int isolat1ToUTF8 (unsigned char *out,
- int *outlen,
- const unsigned char *in,
- int *inlen);
-int xmlGetUTF8Char (const unsigned char *utf,
- int *len);
-/*
- * exports additional "UTF-8 aware" string routines which are.
- */
-
-int xmlCheckUTF8 (const unsigned char *utf);
-
-int xmlUTF8Strsize (const xmlChar *utf,
- int len);
-xmlChar * xmlUTF8Strndup (const xmlChar *utf,
- int len);
-xmlChar * xmlUTF8Strpos (const xmlChar *utf,
- int pos);
-int xmlUTF8Strloc (const xmlChar *utf,
- const xmlChar *utfchar);
-xmlChar * xmlUTF8Strsub (const xmlChar *utf,
- int start,
- int len);
-
-int xmlUTF8Strlen (const xmlChar *utf);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __XML_CHAR_ENCODING_H__ */
diff --git a/bundle/libxml/include/libxml/entities.h b/bundle/libxml/include/libxml/entities.h
deleted file mode 100644
index 480009c0e3..0000000000
--- a/bundle/libxml/include/libxml/entities.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * entities.h : interface for the XML entities handling
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#ifndef __XML_ENTITIES_H__
-#define __XML_ENTITIES_H__
-
-#include <libxml/tree.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * The different valid entity types.
- */
-typedef enum {
- XML_INTERNAL_GENERAL_ENTITY = 1,
- XML_EXTERNAL_GENERAL_PARSED_ENTITY = 2,
- XML_EXTERNAL_GENERAL_UNPARSED_ENTITY = 3,
- XML_INTERNAL_PARAMETER_ENTITY = 4,
- XML_EXTERNAL_PARAMETER_ENTITY = 5,
- XML_INTERNAL_PREDEFINED_ENTITY = 6
-} xmlEntityType;
-
-/*
- * An unit of storage for an entity, contains the string, the value
- * and the linkind data needed for the linking in the hash table.
- */
-
-struct _xmlEntity {
- void *_private; /* application data */
- xmlElementType type; /* XML_ENTITY_DECL, must be second ! */
- const xmlChar *name; /* Entity name */
- struct _xmlNode *children; /* First child link */
- struct _xmlNode *last; /* Last child link */
- struct _xmlDtd *parent; /* -> DTD */
- struct _xmlNode *next; /* next sibling link */
- struct _xmlNode *prev; /* previous sibling link */
- struct _xmlDoc *doc; /* the containing document */
-
- xmlChar *orig; /* content without ref substitution */
- xmlChar *content; /* content or ndata if unparsed */
- int length; /* the content length */
- xmlEntityType etype; /* The entity type */
- const xmlChar *ExternalID; /* External identifier for PUBLIC */
- const xmlChar *SystemID; /* URI for a SYSTEM or PUBLIC Entity */
-
- struct _xmlEntity *nexte; /* unused */
- const xmlChar *URI; /* the full URI as computed */
-};
-
-/*
- * All entities are stored in an hash table.
- * There is 2 separate hash tables for global and parameter entities.
- */
-
-typedef struct _xmlHashTable xmlEntitiesTable;
-typedef xmlEntitiesTable *xmlEntitiesTablePtr;
-
-/*
- * External functions:
- */
-
-void xmlInitializePredefinedEntities (void);
-xmlEntityPtr xmlAddDocEntity (xmlDocPtr doc,
- const xmlChar *name,
- int type,
- const xmlChar *ExternalID,
- const xmlChar *SystemID,
- const xmlChar *content);
-xmlEntityPtr xmlAddDtdEntity (xmlDocPtr doc,
- const xmlChar *name,
- int type,
- const xmlChar *ExternalID,
- const xmlChar *SystemID,
- const xmlChar *content);
-xmlEntityPtr xmlGetPredefinedEntity (const xmlChar *name);
-xmlEntityPtr xmlGetDocEntity (xmlDocPtr doc,
- const xmlChar *name);
-xmlEntityPtr xmlGetDtdEntity (xmlDocPtr doc,
- const xmlChar *name);
-xmlEntityPtr xmlGetParameterEntity (xmlDocPtr doc,
- const xmlChar *name);
-const xmlChar * xmlEncodeEntities (xmlDocPtr doc,
- const xmlChar *input);
-xmlChar * xmlEncodeEntitiesReentrant(xmlDocPtr doc,
- const xmlChar *input);
-xmlChar * xmlEncodeSpecialChars (xmlDocPtr doc,
- const xmlChar *input);
-xmlEntitiesTablePtr xmlCreateEntitiesTable (void);
-xmlEntitiesTablePtr xmlCopyEntitiesTable (xmlEntitiesTablePtr table);
-void xmlFreeEntitiesTable (xmlEntitiesTablePtr table);
-void xmlDumpEntitiesTable (xmlBufferPtr buf,
- xmlEntitiesTablePtr table);
-void xmlDumpEntityDecl (xmlBufferPtr buf,
- xmlEntityPtr ent);
-void xmlCleanupPredefinedEntities(void);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-# endif /* __XML_ENTITIES_H__ */
diff --git a/bundle/libxml/include/libxml/globals.h b/bundle/libxml/include/libxml/globals.h
deleted file mode 100644
index fc6c01e53c..0000000000
--- a/bundle/libxml/include/libxml/globals.h
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * globals.h: interface for all global variables of the library
- *
- * The bottom of this file is automatically generated by build_glob.py
- * based on the description file global.data
- *
- * See Copyright for the status of this software.
- *
- * Gary Pennington <Gary.Pennington@uk.sun.com>
- * daniel@veillard.com
- */
-
-#ifndef __XML_GLOBALS_H
-#define __XML_GLOBALS_H
-
-#include <libxml/parser.h>
-#include <libxml/xmlerror.h>
-#include <libxml/SAX.h>
-#include <libxml/xmlmemory.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Externally global symbols which need to be protected for backwards
- * compatibility support.
- */
-
-#undef docbDefaultSAXHandler
-#undef htmlDefaultSAXHandler
-#undef oldXMLWDcompatibility
-#undef xmlBufferAllocScheme
-#undef xmlDefaultBufferSize
-#undef xmlDefaultSAXHandler
-#undef xmlDefaultSAXLocator
-#undef xmlDoValidityCheckingDefaultValue
-#undef xmlFree
-#undef xmlGenericError
-#undef xmlGenericErrorContext
-#undef xmlGetWarningsDefaultValue
-#undef xmlIndentTreeOutput
-#undef xmlTreeIndentString
-#undef xmlKeepBlanksDefaultValue
-#undef xmlLineNumbersDefaultValue
-#undef xmlLoadExtDtdDefaultValue
-#undef xmlMalloc
-#undef xmlMemStrdup
-#undef xmlParserDebugEntities
-#undef xmlParserVersion
-#undef xmlPedanticParserDefaultValue
-#undef xmlRealloc
-#undef xmlSaveNoEmptyTags
-#undef xmlSubstituteEntitiesDefaultValue
-
-typedef struct _xmlGlobalState xmlGlobalState;
-typedef xmlGlobalState *xmlGlobalStatePtr;
-struct _xmlGlobalState
-{
- const char *xmlParserVersion;
-
- xmlSAXLocator xmlDefaultSAXLocator;
- xmlSAXHandler xmlDefaultSAXHandler;
- xmlSAXHandler docbDefaultSAXHandler;
- xmlSAXHandler htmlDefaultSAXHandler;
-
- xmlFreeFunc xmlFree;
- xmlMallocFunc xmlMalloc;
- xmlStrdupFunc xmlMemStrdup;
- xmlReallocFunc xmlRealloc;
-
- xmlGenericErrorFunc xmlGenericError;
- void *xmlGenericErrorContext;
-
- int oldXMLWDcompatibility;
-
- xmlBufferAllocationScheme xmlBufferAllocScheme;
- int xmlDefaultBufferSize;
-
- int xmlSubstituteEntitiesDefaultValue;
- int xmlDoValidityCheckingDefaultValue;
- int xmlGetWarningsDefaultValue;
- int xmlKeepBlanksDefaultValue;
- int xmlLineNumbersDefaultValue;
- int xmlLoadExtDtdDefaultValue;
- int xmlParserDebugEntities;
- int xmlPedanticParserDefaultValue;
-
- int xmlSaveNoEmptyTags;
- int xmlIndentTreeOutput;
- const char *xmlTreeIndentString;
-};
-
-#ifdef __cplusplus
-}
-#endif
-#include <libxml/threads.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void xmlInitializeGlobalState(xmlGlobalStatePtr gs);
-
-/*
- * In general the memory allocation entry points are not kept
- * thread specific but this can be overridden by LIBXML_THREAD_ALLOC_ENABLED
- * - xmlMalloc
- * - xmlRealloc
- * - xmlMemStrdup
- * - xmlFree
- */
-
-#ifdef LIBXML_THREAD_ALLOC_ENABLED
-#ifdef LIBXML_THREAD_ENABLED
-extern xmlMallocFunc *__xmlMalloc(void);
-#define xmlMalloc \
-(*(__xmlMalloc()))
-#else
-LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMalloc;
-#endif
-
-#ifdef LIBXML_THREAD_ENABLED
-extern xmlReallocFunc *__xmlRealloc(void);
-#define xmlRealloc \
-(*(__xmlRealloc()))
-#else
-LIBXML_DLL_IMPORT extern xmlReallocFunc xmlRealloc;
-#endif
-
-#ifdef LIBXML_THREAD_ENABLED
-extern xmlFreeFunc *__xmlFree(void);
-#define xmlFree \
-(*(__xmlFree()))
-#else
-LIBXML_DLL_IMPORT extern xmlFreeFunc xmlFree;
-#endif
-
-#ifdef LIBXML_THREAD_ENABLED
-extern xmlStrdupFunc *__xmlMemStrdup(void);
-#define xmlMemStrdup \
-(*(__xmlMemStrdup()))
-#else
-LIBXML_DLL_IMPORT extern xmlStrdupFunc xmlMemStrdup;
-#endif
-#else /* !LIBXML_THREAD_ALLOC_ENABLED */
-LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMalloc;
-LIBXML_DLL_IMPORT extern xmlReallocFunc xmlRealloc;
-LIBXML_DLL_IMPORT extern xmlFreeFunc xmlFree;
-LIBXML_DLL_IMPORT extern xmlStrdupFunc xmlMemStrdup;
-#endif /* LIBXML_THREAD_ALLOC_ENABLED */
-
-#ifdef LIBXML_DOCB_ENABLED
-extern xmlSAXHandler *__docbDefaultSAXHandler(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define docbDefaultSAXHandler \
-(*(__docbDefaultSAXHandler()))
-#else
-LIBXML_DLL_IMPORT extern xmlSAXHandler docbDefaultSAXHandler;
-#endif
-#endif
-
-#ifdef LIBXML_HTML_ENABLED
-extern xmlSAXHandler *__htmlDefaultSAXHandler(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define htmlDefaultSAXHandler \
-(*(__htmlDefaultSAXHandler()))
-#else
-LIBXML_DLL_IMPORT extern xmlSAXHandler htmlDefaultSAXHandler;
-#endif
-#endif
-
-
-/*
- * Everything starting from the line below is
- * Automatically generated by build_glob.py.
- * Do not modify the previous line.
- */
-
-
-extern int *__oldXMLWDcompatibility(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define oldXMLWDcompatibility \
-(*(__oldXMLWDcompatibility()))
-#else
-LIBXML_DLL_IMPORT extern int oldXMLWDcompatibility;
-#endif
-
-extern xmlBufferAllocationScheme *__xmlBufferAllocScheme(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlBufferAllocScheme \
-(*(__xmlBufferAllocScheme()))
-#else
-LIBXML_DLL_IMPORT extern xmlBufferAllocationScheme xmlBufferAllocScheme;
-#endif
-
-extern int *__xmlDefaultBufferSize(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlDefaultBufferSize \
-(*(__xmlDefaultBufferSize()))
-#else
-LIBXML_DLL_IMPORT extern int xmlDefaultBufferSize;
-#endif
-
-extern xmlSAXHandler *__xmlDefaultSAXHandler(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlDefaultSAXHandler \
-(*(__xmlDefaultSAXHandler()))
-#else
-LIBXML_DLL_IMPORT extern xmlSAXHandler xmlDefaultSAXHandler;
-#endif
-
-extern xmlSAXLocator *__xmlDefaultSAXLocator(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlDefaultSAXLocator \
-(*(__xmlDefaultSAXLocator()))
-#else
-LIBXML_DLL_IMPORT extern xmlSAXLocator xmlDefaultSAXLocator;
-#endif
-
-extern int *__xmlDoValidityCheckingDefaultValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlDoValidityCheckingDefaultValue \
-(*(__xmlDoValidityCheckingDefaultValue()))
-#else
-LIBXML_DLL_IMPORT extern int xmlDoValidityCheckingDefaultValue;
-#endif
-
-extern xmlGenericErrorFunc *__xmlGenericError(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlGenericError \
-(*(__xmlGenericError()))
-#else
-LIBXML_DLL_IMPORT extern xmlGenericErrorFunc xmlGenericError;
-#endif
-
-extern void * *__xmlGenericErrorContext(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlGenericErrorContext \
-(*(__xmlGenericErrorContext()))
-#else
-LIBXML_DLL_IMPORT extern void * xmlGenericErrorContext;
-#endif
-
-extern int *__xmlGetWarningsDefaultValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlGetWarningsDefaultValue \
-(*(__xmlGetWarningsDefaultValue()))
-#else
-LIBXML_DLL_IMPORT extern int xmlGetWarningsDefaultValue;
-#endif
-
-extern int *__xmlIndentTreeOutput(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlIndentTreeOutput \
-(*(__xmlIndentTreeOutput()))
-#else
-LIBXML_DLL_IMPORT extern int xmlIndentTreeOutput;
-#endif
-
-extern const char * *__xmlTreeIndentString(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlTreeIndentString \
-(*(__xmlTreeIndentString()))
-#else
-LIBXML_DLL_IMPORT extern const char * xmlTreeIndentString;
-#endif
-
-extern int *__xmlKeepBlanksDefaultValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlKeepBlanksDefaultValue \
-(*(__xmlKeepBlanksDefaultValue()))
-#else
-LIBXML_DLL_IMPORT extern int xmlKeepBlanksDefaultValue;
-#endif
-
-extern int *__xmlLineNumbersDefaultValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlLineNumbersDefaultValue \
-(*(__xmlLineNumbersDefaultValue()))
-#else
-LIBXML_DLL_IMPORT extern int xmlLineNumbersDefaultValue;
-#endif
-
-extern int *__xmlLoadExtDtdDefaultValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlLoadExtDtdDefaultValue \
-(*(__xmlLoadExtDtdDefaultValue()))
-#else
-LIBXML_DLL_IMPORT extern int xmlLoadExtDtdDefaultValue;
-#endif
-
-extern int *__xmlParserDebugEntities(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlParserDebugEntities \
-(*(__xmlParserDebugEntities()))
-#else
-LIBXML_DLL_IMPORT extern int xmlParserDebugEntities;
-#endif
-
-extern const char * *__xmlParserVersion(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlParserVersion \
-(*(__xmlParserVersion()))
-#else
-LIBXML_DLL_IMPORT extern const char * xmlParserVersion;
-#endif
-
-extern int *__xmlPedanticParserDefaultValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlPedanticParserDefaultValue \
-(*(__xmlPedanticParserDefaultValue()))
-#else
-LIBXML_DLL_IMPORT extern int xmlPedanticParserDefaultValue;
-#endif
-
-extern int *__xmlSaveNoEmptyTags(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlSaveNoEmptyTags \
-(*(__xmlSaveNoEmptyTags()))
-#else
-LIBXML_DLL_IMPORT extern int xmlSaveNoEmptyTags;
-#endif
-
-extern int *__xmlSubstituteEntitiesDefaultValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlSubstituteEntitiesDefaultValue \
-(*(__xmlSubstituteEntitiesDefaultValue()))
-#else
-LIBXML_DLL_IMPORT extern int xmlSubstituteEntitiesDefaultValue;
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __XML_GLOBALS_H */
diff --git a/bundle/libxml/include/libxml/hash.h b/bundle/libxml/include/libxml/hash.h
deleted file mode 100644
index ec590c91fe..0000000000
--- a/bundle/libxml/include/libxml/hash.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * hash.h: chained hash tables
- *
- * Copyright (C) 2000 Bjorn Reese and Daniel Veillard.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- * Author: bjorn.reese@systematic.dk
- */
-
-#ifndef __XML_HASH_H__
-#define __XML_HASH_H__
-
-#include <libxml/parser.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * The hash table.
- */
-typedef struct _xmlHashTable xmlHashTable;
-typedef xmlHashTable *xmlHashTablePtr;
-
-/*
- * function types:
- */
-/**
- * xmlHashDeallocator:
- * @payload: the data in the hash
- * @name: the name associated
- *
- * Callback to free data from a hash.
- */
-typedef void (*xmlHashDeallocator)(void *payload, xmlChar *name);
-/**
- * xmlHashCopier:
- * @payload: the data in the hash
- * @name: the name associated
- *
- * Callback to copy data from a hash.
- *
- * Returns a copy of the data or NULL in case of error.
- */
-typedef void *(*xmlHashCopier)(void *payload, xmlChar *name);
-/**
- * xmlHashScanner:
- * @payload: the data in the hash
- * @data: extra scannner data
- * @name: the name associated
- *
- * Callback when scanning data in a hash with the simple scanner.
- */
-typedef void (*xmlHashScanner)(void *payload, void *data, xmlChar *name);
-/**
- * xmlHashScannerFull:
- * @payload: the data in the hash
- * @data: extra scannner data
- * @name: the name associated
- * @name2: the second name associated
- * @name3: the third name associated
- *
- * Callback when scanning data in a hash with the full scanner.
- */
-typedef void (*xmlHashScannerFull)(void *payload, void *data,
- const xmlChar *name, const xmlChar *name2,
- const xmlChar *name3);
-
-/*
- * Constructor and destructor.
- */
-xmlHashTablePtr xmlHashCreate (int size);
-void xmlHashFree (xmlHashTablePtr table,
- xmlHashDeallocator f);
-
-/*
- * Add a new entry to the hash table.
- */
-int xmlHashAddEntry (xmlHashTablePtr table,
- const xmlChar *name,
- void *userdata);
-int xmlHashUpdateEntry(xmlHashTablePtr table,
- const xmlChar *name,
- void *userdata,
- xmlHashDeallocator f);
-int xmlHashAddEntry2(xmlHashTablePtr table,
- const xmlChar *name,
- const xmlChar *name2,
- void *userdata);
-int xmlHashUpdateEntry2(xmlHashTablePtr table,
- const xmlChar *name,
- const xmlChar *name2,
- void *userdata,
- xmlHashDeallocator f);
-int xmlHashAddEntry3(xmlHashTablePtr table,
- const xmlChar *name,
- const xmlChar *name2,
- const xmlChar *name3,
- void *userdata);
-int xmlHashUpdateEntry3(xmlHashTablePtr table,
- const xmlChar *name,
- const xmlChar *name2,
- const xmlChar *name3,
- void *userdata,
- xmlHashDeallocator f);
-
-/*
- * Remove an entry from the hash table.
- */
-int xmlHashRemoveEntry(xmlHashTablePtr table, const xmlChar *name,
- xmlHashDeallocator f);
-int xmlHashRemoveEntry2(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, xmlHashDeallocator f);
-int xmlHashRemoveEntry3(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, const xmlChar *name3,
- xmlHashDeallocator f);
-
-/*
- * Retrieve the userdata.
- */
-void * xmlHashLookup (xmlHashTablePtr table,
- const xmlChar *name);
-void * xmlHashLookup2 (xmlHashTablePtr table,
- const xmlChar *name,
- const xmlChar *name2);
-void * xmlHashLookup3 (xmlHashTablePtr table,
- const xmlChar *name,
- const xmlChar *name2,
- const xmlChar *name3);
-
-/*
- * Helpers.
- */
-xmlHashTablePtr xmlHashCopy (xmlHashTablePtr table,
- xmlHashCopier f);
-int xmlHashSize (xmlHashTablePtr table);
-void xmlHashScan (xmlHashTablePtr table,
- xmlHashScanner f,
- void *data);
-void xmlHashScan3 (xmlHashTablePtr table,
- const xmlChar *name,
- const xmlChar *name2,
- const xmlChar *name3,
- xmlHashScanner f,
- void *data);
-void xmlHashScanFull (xmlHashTablePtr table,
- xmlHashScannerFull f,
- void *data);
-void xmlHashScanFull3(xmlHashTablePtr table,
- const xmlChar *name,
- const xmlChar *name2,
- const xmlChar *name3,
- xmlHashScannerFull f,
- void *data);
-#ifdef __cplusplus
-}
-#endif
-#endif /* ! __XML_HASH_H__ */
diff --git a/bundle/libxml/include/libxml/list.h b/bundle/libxml/include/libxml/list.h
deleted file mode 100644
index 8c9515fe1d..0000000000
--- a/bundle/libxml/include/libxml/list.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * list.h: lists interfaces
- *
- * Copyright (C) 2000 Gary Pennington and Daniel Veillard.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- * Author: Gary.Pennington@uk.sun.com
- */
-
-#ifndef __XML_LINK_INCLUDE__
-#define __XML_LINK_INCLUDE__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct _xmlLink xmlLink;
-typedef xmlLink *xmlLinkPtr;
-
-typedef struct _xmlList xmlList;
-typedef xmlList *xmlListPtr;
-
-/**
- * xmlListDeallocator:
- * @lk: the data to deallocate
- *
- * Callback function used to free data from a list.
- */
-typedef void (*xmlListDeallocator) (xmlLinkPtr lk);
-/**
- * xmlListDataCompare:
- * @data0: the first data
- * @data1: the second data
- *
- * Callback function used to compare 2 data.
- *
- * Returns 0 is equality, -1 or 1 otherwise depending on the ordering.
- */
-typedef int (*xmlListDataCompare) (const void *data0, const void *data1);
-/**
- * xmlListWalker:
- * @data: the data found in the list
- * @user: extra user provided data to the walker
- *
- * Callback function used when walking a list with xmlListWalk().
- *
- * Returns 0 to stop walking the list, 1 otherwise.
- */
-typedef int (*xmlListWalker) (const void *data, const void *user);
-
-/* Creation/Deletion */
-xmlListPtr xmlListCreate (xmlListDeallocator deallocator,
- xmlListDataCompare compare);
-void xmlListDelete (xmlListPtr l);
-
-/* Basic Operators */
-void * xmlListSearch (xmlListPtr l,
- void *data);
-void * xmlListReverseSearch (xmlListPtr l,
- void *data);
-int xmlListInsert (xmlListPtr l,
- void *data) ;
-int xmlListAppend (xmlListPtr l,
- void *data) ;
-int xmlListRemoveFirst (xmlListPtr l,
- void *data);
-int xmlListRemoveLast (xmlListPtr l,
- void *data);
-int xmlListRemoveAll (xmlListPtr l,
- void *data);
-void xmlListClear (xmlListPtr l);
-int xmlListEmpty (xmlListPtr l);
-xmlLinkPtr xmlListFront (xmlListPtr l);
-xmlLinkPtr xmlListEnd (xmlListPtr l);
-int xmlListSize (xmlListPtr l);
-
-void xmlListPopFront (xmlListPtr l);
-void xmlListPopBack (xmlListPtr l);
-int xmlListPushFront (xmlListPtr l,
- void *data);
-int xmlListPushBack (xmlListPtr l,
- void *data);
-
-/* Advanced Operators */
-void xmlListReverse (xmlListPtr l);
-void xmlListSort (xmlListPtr l);
-void xmlListWalk (xmlListPtr l,
- xmlListWalker walker,
- const void *user);
-void xmlListReverseWalk (xmlListPtr l,
- xmlListWalker walker,
- const void *user);
-void xmlListMerge (xmlListPtr l1,
- xmlListPtr l2);
-xmlListPtr xmlListDup (const xmlListPtr old);
-int xmlListCopy (xmlListPtr cur,
- const xmlListPtr old);
-/* Link operators */
-void * xmlLinkGetData (xmlLinkPtr lk);
-
-/* xmlListUnique() */
-/* xmlListSwap */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __XML_LINK_INCLUDE__ */
diff --git a/bundle/libxml/include/libxml/nanoftp.h b/bundle/libxml/include/libxml/nanoftp.h
deleted file mode 100644
index a0ba2ceeb3..0000000000
--- a/bundle/libxml/include/libxml/nanoftp.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * nanohttp.c: minimalist FTP implementation to fetch external subsets.
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#ifndef __NANO_FTP_H__
-#define __NANO_FTP_H__
-
-#include <libxml/xmlversion.h>
-
-#ifdef LIBXML_FTP_ENABLED
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * ftpListCallback:
- * @userData: user provided data for the callback
- * @filename: the file name (including "->" when links are shown)
- * @attrib: the attribute string
- * @owner: the owner string
- * @group: the group string
- * @size: the file size
- * @links: the link count
- * @year: the year
- * @month: the month
- * @day: the day
- * @hour: the hour
- * @minute: the minute
- *
- * A callback for the xmlNanoFTPList command.
- * Note that only one of year and day:minute are specified.
- */
-typedef void (*ftpListCallback) (void *userData,
- const char *filename, const char *attrib,
- const char *owner, const char *group,
- unsigned long size, int links, int year,
- const char *month, int day, int hour,
- int minute);
-/**
- * ftpDataCallback:
- * @userData: the user provided context
- * @data: the data received
- * @len: its size in bytes
- *
- * A callback for the xmlNanoFTPGet command.
- */
-typedef void (*ftpDataCallback) (void *userData,
- const char *data,
- int len);
-
-/*
- * Init
- */
-void xmlNanoFTPInit (void);
-void xmlNanoFTPCleanup (void);
-
-/*
- * Creating/freeing contexts.
- */
-void * xmlNanoFTPNewCtxt (const char *URL);
-void xmlNanoFTPFreeCtxt (void * ctx);
-void * xmlNanoFTPConnectTo (const char *server,
- int port);
-/*
- * Opening/closing session connections.
- */
-void * xmlNanoFTPOpen (const char *URL);
-int xmlNanoFTPConnect (void *ctx);
-int xmlNanoFTPClose (void *ctx);
-int xmlNanoFTPQuit (void *ctx);
-void xmlNanoFTPScanProxy (const char *URL);
-void xmlNanoFTPProxy (const char *host,
- int port,
- const char *user,
- const char *passwd,
- int type);
-int xmlNanoFTPUpdateURL (void *ctx,
- const char *URL);
-
-/*
- * Rather internal commands.
- */
-int xmlNanoFTPGetResponse (void *ctx);
-int xmlNanoFTPCheckResponse (void *ctx);
-
-/*
- * CD/DIR/GET handlers.
- */
-int xmlNanoFTPCwd (void *ctx,
- char *directory);
-
-int xmlNanoFTPGetConnection (void *ctx);
-int xmlNanoFTPCloseConnection(void *ctx);
-int xmlNanoFTPList (void *ctx,
- ftpListCallback callback,
- void *userData,
- char *filename);
-int xmlNanoFTPGetSocket (void *ctx,
- const char *filename);
-int xmlNanoFTPGet (void *ctx,
- ftpDataCallback callback,
- void *userData,
- const char *filename);
-int xmlNanoFTPRead (void *ctx,
- void *dest,
- int len);
-
-#ifdef __cplusplus
-}
-#endif /* LIBXML_FTP_ENABLED */
-#endif
-#endif /* __NANO_FTP_H__ */
diff --git a/bundle/libxml/include/libxml/nanohttp.h b/bundle/libxml/include/libxml/nanohttp.h
deleted file mode 100644
index 4fb4e1d256..0000000000
--- a/bundle/libxml/include/libxml/nanohttp.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * nanohttp.c: minimalist HTTP implementation to fetch external subsets.
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#ifndef __NANO_HTTP_H__
-#define __NANO_HTTP_H__
-
-#include <libxml/xmlversion.h>
-
-#ifdef LIBXML_HTTP_ENABLED
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-void xmlNanoHTTPInit (void);
-void xmlNanoHTTPCleanup (void);
-void xmlNanoHTTPScanProxy (const char *URL);
-int xmlNanoHTTPFetch (const char *URL,
- const char *filename,
- char **contentType);
-void * xmlNanoHTTPMethod (const char *URL,
- const char *method,
- const char *input,
- char **contentType,
- const char *headers,
- int ilen);
-void * xmlNanoHTTPMethodRedir (const char *URL,
- const char *method,
- const char *input,
- char **contentType,
- char **redir,
- const char *headers,
- int ilen);
-void * xmlNanoHTTPOpen (const char *URL,
- char **contentType);
-void * xmlNanoHTTPOpenRedir (const char *URL,
- char **contentType,
- char **redir);
-int xmlNanoHTTPReturnCode (void *ctx);
-const char * xmlNanoHTTPAuthHeader(void *ctx);
-int xmlNanoHTTPRead (void *ctx,
- void *dest,
- int len);
-int xmlNanoHTTPSave (void *ctxt,
- const char *filename);
-void xmlNanoHTTPClose (void *ctx);
-#ifdef __cplusplus
-}
-
-#endif /* LIBXML_HTTP_ENABLED */
-#endif
-#endif /* __NANO_HTTP_H__ */
diff --git a/bundle/libxml/include/libxml/parser.h b/bundle/libxml/include/libxml/parser.h
deleted file mode 100644
index e6725a364d..0000000000
--- a/bundle/libxml/include/libxml/parser.h
+++ /dev/null
@@ -1,869 +0,0 @@
-/*
- * parser.h : Interfaces, constants and types related to the XML parser.
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#ifndef __XML_PARSER_H__
-#define __XML_PARSER_H__
-
-#include <libxml/tree.h>
-#include <libxml/valid.h>
-#include <libxml/entities.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * XML_DEFAULT_VERSION:
- *
- * The default version of XML used: 1.0
- */
-#define XML_DEFAULT_VERSION "1.0"
-
-/**
- * xmlParserInput:
- *
- * An xmlParserInput is an input flow for the XML processor.
- * Each entity parsed is associated an xmlParserInput (except the
- * few predefined ones). This is the case both for internal entities
- * - in which case the flow is already completely in memory - or
- * external entities - in which case we use the buf structure for
- * progressive reading and I18N conversions to the internal UTF-8 format.
- */
-
-/**
- * xmlParserInputDeallocate:
- * @str: the string to deallocate
- *
- * Callback for freeing some parser input allocations.
- */
-typedef void (* xmlParserInputDeallocate)(xmlChar *str);
-
-struct _xmlParserInput {
- /* Input buffer */
- xmlParserInputBufferPtr buf; /* UTF-8 encoded buffer */
-
- const char *filename; /* The file analyzed, if any */
- const char *directory; /* the directory/base of the file */
- const xmlChar *base; /* Base of the array to parse */
- const xmlChar *cur; /* Current char being parsed */
- const xmlChar *end; /* end of the array to parse */
- int length; /* length if known */
- int line; /* Current line */
- int col; /* Current column */
- int consumed; /* How many xmlChars already consumed */
- xmlParserInputDeallocate free; /* function to deallocate the base */
- const xmlChar *encoding; /* the encoding string for entity */
- const xmlChar *version; /* the version string for entity */
- int standalone; /* Was that entity marked standalone */
-};
-
-/**
- * xmlParserNodeInfo:
- *
- * The parser can be asked to collect Node informations, i.e. at what
- * place in the file they were detected.
- * NOTE: This is off by default and not very well tested.
- */
-typedef struct _xmlParserNodeInfo xmlParserNodeInfo;
-typedef xmlParserNodeInfo *xmlParserNodeInfoPtr;
-
-struct _xmlParserNodeInfo {
- const struct _xmlNode* node;
- /* Position & line # that text that created the node begins & ends on */
- unsigned long begin_pos;
- unsigned long begin_line;
- unsigned long end_pos;
- unsigned long end_line;
-};
-
-typedef struct _xmlParserNodeInfoSeq xmlParserNodeInfoSeq;
-typedef xmlParserNodeInfoSeq *xmlParserNodeInfoSeqPtr;
-struct _xmlParserNodeInfoSeq {
- unsigned long maximum;
- unsigned long length;
- xmlParserNodeInfo* buffer;
-};
-
-/**
- * xmlParserInputState:
- *
- * The parser is now working also as a state based parser.
- * The recursive one use the state info for entities processing.
- */
-typedef enum {
- XML_PARSER_EOF = -1, /* nothing is to be parsed */
- XML_PARSER_START = 0, /* nothing has been parsed */
- XML_PARSER_MISC, /* Misc* before int subset */
- XML_PARSER_PI, /* Within a processing instruction */
- XML_PARSER_DTD, /* within some DTD content */
- XML_PARSER_PROLOG, /* Misc* after internal subset */
- XML_PARSER_COMMENT, /* within a comment */
- XML_PARSER_START_TAG, /* within a start tag */
- XML_PARSER_CONTENT, /* within the content */
- XML_PARSER_CDATA_SECTION, /* within a CDATA section */
- XML_PARSER_END_TAG, /* within a closing tag */
- XML_PARSER_ENTITY_DECL, /* within an entity declaration */
- XML_PARSER_ENTITY_VALUE, /* within an entity value in a decl */
- XML_PARSER_ATTRIBUTE_VALUE, /* within an attribute value */
- XML_PARSER_SYSTEM_LITERAL, /* within a SYSTEM value */
- XML_PARSER_EPILOG, /* the Misc* after the last end tag */
- XML_PARSER_IGNORE, /* within an IGNORED section */
- XML_PARSER_PUBLIC_LITERAL /* within a PUBLIC value */
-} xmlParserInputState;
-
-/**
- * XML_DETECT_IDS:
- *
- * Bit in the loadsubset context field to tell to do ID/REFs lookups.
- * Use it to initialize xmlLoadExtDtdDefaultValue.
- */
-#define XML_DETECT_IDS 2
-
-/**
- * XML_COMPLETE_ATTRS:
- *
- * Bit in the loadsubset context field to tell to do complete the
- * elements attributes lists with the ones defaulted from the DTDs.
- * Use it to initialize xmlLoadExtDtdDefaultValue.
- */
-#define XML_COMPLETE_ATTRS 4
-
-/**
- * xmlParserCtxt:
- *
- * The parser context.
- * NOTE This doesn't completely define the parser state, the (current ?)
- * design of the parser uses recursive function calls since this allow
- * and easy mapping from the production rules of the specification
- * to the actual code. The drawback is that the actual function call
- * also reflect the parser state. However most of the parsing routines
- * takes as the only argument the parser context pointer, so migrating
- * to a state based parser for progressive parsing shouldn't be too hard.
- */
-struct _xmlParserCtxt {
- struct _xmlSAXHandler *sax; /* The SAX handler */
- void *userData; /* For SAX interface only, used by DOM build */
- xmlDocPtr myDoc; /* the document being built */
- int wellFormed; /* is the document well formed */
- int replaceEntities; /* shall we replace entities ? */
- const xmlChar *version; /* the XML version string */
- const xmlChar *encoding; /* the declared encoding, if any */
- int standalone; /* standalone document */
- int html; /* an HTML(1)/Docbook(2) document */
-
- /* Input stream stack */
- xmlParserInputPtr input; /* Current input stream */
- int inputNr; /* Number of current input streams */
- int inputMax; /* Max number of input streams */
- xmlParserInputPtr *inputTab; /* stack of inputs */
-
- /* Node analysis stack only used for DOM building */
- xmlNodePtr node; /* Current parsed Node */
- int nodeNr; /* Depth of the parsing stack */
- int nodeMax; /* Max depth of the parsing stack */
- xmlNodePtr *nodeTab; /* array of nodes */
-
- int record_info; /* Whether node info should be kept */
- xmlParserNodeInfoSeq node_seq; /* info about each node parsed */
-
- int errNo; /* error code */
-
- int hasExternalSubset; /* reference and external subset */
- int hasPErefs; /* the internal subset has PE refs */
- int external; /* are we parsing an external entity */
-
- int valid; /* is the document valid */
- int validate; /* shall we try to validate ? */
- xmlValidCtxt vctxt; /* The validity context */
-
- xmlParserInputState instate; /* current type of input */
- int token; /* next char look-ahead */
-
- char *directory; /* the data directory */
-
- /* Node name stack */
- xmlChar *name; /* Current parsed Node */
- int nameNr; /* Depth of the parsing stack */
- int nameMax; /* Max depth of the parsing stack */
- xmlChar * *nameTab; /* array of nodes */
-
- long nbChars; /* number of xmlChar processed */
- long checkIndex; /* used by progressive parsing lookup */
- int keepBlanks; /* ugly but ... */
- int disableSAX; /* SAX callbacks are disabled */
- int inSubset; /* Parsing is in int 1/ext 2 subset */
- xmlChar * intSubName; /* name of subset */
- xmlChar * extSubURI; /* URI of external subset */
- xmlChar * extSubSystem; /* SYSTEM ID of external subset */
-
- /* xml:space values */
- int * space; /* Should the parser preserve spaces */
- int spaceNr; /* Depth of the parsing stack */
- int spaceMax; /* Max depth of the parsing stack */
- int * spaceTab; /* array of space infos */
-
- int depth; /* to prevent entity substitution loops */
- xmlParserInputPtr entity; /* used to check entities boundaries */
- int charset; /* encoding of the in-memory content
- actually an xmlCharEncoding */
- int nodelen; /* Those two fields are there to */
- int nodemem; /* Speed up large node parsing */
- int pedantic; /* signal pedantic warnings */
- void *_private; /* For user data, libxml won't touch it */
-
- int loadsubset; /* should the external subset be loaded */
- int linenumbers; /* set line number in element content */
- void *catalogs; /* document's own catalog */
- int recovery; /* run in recovery mode */
-};
-
-/**
- * xmlSAXLocator:
- *
- * A SAX Locator.
- */
-struct _xmlSAXLocator {
- const xmlChar *(*getPublicId)(void *ctx);
- const xmlChar *(*getSystemId)(void *ctx);
- int (*getLineNumber)(void *ctx);
- int (*getColumnNumber)(void *ctx);
-};
-
-/**
- * xmlSAXHandler:
- *
- * A SAX handler is bunch of callbacks called by the parser when processing
- * of the input generate data or structure informations.
- */
-
-/**
- * resolveEntitySAXFunc:
- * @ctx: the user data (XML parser context)
- * @publicId: The public ID of the entity
- * @systemId: The system ID of the entity
- *
- * Callback:
- * The entity loader, to control the loading of external entities,
- * the application can either:
- * - override this resolveEntity() callback in the SAX block
- * - or better use the xmlSetExternalEntityLoader() function to
- * set up it's own entity resolution routine
- *
- * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
- */
-typedef xmlParserInputPtr (*resolveEntitySAXFunc) (void *ctx,
- const xmlChar *publicId,
- const xmlChar *systemId);
-/**
- * internalSubsetSAXFunc:
- * @ctx: the user data (XML parser context)
- * @name: the root element name
- * @ExternalID: the external ID
- * @SystemID: the SYSTEM ID (e.g. filename or URL)
- *
- * Callback on internal subset declaration.
- */
-typedef void (*internalSubsetSAXFunc) (void *ctx,
- const xmlChar *name,
- const xmlChar *ExternalID,
- const xmlChar *SystemID);
-/**
- * externalSubsetSAXFunc:
- * @ctx: the user data (XML parser context)
- * @name: the root element name
- * @ExternalID: the external ID
- * @SystemID: the SYSTEM ID (e.g. filename or URL)
- *
- * Callback on external subset declaration.
- */
-typedef void (*externalSubsetSAXFunc) (void *ctx,
- const xmlChar *name,
- const xmlChar *ExternalID,
- const xmlChar *SystemID);
-/**
- * getEntitySAXFunc:
- * @ctx: the user data (XML parser context)
- * @name: The entity name
- *
- * Get an entity by name.
- *
- * Returns the xmlEntityPtr if found.
- */
-typedef xmlEntityPtr (*getEntitySAXFunc) (void *ctx,
- const xmlChar *name);
-/**
- * getParameterEntitySAXFunc:
- * @ctx: the user data (XML parser context)
- * @name: The entity name
- *
- * Get a parameter entity by name.
- *
- * Returns the xmlEntityPtr if found.
- */
-typedef xmlEntityPtr (*getParameterEntitySAXFunc) (void *ctx,
- const xmlChar *name);
-/**
- * entityDeclSAXFunc:
- * @ctx: the user data (XML parser context)
- * @name: the entity name
- * @type: the entity type
- * @publicId: The public ID of the entity
- * @systemId: The system ID of the entity
- * @content: the entity value (without processing).
- *
- * An entity definition has been parsed.
- */
-typedef void (*entityDeclSAXFunc) (void *ctx,
- const xmlChar *name,
- int type,
- const xmlChar *publicId,
- const xmlChar *systemId,
- xmlChar *content);
-/**
- * notationDeclSAXFunc:
- * @ctx: the user data (XML parser context)
- * @name: The name of the notation
- * @publicId: The public ID of the entity
- * @systemId: The system ID of the entity
- *
- * What to do when a notation declaration has been parsed.
- */
-typedef void (*notationDeclSAXFunc)(void *ctx,
- const xmlChar *name,
- const xmlChar *publicId,
- const xmlChar *systemId);
-/**
- * attributeDeclSAXFunc:
- * @ctx: the user data (XML parser context)
- * @elem: the name of the element
- * @fullname: the attribute name
- * @type: the attribute type
- * @def: the type of default value
- * @defaultValue: the attribute default value
- * @tree: the tree of enumerated value set
- *
- * An attribute definition has been parsed.
- */
-typedef void (*attributeDeclSAXFunc)(void *ctx,
- const xmlChar *elem,
- const xmlChar *fullname,
- int type,
- int def,
- const xmlChar *defaultValue,
- xmlEnumerationPtr tree);
-/**
- * elementDeclSAXFunc:
- * @ctx: the user data (XML parser context)
- * @name: the element name
- * @type: the element type
- * @content: the element value tree
- *
- * An element definition has been parsed.
- */
-typedef void (*elementDeclSAXFunc)(void *ctx,
- const xmlChar *name,
- int type,
- xmlElementContentPtr content);
-/**
- * unparsedEntityDeclSAXFunc:
- * @ctx: the user data (XML parser context)
- * @name: The name of the entity
- * @publicId: The public ID of the entity
- * @systemId: The system ID of the entity
- * @notationName: the name of the notation
- *
- * What to do when an unparsed entity declaration is parsed.
- */
-typedef void (*unparsedEntityDeclSAXFunc)(void *ctx,
- const xmlChar *name,
- const xmlChar *publicId,
- const xmlChar *systemId,
- const xmlChar *notationName);
-/**
- * setDocumentLocatorSAXFunc:
- * @ctx: the user data (XML parser context)
- * @loc: A SAX Locator
- *
- * Receive the document locator at startup, actually xmlDefaultSAXLocator.
- * Everything is available on the context, so this is useless in our case.
- */
-typedef void (*setDocumentLocatorSAXFunc) (void *ctx,
- xmlSAXLocatorPtr loc);
-/**
- * startDocumentSAXFunc:
- * @ctx: the user data (XML parser context)
- *
- * Called when the document start being processed.
- */
-typedef void (*startDocumentSAXFunc) (void *ctx);
-/**
- * endDocumentSAXFunc:
- * @ctx: the user data (XML parser context)
- *
- * Called when the document end has been detected.
- */
-typedef void (*endDocumentSAXFunc) (void *ctx);
-/**
- * startElementSAXFunc:
- * @ctx: the user data (XML parser context)
- * @name: The element name, including namespace prefix
- * @atts: An array of name/value attributes pairs, NULL terminated
- *
- * Called when an opening tag has been processed.
- */
-typedef void (*startElementSAXFunc) (void *ctx,
- const xmlChar *name,
- const xmlChar **atts);
-/**
- * endElementSAXFunc:
- * @ctx: the user data (XML parser context)
- * @name: The element name
- *
- * Called when the end of an element has been detected.
- */
-typedef void (*endElementSAXFunc) (void *ctx,
- const xmlChar *name);
-/**
- * attributeSAXFunc:
- * @ctx: the user data (XML parser context)
- * @name: The attribute name, including namespace prefix
- * @value: The attribute value
- *
- * Handle an attribute that has been read by the parser.
- * The default handling is to convert the attribute into an
- * DOM subtree and past it in a new xmlAttr element added to
- * the element.
- */
-typedef void (*attributeSAXFunc) (void *ctx,
- const xmlChar *name,
- const xmlChar *value);
-/**
- * referenceSAXFunc:
- * @ctx: the user data (XML parser context)
- * @name: The entity name
- *
- * Called when an entity reference is detected.
- */
-typedef void (*referenceSAXFunc) (void *ctx,
- const xmlChar *name);
-/**
- * charactersSAXFunc:
- * @ctx: the user data (XML parser context)
- * @ch: a xmlChar string
- * @len: the number of xmlChar
- *
- * Receiving some chars from the parser.
- */
-typedef void (*charactersSAXFunc) (void *ctx,
- const xmlChar *ch,
- int len);
-/**
- * ignorableWhitespaceSAXFunc:
- * @ctx: the user data (XML parser context)
- * @ch: a xmlChar string
- * @len: the number of xmlChar
- *
- * Receiving some ignorable whitespaces from the parser.
- * UNUSED: by default the DOM building will use characters.
- */
-typedef void (*ignorableWhitespaceSAXFunc) (void *ctx,
- const xmlChar *ch,
- int len);
-/**
- * processingInstructionSAXFunc:
- * @ctx: the user data (XML parser context)
- * @target: the target name
- * @data: the PI data's
- *
- * A processing instruction has been parsed.
- */
-typedef void (*processingInstructionSAXFunc) (void *ctx,
- const xmlChar *target,
- const xmlChar *data);
-/**
- * commentSAXFunc:
- * @ctx: the user data (XML parser context)
- * @value: the comment content
- *
- * A comment has been parsed.
- */
-typedef void (*commentSAXFunc) (void *ctx,
- const xmlChar *value);
-/**
- * cdataBlockSAXFunc:
- * @ctx: the user data (XML parser context)
- * @value: The pcdata content
- * @len: the block length
- *
- * Called when a pcdata block has been parsed.
- */
-typedef void (*cdataBlockSAXFunc) (
- void *ctx,
- const xmlChar *value,
- int len);
-/**
- * warningSAXFunc:
- * @ctx: an XML parser context
- * @msg: the message to display/transmit
- * @...: extra parameters for the message display
- *
- * Display and format a warning messages, callback.
- */
-typedef void (*warningSAXFunc) (void *ctx,
- const char *msg, ...);
-/**
- * errorSAXFunc:
- * @ctx: an XML parser context
- * @msg: the message to display/transmit
- * @...: extra parameters for the message display
- *
- * Display and format an error messages, callback.
- */
-typedef void (*errorSAXFunc) (void *ctx,
- const char *msg, ...);
-/**
- * fatalErrorSAXFunc:
- * @ctx: an XML parser context
- * @msg: the message to display/transmit
- * @...: extra parameters for the message display
- *
- * Display and format fatal error messages, callback.
- * Note: so far fatalError() SAX callbacks are not used, error()
- * get all the callbacks for errors.
- */
-typedef void (*fatalErrorSAXFunc) (void *ctx,
- const char *msg, ...);
-/**
- * isStandaloneSAXFunc:
- * @ctx: the user data (XML parser context)
- *
- * Is this document tagged standalone?
- *
- * Returns 1 if true
- */
-typedef int (*isStandaloneSAXFunc) (void *ctx);
-/**
- * hasInternalSubsetSAXFunc:
- * @ctx: the user data (XML parser context)
- *
- * Does this document has an internal subset.
- *
- * Returns 1 if true
- */
-typedef int (*hasInternalSubsetSAXFunc) (void *ctx);
-/**
- * hasExternalSubsetSAXFunc:
- * @ctx: the user data (XML parser context)
- *
- * Does this document has an external subset?
- *
- * Returns 1 if true
- */
-typedef int (*hasExternalSubsetSAXFunc) (void *ctx);
-
-struct _xmlSAXHandler {
- internalSubsetSAXFunc internalSubset;
- isStandaloneSAXFunc isStandalone;
- hasInternalSubsetSAXFunc hasInternalSubset;
- hasExternalSubsetSAXFunc hasExternalSubset;
- resolveEntitySAXFunc resolveEntity;
- getEntitySAXFunc getEntity;
- entityDeclSAXFunc entityDecl;
- notationDeclSAXFunc notationDecl;
- attributeDeclSAXFunc attributeDecl;
- elementDeclSAXFunc elementDecl;
- unparsedEntityDeclSAXFunc unparsedEntityDecl;
- setDocumentLocatorSAXFunc setDocumentLocator;
- startDocumentSAXFunc startDocument;
- endDocumentSAXFunc endDocument;
- startElementSAXFunc startElement;
- endElementSAXFunc endElement;
- referenceSAXFunc reference;
- charactersSAXFunc characters;
- ignorableWhitespaceSAXFunc ignorableWhitespace;
- processingInstructionSAXFunc processingInstruction;
- commentSAXFunc comment;
- warningSAXFunc warning;
- errorSAXFunc error;
- fatalErrorSAXFunc fatalError; /* unused error() get all the errors */
- getParameterEntitySAXFunc getParameterEntity;
- cdataBlockSAXFunc cdataBlock;
- externalSubsetSAXFunc externalSubset;
- int initialized;
-};
-
-/**
- * xmlExternalEntityLoader:
- * @URL: The System ID of the resource requested
- * @ID: The Public ID of the resource requested
- * @context: the XML parser context
- *
- * External entity loaders types.
- *
- * Returns the entity input parser.
- */
-typedef xmlParserInputPtr (*xmlExternalEntityLoader) (const char *URL,
- const char *ID,
- xmlParserCtxtPtr context);
-
-/*
- * Global variables: just the default SAX interface tables and XML
- * version infos.
- */
-#if 0
-LIBXML_DLL_IMPORT extern const char *xmlParserVersion;
-#endif
-
-/*
-LIBXML_DLL_IMPORT extern xmlSAXLocator xmlDefaultSAXLocator;
-LIBXML_DLL_IMPORT extern xmlSAXHandler xmlDefaultSAXHandler;
-LIBXML_DLL_IMPORT extern xmlSAXHandler htmlDefaultSAXHandler;
-LIBXML_DLL_IMPORT extern xmlSAXHandler docbDefaultSAXHandler;
- */
-
-/*
- * Entity substitution default behavior.
- */
-
-#if 0
-LIBXML_DLL_IMPORT extern int xmlSubstituteEntitiesDefaultValue;
-LIBXML_DLL_IMPORT extern int xmlGetWarningsDefaultValue;
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-#include <libxml/encoding.h>
-#include <libxml/xmlIO.h>
-#include <libxml/globals.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * Init/Cleanup
- */
-void xmlInitParser (void);
-void xmlCleanupParser (void);
-
-/*
- * Input functions
- */
-int xmlParserInputRead (xmlParserInputPtr in,
- int len);
-int xmlParserInputGrow (xmlParserInputPtr in,
- int len);
-
-/*
- * xmlChar handling
- */
-xmlChar * xmlStrdup (const xmlChar *cur);
-xmlChar * xmlStrndup (const xmlChar *cur,
- int len);
-xmlChar * xmlCharStrndup (const char *cur,
- int len);
-xmlChar * xmlCharStrdup (const char *cur);
-xmlChar * xmlStrsub (const xmlChar *str,
- int start,
- int len);
-const xmlChar * xmlStrchr (const xmlChar *str,
- xmlChar val);
-const xmlChar * xmlStrstr (const xmlChar *str,
- const xmlChar *val);
-const xmlChar * xmlStrcasestr (const xmlChar *str,
- xmlChar *val);
-int xmlStrcmp (const xmlChar *str1,
- const xmlChar *str2);
-int xmlStrncmp (const xmlChar *str1,
- const xmlChar *str2,
- int len);
-int xmlStrcasecmp (const xmlChar *str1,
- const xmlChar *str2);
-int xmlStrncasecmp (const xmlChar *str1,
- const xmlChar *str2,
- int len);
-int xmlStrEqual (const xmlChar *str1,
- const xmlChar *str2);
-int xmlStrlen (const xmlChar *str);
-xmlChar * xmlStrcat (xmlChar *cur,
- const xmlChar *add);
-xmlChar * xmlStrncat (xmlChar *cur,
- const xmlChar *add,
- int len);
-
-/*
- * Basic parsing Interfaces
- */
-xmlDocPtr xmlParseDoc (xmlChar *cur);
-xmlDocPtr xmlParseMemory (const char *buffer,
- int size);
-xmlDocPtr xmlParseFile (const char *filename);
-int xmlSubstituteEntitiesDefault(int val);
-int xmlKeepBlanksDefault (int val);
-void xmlStopParser (xmlParserCtxtPtr ctxt);
-int xmlPedanticParserDefault(int val);
-int xmlLineNumbersDefault (int val);
-
-/*
- * Recovery mode
- */
-xmlDocPtr xmlRecoverDoc (xmlChar *cur);
-xmlDocPtr xmlRecoverMemory (const char *buffer,
- int size);
-xmlDocPtr xmlRecoverFile (const char *filename);
-
-/*
- * Less common routines and SAX interfaces
- */
-int xmlParseDocument (xmlParserCtxtPtr ctxt);
-int xmlParseExtParsedEnt (xmlParserCtxtPtr ctxt);
-xmlDocPtr xmlSAXParseDoc (xmlSAXHandlerPtr sax,
- xmlChar *cur,
- int recovery);
-int xmlSAXUserParseFile (xmlSAXHandlerPtr sax,
- void *user_data,
- const char *filename);
-int xmlSAXUserParseMemory (xmlSAXHandlerPtr sax,
- void *user_data,
- const char *buffer,
- int size);
-xmlDocPtr xmlSAXParseMemory (xmlSAXHandlerPtr sax,
- const char *buffer,
- int size,
- int recovery);
-xmlDocPtr xmlSAXParseMemoryWithData (xmlSAXHandlerPtr sax,
- const char *buffer,
- int size,
- int recovery,
- void *data);
-xmlDocPtr xmlSAXParseFile (xmlSAXHandlerPtr sax,
- const char *filename,
- int recovery);
-xmlDocPtr xmlSAXParseFileWithData (xmlSAXHandlerPtr sax,
- const char *filename,
- int recovery,
- void *data);
-xmlDocPtr xmlSAXParseEntity (xmlSAXHandlerPtr sax,
- const char *filename);
-xmlDocPtr xmlParseEntity (const char *filename);
-xmlDtdPtr xmlParseDTD (const xmlChar *ExternalID,
- const xmlChar *SystemID);
-xmlDtdPtr xmlSAXParseDTD (xmlSAXHandlerPtr sax,
- const xmlChar *ExternalID,
- const xmlChar *SystemID);
-xmlDtdPtr xmlIOParseDTD (xmlSAXHandlerPtr sax,
- xmlParserInputBufferPtr input,
- xmlCharEncoding enc);
-int xmlParseBalancedChunkMemory(xmlDocPtr doc,
- xmlSAXHandlerPtr sax,
- void *user_data,
- int depth,
- const xmlChar *string,
- xmlNodePtr *lst);
-int xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc,
- xmlSAXHandlerPtr sax,
- void *user_data,
- int depth,
- const xmlChar *string,
- xmlNodePtr *lst,
- int recover);
-int xmlParseExternalEntity (xmlDocPtr doc,
- xmlSAXHandlerPtr sax,
- void *user_data,
- int depth,
- const xmlChar *URL,
- const xmlChar *ID,
- xmlNodePtr *lst);
-int xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx,
- const xmlChar *URL,
- const xmlChar *ID,
- xmlNodePtr *lst);
-
-/*
- * Parser contexts handling.
- */
-void xmlInitParserCtxt (xmlParserCtxtPtr ctxt);
-void xmlClearParserCtxt (xmlParserCtxtPtr ctxt);
-void xmlFreeParserCtxt (xmlParserCtxtPtr ctxt);
-void xmlSetupParserForBuffer (xmlParserCtxtPtr ctxt,
- const xmlChar* buffer,
- const char *filename);
-xmlParserCtxtPtr xmlCreateDocParserCtxt (xmlChar *cur);
-
-/*
- * Reading/setting optional parsing features.
- */
-
-int xmlGetFeaturesList (int *len,
- const char **result);
-int xmlGetFeature (xmlParserCtxtPtr ctxt,
- const char *name,
- void *result);
-int xmlSetFeature (xmlParserCtxtPtr ctxt,
- const char *name,
- void *value);
-
-/*
- * Interfaces for the Push mode.
- */
-xmlParserCtxtPtr xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax,
- void *user_data,
- const char *chunk,
- int size,
- const char *filename);
-int xmlParseChunk (xmlParserCtxtPtr ctxt,
- const char *chunk,
- int size,
- int terminate);
-
-/*
- * Special I/O mode.
- */
-
-xmlParserCtxtPtr xmlCreateIOParserCtxt (xmlSAXHandlerPtr sax,
- void *user_data,
- xmlInputReadCallback ioread,
- xmlInputCloseCallback ioclose,
- void *ioctx,
- xmlCharEncoding enc);
-
-xmlParserInputPtr xmlNewIOInputStream (xmlParserCtxtPtr ctxt,
- xmlParserInputBufferPtr input,
- xmlCharEncoding enc);
-
-/*
- * Node infos.
- */
-const xmlParserNodeInfo*
- xmlParserFindNodeInfo (const xmlParserCtxtPtr ctxt,
- const xmlNodePtr node);
-void xmlInitNodeInfoSeq (xmlParserNodeInfoSeqPtr seq);
-void xmlClearNodeInfoSeq (xmlParserNodeInfoSeqPtr seq);
-unsigned long xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeqPtr seq,
- const xmlNodePtr node);
-void xmlParserAddNodeInfo (xmlParserCtxtPtr ctxt,
- const xmlParserNodeInfoPtr info);
-
-/*
- * External entities handling actually implemented in xmlIO.
- */
-
-void xmlSetExternalEntityLoader(xmlExternalEntityLoader f);
-xmlExternalEntityLoader
- xmlGetExternalEntityLoader(void);
-xmlParserInputPtr
- xmlLoadExternalEntity (const char *URL,
- const char *ID,
- xmlParserCtxtPtr ctxt);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* __XML_PARSER_H__ */
-
diff --git a/bundle/libxml/include/libxml/parserInternals.h b/bundle/libxml/include/libxml/parserInternals.h
deleted file mode 100644
index 8507442be8..0000000000
--- a/bundle/libxml/include/libxml/parserInternals.h
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * parserInternals.h : internals routines exported by the parser.
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- *
- */
-
-#ifndef __XML_PARSER_INTERNALS_H__
-#define __XML_PARSER_INTERNALS_H__
-
-#include <libxml/parser.h>
-#include <libxml/HTMLparser.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
- /**
- * XML_MAX_NAMELEN:
- *
- * Identifiers can be longer, but this will be more costly
- * at runtime.
- */
-#define XML_MAX_NAMELEN 100
-
-/**
- * INPUT_CHUNK:
- *
- * The parser tries to always have that amount of input ready.
- * One of the point is providing context when reporting errors.
- */
-#define INPUT_CHUNK 250
-
-/************************************************************************
- * *
- * UNICODE version of the macros. *
- * *
- ************************************************************************/
-/**
- * IS_CHAR:
- * @c: an UNICODE value (int)
- *
- * Macro to check the following production in the XML spec:
- *
- * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
- * | [#x10000-#x10FFFF]
- * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
- */
-#define IS_CHAR(c) \
- ((((c) >= 0x20) && ((c) <= 0xD7FF)) || \
- ((c) == 0x09) || ((c) == 0x0A) || ((c) == 0x0D) || \
- (((c) >= 0xE000) && ((c) <= 0xFFFD)) || \
- (((c) >= 0x10000) && ((c) <= 0x10FFFF)))
-
-/**
- * IS_BLANK:
- * @c: an UNICODE value (int)
- *
- * Macro to check the following production in the XML spec:
- *
- * [3] S ::= (#x20 | #x9 | #xD | #xA)+
- */
-#define IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xA) || \
- ((c) == 0x0D))
-
-/**
- * IS_BASECHAR:
- * @c: an UNICODE value (int)
- *
- * Macro to check the following production in the XML spec:
- *
- * [85] BaseChar ::= ... long list see REC ...
- */
-#define IS_BASECHAR(c) xmlIsBaseChar(c)
-
-/**
- * IS_DIGIT:
- * @c: an UNICODE value (int)
- *
- * Macro to check the following production in the XML spec:
- *
- * [88] Digit ::= ... long list see REC ...
- */
-#define IS_DIGIT(c) xmlIsDigit(c)
-
-/**
- * IS_COMBINING:
- * @c: an UNICODE value (int)
- *
- * Macro to check the following production in the XML spec:
- *
- * [87] CombiningChar ::= ... long list see REC ...
- */
-#define IS_COMBINING(c) xmlIsCombining(c)
-
-/**
- * IS_EXTENDER:
- * @c: an UNICODE value (int)
- *
- * Macro to check the following production in the XML spec:
- *
- *
- * [89] Extender ::= #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 |
- * #x0E46 | #x0EC6 | #x3005 | [#x3031-#x3035] |
- * [#x309D-#x309E] | [#x30FC-#x30FE]
- */
-#define IS_EXTENDER(c) xmlIsExtender(c)
-
-/**
- * IS_IDEOGRAPHIC:
- * @c: an UNICODE value (int)
- *
- * Macro to check the following production in the XML spec:
- *
- *
- * [86] Ideographic ::= [#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]
- */
-#define IS_IDEOGRAPHIC(c) xmlIsIdeographic(c)
-
-/**
- * IS_LETTER:
- * @c: an UNICODE value (int)
- *
- * Macro to check the following production in the XML spec:
- *
- *
- * [84] Letter ::= BaseChar | Ideographic
- */
-#define IS_LETTER(c) (IS_BASECHAR(c) || IS_IDEOGRAPHIC(c))
-
-
-/**
- * IS_PUBIDCHAR:
- * @c: an UNICODE value (int)
- *
- * Macro to check the following production in the XML spec:
- *
- *
- * [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
- */
-#define IS_PUBIDCHAR(c) xmlIsPubidChar(c)
-
-/**
- * SKIP_EOL:
- * @p: and UTF8 string pointer
- *
- * Skips the end of line chars.
- */
-#define SKIP_EOL(p) \
- if (*(p) == 0x13) { p++ ; if (*(p) == 0x10) p++; } \
- if (*(p) == 0x10) { p++ ; if (*(p) == 0x13) p++; }
-
-/**
- * MOVETO_ENDTAG:
- * @p: and UTF8 string pointer
- *
- * Skips to the next '>' char.
- */
-#define MOVETO_ENDTAG(p) \
- while ((*p) && (*(p) != '>')) (p)++
-
-/**
- * MOVETO_STARTTAG:
- * @p: and UTF8 string pointer
- *
- * Skips to the next '<' char.
- */
-#define MOVETO_STARTTAG(p) \
- while ((*p) && (*(p) != '<')) (p)++
-
-/**
- * Global variables used for predefined strings.
- */
-LIBXML_DLL_IMPORT extern const xmlChar xmlStringText[];
-LIBXML_DLL_IMPORT extern const xmlChar xmlStringTextNoenc[];
-LIBXML_DLL_IMPORT extern const xmlChar xmlStringComment[];
-
-/*
- * Function to finish the work of the macros where needed.
- */
-int xmlIsBaseChar (int c);
-int xmlIsBlank (int c);
-int xmlIsPubidChar (int c);
-int xmlIsLetter (int c);
-int xmlIsDigit (int c);
-int xmlIsIdeographic(int c);
-int xmlIsExtender (int c);
-int xmlIsCombining (int c);
-int xmlIsChar (int c);
-
-/**
- * Parser context.
- */
-xmlParserCtxtPtr xmlCreateFileParserCtxt (const char *filename);
-xmlParserCtxtPtr xmlCreateMemoryParserCtxt(const char *buffer,
- int size);
-xmlParserCtxtPtr xmlNewParserCtxt (void);
-xmlParserCtxtPtr xmlCreateEntityParserCtxt(const xmlChar *URL,
- const xmlChar *ID,
- const xmlChar *base);
-int xmlSwitchEncoding (xmlParserCtxtPtr ctxt,
- xmlCharEncoding enc);
-int xmlSwitchToEncoding (xmlParserCtxtPtr ctxt,
- xmlCharEncodingHandlerPtr handler);
-
-/**
- * Entities
- */
-void xmlHandleEntity (xmlParserCtxtPtr ctxt,
- xmlEntityPtr entity);
-
-/**
- * Input Streams.
- */
-xmlParserInputPtr xmlNewStringInputStream (xmlParserCtxtPtr ctxt,
- const xmlChar *buffer);
-xmlParserInputPtr xmlNewEntityInputStream (xmlParserCtxtPtr ctxt,
- xmlEntityPtr entity);
-void xmlPushInput (xmlParserCtxtPtr ctxt,
- xmlParserInputPtr input);
-xmlChar xmlPopInput (xmlParserCtxtPtr ctxt);
-void xmlFreeInputStream (xmlParserInputPtr input);
-xmlParserInputPtr xmlNewInputFromFile (xmlParserCtxtPtr ctxt,
- const char *filename);
-xmlParserInputPtr xmlNewInputStream (xmlParserCtxtPtr ctxt);
-
-/**
- * Namespaces.
- */
-xmlChar * xmlSplitQName (xmlParserCtxtPtr ctxt,
- const xmlChar *name,
- xmlChar **prefix);
-xmlChar * xmlNamespaceParseNCName (xmlParserCtxtPtr ctxt);
-xmlChar * xmlNamespaceParseQName (xmlParserCtxtPtr ctxt,
- xmlChar **prefix);
-xmlChar * xmlNamespaceParseNSDef (xmlParserCtxtPtr ctxt);
-xmlChar * xmlParseQuotedString (xmlParserCtxtPtr ctxt);
-void xmlParseNamespace (xmlParserCtxtPtr ctxt);
-
-/**
- * Generic production rules.
- */
-xmlChar * xmlScanName (xmlParserCtxtPtr ctxt);
-xmlChar * xmlParseName (xmlParserCtxtPtr ctxt);
-xmlChar * xmlParseNmtoken (xmlParserCtxtPtr ctxt);
-xmlChar * xmlParseEntityValue (xmlParserCtxtPtr ctxt,
- xmlChar **orig);
-xmlChar * xmlParseAttValue (xmlParserCtxtPtr ctxt);
-xmlChar * xmlParseSystemLiteral (xmlParserCtxtPtr ctxt);
-xmlChar * xmlParsePubidLiteral (xmlParserCtxtPtr ctxt);
-void xmlParseCharData (xmlParserCtxtPtr ctxt,
- int cdata);
-xmlChar * xmlParseExternalID (xmlParserCtxtPtr ctxt,
- xmlChar **publicID,
- int strict);
-void xmlParseComment (xmlParserCtxtPtr ctxt);
-xmlChar * xmlParsePITarget (xmlParserCtxtPtr ctxt);
-void xmlParsePI (xmlParserCtxtPtr ctxt);
-void xmlParseNotationDecl (xmlParserCtxtPtr ctxt);
-void xmlParseEntityDecl (xmlParserCtxtPtr ctxt);
-int xmlParseDefaultDecl (xmlParserCtxtPtr ctxt,
- xmlChar **value);
-xmlEnumerationPtr xmlParseNotationType (xmlParserCtxtPtr ctxt);
-xmlEnumerationPtr xmlParseEnumerationType (xmlParserCtxtPtr ctxt);
-int xmlParseEnumeratedType (xmlParserCtxtPtr ctxt,
- xmlEnumerationPtr *tree);
-int xmlParseAttributeType (xmlParserCtxtPtr ctxt,
- xmlEnumerationPtr *tree);
-void xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt);
-xmlElementContentPtr xmlParseElementMixedContentDecl
- (xmlParserCtxtPtr ctxt,
- xmlParserInputPtr inputchk);
-xmlElementContentPtr xmlParseElementChildrenContentDecl
- (xmlParserCtxtPtr ctxt,
- xmlParserInputPtr inputchk);
-int xmlParseElementContentDecl(xmlParserCtxtPtr ctxt,
- xmlChar *name,
- xmlElementContentPtr *result);
-int xmlParseElementDecl (xmlParserCtxtPtr ctxt);
-void xmlParseMarkupDecl (xmlParserCtxtPtr ctxt);
-int xmlParseCharRef (xmlParserCtxtPtr ctxt);
-xmlEntityPtr xmlParseEntityRef (xmlParserCtxtPtr ctxt);
-void xmlParseReference (xmlParserCtxtPtr ctxt);
-void xmlParsePEReference (xmlParserCtxtPtr ctxt);
-void xmlParseDocTypeDecl (xmlParserCtxtPtr ctxt);
-xmlChar * xmlParseAttribute (xmlParserCtxtPtr ctxt,
- xmlChar **value);
-xmlChar * xmlParseStartTag (xmlParserCtxtPtr ctxt);
-void xmlParseEndTag (xmlParserCtxtPtr ctxt);
-void xmlParseCDSect (xmlParserCtxtPtr ctxt);
-void xmlParseContent (xmlParserCtxtPtr ctxt);
-void xmlParseElement (xmlParserCtxtPtr ctxt);
-xmlChar * xmlParseVersionNum (xmlParserCtxtPtr ctxt);
-xmlChar * xmlParseVersionInfo (xmlParserCtxtPtr ctxt);
-xmlChar * xmlParseEncName (xmlParserCtxtPtr ctxt);
-xmlChar * xmlParseEncodingDecl (xmlParserCtxtPtr ctxt);
-int xmlParseSDDecl (xmlParserCtxtPtr ctxt);
-void xmlParseXMLDecl (xmlParserCtxtPtr ctxt);
-void xmlParseTextDecl (xmlParserCtxtPtr ctxt);
-void xmlParseMisc (xmlParserCtxtPtr ctxt);
-void xmlParseExternalSubset (xmlParserCtxtPtr ctxt,
- const xmlChar *ExternalID,
- const xmlChar *SystemID);
-/**
- * XML_SUBSTITUTE_NONE:
- *
- * If no entities need to be substituted.
- */
-#define XML_SUBSTITUTE_NONE 0
-/**
- * XML_SUBSTITUTE_REF:
- *
- * Whether general entities need to be substituted.
- */
-#define XML_SUBSTITUTE_REF 1
-/**
- * XML_SUBSTITUTE_PEREF:
- *
- * Whether parameter entities need to be substituted.
- */
-#define XML_SUBSTITUTE_PEREF 2
-/**
- * XML_SUBSTITUTE_BOTH:
- *
- * Both general and parameter entities need to be substituted.
- */
-#define XML_SUBSTITUTE_BOTH 3
-
-xmlChar * xmlDecodeEntities (xmlParserCtxtPtr ctxt,
- int len,
- int what,
- xmlChar end,
- xmlChar end2,
- xmlChar end3);
-xmlChar * xmlStringDecodeEntities (xmlParserCtxtPtr ctxt,
- const xmlChar *str,
- int what,
- xmlChar end,
- xmlChar end2,
- xmlChar end3);
-
-/*
- * Generated by MACROS on top of parser.c c.f. PUSH_AND_POP.
- */
-int nodePush (xmlParserCtxtPtr ctxt,
- xmlNodePtr value);
-xmlNodePtr nodePop (xmlParserCtxtPtr ctxt);
-int inputPush (xmlParserCtxtPtr ctxt,
- xmlParserInputPtr value);
-xmlParserInputPtr inputPop (xmlParserCtxtPtr ctxt);
-xmlChar *namePop (xmlParserCtxtPtr ctxt);
-int namePush (xmlParserCtxtPtr ctxt,
- xmlChar *value);
-
-/*
- * other commodities shared between parser.c and parserInternals.
- */
-int xmlSkipBlankChars (xmlParserCtxtPtr ctxt);
-int xmlStringCurrentChar (xmlParserCtxtPtr ctxt,
- const xmlChar *cur,
- int *len);
-void xmlParserHandlePEReference(xmlParserCtxtPtr ctxt);
-void xmlParserHandleReference(xmlParserCtxtPtr ctxt);
-int xmlCheckLanguageID (const xmlChar *lang);
-
-/*
- * Really core function shared with HTML parser.
- */
-int xmlCurrentChar (xmlParserCtxtPtr ctxt,
- int *len);
-int xmlCopyCharMultiByte (xmlChar *out,
- int val);
-int xmlCopyChar (int len,
- xmlChar *out,
- int val);
-void xmlNextChar (xmlParserCtxtPtr ctxt);
-void xmlParserInputShrink (xmlParserInputPtr in);
-
-#ifdef LIBXML_HTML_ENABLED
-/*
- * Actually comes from the HTML parser but launched from the init stuff.
- */
-void htmlInitAutoClose (void);
-htmlParserCtxtPtr htmlCreateFileParserCtxt(const char *filename,
- const char *encoding);
-#endif
-
-/*
- * Specific function to keep track of entities references
- * and used by the XSLT debugger.
- */
-/**
- * xmlEntityReferenceFunc:
- * @ent: the entity
- * @firstNode: the fist node in the chunk
- * @lastNode: the last nod in the chunk
- *
- * Callback function used when one needs to be able to track back the
- * provenance of a chunk of nodes inherited from an entity replacement.
- */
-typedef void (*xmlEntityReferenceFunc) (xmlEntityPtr ent,
- xmlNodePtr firstNode,
- xmlNodePtr lastNode);
-
-void xmlSetEntityReferenceFunc (xmlEntityReferenceFunc func);
-
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* __XML_PARSER_INTERNALS_H__ */
diff --git a/bundle/libxml/include/libxml/schemasInternals.h b/bundle/libxml/include/libxml/schemasInternals.h
deleted file mode 100644
index 29ad862145..0000000000
--- a/bundle/libxml/include/libxml/schemasInternals.h
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * schemasInternals.h : internal interfaces for the XML Schemas handling
- * and schema validity checking
- *
- * See Copyright for the status of this software.
- *
- * Daniel.Veillard@w3.org
- */
-
-
-#ifndef __XML_SCHEMA_INTERNALS_H__
-#define __XML_SCHEMA_INTERNALS_H__
-
-#include <libxml/xmlversion.h>
-
-#ifdef LIBXML_SCHEMAS_ENABLED
-
-#include <libxml/xmlregexp.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * XML Schemas defines multiple type of types.
- */
-typedef enum {
- XML_SCHEMA_TYPE_BASIC = 1,
- XML_SCHEMA_TYPE_ANY,
- XML_SCHEMA_TYPE_FACET,
- XML_SCHEMA_TYPE_SIMPLE,
- XML_SCHEMA_TYPE_COMPLEX,
- XML_SCHEMA_TYPE_SEQUENCE,
- XML_SCHEMA_TYPE_CHOICE,
- XML_SCHEMA_TYPE_ALL,
- XML_SCHEMA_TYPE_SIMPLE_CONTENT,
- XML_SCHEMA_TYPE_COMPLEX_CONTENT,
- XML_SCHEMA_TYPE_UR,
- XML_SCHEMA_TYPE_RESTRICTION,
- XML_SCHEMA_TYPE_EXTENSION,
- XML_SCHEMA_TYPE_ELEMENT,
- XML_SCHEMA_TYPE_ATTRIBUTE,
- XML_SCHEMA_TYPE_ATTRIBUTEGROUP,
- XML_SCHEMA_TYPE_GROUP,
- XML_SCHEMA_TYPE_NOTATION,
- XML_SCHEMA_TYPE_LIST,
- XML_SCHEMA_TYPE_UNION,
- XML_SCHEMA_FACET_MININCLUSIVE = 1000,
- XML_SCHEMA_FACET_MINEXCLUSIVE,
- XML_SCHEMA_FACET_MAXINCLUSIVE,
- XML_SCHEMA_FACET_MAXEXCLUSIVE,
- XML_SCHEMA_FACET_TOTALDIGITS,
- XML_SCHEMA_FACET_FRACTIONDIGITS,
- XML_SCHEMA_FACET_PATTERN,
- XML_SCHEMA_FACET_ENUMERATION,
- XML_SCHEMA_FACET_WHITESPACE,
- XML_SCHEMA_FACET_LENGTH,
- XML_SCHEMA_FACET_MAXLENGTH,
- XML_SCHEMA_FACET_MINLENGTH
-} xmlSchemaTypeType;
-
-typedef enum {
- XML_SCHEMA_CONTENT_UNKNOWN = 0,
- XML_SCHEMA_CONTENT_EMPTY = 1,
- XML_SCHEMA_CONTENT_ELEMENTS,
- XML_SCHEMA_CONTENT_MIXED,
- XML_SCHEMA_CONTENT_SIMPLE,
- XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS,
- XML_SCHEMA_CONTENT_BASIC,
- XML_SCHEMA_CONTENT_ANY
-} xmlSchemaContentType;
-
-typedef struct _xmlSchemaVal xmlSchemaVal;
-typedef xmlSchemaVal *xmlSchemaValPtr;
-
-typedef struct _xmlSchemaType xmlSchemaType;
-typedef xmlSchemaType *xmlSchemaTypePtr;
-
-typedef struct _xmlSchemaFacet xmlSchemaFacet;
-typedef xmlSchemaFacet *xmlSchemaFacetPtr;
-
-/**
- * Annotation
- */
-typedef struct _xmlSchemaAnnot xmlSchemaAnnot;
-typedef xmlSchemaAnnot *xmlSchemaAnnotPtr;
-struct _xmlSchemaAnnot {
- struct _xmlSchemaAnnot *next;
- xmlNodePtr content; /* the annotation */
-};
-
-/**
- * An attribute definition.
- */
-
-#define XML_SCHEMAS_ANYATTR_SKIP 1
-#define XML_SCHEMAS_ANYATTR_LAX 2
-#define XML_SCHEMAS_ANYATTR_STRICT 3
-
-typedef struct _xmlSchemaAttribute xmlSchemaAttribute;
-typedef xmlSchemaAttribute *xmlSchemaAttributePtr;
-struct _xmlSchemaAttribute {
- xmlSchemaTypeType type; /* The kind of type */
- struct _xmlSchemaAttribute *next;/* the next attribute if in a group ... */
- xmlChar *name;
- xmlChar *id;
- xmlChar *ref;
- xmlChar *refNs;
- xmlChar *typeName;
- xmlChar *typeNs;
- xmlSchemaAnnotPtr annot;
-
- xmlSchemaTypePtr base;
- int occurs;
- xmlChar *defValue;
- xmlSchemaTypePtr subtypes;
-};
-
-/**
- * An attribute group definition.
- *
- * xmlSchemaAttribute and xmlSchemaAttributeGroup start of structures
- * must be kept similar
- */
-typedef struct _xmlSchemaAttributeGroup xmlSchemaAttributeGroup;
-typedef xmlSchemaAttributeGroup *xmlSchemaAttributeGroupPtr;
-struct _xmlSchemaAttributeGroup {
- xmlSchemaTypeType type; /* The kind of type */
- struct _xmlSchemaAttribute *next;/* the next attribute if in a group ... */
- xmlChar *name;
- xmlChar *id;
- xmlChar *ref;
- xmlChar *refNs;
- xmlSchemaAnnotPtr annot;
-
- xmlSchemaAttributePtr attributes;
-};
-
-
-/**
- * XML_SCHEMAS_TYPE_MIXED:
- *
- * the element content type is mixed
- */
-#define XML_SCHEMAS_TYPE_MIXED 1 << 0
-
-/**
- * _xmlSchemaType:
- *
- * Schemas type definition.
- */
-struct _xmlSchemaType {
- xmlSchemaTypeType type; /* The kind of type */
- struct _xmlSchemaType *next;/* the next type if in a sequence ... */
- xmlChar *name;
- xmlChar *id;
- xmlChar *ref;
- xmlChar *refNs;
- xmlSchemaAnnotPtr annot;
- xmlSchemaTypePtr subtypes;
- xmlSchemaAttributePtr attributes;
- xmlNodePtr node;
- int minOccurs;
- int maxOccurs;
-
- int flags;
- xmlSchemaContentType contentType;
- xmlChar *base;
- xmlChar *baseNs;
- xmlSchemaTypePtr baseType;
- xmlSchemaFacetPtr facets;
-};
-
-/**
- * xmlSchemaElement:
- * An element definition.
- *
- * xmlSchemaType, xmlSchemaFacet and xmlSchemaElement start of
- * structures must be kept similar
- */
-/**
- * XML_SCHEMAS_ELEM_NILLABLE:
- *
- * the element is nillable
- */
-#define XML_SCHEMAS_ELEM_NILLABLE 1 << 0
-/**
- * XML_SCHEMAS_ELEM_GLOBAL:
- *
- * the element is global
- */
-#define XML_SCHEMAS_ELEM_GLOBAL 1 << 1
-/**
- * XML_SCHEMAS_ELEM_DEFAULT:
- *
- * the element has a default value
- */
-#define XML_SCHEMAS_ELEM_DEFAULT 1 << 2
-/**
- * XML_SCHEMAS_ELEM_FIXED:
- *
- * the element has a fixed value
- */
-#define XML_SCHEMAS_ELEM_FIXED 1 << 3
-/**
- * XML_SCHEMAS_ELEM_ABSTRACT:
- *
- * the element is abstract
- */
-#define XML_SCHEMAS_ELEM_ABSTRACT 1 << 4
-/**
- * XML_SCHEMAS_ELEM_TOPLEVEL:
- *
- * the element is top level
- */
-#define XML_SCHEMAS_ELEM_TOPLEVEL 1 << 5
-/**
- * XML_SCHEMAS_ELEM_REF:
- *
- * the element is a reference to a type
- */
-#define XML_SCHEMAS_ELEM_REF 1 << 6
-
-typedef struct _xmlSchemaElement xmlSchemaElement;
-typedef xmlSchemaElement *xmlSchemaElementPtr;
-struct _xmlSchemaElement {
- xmlSchemaTypeType type; /* The kind of type */
- struct _xmlSchemaType *next;/* the next type if in a sequence ... */
- xmlChar *name;
- xmlChar *id;
- xmlChar *ref;
- xmlChar *refNs;
- xmlSchemaAnnotPtr annot;
- xmlSchemaTypePtr subtypes;
- xmlSchemaAttributePtr attributes;
- xmlNodePtr node;
- int minOccurs;
- int maxOccurs;
-
- int flags;
- xmlChar *targetNamespace;
- xmlChar *namedType;
- xmlChar *namedTypeNs;
- xmlChar *substGroup;
- xmlChar *substGroupNs;
- xmlChar *scope;
- xmlChar *value;
- struct _xmlSchemaElement *refDecl;
- xmlRegexpPtr contModel;
- xmlSchemaContentType contentType;
-};
-
-/*
- * XML_SCHEMAS_FACET_UNKNOWN:
- *
- * unknown facet handling
- */
-#define XML_SCHEMAS_FACET_UNKNOWN 0
-/*
- * XML_SCHEMAS_FACET_PRESERVE:
- *
- * preserve the type of the facet
- */
-#define XML_SCHEMAS_FACET_PRESERVE 1
-/*
- * XML_SCHEMAS_FACET_REPLACE:
- *
- * replace the type of the facet
- */
-#define XML_SCHEMAS_FACET_REPLACE 2
-/*
- * XML_SCHEMAS_FACET_COLLAPSE:
- *
- * collapse the types of the facet
- */
-#define XML_SCHEMAS_FACET_COLLAPSE 3
-
-/**
- * A facet definition.
- */
-struct _xmlSchemaFacet {
- xmlSchemaTypeType type; /* The kind of type */
- struct _xmlSchemaFacet *next;/* the next type if in a sequence ... */
- xmlChar *value;
- xmlChar *id;
- xmlSchemaAnnotPtr annot;
- xmlNodePtr node;
- int fixed;
- int whitespace;
- xmlSchemaValPtr val;
- xmlRegexpPtr regexp;
-};
-
-/**
- * A notation definition.
- */
-typedef struct _xmlSchemaNotation xmlSchemaNotation;
-typedef xmlSchemaNotation *xmlSchemaNotationPtr;
-struct _xmlSchemaNotation {
- xmlSchemaTypeType type; /* The kind of type */
- xmlChar *name;
- xmlSchemaAnnotPtr annot;
- xmlChar *identifier;
-};
-
-/**
- * XML_SCHEMAS_QUALIF_ELEM:
- *
- * the shemas requires qualified elements
- */
-#define XML_SCHEMAS_QUALIF_ELEM 1 << 0
-/**
- * XML_SCHEMAS_QUALIF_ATTR:
- *
- * the shemas requires qualified attributes
- */
-#define XML_SCHEMAS_QUALIF_ATTR 1 << 1
-/**
- * _xmlSchema:
- *
- * A Schemas definition
- */
-struct _xmlSchema {
- xmlChar *name; /* schema name */
- xmlChar *targetNamespace; /* the target namespace */
- xmlChar *version;
- xmlChar *id;
- xmlDocPtr doc;
- xmlSchemaAnnotPtr annot;
- int flags;
-
- xmlHashTablePtr typeDecl;
- xmlHashTablePtr attrDecl;
- xmlHashTablePtr attrgrpDecl;
- xmlHashTablePtr elemDecl;
- xmlHashTablePtr notaDecl;
-
- xmlHashTablePtr schemasImports;
-
- void *_private; /* unused by the library for users or bindings */
-};
-
-void xmlSchemaFreeType (xmlSchemaTypePtr type);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LIBXML_SCHEMAS_ENABLED */
-#endif /* __XML_SCHEMA_INTERNALS_H__ */
-
-
diff --git a/bundle/libxml/include/libxml/threads.h b/bundle/libxml/include/libxml/threads.h
deleted file mode 100644
index afca78ffe5..0000000000
--- a/bundle/libxml/include/libxml/threads.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * threads.c: set of generic threading related routines
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#ifndef __XML_THREADS_H__
-#define __XML_THREADS_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * xmlMutex are a simple mutual exception locks.
- */
-typedef struct _xmlMutex xmlMutex;
-typedef xmlMutex *xmlMutexPtr;
-
-/*
- * xmlRMutex are reentrant mutual exception locks.
- */
-typedef struct _xmlRMutex xmlRMutex;
-typedef xmlRMutex *xmlRMutexPtr;
-
-#ifdef __cplusplus
-}
-#endif
-#include <libxml/globals.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-xmlMutexPtr xmlNewMutex (void);
-void xmlMutexLock (xmlMutexPtr tok);
-void xmlMutexUnlock (xmlMutexPtr tok);
-void xmlFreeMutex (xmlMutexPtr tok);
-
-xmlRMutexPtr xmlNewRMutex (void);
-void xmlRMutexLock (xmlRMutexPtr tok);
-void xmlRMutexUnlock (xmlRMutexPtr tok);
-void xmlFreeRMutex (xmlRMutexPtr tok);
-
-/*
- * Library wide APIs.
- */
-void xmlInitThreads (void);
-void xmlLockLibrary (void);
-void xmlUnlockLibrary(void);
-int xmlGetThreadId (void);
-int xmlIsMainThread (void);
-void xmlCleanupThreads(void);
-xmlGlobalStatePtr xmlGetGlobalState(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* __XML_THREADS_H__ */
diff --git a/bundle/libxml/include/libxml/tree.h b/bundle/libxml/include/libxml/tree.h
deleted file mode 100644
index 93d57e3126..0000000000
--- a/bundle/libxml/include/libxml/tree.h
+++ /dev/null
@@ -1,894 +0,0 @@
-/*
- * tree.h : describes the structures found in an tree resulting
- * from an XML parsing.
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- *
- */
-
-#ifndef __XML_TREE_H__
-#define __XML_TREE_H__
-
-#include <stdio.h>
-#include <libxml/xmlversion.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Some of the basic types pointer to structures:
- */
-/* xmlIO.h */
-typedef struct _xmlParserInputBuffer xmlParserInputBuffer;
-typedef xmlParserInputBuffer *xmlParserInputBufferPtr;
-
-typedef struct _xmlOutputBuffer xmlOutputBuffer;
-typedef xmlOutputBuffer *xmlOutputBufferPtr;
-
-/* parser.h */
-typedef struct _xmlParserInput xmlParserInput;
-typedef xmlParserInput *xmlParserInputPtr;
-
-typedef struct _xmlParserCtxt xmlParserCtxt;
-typedef xmlParserCtxt *xmlParserCtxtPtr;
-
-typedef struct _xmlSAXLocator xmlSAXLocator;
-typedef xmlSAXLocator *xmlSAXLocatorPtr;
-
-typedef struct _xmlSAXHandler xmlSAXHandler;
-typedef xmlSAXHandler *xmlSAXHandlerPtr;
-
-/* entities.h */
-typedef struct _xmlEntity xmlEntity;
-typedef xmlEntity *xmlEntityPtr;
-
-/**
- * BASE_BUFFER_SIZE:
- *
- * default buffer size 4000.
- */
-#define BASE_BUFFER_SIZE 4000
-
-/**
- * XML_XML_NAMESPACE:
- *
- * This is the namespace for the special xml: prefix predefined in the
- * XML Namespace specification.
- */
-#define XML_XML_NAMESPACE \
- (const xmlChar *) "http://www.w3.org/XML/1998/namespace"
-
-/*
- * The different element types carried by an XML tree.
- *
- * NOTE: This is synchronized with DOM Level1 values
- * See http://www.w3.org/TR/REC-DOM-Level-1/
- *
- * Actually this had diverged a bit, and now XML_DOCUMENT_TYPE_NODE should
- * be deprecated to use an XML_DTD_NODE.
- */
-typedef enum {
- XML_ELEMENT_NODE= 1,
- XML_ATTRIBUTE_NODE= 2,
- XML_TEXT_NODE= 3,
- XML_CDATA_SECTION_NODE= 4,
- XML_ENTITY_REF_NODE= 5,
- XML_ENTITY_NODE= 6,
- XML_PI_NODE= 7,
- XML_COMMENT_NODE= 8,
- XML_DOCUMENT_NODE= 9,
- XML_DOCUMENT_TYPE_NODE= 10,
- XML_DOCUMENT_FRAG_NODE= 11,
- XML_NOTATION_NODE= 12,
- XML_HTML_DOCUMENT_NODE= 13,
- XML_DTD_NODE= 14,
- XML_ELEMENT_DECL= 15,
- XML_ATTRIBUTE_DECL= 16,
- XML_ENTITY_DECL= 17,
- XML_NAMESPACE_DECL= 18,
- XML_XINCLUDE_START= 19,
- XML_XINCLUDE_END= 20
-#ifdef LIBXML_DOCB_ENABLED
- ,XML_DOCB_DOCUMENT_NODE= 21
-#endif
-} xmlElementType;
-
-/**
- * xmlChar:
- *
- * This is a basic byte in an UTF-8 encoded string.
- * It's unsigned allowing to pinpoint case where char * are assigned
- * to xmlChar * (possibly making serialization back impossible).
- */
-
-typedef unsigned char xmlChar;
-
-/**
- * BAD_CAST:
- *
- * Macro to cast a string to an xmlChar * when one know its safe.
- */
-#define BAD_CAST (xmlChar *)
-
-/**
- * xmlNotation:
- *
- * A DTD Notation definition.
- */
-
-typedef struct _xmlNotation xmlNotation;
-typedef xmlNotation *xmlNotationPtr;
-struct _xmlNotation {
- const xmlChar *name; /* Notation name */
- const xmlChar *PublicID; /* Public identifier, if any */
- const xmlChar *SystemID; /* System identifier, if any */
-};
-
-/**
- * xmlAttributeType:
- *
- * A DTD Attribute type definition.
- */
-
-typedef enum {
- XML_ATTRIBUTE_CDATA = 1,
- XML_ATTRIBUTE_ID,
- XML_ATTRIBUTE_IDREF ,
- XML_ATTRIBUTE_IDREFS,
- XML_ATTRIBUTE_ENTITY,
- XML_ATTRIBUTE_ENTITIES,
- XML_ATTRIBUTE_NMTOKEN,
- XML_ATTRIBUTE_NMTOKENS,
- XML_ATTRIBUTE_ENUMERATION,
- XML_ATTRIBUTE_NOTATION
-} xmlAttributeType;
-
-/**
- * xmlAttributeDefault:
- *
- * A DTD Attribute default definition.
- */
-
-typedef enum {
- XML_ATTRIBUTE_NONE = 1,
- XML_ATTRIBUTE_REQUIRED,
- XML_ATTRIBUTE_IMPLIED,
- XML_ATTRIBUTE_FIXED
-} xmlAttributeDefault;
-
-/**
- * xmlEnumeration:
- *
- * List structure used when there is an enumeration in DTDs.
- */
-
-typedef struct _xmlEnumeration xmlEnumeration;
-typedef xmlEnumeration *xmlEnumerationPtr;
-struct _xmlEnumeration {
- struct _xmlEnumeration *next; /* next one */
- const xmlChar *name; /* Enumeration name */
-};
-
-/**
- * xmlAttribute:
- *
- * An Attribute declaration in a DTD.
- */
-
-typedef struct _xmlAttribute xmlAttribute;
-typedef xmlAttribute *xmlAttributePtr;
-struct _xmlAttribute {
- void *_private; /* application data */
- xmlElementType type; /* XML_ATTRIBUTE_DECL, must be second ! */
- const xmlChar *name; /* Attribute name */
- struct _xmlNode *children; /* NULL */
- struct _xmlNode *last; /* NULL */
- struct _xmlDtd *parent; /* -> DTD */
- struct _xmlNode *next; /* next sibling link */
- struct _xmlNode *prev; /* previous sibling link */
- struct _xmlDoc *doc; /* the containing document */
-
- struct _xmlAttribute *nexth; /* next in hash table */
- xmlAttributeType atype; /* The attribute type */
- xmlAttributeDefault def; /* the default */
- const xmlChar *defaultValue; /* or the default value */
- xmlEnumerationPtr tree; /* or the enumeration tree if any */
- const xmlChar *prefix; /* the namespace prefix if any */
- const xmlChar *elem; /* Element holding the attribute */
-};
-
-/**
- * xmlElementContentType:
- *
- * Possible definitions of element content types.
- */
-typedef enum {
- XML_ELEMENT_CONTENT_PCDATA = 1,
- XML_ELEMENT_CONTENT_ELEMENT,
- XML_ELEMENT_CONTENT_SEQ,
- XML_ELEMENT_CONTENT_OR
-} xmlElementContentType;
-
-/**
- * xmlElementContentOccur:
- *
- * Possible definitions of element content occurrences.
- */
-typedef enum {
- XML_ELEMENT_CONTENT_ONCE = 1,
- XML_ELEMENT_CONTENT_OPT,
- XML_ELEMENT_CONTENT_MULT,
- XML_ELEMENT_CONTENT_PLUS
-} xmlElementContentOccur;
-
-/**
- * xmlElementContent:
- *
- * An XML Element content as stored after parsing an element definition
- * in a DTD.
- */
-
-typedef struct _xmlElementContent xmlElementContent;
-typedef xmlElementContent *xmlElementContentPtr;
-struct _xmlElementContent {
- xmlElementContentType type; /* PCDATA, ELEMENT, SEQ or OR */
- xmlElementContentOccur ocur; /* ONCE, OPT, MULT or PLUS */
- const xmlChar *name; /* Element name */
- struct _xmlElementContent *c1; /* first child */
- struct _xmlElementContent *c2; /* second child */
- struct _xmlElementContent *parent; /* parent */
- const xmlChar *prefix; /* Namespace prefix */
-};
-
-/**
- * xmlElementTypeVal:
- *
- * The different possibilities for an element content type.
- */
-
-typedef enum {
- XML_ELEMENT_TYPE_UNDEFINED = 0,
- XML_ELEMENT_TYPE_EMPTY = 1,
- XML_ELEMENT_TYPE_ANY,
- XML_ELEMENT_TYPE_MIXED,
- XML_ELEMENT_TYPE_ELEMENT
-} xmlElementTypeVal;
-
-
-#ifdef __cplusplus
-}
-#endif
-#include <libxml/xmlregexp.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * xmlElement:
- *
- * An XML Element declaration from a DTD.
- */
-
-typedef struct _xmlElement xmlElement;
-typedef xmlElement *xmlElementPtr;
-struct _xmlElement {
- void *_private; /* application data */
- xmlElementType type; /* XML_ELEMENT_DECL, must be second ! */
- const xmlChar *name; /* Element name */
- struct _xmlNode *children; /* NULL */
- struct _xmlNode *last; /* NULL */
- struct _xmlDtd *parent; /* -> DTD */
- struct _xmlNode *next; /* next sibling link */
- struct _xmlNode *prev; /* previous sibling link */
- struct _xmlDoc *doc; /* the containing document */
-
- xmlElementTypeVal etype; /* The type */
- xmlElementContentPtr content; /* the allowed element content */
- xmlAttributePtr attributes; /* List of the declared attributes */
- const xmlChar *prefix; /* the namespace prefix if any */
-#ifdef LIBXML_REGEXP_ENABLED
- xmlRegexpPtr contModel; /* the validating regexp */
-#else
- void *contModel;
-#endif
-};
-
-
-/**
- * XML_LOCAL_NAMESPACE:
- *
- * A namespace declaration node.
- */
-#define XML_LOCAL_NAMESPACE XML_NAMESPACE_DECL
-typedef xmlElementType xmlNsType;
-
-/**
- * xmlNs:
- *
- * An XML namespace.
- * Note that prefix == NULL is valid, it defines the default namespace
- * within the subtree (until overridden).
- *
- * xmlNsType is unified with xmlElementType.
- */
-
-typedef struct _xmlNs xmlNs;
-typedef xmlNs *xmlNsPtr;
-struct _xmlNs {
- struct _xmlNs *next; /* next Ns link for this node */
- xmlNsType type; /* global or local */
- const xmlChar *href; /* URL for the namespace */
- const xmlChar *prefix; /* prefix for the namespace */
- void *_private; /* application data */
-};
-
-/**
- * xmlDtd:
- *
- * An XML DTD, as defined by <!DOCTYPE ... There is actually one for
- * the internal subset and for the external subset.
- */
-typedef struct _xmlDtd xmlDtd;
-typedef xmlDtd *xmlDtdPtr;
-struct _xmlDtd {
- void *_private; /* application data */
- xmlElementType type; /* XML_DTD_NODE, must be second ! */
- const xmlChar *name; /* Name of the DTD */
- struct _xmlNode *children; /* the value of the property link */
- struct _xmlNode *last; /* last child link */
- struct _xmlDoc *parent; /* child->parent link */
- struct _xmlNode *next; /* next sibling link */
- struct _xmlNode *prev; /* previous sibling link */
- struct _xmlDoc *doc; /* the containing document */
-
- /* End of common part */
- void *notations; /* Hash table for notations if any */
- void *elements; /* Hash table for elements if any */
- void *attributes; /* Hash table for attributes if any */
- void *entities; /* Hash table for entities if any */
- const xmlChar *ExternalID; /* External identifier for PUBLIC DTD */
- const xmlChar *SystemID; /* URI for a SYSTEM or PUBLIC DTD */
- void *pentities; /* Hash table for param entities if any */
-};
-
-/**
- * xmlAttr:
- *
- * An attribute on an XML node.
- */
-typedef struct _xmlAttr xmlAttr;
-typedef xmlAttr *xmlAttrPtr;
-struct _xmlAttr {
- void *_private; /* application data */
- xmlElementType type; /* XML_ATTRIBUTE_NODE, must be second ! */
- const xmlChar *name; /* the name of the property */
- struct _xmlNode *children; /* the value of the property */
- struct _xmlNode *last; /* NULL */
- struct _xmlNode *parent; /* child->parent link */
- struct _xmlAttr *next; /* next sibling link */
- struct _xmlAttr *prev; /* previous sibling link */
- struct _xmlDoc *doc; /* the containing document */
- xmlNs *ns; /* pointer to the associated namespace */
- xmlAttributeType atype; /* the attribute type if validating */
-};
-
-/**
- * xmlID:
- *
- * An XML ID instance.
- */
-
-typedef struct _xmlID xmlID;
-typedef xmlID *xmlIDPtr;
-struct _xmlID {
- struct _xmlID *next; /* next ID */
- const xmlChar *value; /* The ID name */
- xmlAttrPtr attr; /* The attribute holding it */
-};
-
-/**
- * xmlRef:
- *
- * An XML IDREF instance.
- */
-
-typedef struct _xmlRef xmlRef;
-typedef xmlRef *xmlRefPtr;
-struct _xmlRef {
- struct _xmlRef *next; /* next Ref */
- const xmlChar *value; /* The Ref name */
- xmlAttrPtr attr; /* The attribute holding it */
-};
-
-/**
- * xmlBufferAllocationScheme:
- *
- * A buffer allocation scheme can be defined to either match exactly the
- * need or double it's allocated size each time it is found too small.
- */
-
-typedef enum {
- XML_BUFFER_ALLOC_DOUBLEIT,
- XML_BUFFER_ALLOC_EXACT
-} xmlBufferAllocationScheme;
-
-/**
- * xmlBuffer:
- *
- * A buffer structure.
- */
-typedef struct _xmlBuffer xmlBuffer;
-typedef xmlBuffer *xmlBufferPtr;
-struct _xmlBuffer {
- xmlChar *content; /* The buffer content UTF8 */
- unsigned int use; /* The buffer size used */
- unsigned int size; /* The buffer size */
- xmlBufferAllocationScheme alloc; /* The realloc method */
-};
-
-/**
- * xmlNode:
- *
- * A node in an XML tree.
- */
-typedef struct _xmlNode xmlNode;
-typedef xmlNode *xmlNodePtr;
-struct _xmlNode {
- void *_private; /* application data */
- xmlElementType type; /* type number, must be second ! */
- const xmlChar *name; /* the name of the node, or the entity */
- struct _xmlNode *children; /* parent->childs link */
- struct _xmlNode *last; /* last child link */
- struct _xmlNode *parent; /* child->parent link */
- struct _xmlNode *next; /* next sibling link */
- struct _xmlNode *prev; /* previous sibling link */
- struct _xmlDoc *doc; /* the containing document */
-
- /* End of common part */
- xmlNs *ns; /* pointer to the associated namespace */
- xmlChar *content; /* the content */
- struct _xmlAttr *properties;/* properties list */
- xmlNs *nsDef; /* namespace definitions on this node */
-};
-
-/**
- * XML_GET_CONTENT:
- *
- * Macro to extract the content pointer of a node.
- */
-#define XML_GET_CONTENT(n) \
- ((n)->type == XML_ELEMENT_NODE ? NULL : (n)->content)
-
-/**
- * XML_GET_LINE:
- *
- * Macro to extract the line number of an element node.
- * This will work only if line numbering is activated by
- * calling xmlLineNumbersDefault(1) before parsing.
- */
-#define XML_GET_LINE(n) \
- ((n)->type == XML_ELEMENT_NODE ? (int) (n)->content : 0)
-
-/**
- * xmlDoc:
- *
- * An XML document.
- */
-typedef struct _xmlDoc xmlDoc;
-typedef xmlDoc *xmlDocPtr;
-struct _xmlDoc {
- void *_private; /* application data */
- xmlElementType type; /* XML_DOCUMENT_NODE, must be second ! */
- char *name; /* name/filename/URI of the document */
- struct _xmlNode *children; /* the document tree */
- struct _xmlNode *last; /* last child link */
- struct _xmlNode *parent; /* child->parent link */
- struct _xmlNode *next; /* next sibling link */
- struct _xmlNode *prev; /* previous sibling link */
- struct _xmlDoc *doc; /* autoreference to itself */
-
- /* End of common part */
- int compression;/* level of zlib compression */
- int standalone; /* standalone document (no external refs) */
- struct _xmlDtd *intSubset; /* the document internal subset */
- struct _xmlDtd *extSubset; /* the document external subset */
- struct _xmlNs *oldNs; /* Global namespace, the old way */
- const xmlChar *version; /* the XML version string */
- const xmlChar *encoding; /* external initial encoding, if any */
- void *ids; /* Hash table for ID attributes if any */
- void *refs; /* Hash table for IDREFs attributes if any */
- const xmlChar *URL; /* The URI for that document */
- int charset; /* encoding of the in-memory content
- actually an xmlCharEncoding */
-};
-
-/**
- * xmlChildrenNode:
- *
- * Macro for compatibility naming layer with libxml1.
- */
-#ifndef xmlChildrenNode
-#define xmlChildrenNode children
-#endif
-
-/**
- * xmlRootNode:
- *
- * Macro for compatibility naming layer with libxml1.
- */
-#ifndef xmlRootNode
-#define xmlRootNode children
-#endif
-
-/*
- * Variables.
- */
-#if 0
-LIBXML_DLL_IMPORT extern int oldXMLWDcompatibility;/* maintain compatibility with old WD */
-LIBXML_DLL_IMPORT extern int xmlIndentTreeOutput; /* try to indent the tree dumps */
-LIBXML_DLL_IMPORT extern xmlBufferAllocationScheme xmlBufferAllocScheme; /* alloc scheme to use */
-LIBXML_DLL_IMPORT extern int xmlSaveNoEmptyTags; /* save empty tags as <empty></empty> */
-LIBXML_DLL_IMPORT extern int xmlDefaultBufferSize; /* default buffer size */
-#endif
-
-/*
- * Handling Buffers.
- */
-
-void xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme);
-xmlBufferAllocationScheme xmlGetBufferAllocationScheme(void);
-
-xmlBufferPtr xmlBufferCreate (void);
-xmlBufferPtr xmlBufferCreateSize (size_t size);
-int xmlBufferResize (xmlBufferPtr buf,
- unsigned int size);
-void xmlBufferFree (xmlBufferPtr buf);
-int xmlBufferDump (FILE *file,
- xmlBufferPtr buf);
-void xmlBufferAdd (xmlBufferPtr buf,
- const xmlChar *str,
- int len);
-void xmlBufferAddHead (xmlBufferPtr buf,
- const xmlChar *str,
- int len);
-void xmlBufferCat (xmlBufferPtr buf,
- const xmlChar *str);
-void xmlBufferCCat (xmlBufferPtr buf,
- const char *str);
-int xmlBufferShrink (xmlBufferPtr buf,
- unsigned int len);
-int xmlBufferGrow (xmlBufferPtr buf,
- unsigned int len);
-void xmlBufferEmpty (xmlBufferPtr buf);
-const xmlChar* xmlBufferContent (const xmlBufferPtr buf);
-void xmlBufferSetAllocationScheme(xmlBufferPtr buf,
- xmlBufferAllocationScheme scheme);
-int xmlBufferLength (const xmlBufferPtr buf);
-
-/*
- * Creating/freeing new structures.
- */
-xmlDtdPtr xmlCreateIntSubset (xmlDocPtr doc,
- const xmlChar *name,
- const xmlChar *ExternalID,
- const xmlChar *SystemID);
-xmlDtdPtr xmlNewDtd (xmlDocPtr doc,
- const xmlChar *name,
- const xmlChar *ExternalID,
- const xmlChar *SystemID);
-xmlDtdPtr xmlGetIntSubset (xmlDocPtr doc);
-void xmlFreeDtd (xmlDtdPtr cur);
-xmlNsPtr xmlNewGlobalNs (xmlDocPtr doc,
- const xmlChar *href,
- const xmlChar *prefix);
-xmlNsPtr xmlNewNs (xmlNodePtr node,
- const xmlChar *href,
- const xmlChar *prefix);
-void xmlFreeNs (xmlNsPtr cur);
-void xmlFreeNsList (xmlNsPtr cur);
-xmlDocPtr xmlNewDoc (const xmlChar *version);
-void xmlFreeDoc (xmlDocPtr cur);
-xmlAttrPtr xmlNewDocProp (xmlDocPtr doc,
- const xmlChar *name,
- const xmlChar *value);
-xmlAttrPtr xmlNewProp (xmlNodePtr node,
- const xmlChar *name,
- const xmlChar *value);
-xmlAttrPtr xmlNewNsProp (xmlNodePtr node,
- xmlNsPtr ns,
- const xmlChar *name,
- const xmlChar *value);
-xmlAttrPtr xmlNewNsPropEatName (xmlNodePtr node,
- xmlNsPtr ns,
- xmlChar *name,
- const xmlChar *value);
-void xmlFreePropList (xmlAttrPtr cur);
-void xmlFreeProp (xmlAttrPtr cur);
-xmlAttrPtr xmlCopyProp (xmlNodePtr target,
- xmlAttrPtr cur);
-xmlAttrPtr xmlCopyPropList (xmlNodePtr target,
- xmlAttrPtr cur);
-xmlDtdPtr xmlCopyDtd (xmlDtdPtr dtd);
-xmlDocPtr xmlCopyDoc (xmlDocPtr doc,
- int recursive);
-
-/*
- * Creating new nodes.
- */
-xmlNodePtr xmlNewDocNode (xmlDocPtr doc,
- xmlNsPtr ns,
- const xmlChar *name,
- const xmlChar *content);
-xmlNodePtr xmlNewDocNodeEatName (xmlDocPtr doc,
- xmlNsPtr ns,
- xmlChar *name,
- const xmlChar *content);
-xmlNodePtr xmlNewDocRawNode (xmlDocPtr doc,
- xmlNsPtr ns,
- const xmlChar *name,
- const xmlChar *content);
-xmlNodePtr xmlNewNode (xmlNsPtr ns,
- const xmlChar *name);
-xmlNodePtr xmlNewNodeEatName (xmlNsPtr ns,
- xmlChar *name);
-xmlNodePtr xmlNewChild (xmlNodePtr parent,
- xmlNsPtr ns,
- const xmlChar *name,
- const xmlChar *content);
-xmlNodePtr xmlNewTextChild (xmlNodePtr parent,
- xmlNsPtr ns,
- const xmlChar *name,
- const xmlChar *content);
-xmlNodePtr xmlNewDocText (xmlDocPtr doc,
- const xmlChar *content);
-xmlNodePtr xmlNewText (const xmlChar *content);
-xmlNodePtr xmlNewPI (const xmlChar *name,
- const xmlChar *content);
-xmlNodePtr xmlNewDocTextLen (xmlDocPtr doc,
- const xmlChar *content,
- int len);
-xmlNodePtr xmlNewTextLen (const xmlChar *content,
- int len);
-xmlNodePtr xmlNewDocComment (xmlDocPtr doc,
- const xmlChar *content);
-xmlNodePtr xmlNewComment (const xmlChar *content);
-xmlNodePtr xmlNewCDataBlock (xmlDocPtr doc,
- const xmlChar *content,
- int len);
-xmlNodePtr xmlNewCharRef (xmlDocPtr doc,
- const xmlChar *name);
-xmlNodePtr xmlNewReference (xmlDocPtr doc,
- const xmlChar *name);
-xmlNodePtr xmlCopyNode (const xmlNodePtr node,
- int recursive);
-xmlNodePtr xmlDocCopyNode (const xmlNodePtr node,
- xmlDocPtr doc,
- int recursive);
-xmlNodePtr xmlCopyNodeList (const xmlNodePtr node);
-xmlNodePtr xmlNewDocFragment (xmlDocPtr doc);
-
-/*
- * Navigating.
- */
-long xmlGetLineNo (xmlNodePtr node);
-xmlChar * xmlGetNodePath (xmlNodePtr node);
-xmlNodePtr xmlDocGetRootElement (xmlDocPtr doc);
-xmlNodePtr xmlGetLastChild (xmlNodePtr parent);
-int xmlNodeIsText (xmlNodePtr node);
-int xmlIsBlankNode (xmlNodePtr node);
-
-/*
- * Changing the structure.
- */
-xmlNodePtr xmlDocSetRootElement (xmlDocPtr doc,
- xmlNodePtr root);
-void xmlNodeSetName (xmlNodePtr cur,
- const xmlChar *name);
-xmlNodePtr xmlAddChild (xmlNodePtr parent,
- xmlNodePtr cur);
-xmlNodePtr xmlAddChildList (xmlNodePtr parent,
- xmlNodePtr cur);
-xmlNodePtr xmlReplaceNode (xmlNodePtr old,
- xmlNodePtr cur);
-xmlNodePtr xmlAddSibling (xmlNodePtr cur,
- xmlNodePtr elem);
-xmlNodePtr xmlAddPrevSibling (xmlNodePtr cur,
- xmlNodePtr elem);
-xmlNodePtr xmlAddNextSibling (xmlNodePtr cur,
- xmlNodePtr elem);
-void xmlUnlinkNode (xmlNodePtr cur);
-xmlNodePtr xmlTextMerge (xmlNodePtr first,
- xmlNodePtr second);
-void xmlTextConcat (xmlNodePtr node,
- const xmlChar *content,
- int len);
-void xmlFreeNodeList (xmlNodePtr cur);
-void xmlFreeNode (xmlNodePtr cur);
-void xmlSetTreeDoc (xmlNodePtr tree,
- xmlDocPtr doc);
-void xmlSetListDoc (xmlNodePtr list,
- xmlDocPtr doc);
-
-/*
- * Namespaces.
- */
-xmlNsPtr xmlSearchNs (xmlDocPtr doc,
- xmlNodePtr node,
- const xmlChar *nameSpace);
-xmlNsPtr xmlSearchNsByHref (xmlDocPtr doc,
- xmlNodePtr node,
- const xmlChar *href);
-xmlNsPtr * xmlGetNsList (xmlDocPtr doc,
- xmlNodePtr node);
-void xmlSetNs (xmlNodePtr node,
- xmlNsPtr ns);
-xmlNsPtr xmlCopyNamespace (xmlNsPtr cur);
-xmlNsPtr xmlCopyNamespaceList (xmlNsPtr cur);
-
-/*
- * Changing the content.
- */
-xmlAttrPtr xmlSetProp (xmlNodePtr node,
- const xmlChar *name,
- const xmlChar *value);
-xmlChar * xmlGetProp (xmlNodePtr node,
- const xmlChar *name);
-xmlAttrPtr xmlHasProp (xmlNodePtr node,
- const xmlChar *name);
-xmlAttrPtr xmlHasNsProp (xmlNodePtr node,
- const xmlChar *name,
- const xmlChar *nameSpace);
-xmlAttrPtr xmlSetNsProp (xmlNodePtr node,
- xmlNsPtr ns,
- const xmlChar *name,
- const xmlChar *value);
-xmlChar * xmlGetNsProp (xmlNodePtr node,
- const xmlChar *name,
- const xmlChar *nameSpace);
-xmlNodePtr xmlStringGetNodeList (xmlDocPtr doc,
- const xmlChar *value);
-xmlNodePtr xmlStringLenGetNodeList (xmlDocPtr doc,
- const xmlChar *value,
- int len);
-xmlChar * xmlNodeListGetString (xmlDocPtr doc,
- xmlNodePtr list,
- int inLine);
-xmlChar * xmlNodeListGetRawString (xmlDocPtr doc,
- xmlNodePtr list,
- int inLine);
-void xmlNodeSetContent (xmlNodePtr cur,
- const xmlChar *content);
-void xmlNodeSetContentLen (xmlNodePtr cur,
- const xmlChar *content,
- int len);
-void xmlNodeAddContent (xmlNodePtr cur,
- const xmlChar *content);
-void xmlNodeAddContentLen (xmlNodePtr cur,
- const xmlChar *content,
- int len);
-xmlChar * xmlNodeGetContent (xmlNodePtr cur);
-xmlChar * xmlNodeGetLang (xmlNodePtr cur);
-void xmlNodeSetLang (xmlNodePtr cur,
- const xmlChar *lang);
-int xmlNodeGetSpacePreserve (xmlNodePtr cur);
-void xmlNodeSetSpacePreserve (xmlNodePtr cur,
- int val);
-xmlChar * xmlNodeGetBase (xmlDocPtr doc,
- xmlNodePtr cur);
-void xmlNodeSetBase (xmlNodePtr cur,
- xmlChar *uri);
-
-/*
- * Removing content.
- */
-int xmlRemoveProp (xmlAttrPtr cur);
-int xmlUnsetProp (xmlNodePtr node,
- const xmlChar *name);
-int xmlUnsetNsProp (xmlNodePtr node,
- xmlNsPtr ns,
- const xmlChar *name);
-
-/*
- * Internal, don't use.
- */
-void xmlBufferWriteCHAR (xmlBufferPtr buf,
- const xmlChar *string);
-void xmlBufferWriteChar (xmlBufferPtr buf,
- const char *string);
-void xmlBufferWriteQuotedString(xmlBufferPtr buf,
- const xmlChar *string);
-
-/*
- * Namespace handling.
- */
-int xmlReconciliateNs (xmlDocPtr doc,
- xmlNodePtr tree);
-
-/*
- * Saving.
- */
-void xmlDocDumpFormatMemory (xmlDocPtr cur,
- xmlChar **mem,
- int *size,
- int format);
-void xmlDocDumpMemory (xmlDocPtr cur,
- xmlChar **mem,
- int *size);
-void xmlDocDumpMemoryEnc (xmlDocPtr out_doc,
- xmlChar **doc_txt_ptr,
- int * doc_txt_len,
- const char *txt_encoding);
-void xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc,
- xmlChar **doc_txt_ptr,
- int * doc_txt_len,
- const char *txt_encoding,
- int format);
-int xmlDocFormatDump(FILE *f,
- xmlDocPtr cur,
- int format);
-int xmlDocDump (FILE *f,
- xmlDocPtr cur);
-void xmlElemDump (FILE *f,
- xmlDocPtr doc,
- xmlNodePtr cur);
-int xmlSaveFile (const char *filename,
- xmlDocPtr cur);
-int xmlSaveFormatFile (const char *filename,
- xmlDocPtr cur,
- int format);
-int xmlNodeDump (xmlBufferPtr buf,
- xmlDocPtr doc,
- xmlNodePtr cur,
- int level,
- int format);
-
-int xmlSaveFileTo (xmlOutputBufferPtr buf,
- xmlDocPtr cur,
- const char *encoding);
-int xmlSaveFormatFileTo (xmlOutputBufferPtr buf,
- xmlDocPtr cur,
- const char *encoding,
- int format);
-void xmlNodeDumpOutput (xmlOutputBufferPtr buf,
- xmlDocPtr doc,
- xmlNodePtr cur,
- int level,
- int format,
- const char *encoding);
-
-int xmlSaveFormatFileEnc (const char *filename,
- xmlDocPtr cur,
- const char *encoding,
- int format);
-
-int xmlSaveFileEnc (const char *filename,
- xmlDocPtr cur,
- const char *encoding);
-
-/*
- * XHTML
- */
-int xmlIsXHTML (const xmlChar *systemID,
- const xmlChar *publicID);
-
-/*
- * Compression.
- */
-int xmlGetDocCompressMode (xmlDocPtr doc);
-void xmlSetDocCompressMode (xmlDocPtr doc,
- int mode);
-int xmlGetCompressMode (void);
-void xmlSetCompressMode (int mode);
-
-#ifdef __cplusplus
-}
-#endif
-#ifndef __XML_PARSER_H__
-#include <libxml/xmlmemory.h>
-#endif
-
-#endif /* __XML_TREE_H__ */
-
diff --git a/bundle/libxml/include/libxml/uri.h b/bundle/libxml/include/libxml/uri.h
deleted file mode 100644
index 8ca7dad981..0000000000
--- a/bundle/libxml/include/libxml/uri.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * uri.c: library of generic URI related routines
- *
- * Reference: RFC 2396
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#ifndef __XML_URI_H__
-#define __XML_URI_H__
-
-#include <libxml/tree.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * xmlURI:
- *
- * A parsed URI reference. This is a struct containing the various fields
- * as described in RFC 2396 but separated for further processing.
- */
-typedef struct _xmlURI xmlURI;
-typedef xmlURI *xmlURIPtr;
-struct _xmlURI {
- char *scheme; /* the URI scheme */
- char *opaque; /* opaque part */
- char *authority; /* the authority part */
- char *server; /* the server part */
- char *user; /* the user part */
- int port; /* the port number */
- char *path; /* the path string */
- char *query; /* the query string */
- char *fragment; /* the fragment identifier */
- int cleanup; /* parsing potentially unclean URI */
-};
-
-/*
- * This function is in tree.h:
- * xmlChar * xmlNodeGetBase (xmlDocPtr doc,
- * xmlNodePtr cur);
- */
-xmlURIPtr xmlCreateURI (void);
-xmlChar * xmlBuildURI (const xmlChar *URI,
- const xmlChar *base);
-xmlURIPtr xmlParseURI (const char *str);
-int xmlParseURIReference (xmlURIPtr uri,
- const char *str);
-xmlChar * xmlSaveUri (xmlURIPtr uri);
-void xmlPrintURI (FILE *stream,
- xmlURIPtr uri);
-xmlChar * xmlURIEscapeStr (const xmlChar *str,
- const xmlChar *list);
-char * xmlURIUnescapeString (const char *str,
- int len,
- char *target);
-int xmlNormalizeURIPath (char *path);
-xmlChar * xmlURIEscape (const xmlChar *str);
-void xmlFreeURI (xmlURIPtr uri);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* __XML_URI_H__ */
diff --git a/bundle/libxml/include/libxml/valid.h b/bundle/libxml/include/libxml/valid.h
deleted file mode 100644
index 4cc5f9788d..0000000000
--- a/bundle/libxml/include/libxml/valid.h
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * valid.h : interface to the DTD handling and the validity checking
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-
-#ifndef __XML_VALID_H__
-#define __XML_VALID_H__
-
-#include <libxml/tree.h>
-#include <libxml/list.h>
-#include <libxml/xmlautomata.h>
-#include <libxml/xmlregexp.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Validation state added for non-determinist content model.
- */
-typedef struct _xmlValidState xmlValidState;
-typedef xmlValidState *xmlValidStatePtr;
-
-/**
- * xmlValidityErrorFunc:
- * @ctx: an xmlValidCtxtPtr validity error context
- * @msg: the string to format *printf like vararg
- * @...: remaining arguments to the format
- *
- * Callback called when a validity error is found. This is a message
- * oriented function similar to an *printf function.
- */
-typedef void (*xmlValidityErrorFunc) (void *ctx,
- const char *msg,
- ...);
-
-/**
- * xmlValidityWarningFunc:
- * @ctx: an xmlValidCtxtPtr validity error context
- * @msg: the string to format *printf like vararg
- * @...: remaining arguments to the format
- *
- * Callback called when a validity warning is found. This is a message
- * oriented function similar to an *printf function.
- */
-typedef void (*xmlValidityWarningFunc) (void *ctx,
- const char *msg,
- ...);
-
-/**
- * xmlValidCtxt:
- * An xmlValidCtxt is used for error reporting when validating.
- */
-typedef struct _xmlValidCtxt xmlValidCtxt;
-typedef xmlValidCtxt *xmlValidCtxtPtr;
-struct _xmlValidCtxt {
- void *userData; /* user specific data block */
- xmlValidityErrorFunc error; /* the callback in case of errors */
- xmlValidityWarningFunc warning; /* the callback in case of warning */
-
- /* Node analysis stack used when validating within entities */
- xmlNodePtr node; /* Current parsed Node */
- int nodeNr; /* Depth of the parsing stack */
- int nodeMax; /* Max depth of the parsing stack */
- xmlNodePtr *nodeTab; /* array of nodes */
-
- int finishDtd; /* finished validating the Dtd ? */
- xmlDocPtr doc; /* the document */
- int valid; /* temporary validity check result */
-
- /* state state used for non-determinist content validation */
- xmlValidState *vstate; /* current state */
- int vstateNr; /* Depth of the validation stack */
- int vstateMax; /* Max depth of the validation stack */
- xmlValidState *vstateTab; /* array of validation states */
-
-#ifdef LIBXML_REGEXP_ENABLED
- xmlAutomataPtr am; /* the automata */
- xmlAutomataStatePtr state; /* used to build the automata */
-#else
- void *am;
- void *state;
-#endif
-};
-
-/*
- * ALL notation declarations are stored in a table.
- * There is one table per DTD.
- */
-
-typedef struct _xmlHashTable xmlNotationTable;
-typedef xmlNotationTable *xmlNotationTablePtr;
-
-/*
- * ALL element declarations are stored in a table.
- * There is one table per DTD.
- */
-
-typedef struct _xmlHashTable xmlElementTable;
-typedef xmlElementTable *xmlElementTablePtr;
-
-/*
- * ALL attribute declarations are stored in a table.
- * There is one table per DTD.
- */
-
-typedef struct _xmlHashTable xmlAttributeTable;
-typedef xmlAttributeTable *xmlAttributeTablePtr;
-
-/*
- * ALL IDs attributes are stored in a table.
- * There is one table per document.
- */
-
-typedef struct _xmlHashTable xmlIDTable;
-typedef xmlIDTable *xmlIDTablePtr;
-
-/*
- * ALL Refs attributes are stored in a table.
- * There is one table per document.
- */
-
-typedef struct _xmlHashTable xmlRefTable;
-typedef xmlRefTable *xmlRefTablePtr;
-
-/* helper */
-xmlChar * xmlSplitQName2 (const xmlChar *name,
- xmlChar **prefix);
-
-/* Notation */
-xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
- xmlDtdPtr dtd,
- const xmlChar *name,
- const xmlChar *PublicID,
- const xmlChar *SystemID);
-xmlNotationTablePtr xmlCopyNotationTable(xmlNotationTablePtr table);
-void xmlFreeNotationTable(xmlNotationTablePtr table);
-void xmlDumpNotationDecl (xmlBufferPtr buf,
- xmlNotationPtr nota);
-void xmlDumpNotationTable(xmlBufferPtr buf,
- xmlNotationTablePtr table);
-
-/* Element Content */
-xmlElementContentPtr xmlNewElementContent (xmlChar *name,
- xmlElementContentType type);
-xmlElementContentPtr xmlCopyElementContent(xmlElementContentPtr content);
-void xmlFreeElementContent(xmlElementContentPtr cur);
-void xmlSnprintfElementContent(char *buf,
- int size,
- xmlElementContentPtr content,
- int glob);
-/* DEPRECATED */
-void xmlSprintfElementContent(char *buf,
- xmlElementContentPtr content,
- int glob);
-/* DEPRECATED */
-
-/* Element */
-xmlElementPtr xmlAddElementDecl (xmlValidCtxtPtr ctxt,
- xmlDtdPtr dtd,
- const xmlChar *name,
- xmlElementTypeVal type,
- xmlElementContentPtr content);
-xmlElementTablePtr xmlCopyElementTable (xmlElementTablePtr table);
-void xmlFreeElementTable (xmlElementTablePtr table);
-void xmlDumpElementTable (xmlBufferPtr buf,
- xmlElementTablePtr table);
-void xmlDumpElementDecl (xmlBufferPtr buf,
- xmlElementPtr elem);
-
-/* Enumeration */
-xmlEnumerationPtr xmlCreateEnumeration (xmlChar *name);
-void xmlFreeEnumeration (xmlEnumerationPtr cur);
-xmlEnumerationPtr xmlCopyEnumeration (xmlEnumerationPtr cur);
-
-/* Attribute */
-xmlAttributePtr xmlAddAttributeDecl (xmlValidCtxtPtr ctxt,
- xmlDtdPtr dtd,
- const xmlChar *elem,
- const xmlChar *name,
- const xmlChar *ns,
- xmlAttributeType type,
- xmlAttributeDefault def,
- const xmlChar *defaultValue,
- xmlEnumerationPtr tree);
-xmlAttributeTablePtr xmlCopyAttributeTable (xmlAttributeTablePtr table);
-void xmlFreeAttributeTable (xmlAttributeTablePtr table);
-void xmlDumpAttributeTable (xmlBufferPtr buf,
- xmlAttributeTablePtr table);
-void xmlDumpAttributeDecl (xmlBufferPtr buf,
- xmlAttributePtr attr);
-
-/* IDs */
-xmlIDPtr xmlAddID (xmlValidCtxtPtr ctxt,
- xmlDocPtr doc,
- const xmlChar *value,
- xmlAttrPtr attr);
-void xmlFreeIDTable (xmlIDTablePtr table);
-xmlAttrPtr xmlGetID (xmlDocPtr doc,
- const xmlChar *ID);
-int xmlIsID (xmlDocPtr doc,
- xmlNodePtr elem,
- xmlAttrPtr attr);
-int xmlRemoveID (xmlDocPtr doc, xmlAttrPtr attr);
-
-/* IDREFs */
-xmlRefPtr xmlAddRef (xmlValidCtxtPtr ctxt,
- xmlDocPtr doc,
- const xmlChar *value,
- xmlAttrPtr attr);
-void xmlFreeRefTable (xmlRefTablePtr table);
-int xmlIsRef (xmlDocPtr doc,
- xmlNodePtr elem,
- xmlAttrPtr attr);
-int xmlRemoveRef (xmlDocPtr doc, xmlAttrPtr attr);
-xmlListPtr xmlGetRefs (xmlDocPtr doc,
- const xmlChar *ID);
-
-/**
- * The public function calls related to validity checking.
- */
-
-int xmlValidateRoot (xmlValidCtxtPtr ctxt,
- xmlDocPtr doc);
-int xmlValidateElementDecl (xmlValidCtxtPtr ctxt,
- xmlDocPtr doc,
- xmlElementPtr elem);
-xmlChar * xmlValidNormalizeAttributeValue(xmlDocPtr doc,
- xmlNodePtr elem,
- const xmlChar *name,
- const xmlChar *value);
-xmlChar * xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt,
- xmlDocPtr doc,
- xmlNodePtr elem,
- const xmlChar *name,
- const xmlChar *value);
-int xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt,
- xmlDocPtr doc,
- xmlAttributePtr attr);
-int xmlValidateAttributeValue(xmlAttributeType type,
- const xmlChar *value);
-int xmlValidateNotationDecl (xmlValidCtxtPtr ctxt,
- xmlDocPtr doc,
- xmlNotationPtr nota);
-int xmlValidateDtd (xmlValidCtxtPtr ctxt,
- xmlDocPtr doc,
- xmlDtdPtr dtd);
-int xmlValidateDtdFinal (xmlValidCtxtPtr ctxt,
- xmlDocPtr doc);
-int xmlValidateDocument (xmlValidCtxtPtr ctxt,
- xmlDocPtr doc);
-int xmlValidateElement (xmlValidCtxtPtr ctxt,
- xmlDocPtr doc,
- xmlNodePtr elem);
-int xmlValidateOneElement (xmlValidCtxtPtr ctxt,
- xmlDocPtr doc,
- xmlNodePtr elem);
-int xmlValidateOneAttribute (xmlValidCtxtPtr ctxt,
- xmlDocPtr doc,
- xmlNodePtr elem,
- xmlAttrPtr attr,
- const xmlChar *value);
-int xmlValidateOneNamespace (xmlValidCtxtPtr ctxt,
- xmlDocPtr doc,
- xmlNodePtr elem,
- const xmlChar *prefix,
- xmlNsPtr ns,
- const xmlChar *value);
-int xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt,
- xmlDocPtr doc);
-int xmlValidateNotationUse (xmlValidCtxtPtr ctxt,
- xmlDocPtr doc,
- const xmlChar *notationName);
-int xmlIsMixedElement (xmlDocPtr doc,
- const xmlChar *name);
-xmlAttributePtr xmlGetDtdAttrDesc (xmlDtdPtr dtd,
- const xmlChar *elem,
- const xmlChar *name);
-xmlAttributePtr xmlGetDtdQAttrDesc (xmlDtdPtr dtd,
- const xmlChar *elem,
- const xmlChar *name,
- const xmlChar *prefix);
-xmlNotationPtr xmlGetDtdNotationDesc (xmlDtdPtr dtd,
- const xmlChar *name);
-xmlElementPtr xmlGetDtdQElementDesc (xmlDtdPtr dtd,
- const xmlChar *name,
- const xmlChar *prefix);
-xmlElementPtr xmlGetDtdElementDesc (xmlDtdPtr dtd,
- const xmlChar *name);
-
-int xmlValidGetValidElements(xmlNode *prev,
- xmlNode *next,
- const xmlChar **list,
- int max);
-int xmlValidGetPotentialChildren(xmlElementContent *ctree,
- const xmlChar **list,
- int *len,
- int max);
-int xmlValidateNameValue (const xmlChar *value);
-int xmlValidateNamesValue (const xmlChar *value);
-int xmlValidateNmtokenValue (const xmlChar *value);
-int xmlValidateNmtokensValue(const xmlChar *value);
-
-#ifdef LIBXML_REGEXP_ENABLED
-/*
- * Validation based on the regexp support
- */
-int xmlValidBuildContentModel(xmlValidCtxtPtr ctxt,
- xmlElementPtr elem);
-
-#endif /* LIBXML_REGEXP_ENABLED */
-#ifdef __cplusplus
-}
-#endif
-#endif /* __XML_VALID_H__ */
diff --git a/bundle/libxml/include/libxml/xinclude.h b/bundle/libxml/include/libxml/xinclude.h
deleted file mode 100644
index 9c83ba0e5c..0000000000
--- a/bundle/libxml/include/libxml/xinclude.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * xinclude.c : API to handle XInclude processing
- *
- * World Wide Web Consortium Working Draft 26 October 2000
- * http://www.w3.org/TR/2000/WD-xinclude-20001026
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#ifndef __XML_XINCLUDE_H__
-#define __XML_XINCLUDE_H__
-
-#include <libxml/tree.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int xmlXIncludeProcess (xmlDocPtr doc);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* __XML_XINCLUDE_H__ */
diff --git a/bundle/libxml/include/libxml/xlink.h b/bundle/libxml/include/libxml/xlink.h
deleted file mode 100644
index c7f48c8539..0000000000
--- a/bundle/libxml/include/libxml/xlink.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * xlink.h : interfaces to the hyperlinks detection module
- *
- * See Copyright for the status of this software.
- *
- * Related specification: http://www.w3.org/TR/xlink
- * http://www.w3.org/HTML/
- * and XBase
- *
- * daniel@veillard.com
- */
-
-#ifndef __XML_XLINK_H__
-#define __XML_XLINK_H__
-
-#include <libxml/tree.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-/**
- * Various defines for the various Link properties.
- *
- * NOTE: the link detection layer will try to resolve QName expansion
- * of namespaces. If "foo" is the prefix for "http://foo.com/"
- * then the link detection layer will expand role="foo:myrole"
- * to "http://foo.com/:myrole".
- * NOTE: the link detection layer will expand URI-Refences found on
- * href attributes by using the base mechanism if found.
- */
-typedef xmlChar *xlinkHRef;
-typedef xmlChar *xlinkRole;
-typedef xmlChar *xlinkTitle;
-
-typedef enum {
- XLINK_TYPE_NONE = 0,
- XLINK_TYPE_SIMPLE,
- XLINK_TYPE_EXTENDED,
- XLINK_TYPE_EXTENDED_SET
-} xlinkType;
-
-typedef enum {
- XLINK_SHOW_NONE = 0,
- XLINK_SHOW_NEW,
- XLINK_SHOW_EMBED,
- XLINK_SHOW_REPLACE
-} xlinkShow;
-
-typedef enum {
- XLINK_ACTUATE_NONE = 0,
- XLINK_ACTUATE_AUTO,
- XLINK_ACTUATE_ONREQUEST
-} xlinkActuate;
-
-/**
- * xlinkNodeDetectFunc:
- * @ctx: user data pointer
- * @node: the node to check
- *
- * This is the prototype for the link detection routine.
- * It calls the default link detection callbacks upon link detection.
- */
-typedef void (*xlinkNodeDetectFunc) (void *ctx, xmlNodePtr node);
-
-/**
- * The link detection module interact with the upper layers using
- * a set of callback registered at parsing time.
- */
-
-/**
- * xlinkSimpleLinkFunk:
- * @ctx: user data pointer
- * @node: the node carrying the link
- * @href: the target of the link
- * @role: the role string
- * @title: the link title
- *
- * This is the prototype for a simple link detection callback.
- */
-typedef void
-(*xlinkSimpleLinkFunk) (void *ctx,
- xmlNodePtr node,
- const xlinkHRef href,
- const xlinkRole role,
- const xlinkTitle title);
-
-/**
- * xlinkExtendedLinkFunk:
- * @ctx: user data pointer
- * @node: the node carrying the link
- * @nbLocators: the number of locators detected on the link
- * @hrefs: pointer to the array of locator hrefs
- * @roles: pointer to the array of locator roles
- * @nbArcs: the number of arcs detected on the link
- * @from: pointer to the array of source roles found on the arcs
- * @to: pointer to the array of target roles found on the arcs
- * @show: array of values for the show attributes found on the arcs
- * @actuate: array of values for the actuate attributes found on the arcs
- * @nbTitles: the number of titles detected on the link
- * @title: array of titles detected on the link
- * @langs: array of xml:lang values for the titles
- *
- * This is the prototype for a extended link detection callback.
- */
-typedef void
-(*xlinkExtendedLinkFunk)(void *ctx,
- xmlNodePtr node,
- int nbLocators,
- const xlinkHRef *hrefs,
- const xlinkRole *roles,
- int nbArcs,
- const xlinkRole *from,
- const xlinkRole *to,
- xlinkShow *show,
- xlinkActuate *actuate,
- int nbTitles,
- const xlinkTitle *titles,
- const xmlChar **langs);
-
-/**
- * xlinkExtendedLinkSetFunk:
- * @ctx: user data pointer
- * @node: the node carrying the link
- * @nbLocators: the number of locators detected on the link
- * @hrefs: pointer to the array of locator hrefs
- * @roles: pointer to the array of locator roles
- * @nbTitles: the number of titles detected on the link
- * @title: array of titles detected on the link
- * @langs: array of xml:lang values for the titles
- *
- * This is the prototype for a extended link set detection callback.
- */
-typedef void
-(*xlinkExtendedLinkSetFunk) (void *ctx,
- xmlNodePtr node,
- int nbLocators,
- const xlinkHRef *hrefs,
- const xlinkRole *roles,
- int nbTitles,
- const xlinkTitle *titles,
- const xmlChar **langs);
-
-/**
- * This is the structure containing a set of Links detection callbacks.
- *
- * There is no default xlink callbacks, if one want to get link
- * recognition activated, those call backs must be provided before parsing.
- */
-typedef struct _xlinkHandler xlinkHandler;
-typedef xlinkHandler *xlinkHandlerPtr;
-struct _xlinkHandler {
- xlinkSimpleLinkFunk simple;
- xlinkExtendedLinkFunk extended;
- xlinkExtendedLinkSetFunk set;
-};
-
-/*
- * The default detection routine, can be overridden, they call the default
- * detection callbacks.
- */
-
-xlinkNodeDetectFunc xlinkGetDefaultDetect (void);
-void xlinkSetDefaultDetect (xlinkNodeDetectFunc func);
-
-/*
- * Routines to set/get the default handlers.
- */
-xlinkHandlerPtr xlinkGetDefaultHandler (void);
-void xlinkSetDefaultHandler (xlinkHandlerPtr handler);
-
-/*
- * Link detection module itself.
- */
-xlinkType xlinkIsLink (xmlDocPtr doc,
- xmlNodePtr node);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* __XML_XLINK_H__ */
diff --git a/bundle/libxml/include/libxml/xmlIO.h b/bundle/libxml/include/libxml/xmlIO.h
deleted file mode 100644
index cd4058c88c..0000000000
--- a/bundle/libxml/include/libxml/xmlIO.h
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * xmlIO.h : interface for the I/O interfaces used by the parser
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- *
- */
-
-#ifndef __XML_IO_H__
-#define __XML_IO_H__
-
-#include <stdio.h>
-#include <libxml/xmlversion.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Those are the functions and datatypes for the parser input
- * I/O structures.
- */
-
-/**
- * xmlInputMatchCallback:
- * @filename: the filename or URI
- *
- * Callback used in the I/O Input API to detect if the current handler
- * can provide input fonctionnalities for this resource.
- *
- * Returns 1 if yes and 0 if another Input module should be used
- */
-typedef int (*xmlInputMatchCallback) (char const *filename);
-/**
- * xmlInputOpenCallback:
- * @filename: the filename or URI
- *
- * Callback used in the I/O Input API to open the resource
- *
- * Returns an Input context or NULL in case or error
- */
-typedef void * (*xmlInputOpenCallback) (char const *filename);
-/**
- * xmlInputReadCallback:
- * @context: an Input context
- * @buffer: the buffer to store data read
- * @len: the length of the buffer in bytes
- *
- * Callback used in the I/O Input API to read the resource
- *
- * Returns the number of bytes read or -1 in case of error
- */
-typedef int (*xmlInputReadCallback) (void * context, char * buffer, int len);
-/**
- * xmlInputCloseCallback:
- * @context: an Input context
- *
- * Callback used in the I/O Input API to close the resource
- *
- * Returns 0 or -1 in case of error
- */
-typedef int (*xmlInputCloseCallback) (void * context);
-
-/*
- * Those are the functions and datatypes for the library output
- * I/O structures.
- */
-
-/**
- * xmlOutputMatchCallback:
- * @filename: the filename or URI
- *
- * Callback used in the I/O Output API to detect if the current handler
- * can provide output fonctionnalities for this resource.
- *
- * Returns 1 if yes and 0 if another Output module should be used
- */
-typedef int (*xmlOutputMatchCallback) (char const *filename);
-/**
- * xmlOutputOpenCallback:
- * @filename: the filename or URI
- *
- * Callback used in the I/O Output API to open the resource
- *
- * Returns an Output context or NULL in case or error
- */
-typedef void * (*xmlOutputOpenCallback) (char const *filename);
-/**
- * xmlOutputWriteCallback:
- * @context: an Output context
- * @buffer: the buffer of data to write
- * @len: the length of the buffer in bytes
- *
- * Callback used in the I/O Output API to write to the resource
- *
- * Returns the number of bytes written or -1 in case of error
- */
-typedef int (*xmlOutputWriteCallback) (void * context, const char * buffer,
- int len);
-/**
- * xmlOutputCloseCallback:
- * @context: an Output context
- *
- * Callback used in the I/O Output API to close the resource
- *
- * Returns 0 or -1 in case of error
- */
-typedef int (*xmlOutputCloseCallback) (void * context);
-
-#ifdef __cplusplus
-}
-#endif
-
-#include <libxml/globals.h>
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/encoding.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-struct _xmlParserInputBuffer {
- void* context;
- xmlInputReadCallback readcallback;
- xmlInputCloseCallback closecallback;
-
- xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */
-
- xmlBufferPtr buffer; /* Local buffer encoded in UTF-8 */
- xmlBufferPtr raw; /* if encoder != NULL buffer for raw input */
-};
-
-
-struct _xmlOutputBuffer {
- void* context;
- xmlOutputWriteCallback writecallback;
- xmlOutputCloseCallback closecallback;
-
- xmlCharEncodingHandlerPtr encoder; /* I18N conversions to UTF-8 */
-
- xmlBufferPtr buffer; /* Local buffer encoded in UTF-8 or ISOLatin */
- xmlBufferPtr conv; /* if encoder != NULL buffer for output */
- int written; /* total number of byte written */
-};
-
-/*
- * Interfaces for input
- */
-void xmlCleanupInputCallbacks (void);
-void xmlCleanupOutputCallbacks (void);
-
-void xmlRegisterDefaultInputCallbacks (void);
-xmlParserInputBufferPtr
- xmlAllocParserInputBuffer (xmlCharEncoding enc);
-
-xmlParserInputBufferPtr
- xmlParserInputBufferCreateFilename (const char *URI,
- xmlCharEncoding enc);
-xmlParserInputBufferPtr
- xmlParserInputBufferCreateFile (FILE *file,
- xmlCharEncoding enc);
-xmlParserInputBufferPtr
- xmlParserInputBufferCreateFd (int fd,
- xmlCharEncoding enc);
-xmlParserInputBufferPtr
- xmlParserInputBufferCreateMem (const char *mem, int size,
- xmlCharEncoding enc);
-xmlParserInputBufferPtr
- xmlParserInputBufferCreateIO (xmlInputReadCallback ioread,
- xmlInputCloseCallback ioclose,
- void *ioctx,
- xmlCharEncoding enc);
-int xmlParserInputBufferRead (xmlParserInputBufferPtr in,
- int len);
-int xmlParserInputBufferGrow (xmlParserInputBufferPtr in,
- int len);
-int xmlParserInputBufferPush (xmlParserInputBufferPtr in,
- int len,
- const char *buf);
-void xmlFreeParserInputBuffer (xmlParserInputBufferPtr in);
-char * xmlParserGetDirectory (const char *filename);
-
-int xmlRegisterInputCallbacks (xmlInputMatchCallback matchFunc,
- xmlInputOpenCallback openFunc,
- xmlInputReadCallback readFunc,
- xmlInputCloseCallback closeFunc);
-/*
- * Interfaces for output
- */
-void xmlRegisterDefaultOutputCallbacks(void);
-xmlOutputBufferPtr
- xmlAllocOutputBuffer (xmlCharEncodingHandlerPtr encoder);
-
-xmlOutputBufferPtr
- xmlOutputBufferCreateFilename (const char *URI,
- xmlCharEncodingHandlerPtr encoder,
- int compression);
-
-xmlOutputBufferPtr
- xmlOutputBufferCreateFile (FILE *file,
- xmlCharEncodingHandlerPtr encoder);
-
-xmlOutputBufferPtr
- xmlOutputBufferCreateFd (int fd,
- xmlCharEncodingHandlerPtr encoder);
-
-xmlOutputBufferPtr
- xmlOutputBufferCreateIO (xmlOutputWriteCallback iowrite,
- xmlOutputCloseCallback ioclose,
- void *ioctx,
- xmlCharEncodingHandlerPtr encoder);
-
-int xmlOutputBufferWrite (xmlOutputBufferPtr out,
- int len,
- const char *buf);
-int xmlOutputBufferWriteString (xmlOutputBufferPtr out,
- const char *str);
-
-int xmlOutputBufferFlush (xmlOutputBufferPtr out);
-int xmlOutputBufferClose (xmlOutputBufferPtr out);
-
-int xmlRegisterOutputCallbacks (xmlOutputMatchCallback matchFunc,
- xmlOutputOpenCallback openFunc,
- xmlOutputWriteCallback writeFunc,
- xmlOutputCloseCallback closeFunc);
-
-/* This function only exists if HTTP support built into the library */
-#ifdef LIBXML_HTTP_ENABLED
-void * xmlIOHTTPOpenW (const char * post_uri,
- int compression );
-void xmlRegisterHTTPPostCallbacks (void );
-#endif
-
-/*
- * A predefined entity loader disabling network accesses
- */
-xmlParserInputPtr xmlNoNetExternalEntityLoader(const char *URL,
- const char *ID,
- xmlParserCtxtPtr ctxt);
-
-xmlChar *xmlNormalizeWindowsPath (const xmlChar *path);
-
-int xmlCheckFilename (const char *path);
-/**
- * Default 'file://' protocol callbacks
- */
-int xmlFileMatch (const char *filename);
-void * xmlFileOpen (const char *filename);
-int xmlFileRead (void * context,
- char * buffer,
- int len);
-int xmlFileClose (void * context);
-
-/**
- * Default 'http://' protocol callbacks
- */
-#ifdef LIBXML_HTTP_ENABLED
-int xmlIOHTTPMatch (const char *filename);
-void * xmlIOHTTPOpen (const char *filename);
-int xmlIOHTTPRead (void * context,
- char * buffer,
- int len);
-int xmlIOHTTPClose (void * context);
-#endif /* LIBXML_HTTP_ENABLED */
-
-/**
- * Default 'ftp://' protocol callbacks
- */
-#ifdef LIBXML_FTP_ENABLED
-int xmlIOFTPMatch (const char *filename);
-void * xmlIOFTPOpen (const char *filename);
-int xmlIOFTPRead (void * context,
- char * buffer,
- int len);
-int xmlIOFTPClose (void * context);
-#endif /* LIBXML_FTP_ENABLED */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __XML_IO_H__ */
diff --git a/bundle/libxml/include/libxml/xmlautomata.h b/bundle/libxml/include/libxml/xmlautomata.h
deleted file mode 100644
index 96ba2245b3..0000000000
--- a/bundle/libxml/include/libxml/xmlautomata.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * automata.h : description of the API to build regexp automats
- *
- * See Copyright for the status of this software.
- *
- * Daniel Veillard <veillard@redhat.com>
- */
-
-#ifndef __XML_AUTOMATA_H__
-#define __XML_AUTOMATA_H__
-
-#include <libxml/xmlversion.h>
-#include <libxml/tree.h>
-
-#ifdef LIBXML_AUTOMATA_ENABLED
-#include <libxml/xmlregexp.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * xmlAutomataPtr:
- *
- * A libxml automata description, It can be compiled into a regexp
- */
-typedef struct _xmlAutomata xmlAutomata;
-typedef xmlAutomata *xmlAutomataPtr;
-
-/**
- * xmlAutomataStatePtr:
- *
- * A state int the automata description,
- */
-typedef struct _xmlAutomataState xmlAutomataState;
-typedef xmlAutomataState *xmlAutomataStatePtr;
-
-/*
- * Building API
- */
-xmlAutomataPtr xmlNewAutomata (void);
-void xmlFreeAutomata (xmlAutomataPtr am);
-
-xmlAutomataStatePtr xmlAutomataGetInitState (xmlAutomataPtr am);
-int xmlAutomataSetFinalState(xmlAutomataPtr am,
- xmlAutomataStatePtr state);
-xmlAutomataStatePtr xmlAutomataNewState (xmlAutomataPtr am);
-xmlAutomataStatePtr xmlAutomataNewTransition(xmlAutomataPtr am,
- xmlAutomataStatePtr from,
- xmlAutomataStatePtr to,
- const xmlChar *token,
- void *data);
-xmlAutomataStatePtr xmlAutomataNewCountTrans(xmlAutomataPtr am,
- xmlAutomataStatePtr from,
- xmlAutomataStatePtr to,
- const xmlChar *token,
- int min,
- int max,
- void *data);
-xmlAutomataStatePtr xmlAutomataNewOnceTrans (xmlAutomataPtr am,
- xmlAutomataStatePtr from,
- xmlAutomataStatePtr to,
- const xmlChar *token,
- int min,
- int max,
- void *data);
-xmlAutomataStatePtr xmlAutomataNewAllTrans (xmlAutomataPtr am,
- xmlAutomataStatePtr from,
- xmlAutomataStatePtr to,
- int lax);
-xmlAutomataStatePtr xmlAutomataNewEpsilon (xmlAutomataPtr am,
- xmlAutomataStatePtr from,
- xmlAutomataStatePtr to);
-xmlAutomataStatePtr xmlAutomataNewCountedTrans(xmlAutomataPtr am,
- xmlAutomataStatePtr from,
- xmlAutomataStatePtr to,
- int counter);
-xmlAutomataStatePtr xmlAutomataNewCounterTrans(xmlAutomataPtr am,
- xmlAutomataStatePtr from,
- xmlAutomataStatePtr to,
- int counter);
-int xmlAutomataNewCounter (xmlAutomataPtr am,
- int min,
- int max);
-
-xmlRegexpPtr xmlAutomataCompile (xmlAutomataPtr am);
-int xmlAutomataIsDeterminist(xmlAutomataPtr am);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LIBXML_AUTOMATA_ENABLED */
-#endif /* __XML_AUTOMATA_H__ */
diff --git a/bundle/libxml/include/libxml/xmlerror.h b/bundle/libxml/include/libxml/xmlerror.h
deleted file mode 100644
index 33e2275910..0000000000
--- a/bundle/libxml/include/libxml/xmlerror.h
+++ /dev/null
@@ -1,184 +0,0 @@
-#include <libxml/parser.h>
-
-#ifndef __XML_ERROR_H__
-#define __XML_ERROR_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- XML_ERR_OK = 0,
- XML_ERR_INTERNAL_ERROR,
- XML_ERR_NO_MEMORY,
-
- XML_ERR_DOCUMENT_START, /* 3 */
- XML_ERR_DOCUMENT_EMPTY,
- XML_ERR_DOCUMENT_END,
-
- XML_ERR_INVALID_HEX_CHARREF, /* 6 */
- XML_ERR_INVALID_DEC_CHARREF,
- XML_ERR_INVALID_CHARREF,
- XML_ERR_INVALID_CHAR,
-
- XML_ERR_CHARREF_AT_EOF, /* 10 */
- XML_ERR_CHARREF_IN_PROLOG,
- XML_ERR_CHARREF_IN_EPILOG,
- XML_ERR_CHARREF_IN_DTD,
- XML_ERR_ENTITYREF_AT_EOF,
- XML_ERR_ENTITYREF_IN_PROLOG,
- XML_ERR_ENTITYREF_IN_EPILOG,
- XML_ERR_ENTITYREF_IN_DTD,
- XML_ERR_PEREF_AT_EOF,
- XML_ERR_PEREF_IN_PROLOG,
- XML_ERR_PEREF_IN_EPILOG,
- XML_ERR_PEREF_IN_INT_SUBSET,
-
- XML_ERR_ENTITYREF_NO_NAME, /* 22 */
- XML_ERR_ENTITYREF_SEMICOL_MISSING,
-
- XML_ERR_PEREF_NO_NAME, /* 24 */
- XML_ERR_PEREF_SEMICOL_MISSING,
-
- XML_ERR_UNDECLARED_ENTITY, /* 26 */
- XML_WAR_UNDECLARED_ENTITY,
- XML_ERR_UNPARSED_ENTITY,
- XML_ERR_ENTITY_IS_EXTERNAL,
- XML_ERR_ENTITY_IS_PARAMETER,
-
- XML_ERR_UNKNOWN_ENCODING, /* 31 */
- XML_ERR_UNSUPPORTED_ENCODING,
-
- XML_ERR_STRING_NOT_STARTED, /* 33 */
- XML_ERR_STRING_NOT_CLOSED,
- XML_ERR_NS_DECL_ERROR,
-
- XML_ERR_ENTITY_NOT_STARTED, /* 36 */
- XML_ERR_ENTITY_NOT_FINISHED,
-
- XML_ERR_LT_IN_ATTRIBUTE, /* 38 */
- XML_ERR_ATTRIBUTE_NOT_STARTED,
- XML_ERR_ATTRIBUTE_NOT_FINISHED,
- XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
- XML_ERR_ATTRIBUTE_REDEFINED,
-
- XML_ERR_LITERAL_NOT_STARTED, /* 43 */
- XML_ERR_LITERAL_NOT_FINISHED,
-
- XML_ERR_COMMENT_NOT_FINISHED, /* 45 */
-
- XML_ERR_PI_NOT_STARTED, /* 47 */
- XML_ERR_PI_NOT_FINISHED,
-
- XML_ERR_NOTATION_NOT_STARTED, /* 49 */
- XML_ERR_NOTATION_NOT_FINISHED,
-
- XML_ERR_ATTLIST_NOT_STARTED, /* 51 */
- XML_ERR_ATTLIST_NOT_FINISHED,
-
- XML_ERR_MIXED_NOT_STARTED, /* 53 */
- XML_ERR_MIXED_NOT_FINISHED,
-
- XML_ERR_ELEMCONTENT_NOT_STARTED, /* 55 */
- XML_ERR_ELEMCONTENT_NOT_FINISHED,
-
- XML_ERR_XMLDECL_NOT_STARTED, /* 57 */
- XML_ERR_XMLDECL_NOT_FINISHED,
-
- XML_ERR_CONDSEC_NOT_STARTED, /* 59 */
- XML_ERR_CONDSEC_NOT_FINISHED,
-
- XML_ERR_EXT_SUBSET_NOT_FINISHED, /* 61 */
-
- XML_ERR_DOCTYPE_NOT_FINISHED, /* 62 */
-
- XML_ERR_MISPLACED_CDATA_END, /* 63 */
- XML_ERR_CDATA_NOT_FINISHED,
-
- XML_ERR_RESERVED_XML_NAME, /* 65 */
-
- XML_ERR_SPACE_REQUIRED, /* 66 */
- XML_ERR_SEPARATOR_REQUIRED,
- XML_ERR_NMTOKEN_REQUIRED,
- XML_ERR_NAME_REQUIRED,
- XML_ERR_PCDATA_REQUIRED,
- XML_ERR_URI_REQUIRED,
- XML_ERR_PUBID_REQUIRED,
- XML_ERR_LT_REQUIRED,
- XML_ERR_GT_REQUIRED,
- XML_ERR_LTSLASH_REQUIRED,
- XML_ERR_EQUAL_REQUIRED,
-
- XML_ERR_TAG_NAME_MISMATCH, /* 77 */
- XML_ERR_TAG_NOT_FINISHED,
-
- XML_ERR_STANDALONE_VALUE, /* 79 */
-
- XML_ERR_ENCODING_NAME, /* 80 */
-
- XML_ERR_HYPHEN_IN_COMMENT, /* 81 */
-
- XML_ERR_INVALID_ENCODING, /* 82 */
-
- XML_ERR_EXT_ENTITY_STANDALONE, /* 83 */
-
- XML_ERR_CONDSEC_INVALID, /* 84 */
-
- XML_ERR_VALUE_REQUIRED, /* 85 */
-
- XML_ERR_NOT_WELL_BALANCED, /* 86 */
- XML_ERR_EXTRA_CONTENT, /* 87 */
- XML_ERR_ENTITY_CHAR_ERROR, /* 88 */
- XML_ERR_ENTITY_PE_INTERNAL, /* 88 */
- XML_ERR_ENTITY_LOOP, /* 89 */
- XML_ERR_ENTITY_BOUNDARY, /* 90 */
- XML_ERR_INVALID_URI, /* 91 */
- XML_ERR_URI_FRAGMENT, /* 92 */
- XML_WAR_CATALOG_PI, /* 93 */
- XML_ERR_NO_DTD /* 94 */
-}xmlParserErrors;
-
-/**
- * xmlGenericErrorFunc:
- * @ctx: a parsing context
- * @msg: the message
- * @...: the extra arguments of the varags to format the message
- *
- * Signature of the function to use when there is an error and
- * no parsing or validity context available .
- */
-typedef void (*xmlGenericErrorFunc) (void *ctx,
- const char *msg,
- ...);
-
-/*
- * Use the following function to reset the two global variables
- * xmlGenericError and xmlGenericErrorContext.
- */
-void xmlSetGenericErrorFunc (void *ctx,
- xmlGenericErrorFunc handler);
-void initGenericErrorDefaultFunc(xmlGenericErrorFunc *handler);
-
-/*
- * Default message routines used by SAX and Valid context for error
- * and warning reporting.
- */
-void xmlParserError (void *ctx,
- const char *msg,
- ...);
-void xmlParserWarning (void *ctx,
- const char *msg,
- ...);
-void xmlParserValidityError (void *ctx,
- const char *msg,
- ...);
-void xmlParserValidityWarning(void *ctx,
- const char *msg,
- ...);
-void xmlParserPrintFileInfo (xmlParserInputPtr input);
-void xmlParserPrintFileContext(xmlParserInputPtr input);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* __XML_ERROR_H__ */
diff --git a/bundle/libxml/include/libxml/xmlmemory.h b/bundle/libxml/include/libxml/xmlmemory.h
deleted file mode 100644
index 8e8df944c1..0000000000
--- a/bundle/libxml/include/libxml/xmlmemory.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * xmlmemory.h: interface for the memory allocation debug.
- *
- * daniel@veillard.com
- */
-
-
-#ifndef _DEBUG_MEMORY_ALLOC_
-#define _DEBUG_MEMORY_ALLOC_
-
-#include <stdio.h>
-#include <libxml/xmlversion.h>
-
-/**
- * DEBUG_MEMORY:
- *
- * DEBUG_MEMORY replaces the allocator with a collect and debug
- * shell to the libc allocator.
- * DEBUG_MEMORY should only be activated when debugging
- * libxml i.e. if libxml has been configured with --with-debug-mem too.
- */
-/* #define DEBUG_MEMORY_FREED */
-/* #define DEBUG_MEMORY_LOCATION */
-
-#ifdef DEBUG
-#ifndef DEBUG_MEMORY
-#define DEBUG_MEMORY
-#endif
-#endif
-
-/**
- * DEBUG_MEMORY_LOCATION:
- *
- * DEBUG_MEMORY_LOCATION should be activated only when debugging
- * libxml i.e. if libxml has been configured with --with-debug-mem too.
- */
-#ifdef DEBUG_MEMORY_LOCATION
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * The XML memory wrapper support 4 basic overloadable functions.
- */
-/**
- * xmlFreeFunc:
- * @mem: an already allocated block of memory
- *
- * Signature for a free() implementation.
- */
-typedef void (*xmlFreeFunc)(void *mem);
-/**
- * xmlMallocFunc:
- * @size: the size requested in bytes
- *
- * Signature for a malloc() implementation.
- *
- * Returns a pointer to the newly allocated block or NULL in case of error.
- */
-typedef void *(*xmlMallocFunc)(size_t size);
-
-/**
- * xmlReallocFunc:
- * @mem: an already allocated block of memory
- * @size: the new size requested in bytes
- *
- * Signature for a realloc() implementation.
- *
- * Returns a pointer to the newly reallocated block or NULL in case of error.
- */
-typedef void *(*xmlReallocFunc)(void *mem, size_t size);
-
-/**
- * xmlStrdupFunc:
- * @str: a zero terminated string
- *
- * Signature for an strdup() implementation.
- *
- * Returns the copy of the string or NULL in case of error.
- */
-typedef char *(*xmlStrdupFunc)(const char *str);
-
-/*
- * The 4 interfaces used for all memory handling within libxml.
-LIBXML_DLL_IMPORT extern xmlFreeFunc xmlFree;
-LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMalloc;
-LIBXML_DLL_IMPORT extern xmlReallocFunc xmlRealloc;
-LIBXML_DLL_IMPORT extern xmlStrdupFunc xmlMemStrdup;
- */
-
-/*
- * The way to overload the existing functions.
- */
-int xmlMemSetup (xmlFreeFunc freeFunc,
- xmlMallocFunc mallocFunc,
- xmlReallocFunc reallocFunc,
- xmlStrdupFunc strdupFunc);
-int xmlMemGet (xmlFreeFunc *freeFunc,
- xmlMallocFunc *mallocFunc,
- xmlReallocFunc *reallocFunc,
- xmlStrdupFunc *strdupFunc);
-
-/*
- * Initialization of the memory layer.
- */
-int xmlInitMemory (void);
-
-/*
- * Those are specific to the XML debug memory wrapper.
- */
-int xmlMemUsed (void);
-void xmlMemDisplay (FILE *fp);
-void xmlMemShow (FILE *fp, int nr);
-void xmlMemoryDump (void);
-void * xmlMemMalloc (size_t size);
-void * xmlMemRealloc (void *ptr,size_t size);
-void xmlMemFree (void *ptr);
-char * xmlMemoryStrdup (const char *str);
-
-#ifdef DEBUG_MEMORY_LOCATION
-/**
- * xmlMalloc:
- * @size: number of bytes to allocate
- *
- * Wrapper for the malloc() function used in the XML library.
- *
- * Returns the pointer to the allocated area or NULL in case of error.
- */
-#define xmlMalloc(size) xmlMallocLoc((size), __FILE__, __LINE__)
-/**
- * xmlRealloc:
- * @ptr: pointer to the existing allocated area
- * @size: number of bytes to allocate
- *
- * Wrapper for the realloc() function used in the XML library.
- *
- * Returns the pointer to the allocated area or NULL in case of error.
- */
-#define xmlRealloc(ptr, size) xmlReallocLoc((ptr), (size), __FILE__, __LINE__)
-/**
- * xmlMemStrdup:
- * @str: pointer to the existing string
- *
- * Wrapper for the strdup() function, xmlStrdup() is usually preferred.
- *
- * Returns the pointer to the allocated area or NULL in case of error.
- */
-#define xmlMemStrdup(str) xmlMemStrdupLoc((str), __FILE__, __LINE__)
-
-void * xmlMallocLoc(size_t size, const char *file, int line);
-void * xmlReallocLoc(void *ptr,size_t size, const char *file, int line);
-char * xmlMemStrdupLoc(const char *str, const char *file, int line);
-#endif /* DEBUG_MEMORY_LOCATION */
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#ifndef __XML_GLOBALS_H
-#ifndef __XML_THREADS_H__
-#include <libxml/threads.h>
-#include <libxml/globals.h>
-#endif
-#endif
-
-#endif /* _DEBUG_MEMORY_ALLOC_ */
-
diff --git a/bundle/libxml/include/libxml/xmlreader.h b/bundle/libxml/include/libxml/xmlreader.h
deleted file mode 100644
index 8e4b05783b..0000000000
--- a/bundle/libxml/include/libxml/xmlreader.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * xmlreader.h : Interfaces, constants and types of the XML streaming API.
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#ifndef __XML_XMLREADER_H__
-#define __XML_XMLREADER_H__
-
-#include <libxml/tree.h>
-#include <libxml/xmlIO.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct _xmlTextReader xmlTextReader;
-typedef xmlTextReader *xmlTextReaderPtr;
-
-/*
- * Constructors & Destructor
- */
-xmlTextReaderPtr xmlNewTextReader (xmlParserInputBufferPtr input);
-xmlTextReaderPtr xmlNewTextReaderFilename(const char *URI);
-void xmlFreeTextReader (xmlTextReaderPtr reader);
-
-/*
- * Iterators
- */
-int xmlTextReaderRead (xmlTextReaderPtr reader);
-
-/*
- * Attributes of the node
- */
-int xmlTextReaderAttributeCount(xmlTextReaderPtr reader);
-xmlChar * xmlTextReaderBaseUri (xmlTextReaderPtr reader);
-int xmlTextReaderDepth (xmlTextReaderPtr reader);
-int xmlTextReaderHasAttributes(xmlTextReaderPtr reader);
-int xmlTextReaderHasValue(xmlTextReaderPtr reader);
-int xmlTextReaderIsDefault (xmlTextReaderPtr reader);
-int xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader);
-xmlChar * xmlTextReaderLocalName (xmlTextReaderPtr reader);
-xmlChar * xmlTextReaderName (xmlTextReaderPtr reader);
-xmlChar * xmlTextReaderNamespaceUri(xmlTextReaderPtr reader);
-int xmlTextReaderNodeType (xmlTextReaderPtr reader);
-xmlChar * xmlTextReaderPrefix (xmlTextReaderPtr reader);
-int xmlTextReaderQuoteChar (xmlTextReaderPtr reader);
-xmlChar * xmlTextReaderValue (xmlTextReaderPtr reader);
-xmlChar * xmlTextReaderXmlLang (xmlTextReaderPtr reader);
-#ifdef __cplusplus
-}
-#endif
-#endif /* __XML_XMLREADER_H__ */
-
diff --git a/bundle/libxml/include/libxml/xmlregexp.h b/bundle/libxml/include/libxml/xmlregexp.h
deleted file mode 100644
index 434b7a2bd9..0000000000
--- a/bundle/libxml/include/libxml/xmlregexp.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * regexp.h : describes the basic API for libxml regular expressions handling
- *
- * See Copyright for the status of this software.
- *
- * Daniel Veillard <veillard@redhat.com>
- */
-
-#ifndef __XML_REGEXP_H__
-#define __XML_REGEXP_H__
-
-#include <libxml/xmlversion.h>
-
-#ifdef LIBXML_REGEXP_ENABLED
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * xmlRegexpPtr:
- *
- * A libxml regular expression, they can actually be far more complex
- * thank the POSIX regex expressions.
- */
-typedef struct _xmlRegexp xmlRegexp;
-typedef xmlRegexp *xmlRegexpPtr;
-
-/**
- * xmlRegExecCtxtPtr:
- *
- * A libxml progressive regular expression evaluation context
- */
-typedef struct _xmlRegExecCtxt xmlRegExecCtxt;
-typedef xmlRegExecCtxt *xmlRegExecCtxtPtr;
-
-#ifdef __cplusplus
-}
-#endif
-#include <libxml/tree.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * The POSIX like API
- */
-xmlRegexpPtr xmlRegexpCompile(const xmlChar *regexp);
-void xmlRegFreeRegexp(xmlRegexpPtr regexp);
-int xmlRegexpExec (xmlRegexpPtr comp,
- const xmlChar *value);
-void xmlRegexpPrint (FILE *output,
- xmlRegexpPtr regexp);
-int xmlRegexpIsDeterminist(xmlRegexpPtr comp);
-
-/*
- * Callback function when doing a transition in the automata
- */
-typedef void (*xmlRegExecCallbacks) (xmlRegExecCtxtPtr exec,
- const xmlChar *token,
- void *transdata,
- void *inputdata);
-
-/*
- * The progressive API
- */
-xmlRegExecCtxtPtr xmlRegNewExecCtxt (xmlRegexpPtr comp,
- xmlRegExecCallbacks callback,
- void *data);
-void xmlRegFreeExecCtxt (xmlRegExecCtxtPtr exec);
-int xmlRegExecPushString (xmlRegExecCtxtPtr exec,
- const xmlChar *value,
- void *data);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LIBXML_REGEXP_ENABLED */
-
-#endif /*__XML_REGEXP_H__ */
diff --git a/bundle/libxml/include/libxml/xmlschemas.h b/bundle/libxml/include/libxml/xmlschemas.h
deleted file mode 100644
index 14b9230832..0000000000
--- a/bundle/libxml/include/libxml/xmlschemas.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * schemas.h : interface to the XML Schemas handling and schema validity
- * checking
- *
- * See Copyright for the status of this software.
- *
- * Daniel.Veillard@w3.org
- */
-
-
-#ifndef __XML_SCHEMA_H__
-#define __XML_SCHEMA_H__
-
-#include <libxml/xmlversion.h>
-
-#ifdef LIBXML_SCHEMAS_ENABLED
-
-#include <libxml/tree.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
- XML_SCHEMAS_ERR_OK = 0,
- XML_SCHEMAS_ERR_NOROOT = 1,
- XML_SCHEMAS_ERR_UNDECLAREDELEM,
- XML_SCHEMAS_ERR_NOTTOPLEVEL,
- XML_SCHEMAS_ERR_MISSING,
- XML_SCHEMAS_ERR_WRONGELEM,
- XML_SCHEMAS_ERR_NOTYPE,
- XML_SCHEMAS_ERR_NOROLLBACK,
- XML_SCHEMAS_ERR_ISABSTRACT,
- XML_SCHEMAS_ERR_NOTEMPTY,
- XML_SCHEMAS_ERR_ELEMCONT,
- XML_SCHEMAS_ERR_HAVEDEFAULT,
- XML_SCHEMAS_ERR_NOTNILLABLE,
- XML_SCHEMAS_ERR_EXTRACONTENT,
- XML_SCHEMAS_ERR_INVALIDATTR,
- XML_SCHEMAS_ERR_INVALIDELEM,
- XML_SCHEMAS_ERR_NOTDETERMINIST,
- XML_SCHEMAS_ERR_CONSTRUCT,
- XML_SCHEMAS_ERR_INTERNAL,
- XML_SCHEMAS_ERR_NOTSIMPLE,
- XML_SCHEMAS_ERR_ATTRUNKNOWN,
- XML_SCHEMAS_ERR_ATTRINVALID,
- XML_SCHEMAS_ERR_,
- XML_SCHEMAS_ERR_XXX
-} xmlSchemaValidError;
-
-
-/**
- * The schemas related types are kept internal
- */
-typedef struct _xmlSchema xmlSchema;
-typedef xmlSchema *xmlSchemaPtr;
-
-/**
- * A schemas validation context
- */
-typedef void (*xmlSchemaValidityErrorFunc) (void *ctx, const char *msg, ...);
-typedef void (*xmlSchemaValidityWarningFunc) (void *ctx, const char *msg, ...);
-
-typedef struct _xmlSchemaParserCtxt xmlSchemaParserCtxt;
-typedef xmlSchemaParserCtxt *xmlSchemaParserCtxtPtr;
-
-typedef struct _xmlSchemaValidCtxt xmlSchemaValidCtxt;
-typedef xmlSchemaValidCtxt *xmlSchemaValidCtxtPtr;
-
-/*
- * Interfaces for parsing.
- */
-xmlSchemaParserCtxtPtr xmlSchemaNewParserCtxt (const char *URL);
-xmlSchemaParserCtxtPtr xmlSchemaNewMemParserCtxt(const char *buffer,
- int size);
-void xmlSchemaFreeParserCtxt (xmlSchemaParserCtxtPtr ctxt);
-void xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaValidityErrorFunc err,
- xmlSchemaValidityWarningFunc warn,
- void *ctx);
-xmlSchemaPtr xmlSchemaParse (xmlSchemaParserCtxtPtr ctxt);
-void xmlSchemaFree (xmlSchemaPtr schema);
-void xmlSchemaDump (FILE *output,
- xmlSchemaPtr schema);
-/*
- * Interfaces for validating
- */
-void xmlSchemaSetValidErrors (xmlSchemaValidCtxtPtr ctxt,
- xmlSchemaValidityErrorFunc err,
- xmlSchemaValidityWarningFunc warn,
- void *ctx);
-xmlSchemaValidCtxtPtr xmlSchemaNewValidCtxt (xmlSchemaPtr schema);
-void xmlSchemaFreeValidCtxt (xmlSchemaValidCtxtPtr ctxt);
-int xmlSchemaValidateDoc (xmlSchemaValidCtxtPtr ctxt,
- xmlDocPtr instance);
-int xmlSchemaValidateStream (xmlSchemaValidCtxtPtr ctxt,
- xmlParserInputBufferPtr input,
- xmlCharEncoding enc,
- xmlSAXHandlerPtr sax,
- void *user_data);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LIBXML_SCHEMAS_ENABLED */
-#endif /* __XML_SCHEMA_H__ */
diff --git a/bundle/libxml/include/libxml/xmlschemastypes.h b/bundle/libxml/include/libxml/xmlschemastypes.h
deleted file mode 100644
index a758c128e5..0000000000
--- a/bundle/libxml/include/libxml/xmlschemastypes.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * schemastypes.c : interface of the XML Schema Datatypes
- * definition and validity checking
- *
- * See Copyright for the status of this software.
- *
- * Daniel Veillard <veillard@redhat.com>
- */
-
-
-#ifndef __XML_SCHEMA_TYPES_H__
-#define __XML_SCHEMA_TYPES_H__
-
-#include <libxml/xmlversion.h>
-
-#ifdef LIBXML_SCHEMAS_ENABLED
-
-#include <libxml/schemasInternals.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void xmlSchemaInitTypes (void);
-void xmlSchemaCleanupTypes (void);
-xmlSchemaTypePtr xmlSchemaGetPredefinedType (const xmlChar *name,
- const xmlChar *ns);
-int xmlSchemaValidatePredefinedType (xmlSchemaTypePtr type,
- const xmlChar *value,
- xmlSchemaValPtr *val);
-int xmlSchemaValidateFacet (xmlSchemaTypePtr base,
- xmlSchemaFacetPtr facet,
- const xmlChar *value,
- xmlSchemaValPtr val);
-void xmlSchemaFreeValue (xmlSchemaValPtr val);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LIBXML_SCHEMAS_ENABLED */
-#endif /* __XML_SCHEMA_TYPES_H__ */
diff --git a/bundle/libxml/include/libxml/xmlunicode.h b/bundle/libxml/include/libxml/xmlunicode.h
deleted file mode 100644
index f0f1fe9ce9..0000000000
--- a/bundle/libxml/include/libxml/xmlunicode.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * xmlunicode.h: this header exports interfaces for the Unicode character APIs
- *
- * This file is automatically generated from the
- * UCS description files of the Unicode Character Database
- * http://www.unicode.org/Public/3.1-Update/UnicodeCharacterDatabase-3.1.0.html
- * using the genUnicode.py Python script.
- *
- * Generation date: Tue Apr 16 17:28:05 2002
- * Sources: Blocks-4.txt UnicodeData-3.1.0.txt
- * Daniel Veillard <veillard@redhat.com>
- */
-
-#ifndef __XML_UNICODE_H__
-#define __XML_UNICODE_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int xmlUCSIsAlphabeticPresentationForms (int code);
-int xmlUCSIsArabic (int code);
-int xmlUCSIsArabicPresentationFormsA (int code);
-int xmlUCSIsArabicPresentationFormsB (int code);
-int xmlUCSIsArmenian (int code);
-int xmlUCSIsArrows (int code);
-int xmlUCSIsBasicLatin (int code);
-int xmlUCSIsBengali (int code);
-int xmlUCSIsBlockElements (int code);
-int xmlUCSIsBopomofo (int code);
-int xmlUCSIsBopomofoExtended (int code);
-int xmlUCSIsBoxDrawing (int code);
-int xmlUCSIsBraillePatterns (int code);
-int xmlUCSIsByzantineMusicalSymbols (int code);
-int xmlUCSIsCJKCompatibility (int code);
-int xmlUCSIsCJKCompatibilityForms (int code);
-int xmlUCSIsCJKCompatibilityIdeographs (int code);
-int xmlUCSIsCJKCompatibilityIdeographsSupplement (int code);
-int xmlUCSIsCJKRadicalsSupplement (int code);
-int xmlUCSIsCJKSymbolsandPunctuation (int code);
-int xmlUCSIsCJKUnifiedIdeographs (int code);
-int xmlUCSIsCJKUnifiedIdeographsExtensionA (int code);
-int xmlUCSIsCJKUnifiedIdeographsExtensionB (int code);
-int xmlUCSIsCherokee (int code);
-int xmlUCSIsCombiningDiacriticalMarks (int code);
-int xmlUCSIsCombiningHalfMarks (int code);
-int xmlUCSIsCombiningMarksforSymbols (int code);
-int xmlUCSIsControlPictures (int code);
-int xmlUCSIsCurrencySymbols (int code);
-int xmlUCSIsCyrillic (int code);
-int xmlUCSIsDeseret (int code);
-int xmlUCSIsDevanagari (int code);
-int xmlUCSIsDingbats (int code);
-int xmlUCSIsEnclosedAlphanumerics (int code);
-int xmlUCSIsEnclosedCJKLettersandMonths (int code);
-int xmlUCSIsEthiopic (int code);
-int xmlUCSIsGeneralPunctuation (int code);
-int xmlUCSIsGeometricShapes (int code);
-int xmlUCSIsGeorgian (int code);
-int xmlUCSIsGothic (int code);
-int xmlUCSIsGreek (int code);
-int xmlUCSIsGreekExtended (int code);
-int xmlUCSIsGujarati (int code);
-int xmlUCSIsGurmukhi (int code);
-int xmlUCSIsHalfwidthandFullwidthForms (int code);
-int xmlUCSIsHangulCompatibilityJamo (int code);
-int xmlUCSIsHangulJamo (int code);
-int xmlUCSIsHangulSyllables (int code);
-int xmlUCSIsHebrew (int code);
-int xmlUCSIsHighPrivateUseSurrogates (int code);
-int xmlUCSIsHighSurrogates (int code);
-int xmlUCSIsHiragana (int code);
-int xmlUCSIsIPAExtensions (int code);
-int xmlUCSIsIdeographicDescriptionCharacters (int code);
-int xmlUCSIsKanbun (int code);
-int xmlUCSIsKangxiRadicals (int code);
-int xmlUCSIsKannada (int code);
-int xmlUCSIsKatakana (int code);
-int xmlUCSIsKhmer (int code);
-int xmlUCSIsLao (int code);
-int xmlUCSIsLatin1Supplement (int code);
-int xmlUCSIsLatinExtendedA (int code);
-int xmlUCSIsLatinExtendedB (int code);
-int xmlUCSIsLatinExtendedAdditional (int code);
-int xmlUCSIsLetterlikeSymbols (int code);
-int xmlUCSIsLowSurrogates (int code);
-int xmlUCSIsMalayalam (int code);
-int xmlUCSIsMathematicalAlphanumericSymbols (int code);
-int xmlUCSIsMathematicalOperators (int code);
-int xmlUCSIsMiscellaneousSymbols (int code);
-int xmlUCSIsMiscellaneousTechnical (int code);
-int xmlUCSIsMongolian (int code);
-int xmlUCSIsMusicalSymbols (int code);
-int xmlUCSIsMyanmar (int code);
-int xmlUCSIsNumberForms (int code);
-int xmlUCSIsOgham (int code);
-int xmlUCSIsOldItalic (int code);
-int xmlUCSIsOpticalCharacterRecognition (int code);
-int xmlUCSIsOriya (int code);
-int xmlUCSIsPrivateUse (int code);
-int xmlUCSIsRunic (int code);
-int xmlUCSIsSinhala (int code);
-int xmlUCSIsSmallFormVariants (int code);
-int xmlUCSIsSpacingModifierLetters (int code);
-int xmlUCSIsSpecials (int code);
-int xmlUCSIsSuperscriptsandSubscripts (int code);
-int xmlUCSIsSyriac (int code);
-int xmlUCSIsTags (int code);
-int xmlUCSIsTamil (int code);
-int xmlUCSIsTelugu (int code);
-int xmlUCSIsThaana (int code);
-int xmlUCSIsThai (int code);
-int xmlUCSIsTibetan (int code);
-int xmlUCSIsUnifiedCanadianAboriginalSyllabics (int code);
-int xmlUCSIsYiRadicals (int code);
-int xmlUCSIsYiSyllables (int code);
-
-int xmlUCSIsBlock (int code,
- const char *block);
-
-int xmlUCSIsCatC (int code);
-int xmlUCSIsCatCc (int code);
-int xmlUCSIsCatCf (int code);
-int xmlUCSIsCatCo (int code);
-int xmlUCSIsCatCs (int code);
-int xmlUCSIsCatL (int code);
-int xmlUCSIsCatLl (int code);
-int xmlUCSIsCatLm (int code);
-int xmlUCSIsCatLo (int code);
-int xmlUCSIsCatLt (int code);
-int xmlUCSIsCatLu (int code);
-int xmlUCSIsCatM (int code);
-int xmlUCSIsCatMc (int code);
-int xmlUCSIsCatMe (int code);
-int xmlUCSIsCatMn (int code);
-int xmlUCSIsCatN (int code);
-int xmlUCSIsCatNd (int code);
-int xmlUCSIsCatNl (int code);
-int xmlUCSIsCatNo (int code);
-int xmlUCSIsCatP (int code);
-int xmlUCSIsCatPc (int code);
-int xmlUCSIsCatPd (int code);
-int xmlUCSIsCatPe (int code);
-int xmlUCSIsCatPf (int code);
-int xmlUCSIsCatPi (int code);
-int xmlUCSIsCatPo (int code);
-int xmlUCSIsCatPs (int code);
-int xmlUCSIsCatS (int code);
-int xmlUCSIsCatSc (int code);
-int xmlUCSIsCatSk (int code);
-int xmlUCSIsCatSm (int code);
-int xmlUCSIsCatSo (int code);
-int xmlUCSIsCatZ (int code);
-int xmlUCSIsCatZl (int code);
-int xmlUCSIsCatZp (int code);
-int xmlUCSIsCatZs (int code);
-
-int xmlUCSIsCat (int code,
- const char *cat);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* __XML_UNICODE_H__ */
diff --git a/bundle/libxml/include/libxml/xmlversion.h b/bundle/libxml/include/libxml/xmlversion.h
deleted file mode 100644
index 6cb01d5db3..0000000000
--- a/bundle/libxml/include/libxml/xmlversion.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * xmlversion.h : compile-time version informations for the XML parser.
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#ifndef __XML_VERSION_H__
-#define __XML_VERSION_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * use those to be sure nothing nasty will happen if
- * your library and includes mismatch
- */
-#ifndef LIBXML2_COMPILING_MSCCDEF
-extern void xmlCheckVersion(int version);
-#endif /* LIBXML2_COMPILING_MSCCDEF */
-
-/**
- * LIBXML_DOTTED_VERSION:
- *
- * the version string like "1.2.3"
- */
-#define LIBXML_DOTTED_VERSION "2.4.30"
-
-/**
- * LIBXML_VERSION:
- *
- * the version number: 1.2.3 value is 1002003
- */
-#define LIBXML_VERSION 20430
-
-/**
- * LIBXML_VERSION_STRING:
- *
- * the version number string, 1.2.3 value is "1002003"
- */
-#define LIBXML_VERSION_STRING "20430"
-
-/**
- * LIBXML_TEST_VERSION:
- *
- * Macro to check that the libxml version in use is compatible with
- * the version the software has been compiled against
- */
-#define LIBXML_TEST_VERSION xmlCheckVersion(20430);
-
-#ifndef VMS
-#if 0
-/**
- * WITH_TRIO:
- *
- * defined if the trio support need to be configured in
- */
-#define WITH_TRIO
-#else
-/**
- * WITHOUT_TRIO:
- *
- * defined if the trio support should not be configured in
- */
-#define WITHOUT_TRIO
-#endif
-#else /* VMS */
-#define WITH_TRIO 1
-#endif /* VMS */
-
-/**
- * LIBXML_THREAD_ENABLED:
- *
- * Whether the thread support is configured in
- */
-#if 0
-#if defined(_REENTRANT) || (_POSIX_C_SOURCE - 0 >= 199506L)
-#define LIBXML_THREAD_ENABLED
-#endif
-#endif
-
-/**
- * LIBXML_FTP_ENABLED:
- *
- * Whether the FTP support is configured in
- */
-#if 1
-#define LIBXML_FTP_ENABLED
-#endif
-
-/**
- * LIBXML_HTTP_ENABLED:
- *
- * Whether the HTTP support is configured in
- */
-#if 1
-#define LIBXML_HTTP_ENABLED
-#endif
-
-/**
- * LIBXML_HTML_ENABLED:
- *
- * Whether the HTML support is configured in
- */
-#if 1
-#define LIBXML_HTML_ENABLED
-#endif
-
-/**
- * LIBXML_C14N_ENABLED:
- *
- * Whether the Canonicalization support is configured in
- */
-#if 1
-#define LIBXML_C14N_ENABLED
-#endif
-
-/**
- * LIBXML_CATALOG_ENABLED:
- *
- * Whether the Catalog support is configured in
- */
-#if 1
-#define LIBXML_CATALOG_ENABLED
-#endif
-
-/**
- * LIBXML_DOCB_ENABLED:
- *
- * Whether the SGML Docbook support is configured in
- */
-#if 1
-#define LIBXML_DOCB_ENABLED
-#endif
-
-/**
- * LIBXML_XPATH_ENABLED:
- *
- * Whether XPath is configured in
- */
-#if 1
-#define LIBXML_XPATH_ENABLED
-#endif
-
-/**
- * LIBXML_XPTR_ENABLED:
- *
- * Whether XPointer is configured in
- */
-#if 1
-#define LIBXML_XPTR_ENABLED
-#endif
-
-/**
- * LIBXML_XINCLUDE_ENABLED:
- *
- * Whether XInclude is configured in
- */
-#if 1
-#define LIBXML_XINCLUDE_ENABLED
-#endif
-
-/**
- * LIBXML_ICONV_ENABLED:
- *
- * Whether iconv support is available
- */
-#if 0
-#define LIBXML_ICONV_ENABLED
-#endif
-
-/**
- * LIBXML_DEBUG_ENABLED:
- *
- * Whether Debugging module is configured in
- */
-#if 1
-#define LIBXML_DEBUG_ENABLED
-#endif
-
-/**
- * DEBUG_MEMORY_LOCATION:
- *
- * Whether the memory debugging is configured in
- */
-#if 1
-#define DEBUG_MEMORY_LOCATION
-#endif
-
-/**
- * LIBXML_UNICODE_ENABLED
- *
- * Whether the Unicode related interfaces are compiled in
- */
-#if 1
-#define LIBXML_UNICODE_ENABLED
-#endif
-
-/**
- * LIBXML_REGEXP_ENABLED
- *
- * Whether the regular expressions interfaces are compiled in
- */
-#if 1
-#define LIBXML_REGEXP_ENABLED
-#endif
-
-/**
- * LIBXML_AUTOMATA_ENABLED
- *
- * Whether the automata interfaces are compiled in
- */
-#if 1
-#define LIBXML_AUTOMATA_ENABLED
-#endif
-
-/**
- * LIBXML_SCHEMAS_ENABLED
- *
- * Whether the Schemas validation interfaces are compiled in
- */
-#if 1
-#define LIBXML_SCHEMAS_ENABLED
-#endif
-
-/**
- * LIBXML_DLL_IMPORT:
- *
- * Used on Windows (MS C compiler only) to declare a variable as
- * imported from the library. This macro should be empty when compiling
- * libxml itself. It should expand to __declspec(dllimport)
- * when the client code includes this header, and that only if the client
- * links dynamically against libxml.
- * For this to work, we need three macros. One tells us which compiler is
- * being used and luckily the compiler defines such a thing: _MSC_VER. The
- * second macro tells us if we are compiling libxml or the client code and
- * we define the macro IN_LIBXML on the compiler's command line for this
- * purpose. The third macro, LIBXML_STATIC, must be defined by any client
- * code which links against libxml statically.
- */
-#ifndef LIBXML_DLL_IMPORT
-#if (defined(_MSC_VER) || defined(__CYGWIN__)) && !defined(IN_LIBXML) && !defined(LIBXML_STATIC)
-#define LIBXML_DLL_IMPORT __declspec(dllimport)
-#else
-#define LIBXML_DLL_IMPORT
-#endif
-#endif
-
-/**
- * ATTRIBUTE_UNUSED:
- *
- * Macro used to signal to GCC unused function parameters
- */
-#ifdef __GNUC__
-#ifdef HAVE_ANSIDECL_H
-#include <ansidecl.h>
-#endif
-#ifndef ATTRIBUTE_UNUSED
-#define ATTRIBUTE_UNUSED
-#endif
-#else
-#define ATTRIBUTE_UNUSED
-#endif
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif
-
-
diff --git a/bundle/libxml/include/libxml/xmlversion.h.in b/bundle/libxml/include/libxml/xmlversion.h.in
deleted file mode 100644
index 94def1804b..0000000000
--- a/bundle/libxml/include/libxml/xmlversion.h.in
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * xmlversion.h : compile-time version informations for the XML parser.
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#ifndef __XML_VERSION_H__
-#define __XML_VERSION_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * use those to be sure nothing nasty will happen if
- * your library and includes mismatch
- */
-#ifndef LIBXML2_COMPILING_MSCCDEF
-extern void xmlCheckVersion(int version);
-#endif /* LIBXML2_COMPILING_MSCCDEF */
-
-/**
- * LIBXML_DOTTED_VERSION:
- *
- * the version string like "1.2.3"
- */
-#define LIBXML_DOTTED_VERSION "@VERSION@"
-
-/**
- * LIBXML_VERSION:
- *
- * the version number: 1.2.3 value is 1002003
- */
-#define LIBXML_VERSION @LIBXML_VERSION_NUMBER@
-
-/**
- * LIBXML_VERSION_STRING:
- *
- * the version number string, 1.2.3 value is "1002003"
- */
-#define LIBXML_VERSION_STRING "@LIBXML_VERSION_NUMBER@"
-
-/**
- * LIBXML_TEST_VERSION:
- *
- * Macro to check that the libxml version in use is compatible with
- * the version the software has been compiled against
- */
-#define LIBXML_TEST_VERSION xmlCheckVersion(@LIBXML_VERSION_NUMBER@);
-
-#ifndef VMS
-#if @WITH_TRIO@
-/**
- * WITH_TRIO:
- *
- * defined if the trio support need to be configured in
- */
-#define WITH_TRIO
-#else
-/**
- * WITHOUT_TRIO:
- *
- * defined if the trio support should not be configured in
- */
-#define WITHOUT_TRIO
-#endif
-#else /* VMS */
-#define WITH_TRIO 1
-#endif /* VMS */
-
-/**
- * LIBXML_THREAD_ENABLED:
- *
- * Whether the thread support is configured in
- */
-#if @WITH_THREADS@
-#if defined(_REENTRANT) || (_POSIX_C_SOURCE - 0 >= 199506L)
-#define LIBXML_THREAD_ENABLED
-#endif
-#endif
-
-/**
- * LIBXML_FTP_ENABLED:
- *
- * Whether the FTP support is configured in
- */
-#if @WITH_FTP@
-#define LIBXML_FTP_ENABLED
-#endif
-
-/**
- * LIBXML_HTTP_ENABLED:
- *
- * Whether the HTTP support is configured in
- */
-#if @WITH_HTTP@
-#define LIBXML_HTTP_ENABLED
-#endif
-
-/**
- * LIBXML_HTML_ENABLED:
- *
- * Whether the HTML support is configured in
- */
-#if @WITH_HTML@
-#define LIBXML_HTML_ENABLED
-#endif
-
-/**
- * LIBXML_C14N_ENABLED:
- *
- * Whether the Canonicalization support is configured in
- */
-#if @WITH_C14N@
-#define LIBXML_C14N_ENABLED
-#endif
-
-/**
- * LIBXML_CATALOG_ENABLED:
- *
- * Whether the Catalog support is configured in
- */
-#if @WITH_CATALOG@
-#define LIBXML_CATALOG_ENABLED
-#endif
-
-/**
- * LIBXML_DOCB_ENABLED:
- *
- * Whether the SGML Docbook support is configured in
- */
-#if @WITH_DOCB@
-#define LIBXML_DOCB_ENABLED
-#endif
-
-/**
- * LIBXML_XPATH_ENABLED:
- *
- * Whether XPath is configured in
- */
-#if @WITH_XPATH@
-#define LIBXML_XPATH_ENABLED
-#endif
-
-/**
- * LIBXML_XPTR_ENABLED:
- *
- * Whether XPointer is configured in
- */
-#if @WITH_XPTR@
-#define LIBXML_XPTR_ENABLED
-#endif
-
-/**
- * LIBXML_XINCLUDE_ENABLED:
- *
- * Whether XInclude is configured in
- */
-#if @WITH_XINCLUDE@
-#define LIBXML_XINCLUDE_ENABLED
-#endif
-
-/**
- * LIBXML_ICONV_ENABLED:
- *
- * Whether iconv support is available
- */
-#if @WITH_ICONV@
-#define LIBXML_ICONV_ENABLED
-#endif
-
-/**
- * LIBXML_DEBUG_ENABLED:
- *
- * Whether Debugging module is configured in
- */
-#if @WITH_DEBUG@
-#define LIBXML_DEBUG_ENABLED
-#endif
-
-/**
- * DEBUG_MEMORY_LOCATION:
- *
- * Whether the memory debugging is configured in
- */
-#if @WITH_MEM_DEBUG@
-#define DEBUG_MEMORY_LOCATION
-#endif
-
-/**
- * LIBXML_UNICODE_ENABLED
- *
- * Whether the Unicode related interfaces are compiled in
- */
-#if @WITH_REGEXPS@
-#define LIBXML_UNICODE_ENABLED
-#endif
-
-/**
- * LIBXML_REGEXP_ENABLED
- *
- * Whether the regular expressions interfaces are compiled in
- */
-#if @WITH_REGEXPS@
-#define LIBXML_REGEXP_ENABLED
-#endif
-
-/**
- * LIBXML_AUTOMATA_ENABLED
- *
- * Whether the automata interfaces are compiled in
- */
-#if @WITH_REGEXPS@
-#define LIBXML_AUTOMATA_ENABLED
-#endif
-
-/**
- * LIBXML_SCHEMAS_ENABLED
- *
- * Whether the Schemas validation interfaces are compiled in
- */
-#if @WITH_SCHEMAS@
-#define LIBXML_SCHEMAS_ENABLED
-#endif
-
-/**
- * LIBXML_DLL_IMPORT:
- *
- * Used on Windows (MS C compiler only) to declare a variable as
- * imported from the library. This macro should be empty when compiling
- * libxml itself. It should expand to __declspec(dllimport)
- * when the client code includes this header, and that only if the client
- * links dynamically against libxml.
- * For this to work, we need three macros. One tells us which compiler is
- * being used and luckily the compiler defines such a thing: _MSC_VER. The
- * second macro tells us if we are compiling libxml or the client code and
- * we define the macro IN_LIBXML on the compiler's command line for this
- * purpose. The third macro, LIBXML_STATIC, must be defined by any client
- * code which links against libxml statically.
- */
-#ifndef LIBXML_DLL_IMPORT
-#if (defined(_MSC_VER) || defined(__CYGWIN__)) && !defined(IN_LIBXML) && !defined(LIBXML_STATIC)
-#define LIBXML_DLL_IMPORT __declspec(dllimport)
-#else
-#define LIBXML_DLL_IMPORT
-#endif
-#endif
-
-/**
- * ATTRIBUTE_UNUSED:
- *
- * Macro used to signal to GCC unused function parameters
- */
-#ifdef __GNUC__
-#ifdef HAVE_ANSIDECL_H
-#include <ansidecl.h>
-#endif
-#ifndef ATTRIBUTE_UNUSED
-#define ATTRIBUTE_UNUSED
-#endif
-#else
-#define ATTRIBUTE_UNUSED
-#endif
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif
-
-
diff --git a/bundle/libxml/include/libxml/xpath.h b/bundle/libxml/include/libxml/xpath.h
deleted file mode 100644
index f36b16f938..0000000000
--- a/bundle/libxml/include/libxml/xpath.h
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * xpath.c: interface for XML Path Language implementation
- *
- * Reference: W3C Working Draft 5 July 1999
- * http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html
- *
- * See COPYRIGHT for the status of this software
- *
- * Author: daniel@veillard.com
- */
-
-#ifndef __XML_XPATH_H__
-#define __XML_XPATH_H__
-
-#include <libxml/tree.h>
-#include <libxml/hash.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct _xmlXPathContext xmlXPathContext;
-typedef xmlXPathContext *xmlXPathContextPtr;
-typedef struct _xmlXPathParserContext xmlXPathParserContext;
-typedef xmlXPathParserContext *xmlXPathParserContextPtr;
-
-/**
- * The set of XPath error codes.
- */
-
-typedef enum {
- XPATH_EXPRESSION_OK = 0,
- XPATH_NUMBER_ERROR,
- XPATH_UNFINISHED_LITERAL_ERROR,
- XPATH_START_LITERAL_ERROR,
- XPATH_VARIABLE_REF_ERROR,
- XPATH_UNDEF_VARIABLE_ERROR,
- XPATH_INVALID_PREDICATE_ERROR,
- XPATH_EXPR_ERROR,
- XPATH_UNCLOSED_ERROR,
- XPATH_UNKNOWN_FUNC_ERROR,
- XPATH_INVALID_OPERAND,
- XPATH_INVALID_TYPE,
- XPATH_INVALID_ARITY,
- XPATH_INVALID_CTXT_SIZE,
- XPATH_INVALID_CTXT_POSITION,
- XPATH_MEMORY_ERROR,
- XPTR_SYNTAX_ERROR,
- XPTR_RESOURCE_ERROR,
- XPTR_SUB_RESOURCE_ERROR,
- XPATH_UNDEF_PREFIX_ERROR,
- XPATH_ENCODING_ERROR,
- XPATH_INVALID_CHAR_ERROR
-} xmlXPathError;
-
-/*
- * A node-set (an unordered collection of nodes without duplicates).
- */
-typedef struct _xmlNodeSet xmlNodeSet;
-typedef xmlNodeSet *xmlNodeSetPtr;
-struct _xmlNodeSet {
- int nodeNr; /* number of nodes in the set */
- int nodeMax; /* size of the array as allocated */
- xmlNodePtr *nodeTab; /* array of nodes in no particular order */
- /* @@ with_ns to check wether namespace nodes should be looked at @@ */
-};
-
-/*
- * An expression is evaluated to yield an object, which
- * has one of the following four basic types:
- * - node-set
- * - boolean
- * - number
- * - string
- *
- * @@ XPointer will add more types !
- */
-
-typedef enum {
- XPATH_UNDEFINED = 0,
- XPATH_NODESET = 1,
- XPATH_BOOLEAN = 2,
- XPATH_NUMBER = 3,
- XPATH_STRING = 4,
- XPATH_POINT = 5,
- XPATH_RANGE = 6,
- XPATH_LOCATIONSET = 7,
- XPATH_USERS = 8,
- XPATH_XSLT_TREE = 9 /* An XSLT value tree, non modifiable */
-} xmlXPathObjectType;
-
-typedef struct _xmlXPathObject xmlXPathObject;
-typedef xmlXPathObject *xmlXPathObjectPtr;
-struct _xmlXPathObject {
- xmlXPathObjectType type;
- xmlNodeSetPtr nodesetval;
- int boolval;
- double floatval;
- xmlChar *stringval;
- void *user;
- int index;
- void *user2;
- int index2;
-};
-
-/**
- * xmlXPathConvertFunc:
- * @obj: an XPath object
- * @type: the number of the target type
- *
- * A conversion function is associated to a type and used to cast
- * the new type to primitive values.
- *
- * Returns -1 in case of error, 0 otherwise
- */
-typedef int (*xmlXPathConvertFunc) (xmlXPathObjectPtr obj, int type);
-
-/*
- * Extra type: a name and a conversion function.
- */
-
-typedef struct _xmlXPathType xmlXPathType;
-typedef xmlXPathType *xmlXPathTypePtr;
-struct _xmlXPathType {
- const xmlChar *name; /* the type name */
- xmlXPathConvertFunc func; /* the conversion function */
-};
-
-/*
- * Extra variable: a name and a value.
- */
-
-typedef struct _xmlXPathVariable xmlXPathVariable;
-typedef xmlXPathVariable *xmlXPathVariablePtr;
-struct _xmlXPathVariable {
- const xmlChar *name; /* the variable name */
- xmlXPathObjectPtr value; /* the value */
-};
-
-/**
- * xmlXPathEvalFunc:
- * @ctxt: an XPath parser context
- * @nargs: the number of arguments passed to the function
- *
- * An XPath evaluation function, the parameters are on the XPath context stack.
- */
-
-typedef void (*xmlXPathEvalFunc)(xmlXPathParserContextPtr ctxt,
- int nargs);
-
-/*
- * Extra function: a name and a evaluation function.
- */
-
-typedef struct _xmlXPathFunct xmlXPathFunct;
-typedef xmlXPathFunct *xmlXPathFuncPtr;
-struct _xmlXPathFunct {
- const xmlChar *name; /* the function name */
- xmlXPathEvalFunc func; /* the evaluation function */
-};
-
-/**
- * xmlXPathAxisFunc:
- * @ctxt: the XPath interpreter context
- * @cur: the previous node being explored on that axis
- *
- * An axis traversal function. To traverse an axis, the engine calls
- * the first time with cur == NULL and repeat until the function returns
- * NULL indicating the end of the axis traversal.
- *
- * Returns the next node in that axis or NULL if at the end of the axis.
- */
-
-typedef xmlXPathObjectPtr (*xmlXPathAxisFunc) (xmlXPathParserContextPtr ctxt,
- xmlXPathObjectPtr cur);
-
-/*
- * Extra axis: a name and an axis function.
- */
-
-typedef struct _xmlXPathAxis xmlXPathAxis;
-typedef xmlXPathAxis *xmlXPathAxisPtr;
-struct _xmlXPathAxis {
- const xmlChar *name; /* the axis name */
- xmlXPathAxisFunc func; /* the search function */
-};
-
-/**
- * xmlXPathContext:
- *
- * Expression evaluation occurs with respect to a context.
- * he context consists of:
- * - a node (the context node)
- * - a node list (the context node list)
- * - a set of variable bindings
- * - a function library
- * - the set of namespace declarations in scope for the expression
- * Following the switch to hash tables, this need to be trimmed up at
- * the next binary incompatible release.
- */
-
-struct _xmlXPathContext {
- xmlDocPtr doc; /* The current document */
- xmlNodePtr node; /* The current node */
-
- int nb_variables_unused; /* unused (hash table) */
- int max_variables_unused; /* unused (hash table) */
- xmlHashTablePtr varHash; /* Hash table of defined variables */
-
- int nb_types; /* number of defined types */
- int max_types; /* max number of types */
- xmlXPathTypePtr types; /* Array of defined types */
-
- int nb_funcs_unused; /* unused (hash table) */
- int max_funcs_unused; /* unused (hash table) */
- xmlHashTablePtr funcHash; /* Hash table of defined funcs */
-
- int nb_axis; /* number of defined axis */
- int max_axis; /* max number of axis */
- xmlXPathAxisPtr axis; /* Array of defined axis */
-
- /* the namespace nodes of the context node */
- xmlNsPtr *namespaces; /* Array of namespaces */
- int nsNr; /* number of namespace in scope */
- void *user; /* function to free */
-
- /* extra variables */
- int contextSize; /* the context size */
- int proximityPosition; /* the proximity position */
-
- /* extra stuff for XPointer */
- int xptr; /* it this an XPointer context */
- xmlNodePtr here; /* for here() */
- xmlNodePtr origin; /* for origin() */
-
- /* the set of namespace declarations in scope for the expression */
- xmlHashTablePtr nsHash; /* The namespaces hash table */
- void *varLookupFunc; /* variable lookup func */
- void *varLookupData; /* variable lookup data */
-
- /* Possibility to link in an extra item */
- void *extra; /* needed for XSLT */
-
- /* The function name and URI when calling a function */
- const xmlChar *function;
- const xmlChar *functionURI;
-
- /* function lookup function and data */
- void *funcLookupFunc; /* function lookup func */
- void *funcLookupData; /* function lookup data */
-
- /* temporary namespace lists kept for walking the namespace axis */
- xmlNsPtr *tmpNsList; /* Array of namespaces */
- int tmpNsNr; /* number of namespace in scope */
-};
-
-/*
- * The structure of a compiled expression form is not public.
- */
-
-typedef struct _xmlXPathCompExpr xmlXPathCompExpr;
-typedef xmlXPathCompExpr *xmlXPathCompExprPtr;
-
-/**
- * xmlXPathParserContext:
- *
- * An XPath parser context. It contains pure parsing informations,
- * an xmlXPathContext, and the stack of objects.
- */
-struct _xmlXPathParserContext {
- const xmlChar *cur; /* the current char being parsed */
- const xmlChar *base; /* the full expression */
-
- int error; /* error code */
-
- xmlXPathContextPtr context; /* the evaluation context */
- xmlXPathObjectPtr value; /* the current value */
- int valueNr; /* number of values stacked */
- int valueMax; /* max number of values stacked */
- xmlXPathObjectPtr *valueTab; /* stack of values */
-
- xmlXPathCompExprPtr comp; /* the precompiled expression */
- int xptr; /* it this an XPointer expression */
- xmlNodePtr ancestor; /* used for walking preceding axis */
-};
-
-/**
- * xmlXPathFunction:
- * @ctxt: the XPath interprestation context
- * @nargs: the number of arguments
- *
- * An XPath function.
- * The arguments (if any) are popped out from the context stack
- * and the result is pushed on the stack.
- */
-
-typedef void (*xmlXPathFunction) (xmlXPathParserContextPtr ctxt, int nargs);
-
-/************************************************************************
- * *
- * Public API *
- * *
- ************************************************************************/
-
-/**
- * Objects and Nodesets handling
- */
-
-LIBXML_DLL_IMPORT extern double xmlXPathNAN;
-LIBXML_DLL_IMPORT extern double xmlXPathPINF;
-LIBXML_DLL_IMPORT extern double xmlXPathNINF;
-
-int xmlXPathIsNaN (double val);
-int xmlXPathIsInf (double val);
-
-/* These macros may later turn into functions */
-/**
- * xmlXPathNodeSetGetLength:
- * @ns: a node-set
- *
- * Implement a functionality similar to the DOM NodeList.length.
- *
- * Returns the number of nodes in the node-set.
- */
-#define xmlXPathNodeSetGetLength(ns) ((ns) ? (ns)->nodeNr : 0)
-/**
- * xmlXPathNodeSetItem:
- * @ns: a node-set
- * @index: index of a node in the set
- *
- * Implements a functionality similar to the DOM NodeList.item().
- *
- * Returns the xmlNodePtr at the given @index in @ns or NULL if
- * @index is out of range (0 to length-1)
- */
-#define xmlXPathNodeSetItem(ns, index) \
- ((((ns) != NULL) && \
- ((index) >= 0) && ((index) < (ns)->nodeNr)) ? \
- (ns)->nodeTab[(index)] \
- : NULL)
-/**
- * xmlXPathNodeSetIsEmpty:
- * @ns: a node-set
- *
- * Checks whether @ns is empty or not.
- *
- * Returns %TRUE if @ns is an empty node-set.
- */
-#define xmlXPathNodeSetIsEmpty(ns) \
- (((ns) == NULL) || ((ns)->nodeNr == 0) || ((ns)->nodeTab == NULL))
-
-
-void xmlXPathFreeObject (xmlXPathObjectPtr obj);
-xmlNodeSetPtr xmlXPathNodeSetCreate (xmlNodePtr val);
-void xmlXPathFreeNodeSetList (xmlXPathObjectPtr obj);
-void xmlXPathFreeNodeSet (xmlNodeSetPtr obj);
-xmlXPathObjectPtr xmlXPathObjectCopy (xmlXPathObjectPtr val);
-int xmlXPathCmpNodes (xmlNodePtr node1,
- xmlNodePtr node2);
-/**
- * Conversion functions to basic types.
- */
-int xmlXPathCastNumberToBoolean (double val);
-int xmlXPathCastStringToBoolean (const xmlChar * val);
-int xmlXPathCastNodeSetToBoolean (xmlNodeSetPtr ns);
-int xmlXPathCastToBoolean (xmlXPathObjectPtr val);
-
-double xmlXPathCastBooleanToNumber (int val);
-double xmlXPathCastStringToNumber (const xmlChar * val);
-double xmlXPathCastNodeToNumber (xmlNodePtr node);
-double xmlXPathCastNodeSetToNumber (xmlNodeSetPtr ns);
-double xmlXPathCastToNumber (xmlXPathObjectPtr val);
-
-xmlChar * xmlXPathCastBooleanToString (int val);
-xmlChar * xmlXPathCastNumberToString (double val);
-xmlChar * xmlXPathCastNodeToString (xmlNodePtr node);
-xmlChar * xmlXPathCastNodeSetToString (xmlNodeSetPtr ns);
-xmlChar * xmlXPathCastToString (xmlXPathObjectPtr val);
-
-xmlXPathObjectPtr xmlXPathConvertBoolean (xmlXPathObjectPtr val);
-xmlXPathObjectPtr xmlXPathConvertNumber (xmlXPathObjectPtr val);
-xmlXPathObjectPtr xmlXPathConvertString (xmlXPathObjectPtr val);
-
-/**
- * Context handling.
- */
-void xmlXPathInit (void);
-xmlXPathContextPtr xmlXPathNewContext (xmlDocPtr doc);
-void xmlXPathFreeContext (xmlXPathContextPtr ctxt);
-
-/**
- * Evaluation functions.
- */
-xmlXPathObjectPtr xmlXPathEval (const xmlChar *str,
- xmlXPathContextPtr ctx);
-xmlXPathObjectPtr xmlXPathEvalExpression (const xmlChar *str,
- xmlXPathContextPtr ctxt);
-int xmlXPathEvalPredicate (xmlXPathContextPtr ctxt,
- xmlXPathObjectPtr res);
-/**
- * Separate compilation/evaluation entry points.
- */
-xmlXPathCompExprPtr xmlXPathCompile (const xmlChar *str);
-xmlXPathObjectPtr xmlXPathCompiledEval (xmlXPathCompExprPtr comp,
- xmlXPathContextPtr ctx);
-void xmlXPathFreeCompExpr (xmlXPathCompExprPtr comp);
-#ifdef __cplusplus
-}
-#endif
-#endif /* ! __XML_XPATH_H__ */
diff --git a/bundle/libxml/include/libxml/xpathInternals.h b/bundle/libxml/include/libxml/xpathInternals.h
deleted file mode 100644
index 59a4e35d53..0000000000
--- a/bundle/libxml/include/libxml/xpathInternals.h
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
- * xpathInternals.c: internal interfaces for XML Path Language implementation
- * used to build new modules on top of XPath
- *
- * See COPYRIGHT for the status of this software
- *
- * Author: daniel@veillard.com
- */
-
-#ifndef __XML_XPATH_INTERNALS_H__
-#define __XML_XPATH_INTERNALS_H__
-
-#include <libxml/xmlversion.h>
-#include <libxml/xpath.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/************************************************************************
- * *
- * Helpers *
- * *
- ************************************************************************/
-
-/**
- * Many of these macros may later turn into functions. They
- * shouldn't be used in #ifdef's preprocessor instructions.
- */
-/**
- * xmlXPathSetError:
- * @ctxt: an XPath parser context
- * @err: an xmlXPathError code
- *
- * Raises an error.
- */
-#define xmlXPathSetError(ctxt, err) \
- { xmlXPatherror((ctxt), __FILE__, __LINE__, (err)); \
- (ctxt)->error = (err); }
-
-/**
- * xmlXPathSetArityError:
- * @ctxt: an XPath parser context
- *
- * Raises an XPATH_INVALID_ARITY error.
- */
-#define xmlXPathSetArityError(ctxt) \
- xmlXPathSetError((ctxt), XPATH_INVALID_ARITY)
-
-/**
- * xmlXPathSetTypeError:
- * @ctxt: an XPath parser context
- *
- * Raises an XPATH_INVALID_TYPE error.
- */
-#define xmlXPathSetTypeError(ctxt) \
- xmlXPathSetError((ctxt), XPATH_INVALID_TYPE)
-
-/**
- * xmlXPathGetError:
- * @ctxt: an XPath parser context
- *
- * Get the error code of an XPath context.
- *
- * Returns the context error.
- */
-#define xmlXPathGetError(ctxt) ((ctxt)->error)
-
-/**
- * xmlXPathCheckError:
- * @ctxt: an XPath parser context
- *
- * Check if an XPath error was raised.
- *
- * Returns true if an error has been raised, false otherwise.
- */
-#define xmlXPathCheckError(ctxt) ((ctxt)->error != XPATH_EXPRESSION_OK)
-
-/**
- * xmlXPathGetDocument:
- * @ctxt: an XPath parser context
- *
- * Get the document of an XPath context.
- *
- * Returns the context document.
- */
-#define xmlXPathGetDocument(ctxt) ((ctxt)->context->doc)
-
-/**
- * xmlXPathGetContextNode:
- * @ctxt: an XPath parser context
- *
- * Get the context node of an XPath context.
- *
- * Returns the context node.
- */
-#define xmlXPathGetContextNode(ctxt) ((ctxt)->context->node)
-
-int xmlXPathPopBoolean (xmlXPathParserContextPtr ctxt);
-double xmlXPathPopNumber (xmlXPathParserContextPtr ctxt);
-xmlChar * xmlXPathPopString (xmlXPathParserContextPtr ctxt);
-xmlNodeSetPtr xmlXPathPopNodeSet (xmlXPathParserContextPtr ctxt);
-void * xmlXPathPopExternal (xmlXPathParserContextPtr ctxt);
-
-/**
- * xmlXPathReturnBoolean:
- * @ctxt: an XPath parser context
- * @val: a boolean
- *
- * Pushes the boolean @val on the context stack.
- */
-#define xmlXPathReturnBoolean(ctxt, val) \
- valuePush((ctxt), xmlXPathNewBoolean(val))
-
-/**
- * xmlXPathReturnTrue:
- * @ctxt: an XPath parser context
- *
- * Pushes true on the context stack.
- */
-#define xmlXPathReturnTrue(ctxt) xmlXPathReturnBoolean((ctxt), 1)
-
-/**
- * xmlXPathReturnFalse:
- * @ctxt: an XPath parser context
- *
- * Pushes false on the context stack.
- */
-#define xmlXPathReturnFalse(ctxt) xmlXPathReturnBoolean((ctxt), 0)
-
-/**
- * xmlXPathReturnNumber:
- * @ctxt: an XPath parser context
- * @val: a double
- *
- * Pushes the double @val on the context stack.
- */
-#define xmlXPathReturnNumber(ctxt, val) \
- valuePush((ctxt), xmlXPathNewFloat(val))
-
-/**
- * xmlXPathReturnString:
- * @ctxt: an XPath parser context
- * @str: a string
- *
- * Pushes the string @str on the context stack.
- */
-#define xmlXPathReturnString(ctxt, str) \
- valuePush((ctxt), xmlXPathWrapString(str))
-
-/**
- * xmlXPathReturnEmptyString:
- * @ctxt: an XPath parser context
- *
- * Pushes an empty string on the stack.
- */
-#define xmlXPathReturnEmptyString(ctxt) \
- valuePush((ctxt), xmlXPathNewCString(""))
-
-/**
- * xmlXPathReturnNodeSet:
- * @ctxt: an XPath parser context
- * @ns: a node-set
- *
- * Pushes the node-set @ns on the context stack.
- */
-#define xmlXPathReturnNodeSet(ctxt, ns) \
- valuePush((ctxt), xmlXPathWrapNodeSet(ns))
-
-/**
- * xmlXPathReturnEmptyNodeSet:
- * @ctxt: an XPath parser context
- *
- * Pushes an empty node-set on the context stack.
- */
-#define xmlXPathReturnEmptyNodeSet(ctxt) \
- valuePush((ctxt), xmlXPathNewNodeSet(NULL))
-
-/**
- * xmlXPathReturnExternal:
- * @ctxt: an XPath parser context
- * @val: user data
- *
- * Pushes user data on the context stack.
- */
-#define xmlXPathReturnExternal(ctxt, val) \
- valuePush((ctxt), xmlXPathWrapExternal(val))
-
-/**
- * xmlXPathStackIsNodeSet:
- * @ctxt: an XPath parser context
- *
- * Check if the current value on the XPath stack is a node set or
- * an XSLT value tree.
- *
- * Returns true if the current object on the stack is a node-set.
- */
-#define xmlXPathStackIsNodeSet(ctxt) \
- (((ctxt)->value != NULL) \
- && (((ctxt)->value->type == XPATH_NODESET) \
- || ((ctxt)->value->type == XPATH_XSLT_TREE)))
-
-/**
- * xmlXPathStackIsExternal:
- * @ctxt: an XPath parser context
- *
- * Checks if the current value on the XPath stack is an external
- * object.
- *
- * Returns true if the current object on the stack is an external
- * object.
- */
-#define xmlXPathStackIsExternal(ctxt) \
- ((ctxt->value != NULL) && (ctxt->value->type == XPATH_USERS))
-
-/**
- * xmlXPathEmptyNodeSet:
- * @ns: a node-set
- *
- * Empties a node-set.
- */
-#define xmlXPathEmptyNodeSet(ns) \
- { while ((ns)->nodeNr > 0) (ns)->nodeTab[(ns)->nodeNr--] = NULL; }
-
-/**
- * CHECK_ERROR:
- *
- * Macro to return from the function if an XPath error was detected.
- */
-#define CHECK_ERROR \
- if (ctxt->error != XPATH_EXPRESSION_OK) return
-
-/**
- * CHECK_ERROR0:
- *
- * Macro to return 0 from the function if an XPath error was detected.
- */
-#define CHECK_ERROR0 \
- if (ctxt->error != XPATH_EXPRESSION_OK) return(0)
-
-/**
- * XP_ERROR:
- * @X: the error code
- *
- * Macro to raise an XPath error and return.
- */
-#define XP_ERROR(X) \
- { xmlXPatherror(ctxt, __FILE__, __LINE__, X); \
- ctxt->error = (X); return; }
-
-/**
- * XP_ERROR0:
- * @X: the error code
- *
- * Macro to raise an XPath error and return 0.
- */
-#define XP_ERROR0(X) \
- { xmlXPatherror(ctxt, __FILE__, __LINE__, X); \
- ctxt->error = (X); return(0); }
-
-/**
- * CHECK_TYPE:
- * @typeval: the XPath type
- *
- * Macro to check that the value on top of the XPath stack is of a given
- * type.
- */
-#define CHECK_TYPE(typeval) \
- if ((ctxt->value == NULL) || (ctxt->value->type != typeval)) \
- XP_ERROR(XPATH_INVALID_TYPE)
-
-/**
- * CHECK_TYPE0:
- * @typeval: the XPath type
- *
- * Macro to check that the value on top of the XPath stack is of a given
- * type. Return(0) in case of failure
- */
-#define CHECK_TYPE0(typeval) \
- if ((ctxt->value == NULL) || (ctxt->value->type != typeval)) \
- XP_ERROR0(XPATH_INVALID_TYPE)
-
-/**
- * CHECK_ARITY:
- * @x: the number of expected args
- *
- * Macro to check that the number of args passed to an XPath function matches.
- */
-#define CHECK_ARITY(x) \
- if (nargs != (x)) \
- XP_ERROR(XPATH_INVALID_ARITY);
-
-/**
- * CAST_TO_STRING:
- *
- * Macro to try to cast the value on the top of the XPath stack to a string.
- */
-#define CAST_TO_STRING \
- if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_STRING)) \
- xmlXPathStringFunction(ctxt, 1);
-
-/**
- * CAST_TO_NUMBER:
- *
- * Macro to try to cast the value on the top of the XPath stack to a number.
- */
-#define CAST_TO_NUMBER \
- if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_NUMBER)) \
- xmlXPathNumberFunction(ctxt, 1);
-
-/**
- * CAST_TO_BOOLEAN:
- *
- * Macro to try to cast the value on the top of the XPath stack to a boolean.
- */
-#define CAST_TO_BOOLEAN \
- if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_BOOLEAN)) \
- xmlXPathBooleanFunction(ctxt, 1);
-
-/*
- * Variable Lookup forwarding.
- */
-/**
- * xmlXPathVariableLookupFunc:
- * @ctxt: an XPath context
- * @name: name of the variable
- * @ns_uri: the namespace name hosting this variable
- *
- * Prototype for callbacks used to plug variable lookup in the XPath
- * engine.
- *
- * Returns the XPath object value or NULL if not found.
- */
-typedef xmlXPathObjectPtr (*xmlXPathVariableLookupFunc) (void *ctxt,
- const xmlChar *name,
- const xmlChar *ns_uri);
-
-void xmlXPathRegisterVariableLookup (xmlXPathContextPtr ctxt,
- xmlXPathVariableLookupFunc f,
- void *data);
-
-/*
- * Function Lookup forwarding.
- */
-/**
- * xmlXPathFuncLookupFunc:
- * @ctxt: an XPath context
- * @name: name of the function
- * @ns_uri: the namespace name hosting this function
- *
- * Prototype for callbacks used to plug function lookup in the XPath
- * engine.
- *
- * Returns the XPath function or NULL if not found.
- */
-typedef xmlXPathFunction (*xmlXPathFuncLookupFunc) (void *ctxt,
- const xmlChar *name,
- const xmlChar *ns_uri);
-
-void xmlXPathRegisterFuncLookup (xmlXPathContextPtr ctxt,
- xmlXPathFuncLookupFunc f,
- void *funcCtxt);
-
-/*
- * Error reporting.
- */
-void xmlXPatherror (xmlXPathParserContextPtr ctxt,
- const char *file,
- int line,
- int no);
-
-void xmlXPathDebugDumpObject (FILE *output,
- xmlXPathObjectPtr cur,
- int depth);
-void xmlXPathDebugDumpCompExpr(FILE *output,
- xmlXPathCompExprPtr comp,
- int depth);
-
-/**
- * NodeSet handling.
- */
-int xmlXPathNodeSetContains (xmlNodeSetPtr cur,
- xmlNodePtr val);
-xmlNodeSetPtr xmlXPathDifference (xmlNodeSetPtr nodes1,
- xmlNodeSetPtr nodes2);
-xmlNodeSetPtr xmlXPathIntersection (xmlNodeSetPtr nodes1,
- xmlNodeSetPtr nodes2);
-
-xmlNodeSetPtr xmlXPathDistinctSorted (xmlNodeSetPtr nodes);
-xmlNodeSetPtr xmlXPathDistinct (xmlNodeSetPtr nodes);
-
-int xmlXPathHasSameNodes (xmlNodeSetPtr nodes1,
- xmlNodeSetPtr nodes2);
-
-xmlNodeSetPtr xmlXPathNodeLeadingSorted (xmlNodeSetPtr nodes,
- xmlNodePtr node);
-xmlNodeSetPtr xmlXPathLeadingSorted (xmlNodeSetPtr nodes1,
- xmlNodeSetPtr nodes2);
-xmlNodeSetPtr xmlXPathNodeLeading (xmlNodeSetPtr nodes,
- xmlNodePtr node);
-xmlNodeSetPtr xmlXPathLeading (xmlNodeSetPtr nodes1,
- xmlNodeSetPtr nodes2);
-
-xmlNodeSetPtr xmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes,
- xmlNodePtr node);
-xmlNodeSetPtr xmlXPathTrailingSorted (xmlNodeSetPtr nodes1,
- xmlNodeSetPtr nodes2);
-xmlNodeSetPtr xmlXPathNodeTrailing (xmlNodeSetPtr nodes,
- xmlNodePtr node);
-xmlNodeSetPtr xmlXPathTrailing (xmlNodeSetPtr nodes1,
- xmlNodeSetPtr nodes2);
-
-
-/**
- * Extending a context.
- */
-
-int xmlXPathRegisterNs (xmlXPathContextPtr ctxt,
- const xmlChar *prefix,
- const xmlChar *ns_uri);
-const xmlChar * xmlXPathNsLookup (xmlXPathContextPtr ctxt,
- const xmlChar *prefix);
-void xmlXPathRegisteredNsCleanup (xmlXPathContextPtr ctxt);
-
-int xmlXPathRegisterFunc (xmlXPathContextPtr ctxt,
- const xmlChar *name,
- xmlXPathFunction f);
-int xmlXPathRegisterFuncNS (xmlXPathContextPtr ctxt,
- const xmlChar *name,
- const xmlChar *ns_uri,
- xmlXPathFunction f);
-int xmlXPathRegisterVariable (xmlXPathContextPtr ctxt,
- const xmlChar *name,
- xmlXPathObjectPtr value);
-int xmlXPathRegisterVariableNS (xmlXPathContextPtr ctxt,
- const xmlChar *name,
- const xmlChar *ns_uri,
- xmlXPathObjectPtr value);
-xmlXPathFunction xmlXPathFunctionLookup (xmlXPathContextPtr ctxt,
- const xmlChar *name);
-xmlXPathFunction xmlXPathFunctionLookupNS (xmlXPathContextPtr ctxt,
- const xmlChar *name,
- const xmlChar *ns_uri);
-void xmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt);
-xmlXPathObjectPtr xmlXPathVariableLookup (xmlXPathContextPtr ctxt,
- const xmlChar *name);
-xmlXPathObjectPtr xmlXPathVariableLookupNS (xmlXPathContextPtr ctxt,
- const xmlChar *name,
- const xmlChar *ns_uri);
-void xmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt);
-
-/**
- * Utilities to extend XPath.
- */
-xmlXPathParserContextPtr
- xmlXPathNewParserContext (const xmlChar *str,
- xmlXPathContextPtr ctxt);
-void xmlXPathFreeParserContext (xmlXPathParserContextPtr ctxt);
-
-/* TODO: remap to xmlXPathValuePop and Push. */
-xmlXPathObjectPtr valuePop (xmlXPathParserContextPtr ctxt);
-int valuePush (xmlXPathParserContextPtr ctxt,
- xmlXPathObjectPtr value);
-
-xmlXPathObjectPtr xmlXPathNewString (const xmlChar *val);
-xmlXPathObjectPtr xmlXPathNewCString (const char *val);
-xmlXPathObjectPtr xmlXPathWrapString (xmlChar *val);
-xmlXPathObjectPtr xmlXPathWrapCString (char * val);
-xmlXPathObjectPtr xmlXPathNewFloat (double val);
-xmlXPathObjectPtr xmlXPathNewBoolean (int val);
-xmlXPathObjectPtr xmlXPathNewNodeSet (xmlNodePtr val);
-xmlXPathObjectPtr xmlXPathNewValueTree (xmlNodePtr val);
-void xmlXPathNodeSetAdd (xmlNodeSetPtr cur,
- xmlNodePtr val);
-void xmlXPathNodeSetAddUnique (xmlNodeSetPtr cur,
- xmlNodePtr val);
-void xmlXPathNodeSetAddNs (xmlNodeSetPtr cur,
- xmlNodePtr node,
- xmlNsPtr ns);
-void xmlXPathNodeSetSort (xmlNodeSetPtr set);
-
-void xmlXPathRoot (xmlXPathParserContextPtr ctxt);
-void xmlXPathEvalExpr (xmlXPathParserContextPtr ctxt);
-xmlChar * xmlXPathParseName (xmlXPathParserContextPtr ctxt);
-xmlChar * xmlXPathParseNCName (xmlXPathParserContextPtr ctxt);
-
-/*
- * Existing functions.
- */
-double xmlXPathStringEvalNumber(const xmlChar *str);
-int xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
- xmlXPathObjectPtr res);
-void xmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt);
-xmlNodeSetPtr xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2);
-void xmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val);
-void xmlXPathNodeSetRemove(xmlNodeSetPtr cur, int val);
-xmlXPathObjectPtr xmlXPathNewNodeSetList(xmlNodeSetPtr val);
-xmlXPathObjectPtr xmlXPathWrapNodeSet(xmlNodeSetPtr val);
-xmlXPathObjectPtr xmlXPathWrapExternal(void *val);
-
-int xmlXPathEqualValues(xmlXPathParserContextPtr ctxt);
-int xmlXPathNotEqualValues(xmlXPathParserContextPtr ctxt);
-int xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict);
-void xmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt);
-void xmlXPathAddValues(xmlXPathParserContextPtr ctxt);
-void xmlXPathSubValues(xmlXPathParserContextPtr ctxt);
-void xmlXPathMultValues(xmlXPathParserContextPtr ctxt);
-void xmlXPathDivValues(xmlXPathParserContextPtr ctxt);
-void xmlXPathModValues(xmlXPathParserContextPtr ctxt);
-
-int xmlXPathIsNodeType(const xmlChar *name);
-
-/*
- * Some of the axis navigation routines.
- */
-xmlNodePtr xmlXPathNextSelf(xmlXPathParserContextPtr ctxt,
- xmlNodePtr cur);
-xmlNodePtr xmlXPathNextChild(xmlXPathParserContextPtr ctxt,
- xmlNodePtr cur);
-xmlNodePtr xmlXPathNextDescendant(xmlXPathParserContextPtr ctxt,
- xmlNodePtr cur);
-xmlNodePtr xmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt,
- xmlNodePtr cur);
-xmlNodePtr xmlXPathNextParent(xmlXPathParserContextPtr ctxt,
- xmlNodePtr cur);
-xmlNodePtr xmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt,
- xmlNodePtr cur);
-xmlNodePtr xmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt,
- xmlNodePtr cur);
-xmlNodePtr xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt,
- xmlNodePtr cur);
-xmlNodePtr xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt,
- xmlNodePtr cur);
-xmlNodePtr xmlXPathNextAttribute(xmlXPathParserContextPtr ctxt,
- xmlNodePtr cur);
-xmlNodePtr xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt,
- xmlNodePtr cur);
-xmlNodePtr xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt,
- xmlNodePtr cur);
-xmlNodePtr xmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt,
- xmlNodePtr cur);
-/*
- * The official core of XPath functions.
- */
-void xmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs);
-
-/**
- * Really internal functions
- */
-void xmlXPathNodeSetFreeNs(xmlNsPtr ns);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* ! __XML_XPATH_INTERNALS_H__ */
diff --git a/bundle/libxml/include/libxml/xpointer.h b/bundle/libxml/include/libxml/xpointer.h
deleted file mode 100644
index 80c465c70f..0000000000
--- a/bundle/libxml/include/libxml/xpointer.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * xpointer.h : API to handle XML Pointers
- *
- * World Wide Web Consortium Working Draft 03-March-1998
- * http://www.w3.org/TR/1998/WD-xptr-19980303
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#ifndef __XML_XPTR_H__
-#define __XML_XPTR_H__
-
-#include <libxml/tree.h>
-#include <libxml/xpath.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * A Location Set
- */
-typedef struct _xmlLocationSet xmlLocationSet;
-typedef xmlLocationSet *xmlLocationSetPtr;
-struct _xmlLocationSet {
- int locNr; /* number of locations in the set */
- int locMax; /* size of the array as allocated */
- xmlXPathObjectPtr *locTab;/* array of locations */
-};
-
-/*
- * Handling of location sets.
- */
-
-xmlLocationSetPtr xmlXPtrLocationSetCreate(xmlXPathObjectPtr val);
-void xmlXPtrFreeLocationSet (xmlLocationSetPtr obj);
-xmlLocationSetPtr xmlXPtrLocationSetMerge (xmlLocationSetPtr val1,
- xmlLocationSetPtr val2);
-xmlXPathObjectPtr xmlXPtrNewRange (xmlNodePtr start,
- int startindex,
- xmlNodePtr end,
- int endindex);
-xmlXPathObjectPtr xmlXPtrNewRangePoints (xmlXPathObjectPtr start,
- xmlXPathObjectPtr end);
-xmlXPathObjectPtr xmlXPtrNewRangeNodePoint(xmlNodePtr start,
- xmlXPathObjectPtr end);
-xmlXPathObjectPtr xmlXPtrNewRangePointNode(xmlXPathObjectPtr start,
- xmlNodePtr end);
-xmlXPathObjectPtr xmlXPtrNewRangeNodes (xmlNodePtr start,
- xmlNodePtr end);
-xmlXPathObjectPtr xmlXPtrNewLocationSetNodes(xmlNodePtr start,
- xmlNodePtr end);
-xmlXPathObjectPtr xmlXPtrNewLocationSetNodeSet(xmlNodeSetPtr set);
-xmlXPathObjectPtr xmlXPtrNewRangeNodeObject(xmlNodePtr start,
- xmlXPathObjectPtr end);
-xmlXPathObjectPtr xmlXPtrNewCollapsedRange(xmlNodePtr start);
-void xmlXPtrLocationSetAdd (xmlLocationSetPtr cur,
- xmlXPathObjectPtr val);
-xmlXPathObjectPtr xmlXPtrWrapLocationSet (xmlLocationSetPtr val);
-void xmlXPtrLocationSetDel (xmlLocationSetPtr cur,
- xmlXPathObjectPtr val);
-void xmlXPtrLocationSetRemove(xmlLocationSetPtr cur,
- int val);
-
-/*
- * Functions.
- */
-xmlXPathContextPtr xmlXPtrNewContext (xmlDocPtr doc,
- xmlNodePtr here,
- xmlNodePtr origin);
-xmlXPathObjectPtr xmlXPtrEval (const xmlChar *str,
- xmlXPathContextPtr ctx);
-void xmlXPtrRangeToFunction (xmlXPathParserContextPtr ctxt,
- int nargs);
-xmlNodePtr xmlXPtrBuildNodeList (xmlXPathObjectPtr obj);
-void xmlXPtrEvalRangePredicate (xmlXPathParserContextPtr ctxt);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* __XML_XPTR_H__ */
diff --git a/bundle/libxml/include/win32config.h b/bundle/libxml/include/win32config.h
deleted file mode 100644
index 5b004798cc..0000000000
--- a/bundle/libxml/include/win32config.h
+++ /dev/null
@@ -1,111 +0,0 @@
-#ifndef __LIBXML_WIN32_CONFIG__
-#define __LIBXML_WIN32_CONFIG__
-
-#define HAVE_CTYPE_H
-#define HAVE_STDARG_H
-#define HAVE_MALLOC_H
-#define HAVE_ERRNO_H
-
-#ifdef _WIN32_WCE
-#undef HAVE_ERRNO_H
-#include <windows.h>
-#include "wincecompat.h"
-#else
-#define HAVE_SYS_STAT_H
-#define HAVE__STAT
-#define HAVE_STAT
-#define HAVE_STDLIB_H
-#define HAVE_TIME_H
-#define HAVE_FCNTL_H
-#include <io.h>
-#include <direct.h>
-#endif
-
-#include <libxml/xmlversion.h>
-
-#ifdef NEED_SOCKETS
-#include <wsockcompat.h>
-#endif
-
-#define HAVE_ISINF
-#define HAVE_ISNAN
-#include <math.h>
-#ifdef _MSC_VER
-/* MS C-runtime has functions which can be used in order to determine if
- a given floating-point variable contains NaN, (+-)INF. These are
- preferred, because floating-point technology is considered propriatary
- by MS and we can assume that their functions know more about their
- oddities than we do. */
-#include <float.h>
-/* Bjorn Reese figured a quite nice construct for isinf() using the _fpclass
- function. */
-#ifndef isinf
-#define isinf(d) ((_fpclass(d) == _FPCLASS_PINF) ? 1 \
- : ((_fpclass(d) == _FPCLASS_NINF) ? -1 : 0))
-#endif
-/* _isnan(x) returns nonzero if (x == NaN) and zero otherwise. */
-#ifndef isnan
-#define isnan(d) (_isnan(d))
-#endif
-#else /* _MSC_VER */
-#ifndef isinf
-static int isinf (double d) {
- int expon = 0;
- double val = frexp (d, &expon);
- if (expon == 1025) {
- if (val == 0.5) {
- return 1;
- } else if (val == -0.5) {
- return -1;
- } else {
- return 0;
- }
- } else {
- return 0;
- }
-}
-#endif
-#ifndef isnan
-static int isnan (double d) {
- int expon = 0;
- double val = frexp (d, &expon);
- if (expon == 1025) {
- if (val == 0.5) {
- return 0;
- } else if (val == -0.5) {
- return 0;
- } else {
- return 1;
- }
- } else {
- return 0;
- }
-}
-#endif
-#endif /* _MSC_VER */
-
-#if defined(_MSC_VER) || defined(__MINGW32__)
-#define mkdir(p,m) _mkdir(p)
-#define snprintf _snprintf
-#define vsnprintf(b,c,f,a) _vsnprintf(b,c,f,a)
-#endif
-
-/* Threading API to use should be specified here for compatibility reasons.
- This is however best specified on the compiler's command-line. */
-#if defined(LIBXML_THREAD_ENABLED)
-#if !defined(HAVE_PTHREAD_H) && !defined(HAVE_WIN32_THREADS)
-#define HAVE_WIN32_THREADS
-#endif
-#endif
-
-/* Some third-party libraries far from our control assume the following
- is defined, which it is not if we don't include windows.h. */
-#if !defined(FALSE)
-#define FALSE 0
-#endif
-#if !defined(TRUE)
-#define TRUE (!(FALSE))
-#endif
-
-#endif /* __LIBXML_WIN32_CONFIG__ */
-
diff --git a/bundle/libxml/include/wsockcompat.h b/bundle/libxml/include/wsockcompat.h
deleted file mode 100644
index 690048cede..0000000000
--- a/bundle/libxml/include/wsockcompat.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* include/wsockcompat.h
- * Windows -> Berkeley Sockets compatibility things.
- */
-
-#if !defined __XML_WSOCKCOMPAT_H__
-#define __XML_WSOCKCOMPAT_H__
-
-#ifdef _WIN32_WCE
-#include <winsock.h>
-#else
-#undef HAVE_ERRNO_H
-#include <winsock2.h>
-#endif
-
-#if !defined SOCKLEN_T
-#define SOCKLEN_T int
-#endif
-
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#define EINPROGRESS WSAEINPROGRESS
-#define EALREADY WSAEALREADY
-#define ENOTSOCK WSAENOTSOCK
-#define EDESTADDRREQ WSAEDESTADDRREQ
-#define EMSGSIZE WSAEMSGSIZE
-#define EPROTOTYPE WSAEPROTOTYPE
-#define ENOPROTOOPT WSAENOPROTOOPT
-#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
-#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
-#define EOPNOTSUPP WSAEOPNOTSUPP
-#define EPFNOSUPPORT WSAEPFNOSUPPORT
-#define EAFNOSUPPORT WSAEAFNOSUPPORT
-#define EADDRINUSE WSAEADDRINUSE
-#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
-#define ENETDOWN WSAENETDOWN
-#define ENETUNREACH WSAENETUNREACH
-#define ENETRESET WSAENETRESET
-#define ECONNABORTED WSAECONNABORTED
-#define ECONNRESET WSAECONNRESET
-#define ENOBUFS WSAENOBUFS
-#define EISCONN WSAEISCONN
-#define ENOTCONN WSAENOTCONN
-#define ESHUTDOWN WSAESHUTDOWN
-#define ETOOMANYREFS WSAETOOMANYREFS
-#define ETIMEDOUT WSAETIMEDOUT
-#define ECONNREFUSED WSAECONNREFUSED
-#define ELOOP WSAELOOP
-#define EHOSTDOWN WSAEHOSTDOWN
-#define EHOSTUNREACH WSAEHOSTUNREACH
-#define EPROCLIM WSAEPROCLIM
-#define EUSERS WSAEUSERS
-#define EDQUOT WSAEDQUOT
-#define ESTALE WSAESTALE
-#define EREMOTE WSAEREMOTE
-/* These cause conflicts with the codes from errno.h. Since they are
- not used in the relevant code (nanoftp, nanohttp), we can leave
- them disabled.
-#define ENAMETOOLONG WSAENAMETOOLONG
-#define ENOTEMPTY WSAENOTEMPTY
-*/
-
-#endif /* __XML_WSOCKCOMPAT_H__ */
diff --git a/bundle/libxml/libxml.h b/bundle/libxml/libxml.h
deleted file mode 100644
index d34dd10444..0000000000
--- a/bundle/libxml/libxml.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * libxml.h: internal header only used during the compilation of libxml
- *
- * See COPYRIGHT for the status of this software
- *
- * Author: breese@users.sourceforge.net
- */
-
-#ifndef __XML_LIBXML_H__
-#define __XML_LIBXML_H__
-
-#include "php_config.h"
-#include <libxml/xmlversion.h>
-
-#ifndef WITH_TRIO
-#include <stdio.h>
-#else
-/**
- * TRIO_REPLACE_STDIO:
- *
- * This macro is defined if teh trio string formatting functions are to
- * be used instead of the default stdio ones.
- */
-#define TRIO_REPLACE_STDIO
-#include "trio.h"
-#endif
-
-#endif /* ! __XML_LIBXML_H__ */
diff --git a/bundle/libxml/list.c b/bundle/libxml/list.c
deleted file mode 100644
index 18a82973e5..0000000000
--- a/bundle/libxml/list.c
+++ /dev/null
@@ -1,720 +0,0 @@
-/*
- * list.c: lists handling implementation
- *
- * Copyright (C) 2000 Gary Pennington and Daniel Veillard.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- * Author: Gary.Pennington@uk.sun.com
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/list.h>
-#include <libxml/globals.h>
-
-/*
- * Type definition are kept internal
- */
-
-struct _xmlLink
-{
- struct _xmlLink *next;
- struct _xmlLink *prev;
- void *data;
-};
-
-struct _xmlList
-{
- xmlLinkPtr sentinel;
- void (*linkDeallocator)(xmlLinkPtr );
- int (*linkCompare)(const void *, const void*);
-};
-
-/************************************************************************
- * *
- * Interfaces *
- * *
- ************************************************************************/
-
-/**
- * xmlLinkDeallocator:
- * @l: a list
- * @lk: a link
- *
- * Unlink and deallocate @lk from list @l
- */
-static void
-xmlLinkDeallocator(xmlListPtr l, xmlLinkPtr lk)
-{
- (lk->prev)->next = lk->next;
- (lk->next)->prev = lk->prev;
- if(l->linkDeallocator)
- l->linkDeallocator(lk);
- xmlFree(lk);
-}
-
-/**
- * xmlLinkCompare:
- * @data0: first data
- * @data1: second data
- *
- * Compares two arbitrary data
- *
- * Returns -1, 0 or 1 depending on whether data1 is greater equal or smaller
- * than data0
- */
-static int
-xmlLinkCompare(const void *data0, const void *data1)
-{
- if (data0 < data1)
- return (-1);
- else if (data0 == data1)
- return (0);
- return (1);
-}
-
-/**
- * xmlListLowerSearch:
- * @l: a list
- * @data: a data
- *
- * Search data in the ordered list walking from the beginning
- *
- * Returns the link containing the data or NULL
- */
-static xmlLinkPtr
-xmlListLowerSearch(xmlListPtr l, void *data)
-{
- xmlLinkPtr lk;
-
- for(lk = l->sentinel->next;lk != l->sentinel && l->linkCompare(lk->data, data) <0 ;lk = lk->next);
- return lk;
-}
-
-/**
- * xmlListHigherSearch:
- * @l: a list
- * @data: a data
- *
- * Search data in the ordered list walking backward from the end
- *
- * Returns the link containing the data or NULL
- */
-static xmlLinkPtr
-xmlListHigherSearch(xmlListPtr l, void *data)
-{
- xmlLinkPtr lk;
-
- for(lk = l->sentinel->prev;lk != l->sentinel && l->linkCompare(lk->data, data) >0 ;lk = lk->prev);
- return lk;
-}
-
-/**
- * xmlListSearch:
- * @l: a list
- * @data: a data
- *
- * Search data in the list
- *
- * Returns the link containing the data or NULL
- */
-static xmlLinkPtr
-xmlListLinkSearch(xmlListPtr l, void *data)
-{
- xmlLinkPtr lk;
- lk = xmlListLowerSearch(l, data);
- if (lk == l->sentinel)
- return NULL;
- else {
- if (l->linkCompare(lk->data, data) ==0)
- return lk;
- return NULL;
- }
-}
-
-/**
- * xmlListLinkReverseSearch:
- * @l: a list
- * @data: a data
- *
- * Search data in the list processing backward
- *
- * Returns the link containing the data or NULL
- */
-static xmlLinkPtr
-xmlListLinkReverseSearch(xmlListPtr l, void *data)
-{
- xmlLinkPtr lk;
- lk = xmlListHigherSearch(l, data);
- if (lk == l->sentinel)
- return NULL;
- else {
- if (l->linkCompare(lk->data, data) ==0)
- return lk;
- return NULL;
- }
-}
-
-/**
- * xmlListCreate:
- * @deallocator: an optional deallocator function
- * @compare: an optional comparison function
- *
- * Create a new list
- *
- * Returns the new list or NULL in case of error
- */
-xmlListPtr
-xmlListCreate(xmlListDeallocator deallocator, xmlListDataCompare compare)
-{
- xmlListPtr l;
- if (NULL == (l = (xmlListPtr )xmlMalloc( sizeof(xmlList)))) {
- xmlGenericError(xmlGenericErrorContext,
- "Cannot initialize memory for list");
- return (NULL);
- }
- /* Initialize the list to NULL */
- memset(l, 0, sizeof(xmlList));
-
- /* Add the sentinel */
- if (NULL ==(l->sentinel = (xmlLinkPtr )xmlMalloc(sizeof(xmlLink)))) {
- xmlGenericError(xmlGenericErrorContext,
- "Cannot initialize memory for sentinel");
- xmlFree(l);
- return (NULL);
- }
- l->sentinel->next = l->sentinel;
- l->sentinel->prev = l->sentinel;
- l->sentinel->data = NULL;
-
- /* If there is a link deallocator, use it */
- if (deallocator != NULL)
- l->linkDeallocator = deallocator;
- /* If there is a link comparator, use it */
- if (compare != NULL)
- l->linkCompare = compare;
- else /* Use our own */
- l->linkCompare = xmlLinkCompare;
- return l;
-}
-
-/**
- * xmlListSearch:
- * @l: a list
- * @data: a search value
- *
- * Search the list for an existing value of @data
- *
- * Returns the value associated to @data or NULL in case of error
- */
-void *
-xmlListSearch(xmlListPtr l, void *data)
-{
- xmlLinkPtr lk;
- lk = xmlListLinkSearch(l, data);
- if (lk)
- return (lk->data);
- return NULL;
-}
-
-/**
- * xmlListReverseSearch:
- * @l: a list
- * @data: a search value
- *
- * Search the list in reverse order for an existing value of @data
- *
- * Returns the value associated to @data or NULL in case of error
- */
-void *
-xmlListReverseSearch(xmlListPtr l, void *data)
-{
- xmlLinkPtr lk;
- lk = xmlListLinkReverseSearch(l, data);
- if (lk)
- return (lk->data);
- return NULL;
-}
-
-/**
- * xmlListInsert:
- * @l: a list
- * @data: the data
- *
- * Insert data in the ordered list at the beginning for this value
- *
- * Returns 0 in case of success, 1 in case of failure
- */
-int
-xmlListInsert(xmlListPtr l, void *data)
-{
- xmlLinkPtr lkPlace, lkNew;
-
- lkPlace = xmlListLowerSearch(l, data);
- /* Add the new link */
- lkNew = (xmlLinkPtr) xmlMalloc(sizeof(xmlLink));
- if (lkNew == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Cannot initialize memory for new link");
- return (1);
- }
- lkNew->data = data;
- lkPlace = lkPlace->prev;
- lkNew->next = lkPlace->next;
- (lkPlace->next)->prev = lkNew;
- lkPlace->next = lkNew;
- lkNew->prev = lkPlace;
- return 0;
-}
-
-/**
- * xmlListAppend:
- * @l: a list
- * @data: the data
- *
- * Insert data in the ordered list at the end for this value
- *
- * Returns 0 in case of success, 1 in case of failure
- */
-int xmlListAppend(xmlListPtr l, void *data)
-{
- xmlLinkPtr lkPlace, lkNew;
-
- lkPlace = xmlListHigherSearch(l, data);
- /* Add the new link */
- lkNew = (xmlLinkPtr) xmlMalloc(sizeof(xmlLink));
- if (lkNew == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Cannot initialize memory for new link");
- return (0);
- }
- lkNew->data = data;
- lkNew->next = lkPlace->next;
- (lkPlace->next)->prev = lkNew;
- lkPlace->next = lkNew;
- lkNew->prev = lkPlace;
- return 1;
-}
-
-/**
- * xmlListDelete:
- * @l: a list
- *
- * Deletes the list and its associated data
- */
-void xmlListDelete(xmlListPtr l)
-{
- xmlListClear(l);
- xmlFree(l->sentinel);
- xmlFree(l);
-}
-
-/**
- * xmlListRemoveFirst:
- * @l: a list
- * @data: list data
- *
- * Remove the first instance associated to data in the list
- *
- * Returns 1 if a deallocation occured, or 0 if not found
- */
-int
-xmlListRemoveFirst(xmlListPtr l, void *data)
-{
- xmlLinkPtr lk;
-
- /*Find the first instance of this data */
- lk = xmlListLinkSearch(l, data);
- if (lk != NULL) {
- xmlLinkDeallocator(l, lk);
- return 1;
- }
- return 0;
-}
-
-/**
- * xmlListRemoveLast:
- * @l: a list
- * @data: list data
- *
- * Remove the last instance associated to data in the list
- *
- * Returns 1 if a deallocation occured, or 0 if not found
- */
-int
-xmlListRemoveLast(xmlListPtr l, void *data)
-{
- xmlLinkPtr lk;
-
- /*Find the last instance of this data */
- lk = xmlListLinkReverseSearch(l, data);
- if (lk != NULL) {
- xmlLinkDeallocator(l, lk);
- return 1;
- }
- return 0;
-}
-
-/**
- * xmlListRemoveAll:
- * @l: a list
- * @data: list data
- *
- * Remove the all instance associated to data in the list
- *
- * Returns the number of deallocation, or 0 if not found
- */
-int
-xmlListRemoveAll(xmlListPtr l, void *data)
-{
- int count=0;
-
-
- while(xmlListRemoveFirst(l, data))
- count++;
- return count;
-}
-
-/**
- * xmlListClear:
- * @l: a list
- *
- * Remove the all data in the list
- */
-void
-xmlListClear(xmlListPtr l)
-{
- xmlLinkPtr lk = l->sentinel->next;
-
- while(lk != l->sentinel) {
- xmlLinkPtr next = lk->next;
-
- xmlLinkDeallocator(l, lk);
- lk = next;
- }
-}
-
-/**
- * xmlListEmpty:
- * @l: a list
- *
- * Is the list empty ?
- *
- * Returns 1 if the list is empty, 0 otherwise
- */
-int
-xmlListEmpty(xmlListPtr l)
-{
- return (l->sentinel->next == l->sentinel);
-}
-
-/**
- * xmlListFront:
- * @l: a list
- *
- * Get the first element in the list
- *
- * Returns the first element in the list, or NULL
- */
-xmlLinkPtr
-xmlListFront(xmlListPtr l)
-{
- return (l->sentinel->next);
-}
-
-/**
- * xmlListEnd:
- * @l: a list
- *
- * Get the last element in the list
- *
- * Returns the last element in the list, or NULL
- */
-xmlLinkPtr
-xmlListEnd(xmlListPtr l)
-{
- return (l->sentinel->prev);
-}
-
-/**
- * xmlListSize:
- * @l: a list
- *
- * Get the number of elements in the list
- *
- * Returns the number of elements in the list
- */
-int
-xmlListSize(xmlListPtr l)
-{
- xmlLinkPtr lk;
- int count=0;
-
- /* TODO: keep a counter in xmlList instead */
- for(lk = l->sentinel->next; lk != l->sentinel; lk = lk->next, count++);
- return count;
-}
-
-/**
- * xmlListPopFront:
- * @l: a list
- *
- * Removes the first element in the list
- */
-void
-xmlListPopFront(xmlListPtr l)
-{
- if(!xmlListEmpty(l))
- xmlLinkDeallocator(l, l->sentinel->next);
-}
-
-/**
- * xmlListPopBack:
- * @l: a list
- *
- * Removes the last element in the list
- */
-void
-xmlListPopBack(xmlListPtr l)
-{
- if(!xmlListEmpty(l))
- xmlLinkDeallocator(l, l->sentinel->prev);
-}
-
-/**
- * xmlListPushFront:
- * @l: a list
- * @data: new data
- *
- * add the new data at the beginning of the list
- *
- * Returns 1 if successful, 0 otherwise
- */
-int
-xmlListPushFront(xmlListPtr l, void *data)
-{
- xmlLinkPtr lkPlace, lkNew;
-
- lkPlace = l->sentinel;
- /* Add the new link */
- lkNew = (xmlLinkPtr) xmlMalloc(sizeof(xmlLink));
- if (lkNew == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Cannot initialize memory for new link");
- return (0);
- }
- lkNew->data = data;
- lkNew->next = lkPlace->next;
- (lkPlace->next)->prev = lkNew;
- lkPlace->next = lkNew;
- lkNew->prev = lkPlace;
- return 1;
-}
-
-/**
- * xmlListPushBack:
- * @l: a list
- * @data: new data
- *
- * add the new data at the end of the list
- *
- * Returns 1 if successful, 0 otherwise
- */
-int
-xmlListPushBack(xmlListPtr l, void *data)
-{
- xmlLinkPtr lkPlace, lkNew;
-
- lkPlace = l->sentinel->prev;
- /* Add the new link */
- if (NULL ==(lkNew = (xmlLinkPtr )xmlMalloc(sizeof(xmlLink)))) {
- xmlGenericError(xmlGenericErrorContext,
- "Cannot initialize memory for new link");
- return (0);
- }
- lkNew->data = data;
- lkNew->next = lkPlace->next;
- (lkPlace->next)->prev = lkNew;
- lkPlace->next = lkNew;
- lkNew->prev = lkPlace;
- return 1;
-}
-
-/**
- * xmlLinkGetData:
- * @lk: a link
- *
- * See Returns.
- *
- * Returns a pointer to the data referenced from this link
- */
-void *
-xmlLinkGetData(xmlLinkPtr lk)
-{
- return lk->data;
-}
-
-/**
- * xmlListReverse:
- * @l: a list
- *
- * Reverse the order of the elements in the list
- */
-void
-xmlListReverse(xmlListPtr l) {
- xmlLinkPtr lk;
- xmlLinkPtr lkPrev = l->sentinel;
-
- for(lk = l->sentinel->next; lk != l->sentinel; lk = lk->next) {
- lkPrev->next = lkPrev->prev;
- lkPrev->prev = lk;
- lkPrev = lk;
- }
- /* Fix up the last node */
- lkPrev->next = lkPrev->prev;
- lkPrev->prev = lk;
-}
-
-/**
- * xmlListSort:
- * @l: a list
- *
- * Sort all the elements in the list
- */
-void
-xmlListSort(xmlListPtr l)
-{
- xmlListPtr lTemp;
-
- if(xmlListEmpty(l))
- return;
-
- /* I think that the real answer is to implement quicksort, the
- * alternative is to implement some list copying procedure which
- * would be based on a list copy followed by a clear followed by
- * an insert. This is slow...
- */
-
- if (NULL ==(lTemp = xmlListDup(l)))
- return;
- xmlListClear(l);
- xmlListMerge(l, lTemp);
- xmlListDelete(lTemp);
- return;
-}
-
-/**
- * xmlListWalk:
- * @l: a list
- * @walker: a processing function
- * @user: a user parameter passed to the walker function
- *
- * Walk all the element of the first from first to last and
- * apply the walker function to it
- */
-void
-xmlListWalk(xmlListPtr l, xmlListWalker walker, const void *user) {
- xmlLinkPtr lk;
-
- for(lk = l->sentinel->next; lk != l->sentinel; lk = lk->next) {
- if((walker(lk->data, user)) == 0)
- break;
- }
-}
-
-/**
- * xmlListReverseWalk:
- * @l: a list
- * @walker: a processing function
- * @user: a user parameter passed to the walker function
- *
- * Walk all the element of the list in reverse order and
- * apply the walker function to it
- */
-void
-xmlListReverseWalk(xmlListPtr l, xmlListWalker walker, const void *user) {
- xmlLinkPtr lk;
-
- for(lk = l->sentinel->prev; lk != l->sentinel; lk = lk->prev) {
- if((walker(lk->data, user)) == 0)
- break;
- }
-}
-
-/**
- * xmlListMerge:
- * @l1: the original list
- * @l2: the new list
- *
- * include all the elements of the second list in the first one and
- * clear the second list
- */
-void
-xmlListMerge(xmlListPtr l1, xmlListPtr l2)
-{
- xmlListCopy(l1, l2);
- xmlListClear(l2);
-}
-
-/**
- * xmlListDup:
- * @old: the list
- *
- * Duplicate the list
- *
- * Returns a new copy of the list or NULL in case of error
- */
-xmlListPtr
-xmlListDup(const xmlListPtr old)
-{
- xmlListPtr cur;
- /* Hmmm, how to best deal with allocation issues when copying
- * lists. If there is a de-allocator, should responsibility lie with
- * the new list or the old list. Surely not both. I'll arbitrarily
- * set it to be the old list for the time being whilst I work out
- * the answer
- */
- if (NULL ==(cur = xmlListCreate(NULL, old->linkCompare)))
- return (NULL);
- if (0 != xmlListCopy(cur, old))
- return NULL;
- return cur;
-}
-
-/**
- * xmlListCopy:
- * @cur: the new list
- * @old: the old list
- *
- * Move all the element from the old list in the new list
- *
- * Returns 0 in case of success 1 in case of error
- */
-int
-xmlListCopy(xmlListPtr cur, const xmlListPtr old)
-{
- /* Walk the old tree and insert the data into the new one */
- xmlLinkPtr lk;
-
- for(lk = old->sentinel->next; lk != old->sentinel; lk = lk->next) {
- if (0 !=xmlListInsert(cur, lk->data)) {
- xmlListDelete(cur);
- return (1);
- }
- }
- return (0);
-}
-/* xmlListUnique() */
-/* xmlListSwap */
diff --git a/bundle/libxml/nanoftp.c b/bundle/libxml/nanoftp.c
deleted file mode 100644
index 4f3b819238..0000000000
--- a/bundle/libxml/nanoftp.c
+++ /dev/null
@@ -1,1924 +0,0 @@
-/*
- * nanoftp.c: basic FTP client support
- *
- * Reference: RFC 959
- */
-
-#ifdef TESTING
-#define STANDALONE
-#define HAVE_STDLIB_H
-#define HAVE_UNISTD_H
-#define HAVE_SYS_SOCKET_H
-#define HAVE_NETINET_IN_H
-#define HAVE_NETDB_H
-#define HAVE_SYS_TIME_H
-#else /* TESTING */
-#define NEED_SOCKETS
-#endif /* TESTING */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#ifdef LIBXML_FTP_ENABLED
-#include <string.h>
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include <libxml/xmlerror.h>
-#include <libxml/nanoftp.h>
-#include <libxml/globals.h>
-
-/* #define DEBUG_FTP 1 */
-#ifdef STANDALONE
-#ifndef DEBUG_FTP
-#define DEBUG_FTP 1
-#endif
-#endif
-
-/**
- * A couple portability macros
- */
-#ifndef _WINSOCKAPI_
-#define closesocket(s) close(s)
-#define SOCKET int
-#endif
-#if defined(VMS) || defined(__VMS)
-#define SOCKLEN_T unsigned int
-#endif
-
-/*
- * Hack to make compilation work -SH
- */
-#ifndef SOCKLEN_T
-#define SOCKLEN_T unsigned int
-#endif
-
-#define FTP_COMMAND_OK 200
-#define FTP_SYNTAX_ERROR 500
-#define FTP_GET_PASSWD 331
-#define FTP_BUF_SIZE 512
-
-typedef struct xmlNanoFTPCtxt {
- char *protocol; /* the protocol name */
- char *hostname; /* the host name */
- int port; /* the port */
- char *path; /* the path within the URL */
- char *user; /* user string */
- char *passwd; /* passwd string */
- struct sockaddr_in ftpAddr; /* the socket address struct */
- int passive; /* currently we support only passive !!! */
- SOCKET controlFd; /* the file descriptor for the control socket */
- SOCKET dataFd; /* the file descriptor for the data socket */
- int state; /* WRITE / READ / CLOSED */
- int returnValue; /* the protocol return value */
- /* buffer for data received from the control connection */
- char controlBuf[FTP_BUF_SIZE + 1];
- int controlBufIndex;
- int controlBufUsed;
- int controlBufAnswer;
-} xmlNanoFTPCtxt, *xmlNanoFTPCtxtPtr;
-
-static int initialized = 0;
-static char *proxy = NULL; /* the proxy name if any */
-static int proxyPort = 0; /* the proxy port if any */
-static char *proxyUser = NULL; /* user for proxy authentication */
-static char *proxyPasswd = NULL;/* passwd for proxy authentication */
-static int proxyType = 0; /* uses TYPE or a@b ? */
-
-/**
- * xmlNanoFTPInit:
- *
- * Initialize the FTP protocol layer.
- * Currently it just checks for proxy informations,
- * and get the hostname
- */
-
-void
-xmlNanoFTPInit(void) {
- const char *env;
-#ifdef _WINSOCKAPI_
- WSADATA wsaData;
-#endif
-
- if (initialized)
- return;
-
-#ifdef _WINSOCKAPI_
- if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
- return;
-#endif
-
- proxyPort = 21;
- env = getenv("no_proxy");
- if (env != NULL)
- return;
- env = getenv("ftp_proxy");
- if (env != NULL) {
- xmlNanoFTPScanProxy(env);
- } else {
- env = getenv("FTP_PROXY");
- if (env != NULL) {
- xmlNanoFTPScanProxy(env);
- }
- }
- env = getenv("ftp_proxy_user");
- if (env != NULL) {
- proxyUser = xmlMemStrdup(env);
- }
- env = getenv("ftp_proxy_password");
- if (env != NULL) {
- proxyPasswd = xmlMemStrdup(env);
- }
- initialized = 1;
-}
-
-/**
- * xmlNanoFTPCleanup:
- *
- * Cleanup the FTP protocol layer. This cleanup proxy informations.
- */
-
-void
-xmlNanoFTPCleanup(void) {
- if (proxy != NULL) {
- xmlFree(proxy);
- proxy = NULL;
- }
- if (proxyUser != NULL) {
- xmlFree(proxyUser);
- proxyUser = NULL;
- }
- if (proxyPasswd != NULL) {
- xmlFree(proxyPasswd);
- proxyPasswd = NULL;
- }
-#ifdef _WINSOCKAPI_
- if (initialized)
- WSACleanup();
-#endif
- initialized = 0;
-}
-
-/**
- * xmlNanoFTPProxy:
- * @host: the proxy host name
- * @port: the proxy port
- * @user: the proxy user name
- * @passwd: the proxy password
- * @type: the type of proxy 1 for using SITE, 2 for USER a@b
- *
- * Setup the FTP proxy informations.
- * This can also be done by using ftp_proxy ftp_proxy_user and
- * ftp_proxy_password environment variables.
- */
-
-void
-xmlNanoFTPProxy(const char *host, int port, const char *user,
- const char *passwd, int type) {
- if (proxy != NULL)
- xmlFree(proxy);
- if (proxyUser != NULL)
- xmlFree(proxyUser);
- if (proxyPasswd != NULL)
- xmlFree(proxyPasswd);
- if (host)
- proxy = xmlMemStrdup(host);
- if (user)
- proxyUser = xmlMemStrdup(user);
- if (passwd)
- proxyPasswd = xmlMemStrdup(passwd);
- proxyPort = port;
- proxyType = type;
-}
-
-/**
- * xmlNanoFTPScanURL:
- * @ctx: an FTP context
- * @URL: The URL used to initialize the context
- *
- * (Re)Initialize an FTP context by parsing the URL and finding
- * the protocol host port and path it indicates.
- */
-
-static void
-xmlNanoFTPScanURL(void *ctx, const char *URL) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
- const char *cur = URL;
- char buf[4096];
- int indx = 0;
- int port = 0;
-
- if (ctxt->protocol != NULL) {
- xmlFree(ctxt->protocol);
- ctxt->protocol = NULL;
- }
- if (ctxt->hostname != NULL) {
- xmlFree(ctxt->hostname);
- ctxt->hostname = NULL;
- }
- if (ctxt->path != NULL) {
- xmlFree(ctxt->path);
- ctxt->path = NULL;
- }
- if (URL == NULL) return;
- buf[indx] = 0;
- while (*cur != 0) {
- if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
- buf[indx] = 0;
- ctxt->protocol = xmlMemStrdup(buf);
- indx = 0;
- cur += 3;
- break;
- }
- buf[indx++] = *cur++;
- }
- if (*cur == 0) return;
-
- buf[indx] = 0;
- /* allow user@ and user:pass@ forms */
- {
- const char *p = strchr(cur, '@');
- if(p) {
- while(1) {
- if(cur[0] == ':' || cur[0] == '@') break;
- buf[indx++] = *cur++;
- }
- buf[indx] = 0;
- ctxt->user = xmlMemStrdup(buf);
- indx = 0;
- if(cur[0] == ':') {
- cur++;
- while(1) {
- if(cur[0] == '@') break;
- buf[indx++] = *cur++;
- }
- buf[indx] = 0;
- ctxt->passwd = xmlMemStrdup(buf);
- indx = 0;
- }
- cur = p+1;
- }
- }
-
- while (1) {
- if (cur[0] == ':') {
- buf[indx] = 0;
- ctxt->hostname = xmlMemStrdup(buf);
- indx = 0;
- cur += 1;
- while ((*cur >= '0') && (*cur <= '9')) {
- port *= 10;
- port += *cur - '0';
- cur++;
- }
- if (port != 0) ctxt->port = port;
- while ((cur[0] != '/') && (*cur != 0))
- cur++;
- break;
- }
- if ((*cur == '/') || (*cur == 0)) {
- buf[indx] = 0;
- ctxt->hostname = xmlMemStrdup(buf);
- indx = 0;
- break;
- }
- buf[indx++] = *cur++;
- }
- if (*cur == 0)
- ctxt->path = xmlMemStrdup("/");
- else {
- indx = 0;
- buf[indx] = 0;
- while (*cur != 0)
- buf[indx++] = *cur++;
- buf[indx] = 0;
- ctxt->path = xmlMemStrdup(buf);
- }
-}
-
-/**
- * xmlNanoFTPUpdateURL:
- * @ctx: an FTP context
- * @URL: The URL used to update the context
- *
- * Update an FTP context by parsing the URL and finding
- * new path it indicates. If there is an error in the
- * protocol, hostname, port or other information, the
- * error is raised. It indicates a new connection has to
- * be established.
- *
- * Returns 0 if Ok, -1 in case of error (other host).
- */
-
-int
-xmlNanoFTPUpdateURL(void *ctx, const char *URL) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
- const char *cur = URL;
- char buf[4096];
- int indx = 0;
- int port = 0;
-
- if (URL == NULL)
- return(-1);
- if (ctxt == NULL)
- return(-1);
- if (ctxt->protocol == NULL)
- return(-1);
- if (ctxt->hostname == NULL)
- return(-1);
- buf[indx] = 0;
- while (*cur != 0) {
- if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
- buf[indx] = 0;
- if (strcmp(ctxt->protocol, buf))
- return(-1);
- indx = 0;
- cur += 3;
- break;
- }
- buf[indx++] = *cur++;
- }
- if (*cur == 0)
- return(-1);
-
- buf[indx] = 0;
- while (1) {
- if (cur[0] == ':') {
- buf[indx] = 0;
- if (strcmp(ctxt->hostname, buf))
- return(-1);
- indx = 0;
- cur += 1;
- while ((*cur >= '0') && (*cur <= '9')) {
- port *= 10;
- port += *cur - '0';
- cur++;
- }
- if (port != ctxt->port)
- return(-1);
- while ((cur[0] != '/') && (*cur != 0))
- cur++;
- break;
- }
- if ((*cur == '/') || (*cur == 0)) {
- buf[indx] = 0;
- if (strcmp(ctxt->hostname, buf))
- return(-1);
- indx = 0;
- break;
- }
- buf[indx++] = *cur++;
- }
- if (ctxt->path != NULL) {
- xmlFree(ctxt->path);
- ctxt->path = NULL;
- }
-
- if (*cur == 0)
- ctxt->path = xmlMemStrdup("/");
- else {
- indx = 0;
- buf[indx] = 0;
- while (*cur != 0)
- buf[indx++] = *cur++;
- buf[indx] = 0;
- ctxt->path = xmlMemStrdup(buf);
- }
- return(0);
-}
-
-/**
- * xmlNanoFTPScanProxy:
- * @URL: The proxy URL used to initialize the proxy context
- *
- * (Re)Initialize the FTP Proxy context by parsing the URL and finding
- * the protocol host port it indicates.
- * Should be like ftp://myproxy/ or ftp://myproxy:3128/
- * A NULL URL cleans up proxy informations.
- */
-
-void
-xmlNanoFTPScanProxy(const char *URL) {
- const char *cur = URL;
- char buf[4096];
- int indx = 0;
- int port = 0;
-
- if (proxy != NULL) {
- xmlFree(proxy);
- proxy = NULL;
- }
- if (proxyPort != 0) {
- proxyPort = 0;
- }
-#ifdef DEBUG_FTP
- if (URL == NULL)
- xmlGenericError(xmlGenericErrorContext, "Removing FTP proxy info\n");
- else
- xmlGenericError(xmlGenericErrorContext, "Using FTP proxy %s\n", URL);
-#endif
- if (URL == NULL) return;
- buf[indx] = 0;
- while (*cur != 0) {
- if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
- buf[indx] = 0;
- indx = 0;
- cur += 3;
- break;
- }
- buf[indx++] = *cur++;
- }
- if (*cur == 0) return;
-
- buf[indx] = 0;
- while (1) {
- if (cur[0] == ':') {
- buf[indx] = 0;
- proxy = xmlMemStrdup(buf);
- indx = 0;
- cur += 1;
- while ((*cur >= '0') && (*cur <= '9')) {
- port *= 10;
- port += *cur - '0';
- cur++;
- }
- if (port != 0) proxyPort = port;
- while ((cur[0] != '/') && (*cur != 0))
- cur++;
- break;
- }
- if ((*cur == '/') || (*cur == 0)) {
- buf[indx] = 0;
- proxy = xmlMemStrdup(buf);
- indx = 0;
- break;
- }
- buf[indx++] = *cur++;
- }
-}
-
-/**
- * xmlNanoFTPNewCtxt:
- * @URL: The URL used to initialize the context
- *
- * Allocate and initialize a new FTP context.
- *
- * Returns an FTP context or NULL in case of error.
- */
-
-void*
-xmlNanoFTPNewCtxt(const char *URL) {
- xmlNanoFTPCtxtPtr ret;
-
- ret = (xmlNanoFTPCtxtPtr) xmlMalloc(sizeof(xmlNanoFTPCtxt));
- if (ret == NULL) return(NULL);
-
- memset(ret, 0, sizeof(xmlNanoFTPCtxt));
- ret->port = 21;
- ret->passive = 1;
- ret->returnValue = 0;
- ret->controlBufIndex = 0;
- ret->controlBufUsed = 0;
- ret->controlFd = -1;
-
- if (URL != NULL)
- xmlNanoFTPScanURL(ret, URL);
-
- return(ret);
-}
-
-/**
- * xmlNanoFTPFreeCtxt:
- * @ctx: an FTP context
- *
- * Frees the context after closing the connection.
- */
-
-void
-xmlNanoFTPFreeCtxt(void * ctx) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
- if (ctxt == NULL) return;
- if (ctxt->hostname != NULL) xmlFree(ctxt->hostname);
- if (ctxt->protocol != NULL) xmlFree(ctxt->protocol);
- if (ctxt->path != NULL) xmlFree(ctxt->path);
- ctxt->passive = 1;
- if (ctxt->controlFd >= 0) closesocket(ctxt->controlFd);
- ctxt->controlFd = -1;
- ctxt->controlBufIndex = -1;
- ctxt->controlBufUsed = -1;
- xmlFree(ctxt);
-}
-
-/**
- * xmlNanoFTPParseResponse:
- * @buf: the buffer containing the response
- * @len: the buffer length
- *
- * Parsing of the server answer, we just extract the code.
- *
- * returns 0 for errors
- * +XXX for last line of response
- * -XXX for response to be continued
- */
-static int
-xmlNanoFTPParseResponse(char *buf, int len) {
- int val = 0;
-
- if (len < 3) return(-1);
- if ((*buf >= '0') && (*buf <= '9'))
- val = val * 10 + (*buf - '0');
- else
- return(0);
- buf++;
- if ((*buf >= '0') && (*buf <= '9'))
- val = val * 10 + (*buf - '0');
- else
- return(0);
- buf++;
- if ((*buf >= '0') && (*buf <= '9'))
- val = val * 10 + (*buf - '0');
- else
- return(0);
- buf++;
- if (*buf == '-')
- return(-val);
- return(val);
-}
-
-/**
- * xmlNanoFTPGetMore:
- * @ctx: an FTP context
- *
- * Read more information from the FTP control connection
- * Returns the number of bytes read, < 0 indicates an error
- */
-static int
-xmlNanoFTPGetMore(void *ctx) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
- int len;
- int size;
-
- if ((ctxt->controlBufIndex < 0) || (ctxt->controlBufIndex > FTP_BUF_SIZE)) {
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext,
- "xmlNanoFTPGetMore : controlBufIndex = %d\n",
- ctxt->controlBufIndex);
-#endif
- return(-1);
- }
-
- if ((ctxt->controlBufUsed < 0) || (ctxt->controlBufUsed > FTP_BUF_SIZE)) {
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext,
- "xmlNanoFTPGetMore : controlBufUsed = %d\n",
- ctxt->controlBufUsed);
-#endif
- return(-1);
- }
- if (ctxt->controlBufIndex > ctxt->controlBufUsed) {
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext,
- "xmlNanoFTPGetMore : controlBufIndex > controlBufUsed %d > %d\n",
- ctxt->controlBufIndex, ctxt->controlBufUsed);
-#endif
- return(-1);
- }
-
- /*
- * First pack the control buffer
- */
- if (ctxt->controlBufIndex > 0) {
- memmove(&ctxt->controlBuf[0], &ctxt->controlBuf[ctxt->controlBufIndex],
- ctxt->controlBufUsed - ctxt->controlBufIndex);
- ctxt->controlBufUsed -= ctxt->controlBufIndex;
- ctxt->controlBufIndex = 0;
- }
- size = FTP_BUF_SIZE - ctxt->controlBufUsed;
- if (size == 0) {
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext,
- "xmlNanoFTPGetMore : buffer full %d \n", ctxt->controlBufUsed);
-#endif
- return(0);
- }
-
- /*
- * Read the amount left on the control connection
- */
- if ((len = recv(ctxt->controlFd, &ctxt->controlBuf[ctxt->controlBufIndex],
- size, 0)) < 0) {
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
- return(-1);
- }
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext,
- "xmlNanoFTPGetMore : read %d [%d - %d]\n", len,
- ctxt->controlBufUsed, ctxt->controlBufUsed + len);
-#endif
- ctxt->controlBufUsed += len;
- ctxt->controlBuf[ctxt->controlBufUsed] = 0;
-
- return(len);
-}
-
-/**
- * xmlNanoFTPReadResponse:
- * @ctx: an FTP context
- *
- * Read the response from the FTP server after a command.
- * Returns the code number
- */
-static int
-xmlNanoFTPReadResponse(void *ctx) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
- char *ptr, *end;
- int len;
- int res = -1, cur = -1;
-
-get_more:
- /*
- * Assumes everything up to controlBuf[controlBufIndex] has been read
- * and analyzed.
- */
- len = xmlNanoFTPGetMore(ctx);
- if (len < 0) {
- return(-1);
- }
- if ((ctxt->controlBufUsed == 0) && (len == 0)) {
- return(-1);
- }
- ptr = &ctxt->controlBuf[ctxt->controlBufIndex];
- end = &ctxt->controlBuf[ctxt->controlBufUsed];
-
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext,
- "\n<<<\n%s\n--\n", ptr);
-#endif
- while (ptr < end) {
- cur = xmlNanoFTPParseResponse(ptr, end - ptr);
- if (cur > 0) {
- /*
- * Successfully scanned the control code, scratch
- * till the end of the line, but keep the index to be
- * able to analyze the result if needed.
- */
- res = cur;
- ptr += 3;
- ctxt->controlBufAnswer = ptr - ctxt->controlBuf;
- while ((ptr < end) && (*ptr != '\n')) ptr++;
- if (*ptr == '\n') ptr++;
- if (*ptr == '\r') ptr++;
- break;
- }
- while ((ptr < end) && (*ptr != '\n')) ptr++;
- if (ptr >= end) {
- ctxt->controlBufIndex = ctxt->controlBufUsed;
- goto get_more;
- }
- if (*ptr != '\r') ptr++;
- }
-
- if (res < 0) goto get_more;
- ctxt->controlBufIndex = ptr - ctxt->controlBuf;
-#ifdef DEBUG_FTP
- ptr = &ctxt->controlBuf[ctxt->controlBufIndex];
- xmlGenericError(xmlGenericErrorContext, "\n---\n%s\n--\n", ptr);
-#endif
-
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext, "Got %d\n", res);
-#endif
- return(res / 100);
-}
-
-/**
- * xmlNanoFTPGetResponse:
- * @ctx: an FTP context
- *
- * Get the response from the FTP server after a command.
- * Returns the code number
- */
-
-int
-xmlNanoFTPGetResponse(void *ctx) {
- int res;
-
- res = xmlNanoFTPReadResponse(ctx);
-
- return(res);
-}
-
-/**
- * xmlNanoFTPCheckResponse:
- * @ctx: an FTP context
- *
- * Check if there is a response from the FTP server after a command.
- * Returns the code number, or 0
- */
-
-int
-xmlNanoFTPCheckResponse(void *ctx) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
- fd_set rfd;
- struct timeval tv;
-
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- FD_ZERO(&rfd);
- FD_SET(ctxt->controlFd, &rfd);
- switch(select(ctxt->controlFd + 1, &rfd, NULL, NULL, &tv)) {
- case 0:
- return(0);
- case -1:
-#ifdef DEBUG_FTP
- perror("select");
-#endif
- return(-1);
-
- }
-
- return(xmlNanoFTPReadResponse(ctx));
-}
-
-/**
- * Send the user authentication
- */
-
-static int
-xmlNanoFTPSendUser(void *ctx) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
- char buf[200];
- int len;
- int res;
-
- if (ctxt->user == NULL)
- snprintf(buf, sizeof(buf), "USER anonymous\r\n");
- else
- snprintf(buf, sizeof(buf), "USER %s\r\n", ctxt->user);
- buf[sizeof(buf) - 1] = 0;
- len = strlen(buf);
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
- res = send(ctxt->controlFd, buf, len, 0);
- if (res < 0) return(res);
- return(0);
-}
-
-/**
- * Send the password authentication
- */
-
-static int
-xmlNanoFTPSendPasswd(void *ctx) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
- char buf[200];
- int len;
- int res;
-
- if (ctxt->passwd == NULL)
- snprintf(buf, sizeof(buf), "PASS anonymous@\r\n");
- else
- snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);
- buf[sizeof(buf) - 1] = 0;
- len = strlen(buf);
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
- res = send(ctxt->controlFd, buf, len, 0);
- if (res < 0) return(res);
- return(0);
-}
-
-/**
- * xmlNanoFTPQuit:
- * @ctx: an FTP context
- *
- * Send a QUIT command to the server
- *
- * Returns -1 in case of error, 0 otherwise
- */
-
-
-int
-xmlNanoFTPQuit(void *ctx) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
- char buf[200];
- int len;
- int res;
-
- snprintf(buf, sizeof(buf), "QUIT\r\n");
- len = strlen(buf);
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext, "%s", buf); /* Just to be consistent, even though we know it can't have a % in it */
-#endif
- res = send(ctxt->controlFd, buf, len, 0);
- return(0);
-}
-
-/**
- * xmlNanoFTPConnect:
- * @ctx: an FTP context
- *
- * Tries to open a control connection
- *
- * Returns -1 in case of error, 0 otherwise
- */
-
-int
-xmlNanoFTPConnect(void *ctx) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
- struct hostent *hp;
- int port;
- int res;
-
- if (ctxt == NULL)
- return(-1);
- if (ctxt->hostname == NULL)
- return(-1);
-
- /*
- * do the blocking DNS query.
- */
- if (proxy)
- hp = gethostbyname(proxy);
- else
- hp = gethostbyname(ctxt->hostname);
- if (hp == NULL)
- return(-1);
-
- /*
- * Prepare the socket
- */
- memset(&ctxt->ftpAddr, 0, sizeof(ctxt->ftpAddr));
- ctxt->ftpAddr.sin_family = AF_INET;
- memcpy(&ctxt->ftpAddr.sin_addr, hp->h_addr_list[0], hp->h_length);
- if (proxy) {
- port = proxyPort;
- } else {
- port = ctxt->port;
- }
- if (port == 0)
- port = 21;
- ctxt->ftpAddr.sin_port = htons(port);
- ctxt->controlFd = socket(AF_INET, SOCK_STREAM, 0);
- if (ctxt->controlFd < 0)
- return(-1);
-
- /*
- * Do the connect.
- */
- if (connect(ctxt->controlFd, (struct sockaddr *) &ctxt->ftpAddr,
- sizeof(struct sockaddr_in)) < 0) {
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
- return(-1);
- }
-
- /*
- * Wait for the HELLO from the server.
- */
- res = xmlNanoFTPGetResponse(ctxt);
- if (res != 2) {
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
- return(-1);
- }
-
- /*
- * State diagram for the login operation on the FTP server
- *
- * Reference: RFC 959
- *
- * 1
- * +---+ USER +---+------------->+---+
- * | B |---------->| W | 2 ---->| E |
- * +---+ +---+------ | -->+---+
- * | | | | |
- * 3 | | 4,5 | | |
- * -------------- ----- | | |
- * | | | | |
- * | | | | |
- * | --------- |
- * | 1| | | |
- * V | | | |
- * +---+ PASS +---+ 2 | ------>+---+
- * | |---------->| W |------------->| S |
- * +---+ +---+ ---------->+---+
- * | | | | |
- * 3 | |4,5| | |
- * -------------- -------- |
- * | | | | |
- * | | | | |
- * | -----------
- * | 1,3| | | |
- * V | 2| | |
- * +---+ ACCT +---+-- | ----->+---+
- * | |---------->| W | 4,5 -------->| F |
- * +---+ +---+------------->+---+
- *
- * Of course in case of using a proxy this get really nasty and is not
- * standardized at all :-(
- */
- if (proxy) {
- int len;
- char buf[400];
-
- if (proxyUser != NULL) {
- /*
- * We need proxy auth
- */
- snprintf(buf, sizeof(buf), "USER %s\r\n", proxyUser);
- buf[sizeof(buf) - 1] = 0;
- len = strlen(buf);
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
- res = send(ctxt->controlFd, buf, len, 0);
- if (res < 0) {
- closesocket(ctxt->controlFd);
- ctxt->controlFd = -1;
- return(res);
- }
- res = xmlNanoFTPGetResponse(ctxt);
- switch (res) {
- case 2:
- if (proxyPasswd == NULL)
- break;
- case 3:
- if (proxyPasswd != NULL)
- snprintf(buf, sizeof(buf), "PASS %s\r\n", proxyPasswd);
- else
- snprintf(buf, sizeof(buf), "PASS anonymous@\r\n");
- buf[sizeof(buf) - 1] = 0;
- len = strlen(buf);
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
- res = send(ctxt->controlFd, buf, len, 0);
- if (res < 0) {
- closesocket(ctxt->controlFd);
- ctxt->controlFd = -1;
- return(res);
- }
- res = xmlNanoFTPGetResponse(ctxt);
- if (res > 3) {
- closesocket(ctxt->controlFd);
- ctxt->controlFd = -1;
- return(-1);
- }
- break;
- case 1:
- break;
- case 4:
- case 5:
- case -1:
- default:
- closesocket(ctxt->controlFd);
- ctxt->controlFd = -1;
- return(-1);
- }
- }
-
- /*
- * We assume we don't need more authentication to the proxy
- * and that it succeeded :-\
- */
- switch (proxyType) {
- case 0:
- /* we will try in sequence */
- case 1:
- /* Using SITE command */
- snprintf(buf, sizeof(buf), "SITE %s\r\n", ctxt->hostname);
- buf[sizeof(buf) - 1] = 0;
- len = strlen(buf);
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
- res = send(ctxt->controlFd, buf, len, 0);
- if (res < 0) {
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
- return(res);
- }
- res = xmlNanoFTPGetResponse(ctxt);
- if (res == 2) {
- /* we assume it worked :-\ 1 is error for SITE command */
- proxyType = 1;
- break;
- }
- if (proxyType == 1) {
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
- return(-1);
- }
- case 2:
- /* USER user@host command */
- if (ctxt->user == NULL)
- snprintf(buf, sizeof(buf), "USER anonymous@%s\r\n",
- ctxt->hostname);
- else
- snprintf(buf, sizeof(buf), "USER %s@%s\r\n",
- ctxt->user, ctxt->hostname);
- buf[sizeof(buf) - 1] = 0;
- len = strlen(buf);
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
- res = send(ctxt->controlFd, buf, len, 0);
- if (res < 0) {
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
- return(res);
- }
- res = xmlNanoFTPGetResponse(ctxt);
- if ((res == 1) || (res == 2)) {
- /* we assume it worked :-\ */
- proxyType = 2;
- return(0);
- }
- if (ctxt->passwd == NULL)
- snprintf(buf, sizeof(buf), "PASS anonymous@\r\n");
- else
- snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);
- buf[sizeof(buf) - 1] = 0;
- len = strlen(buf);
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
- res = send(ctxt->controlFd, buf, len, 0);
- if (res < 0) {
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
- return(res);
- }
- res = xmlNanoFTPGetResponse(ctxt);
- if ((res == 1) || (res == 2)) {
- /* we assume it worked :-\ */
- proxyType = 2;
- return(0);
- }
- if (proxyType == 2) {
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
- return(-1);
- }
- case 3:
- /*
- * If you need support for other Proxy authentication scheme
- * send the code or at least the sequence in use.
- */
- default:
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
- return(-1);
- }
- }
- /*
- * Non-proxy handling.
- */
- res = xmlNanoFTPSendUser(ctxt);
- if (res < 0) {
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
- return(-1);
- }
- res = xmlNanoFTPGetResponse(ctxt);
- switch (res) {
- case 2:
- return(0);
- case 3:
- break;
- case 1:
- case 4:
- case 5:
- case -1:
- default:
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
- return(-1);
- }
- res = xmlNanoFTPSendPasswd(ctxt);
- if (res < 0) {
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
- return(-1);
- }
- res = xmlNanoFTPGetResponse(ctxt);
- switch (res) {
- case 2:
- break;
- case 3:
- xmlGenericError(xmlGenericErrorContext,
- "FTP server asking for ACCNT on anonymous\n");
- case 1:
- case 4:
- case 5:
- case -1:
- default:
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
- return(-1);
- }
-
- return(0);
-}
-
-/**
- * xmlNanoFTPConnectTo:
- * @server: an FTP server name
- * @port: the port (use 21 if 0)
- *
- * Tries to open a control connection to the given server/port
- *
- * Returns an fTP context or NULL if it failed
- */
-
-void*
-xmlNanoFTPConnectTo(const char *server, int port) {
- xmlNanoFTPCtxtPtr ctxt;
- int res;
-
- xmlNanoFTPInit();
- if (server == NULL)
- return(NULL);
- ctxt = (xmlNanoFTPCtxtPtr) xmlNanoFTPNewCtxt(NULL);
- ctxt->hostname = xmlMemStrdup(server);
- if (port != 0)
- ctxt->port = port;
- res = xmlNanoFTPConnect(ctxt);
- if (res < 0) {
- xmlNanoFTPFreeCtxt(ctxt);
- return(NULL);
- }
- return(ctxt);
-}
-
-/**
- * xmlNanoFTPCwd:
- * @ctx: an FTP context
- * @directory: a directory on the server
- *
- * Tries to change the remote directory
- *
- * Returns -1 incase of error, 1 if CWD worked, 0 if it failed
- */
-
-int
-xmlNanoFTPCwd(void *ctx, char *directory) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
- char buf[400];
- int len;
- int res;
-
- /*
- * Expected response code for CWD:
- *
- * CWD
- * 250
- * 500, 501, 502, 421, 530, 550
- */
- snprintf(buf, sizeof(buf), "CWD %s\r\n", directory);
- buf[sizeof(buf) - 1] = 0;
- len = strlen(buf);
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
- res = send(ctxt->controlFd, buf, len, 0);
- if (res < 0) return(res);
- res = xmlNanoFTPGetResponse(ctxt);
- if (res == 4) {
- return(-1);
- }
- if (res == 2) return(1);
- if (res == 5) {
- return(0);
- }
- return(0);
-}
-
-/**
- * xmlNanoFTPGetConnection:
- * @ctx: an FTP context
- *
- * Try to open a data connection to the server. Currently only
- * passive mode is supported.
- *
- * Returns -1 incase of error, 0 otherwise
- */
-
-int
-xmlNanoFTPGetConnection(void *ctx) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
- char buf[200], *cur;
- int len, i;
- int res;
- unsigned char ad[6], *adp, *portp;
- unsigned int temp[6];
- struct sockaddr_in dataAddr;
- SOCKLEN_T dataAddrLen;
-
- ctxt->dataFd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (ctxt->dataFd < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNanoFTPGetConnection: failed to create socket\n");
- return(-1);
- }
- dataAddrLen = sizeof(dataAddr);
- memset(&dataAddr, 0, dataAddrLen);
- dataAddr.sin_family = AF_INET;
-
- if (ctxt->passive) {
- snprintf(buf, sizeof(buf), "PASV\r\n");
- len = strlen(buf);
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
- res = send(ctxt->controlFd, buf, len, 0);
- if (res < 0) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(res);
- }
- res = xmlNanoFTPReadResponse(ctx);
- if (res != 2) {
- if (res == 5) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(-1);
- } else {
- /*
- * retry with an active connection
- */
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- ctxt->passive = 0;
- }
- }
- cur = &ctxt->controlBuf[ctxt->controlBufAnswer];
- while (((*cur < '0') || (*cur > '9')) && *cur != '\0') cur++;
- if (sscanf(cur, "%u,%u,%u,%u,%u,%u", &temp[0], &temp[1], &temp[2],
- &temp[3], &temp[4], &temp[5]) != 6) {
- xmlGenericError(xmlGenericErrorContext,
- "Invalid answer to PASV\n");
- if (ctxt->dataFd != -1) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- }
- return(-1);
- }
- for (i=0; i<6; i++) ad[i] = (unsigned char) (temp[i] & 0xff);
- memcpy(&dataAddr.sin_addr, &ad[0], 4);
- memcpy(&dataAddr.sin_port, &ad[4], 2);
- if (connect(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "Failed to create a data connection\n");
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return (-1);
- }
- } else {
- getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);
- dataAddr.sin_port = 0;
- if (bind(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "Failed to bind a port\n");
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return (-1);
- }
- getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);
-
- if (listen(ctxt->dataFd, 1) < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "Could not listen on port %d\n",
- ntohs(dataAddr.sin_port));
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return (-1);
- }
- adp = (unsigned char *) &dataAddr.sin_addr;
- portp = (unsigned char *) &dataAddr.sin_port;
- snprintf(buf, sizeof(buf), "PORT %d,%d,%d,%d,%d,%d\r\n",
- adp[0] & 0xff, adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff,
- portp[0] & 0xff, portp[1] & 0xff);
- buf[sizeof(buf) - 1] = 0;
- len = strlen(buf);
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
-
- res = send(ctxt->controlFd, buf, len, 0);
- if (res < 0) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(res);
- }
- res = xmlNanoFTPGetResponse(ctxt);
- if (res != 2) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(-1);
- }
- }
- return(ctxt->dataFd);
-
-}
-
-/**
- * xmlNanoFTPCloseConnection:
- * @ctx: an FTP context
- *
- * Close the data connection from the server
- *
- * Returns -1 incase of error, 0 otherwise
- */
-
-int
-xmlNanoFTPCloseConnection(void *ctx) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
- int res;
- fd_set rfd, efd;
- struct timeval tv;
-
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- tv.tv_sec = 15;
- tv.tv_usec = 0;
- FD_ZERO(&rfd);
- FD_SET(ctxt->controlFd, &rfd);
- FD_ZERO(&efd);
- FD_SET(ctxt->controlFd, &efd);
- res = select(ctxt->controlFd + 1, &rfd, NULL, &efd, &tv);
- if (res < 0) {
-#ifdef DEBUG_FTP
- perror("select");
-#endif
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- return(-1);
- }
- if (res == 0) {
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext,
- "xmlNanoFTPCloseConnection: timeout\n");
-#endif
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- } else {
- res = xmlNanoFTPGetResponse(ctxt);
- if (res != 2) {
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- return(-1);
- }
- }
- return(0);
-}
-
-/**
- * xmlNanoFTPParseList:
- * @list: some data listing received from the server
- * @callback: the user callback
- * @userData: the user callback data
- *
- * Parse at most one entry from the listing.
- *
- * Returns -1 incase of error, the length of data parsed otherwise
- */
-
-static int
-xmlNanoFTPParseList(const char *list, ftpListCallback callback, void *userData) {
- const char *cur = list;
- char filename[151];
- char attrib[11];
- char owner[11];
- char group[11];
- char month[4];
- int year = 0;
- int minute = 0;
- int hour = 0;
- int day = 0;
- unsigned long size = 0;
- int links = 0;
- int i;
-
- if (!strncmp(cur, "total", 5)) {
- cur += 5;
- while (*cur == ' ') cur++;
- while ((*cur >= '0') && (*cur <= '9'))
- links = (links * 10) + (*cur++ - '0');
- while ((*cur == ' ') || (*cur == '\n') || (*cur == '\r'))
- cur++;
- return(cur - list);
- } else if (*list == '+') {
- return(0);
- } else {
- while ((*cur == ' ') || (*cur == '\n') || (*cur == '\r'))
- cur++;
- if (*cur == 0) return(0);
- i = 0;
- while (*cur != ' ') {
- if (i < 10)
- attrib[i++] = *cur;
- cur++;
- if (*cur == 0) return(0);
- }
- attrib[10] = 0;
- while (*cur == ' ') cur++;
- if (*cur == 0) return(0);
- while ((*cur >= '0') && (*cur <= '9'))
- links = (links * 10) + (*cur++ - '0');
- while (*cur == ' ') cur++;
- if (*cur == 0) return(0);
- i = 0;
- while (*cur != ' ') {
- if (i < 10)
- owner[i++] = *cur;
- cur++;
- if (*cur == 0) return(0);
- }
- owner[i] = 0;
- while (*cur == ' ') cur++;
- if (*cur == 0) return(0);
- i = 0;
- while (*cur != ' ') {
- if (i < 10)
- group[i++] = *cur;
- cur++;
- if (*cur == 0) return(0);
- }
- group[i] = 0;
- while (*cur == ' ') cur++;
- if (*cur == 0) return(0);
- while ((*cur >= '0') && (*cur <= '9'))
- size = (size * 10) + (*cur++ - '0');
- while (*cur == ' ') cur++;
- if (*cur == 0) return(0);
- i = 0;
- while (*cur != ' ') {
- if (i < 3)
- month[i++] = *cur;
- cur++;
- if (*cur == 0) return(0);
- }
- month[i] = 0;
- while (*cur == ' ') cur++;
- if (*cur == 0) return(0);
- while ((*cur >= '0') && (*cur <= '9'))
- day = (day * 10) + (*cur++ - '0');
- while (*cur == ' ') cur++;
- if (*cur == 0) return(0);
- if ((cur[1] == 0) || (cur[2] == 0)) return(0);
- if ((cur[1] == ':') || (cur[2] == ':')) {
- while ((*cur >= '0') && (*cur <= '9'))
- hour = (hour * 10) + (*cur++ - '0');
- if (*cur == ':') cur++;
- while ((*cur >= '0') && (*cur <= '9'))
- minute = (minute * 10) + (*cur++ - '0');
- } else {
- while ((*cur >= '0') && (*cur <= '9'))
- year = (year * 10) + (*cur++ - '0');
- }
- while (*cur == ' ') cur++;
- if (*cur == 0) return(0);
- i = 0;
- while ((*cur != '\n') && (*cur != '\r')) {
- if (i < 150)
- filename[i++] = *cur;
- cur++;
- if (*cur == 0) return(0);
- }
- filename[i] = 0;
- if ((*cur != '\n') && (*cur != '\r'))
- return(0);
- while ((*cur == '\n') || (*cur == '\r'))
- cur++;
- }
- if (callback != NULL) {
- callback(userData, filename, attrib, owner, group, size, links,
- year, month, day, hour, minute);
- }
- return(cur - list);
-}
-
-/**
- * xmlNanoFTPList:
- * @ctx: an FTP context
- * @callback: the user callback
- * @userData: the user callback data
- * @filename: optional files to list
- *
- * Do a listing on the server. All files info are passed back
- * in the callbacks.
- *
- * Returns -1 incase of error, 0 otherwise
- */
-
-int
-xmlNanoFTPList(void *ctx, ftpListCallback callback, void *userData,
- char *filename) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
- char buf[4096 + 1];
- int len, res;
- int indx = 0, base;
- fd_set rfd, efd;
- struct timeval tv;
-
- if (filename == NULL) {
- if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)
- return(-1);
- ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
- if (ctxt->dataFd == -1)
- return(-1);
- snprintf(buf, sizeof(buf), "LIST -L\r\n");
- } else {
- if (filename[0] != '/') {
- if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)
- return(-1);
- }
- ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
- if (ctxt->dataFd == -1)
- return(-1);
- snprintf(buf, sizeof(buf), "LIST -L %s\r\n", filename);
- }
- buf[sizeof(buf) - 1] = 0;
- len = strlen(buf);
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
- res = send(ctxt->controlFd, buf, len, 0);
- if (res < 0) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(res);
- }
- res = xmlNanoFTPReadResponse(ctxt);
- if (res != 1) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(-res);
- }
-
- do {
- tv.tv_sec = 1;
- tv.tv_usec = 0;
- FD_ZERO(&rfd);
- FD_SET(ctxt->dataFd, &rfd);
- FD_ZERO(&efd);
- FD_SET(ctxt->dataFd, &efd);
- res = select(ctxt->dataFd + 1, &rfd, NULL, &efd, &tv);
- if (res < 0) {
-#ifdef DEBUG_FTP
- perror("select");
-#endif
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(-1);
- }
- if (res == 0) {
- res = xmlNanoFTPCheckResponse(ctxt);
- if (res < 0) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- ctxt->dataFd = -1;
- return(-1);
- }
- if (res == 2) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(0);
- }
-
- continue;
- }
-
- if ((len = recv(ctxt->dataFd, &buf[indx], sizeof(buf) - (indx + 1), 0)) < 0) {
-#ifdef DEBUG_FTP
- perror("recv");
-#endif
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- ctxt->dataFd = -1;
- return(-1);
- }
-#ifdef DEBUG_FTP
- write(1, &buf[indx], len);
-#endif
- indx += len;
- buf[indx] = 0;
- base = 0;
- do {
- res = xmlNanoFTPParseList(&buf[base], callback, userData);
- base += res;
- } while (res > 0);
-
- memmove(&buf[0], &buf[base], indx - base);
- indx -= base;
- } while (len != 0);
- xmlNanoFTPCloseConnection(ctxt);
- return(0);
-}
-
-/**
- * xmlNanoFTPGetSocket:
- * @ctx: an FTP context
- * @filename: the file to retrieve (or NULL if path is in context).
- *
- * Initiate fetch of the given file from the server.
- *
- * Returns the socket for the data connection, or <0 in case of error
- */
-
-
-int
-xmlNanoFTPGetSocket(void *ctx, const char *filename) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
- char buf[300];
- int res, len;
- if ((filename == NULL) && (ctxt->path == NULL))
- return(-1);
- ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
- if (ctxt->dataFd == -1)
- return(-1);
-
- snprintf(buf, sizeof(buf), "TYPE I\r\n");
- len = strlen(buf);
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
- res = send(ctxt->controlFd, buf, len, 0);
- if (res < 0) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(res);
- }
- res = xmlNanoFTPReadResponse(ctxt);
- if (res != 2) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(-res);
- }
- if (filename == NULL)
- snprintf(buf, sizeof(buf), "RETR %s\r\n", ctxt->path);
- else
- snprintf(buf, sizeof(buf), "RETR %s\r\n", filename);
- buf[sizeof(buf) - 1] = 0;
- len = strlen(buf);
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
- res = send(ctxt->controlFd, buf, len, 0);
- if (res < 0) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(res);
- }
- res = xmlNanoFTPReadResponse(ctxt);
- if (res != 1) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(-res);
- }
- return(ctxt->dataFd);
-}
-
-/**
- * xmlNanoFTPGet:
- * @ctx: an FTP context
- * @callback: the user callback
- * @userData: the user callback data
- * @filename: the file to retrieve
- *
- * Fetch the given file from the server. All data are passed back
- * in the callbacks. The last callback has a size of 0 block.
- *
- * Returns -1 incase of error, 0 otherwise
- */
-
-int
-xmlNanoFTPGet(void *ctx, ftpDataCallback callback, void *userData,
- const char *filename) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
- char buf[4096];
- int len = 0, res;
- fd_set rfd;
- struct timeval tv;
-
- if ((filename == NULL) && (ctxt->path == NULL))
- return(-1);
- if (callback == NULL)
- return(-1);
- if (xmlNanoFTPGetSocket(ctxt, filename) < 0)
- return(-1);
-
- do {
- tv.tv_sec = 1;
- tv.tv_usec = 0;
- FD_ZERO(&rfd);
- FD_SET(ctxt->dataFd, &rfd);
- res = select(ctxt->dataFd + 1, &rfd, NULL, NULL, &tv);
- if (res < 0) {
-#ifdef DEBUG_FTP
- perror("select");
-#endif
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(-1);
- }
- if (res == 0) {
- res = xmlNanoFTPCheckResponse(ctxt);
- if (res < 0) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- ctxt->dataFd = -1;
- return(-1);
- }
- if (res == 2) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(0);
- }
-
- continue;
- }
- if ((len = recv(ctxt->dataFd, buf, sizeof(buf), 0)) < 0) {
- callback(userData, buf, len);
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(-1);
- }
- callback(userData, buf, len);
- } while (len != 0);
-
- return(xmlNanoFTPCloseConnection(ctxt));
-}
-
-/**
- * xmlNanoFTPRead:
- * @ctx: the FTP context
- * @dest: a buffer
- * @len: the buffer length
- *
- * This function tries to read @len bytes from the existing FTP connection
- * and saves them in @dest. This is a blocking call.
- *
- * Returns the number of byte read. 0 is an indication of an end of connection.
- * -1 indicates a parameter error.
- */
-int
-xmlNanoFTPRead(void *ctx, void *dest, int len) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-
- if (ctx == NULL) return(-1);
- if (ctxt->dataFd < 0) return(0);
- if (dest == NULL) return(-1);
- if (len <= 0) return(0);
-
- len = recv(ctxt->dataFd, dest, len, 0);
-#ifdef DEBUG_FTP
- xmlGenericError(xmlGenericErrorContext, "Recvd %d bytes\n", len);
-#endif
- if (len <= 0) {
- xmlNanoFTPCloseConnection(ctxt);
- }
- return(len);
-}
-
-/**
- * xmlNanoFTPOpen:
- * @URL: the URL to the resource
- *
- * Start to fetch the given ftp:// resource
- *
- * Returns an FTP context, or NULL
- */
-
-void*
-xmlNanoFTPOpen(const char *URL) {
- xmlNanoFTPCtxtPtr ctxt;
- int sock;
-
- xmlNanoFTPInit();
- if (URL == NULL) return(NULL);
- if (strncmp("ftp://", URL, 6)) return(NULL);
-
- ctxt = (xmlNanoFTPCtxtPtr) xmlNanoFTPNewCtxt(URL);
- if (ctxt == NULL) return(NULL);
- if (xmlNanoFTPConnect(ctxt) < 0) {
- xmlNanoFTPFreeCtxt(ctxt);
- return(NULL);
- }
- sock = xmlNanoFTPGetSocket(ctxt, ctxt->path);
- if (sock < 0) {
- xmlNanoFTPFreeCtxt(ctxt);
- return(NULL);
- }
- return(ctxt);
-}
-
-/**
- * xmlNanoFTPClose:
- * @ctx: an FTP context
- *
- * Close the connection and both control and transport
- *
- * Returns -1 incase of error, 0 otherwise
- */
-
-int
-xmlNanoFTPClose(void *ctx) {
- xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
-
- if (ctxt == NULL)
- return(-1);
-
- if (ctxt->dataFd >= 0) {
- closesocket(ctxt->dataFd);
- ctxt->dataFd = -1;
- }
- if (ctxt->controlFd >= 0) {
- xmlNanoFTPQuit(ctxt);
- closesocket(ctxt->controlFd);
- ctxt->controlFd = -1;
- }
- xmlNanoFTPFreeCtxt(ctxt);
- return(0);
-}
-
-#ifdef STANDALONE
-/************************************************************************
- * *
- * Basic test in Standalone mode *
- * *
- ************************************************************************/
-static
-void ftpList(void *userData, const char *filename, const char* attrib,
- const char *owner, const char *group, unsigned long size, int links,
- int year, const char *month, int day, int hour, int minute) {
- xmlGenericError(xmlGenericErrorContext,
- "%s %s %s %ld %s\n", attrib, owner, group, size, filename);
-}
-static
-void ftpData(void *userData, const char *data, int len) {
- if (userData == NULL) return;
- if (len <= 0) {
- fclose(userData);
- return;
- }
- fwrite(data, len, 1, userData);
-}
-
-int main(int argc, char **argv) {
- void *ctxt;
- FILE *output;
- char *tstfile = NULL;
-
- xmlNanoFTPInit();
- if (argc > 1) {
- ctxt = xmlNanoFTPNewCtxt(argv[1]);
- if (xmlNanoFTPConnect(ctxt) < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "Couldn't connect to %s\n", argv[1]);
- exit(1);
- }
- if (argc > 2)
- tstfile = argv[2];
- } else
- ctxt = xmlNanoFTPConnectTo("localhost", 0);
- if (ctxt == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Couldn't connect to localhost\n");
- exit(1);
- }
- xmlNanoFTPList(ctxt, ftpList, NULL, tstfile);
- output = fopen("/tmp/tstdata", "w");
- if (output != NULL) {
- if (xmlNanoFTPGet(ctxt, ftpData, (void *) output, tstfile) < 0)
- xmlGenericError(xmlGenericErrorContext,
- "Failed to get file\n");
-
- }
- xmlNanoFTPClose(ctxt);
- xmlMemoryDump();
- exit(0);
-}
-#endif /* STANDALONE */
-#else /* !LIBXML_FTP_ENABLED */
-#ifdef STANDALONE
-#include <stdio.h>
-int main(int argc, char **argv) {
- xmlGenericError(xmlGenericErrorContext,
- "%s : FTP support not compiled in\n", argv[0]);
- return(0);
-}
-#endif /* STANDALONE */
-#endif /* LIBXML_FTP_ENABLED */
diff --git a/bundle/libxml/nanohttp.c b/bundle/libxml/nanohttp.c
deleted file mode 100644
index 5a126b8868..0000000000
--- a/bundle/libxml/nanohttp.c
+++ /dev/null
@@ -1,1528 +0,0 @@
-/*
- * nanohttp.c: minimalist HTTP GET implementation to fetch external subsets.
- * focuses on size, streamability, reentrancy and portability
- *
- * This is clearly not a general purpose HTTP implementation
- * If you look for one, check:
- * http://www.w3.org/Library/
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-/* TODO add compression support, Send the Accept- , and decompress on the
- fly with ZLIB if found at compile-time */
-
-#define NEED_SOCKETS
-#define IN_LIBXML
-#include "libxml.h"
-/* Hack to get compilation to work -SH */
-#include <errno.h>
-
-#ifdef LIBXML_HTTP_ENABLED
-#include <string.h>
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_RESOLV_H
-#ifdef HAVE_ARPA_NAMESER_H
-#include <arpa/nameser.h>
-#endif
-#include <resolv.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#ifdef SUPPORT_IP6
-#include <resolv.h>
-#endif
-
-#ifdef VMS
-#include <stropts>
-#define SOCKLEN_T unsigned int
-#define SOCKET int
-#endif
-
-#include <libxml/globals.h>
-#include <libxml/xmlerror.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h> /* for xmlStr(n)casecmp() */
-#include <libxml/nanohttp.h>
-#include <libxml/globals.h>
-#include <libxml/uri.h>
-
-/**
- * A couple portability macros
- */
-#ifndef _WINSOCKAPI_
-#define closesocket(s) close(s)
-#define SOCKET int
-#endif
-
-#ifndef SOCKLEN_T
-#define SOCKLEN_T unsigned int
-#endif
-#ifndef SOCKET
-#define SOCKET int
-#endif
-
-#ifdef STANDALONE
-#define DEBUG_HTTP
-#define xmlStrncasecmp(a, b, n) strncasecmp((char *)a, (char *)b, n)
-#define xmlStrcasecmpi(a, b) strcasecmp((char *)a, (char *)b)
-#endif
-
-#define XML_NANO_HTTP_MAX_REDIR 10
-
-#define XML_NANO_HTTP_CHUNK 4096
-
-#define XML_NANO_HTTP_CLOSED 0
-#define XML_NANO_HTTP_WRITE 1
-#define XML_NANO_HTTP_READ 2
-#define XML_NANO_HTTP_NONE 4
-
-typedef struct xmlNanoHTTPCtxt {
- char *protocol; /* the protocol name */
- char *hostname; /* the host name */
- int port; /* the port */
- char *path; /* the path within the URL */
- SOCKET fd; /* the file descriptor for the socket */
- int state; /* WRITE / READ / CLOSED */
- char *out; /* buffer sent (zero terminated) */
- char *outptr; /* index within the buffer sent */
- char *in; /* the receiving buffer */
- char *content; /* the start of the content */
- char *inptr; /* the next byte to read from network */
- char *inrptr; /* the next byte to give back to the client */
- int inlen; /* len of the input buffer */
- int last; /* return code for last operation */
- int returnValue; /* the protocol return value */
- int ContentLength; /* specified content length from HTTP header */
- char *contentType; /* the MIME type for the input */
- char *location; /* the new URL in case of redirect */
- char *authHeader; /* contents of {WWW,Proxy}-Authenticate header */
-} xmlNanoHTTPCtxt, *xmlNanoHTTPCtxtPtr;
-
-static int initialized = 0;
-static char *proxy = NULL; /* the proxy name if any */
-static int proxyPort; /* the proxy port if any */
-static unsigned int timeout = 60;/* the select() timeout in seconds */
-
-int xmlNanoHTTPFetchContent( void * ctx, char ** ptr, int * len );
-int xmlNanoHTTPContentLength( void * ctx );
-
-/**
- * A portability function
- */
-static int socket_errno(void) {
-#ifdef _WINSOCKAPI_
- return(WSAGetLastError());
-#else
- return(errno);
-#endif
-}
-
-/**
- * xmlNanoHTTPInit:
- *
- * Initialize the HTTP protocol layer.
- * Currently it just checks for proxy informations
- */
-
-void
-xmlNanoHTTPInit(void) {
- const char *env;
-#ifdef _WINSOCKAPI_
- WSADATA wsaData;
-#endif
-
- if (initialized)
- return;
-
-#ifdef _WINSOCKAPI_
- if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
- return;
-#endif
-
- if (proxy == NULL) {
- proxyPort = 80;
- env = getenv("no_proxy");
- if (env != NULL)
- goto done;
- env = getenv("http_proxy");
- if (env != NULL) {
- xmlNanoHTTPScanProxy(env);
- goto done;
- }
- env = getenv("HTTP_PROXY");
- if (env != NULL) {
- xmlNanoHTTPScanProxy(env);
- goto done;
- }
- }
-done:
- initialized = 1;
-}
-
-/**
- * xmlNanoHTTPCleanup:
- *
- * Cleanup the HTTP protocol layer.
- */
-
-void
-xmlNanoHTTPCleanup(void) {
- if (proxy != NULL)
- xmlFree(proxy);
-#ifdef _WINSOCKAPI_
- if (initialized)
- WSACleanup();
-#endif
- initialized = 0;
- return;
-}
-
-/**
- * xmlNanoHTTPScanURL:
- * @ctxt: an HTTP context
- * @URL: The URL used to initialize the context
- *
- * (Re)Initialize an HTTP context by parsing the URL and finding
- * the protocol host port and path it indicates.
- */
-
-static void
-xmlNanoHTTPScanURL(xmlNanoHTTPCtxtPtr ctxt, const char *URL) {
- const char *cur = URL;
- char buf[4096];
- int indx = 0;
- int port = 0;
-
- if (ctxt->protocol != NULL) {
- xmlFree(ctxt->protocol);
- ctxt->protocol = NULL;
- }
- if (ctxt->hostname != NULL) {
- xmlFree(ctxt->hostname);
- ctxt->hostname = NULL;
- }
- if (ctxt->path != NULL) {
- xmlFree(ctxt->path);
- ctxt->path = NULL;
- }
- if (URL == NULL) return;
- buf[indx] = 0;
- while (*cur != 0) {
- if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
- buf[indx] = 0;
- ctxt->protocol = xmlMemStrdup(buf);
- indx = 0;
- cur += 3;
- break;
- }
- buf[indx++] = *cur++;
- }
- if (*cur == 0) return;
-
- buf[indx] = 0;
- while (1) {
- if (cur[0] == ':') {
- buf[indx] = 0;
- ctxt->hostname = xmlMemStrdup(buf);
- indx = 0;
- cur += 1;
- while ((*cur >= '0') && (*cur <= '9')) {
- port *= 10;
- port += *cur - '0';
- cur++;
- }
- if (port != 0) ctxt->port = port;
- while ((cur[0] != '/') && (*cur != 0))
- cur++;
- break;
- }
- if ((*cur == '/') || (*cur == 0)) {
- buf[indx] = 0;
- ctxt->hostname = xmlMemStrdup(buf);
- indx = 0;
- break;
- }
- buf[indx++] = *cur++;
- }
- if (*cur == 0)
- ctxt->path = xmlMemStrdup("/");
- else {
- indx = 0;
- buf[indx] = 0;
- while (*cur != 0)
- buf[indx++] = *cur++;
- buf[indx] = 0;
- ctxt->path = xmlMemStrdup(buf);
- }
-}
-
-/**
- * xmlNanoHTTPScanProxy:
- * @URL: The proxy URL used to initialize the proxy context
- *
- * (Re)Initialize the HTTP Proxy context by parsing the URL and finding
- * the protocol host port it indicates.
- * Should be like http://myproxy/ or http://myproxy:3128/
- * A NULL URL cleans up proxy informations.
- */
-
-void
-xmlNanoHTTPScanProxy(const char *URL) {
- const char *cur = URL;
- char buf[4096];
- int indx = 0;
- int port = 0;
-
- if (proxy != NULL) {
- xmlFree(proxy);
- proxy = NULL;
- }
- if (proxyPort != 0) {
- proxyPort = 0;
- }
-#ifdef DEBUG_HTTP
- if (URL == NULL)
- xmlGenericError(xmlGenericErrorContext,
- "Removing HTTP proxy info\n");
- else
- xmlGenericError(xmlGenericErrorContext,
- "Using HTTP proxy %s\n", URL);
-#endif
- if (URL == NULL) return;
- buf[indx] = 0;
- while (*cur != 0) {
- if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
- buf[indx] = 0;
- indx = 0;
- cur += 3;
- break;
- }
- buf[indx++] = *cur++;
- }
- if (*cur == 0) return;
-
- buf[indx] = 0;
- while (1) {
- if (cur[0] == ':') {
- buf[indx] = 0;
- proxy = xmlMemStrdup(buf);
- indx = 0;
- cur += 1;
- while ((*cur >= '0') && (*cur <= '9')) {
- port *= 10;
- port += *cur - '0';
- cur++;
- }
- if (port != 0) proxyPort = port;
- while ((cur[0] != '/') && (*cur != 0))
- cur++;
- break;
- }
- if ((*cur == '/') || (*cur == 0)) {
- buf[indx] = 0;
- proxy = xmlMemStrdup(buf);
- indx = 0;
- break;
- }
- buf[indx++] = *cur++;
- }
-}
-
-/**
- * xmlNanoHTTPNewCtxt:
- * @URL: The URL used to initialize the context
- *
- * Allocate and initialize a new HTTP context.
- *
- * Returns an HTTP context or NULL in case of error.
- */
-
-static xmlNanoHTTPCtxtPtr
-xmlNanoHTTPNewCtxt(const char *URL) {
- xmlNanoHTTPCtxtPtr ret;
- xmlChar *escaped;
-
- ret = (xmlNanoHTTPCtxtPtr) xmlMalloc(sizeof(xmlNanoHTTPCtxt));
- if (ret == NULL) return(NULL);
-
- memset(ret, 0, sizeof(xmlNanoHTTPCtxt));
- ret->port = 80;
- ret->returnValue = 0;
- ret->fd = -1;
- ret->ContentLength = -1;
-
- escaped = xmlURIEscapeStr(BAD_CAST URL, BAD_CAST"@/:=?;#%&");
- if (escaped != NULL) {
- xmlNanoHTTPScanURL(ret, (const char *) escaped);
- xmlFree(escaped);
- } else {
- xmlNanoHTTPScanURL(ret, URL);
- }
-
- return(ret);
-}
-
-/**
- * xmlNanoHTTPFreeCtxt:
- * @ctxt: an HTTP context
- *
- * Frees the context after closing the connection.
- */
-
-static void
-xmlNanoHTTPFreeCtxt(xmlNanoHTTPCtxtPtr ctxt) {
- if (ctxt == NULL) return;
- if (ctxt->hostname != NULL) xmlFree(ctxt->hostname);
- if (ctxt->protocol != NULL) xmlFree(ctxt->protocol);
- if (ctxt->path != NULL) xmlFree(ctxt->path);
- if (ctxt->out != NULL) xmlFree(ctxt->out);
- if (ctxt->in != NULL) xmlFree(ctxt->in);
- if (ctxt->contentType != NULL) xmlFree(ctxt->contentType);
- if (ctxt->location != NULL) xmlFree(ctxt->location);
- if (ctxt->authHeader != NULL) xmlFree(ctxt->authHeader);
- ctxt->state = XML_NANO_HTTP_NONE;
- if (ctxt->fd >= 0) closesocket(ctxt->fd);
- ctxt->fd = -1;
- xmlFree(ctxt);
-}
-
-/**
- * xmlNanoHTTPSend:
- * @ctxt: an HTTP context
- *
- * Send the input needed to initiate the processing on the server side
- * Returns number of bytes sent or -1 on error.
- */
-
-static int
-xmlNanoHTTPSend(xmlNanoHTTPCtxtPtr ctxt, const char * xmt_ptr, int outlen) {
-
- int total_sent = 0;
-
- if ( (ctxt->state & XML_NANO_HTTP_WRITE) && (xmt_ptr != NULL ) ) {
- while (total_sent < outlen) {
- int nsent = send(ctxt->fd, xmt_ptr + total_sent,
- outlen - total_sent, 0);
- if (nsent>0)
- total_sent += nsent;
- else if ( ( nsent == -1 ) &&
-#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
- ( socket_errno( ) != EAGAIN ) &&
-#endif
- ( socket_errno( ) != EWOULDBLOCK ) ) {
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPSend error: %s",
- strerror( socket_errno( ) ) );
-
- if ( total_sent == 0 )
- total_sent = -1;
- break;
- }
- else {
- /*
- ** No data sent
- ** Since non-blocking sockets are used, wait for
- ** socket to be writable or default timeout prior
- ** to retrying.
- */
-
- struct timeval tv;
- fd_set wfd;
-
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
- FD_ZERO( &wfd );
- FD_SET( ctxt->fd, &wfd );
- (void)select( ctxt->fd + 1, NULL, &wfd, NULL, &tv );
- }
- }
- }
-
- return total_sent;
-}
-
-/**
- * xmlNanoHTTPRecv:
- * @ctxt: an HTTP context
- *
- * Read information coming from the HTTP connection.
- * This is a blocking call (but it blocks in select(), not read()).
- *
- * Returns the number of byte read or -1 in case of error.
- */
-
-static int
-xmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt) {
- fd_set rfd;
- struct timeval tv;
-
-
- while (ctxt->state & XML_NANO_HTTP_READ) {
- if (ctxt->in == NULL) {
- ctxt->in = (char *) xmlMalloc(65000 * sizeof(char));
- if (ctxt->in == NULL) {
- ctxt->last = -1;
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPRecv: Error allocating input memory." );
- return(-1);
- }
- ctxt->inlen = 65000;
- ctxt->inptr = ctxt->content = ctxt->inrptr = ctxt->in;
- }
- if (ctxt->inrptr > ctxt->in + XML_NANO_HTTP_CHUNK) {
- int delta = ctxt->inrptr - ctxt->in;
- int len = ctxt->inptr - ctxt->inrptr;
-
- memmove(ctxt->in, ctxt->inrptr, len);
- ctxt->inrptr -= delta;
- ctxt->content -= delta;
- ctxt->inptr -= delta;
- }
- if ((ctxt->in + ctxt->inlen) < (ctxt->inptr + XML_NANO_HTTP_CHUNK)) {
- int d_inptr = ctxt->inptr - ctxt->in;
- int d_content = ctxt->content - ctxt->in;
- int d_inrptr = ctxt->inrptr - ctxt->in;
- char * tmp_ptr = ctxt->in;
-
- ctxt->inlen *= 2;
- ctxt->in = (char *) xmlRealloc(tmp_ptr, ctxt->inlen);
- if (ctxt->in == NULL) {
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPRecv: %s %d bytes.",
- "Failed to realloc input buffer to",
- ctxt->inlen );
- xmlFree( tmp_ptr );
- ctxt->last = -1;
- return(-1);
- }
- ctxt->inptr = ctxt->in + d_inptr;
- ctxt->content = ctxt->in + d_content;
- ctxt->inrptr = ctxt->in + d_inrptr;
- }
- ctxt->last = recv(ctxt->fd, ctxt->inptr, XML_NANO_HTTP_CHUNK, 0);
- if (ctxt->last > 0) {
- ctxt->inptr += ctxt->last;
- return(ctxt->last);
- }
- if (ctxt->last == 0) {
- return(0);
- }
- if (ctxt->last == -1) {
- switch (socket_errno()) {
- case EINPROGRESS:
- case EWOULDBLOCK:
-#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
- case EAGAIN:
-#endif
- break;
-
- case ECONNRESET:
- case ESHUTDOWN:
- return ( 0 );
-
- default:
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPRecv: recv( ) failure - %s",
- strerror( socket_errno( ) ) );
- return(-1);
- }
- }
-
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
- FD_ZERO(&rfd);
- FD_SET(ctxt->fd, &rfd);
-
- if ( (select(ctxt->fd+1, &rfd, NULL, NULL, &tv)<1)
-#if defined(EINTR)
- && (errno != EINTR)
-#endif
- )
- return(0);
- }
- return(0);
-}
-
-/**
- * xmlNanoHTTPReadLine:
- * @ctxt: an HTTP context
- *
- * Read one line in the HTTP server output, usually for extracting
- * the HTTP protocol informations from the answer header.
- *
- * Returns a newly allocated string with a copy of the line, or NULL
- * which indicate the end of the input.
- */
-
-static char *
-xmlNanoHTTPReadLine(xmlNanoHTTPCtxtPtr ctxt) {
- char buf[4096];
- char *bp = buf;
- int rc;
-
- while (bp - buf < 4095) {
- if (ctxt->inrptr == ctxt->inptr) {
- if ( (rc = xmlNanoHTTPRecv(ctxt)) == 0) {
- if (bp == buf)
- return(NULL);
- else
- *bp = 0;
- return(xmlMemStrdup(buf));
- }
- else if ( rc == -1 ) {
- return ( NULL );
- }
- }
- *bp = *ctxt->inrptr++;
- if (*bp == '\n') {
- *bp = 0;
- return(xmlMemStrdup(buf));
- }
- if (*bp != '\r')
- bp++;
- }
- buf[4095] = 0;
- return(xmlMemStrdup(buf));
-}
-
-
-/**
- * xmlNanoHTTPScanAnswer:
- * @ctxt: an HTTP context
- * @line: an HTTP header line
- *
- * Try to extract useful informations from the server answer.
- * We currently parse and process:
- * - The HTTP revision/ return code
- * - The Content-Type
- * - The Location for redirect processing.
- *
- * Returns -1 in case of failure, the file descriptor number otherwise
- */
-
-static void
-xmlNanoHTTPScanAnswer(xmlNanoHTTPCtxtPtr ctxt, const char *line) {
- const char *cur = line;
-
- if (line == NULL) return;
-
- if (!strncmp(line, "HTTP/", 5)) {
- int version = 0;
- int ret = 0;
-
- cur += 5;
- while ((*cur >= '0') && (*cur <= '9')) {
- version *= 10;
- version += *cur - '0';
- cur++;
- }
- if (*cur == '.') {
- cur++;
- if ((*cur >= '0') && (*cur <= '9')) {
- version *= 10;
- version += *cur - '0';
- cur++;
- }
- while ((*cur >= '0') && (*cur <= '9'))
- cur++;
- } else
- version *= 10;
- if ((*cur != ' ') && (*cur != '\t')) return;
- while ((*cur == ' ') || (*cur == '\t')) cur++;
- if ((*cur < '0') || (*cur > '9')) return;
- while ((*cur >= '0') && (*cur <= '9')) {
- ret *= 10;
- ret += *cur - '0';
- cur++;
- }
- if ((*cur != 0) && (*cur != ' ') && (*cur != '\t')) return;
- ctxt->returnValue = ret;
- } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Content-Type:", 13)) {
- cur += 13;
- while ((*cur == ' ') || (*cur == '\t')) cur++;
- if (ctxt->contentType != NULL)
- xmlFree(ctxt->contentType);
- ctxt->contentType = xmlMemStrdup(cur);
- } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"ContentType:", 12)) {
- cur += 12;
- if (ctxt->contentType != NULL) return;
- while ((*cur == ' ') || (*cur == '\t')) cur++;
- ctxt->contentType = xmlMemStrdup(cur);
- } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Location:", 9)) {
- cur += 9;
- while ((*cur == ' ') || (*cur == '\t')) cur++;
- if (ctxt->location != NULL)
- xmlFree(ctxt->location);
- ctxt->location = xmlMemStrdup(cur);
- } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"WWW-Authenticate:", 17)) {
- cur += 17;
- while ((*cur == ' ') || (*cur == '\t')) cur++;
- if (ctxt->authHeader != NULL)
- xmlFree(ctxt->authHeader);
- ctxt->authHeader = xmlMemStrdup(cur);
- } else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Proxy-Authenticate:", 19)) {
- cur += 19;
- while ((*cur == ' ') || (*cur == '\t')) cur++;
- if (ctxt->authHeader != NULL)
- xmlFree(ctxt->authHeader);
- ctxt->authHeader = xmlMemStrdup(cur);
- } else if ( !xmlStrncasecmp( BAD_CAST line, BAD_CAST"Content-Length:", 15) ) {
- cur += 15;
- ctxt->ContentLength = strtol( cur, NULL, 10 );
- }
-}
-
-/**
- * xmlNanoHTTPConnectAttempt:
- * @addr: a socket address structure
- *
- * Attempt a connection to the given IP:port endpoint. It forces
- * non-blocking semantic on the socket, and allow 60 seconds for
- * the host to answer.
- *
- * Returns -1 in case of failure, the file descriptor number otherwise
- */
-
-static int
-xmlNanoHTTPConnectAttempt(struct sockaddr *addr)
-{
- SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
- fd_set wfd;
- struct timeval tv;
- int status;
-
- if (s==-1) {
-#ifdef DEBUG_HTTP
- perror("socket");
-#endif
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPConnectAttempt: %s - %s",
- "socket creation failure",
- strerror( socket_errno( ) ) );
- return(-1);
- }
-
-#ifdef _WINSOCKAPI_
- {
- u_long one = 1;
-
- status = ioctlsocket(s, FIONBIO, &one) == SOCKET_ERROR ? -1 : 0;
- }
-#else /* _WINSOCKAPI_ */
-#if defined(VMS)
- {
- int enable = 1;
- status = ioctl(s, FIONBIO, &enable);
- }
-#else /* VMS */
- if ((status = fcntl(s, F_GETFL, 0)) != -1) {
-#ifdef O_NONBLOCK
- status |= O_NONBLOCK;
-#else /* O_NONBLOCK */
-#ifdef F_NDELAY
- status |= F_NDELAY;
-#endif /* F_NDELAY */
-#endif /* !O_NONBLOCK */
- status = fcntl(s, F_SETFL, status);
- }
- if (status < 0) {
-#ifdef DEBUG_HTTP
- perror("nonblocking");
-#endif
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPConnectAttempt: %s - %s",
- "error setting non-blocking IO",
- strerror( socket_errno( ) ) );
- closesocket(s);
- return(-1);
- }
-#endif /* !VMS */
-#endif /* !_WINSOCKAPI_ */
-
- if ((connect(s, addr, sizeof(*addr))==-1)) {
- switch (socket_errno()) {
- case EINPROGRESS:
- case EWOULDBLOCK:
- break;
- default:
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPConnectAttempt: %s - %s",
- "error connecting to HTTP server",
- strerror( socket_errno( ) ) );
- closesocket(s);
- return(-1);
- }
- }
-
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
-
- FD_ZERO(&wfd);
- FD_SET(s, &wfd);
-
- switch(select(s+1, NULL, &wfd, NULL, &tv))
- {
- case 0:
- /* Time out */
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPConnectAttempt: %s",
- "Connect attempt timed out." );
- closesocket(s);
- return(-1);
- case -1:
- /* Ermm.. ?? */
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPConnectAttempt: %s - %s",
- "Error connecting to host",
- strerror( socket_errno( ) ) );
- closesocket(s);
- return(-1);
- }
-
- if ( FD_ISSET(s, &wfd) ) {
- SOCKLEN_T len;
- len = sizeof(status);
- if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*)&status, &len) < 0 ) {
- /* Solaris error code */
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPConnectAttempt: %s - %s",
- "Error retrieving pending socket errors",
- strerror( socket_errno( ) ) );
- return (-1);
- }
- if ( status ) {
- closesocket(s);
- errno = status;
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPConnectAttempt: %s - %s",
- "Error connecting to remote host",
- strerror( status ) );
- return (-1);
- }
- } else {
- /* pbm */
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPConnectAttempt: %s\n",
- "Select returned, but descriptor not set for connection.\n" );
- closesocket(s);
- return (-1);
- }
-
- return(s);
-}
-
-/**
- * xmlNanoHTTPConnectHost:
- * @host: the host name
- * @port: the port number
- *
- * Attempt a connection to the given host:port endpoint. It tries
- * the multiple IP provided by the DNS if available.
- *
- * Returns -1 in case of failure, the file descriptor number otherwise
- */
-
-static int
-xmlNanoHTTPConnectHost(const char *host, int port)
-{
- struct hostent *h;
- struct sockaddr *addr;
- struct in_addr ia;
- struct sockaddr_in sockin;
-
-#ifdef SUPPORT_IP6
- struct in6_addr ia6;
- struct sockaddr_in6 sockin6;
-#endif
- int i;
- int s;
-
-#if defined(SUPPORT_IP6) && defined(RES_USE_INET6)
- if (!(_res.options & RES_INIT))
- res_init();
- _res.options |= RES_USE_INET6;
-#endif
- h = gethostbyname(host);
- if (h == NULL) {
-
-/*
- * Okay, I got fed up by the non-portability of this error message
- * extraction code. it work on Linux, if it work on your platform
- * and one want to enable it, send me the defined(foobar) needed
- */
-#if defined(HAVE_NETDB_H) && defined(HOST_NOT_FOUND) && defined(linux)
- const char *h_err_txt = "";
-
- switch (h_errno) {
- case HOST_NOT_FOUND:
- h_err_txt = "Authoritive host not found";
- break;
-
- case TRY_AGAIN:
- h_err_txt =
- "Non-authoritive host not found or server failure.";
- break;
-
- case NO_RECOVERY:
- h_err_txt =
- "Non-recoverable errors: FORMERR, REFUSED, or NOTIMP.";
- break;
-
- case NO_ADDRESS:
- h_err_txt =
- "Valid name, no data record of requested type.";
- break;
-
- default:
- h_err_txt = "No error text defined.";
- break;
- }
- xmlGenericError(xmlGenericErrorContext,
- "xmlNanoHTTPConnectHost: %s '%s' - %s",
- "Failed to resolve host", host, h_err_txt);
-#else
- xmlGenericError(xmlGenericErrorContext,
- "xmlNanoHTTPConnectHost: %s '%s'",
- "Failed to resolve host", host);
-#endif
- return (-1);
- }
-
- for (i = 0; h->h_addr_list[i]; i++) {
- if (h->h_addrtype == AF_INET) {
- /* A records (IPv4) */
- memcpy(&ia, h->h_addr_list[i], h->h_length);
- sockin.sin_family = h->h_addrtype;
- sockin.sin_addr = ia;
- sockin.sin_port = htons(port);
- addr = (struct sockaddr *) &sockin;
-#ifdef SUPPORT_IP6
- } else if (h->h_addrtype == AF_INET6) {
- /* AAAA records (IPv6) */
- memcpy(&ia6, h->h_addr_list[i], h->h_length);
- sockin6.sin_family = h->h_addrtype;
- sockin6.sin_addr = ia6;
- sockin6.sin_port = htons(port);
- addr = (struct sockaddr *) &sockin6;
-#endif
- } else
- break; /* for */
-
- s = xmlNanoHTTPConnectAttempt(addr);
- if (s != -1)
- return (s);
- }
-
-#ifdef DEBUG_HTTP
- xmlGenericError(xmlGenericErrorContext,
- "xmlNanoHTTPConnectHost: unable to connect to '%s'.\n",
- host);
-#endif
- return (-1);
-}
-
-
-/**
- * xmlNanoHTTPOpen:
- * @URL: The URL to load
- * @contentType: if available the Content-Type information will be
- * returned at that location
- *
- * This function try to open a connection to the indicated resource
- * via HTTP GET.
- *
- * Returns NULL in case of failure, otherwise a request handler.
- * The contentType, if provided must be freed by the caller
- */
-
-void*
-xmlNanoHTTPOpen(const char *URL, char **contentType) {
- if (contentType != NULL) *contentType = NULL;
- return(xmlNanoHTTPMethod(URL, NULL, NULL, contentType, NULL, 0));
-}
-
-/**
- * xmlNanoHTTPOpenRedir:
- * @URL: The URL to load
- * @contentType: if available the Content-Type information will be
- * returned at that location
- * @redir: if available the redirected URL will be returned
- *
- * This function try to open a connection to the indicated resource
- * via HTTP GET.
- *
- * Returns NULL in case of failure, otherwise a request handler.
- * The contentType, if provided must be freed by the caller
- */
-
-void*
-xmlNanoHTTPOpenRedir(const char *URL, char **contentType, char **redir) {
- if (contentType != NULL) *contentType = NULL;
- if (redir != NULL) *redir = NULL;
- return(xmlNanoHTTPMethodRedir(URL, NULL, NULL, contentType, redir, NULL,0));
-}
-
-/**
- * xmlNanoHTTPRead:
- * @ctx: the HTTP context
- * @dest: a buffer
- * @len: the buffer length
- *
- * This function tries to read @len bytes from the existing HTTP connection
- * and saves them in @dest. This is a blocking call.
- *
- * Returns the number of byte read. 0 is an indication of an end of connection.
- * -1 indicates a parameter error.
- */
-int
-xmlNanoHTTPRead(void *ctx, void *dest, int len) {
- xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx;
-
- if (ctx == NULL) return(-1);
- if (dest == NULL) return(-1);
- if (len <= 0) return(0);
-
- while (ctxt->inptr - ctxt->inrptr < len) {
- if (xmlNanoHTTPRecv(ctxt) <= 0) break;
- }
- if (ctxt->inptr - ctxt->inrptr < len)
- len = ctxt->inptr - ctxt->inrptr;
- memcpy(dest, ctxt->inrptr, len);
- ctxt->inrptr += len;
- return(len);
-}
-
-/**
- * xmlNanoHTTPClose:
- * @ctx: the HTTP context
- *
- * This function closes an HTTP context, it ends up the connection and
- * free all data related to it.
- */
-void
-xmlNanoHTTPClose(void *ctx) {
- xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx;
-
- if (ctx == NULL) return;
-
- xmlNanoHTTPFreeCtxt(ctxt);
-}
-
-/**
- * xmlNanoHTTPMethodRedir:
- * @URL: The URL to load
- * @method: the HTTP method to use
- * @input: the input string if any
- * @contentType: the Content-Type information IN and OUT
- * @redir: the redirected URL OUT
- * @headers: the extra headers
- * @ilen: input length
- *
- * This function try to open a connection to the indicated resource
- * via HTTP using the given @method, adding the given extra headers
- * and the input buffer for the request content.
- *
- * Returns NULL in case of failure, otherwise a request handler.
- * The contentType, or redir, if provided must be freed by the caller
- */
-
-void*
-xmlNanoHTTPMethodRedir(const char *URL, const char *method, const char *input,
- char **contentType, char **redir,
- const char *headers, int ilen ) {
- xmlNanoHTTPCtxtPtr ctxt;
- char *bp, *p;
- int blen, ret;
- int head;
- int xmt_bytes;
- int nbRedirects = 0;
- char *redirURL = NULL;
-
- if (URL == NULL) return(NULL);
- if (method == NULL) method = "GET";
- xmlNanoHTTPInit();
-
-retry:
- if (redirURL == NULL)
- ctxt = xmlNanoHTTPNewCtxt(URL);
- else {
- ctxt = xmlNanoHTTPNewCtxt(redirURL);
- }
-
- if ( ctxt == NULL ) {
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPMethodRedir: %s %s.",
- "Unable to allocate HTTP context to URI",
- ( ( redirURL == NULL ) ? URL : redirURL ) );
- return ( NULL );
- }
-
- if ((ctxt->protocol == NULL) || (strcmp(ctxt->protocol, "http"))) {
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPMethodRedir: %s - %s.",
- "Not a valid HTTP URI",
- ( ( redirURL == NULL ) ? URL : redirURL ) );
- xmlNanoHTTPFreeCtxt(ctxt);
- if (redirURL != NULL) xmlFree(redirURL);
- return(NULL);
- }
- if (ctxt->hostname == NULL) {
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPMethodRedir: %s - %s",
- "Failed to identify host in URI",
- ( ( redirURL == NULL ) ? URL : redirURL ) );
- xmlNanoHTTPFreeCtxt(ctxt);
- if (redirURL != NULL) xmlFree(redirURL);
- return(NULL);
- }
- if (proxy) {
- blen = strlen(ctxt->hostname) * 2 + 16;
- ret = xmlNanoHTTPConnectHost(proxy, proxyPort);
- }
- else {
- blen = strlen(ctxt->hostname);
- ret = xmlNanoHTTPConnectHost(ctxt->hostname, ctxt->port);
- }
- if (ret < 0) {
- xmlNanoHTTPFreeCtxt(ctxt);
- if (redirURL != NULL) xmlFree(redirURL);
- return(NULL);
- }
- ctxt->fd = ret;
-
- if (input == NULL)
- ilen = 0;
- else
- blen += 36;
-
- if (headers != NULL)
- blen += strlen(headers) + 2;
- if (contentType && *contentType)
- blen += strlen(*contentType) + 16;
- blen += strlen(method) + strlen(ctxt->path) + 24;
- bp = xmlMalloc(blen);
- if ( bp == NULL ) {
- xmlNanoHTTPFreeCtxt( ctxt );
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPMethodRedir: %s",
- "Error allocating HTTP header buffer." );
- return ( NULL );
- }
-
- p = bp;
-
- if (proxy) {
- if (ctxt->port != 80) {
- p += snprintf( p, blen - (p - bp), "%s http://%s:%d%s",
- method, ctxt->hostname,
- ctxt->port, ctxt->path );
- }
- else
- p += snprintf( p, blen - (p - bp), "%s http://%s%s", method,
- ctxt->hostname, ctxt->path);
- }
- else
- p += snprintf( p, blen - (p - bp), "%s %s", method, ctxt->path);
-
- p += snprintf( p, blen - (p - bp), " HTTP/1.0\r\nHost: %s\r\n",
- ctxt->hostname);
-
- if (contentType != NULL && *contentType)
- p += snprintf(p, blen - (p - bp), "Content-Type: %s\r\n", *contentType);
-
- if (headers != NULL)
- p += snprintf( p, blen - (p - bp), "%s", headers );
-
- if (input != NULL)
- snprintf(p, blen - (p - bp), "Content-Length: %d\r\n\r\n", ilen );
- else
- snprintf(p, blen - (p - bp), "\r\n");
-
-#ifdef DEBUG_HTTP
- xmlGenericError(xmlGenericErrorContext,
- "-> %s%s", proxy? "(Proxy) " : "", bp);
- if ((blen -= strlen(bp)+1) < 0)
- xmlGenericError(xmlGenericErrorContext,
- "ERROR: overflowed buffer by %d bytes\n", -blen);
-#endif
- ctxt->outptr = ctxt->out = bp;
- ctxt->state = XML_NANO_HTTP_WRITE;
- blen = strlen( ctxt->out );
- xmt_bytes = xmlNanoHTTPSend(ctxt, ctxt->out, blen );
-#ifdef DEBUG_HTTP
- if ( xmt_bytes != blen )
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPMethodRedir: Only %d of %d %s %s\n",
- xmt_bytes, blen,
- "bytes of HTTP headers sent to host",
- ctxt->hostname );
-#endif
-
- if ( input != NULL ) {
- xmt_bytes = xmlNanoHTTPSend( ctxt, input, ilen );
-
-#ifdef DEBUG_HTTP
- if ( xmt_bytes != ilen )
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPMethodRedir: Only %d of %d %s %s\n",
- xmt_bytes, ilen,
- "bytes of HTTP content sent to host",
- ctxt->hostname );
-#endif
- }
-
- ctxt->state = XML_NANO_HTTP_READ;
- head = 1;
-
- while ((p = xmlNanoHTTPReadLine(ctxt)) != NULL) {
- if (head && (*p == 0)) {
- head = 0;
- ctxt->content = ctxt->inrptr;
- xmlFree(p);
- break;
- }
- xmlNanoHTTPScanAnswer(ctxt, p);
-
-#ifdef DEBUG_HTTP
- xmlGenericError(xmlGenericErrorContext, "<- %s\n", p);
-#endif
- xmlFree(p);
- }
-
- if ((ctxt->location != NULL) && (ctxt->returnValue >= 300) &&
- (ctxt->returnValue < 400)) {
-#ifdef DEBUG_HTTP
- xmlGenericError(xmlGenericErrorContext,
- "\nRedirect to: %s\n", ctxt->location);
-#endif
- while ( xmlNanoHTTPRecv(ctxt) > 0 ) ;
- if (nbRedirects < XML_NANO_HTTP_MAX_REDIR) {
- nbRedirects++;
- if (redirURL != NULL)
- xmlFree(redirURL);
- redirURL = xmlMemStrdup(ctxt->location);
- xmlNanoHTTPFreeCtxt(ctxt);
- goto retry;
- }
- xmlNanoHTTPFreeCtxt(ctxt);
- if (redirURL != NULL) xmlFree(redirURL);
-#ifdef DEBUG_HTTP
- xmlGenericError(xmlGenericErrorContext,
- "xmlNanoHTTPMethodRedir: Too many redirects, aborting ...\n");
-#endif
- return(NULL);
- }
-
- if (contentType != NULL) {
- if (ctxt->contentType != NULL)
- *contentType = xmlMemStrdup(ctxt->contentType);
- else
- *contentType = NULL;
- }
-
- if ((redir != NULL) && (redirURL != NULL)) {
- *redir = redirURL;
- } else {
- if (redirURL != NULL)
- xmlFree(redirURL);
- if (redir != NULL)
- *redir = NULL;
- }
-
-#ifdef DEBUG_HTTP
- if (ctxt->contentType != NULL)
- xmlGenericError(xmlGenericErrorContext,
- "\nCode %d, content-type '%s'\n\n",
- ctxt->returnValue, ctxt->contentType);
- else
- xmlGenericError(xmlGenericErrorContext,
- "\nCode %d, no content-type\n\n",
- ctxt->returnValue);
-#endif
-
- return((void *) ctxt);
-}
-
-/**
- * xmlNanoHTTPMethod:
- * @URL: The URL to load
- * @method: the HTTP method to use
- * @input: the input string if any
- * @contentType: the Content-Type information IN and OUT
- * @headers: the extra headers
- * @ilen: input length
- *
- * This function try to open a connection to the indicated resource
- * via HTTP using the given @method, adding the given extra headers
- * and the input buffer for the request content.
- *
- * Returns NULL in case of failure, otherwise a request handler.
- * The contentType, if provided must be freed by the caller
- */
-
-void*
-xmlNanoHTTPMethod(const char *URL, const char *method, const char *input,
- char **contentType, const char *headers, int ilen) {
- return(xmlNanoHTTPMethodRedir(URL, method, input, contentType,
- NULL, headers, ilen));
-}
-
-/**
- * xmlNanoHTTPFetch:
- * @URL: The URL to load
- * @filename: the filename where the content should be saved
- * @contentType: if available the Content-Type information will be
- * returned at that location
- *
- * This function try to fetch the indicated resource via HTTP GET
- * and save it's content in the file.
- *
- * Returns -1 in case of failure, 0 incase of success. The contentType,
- * if provided must be freed by the caller
- */
-int
-xmlNanoHTTPFetch(const char *URL, const char *filename, char **contentType) {
- void *ctxt = NULL;
- char *buf = NULL;
- int fd;
- int len;
-
- ctxt = xmlNanoHTTPOpen(URL, contentType);
- if (ctxt == NULL) return(-1);
-
- if (!strcmp(filename, "-"))
- fd = 0;
- else {
- fd = open(filename, O_CREAT | O_WRONLY, 00644);
- if (fd < 0) {
- xmlNanoHTTPClose(ctxt);
- if ((contentType != NULL) && (*contentType != NULL)) {
- xmlFree(*contentType);
- *contentType = NULL;
- }
- return(-1);
- }
- }
-
- xmlNanoHTTPFetchContent( ctxt, &buf, &len );
- if ( len > 0 ) {
- write(fd, buf, len);
- }
-
- xmlNanoHTTPClose(ctxt);
- close(fd);
- return(0);
-}
-
-/**
- * xmlNanoHTTPSave:
- * @ctxt: the HTTP context
- * @filename: the filename where the content should be saved
- *
- * This function saves the output of the HTTP transaction to a file
- * It closes and free the context at the end
- *
- * Returns -1 in case of failure, 0 incase of success.
- */
-int
-xmlNanoHTTPSave(void *ctxt, const char *filename) {
- char *buf = NULL;
- int fd;
- int len;
-
- if (ctxt == NULL) return(-1);
-
- if (!strcmp(filename, "-"))
- fd = 0;
- else {
- fd = open(filename, O_CREAT | O_WRONLY);
- if (fd < 0) {
- xmlNanoHTTPClose(ctxt);
- return(-1);
- }
- }
-
- xmlNanoHTTPFetchContent( ctxt, &buf, &len );
- if ( len > 0 ) {
- write(fd, buf, len);
- }
-
- xmlNanoHTTPClose(ctxt);
- return(0);
-}
-
-/**
- * xmlNanoHTTPReturnCode:
- * @ctx: the HTTP context
- *
- * Get the latest HTTP return code received
- *
- * Returns the HTTP return code for the request.
- */
-int
-xmlNanoHTTPReturnCode(void *ctx) {
- xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx;
-
- if (ctxt == NULL) return(-1);
-
- return(ctxt->returnValue);
-}
-
-/**
- * xmlNanoHTTPAuthHeader:
- * @ctx: the HTTP context
- *
- * Get the authentication header of an HTTP context
- *
- * Returns the stashed value of the WWW-Authenticate or Proxy-Authenticate
- * header.
- */
-const char *
-xmlNanoHTTPAuthHeader(void *ctx) {
- xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx;
-
- if (ctxt == NULL) return(NULL);
-
- return(ctxt->authHeader);
-}
-
-/**
- * xmlNanoHTTPContentLength:
- * @ctx: the HTTP context
- *
- * Provides the specified content length from the HTTP header.
- *
- * Return the specified content length from the HTTP header. Note that
- * a value of -1 indicates that the content length element was not included in
- * the response header.
- */
-int
-xmlNanoHTTPContentLength( void * ctx ) {
- xmlNanoHTTPCtxtPtr ctxt = ctx;
-
- return ( ( ctxt == NULL ) ? -1 : ctxt->ContentLength );
-}
-
-/**
- * xmlNanoHTTPFetchContent:
- * @ctx: the HTTP context
- * @ptr: pointer to set to the content buffer.
- * @len: integer pointer to hold the length of the content
- *
- * Check if all the content was read
- *
- * Returns 0 if all the content was read and available, returns
- * -1 if received content length was less than specified or an error
- * occurred.
- */
-int
-xmlNanoHTTPFetchContent( void * ctx, char ** ptr, int * len ) {
- xmlNanoHTTPCtxtPtr ctxt = ctx;
-
- int rc = 0;
- int cur_lgth;
- int rcvd_lgth;
- int dummy_int;
- char * dummy_ptr = NULL;
-
- /* Dummy up return input parameters if not provided */
-
- if ( len == NULL )
- len = &dummy_int;
-
- if ( ptr == NULL )
- ptr = &dummy_ptr;
-
- /* But can't work without the context pointer */
-
- if ( ( ctxt == NULL ) || ( ctxt->content == NULL ) ) {
- *len = 0;
- *ptr = NULL;
- return ( -1 );
- }
-
- rcvd_lgth = ctxt->inptr - ctxt->content;
-
- while ( (cur_lgth = xmlNanoHTTPRecv( ctxt )) > 0 ) {
-
- rcvd_lgth += cur_lgth;
- if ( (ctxt->ContentLength > 0) && (rcvd_lgth >= ctxt->ContentLength) )
- break;
- }
-
- *ptr = ctxt->content;
- *len = rcvd_lgth;
-
- if ( ( ctxt->ContentLength > 0 ) && ( rcvd_lgth < ctxt->ContentLength ) )
- rc = -1;
- else if ( rcvd_lgth == 0 )
- rc = -1;
-
- return ( rc );
-}
-
-#ifdef STANDALONE
-int main(int argc, char **argv) {
- char *contentType = NULL;
-
- if (argv[1] != NULL) {
- if (argv[2] != NULL)
- xmlNanoHTTPFetch(argv[1], argv[2], &contentType);
- else
- xmlNanoHTTPFetch(argv[1], "-", &contentType);
- if (contentType != NULL) xmlFree(contentType);
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "%s: minimal HTTP GET implementation\n", argv[0]);
- xmlGenericError(xmlGenericErrorContext,
- "\tusage %s [ URL [ filename ] ]\n", argv[0]);
- }
- xmlNanoHTTPCleanup();
- xmlMemoryDump();
- return(0);
-}
-#endif /* STANDALONE */
-#else /* !LIBXML_HTTP_ENABLED */
-#ifdef STANDALONE
-#include <stdio.h>
-int main(int argc, char **argv) {
- xmlGenericError(xmlGenericErrorContext,
- "%s : HTTP support not compiled in\n", argv[0]);
- return(0);
-}
-#endif /* STANDALONE */
-#endif /* LIBXML_HTTP_ENABLED */
diff --git a/bundle/libxml/parser.c b/bundle/libxml/parser.c
deleted file mode 100644
index 66908264fc..0000000000
--- a/bundle/libxml/parser.c
+++ /dev/null
@@ -1,10912 +0,0 @@
-/*
- * parser.c : an XML 1.0 parser, namespaces and validity support are mostly
- * implemented on top of the SAX interfaces
- *
- * References:
- * The XML specification:
- * http://www.w3.org/TR/REC-xml
- * Original 1.0 version:
- * http://www.w3.org/TR/1998/REC-xml-19980210
- * XML second edition working draft
- * http://www.w3.org/TR/2000/WD-xml-2e-20000814
- *
- * Okay this is a big file, the parser core is around 7000 lines, then it
- * is followed by the progressive parser top routines, then the various
- * high level APIs to call the parser and a few miscellaneous functions.
- * A number of helper functions and deprecated ones have been moved to
- * parserInternals.c to reduce this file size.
- * As much as possible the functions are associated with their relative
- * production in the XML specification. A few productions defining the
- * different ranges of character are actually implanted either in
- * parserInternals.h or parserInternals.c
- * The DOM tree build is realized from the default SAX callbacks in
- * the module SAX.c.
- * The routines doing the validation checks are in valid.c and called either
- * from the SAX callbacks or as standalone functions using a preparsed
- * document.
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#if defined(WIN32) && !defined (__CYGWIN__)
-#define XML_DIR_SEP '\\'
-#else
-#define XML_DIR_SEP '/'
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/threads.h>
-#include <libxml/globals.h>
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/parserInternals.h>
-#include <libxml/valid.h>
-#include <libxml/entities.h>
-#include <libxml/xmlerror.h>
-#include <libxml/encoding.h>
-#include <libxml/xmlIO.h>
-#include <libxml/uri.h>
-#ifdef LIBXML_CATALOG_ENABLED
-#include <libxml/catalog.h>
-#endif
-
-#ifdef HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-
-#define XML_PARSER_BIG_BUFFER_SIZE 300
-#define XML_PARSER_BUFFER_SIZE 100
-
-#define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
-
-/*
- * List of XML prefixed PI allowed by W3C specs
- */
-
-static const char *xmlW3CPIs[] = {
- "xml-stylesheet",
- NULL
-};
-
-/* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
-xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
- const xmlChar **str);
-
-static int
-xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
- xmlSAXHandlerPtr sax,
- void *user_data, int depth, const xmlChar *URL,
- const xmlChar *ID, xmlNodePtr *list);
-
-static void
-xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
- xmlNodePtr lastNode);
-
-static int
-xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
- const xmlChar *string, void *user_data, xmlNodePtr *lst);
-/************************************************************************
- * *
- * Parser stacks related functions and macros *
- * *
- ************************************************************************/
-
-xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
- const xmlChar ** str);
-
-/**
- * inputPush:
- * @ctxt: an XML parser context
- * @value: the parser input
- *
- * Pushes a new parser input on top of the input stack
- *
- * Returns 0 in case of error, the index in the stack otherwise
- */
-extern int
-inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
-{
- if (ctxt->inputNr >= ctxt->inputMax) {
- ctxt->inputMax *= 2;
- ctxt->inputTab =
- (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
- ctxt->inputMax *
- sizeof(ctxt->inputTab[0]));
- if (ctxt->inputTab == NULL) {
- xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
- return (0);
- }
- }
- ctxt->inputTab[ctxt->inputNr] = value;
- ctxt->input = value;
- return (ctxt->inputNr++);
-}
-/**
- * inputPop:
- * @ctxt: an XML parser context
- *
- * Pops the top parser input from the input stack
- *
- * Returns the input just removed
- */
-extern xmlParserInputPtr
-inputPop(xmlParserCtxtPtr ctxt)
-{
- xmlParserInputPtr ret;
-
- if (ctxt->inputNr <= 0)
- return (0);
- ctxt->inputNr--;
- if (ctxt->inputNr > 0)
- ctxt->input = ctxt->inputTab[ctxt->inputNr - 1];
- else
- ctxt->input = NULL;
- ret = ctxt->inputTab[ctxt->inputNr];
- ctxt->inputTab[ctxt->inputNr] = 0;
- return (ret);
-}
-/**
- * nodePush:
- * @ctxt: an XML parser context
- * @value: the element node
- *
- * Pushes a new element node on top of the node stack
- *
- * Returns 0 in case of error, the index in the stack otherwise
- */
-extern int
-nodePush(xmlParserCtxtPtr ctxt, xmlNodePtr value)
-{
- if (ctxt->nodeNr >= ctxt->nodeMax) {
- ctxt->nodeMax *= 2;
- ctxt->nodeTab =
- (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
- ctxt->nodeMax *
- sizeof(ctxt->nodeTab[0]));
- if (ctxt->nodeTab == NULL) {
- xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
- return (0);
- }
- }
- ctxt->nodeTab[ctxt->nodeNr] = value;
- ctxt->node = value;
- return (ctxt->nodeNr++);
-}
-/**
- * nodePop:
- * @ctxt: an XML parser context
- *
- * Pops the top element node from the node stack
- *
- * Returns the node just removed
- */
-extern xmlNodePtr
-nodePop(xmlParserCtxtPtr ctxt)
-{
- xmlNodePtr ret;
-
- if (ctxt->nodeNr <= 0)
- return (0);
- ctxt->nodeNr--;
- if (ctxt->nodeNr > 0)
- ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
- else
- ctxt->node = NULL;
- ret = ctxt->nodeTab[ctxt->nodeNr];
- ctxt->nodeTab[ctxt->nodeNr] = 0;
- return (ret);
-}
-/**
- * namePush:
- * @ctxt: an XML parser context
- * @value: the element name
- *
- * Pushes a new element name on top of the name stack
- *
- * Returns 0 in case of error, the index in the stack otherwise
- */
-extern int
-namePush(xmlParserCtxtPtr ctxt, xmlChar * value)
-{
- if (ctxt->nameNr >= ctxt->nameMax) {
- ctxt->nameMax *= 2;
- ctxt->nameTab =
- (xmlChar * *)xmlRealloc(ctxt->nameTab,
- ctxt->nameMax *
- sizeof(ctxt->nameTab[0]));
- if (ctxt->nameTab == NULL) {
- xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
- return (0);
- }
- }
- ctxt->nameTab[ctxt->nameNr] = value;
- ctxt->name = value;
- return (ctxt->nameNr++);
-}
-/**
- * namePop:
- * @ctxt: an XML parser context
- *
- * Pops the top element name from the name stack
- *
- * Returns the name just removed
- */
-extern xmlChar *
-namePop(xmlParserCtxtPtr ctxt)
-{
- xmlChar *ret;
-
- if (ctxt->nameNr <= 0)
- return (0);
- ctxt->nameNr--;
- if (ctxt->nameNr > 0)
- ctxt->name = ctxt->nameTab[ctxt->nameNr - 1];
- else
- ctxt->name = NULL;
- ret = ctxt->nameTab[ctxt->nameNr];
- ctxt->nameTab[ctxt->nameNr] = 0;
- return (ret);
-}
-
-static int spacePush(xmlParserCtxtPtr ctxt, int val) {
- if (ctxt->spaceNr >= ctxt->spaceMax) {
- ctxt->spaceMax *= 2;
- ctxt->spaceTab = (int *) xmlRealloc(ctxt->spaceTab,
- ctxt->spaceMax * sizeof(ctxt->spaceTab[0]));
- if (ctxt->spaceTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc failed !\n");
- return(0);
- }
- }
- ctxt->spaceTab[ctxt->spaceNr] = val;
- ctxt->space = &ctxt->spaceTab[ctxt->spaceNr];
- return(ctxt->spaceNr++);
-}
-
-static int spacePop(xmlParserCtxtPtr ctxt) {
- int ret;
- if (ctxt->spaceNr <= 0) return(0);
- ctxt->spaceNr--;
- if (ctxt->spaceNr > 0)
- ctxt->space = &ctxt->spaceTab[ctxt->spaceNr - 1];
- else
- ctxt->space = NULL;
- ret = ctxt->spaceTab[ctxt->spaceNr];
- ctxt->spaceTab[ctxt->spaceNr] = -1;
- return(ret);
-}
-
-/*
- * Macros for accessing the content. Those should be used only by the parser,
- * and not exported.
- *
- * Dirty macros, i.e. one often need to make assumption on the context to
- * use them
- *
- * CUR_PTR return the current pointer to the xmlChar to be parsed.
- * To be used with extreme caution since operations consuming
- * characters may move the input buffer to a different location !
- * CUR returns the current xmlChar value, i.e. a 8 bit value if compiled
- * This should be used internally by the parser
- * only to compare to ASCII values otherwise it would break when
- * running with UTF-8 encoding.
- * RAW same as CUR but in the input buffer, bypass any token
- * extraction that may have been done
- * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only
- * to compare on ASCII based substring.
- * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
- * strings within the parser.
- *
- * Clean macros, not dependent of an ASCII context, expect UTF-8 encoding
- *
- * NEXT Skip to the next character, this does the proper decoding
- * in UTF-8 mode. It also pop-up unfinished entities on the fly.
- * NEXTL(l) Skip l xmlChar in the input buffer
- * CUR_CHAR(l) returns the current unicode character (int), set l
- * to the number of xmlChars used for the encoding [0-5].
- * CUR_SCHAR same but operate on a string instead of the context
- * COPY_BUF copy the current unicode char to the target buffer, increment
- * the index
- * GROW, SHRINK handling of input buffers
- */
-
-#define RAW (*ctxt->input->cur)
-#define CUR (*ctxt->input->cur)
-#define NXT(val) ctxt->input->cur[(val)]
-#define CUR_PTR ctxt->input->cur
-
-#define SKIP(val) do { \
- ctxt->nbChars += (val),ctxt->input->cur += (val); \
- if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
- if ((*ctxt->input->cur == 0) && \
- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) \
- xmlPopInput(ctxt); \
- } while (0)
-
-#define SHRINK if (ctxt->input->cur - ctxt->input->base > INPUT_CHUNK) \
- xmlSHRINK (ctxt);
-
-static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
- xmlParserInputShrink(ctxt->input);
- if ((*ctxt->input->cur == 0) &&
- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
- xmlPopInput(ctxt);
- }
-
-#define GROW if (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK) \
- xmlGROW (ctxt);
-
-static void xmlGROW (xmlParserCtxtPtr ctxt) {
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- if ((*ctxt->input->cur == 0) &&
- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
- xmlPopInput(ctxt);
- }
-
-#define SKIP_BLANKS xmlSkipBlankChars(ctxt)
-
-#define NEXT xmlNextChar(ctxt)
-
-#define NEXT1 { \
- ctxt->input->cur++; \
- ctxt->nbChars++; \
- if (*ctxt->input->cur == 0) \
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK); \
- }
-
-#define NEXTL(l) do { \
- if (*(ctxt->input->cur) == '\n') { \
- ctxt->input->line++; ctxt->input->col = 1; \
- } else ctxt->input->col++; \
- ctxt->input->cur += l; \
- if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
- } while (0)
-
-#define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
-#define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
-
-#define COPY_BUF(l,b,i,v) \
- if (l == 1) b[i++] = (xmlChar) v; \
- else i += xmlCopyCharMultiByte(&b[i],v)
-
-/**
- * xmlSkipBlankChars:
- * @ctxt: the XML parser context
- *
- * skip all blanks character found at that point in the input streams.
- * It pops up finished entities in the process if allowable at that point.
- *
- * Returns the number of space chars skipped
- */
-
-int
-xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
- int res = 0;
-
- /*
- * It's Okay to use CUR/NEXT here since all the blanks are on
- * the ASCII range.
- */
- if ((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) {
- const xmlChar *cur;
- /*
- * if we are in the document content, go really fast
- */
- cur = ctxt->input->cur;
- while (IS_BLANK(*cur)) {
- if (*cur == '\n') {
- ctxt->input->line++; ctxt->input->col = 1;
- }
- cur++;
- res++;
- if (*cur == 0) {
- ctxt->input->cur = cur;
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- cur = ctxt->input->cur;
- }
- }
- ctxt->input->cur = cur;
- } else {
- int cur;
- do {
- cur = CUR;
- while (IS_BLANK(cur)) { /* CHECKED tstblanks.xml */
- NEXT;
- cur = CUR;
- res++;
- }
- while ((cur == 0) && (ctxt->inputNr > 1) &&
- (ctxt->instate != XML_PARSER_COMMENT)) {
- xmlPopInput(ctxt);
- cur = CUR;
- }
- /*
- * Need to handle support of entities branching here
- */
- if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
- } while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */
- }
- return(res);
-}
-
-/************************************************************************
- * *
- * Commodity functions to handle entities *
- * *
- ************************************************************************/
-
-/**
- * xmlPopInput:
- * @ctxt: an XML parser context
- *
- * xmlPopInput: the current input pointed by ctxt->input came to an end
- * pop it and return the next char.
- *
- * Returns the current xmlChar in the parser context
- */
-xmlChar
-xmlPopInput(xmlParserCtxtPtr ctxt) {
- if (ctxt->inputNr == 1) return(0); /* End of main Input */
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext,
- "Popping input %d\n", ctxt->inputNr);
- xmlFreeInputStream(inputPop(ctxt));
- if ((*ctxt->input->cur == 0) &&
- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
- return(xmlPopInput(ctxt));
- return(CUR);
-}
-
-/**
- * xmlPushInput:
- * @ctxt: an XML parser context
- * @input: an XML parser input fragment (entity, XML fragment ...).
- *
- * xmlPushInput: switch to a new input stream which is stacked on top
- * of the previous one(s).
- */
-void
-xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
- if (input == NULL) return;
-
- if (xmlParserDebugEntities) {
- if ((ctxt->input != NULL) && (ctxt->input->filename))
- xmlGenericError(xmlGenericErrorContext,
- "%s(%d): ", ctxt->input->filename,
- ctxt->input->line);
- xmlGenericError(xmlGenericErrorContext,
- "Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
- }
- inputPush(ctxt, input);
- GROW;
-}
-
-/**
- * xmlParseCharRef:
- * @ctxt: an XML parser context
- *
- * parse Reference declarations
- *
- * [66] CharRef ::= '&#' [0-9]+ ';' |
- * '&#x' [0-9a-fA-F]+ ';'
- *
- * [ WFC: Legal Character ]
- * Characters referred to using character references must match the
- * production for Char.
- *
- * Returns the value parsed (as an int), 0 in case of error
- */
-int
-xmlParseCharRef(xmlParserCtxtPtr ctxt) {
- unsigned int val = 0;
- int count = 0;
-
- /*
- * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
- */
- if ((RAW == '&') && (NXT(1) == '#') &&
- (NXT(2) == 'x')) {
- SKIP(3);
- GROW;
- while (RAW != ';') { /* loop blocked by count */
- if (count++ > 20) {
- count = 0;
- GROW;
- }
- if ((RAW >= '0') && (RAW <= '9'))
- val = val * 16 + (CUR - '0');
- else if ((RAW >= 'a') && (RAW <= 'f') && (count < 20))
- val = val * 16 + (CUR - 'a') + 10;
- else if ((RAW >= 'A') && (RAW <= 'F') && (count < 20))
- val = val * 16 + (CUR - 'A') + 10;
- else {
- ctxt->errNo = XML_ERR_INVALID_HEX_CHARREF;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseCharRef: invalid hexadecimal value\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- val = 0;
- break;
- }
- NEXT;
- count++;
- }
- if (RAW == ';') {
- /* on purpose to avoid reentrancy problems with NEXT and SKIP */
- ctxt->nbChars ++;
- ctxt->input->cur++;
- }
- } else if ((RAW == '&') && (NXT(1) == '#')) {
- SKIP(2);
- GROW;
- while (RAW != ';') { /* loop blocked by count */
- if (count++ > 20) {
- count = 0;
- GROW;
- }
- if ((RAW >= '0') && (RAW <= '9'))
- val = val * 10 + (CUR - '0');
- else {
- ctxt->errNo = XML_ERR_INVALID_DEC_CHARREF;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseCharRef: invalid decimal value\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- val = 0;
- break;
- }
- NEXT;
- count++;
- }
- if (RAW == ';') {
- /* on purpose to avoid reentrancy problems with NEXT and SKIP */
- ctxt->nbChars ++;
- ctxt->input->cur++;
- }
- } else {
- ctxt->errNo = XML_ERR_INVALID_CHARREF;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseCharRef: invalid value\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
- /*
- * [ WFC: Legal Character ]
- * Characters referred to using character references must match the
- * production for Char.
- */
- if (IS_CHAR(val)) {
- return(val);
- } else {
- ctxt->errNo = XML_ERR_INVALID_CHAR;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseCharRef: invalid xmlChar value %d\n",
- val);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- return(0);
-}
-
-/**
- * xmlParseStringCharRef:
- * @ctxt: an XML parser context
- * @str: a pointer to an index in the string
- *
- * parse Reference declarations, variant parsing from a string rather
- * than an an input flow.
- *
- * [66] CharRef ::= '&#' [0-9]+ ';' |
- * '&#x' [0-9a-fA-F]+ ';'
- *
- * [ WFC: Legal Character ]
- * Characters referred to using character references must match the
- * production for Char.
- *
- * Returns the value parsed (as an int), 0 in case of error, str will be
- * updated to the current value of the index
- */
-static int
-xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
- const xmlChar *ptr;
- xmlChar cur;
- int val = 0;
-
- if ((str == NULL) || (*str == NULL)) return(0);
- ptr = *str;
- cur = *ptr;
- if ((cur == '&') && (ptr[1] == '#') && (ptr[2] == 'x')) {
- ptr += 3;
- cur = *ptr;
- while (cur != ';') { /* Non input consuming loop */
- if ((cur >= '0') && (cur <= '9'))
- val = val * 16 + (cur - '0');
- else if ((cur >= 'a') && (cur <= 'f'))
- val = val * 16 + (cur - 'a') + 10;
- else if ((cur >= 'A') && (cur <= 'F'))
- val = val * 16 + (cur - 'A') + 10;
- else {
- ctxt->errNo = XML_ERR_INVALID_HEX_CHARREF;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseStringCharRef: invalid hexadecimal value\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- val = 0;
- break;
- }
- ptr++;
- cur = *ptr;
- }
- if (cur == ';')
- ptr++;
- } else if ((cur == '&') && (ptr[1] == '#')){
- ptr += 2;
- cur = *ptr;
- while (cur != ';') { /* Non input consuming loops */
- if ((cur >= '0') && (cur <= '9'))
- val = val * 10 + (cur - '0');
- else {
- ctxt->errNo = XML_ERR_INVALID_DEC_CHARREF;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseStringCharRef: invalid decimal value\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- val = 0;
- break;
- }
- ptr++;
- cur = *ptr;
- }
- if (cur == ';')
- ptr++;
- } else {
- ctxt->errNo = XML_ERR_INVALID_CHARREF;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseStringCharRef: invalid value\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(0);
- }
- *str = ptr;
-
- /*
- * [ WFC: Legal Character ]
- * Characters referred to using character references must match the
- * production for Char.
- */
- if (IS_CHAR(val)) {
- return(val);
- } else {
- ctxt->errNo = XML_ERR_INVALID_CHAR;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseStringCharRef: invalid xmlChar value %d\n", val);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- return(0);
-}
-
-/**
- * xmlNewBlanksWrapperInputStream:
- * @ctxt: an XML parser context
- * @entity: an Entity pointer
- *
- * Create a new input stream for wrapping
- * blanks around a PEReference
- *
- * Returns the new input stream or NULL
- */
-
-static void deallocblankswrapper (xmlChar *str) {xmlFree(str);}
-
-static xmlParserInputPtr
-xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
- xmlParserInputPtr input;
- xmlChar *buffer;
- size_t length;
- if (entity == NULL) {
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "internal: xmlNewBlanksWrapperInputStream entity = NULL\n");
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- return(NULL);
- }
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext,
- "new blanks wrapper for entity: %s\n", entity->name);
- input = xmlNewInputStream(ctxt);
- if (input == NULL) {
- return(NULL);
- }
- length = xmlStrlen(entity->name) + 5;
- buffer = xmlMalloc(length);
- if (buffer == NULL) {
- return(NULL);
- }
- buffer [0] = ' ';
- buffer [1] = '%';
- buffer [length-3] = ';';
- buffer [length-2] = ' ';
- buffer [length-1] = 0;
- memcpy(buffer + 2, entity->name, length - 5);
- input->free = deallocblankswrapper;
- input->base = buffer;
- input->cur = buffer;
- input->length = length;
- input->end = &buffer[length];
- return(input);
-}
-
-/**
- * xmlParserHandlePEReference:
- * @ctxt: the parser context
- *
- * [69] PEReference ::= '%' Name ';'
- *
- * [ WFC: No Recursion ]
- * A parsed entity must not contain a recursive
- * reference to itself, either directly or indirectly.
- *
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an internal DTD
- * subset which contains no parameter entity references, or a document
- * with "standalone='yes'", ... ... The declaration of a parameter
- * entity must precede any reference to it...
- *
- * [ VC: Entity Declared ]
- * In a document with an external subset or external parameter entities
- * with "standalone='no'", ... ... The declaration of a parameter entity
- * must precede any reference to it...
- *
- * [ WFC: In DTD ]
- * Parameter-entity references may only appear in the DTD.
- * NOTE: misleading but this is handled.
- *
- * A PEReference may have been detected in the current input stream
- * the handling is done accordingly to
- * http://www.w3.org/TR/REC-xml#entproc
- * i.e.
- * - Included in literal in entity values
- * - Included as Parameter Entity reference within DTDs
- */
-void
-xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlEntityPtr entity = NULL;
- xmlParserInputPtr input;
-
- if (RAW != '%') return;
- switch(ctxt->instate) {
- case XML_PARSER_CDATA_SECTION:
- return;
- case XML_PARSER_COMMENT:
- return;
- case XML_PARSER_START_TAG:
- return;
- case XML_PARSER_END_TAG:
- return;
- case XML_PARSER_EOF:
- ctxt->errNo = XML_ERR_PEREF_AT_EOF;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "PEReference at EOF\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return;
- case XML_PARSER_PROLOG:
- case XML_PARSER_START:
- case XML_PARSER_MISC:
- ctxt->errNo = XML_ERR_PEREF_IN_PROLOG;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "PEReference in prolog!\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return;
- case XML_PARSER_ENTITY_DECL:
- case XML_PARSER_CONTENT:
- case XML_PARSER_ATTRIBUTE_VALUE:
- case XML_PARSER_PI:
- case XML_PARSER_SYSTEM_LITERAL:
- case XML_PARSER_PUBLIC_LITERAL:
- /* we just ignore it there */
- return;
- case XML_PARSER_EPILOG:
- ctxt->errNo = XML_ERR_PEREF_IN_EPILOG;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "PEReference in epilog!\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return;
- case XML_PARSER_ENTITY_VALUE:
- /*
- * NOTE: in the case of entity values, we don't do the
- * substitution here since we need the literal
- * entity value to be able to save the internal
- * subset of the document.
- * This will be handled by xmlStringDecodeEntities
- */
- return;
- case XML_PARSER_DTD:
- /*
- * [WFC: Well-Formedness Constraint: PEs in Internal Subset]
- * In the internal DTD subset, parameter-entity references
- * can occur only where markup declarations can occur, not
- * within markup declarations.
- * In that case this is handled in xmlParseMarkupDecl
- */
- if ((ctxt->external == 0) && (ctxt->inputNr == 1))
- return;
- if (IS_BLANK(NXT(1)) || NXT(1) == 0)
- return;
- break;
- case XML_PARSER_IGNORE:
- return;
- }
-
- NEXT;
- name = xmlParseName(ctxt);
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext,
- "PEReference: %s\n", name);
- if (name == NULL) {
- ctxt->errNo = XML_ERR_PEREF_NO_NAME;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "xmlParserHandlePEReference: no name\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- if (RAW == ';') {
- NEXT;
- if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
- entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
- if (entity == NULL) {
-
- /*
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an
- * internal DTD subset which contains no parameter entity
- * references, or a document with "standalone='yes'", ...
- * ... The declaration of a parameter entity must precede
- * any reference to it...
- */
- if ((ctxt->standalone == 1) ||
- ((ctxt->hasExternalSubset == 0) &&
- (ctxt->hasPErefs == 0))) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "PEReference: %%%s; not found\n", name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- /*
- * [ VC: Entity Declared ]
- * In a document with an external subset or external
- * parameter entities with "standalone='no'", ...
- * ... The declaration of a parameter entity must precede
- * any reference to it...
- */
- if ((!ctxt->disableSAX) &&
- (ctxt->validate) && (ctxt->vctxt.error != NULL)) {
- ctxt->vctxt.error(ctxt->vctxt.userData,
- "PEReference: %%%s; not found\n", name);
- } else if ((!ctxt->disableSAX) &&
- (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "PEReference: %%%s; not found\n", name);
- ctxt->valid = 0;
- }
- } else if (ctxt->input->free != deallocblankswrapper) {
- input = xmlNewBlanksWrapperInputStream(ctxt, entity);
- xmlPushInput(ctxt, input);
- } else {
- if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
- (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
- xmlChar start[4];
- xmlCharEncoding enc;
-
- /*
- * handle the extra spaces added before and after
- * c.f. http://www.w3.org/TR/REC-xml#as-PE
- * this is done independently.
- */
- input = xmlNewEntityInputStream(ctxt, entity);
- xmlPushInput(ctxt, input);
-
- /*
- * Get the 4 first bytes and decode the charset
- * if enc != XML_CHAR_ENCODING_NONE
- * plug some encoding conversion routines.
- */
- GROW
- if (entity->length >= 4) {
- start[0] = RAW;
- start[1] = NXT(1);
- start[2] = NXT(2);
- start[3] = NXT(3);
- enc = xmlDetectCharEncoding(start, 4);
- if (enc != XML_CHAR_ENCODING_NONE) {
- xmlSwitchEncoding(ctxt, enc);
- }
- }
-
- if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
- (RAW == '<') && (NXT(1) == '?') &&
- (NXT(2) == 'x') && (NXT(3) == 'm') &&
- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
- xmlParseTextDecl(ctxt);
- }
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParserHandlePEReference: %s is not a parameter entity\n",
- name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- }
- } else {
- ctxt->errNo = XML_ERR_PEREF_SEMICOL_MISSING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParserHandlePEReference: expecting ';'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- xmlFree(name);
- }
-}
-
-/*
- * Macro used to grow the current buffer.
- */
-#define growBuffer(buffer) { \
- buffer##_size *= 2; \
- buffer = (xmlChar *) \
- xmlRealloc(buffer, buffer##_size * sizeof(xmlChar)); \
- if (buffer == NULL) { \
- xmlGenericError(xmlGenericErrorContext, "realloc failed"); \
- return(NULL); \
- } \
-}
-
-/**
- * xmlStringDecodeEntities:
- * @ctxt: the parser context
- * @str: the input string
- * @what: combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
- * @end: an end marker xmlChar, 0 if none
- * @end2: an end marker xmlChar, 0 if none
- * @end3: an end marker xmlChar, 0 if none
- *
- * Takes a entity string content and process to do the adequate substitutions.
- *
- * [67] Reference ::= EntityRef | CharRef
- *
- * [69] PEReference ::= '%' Name ';'
- *
- * Returns A newly allocated string with the substitution done. The caller
- * must deallocate it !
- */
-xmlChar *
-xmlStringDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int what,
- xmlChar end, xmlChar end2, xmlChar end3) {
- xmlChar *buffer = NULL;
- int buffer_size = 0;
-
- xmlChar *current = NULL;
- xmlEntityPtr ent;
- int c,l;
- int nbchars = 0;
-
- if (str == NULL)
- return(NULL);
-
- if (ctxt->depth > 40) {
- ctxt->errNo = XML_ERR_ENTITY_LOOP;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Detected entity reference loop\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(NULL);
- }
-
- /*
- * allocate a translation buffer.
- */
- buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
- buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
- if (buffer == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlStringDecodeEntities: malloc failed");
- return(NULL);
- }
-
- /*
- * OK loop until we reach one of the ending char or a size limit.
- * we are operating on already parsed values.
- */
- c = CUR_SCHAR(str, l);
- while ((c != 0) && (c != end) && /* non input consuming loop */
- (c != end2) && (c != end3)) {
-
- if (c == 0) break;
- if ((c == '&') && (str[1] == '#')) {
- int val = xmlParseStringCharRef(ctxt, &str);
- if (val != 0) {
- COPY_BUF(0,buffer,nbchars,val);
- }
- } else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext,
- "String decoding Entity Reference: %.30s\n",
- str);
- ent = xmlParseStringEntityRef(ctxt, &str);
- if ((ent != NULL) &&
- (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
- if (ent->content != NULL) {
- COPY_BUF(0,buffer,nbchars,ent->content[0]);
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "internal error entity has no content\n");
- }
- } else if ((ent != NULL) && (ent->content != NULL)) {
- xmlChar *rep;
-
- ctxt->depth++;
- rep = xmlStringDecodeEntities(ctxt, ent->content, what,
- 0, 0, 0);
- ctxt->depth--;
- if (rep != NULL) {
- current = rep;
- while (*current != 0) { /* non input consuming loop */
- buffer[nbchars++] = *current++;
- if (nbchars >
- buffer_size - XML_PARSER_BUFFER_SIZE) {
- growBuffer(buffer);
- }
- }
- xmlFree(rep);
- }
- } else if (ent != NULL) {
- int i = xmlStrlen(ent->name);
- const xmlChar *cur = ent->name;
-
- buffer[nbchars++] = '&';
- if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
- growBuffer(buffer);
- }
- for (;i > 0;i--)
- buffer[nbchars++] = *cur++;
- buffer[nbchars++] = ';';
- }
- } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext,
- "String decoding PE Reference: %.30s\n", str);
- ent = xmlParseStringPEReference(ctxt, &str);
- if (ent != NULL) {
- xmlChar *rep;
-
- ctxt->depth++;
- rep = xmlStringDecodeEntities(ctxt, ent->content, what,
- 0, 0, 0);
- ctxt->depth--;
- if (rep != NULL) {
- current = rep;
- while (*current != 0) { /* non input consuming loop */
- buffer[nbchars++] = *current++;
- if (nbchars >
- buffer_size - XML_PARSER_BUFFER_SIZE) {
- growBuffer(buffer);
- }
- }
- xmlFree(rep);
- }
- }
- } else {
- COPY_BUF(l,buffer,nbchars,c);
- str += l;
- if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
- growBuffer(buffer);
- }
- }
- c = CUR_SCHAR(str, l);
- }
- buffer[nbchars++] = 0;
- return(buffer);
-}
-
-
-/************************************************************************
- * *
- * Commodity functions to handle xmlChars *
- * *
- ************************************************************************/
-
-/**
- * xmlStrndup:
- * @cur: the input xmlChar *
- * @len: the len of @cur
- *
- * a strndup for array of xmlChar's
- *
- * Returns a new xmlChar * or NULL
- */
-xmlChar *
-xmlStrndup(const xmlChar *cur, int len) {
- xmlChar *ret;
-
- if ((cur == NULL) || (len < 0)) return(NULL);
- ret = (xmlChar *) xmlMalloc((len + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %ld byte failed\n",
- (len + 1) * (long)sizeof(xmlChar));
- return(NULL);
- }
- memcpy(ret, cur, len * sizeof(xmlChar));
- ret[len] = 0;
- return(ret);
-}
-
-/**
- * xmlStrdup:
- * @cur: the input xmlChar *
- *
- * a strdup for array of xmlChar's. Since they are supposed to be
- * encoded in UTF-8 or an encoding with 8bit based chars, we assume
- * a termination mark of '0'.
- *
- * Returns a new xmlChar * or NULL
- */
-xmlChar *
-xmlStrdup(const xmlChar *cur) {
- const xmlChar *p = cur;
-
- if (cur == NULL) return(NULL);
- while (*p != 0) p++; /* non input consuming */
- return(xmlStrndup(cur, p - cur));
-}
-
-/**
- * xmlCharStrndup:
- * @cur: the input char *
- * @len: the len of @cur
- *
- * a strndup for char's to xmlChar's
- *
- * Returns a new xmlChar * or NULL
- */
-
-xmlChar *
-xmlCharStrndup(const char *cur, int len) {
- int i;
- xmlChar *ret;
-
- if ((cur == NULL) || (len < 0)) return(NULL);
- ret = (xmlChar *) xmlMalloc((len + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext, "malloc of %ld byte failed\n",
- (len + 1) * (long)sizeof(xmlChar));
- return(NULL);
- }
- for (i = 0;i < len;i++)
- ret[i] = (xmlChar) cur[i];
- ret[len] = 0;
- return(ret);
-}
-
-/**
- * xmlCharStrdup:
- * @cur: the input char *
- *
- * a strdup for char's to xmlChar's
- *
- * Returns a new xmlChar * or NULL
- */
-
-xmlChar *
-xmlCharStrdup(const char *cur) {
- const char *p = cur;
-
- if (cur == NULL) return(NULL);
- while (*p != '\0') p++; /* non input consuming */
- return(xmlCharStrndup(cur, p - cur));
-}
-
-/**
- * xmlStrcmp:
- * @str1: the first xmlChar *
- * @str2: the second xmlChar *
- *
- * a strcmp for xmlChar's
- *
- * Returns the integer result of the comparison
- */
-
-int
-xmlStrcmp(const xmlChar *str1, const xmlChar *str2) {
- register int tmp;
-
- if (str1 == str2) return(0);
- if (str1 == NULL) return(-1);
- if (str2 == NULL) return(1);
- do {
- tmp = *str1++ - *str2;
- if (tmp != 0) return(tmp);
- } while (*str2++ != 0);
- return 0;
-}
-
-/**
- * xmlStrEqual:
- * @str1: the first xmlChar *
- * @str2: the second xmlChar *
- *
- * Check if both string are equal of have same content
- * Should be a bit more readable and faster than xmlStrEqual()
- *
- * Returns 1 if they are equal, 0 if they are different
- */
-
-int
-xmlStrEqual(const xmlChar *str1, const xmlChar *str2) {
- if (str1 == str2) return(1);
- if (str1 == NULL) return(0);
- if (str2 == NULL) return(0);
- do {
- if (*str1++ != *str2) return(0);
- } while (*str2++);
- return(1);
-}
-
-/**
- * xmlStrncmp:
- * @str1: the first xmlChar *
- * @str2: the second xmlChar *
- * @len: the max comparison length
- *
- * a strncmp for xmlChar's
- *
- * Returns the integer result of the comparison
- */
-
-int
-xmlStrncmp(const xmlChar *str1, const xmlChar *str2, int len) {
- register int tmp;
-
- if (len <= 0) return(0);
- if (str1 == str2) return(0);
- if (str1 == NULL) return(-1);
- if (str2 == NULL) return(1);
- do {
- tmp = *str1++ - *str2;
- if (tmp != 0 || --len == 0) return(tmp);
- } while (*str2++ != 0);
- return 0;
-}
-
-static const xmlChar casemap[256] = {
- 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
- 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
- 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
- 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
- 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
- 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
- 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
- 0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
- 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
- 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
- 0x78,0x79,0x7A,0x7B,0x5C,0x5D,0x5E,0x5F,
- 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
- 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
- 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
- 0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
- 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
- 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
- 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
- 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
- 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
- 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
- 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
- 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
- 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
- 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
- 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
- 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
- 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
- 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
- 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
- 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
-};
-
-/**
- * xmlStrcasecmp:
- * @str1: the first xmlChar *
- * @str2: the second xmlChar *
- *
- * a strcasecmp for xmlChar's
- *
- * Returns the integer result of the comparison
- */
-
-int
-xmlStrcasecmp(const xmlChar *str1, const xmlChar *str2) {
- register int tmp;
-
- if (str1 == str2) return(0);
- if (str1 == NULL) return(-1);
- if (str2 == NULL) return(1);
- do {
- tmp = casemap[*str1++] - casemap[*str2];
- if (tmp != 0) return(tmp);
- } while (*str2++ != 0);
- return 0;
-}
-
-/**
- * xmlStrncasecmp:
- * @str1: the first xmlChar *
- * @str2: the second xmlChar *
- * @len: the max comparison length
- *
- * a strncasecmp for xmlChar's
- *
- * Returns the integer result of the comparison
- */
-
-int
-xmlStrncasecmp(const xmlChar *str1, const xmlChar *str2, int len) {
- register int tmp;
-
- if (len <= 0) return(0);
- if (str1 == str2) return(0);
- if (str1 == NULL) return(-1);
- if (str2 == NULL) return(1);
- do {
- tmp = casemap[*str1++] - casemap[*str2];
- if (tmp != 0 || --len == 0) return(tmp);
- } while (*str2++ != 0);
- return 0;
-}
-
-/**
- * xmlStrchr:
- * @str: the xmlChar * array
- * @val: the xmlChar to search
- *
- * a strchr for xmlChar's
- *
- * Returns the xmlChar * for the first occurrence or NULL.
- */
-
-const xmlChar *
-xmlStrchr(const xmlChar *str, xmlChar val) {
- if (str == NULL) return(NULL);
- while (*str != 0) { /* non input consuming */
- if (*str == val) return((xmlChar *) str);
- str++;
- }
- return(NULL);
-}
-
-/**
- * xmlStrstr:
- * @str: the xmlChar * array (haystack)
- * @val: the xmlChar to search (needle)
- *
- * a strstr for xmlChar's
- *
- * Returns the xmlChar * for the first occurrence or NULL.
- */
-
-const xmlChar *
-xmlStrstr(const xmlChar *str, const xmlChar *val) {
- int n;
-
- if (str == NULL) return(NULL);
- if (val == NULL) return(NULL);
- n = xmlStrlen(val);
-
- if (n == 0) return(str);
- while (*str != 0) { /* non input consuming */
- if (*str == *val) {
- if (!xmlStrncmp(str, val, n)) return((const xmlChar *) str);
- }
- str++;
- }
- return(NULL);
-}
-
-/**
- * xmlStrcasestr:
- * @str: the xmlChar * array (haystack)
- * @val: the xmlChar to search (needle)
- *
- * a case-ignoring strstr for xmlChar's
- *
- * Returns the xmlChar * for the first occurrence or NULL.
- */
-
-const xmlChar *
-xmlStrcasestr(const xmlChar *str, xmlChar *val) {
- int n;
-
- if (str == NULL) return(NULL);
- if (val == NULL) return(NULL);
- n = xmlStrlen(val);
-
- if (n == 0) return(str);
- while (*str != 0) { /* non input consuming */
- if (casemap[*str] == casemap[*val])
- if (!xmlStrncasecmp(str, val, n)) return(str);
- str++;
- }
- return(NULL);
-}
-
-/**
- * xmlStrsub:
- * @str: the xmlChar * array (haystack)
- * @start: the index of the first char (zero based)
- * @len: the length of the substring
- *
- * Extract a substring of a given string
- *
- * Returns the xmlChar * for the first occurrence or NULL.
- */
-
-xmlChar *
-xmlStrsub(const xmlChar *str, int start, int len) {
- int i;
-
- if (str == NULL) return(NULL);
- if (start < 0) return(NULL);
- if (len < 0) return(NULL);
-
- for (i = 0;i < start;i++) {
- if (*str == 0) return(NULL);
- str++;
- }
- if (*str == 0) return(NULL);
- return(xmlStrndup(str, len));
-}
-
-/**
- * xmlStrlen:
- * @str: the xmlChar * array
- *
- * length of a xmlChar's string
- *
- * Returns the number of xmlChar contained in the ARRAY.
- */
-
-int
-xmlStrlen(const xmlChar *str) {
- int len = 0;
-
- if (str == NULL) return(0);
- while (*str != 0) { /* non input consuming */
- str++;
- len++;
- }
- return(len);
-}
-
-/**
- * xmlStrncat:
- * @cur: the original xmlChar * array
- * @add: the xmlChar * array added
- * @len: the length of @add
- *
- * a strncat for array of xmlChar's, it will extend @cur with the len
- * first bytes of @add.
- *
- * Returns a new xmlChar *, the original @cur is reallocated if needed
- * and should not be freed
- */
-
-xmlChar *
-xmlStrncat(xmlChar *cur, const xmlChar *add, int len) {
- int size;
- xmlChar *ret;
-
- if ((add == NULL) || (len == 0))
- return(cur);
- if (cur == NULL)
- return(xmlStrndup(add, len));
-
- size = xmlStrlen(cur);
- ret = (xmlChar *) xmlRealloc(cur, (size + len + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlStrncat: realloc of %ld byte failed\n",
- (size + len + 1) * (long)sizeof(xmlChar));
- return(cur);
- }
- memcpy(&ret[size], add, len * sizeof(xmlChar));
- ret[size + len] = 0;
- return(ret);
-}
-
-/**
- * xmlStrcat:
- * @cur: the original xmlChar * array
- * @add: the xmlChar * array added
- *
- * a strcat for array of xmlChar's. Since they are supposed to be
- * encoded in UTF-8 or an encoding with 8bit based chars, we assume
- * a termination mark of '0'.
- *
- * Returns a new xmlChar * containing the concatenated string.
- */
-xmlChar *
-xmlStrcat(xmlChar *cur, const xmlChar *add) {
- const xmlChar *p = add;
-
- if (add == NULL) return(cur);
- if (cur == NULL)
- return(xmlStrdup(add));
-
- while (*p != 0) p++; /* non input consuming */
- return(xmlStrncat(cur, add, p - add));
-}
-
-/************************************************************************
- * *
- * Commodity functions, cleanup needed ? *
- * *
- ************************************************************************/
-
-/**
- * areBlanks:
- * @ctxt: an XML parser context
- * @str: a xmlChar *
- * @len: the size of @str
- *
- * Is this a sequence of blank chars that one can ignore ?
- *
- * Returns 1 if ignorable 0 otherwise.
- */
-
-static int areBlanks(xmlParserCtxtPtr ctxt, const xmlChar *str, int len) {
- int i, ret;
- xmlNodePtr lastChild;
-
- /*
- * Don't spend time trying to differentiate them, the same callback is
- * used !
- */
- if (ctxt->sax->ignorableWhitespace == ctxt->sax->characters)
- return(0);
-
- /*
- * Check for xml:space value.
- */
- if (*(ctxt->space) == 1)
- return(0);
-
- /*
- * Check that the string is made of blanks
- */
- for (i = 0;i < len;i++)
- if (!(IS_BLANK(str[i]))) return(0);
-
- /*
- * Look if the element is mixed content in the DTD if available
- */
- if (ctxt->node == NULL) return(0);
- if (ctxt->myDoc != NULL) {
- ret = xmlIsMixedElement(ctxt->myDoc, ctxt->node->name);
- if (ret == 0) return(1);
- if (ret == 1) return(0);
- }
-
- /*
- * Otherwise, heuristic :-\
- */
- if (RAW != '<') return(0);
- if ((ctxt->node->children == NULL) &&
- (RAW == '<') && (NXT(1) == '/')) return(0);
-
- lastChild = xmlGetLastChild(ctxt->node);
- if (lastChild == NULL) {
- if ((ctxt->node->type != XML_ELEMENT_NODE) &&
- (ctxt->node->content != NULL)) return(0);
- } else if (xmlNodeIsText(lastChild))
- return(0);
- else if ((ctxt->node->children != NULL) &&
- (xmlNodeIsText(ctxt->node->children)))
- return(0);
- return(1);
-}
-
-/************************************************************************
- * *
- * Extra stuff for namespace support *
- * Relates to http://www.w3.org/TR/WD-xml-names *
- * *
- ************************************************************************/
-
-/**
- * xmlSplitQName:
- * @ctxt: an XML parser context
- * @name: an XML parser context
- * @prefix: a xmlChar **
- *
- * parse an UTF8 encoded XML qualified name string
- *
- * [NS 5] QName ::= (Prefix ':')? LocalPart
- *
- * [NS 6] Prefix ::= NCName
- *
- * [NS 7] LocalPart ::= NCName
- *
- * Returns the local part, and prefix is updated
- * to get the Prefix if any.
- */
-
-xmlChar *
-xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
- xmlChar buf[XML_MAX_NAMELEN + 5];
- xmlChar *buffer = NULL;
- int len = 0;
- int max = XML_MAX_NAMELEN;
- xmlChar *ret = NULL;
- const xmlChar *cur = name;
- int c;
-
- *prefix = NULL;
-
-#ifndef XML_XML_NAMESPACE
- /* xml: prefix is not really a namespace */
- if ((cur[0] == 'x') && (cur[1] == 'm') &&
- (cur[2] == 'l') && (cur[3] == ':'))
- return(xmlStrdup(name));
-#endif
-
- /* nasty but valid */
- if (cur[0] == ':')
- return(xmlStrdup(name));
-
- c = *cur++;
- while ((c != 0) && (c != ':') && (len < max)) { /* tested bigname.xml */
- buf[len++] = c;
- c = *cur++;
- }
- if (len >= max) {
- /*
- * Okay someone managed to make a huge name, so he's ready to pay
- * for the processing speed.
- */
- max = len * 2;
-
- buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
- if (buffer == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlSplitQName: out of memory\n");
- return(NULL);
- }
- memcpy(buffer, buf, len);
- while ((c != 0) && (c != ':')) { /* tested bigname.xml */
- if (len + 10 > max) {
- max *= 2;
- buffer = (xmlChar *) xmlRealloc(buffer,
- max * sizeof(xmlChar));
- if (buffer == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlSplitQName: out of memory\n");
- return(NULL);
- }
- }
- buffer[len++] = c;
- c = *cur++;
- }
- buffer[len] = 0;
- }
-
- if (buffer == NULL)
- ret = xmlStrndup(buf, len);
- else {
- ret = buffer;
- buffer = NULL;
- max = XML_MAX_NAMELEN;
- }
-
-
- if (c == ':') {
- c = *cur;
- if (c == 0) return(ret);
- *prefix = ret;
- len = 0;
-
- /*
- * Check that the first character is proper to start
- * a new name
- */
- if (!(((c >= 0x61) && (c <= 0x7A)) ||
- ((c >= 0x41) && (c <= 0x5A)) ||
- (c == '_') || (c == ':'))) {
- int l;
- int first = CUR_SCHAR(cur, l);
-
- if (!IS_LETTER(first) && (first != '_')) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Name %s is not XML Namespace compliant\n",
- name);
- }
- }
- cur++;
-
- while ((c != 0) && (len < max)) { /* tested bigname2.xml */
- buf[len++] = c;
- c = *cur++;
- }
- if (len >= max) {
- /*
- * Okay someone managed to make a huge name, so he's ready to pay
- * for the processing speed.
- */
- max = len * 2;
-
- buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
- if (buffer == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlSplitQName: out of memory\n");
- return(NULL);
- }
- memcpy(buffer, buf, len);
- while (c != 0) { /* tested bigname2.xml */
- if (len + 10 > max) {
- max *= 2;
- buffer = (xmlChar *) xmlRealloc(buffer,
- max * sizeof(xmlChar));
- if (buffer == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlSplitQName: out of memory\n");
- return(NULL);
- }
- }
- buffer[len++] = c;
- c = *cur++;
- }
- buffer[len] = 0;
- }
-
- if (buffer == NULL)
- ret = xmlStrndup(buf, len);
- else {
- ret = buffer;
- }
- }
-
- return(ret);
-}
-
-/************************************************************************
- * *
- * The parser itself *
- * Relates to http://www.w3.org/TR/REC-xml *
- * *
- ************************************************************************/
-
-static xmlChar * xmlParseNameComplex(xmlParserCtxtPtr ctxt);
-/**
- * xmlParseName:
- * @ctxt: an XML parser context
- *
- * parse an XML name.
- *
- * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
- * CombiningChar | Extender
- *
- * [5] Name ::= (Letter | '_' | ':') (NameChar)*
- *
- * [6] Names ::= Name (S Name)*
- *
- * Returns the Name parsed or NULL
- */
-
-xmlChar *
-xmlParseName(xmlParserCtxtPtr ctxt) {
- const xmlChar *in;
- xmlChar *ret;
- int count = 0;
-
- GROW;
-
- /*
- * Accelerator for simple ASCII names
- */
- in = ctxt->input->cur;
- if (((*in >= 0x61) && (*in <= 0x7A)) ||
- ((*in >= 0x41) && (*in <= 0x5A)) ||
- (*in == '_') || (*in == ':')) {
- in++;
- while (((*in >= 0x61) && (*in <= 0x7A)) ||
- ((*in >= 0x41) && (*in <= 0x5A)) ||
- ((*in >= 0x30) && (*in <= 0x39)) ||
- (*in == '_') || (*in == '-') ||
- (*in == ':') || (*in == '.'))
- in++;
- if ((*in > 0) && (*in < 0x80)) {
- count = in - ctxt->input->cur;
- ret = xmlStrndup(ctxt->input->cur, count);
- ctxt->input->cur = in;
- return(ret);
- }
- }
- return(xmlParseNameComplex(ctxt));
-}
-
-/**
- * xmlParseNameAndCompare:
- * @ctxt: an XML parser context
- *
- * parse an XML name and compares for match
- * (specialized for endtag parsing)
- *
- *
- * Returns NULL for an illegal name, (xmlChar*) 1 for success
- * and the name for mismatch
- */
-
-static xmlChar *
-xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
- const xmlChar *cmp = other;
- const xmlChar *in;
- xmlChar *ret;
-
- GROW;
-
- in = ctxt->input->cur;
- while (*in != 0 && *in == *cmp) {
- ++in;
- ++cmp;
- }
- if (*cmp == 0 && (*in == '>' || IS_BLANK (*in))) {
- /* success */
- ctxt->input->cur = in;
- return (xmlChar*) 1;
- }
- /* failure (or end of input buffer), check with full function */
- ret = xmlParseName (ctxt);
- if (ret != 0 && xmlStrEqual (ret, other)) {
- xmlFree (ret);
- return (xmlChar*) 1;
- }
- return ret;
-}
-
-static xmlChar *
-xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
- xmlChar buf[XML_MAX_NAMELEN + 5];
- int len = 0, l;
- int c;
- int count = 0;
-
- /*
- * Handler for more complex cases
- */
- GROW;
- c = CUR_CHAR(l);
- if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
- (!IS_LETTER(c) && (c != '_') &&
- (c != ':'))) {
- return(NULL);
- }
-
- while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
- ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
- (c == '.') || (c == '-') ||
- (c == '_') || (c == ':') ||
- (IS_COMBINING(c)) ||
- (IS_EXTENDER(c)))) {
- if (count++ > 100) {
- count = 0;
- GROW;
- }
- COPY_BUF(l,buf,len,c);
- NEXTL(l);
- c = CUR_CHAR(l);
- if (len >= XML_MAX_NAMELEN) {
- /*
- * Okay someone managed to make a huge name, so he's ready to pay
- * for the processing speed.
- */
- xmlChar *buffer;
- int max = len * 2;
-
- buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
- if (buffer == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseNameComplex: out of memory\n");
- return(NULL);
- }
- memcpy(buffer, buf, len);
- while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigname.xml */
- (c == '.') || (c == '-') ||
- (c == '_') || (c == ':') ||
- (IS_COMBINING(c)) ||
- (IS_EXTENDER(c))) {
- if (count++ > 100) {
- count = 0;
- GROW;
- }
- if (len + 10 > max) {
- max *= 2;
- buffer = (xmlChar *) xmlRealloc(buffer,
- max * sizeof(xmlChar));
- if (buffer == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseNameComplex: out of memory\n");
- return(NULL);
- }
- }
- COPY_BUF(l,buffer,len,c);
- NEXTL(l);
- c = CUR_CHAR(l);
- }
- buffer[len] = 0;
- return(buffer);
- }
- }
- return(xmlStrndup(buf, len));
-}
-
-/**
- * xmlParseStringName:
- * @ctxt: an XML parser context
- * @str: a pointer to the string pointer (IN/OUT)
- *
- * parse an XML name.
- *
- * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
- * CombiningChar | Extender
- *
- * [5] Name ::= (Letter | '_' | ':') (NameChar)*
- *
- * [6] Names ::= Name (S Name)*
- *
- * Returns the Name parsed or NULL. The @str pointer
- * is updated to the current location in the string.
- */
-
-static xmlChar *
-xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
- xmlChar buf[XML_MAX_NAMELEN + 5];
- const xmlChar *cur = *str;
- int len = 0, l;
- int c;
-
- c = CUR_SCHAR(cur, l);
- if (!IS_LETTER(c) && (c != '_') &&
- (c != ':')) {
- return(NULL);
- }
-
- while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigentname.xml */
- (c == '.') || (c == '-') ||
- (c == '_') || (c == ':') ||
- (IS_COMBINING(c)) ||
- (IS_EXTENDER(c))) {
- COPY_BUF(l,buf,len,c);
- cur += l;
- c = CUR_SCHAR(cur, l);
- if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
- /*
- * Okay someone managed to make a huge name, so he's ready to pay
- * for the processing speed.
- */
- xmlChar *buffer;
- int max = len * 2;
-
- buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
- if (buffer == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseStringName: out of memory\n");
- return(NULL);
- }
- memcpy(buffer, buf, len);
- while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigentname.xml */
- (c == '.') || (c == '-') ||
- (c == '_') || (c == ':') ||
- (IS_COMBINING(c)) ||
- (IS_EXTENDER(c))) {
- if (len + 10 > max) {
- max *= 2;
- buffer = (xmlChar *) xmlRealloc(buffer,
- max * sizeof(xmlChar));
- if (buffer == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseStringName: out of memory\n");
- return(NULL);
- }
- }
- COPY_BUF(l,buffer,len,c);
- cur += l;
- c = CUR_SCHAR(cur, l);
- }
- buffer[len] = 0;
- *str = cur;
- return(buffer);
- }
- }
- *str = cur;
- return(xmlStrndup(buf, len));
-}
-
-/**
- * xmlParseNmtoken:
- * @ctxt: an XML parser context
- *
- * parse an XML Nmtoken.
- *
- * [7] Nmtoken ::= (NameChar)+
- *
- * [8] Nmtokens ::= Nmtoken (S Nmtoken)*
- *
- * Returns the Nmtoken parsed or NULL
- */
-
-xmlChar *
-xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
- xmlChar buf[XML_MAX_NAMELEN + 5];
- int len = 0, l;
- int c;
- int count = 0;
-
- GROW;
- c = CUR_CHAR(l);
-
- while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigtoken.xml */
- (c == '.') || (c == '-') ||
- (c == '_') || (c == ':') ||
- (IS_COMBINING(c)) ||
- (IS_EXTENDER(c))) {
- if (count++ > 100) {
- count = 0;
- GROW;
- }
- COPY_BUF(l,buf,len,c);
- NEXTL(l);
- c = CUR_CHAR(l);
- if (len >= XML_MAX_NAMELEN) {
- /*
- * Okay someone managed to make a huge token, so he's ready to pay
- * for the processing speed.
- */
- xmlChar *buffer;
- int max = len * 2;
-
- buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
- if (buffer == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseNmtoken: out of memory\n");
- return(NULL);
- }
- memcpy(buffer, buf, len);
- while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigtoken.xml */
- (c == '.') || (c == '-') ||
- (c == '_') || (c == ':') ||
- (IS_COMBINING(c)) ||
- (IS_EXTENDER(c))) {
- if (count++ > 100) {
- count = 0;
- GROW;
- }
- if (len + 10 > max) {
- max *= 2;
- buffer = (xmlChar *) xmlRealloc(buffer,
- max * sizeof(xmlChar));
- if (buffer == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseNmtoken: out of memory\n");
- return(NULL);
- }
- }
- COPY_BUF(l,buffer,len,c);
- NEXTL(l);
- c = CUR_CHAR(l);
- }
- buffer[len] = 0;
- return(buffer);
- }
- }
- if (len == 0)
- return(NULL);
- return(xmlStrndup(buf, len));
-}
-
-/**
- * xmlParseEntityValue:
- * @ctxt: an XML parser context
- * @orig: if non-NULL store a copy of the original entity value
- *
- * parse a value for ENTITY declarations
- *
- * [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |
- * "'" ([^%&'] | PEReference | Reference)* "'"
- *
- * Returns the EntityValue parsed with reference substituted or NULL
- */
-
-xmlChar *
-xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
- xmlChar *buf = NULL;
- int len = 0;
- int size = XML_PARSER_BUFFER_SIZE;
- int c, l;
- xmlChar stop;
- xmlChar *ret = NULL;
- const xmlChar *cur = NULL;
- xmlParserInputPtr input;
-
- if (RAW == '"') stop = '"';
- else if (RAW == '\'') stop = '\'';
- else {
- ctxt->errNo = XML_ERR_ENTITY_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "EntityValue: \" or ' expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(NULL);
- }
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %d byte failed\n", size);
- return(NULL);
- }
-
- /*
- * The content of the entity definition is copied in a buffer.
- */
-
- ctxt->instate = XML_PARSER_ENTITY_VALUE;
- input = ctxt->input;
- GROW;
- NEXT;
- c = CUR_CHAR(l);
- /*
- * NOTE: 4.4.5 Included in Literal
- * When a parameter entity reference appears in a literal entity
- * value, ... a single or double quote character in the replacement
- * text is always treated as a normal data character and will not
- * terminate the literal.
- * In practice it means we stop the loop only when back at parsing
- * the initial entity and the quote is found
- */
- while ((IS_CHAR(c)) && ((c != stop) || /* checked */
- (ctxt->input != input))) {
- if (len + 5 >= size) {
- size *= 2;
- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc of %d byte failed\n", size);
- return(NULL);
- }
- }
- COPY_BUF(l,buf,len,c);
- NEXTL(l);
- /*
- * Pop-up of finished entities.
- */
- while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
- xmlPopInput(ctxt);
-
- GROW;
- c = CUR_CHAR(l);
- if (c == 0) {
- GROW;
- c = CUR_CHAR(l);
- }
- }
- buf[len] = 0;
-
- /*
- * Raise problem w.r.t. '&' and '%' being used in non-entities
- * reference constructs. Note Charref will be handled in
- * xmlStringDecodeEntities()
- */
- cur = buf;
- while (*cur != 0) { /* non input consuming */
- if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) {
- xmlChar *name;
- xmlChar tmp = *cur;
-
- cur++;
- name = xmlParseStringName(ctxt, &cur);
- if ((name == NULL) || (*cur != ';')) {
- ctxt->errNo = XML_ERR_ENTITY_CHAR_ERROR;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "EntityValue: '%c' forbidden except for entities references\n",
- tmp);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- if ((tmp == '%') && (ctxt->inSubset == 1) &&
- (ctxt->inputNr == 1)) {
- ctxt->errNo = XML_ERR_ENTITY_PE_INTERNAL;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "EntityValue: PEReferences forbidden in internal subset\n",
- tmp);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- if (name != NULL)
- xmlFree(name);
- }
- cur++;
- }
-
- /*
- * Then PEReference entities are substituted.
- */
- if (c != stop) {
- ctxt->errNo = XML_ERR_ENTITY_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "EntityValue: \" expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- xmlFree(buf);
- } else {
- NEXT;
- /*
- * NOTE: 4.4.7 Bypassed
- * When a general entity reference appears in the EntityValue in
- * an entity declaration, it is bypassed and left as is.
- * so XML_SUBSTITUTE_REF is not set here.
- */
- ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
- 0, 0, 0);
- if (orig != NULL)
- *orig = buf;
- else
- xmlFree(buf);
- }
-
- return(ret);
-}
-
-/**
- * xmlParseAttValue:
- * @ctxt: an XML parser context
- *
- * parse a value for an attribute
- * Note: the parser won't do substitution of entities here, this
- * will be handled later in xmlStringGetNodeList
- *
- * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |
- * "'" ([^<&'] | Reference)* "'"
- *
- * 3.3.3 Attribute-Value Normalization:
- * Before the value of an attribute is passed to the application or
- * checked for validity, the XML processor must normalize it as follows:
- * - a character reference is processed by appending the referenced
- * character to the attribute value
- * - an entity reference is processed by recursively processing the
- * replacement text of the entity
- * - a whitespace character (#x20, #xD, #xA, #x9) is processed by
- * appending #x20 to the normalized value, except that only a single
- * #x20 is appended for a "#xD#xA" sequence that is part of an external
- * parsed entity or the literal entity value of an internal parsed entity
- * - other characters are processed by appending them to the normalized value
- * If the declared value is not CDATA, then the XML processor must further
- * process the normalized attribute value by discarding any leading and
- * trailing space (#x20) characters, and by replacing sequences of space
- * (#x20) characters by a single space (#x20) character.
- * All attributes for which no declaration has been read should be treated
- * by a non-validating parser as if declared CDATA.
- *
- * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
- */
-
-xmlChar *
-xmlParseAttValueComplex(xmlParserCtxtPtr ctxt);
-
-xmlChar *
-xmlParseAttValue(xmlParserCtxtPtr ctxt) {
- xmlChar limit = 0;
- const xmlChar *in = NULL;
- xmlChar *ret = NULL;
- SHRINK;
- GROW;
- in = (xmlChar *) CUR_PTR;
- if (*in != '"' && *in != '\'') {
- ctxt->errNo = XML_ERR_ATTRIBUTE_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "AttValue: \" or ' expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(NULL);
- }
- ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
- limit = *in;
- ++in;
-
- while (*in != limit && *in >= 0x20 && *in <= 0x7f &&
- *in != '&' && *in != '<'
- ) {
- ++in;
- }
- if (*in != limit) {
- return xmlParseAttValueComplex(ctxt);
- }
- ++in;
- ret = xmlStrndup (CUR_PTR + 1, in - CUR_PTR - 2);
- CUR_PTR = in;
- return ret;
-}
-
-/**
- * xmlParseAttValueComplex:
- * @ctxt: an XML parser context
- *
- * parse a value for an attribute, this is the fallback function
- * of xmlParseAttValue() when the attribute parsing requires handling
- * of non-ASCII characters.
- *
- * Returns the AttValue parsed or NULL. The value has to be freed by the caller.
- */
-xmlChar *
-xmlParseAttValueComplex(xmlParserCtxtPtr ctxt) {
- xmlChar limit = 0;
- xmlChar *buf = NULL;
- int len = 0;
- int buf_size = 0;
- int c, l;
- xmlChar *current = NULL;
- xmlEntityPtr ent;
-
-
- SHRINK;
- if (NXT(0) == '"') {
- ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
- limit = '"';
- NEXT;
- } else if (NXT(0) == '\'') {
- limit = '\'';
- ctxt->instate = XML_PARSER_ATTRIBUTE_VALUE;
- NEXT;
- } else {
- ctxt->errNo = XML_ERR_ATTRIBUTE_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "AttValue: \" or ' expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(NULL);
- }
-
- /*
- * allocate a translation buffer.
- */
- buf_size = XML_PARSER_BUFFER_SIZE;
- buf = (xmlChar *) xmlMalloc(buf_size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlParseAttValue: malloc failed");
- return(NULL);
- }
-
- /*
- * OK loop until we reach one of the ending char or a size limit.
- */
- c = CUR_CHAR(l);
- while ((NXT(0) != limit) && /* checked */
- (c != '<')) {
- if (c == 0) break;
- if (c == '&') {
- if (NXT(1) == '#') {
- int val = xmlParseCharRef(ctxt);
- if (val == '&') {
- if (ctxt->replaceEntities) {
- if (len > buf_size - 10) {
- growBuffer(buf);
- }
- buf[len++] = '&';
- } else {
- /*
- * The reparsing will be done in xmlStringGetNodeList()
- * called by the attribute() function in SAX.c
- */
- static xmlChar buffer[6] = "&#38;";
-
- if (len > buf_size - 10) {
- growBuffer(buf);
- }
- current = &buffer[0];
- while (*current != 0) { /* non input consuming */
- buf[len++] = *current++;
- }
- }
- } else {
- if (len > buf_size - 10) {
- growBuffer(buf);
- }
- len += xmlCopyChar(0, &buf[len], val);
- }
- } else {
- ent = xmlParseEntityRef(ctxt);
- if ((ent != NULL) &&
- (ctxt->replaceEntities != 0)) {
- xmlChar *rep;
-
- if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
- rep = xmlStringDecodeEntities(ctxt, ent->content,
- XML_SUBSTITUTE_REF, 0, 0, 0);
- if (rep != NULL) {
- current = rep;
- while (*current != 0) { /* non input consuming */
- buf[len++] = *current++;
- if (len > buf_size - 10) {
- growBuffer(buf);
- }
- }
- xmlFree(rep);
- }
- } else {
- if (len > buf_size - 10) {
- growBuffer(buf);
- }
- if (ent->content != NULL)
- buf[len++] = ent->content[0];
- }
- } else if (ent != NULL) {
- int i = xmlStrlen(ent->name);
- const xmlChar *cur = ent->name;
-
- /*
- * This may look absurd but is needed to detect
- * entities problems
- */
- if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
- (ent->content != NULL)) {
- xmlChar *rep;
- rep = xmlStringDecodeEntities(ctxt, ent->content,
- XML_SUBSTITUTE_REF, 0, 0, 0);
- if (rep != NULL)
- xmlFree(rep);
- }
-
- /*
- * Just output the reference
- */
- buf[len++] = '&';
- if (len > buf_size - i - 10) {
- growBuffer(buf);
- }
- for (;i > 0;i--)
- buf[len++] = *cur++;
- buf[len++] = ';';
- }
- }
- } else {
- if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
- COPY_BUF(l,buf,len,0x20);
- if (len > buf_size - 10) {
- growBuffer(buf);
- }
- } else {
- COPY_BUF(l,buf,len,c);
- if (len > buf_size - 10) {
- growBuffer(buf);
- }
- }
- NEXTL(l);
- }
- GROW;
- c = CUR_CHAR(l);
- }
- buf[len++] = 0;
- if (RAW == '<') {
- ctxt->errNo = XML_ERR_LT_IN_ATTRIBUTE;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Unescaped '<' not allowed in attributes values\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else if (RAW != limit) {
- ctxt->errNo = XML_ERR_ATTRIBUTE_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "AttValue: ' expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else
- NEXT;
- return(buf);
-}
-
-/**
- * xmlParseSystemLiteral:
- * @ctxt: an XML parser context
- *
- * parse an XML Literal
- *
- * [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
- *
- * Returns the SystemLiteral parsed or NULL
- */
-
-xmlChar *
-xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
- xmlChar *buf = NULL;
- int len = 0;
- int size = XML_PARSER_BUFFER_SIZE;
- int cur, l;
- xmlChar stop;
- int state = ctxt->instate;
- int count = 0;
-
- SHRINK;
- if (RAW == '"') {
- NEXT;
- stop = '"';
- } else if (RAW == '\'') {
- NEXT;
- stop = '\'';
- } else {
- ctxt->errNo = XML_ERR_LITERAL_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "SystemLiteral \" or ' expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(NULL);
- }
-
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %d byte failed\n", size);
- return(NULL);
- }
- ctxt->instate = XML_PARSER_SYSTEM_LITERAL;
- cur = CUR_CHAR(l);
- while ((IS_CHAR(cur)) && (cur != stop)) { /* checked */
- if (len + 5 >= size) {
- size *= 2;
- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc of %d byte failed\n", size);
- ctxt->instate = (xmlParserInputState) state;
- return(NULL);
- }
- }
- count++;
- if (count > 50) {
- GROW;
- count = 0;
- }
- COPY_BUF(l,buf,len,cur);
- NEXTL(l);
- cur = CUR_CHAR(l);
- if (cur == 0) {
- GROW;
- SHRINK;
- cur = CUR_CHAR(l);
- }
- }
- buf[len] = 0;
- ctxt->instate = (xmlParserInputState) state;
- if (!IS_CHAR(cur)) {
- ctxt->errNo = XML_ERR_LITERAL_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Unfinished SystemLiteral\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- NEXT;
- }
- return(buf);
-}
-
-/**
- * xmlParsePubidLiteral:
- * @ctxt: an XML parser context
- *
- * parse an XML public literal
- *
- * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
- *
- * Returns the PubidLiteral parsed or NULL.
- */
-
-xmlChar *
-xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
- xmlChar *buf = NULL;
- int len = 0;
- int size = XML_PARSER_BUFFER_SIZE;
- xmlChar cur;
- xmlChar stop;
- int count = 0;
- xmlParserInputState oldstate = ctxt->instate;
-
- SHRINK;
- if (RAW == '"') {
- NEXT;
- stop = '"';
- } else if (RAW == '\'') {
- NEXT;
- stop = '\'';
- } else {
- ctxt->errNo = XML_ERR_LITERAL_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "SystemLiteral \" or ' expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(NULL);
- }
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %d byte failed\n", size);
- return(NULL);
- }
- ctxt->instate = XML_PARSER_PUBLIC_LITERAL;
- cur = CUR;
- while ((IS_PUBIDCHAR(cur)) && (cur != stop)) { /* checked */
- if (len + 1 >= size) {
- size *= 2;
- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc of %d byte failed\n", size);
- return(NULL);
- }
- }
- buf[len++] = cur;
- count++;
- if (count > 50) {
- GROW;
- count = 0;
- }
- NEXT;
- cur = CUR;
- if (cur == 0) {
- GROW;
- SHRINK;
- cur = CUR;
- }
- }
- buf[len] = 0;
- if (cur != stop) {
- ctxt->errNo = XML_ERR_LITERAL_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Unfinished PubidLiteral\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- NEXT;
- }
- ctxt->instate = oldstate;
- return(buf);
-}
-
-void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
-/**
- * xmlParseCharData:
- * @ctxt: an XML parser context
- * @cdata: int indicating whether we are within a CDATA section
- *
- * parse a CharData section.
- * if we are within a CDATA section ']]>' marks an end of section.
- *
- * The right angle bracket (>) may be represented using the string "&gt;",
- * and must, for compatibility, be escaped using "&gt;" or a character
- * reference when it appears in the string "]]>" in content, when that
- * string is not marking the end of a CDATA section.
- *
- * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
- */
-
-void
-xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) {
- const xmlChar *in;
- int nbchar = 0;
- int line = ctxt->input->line;
- int col = ctxt->input->col;
-
- SHRINK;
- GROW;
- /*
- * Accelerated common case where input don't need to be
- * modified before passing it to the handler.
- */
- if (!cdata) {
- in = ctxt->input->cur;
- do {
-get_more:
- while (((*in >= 0x20) && (*in != '<') && (*in != ']') &&
- (*in != '&') && (*in <= 0x7F)) || (*in == 0x09))
- in++;
- if (*in == 0xA) {
- ctxt->input->line++;
- in++;
- while (*in == 0xA) {
- ctxt->input->line++;
- in++;
- }
- goto get_more;
- }
- if (*in == ']') {
- if ((in[1] == ']') && (in[2] == '>')) {
- ctxt->errNo = XML_ERR_MISPLACED_CDATA_END;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Sequence ']]>' not allowed in content\n");
- ctxt->input->cur = in;
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return;
- }
- in++;
- goto get_more;
- }
- nbchar = in - ctxt->input->cur;
- if (nbchar > 0) {
- if (IS_BLANK(*ctxt->input->cur)) {
- const xmlChar *tmp = ctxt->input->cur;
- ctxt->input->cur = in;
- if (areBlanks(ctxt, tmp, nbchar)) {
- if (ctxt->sax->ignorableWhitespace != NULL)
- ctxt->sax->ignorableWhitespace(ctxt->userData,
- tmp, nbchar);
- } else {
- if (ctxt->sax->characters != NULL)
- ctxt->sax->characters(ctxt->userData,
- tmp, nbchar);
- }
- line = ctxt->input->line;
- col = ctxt->input->col;
- } else {
- if (ctxt->sax->characters != NULL)
- ctxt->sax->characters(ctxt->userData,
- ctxt->input->cur, nbchar);
- line = ctxt->input->line;
- col = ctxt->input->col;
- }
- }
- ctxt->input->cur = in;
- if (*in == 0xD) {
- in++;
- if (*in == 0xA) {
- ctxt->input->cur = in;
- in++;
- ctxt->input->line++;
- continue; /* while */
- }
- in--;
- }
- if (*in == '<') {
- return;
- }
- if (*in == '&') {
- return;
- }
- SHRINK;
- GROW;
- in = ctxt->input->cur;
- } while ((*in >= 0x20) && (*in <= 0x7F));
- nbchar = 0;
- }
- ctxt->input->line = line;
- ctxt->input->col = col;
- xmlParseCharDataComplex(ctxt, cdata);
-}
-
-/**
- * xmlParseCharDataComplex:
- * @ctxt: an XML parser context
- * @cdata: int indicating whether we are within a CDATA section
- *
- * parse a CharData section.this is the fallback function
- * of xmlParseCharData() when the parsing requires handling
- * of non-ASCII characters.
- */
-void
-xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
- xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
- int nbchar = 0;
- int cur, l;
- int count = 0;
-
- SHRINK;
- GROW;
- cur = CUR_CHAR(l);
- while ((cur != '<') && /* checked */
- (cur != '&') &&
- (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
- if ((cur == ']') && (NXT(1) == ']') &&
- (NXT(2) == '>')) {
- if (cdata) break;
- else {
- ctxt->errNo = XML_ERR_MISPLACED_CDATA_END;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Sequence ']]>' not allowed in content\n");
- /* Should this be relaxed ??? I see a "must here */
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- }
- COPY_BUF(l,buf,nbchar,cur);
- if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
- /*
- * OK the segment is to be consumed as chars.
- */
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
- if (areBlanks(ctxt, buf, nbchar)) {
- if (ctxt->sax->ignorableWhitespace != NULL)
- ctxt->sax->ignorableWhitespace(ctxt->userData,
- buf, nbchar);
- } else {
- if (ctxt->sax->characters != NULL)
- ctxt->sax->characters(ctxt->userData, buf, nbchar);
- }
- }
- nbchar = 0;
- }
- count++;
- if (count > 50) {
- GROW;
- count = 0;
- }
- NEXTL(l);
- cur = CUR_CHAR(l);
- }
- if (nbchar != 0) {
- /*
- * OK the segment is to be consumed as chars.
- */
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
- if (areBlanks(ctxt, buf, nbchar)) {
- if (ctxt->sax->ignorableWhitespace != NULL)
- ctxt->sax->ignorableWhitespace(ctxt->userData, buf, nbchar);
- } else {
- if (ctxt->sax->characters != NULL)
- ctxt->sax->characters(ctxt->userData, buf, nbchar);
- }
- }
- }
-}
-
-/**
- * xmlParseExternalID:
- * @ctxt: an XML parser context
- * @publicID: a xmlChar** receiving PubidLiteral
- * @strict: indicate whether we should restrict parsing to only
- * production [75], see NOTE below
- *
- * Parse an External ID or a Public ID
- *
- * NOTE: Productions [75] and [83] interact badly since [75] can generate
- * 'PUBLIC' S PubidLiteral S SystemLiteral
- *
- * [75] ExternalID ::= 'SYSTEM' S SystemLiteral
- * | 'PUBLIC' S PubidLiteral S SystemLiteral
- *
- * [83] PublicID ::= 'PUBLIC' S PubidLiteral
- *
- * Returns the function returns SystemLiteral and in the second
- * case publicID receives PubidLiteral, is strict is off
- * it is possible to return NULL and have publicID set.
- */
-
-xmlChar *
-xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
- xmlChar *URI = NULL;
-
- SHRINK;
-
- *publicID = NULL;
- if ((RAW == 'S') && (NXT(1) == 'Y') &&
- (NXT(2) == 'S') && (NXT(3) == 'T') &&
- (NXT(4) == 'E') && (NXT(5) == 'M')) {
- SKIP(6);
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after 'SYSTEM'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- URI = xmlParseSystemLiteral(ctxt);
- if (URI == NULL) {
- ctxt->errNo = XML_ERR_URI_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseExternalID: SYSTEM, no URI\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- } else if ((RAW == 'P') && (NXT(1) == 'U') &&
- (NXT(2) == 'B') && (NXT(3) == 'L') &&
- (NXT(4) == 'I') && (NXT(5) == 'C')) {
- SKIP(6);
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after 'PUBLIC'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- *publicID = xmlParsePubidLiteral(ctxt);
- if (*publicID == NULL) {
- ctxt->errNo = XML_ERR_PUBID_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseExternalID: PUBLIC, no Public Identifier\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- if (strict) {
- /*
- * We don't handle [83] so "S SystemLiteral" is required.
- */
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after the Public Identifier\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- } else {
- /*
- * We handle [83] so we return immediately, if
- * "S SystemLiteral" is not detected. From a purely parsing
- * point of view that's a nice mess.
- */
- const xmlChar *ptr;
- GROW;
-
- ptr = CUR_PTR;
- if (!IS_BLANK(*ptr)) return(NULL);
-
- while (IS_BLANK(*ptr)) ptr++; /* TODO: dangerous, fix ! */
- if ((*ptr != '\'') && (*ptr != '"')) return(NULL);
- }
- SKIP_BLANKS;
- URI = xmlParseSystemLiteral(ctxt);
- if (URI == NULL) {
- ctxt->errNo = XML_ERR_URI_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseExternalID: PUBLIC, no URI\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- }
- return(URI);
-}
-
-/**
- * xmlParseComment:
- * @ctxt: an XML parser context
- *
- * Skip an XML (SGML) comment <!-- .... -->
- * The spec says that "For compatibility, the string "--" (double-hyphen)
- * must not occur within comments. "
- *
- * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
- */
-void
-xmlParseComment(xmlParserCtxtPtr ctxt) {
- xmlChar *buf = NULL;
- int len;
- int size = XML_PARSER_BUFFER_SIZE;
- int q, ql;
- int r, rl;
- int cur, l;
- xmlParserInputState state;
- xmlParserInputPtr input = ctxt->input;
- int count = 0;
-
- /*
- * Check that there is a comment right here.
- */
- if ((RAW != '<') || (NXT(1) != '!') ||
- (NXT(2) != '-') || (NXT(3) != '-')) return;
-
- state = ctxt->instate;
- ctxt->instate = XML_PARSER_COMMENT;
- SHRINK;
- SKIP(4);
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %d byte failed\n", size);
- ctxt->instate = state;
- return;
- }
- q = CUR_CHAR(ql);
- NEXTL(ql);
- r = CUR_CHAR(rl);
- NEXTL(rl);
- cur = CUR_CHAR(l);
- len = 0;
- while (IS_CHAR(cur) && /* checked */
- ((cur != '>') ||
- (r != '-') || (q != '-'))) {
- if ((r == '-') && (q == '-')) {
- ctxt->errNo = XML_ERR_HYPHEN_IN_COMMENT;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Comment must not contain '--' (double-hyphen)`\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- if (len + 5 >= size) {
- size *= 2;
- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc of %d byte failed\n", size);
- ctxt->instate = state;
- return;
- }
- }
- COPY_BUF(ql,buf,len,q);
- q = r;
- ql = rl;
- r = cur;
- rl = l;
-
- count++;
- if (count > 50) {
- GROW;
- count = 0;
- }
- NEXTL(l);
- cur = CUR_CHAR(l);
- if (cur == 0) {
- SHRINK;
- GROW;
- cur = CUR_CHAR(l);
- }
- }
- buf[len] = 0;
- if (!IS_CHAR(cur)) {
- ctxt->errNo = XML_ERR_COMMENT_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Comment not terminated \n<!--%.50s\n", buf);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- xmlFree(buf);
- } else {
- if (input != ctxt->input) {
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
-"Comment doesn't start and stop in the same entity\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- NEXT;
- if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->comment(ctxt->userData, buf);
- xmlFree(buf);
- }
- ctxt->instate = state;
-}
-
-/**
- * xmlParsePITarget:
- * @ctxt: an XML parser context
- *
- * parse the name of a PI
- *
- * [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
- *
- * Returns the PITarget name or NULL
- */
-
-xmlChar *
-xmlParsePITarget(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
-
- name = xmlParseName(ctxt);
- if ((name != NULL) &&
- ((name[0] == 'x') || (name[0] == 'X')) &&
- ((name[1] == 'm') || (name[1] == 'M')) &&
- ((name[2] == 'l') || (name[2] == 'L'))) {
- int i;
- if ((name[0] == 'x') && (name[1] == 'm') &&
- (name[2] == 'l') && (name[3] == 0)) {
- ctxt->errNo = XML_ERR_RESERVED_XML_NAME;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "XML declaration allowed only at the start of the document\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(name);
- } else if (name[3] == 0) {
- ctxt->errNo = XML_ERR_RESERVED_XML_NAME;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Invalid PI name\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(name);
- }
- for (i = 0;;i++) {
- if (xmlW3CPIs[i] == NULL) break;
- if (xmlStrEqual(name, (const xmlChar *)xmlW3CPIs[i]))
- return(name);
- }
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL)) {
- ctxt->errNo = XML_ERR_RESERVED_XML_NAME;
- ctxt->sax->warning(ctxt->userData,
- "xmlParsePITarget: invalid name prefix 'xml'\n");
- }
- }
- return(name);
-}
-
-#ifdef LIBXML_CATALOG_ENABLED
-/**
- * xmlParseCatalogPI:
- * @ctxt: an XML parser context
- * @catalog: the PI value string
- *
- * parse an XML Catalog Processing Instruction.
- *
- * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
- *
- * Occurs only if allowed by the user and if happening in the Misc
- * part of the document before any doctype informations
- * This will add the given catalog to the parsing context in order
- * to be used if there is a resolution need further down in the document
- */
-
-static void
-xmlParseCatalogPI(xmlParserCtxtPtr ctxt, const xmlChar *catalog) {
- xmlChar *URL = NULL;
- const xmlChar *tmp, *base;
- xmlChar marker;
-
- tmp = catalog;
- while (IS_BLANK(*tmp)) tmp++;
- if (xmlStrncmp(tmp, BAD_CAST"catalog", 7))
- goto error;
- tmp += 7;
- while (IS_BLANK(*tmp)) tmp++;
- if (*tmp != '=') {
- return;
- }
- tmp++;
- while (IS_BLANK(*tmp)) tmp++;
- marker = *tmp;
- if ((marker != '\'') && (marker != '"'))
- goto error;
- tmp++;
- base = tmp;
- while ((*tmp != 0) && (*tmp != marker)) tmp++;
- if (*tmp == 0)
- goto error;
- URL = xmlStrndup(base, tmp - base);
- tmp++;
- while (IS_BLANK(*tmp)) tmp++;
- if (*tmp != 0)
- goto error;
-
- if (URL != NULL) {
- ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
- xmlFree(URL);
- }
- return;
-
-error:
- ctxt->errNo = XML_WAR_CATALOG_PI;
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "Catalog PI syntax error: %s\n", catalog);
- if (URL != NULL)
- xmlFree(URL);
-}
-#endif
-
-/**
- * xmlParsePI:
- * @ctxt: an XML parser context
- *
- * parse an XML Processing Instruction.
- *
- * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
- *
- * The processing is transfered to SAX once parsed.
- */
-
-void
-xmlParsePI(xmlParserCtxtPtr ctxt) {
- xmlChar *buf = NULL;
- int len = 0;
- int size = XML_PARSER_BUFFER_SIZE;
- int cur, l;
- xmlChar *target;
- xmlParserInputState state;
- int count = 0;
-
- if ((RAW == '<') && (NXT(1) == '?')) {
- xmlParserInputPtr input = ctxt->input;
- state = ctxt->instate;
- ctxt->instate = XML_PARSER_PI;
- /*
- * this is a Processing Instruction.
- */
- SKIP(2);
- SHRINK;
-
- /*
- * Parse the target name and check for special support like
- * namespace.
- */
- target = xmlParsePITarget(ctxt);
- if (target != NULL) {
- if ((RAW == '?') && (NXT(1) == '>')) {
- if (input != ctxt->input) {
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "PI declaration doesn't start and stop in the same entity\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP(2);
-
- /*
- * SAX: PI detected.
- */
- if ((ctxt->sax) && (!ctxt->disableSAX) &&
- (ctxt->sax->processingInstruction != NULL))
- ctxt->sax->processingInstruction(ctxt->userData,
- target, NULL);
- ctxt->instate = state;
- xmlFree(target);
- return;
- }
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %d byte failed\n", size);
- ctxt->instate = state;
- return;
- }
- cur = CUR;
- if (!IS_BLANK(cur)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParsePI: PI %s space expected\n", target);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- cur = CUR_CHAR(l);
- while (IS_CHAR(cur) && /* checked */
- ((cur != '?') || (NXT(1) != '>'))) {
- if (len + 5 >= size) {
- size *= 2;
- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc of %d byte failed\n", size);
- ctxt->instate = state;
- return;
- }
- }
- count++;
- if (count > 50) {
- GROW;
- count = 0;
- }
- COPY_BUF(l,buf,len,cur);
- NEXTL(l);
- cur = CUR_CHAR(l);
- if (cur == 0) {
- SHRINK;
- GROW;
- cur = CUR_CHAR(l);
- }
- }
- buf[len] = 0;
- if (cur != '?') {
- ctxt->errNo = XML_ERR_PI_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParsePI: PI %s never end ...\n", target);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- if (input != ctxt->input) {
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "PI declaration doesn't start and stop in the same entity\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP(2);
-
-#ifdef LIBXML_CATALOG_ENABLED
- if (((state == XML_PARSER_MISC) ||
- (state == XML_PARSER_START)) &&
- (xmlStrEqual(target, XML_CATALOG_PI))) {
- xmlCatalogAllow allow = xmlCatalogGetDefaults();
- if ((allow == XML_CATA_ALLOW_DOCUMENT) ||
- (allow == XML_CATA_ALLOW_ALL))
- xmlParseCatalogPI(ctxt, buf);
- }
-#endif
-
-
- /*
- * SAX: PI detected.
- */
- if ((ctxt->sax) && (!ctxt->disableSAX) &&
- (ctxt->sax->processingInstruction != NULL))
- ctxt->sax->processingInstruction(ctxt->userData,
- target, buf);
- }
- xmlFree(buf);
- xmlFree(target);
- } else {
- ctxt->errNo = XML_ERR_PI_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParsePI : no target name\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- ctxt->instate = state;
- }
-}
-
-/**
- * xmlParseNotationDecl:
- * @ctxt: an XML parser context
- *
- * parse a notation declaration
- *
- * [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID | PublicID) S? '>'
- *
- * Hence there is actually 3 choices:
- * 'PUBLIC' S PubidLiteral
- * 'PUBLIC' S PubidLiteral S SystemLiteral
- * and 'SYSTEM' S SystemLiteral
- *
- * See the NOTE on xmlParseExternalID().
- */
-
-void
-xmlParseNotationDecl(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlChar *Pubid;
- xmlChar *Systemid;
-
- if ((RAW == '<') && (NXT(1) == '!') &&
- (NXT(2) == 'N') && (NXT(3) == 'O') &&
- (NXT(4) == 'T') && (NXT(5) == 'A') &&
- (NXT(6) == 'T') && (NXT(7) == 'I') &&
- (NXT(8) == 'O') && (NXT(9) == 'N')) {
- xmlParserInputPtr input = ctxt->input;
- SHRINK;
- SKIP(10);
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after '<!NOTATION'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return;
- }
- SKIP_BLANKS;
-
- name = xmlParseName(ctxt);
- if (name == NULL) {
- ctxt->errNo = XML_ERR_NOTATION_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "NOTATION: Name expected here\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return;
- }
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after the NOTATION name'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return;
- }
- SKIP_BLANKS;
-
- /*
- * Parse the IDs.
- */
- Systemid = xmlParseExternalID(ctxt, &Pubid, 0);
- SKIP_BLANKS;
-
- if (RAW == '>') {
- if (input != ctxt->input) {
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
-"Notation declaration doesn't start and stop in the same entity\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- NEXT;
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
- (ctxt->sax->notationDecl != NULL))
- ctxt->sax->notationDecl(ctxt->userData, name, Pubid, Systemid);
- } else {
- ctxt->errNo = XML_ERR_NOTATION_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "'>' required to close NOTATION declaration\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- xmlFree(name);
- if (Systemid != NULL) xmlFree(Systemid);
- if (Pubid != NULL) xmlFree(Pubid);
- }
-}
-
-/**
- * xmlParseEntityDecl:
- * @ctxt: an XML parser context
- *
- * parse <!ENTITY declarations
- *
- * [70] EntityDecl ::= GEDecl | PEDecl
- *
- * [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
- *
- * [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
- *
- * [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
- *
- * [74] PEDef ::= EntityValue | ExternalID
- *
- * [76] NDataDecl ::= S 'NDATA' S Name
- *
- * [ VC: Notation Declared ]
- * The Name must match the declared name of a notation.
- */
-
-void
-xmlParseEntityDecl(xmlParserCtxtPtr ctxt) {
- xmlChar *name = NULL;
- xmlChar *value = NULL;
- xmlChar *URI = NULL, *literal = NULL;
- xmlChar *ndata = NULL;
- int isParameter = 0;
- xmlChar *orig = NULL;
- int skipped;
-
- GROW;
- if ((RAW == '<') && (NXT(1) == '!') &&
- (NXT(2) == 'E') && (NXT(3) == 'N') &&
- (NXT(4) == 'T') && (NXT(5) == 'I') &&
- (NXT(6) == 'T') && (NXT(7) == 'Y')) {
- xmlParserInputPtr input = ctxt->input;
- SHRINK;
- SKIP(8);
- skipped = SKIP_BLANKS;
- if (skipped == 0) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after '<!ENTITY'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
- if (RAW == '%') {
- NEXT;
- skipped = SKIP_BLANKS;
- if (skipped == 0) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after '%'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- isParameter = 1;
- }
-
- name = xmlParseName(ctxt);
- if (name == NULL) {
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "xmlParseEntityDecl: no name\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return;
- }
- skipped = SKIP_BLANKS;
- if (skipped == 0) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after the entity name\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
- ctxt->instate = XML_PARSER_ENTITY_DECL;
- /*
- * handle the various case of definitions...
- */
- if (isParameter) {
- if ((RAW == '"') || (RAW == '\'')) {
- value = xmlParseEntityValue(ctxt, &orig);
- if (value) {
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
- ctxt->sax->entityDecl(ctxt->userData, name,
- XML_INTERNAL_PARAMETER_ENTITY,
- NULL, NULL, value);
- }
- } else {
- URI = xmlParseExternalID(ctxt, &literal, 1);
- if ((URI == NULL) && (literal == NULL)) {
- ctxt->errNo = XML_ERR_VALUE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity value required\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- if (URI) {
- xmlURIPtr uri;
-
- uri = xmlParseURI((const char *) URI);
- if (uri == NULL) {
- ctxt->errNo = XML_ERR_INVALID_URI;
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) &&
- (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Invalid URI: %s\n", URI);
- /*
- * This really ought to be a well formedness error
- * but the XML Core WG decided otherwise c.f. issue
- * E26 of the XML erratas.
- */
- } else {
- if (uri->fragment != NULL) {
- ctxt->errNo = XML_ERR_URI_FRAGMENT;
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) &&
- (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Fragment not allowed: %s\n", URI);
- /*
- * Okay this is foolish to block those but not
- * invalid URIs.
- */
- ctxt->wellFormed = 0;
- } else {
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) &&
- (ctxt->sax->entityDecl != NULL))
- ctxt->sax->entityDecl(ctxt->userData, name,
- XML_EXTERNAL_PARAMETER_ENTITY,
- literal, URI, NULL);
- }
- xmlFreeURI(uri);
- }
- }
- }
- } else {
- if ((RAW == '"') || (RAW == '\'')) {
- value = xmlParseEntityValue(ctxt, &orig);
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
- ctxt->sax->entityDecl(ctxt->userData, name,
- XML_INTERNAL_GENERAL_ENTITY,
- NULL, NULL, value);
- /*
- * For expat compatibility in SAX mode.
- */
- if ((ctxt->myDoc == NULL) ||
- (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
- if (ctxt->myDoc == NULL) {
- ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
- }
- if (ctxt->myDoc->intSubset == NULL)
- ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
- BAD_CAST "fake", NULL, NULL);
-
- entityDecl(ctxt, name, XML_INTERNAL_GENERAL_ENTITY,
- NULL, NULL, value);
- }
- } else {
- URI = xmlParseExternalID(ctxt, &literal, 1);
- if ((URI == NULL) && (literal == NULL)) {
- ctxt->errNo = XML_ERR_VALUE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity value required\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- if (URI) {
- xmlURIPtr uri;
-
- uri = xmlParseURI((const char *)URI);
- if (uri == NULL) {
- ctxt->errNo = XML_ERR_INVALID_URI;
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) &&
- (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Invalid URI: %s\n", URI);
- /*
- * This really ought to be a well formedness error
- * but the XML Core WG decided otherwise c.f. issue
- * E26 of the XML erratas.
- */
- } else {
- if (uri->fragment != NULL) {
- ctxt->errNo = XML_ERR_URI_FRAGMENT;
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) &&
- (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Fragment not allowed: %s\n", URI);
- /*
- * Okay this is foolish to block those but not
- * invalid URIs.
- */
- ctxt->wellFormed = 0;
- }
- xmlFreeURI(uri);
- }
- }
- if ((RAW != '>') && (!IS_BLANK(CUR))) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required before 'NDATA'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- if ((RAW == 'N') && (NXT(1) == 'D') &&
- (NXT(2) == 'A') && (NXT(3) == 'T') &&
- (NXT(4) == 'A')) {
- SKIP(5);
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after 'NDATA'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- ndata = xmlParseName(ctxt);
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
- (ctxt->sax->unparsedEntityDecl != NULL))
- ctxt->sax->unparsedEntityDecl(ctxt->userData, name,
- literal, URI, ndata);
- } else {
- if ((ctxt->sax != NULL) &&
- (!ctxt->disableSAX) && (ctxt->sax->entityDecl != NULL))
- ctxt->sax->entityDecl(ctxt->userData, name,
- XML_EXTERNAL_GENERAL_PARSED_ENTITY,
- literal, URI, NULL);
- /*
- * For expat compatibility in SAX mode.
- * assuming the entity repalcement was asked for
- */
- if ((ctxt->replaceEntities != 0) &&
- ((ctxt->myDoc == NULL) ||
- (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE)))) {
- if (ctxt->myDoc == NULL) {
- ctxt->myDoc = xmlNewDoc(SAX_COMPAT_MODE);
- }
-
- if (ctxt->myDoc->intSubset == NULL)
- ctxt->myDoc->intSubset = xmlNewDtd(ctxt->myDoc,
- BAD_CAST "fake", NULL, NULL);
- entityDecl(ctxt, name,
- XML_EXTERNAL_GENERAL_PARSED_ENTITY,
- literal, URI, NULL);
- }
- }
- }
- }
- SKIP_BLANKS;
- if (RAW != '>') {
- ctxt->errNo = XML_ERR_ENTITY_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseEntityDecl: entity %s not terminated\n", name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- if (input != ctxt->input) {
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
-"Entity declaration doesn't start and stop in the same entity\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- NEXT;
- }
- if (orig != NULL) {
- /*
- * Ugly mechanism to save the raw entity value.
- */
- xmlEntityPtr cur = NULL;
-
- if (isParameter) {
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->getParameterEntity != NULL))
- cur = ctxt->sax->getParameterEntity(ctxt->userData, name);
- } else {
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->getEntity != NULL))
- cur = ctxt->sax->getEntity(ctxt->userData, name);
- if ((cur == NULL) && (ctxt->userData==ctxt)) {
- cur = getEntity(ctxt, name);
- }
- }
- if (cur != NULL) {
- if (cur->orig != NULL)
- xmlFree(orig);
- else
- cur->orig = orig;
- } else
- xmlFree(orig);
- }
- if (name != NULL) xmlFree(name);
- if (value != NULL) xmlFree(value);
- if (URI != NULL) xmlFree(URI);
- if (literal != NULL) xmlFree(literal);
- if (ndata != NULL) xmlFree(ndata);
- }
-}
-
-/**
- * xmlParseDefaultDecl:
- * @ctxt: an XML parser context
- * @value: Receive a possible fixed default value for the attribute
- *
- * Parse an attribute default declaration
- *
- * [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
- *
- * [ VC: Required Attribute ]
- * if the default declaration is the keyword #REQUIRED, then the
- * attribute must be specified for all elements of the type in the
- * attribute-list declaration.
- *
- * [ VC: Attribute Default Legal ]
- * The declared default value must meet the lexical constraints of
- * the declared attribute type c.f. xmlValidateAttributeDecl()
- *
- * [ VC: Fixed Attribute Default ]
- * if an attribute has a default value declared with the #FIXED
- * keyword, instances of that attribute must match the default value.
- *
- * [ WFC: No < in Attribute Values ]
- * handled in xmlParseAttValue()
- *
- * returns: XML_ATTRIBUTE_NONE, XML_ATTRIBUTE_REQUIRED, XML_ATTRIBUTE_IMPLIED
- * or XML_ATTRIBUTE_FIXED.
- */
-
-int
-xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) {
- int val;
- xmlChar *ret;
-
- *value = NULL;
- if ((RAW == '#') && (NXT(1) == 'R') &&
- (NXT(2) == 'E') && (NXT(3) == 'Q') &&
- (NXT(4) == 'U') && (NXT(5) == 'I') &&
- (NXT(6) == 'R') && (NXT(7) == 'E') &&
- (NXT(8) == 'D')) {
- SKIP(9);
- return(XML_ATTRIBUTE_REQUIRED);
- }
- if ((RAW == '#') && (NXT(1) == 'I') &&
- (NXT(2) == 'M') && (NXT(3) == 'P') &&
- (NXT(4) == 'L') && (NXT(5) == 'I') &&
- (NXT(6) == 'E') && (NXT(7) == 'D')) {
- SKIP(8);
- return(XML_ATTRIBUTE_IMPLIED);
- }
- val = XML_ATTRIBUTE_NONE;
- if ((RAW == '#') && (NXT(1) == 'F') &&
- (NXT(2) == 'I') && (NXT(3) == 'X') &&
- (NXT(4) == 'E') && (NXT(5) == 'D')) {
- SKIP(6);
- val = XML_ATTRIBUTE_FIXED;
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after '#FIXED'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- }
- ret = xmlParseAttValue(ctxt);
- ctxt->instate = XML_PARSER_DTD;
- if (ret == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Attribute default value declaration error\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else
- *value = ret;
- return(val);
-}
-
-/**
- * xmlParseNotationType:
- * @ctxt: an XML parser context
- *
- * parse an Notation attribute type.
- *
- * Note: the leading 'NOTATION' S part has already being parsed...
- *
- * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
- *
- * [ VC: Notation Attributes ]
- * Values of this type must match one of the notation names included
- * in the declaration; all notation names in the declaration must be declared.
- *
- * Returns: the notation attribute tree built while parsing
- */
-
-xmlEnumerationPtr
-xmlParseNotationType(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlEnumerationPtr ret = NULL, last = NULL, cur;
-
- if (RAW != '(') {
- ctxt->errNo = XML_ERR_NOTATION_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "'(' required to start 'NOTATION'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(NULL);
- }
- SHRINK;
- do {
- NEXT;
- SKIP_BLANKS;
- name = xmlParseName(ctxt);
- if (name == NULL) {
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Name expected in NOTATION declaration\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(ret);
- }
- cur = xmlCreateEnumeration(name);
- xmlFree(name);
- if (cur == NULL) return(ret);
- if (last == NULL) ret = last = cur;
- else {
- last->next = cur;
- last = cur;
- }
- SKIP_BLANKS;
- } while (RAW == '|');
- if (RAW != ')') {
- ctxt->errNo = XML_ERR_NOTATION_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "')' required to finish NOTATION declaration\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- if ((last != NULL) && (last != ret))
- xmlFreeEnumeration(last);
- return(ret);
- }
- NEXT;
- return(ret);
-}
-
-/**
- * xmlParseEnumerationType:
- * @ctxt: an XML parser context
- *
- * parse an Enumeration attribute type.
- *
- * [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
- *
- * [ VC: Enumeration ]
- * Values of this type must match one of the Nmtoken tokens in
- * the declaration
- *
- * Returns: the enumeration attribute tree built while parsing
- */
-
-xmlEnumerationPtr
-xmlParseEnumerationType(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlEnumerationPtr ret = NULL, last = NULL, cur;
-
- if (RAW != '(') {
- ctxt->errNo = XML_ERR_ATTLIST_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "'(' required to start ATTLIST enumeration\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(NULL);
- }
- SHRINK;
- do {
- NEXT;
- SKIP_BLANKS;
- name = xmlParseNmtoken(ctxt);
- if (name == NULL) {
- ctxt->errNo = XML_ERR_NMTOKEN_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "NmToken expected in ATTLIST enumeration\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(ret);
- }
- cur = xmlCreateEnumeration(name);
- xmlFree(name);
- if (cur == NULL) return(ret);
- if (last == NULL) ret = last = cur;
- else {
- last->next = cur;
- last = cur;
- }
- SKIP_BLANKS;
- } while (RAW == '|');
- if (RAW != ')') {
- ctxt->errNo = XML_ERR_ATTLIST_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "')' required to finish ATTLIST enumeration\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(ret);
- }
- NEXT;
- return(ret);
-}
-
-/**
- * xmlParseEnumeratedType:
- * @ctxt: an XML parser context
- * @tree: the enumeration tree built while parsing
- *
- * parse an Enumerated attribute type.
- *
- * [57] EnumeratedType ::= NotationType | Enumeration
- *
- * [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
- *
- *
- * Returns: XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
- */
-
-int
-xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
- if ((RAW == 'N') && (NXT(1) == 'O') &&
- (NXT(2) == 'T') && (NXT(3) == 'A') &&
- (NXT(4) == 'T') && (NXT(5) == 'I') &&
- (NXT(6) == 'O') && (NXT(7) == 'N')) {
- SKIP(8);
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after 'NOTATION'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(0);
- }
- SKIP_BLANKS;
- *tree = xmlParseNotationType(ctxt);
- if (*tree == NULL) return(0);
- return(XML_ATTRIBUTE_NOTATION);
- }
- *tree = xmlParseEnumerationType(ctxt);
- if (*tree == NULL) return(0);
- return(XML_ATTRIBUTE_ENUMERATION);
-}
-
-/**
- * xmlParseAttributeType:
- * @ctxt: an XML parser context
- * @tree: the enumeration tree built while parsing
- *
- * parse the Attribute list def for an element
- *
- * [54] AttType ::= StringType | TokenizedType | EnumeratedType
- *
- * [55] StringType ::= 'CDATA'
- *
- * [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' |
- * 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS'
- *
- * Validity constraints for attribute values syntax are checked in
- * xmlValidateAttributeValue()
- *
- * [ VC: ID ]
- * Values of type ID must match the Name production. A name must not
- * appear more than once in an XML document as a value of this type;
- * i.e., ID values must uniquely identify the elements which bear them.
- *
- * [ VC: One ID per Element Type ]
- * No element type may have more than one ID attribute specified.
- *
- * [ VC: ID Attribute Default ]
- * An ID attribute must have a declared default of #IMPLIED or #REQUIRED.
- *
- * [ VC: IDREF ]
- * Values of type IDREF must match the Name production, and values
- * of type IDREFS must match Names; each IDREF Name must match the value
- * of an ID attribute on some element in the XML document; i.e. IDREF
- * values must match the value of some ID attribute.
- *
- * [ VC: Entity Name ]
- * Values of type ENTITY must match the Name production, values
- * of type ENTITIES must match Names; each Entity Name must match the
- * name of an unparsed entity declared in the DTD.
- *
- * [ VC: Name Token ]
- * Values of type NMTOKEN must match the Nmtoken production; values
- * of type NMTOKENS must match Nmtokens.
- *
- * Returns the attribute type
- */
-int
-xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) {
- SHRINK;
- if ((RAW == 'C') && (NXT(1) == 'D') &&
- (NXT(2) == 'A') && (NXT(3) == 'T') &&
- (NXT(4) == 'A')) {
- SKIP(5);
- return(XML_ATTRIBUTE_CDATA);
- } else if ((RAW == 'I') && (NXT(1) == 'D') &&
- (NXT(2) == 'R') && (NXT(3) == 'E') &&
- (NXT(4) == 'F') && (NXT(5) == 'S')) {
- SKIP(6);
- return(XML_ATTRIBUTE_IDREFS);
- } else if ((RAW == 'I') && (NXT(1) == 'D') &&
- (NXT(2) == 'R') && (NXT(3) == 'E') &&
- (NXT(4) == 'F')) {
- SKIP(5);
- return(XML_ATTRIBUTE_IDREF);
- } else if ((RAW == 'I') && (NXT(1) == 'D')) {
- SKIP(2);
- return(XML_ATTRIBUTE_ID);
- } else if ((RAW == 'E') && (NXT(1) == 'N') &&
- (NXT(2) == 'T') && (NXT(3) == 'I') &&
- (NXT(4) == 'T') && (NXT(5) == 'Y')) {
- SKIP(6);
- return(XML_ATTRIBUTE_ENTITY);
- } else if ((RAW == 'E') && (NXT(1) == 'N') &&
- (NXT(2) == 'T') && (NXT(3) == 'I') &&
- (NXT(4) == 'T') && (NXT(5) == 'I') &&
- (NXT(6) == 'E') && (NXT(7) == 'S')) {
- SKIP(8);
- return(XML_ATTRIBUTE_ENTITIES);
- } else if ((RAW == 'N') && (NXT(1) == 'M') &&
- (NXT(2) == 'T') && (NXT(3) == 'O') &&
- (NXT(4) == 'K') && (NXT(5) == 'E') &&
- (NXT(6) == 'N') && (NXT(7) == 'S')) {
- SKIP(8);
- return(XML_ATTRIBUTE_NMTOKENS);
- } else if ((RAW == 'N') && (NXT(1) == 'M') &&
- (NXT(2) == 'T') && (NXT(3) == 'O') &&
- (NXT(4) == 'K') && (NXT(5) == 'E') &&
- (NXT(6) == 'N')) {
- SKIP(7);
- return(XML_ATTRIBUTE_NMTOKEN);
- }
- return(xmlParseEnumeratedType(ctxt, tree));
-}
-
-/**
- * xmlParseAttributeListDecl:
- * @ctxt: an XML parser context
- *
- * : parse the Attribute list def for an element
- *
- * [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
- *
- * [53] AttDef ::= S Name S AttType S DefaultDecl
- *
- */
-void
-xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
- xmlChar *elemName;
- xmlChar *attrName;
- xmlEnumerationPtr tree;
-
- if ((RAW == '<') && (NXT(1) == '!') &&
- (NXT(2) == 'A') && (NXT(3) == 'T') &&
- (NXT(4) == 'T') && (NXT(5) == 'L') &&
- (NXT(6) == 'I') && (NXT(7) == 'S') &&
- (NXT(8) == 'T')) {
- xmlParserInputPtr input = ctxt->input;
-
- SKIP(9);
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after '<!ATTLIST'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- elemName = xmlParseName(ctxt);
- if (elemName == NULL) {
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "ATTLIST: no name for Element\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return;
- }
- SKIP_BLANKS;
- GROW;
- while (RAW != '>') {
- const xmlChar *check = CUR_PTR;
- int type;
- int def;
- xmlChar *defaultValue = NULL;
-
- GROW;
- tree = NULL;
- attrName = xmlParseName(ctxt);
- if (attrName == NULL) {
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "ATTLIST: no name for Attribute\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- break;
- }
- GROW;
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after the attribute name\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- if (attrName != NULL)
- xmlFree(attrName);
- if (defaultValue != NULL)
- xmlFree(defaultValue);
- break;
- }
- SKIP_BLANKS;
-
- type = xmlParseAttributeType(ctxt, &tree);
- if (type <= 0) {
- if (attrName != NULL)
- xmlFree(attrName);
- if (defaultValue != NULL)
- xmlFree(defaultValue);
- break;
- }
-
- GROW;
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after the attribute type\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- if (attrName != NULL)
- xmlFree(attrName);
- if (defaultValue != NULL)
- xmlFree(defaultValue);
- if (tree != NULL)
- xmlFreeEnumeration(tree);
- break;
- }
- SKIP_BLANKS;
-
- def = xmlParseDefaultDecl(ctxt, &defaultValue);
- if (def <= 0) {
- if (attrName != NULL)
- xmlFree(attrName);
- if (defaultValue != NULL)
- xmlFree(defaultValue);
- if (tree != NULL)
- xmlFreeEnumeration(tree);
- break;
- }
-
- GROW;
- if (RAW != '>') {
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after the attribute default value\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- if (attrName != NULL)
- xmlFree(attrName);
- if (defaultValue != NULL)
- xmlFree(defaultValue);
- if (tree != NULL)
- xmlFreeEnumeration(tree);
- break;
- }
- SKIP_BLANKS;
- }
- if (check == CUR_PTR) {
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseAttributeListDecl: detected internal error\n");
- if (attrName != NULL)
- xmlFree(attrName);
- if (defaultValue != NULL)
- xmlFree(defaultValue);
- if (tree != NULL)
- xmlFreeEnumeration(tree);
- break;
- }
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
- (ctxt->sax->attributeDecl != NULL))
- ctxt->sax->attributeDecl(ctxt->userData, elemName, attrName,
- type, def, defaultValue, tree);
- if (attrName != NULL)
- xmlFree(attrName);
- if (defaultValue != NULL)
- xmlFree(defaultValue);
- GROW;
- }
- if (RAW == '>') {
- if (input != ctxt->input) {
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
-"Attribute list declaration doesn't start and stop in the same entity\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- NEXT;
- }
-
- xmlFree(elemName);
- }
-}
-
-/**
- * xmlParseElementMixedContentDecl:
- * @ctxt: an XML parser context
- * @inputchk: the input used for the current entity, needed for boundary checks
- *
- * parse the declaration for a Mixed Element content
- * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
- *
- * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' |
- * '(' S? '#PCDATA' S? ')'
- *
- * [ VC: Proper Group/PE Nesting ] applies to [51] too (see [49])
- *
- * [ VC: No Duplicate Types ]
- * The same name must not appear more than once in a single
- * mixed-content declaration.
- *
- * returns: the list of the xmlElementContentPtr describing the element choices
- */
-xmlElementContentPtr
-xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, xmlParserInputPtr inputchk) {
- xmlElementContentPtr ret = NULL, cur = NULL, n;
- xmlChar *elem = NULL;
-
- GROW;
- if ((RAW == '#') && (NXT(1) == 'P') &&
- (NXT(2) == 'C') && (NXT(3) == 'D') &&
- (NXT(4) == 'A') && (NXT(5) == 'T') &&
- (NXT(6) == 'A')) {
- SKIP(7);
- SKIP_BLANKS;
- SHRINK;
- if (RAW == ')') {
- if ((ctxt->validate) && (ctxt->input != inputchk)) {
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- if (ctxt->vctxt.error != NULL)
- ctxt->vctxt.error(ctxt->vctxt.userData,
-"Element content declaration doesn't start and stop in the same entity\n");
- ctxt->valid = 0;
- }
- NEXT;
- ret = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_PCDATA);
- if (RAW == '*') {
- ret->ocur = XML_ELEMENT_CONTENT_MULT;
- NEXT;
- }
- return(ret);
- }
- if ((RAW == '(') || (RAW == '|')) {
- ret = cur = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_PCDATA);
- if (ret == NULL) return(NULL);
- }
- while (RAW == '|') {
- NEXT;
- if (elem == NULL) {
- ret = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
- if (ret == NULL) return(NULL);
- ret->c1 = cur;
- if (cur != NULL)
- cur->parent = ret;
- cur = ret;
- } else {
- n = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
- if (n == NULL) return(NULL);
- n->c1 = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
- if (n->c1 != NULL)
- n->c1->parent = n;
- cur->c2 = n;
- if (n != NULL)
- n->parent = cur;
- cur = n;
- xmlFree(elem);
- }
- SKIP_BLANKS;
- elem = xmlParseName(ctxt);
- if (elem == NULL) {
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementMixedContentDecl : Name expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- xmlFreeElementContent(cur);
- return(NULL);
- }
- SKIP_BLANKS;
- GROW;
- }
- if ((RAW == ')') && (NXT(1) == '*')) {
- if (elem != NULL) {
- cur->c2 = xmlNewElementContent(elem,
- XML_ELEMENT_CONTENT_ELEMENT);
- if (cur->c2 != NULL)
- cur->c2->parent = cur;
- xmlFree(elem);
- }
- ret->ocur = XML_ELEMENT_CONTENT_MULT;
- if ((ctxt->validate) && (ctxt->input != inputchk)) {
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- if (ctxt->vctxt.error != NULL)
- ctxt->vctxt.error(ctxt->vctxt.userData,
-"Element content declaration doesn't start and stop in the same entity\n");
- ctxt->valid = 0;
- }
- SKIP(2);
- } else {
- if (elem != NULL) xmlFree(elem);
- xmlFreeElementContent(ret);
- ctxt->errNo = XML_ERR_MIXED_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementMixedContentDecl : '|' or ')*' expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(NULL);
- }
-
- } else {
- ctxt->errNo = XML_ERR_PCDATA_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementMixedContentDecl : '#PCDATA' expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- return(ret);
-}
-
-/**
- * xmlParseElementChildrenContentDecl:
- * @ctxt: an XML parser context
- * @inputchk: the input used for the current entity, needed for boundary checks
- *
- * parse the declaration for a Mixed Element content
- * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
- *
- *
- * [47] children ::= (choice | seq) ('?' | '*' | '+')?
- *
- * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
- *
- * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
- *
- * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
- *
- * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
- * TODO Parameter-entity replacement text must be properly nested
- * with parenthesized groups. That is to say, if either of the
- * opening or closing parentheses in a choice, seq, or Mixed
- * construct is contained in the replacement text for a parameter
- * entity, both must be contained in the same replacement text. For
- * interoperability, if a parameter-entity reference appears in a
- * choice, seq, or Mixed construct, its replacement text should not
- * be empty, and neither the first nor last non-blank character of
- * the replacement text should be a connector (| or ,).
- *
- * Returns the tree of xmlElementContentPtr describing the element
- * hierarchy.
- */
-xmlElementContentPtr
-xmlParseElementChildrenContentDecl
-(xmlParserCtxtPtr ctxt, xmlParserInputPtr inputchk) {
- xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
- xmlChar *elem;
- xmlChar type = 0;
-
- SKIP_BLANKS;
- GROW;
- if (RAW == '(') {
- xmlParserInputPtr input = ctxt->input;
-
- /* Recurse on first child */
- NEXT;
- SKIP_BLANKS;
- cur = ret = xmlParseElementChildrenContentDecl(ctxt, input);
- SKIP_BLANKS;
- GROW;
- } else {
- elem = xmlParseName(ctxt);
- if (elem == NULL) {
- ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementChildrenContentDecl : Name or '(' expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(NULL);
- }
- cur = ret = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
- GROW;
- if (RAW == '?') {
- cur->ocur = XML_ELEMENT_CONTENT_OPT;
- NEXT;
- } else if (RAW == '*') {
- cur->ocur = XML_ELEMENT_CONTENT_MULT;
- NEXT;
- } else if (RAW == '+') {
- cur->ocur = XML_ELEMENT_CONTENT_PLUS;
- NEXT;
- } else {
- cur->ocur = XML_ELEMENT_CONTENT_ONCE;
- }
- xmlFree(elem);
- GROW;
- }
- SKIP_BLANKS;
- SHRINK;
- while (RAW != ')') {
- /*
- * Each loop we parse one separator and one element.
- */
- if (RAW == ',') {
- if (type == 0) type = CUR;
-
- /*
- * Detect "Name | Name , Name" error
- */
- else if (type != CUR) {
- ctxt->errNo = XML_ERR_SEPARATOR_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementChildrenContentDecl : '%c' expected\n",
- type);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- if ((last != NULL) && (last != ret))
- xmlFreeElementContent(last);
- if (ret != NULL)
- xmlFreeElementContent(ret);
- return(NULL);
- }
- NEXT;
-
- op = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_SEQ);
- if (op == NULL) {
- if ((last != NULL) && (last != ret))
- xmlFreeElementContent(last);
- xmlFreeElementContent(ret);
- return(NULL);
- }
- if (last == NULL) {
- op->c1 = ret;
- if (ret != NULL)
- ret->parent = op;
- ret = cur = op;
- } else {
- cur->c2 = op;
- if (op != NULL)
- op->parent = cur;
- op->c1 = last;
- if (last != NULL)
- last->parent = op;
- cur =op;
- last = NULL;
- }
- } else if (RAW == '|') {
- if (type == 0) type = CUR;
-
- /*
- * Detect "Name , Name | Name" error
- */
- else if (type != CUR) {
- ctxt->errNo = XML_ERR_SEPARATOR_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementChildrenContentDecl : '%c' expected\n",
- type);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- if ((last != NULL) && (last != ret))
- xmlFreeElementContent(last);
- if (ret != NULL)
- xmlFreeElementContent(ret);
- return(NULL);
- }
- NEXT;
-
- op = xmlNewElementContent(NULL, XML_ELEMENT_CONTENT_OR);
- if (op == NULL) {
- if ((last != NULL) && (last != ret))
- xmlFreeElementContent(last);
- if (ret != NULL)
- xmlFreeElementContent(ret);
- return(NULL);
- }
- if (last == NULL) {
- op->c1 = ret;
- if (ret != NULL)
- ret->parent = op;
- ret = cur = op;
- } else {
- cur->c2 = op;
- if (op != NULL)
- op->parent = cur;
- op->c1 = last;
- if (last != NULL)
- last->parent = op;
- cur =op;
- last = NULL;
- }
- } else {
- ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementChildrenContentDecl : ',' '|' or ')' expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- if (ret != NULL)
- xmlFreeElementContent(ret);
- return(NULL);
- }
- GROW;
- SKIP_BLANKS;
- GROW;
- if (RAW == '(') {
- xmlParserInputPtr input = ctxt->input;
- /* Recurse on second child */
- NEXT;
- SKIP_BLANKS;
- last = xmlParseElementChildrenContentDecl(ctxt, input);
- SKIP_BLANKS;
- } else {
- elem = xmlParseName(ctxt);
- if (elem == NULL) {
- ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementChildrenContentDecl : Name or '(' expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- if (ret != NULL)
- xmlFreeElementContent(ret);
- return(NULL);
- }
- last = xmlNewElementContent(elem, XML_ELEMENT_CONTENT_ELEMENT);
- xmlFree(elem);
- if (RAW == '?') {
- last->ocur = XML_ELEMENT_CONTENT_OPT;
- NEXT;
- } else if (RAW == '*') {
- last->ocur = XML_ELEMENT_CONTENT_MULT;
- NEXT;
- } else if (RAW == '+') {
- last->ocur = XML_ELEMENT_CONTENT_PLUS;
- NEXT;
- } else {
- last->ocur = XML_ELEMENT_CONTENT_ONCE;
- }
- }
- SKIP_BLANKS;
- GROW;
- }
- if ((cur != NULL) && (last != NULL)) {
- cur->c2 = last;
- if (last != NULL)
- last->parent = cur;
- }
- if ((ctxt->validate) && (ctxt->input != inputchk)) {
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- if (ctxt->vctxt.error != NULL)
- ctxt->vctxt.error(ctxt->vctxt.userData,
-"Element content declaration doesn't start and stop in the same entity\n");
- ctxt->valid = 0;
- }
- NEXT;
- if (RAW == '?') {
- if (ret != NULL)
- ret->ocur = XML_ELEMENT_CONTENT_OPT;
- NEXT;
- } else if (RAW == '*') {
- if (ret != NULL) {
- ret->ocur = XML_ELEMENT_CONTENT_MULT;
- cur = ret;
- /*
- * Some normalization:
- * (a | b* | c?)* == (a | b | c)*
- */
- while (cur->type == XML_ELEMENT_CONTENT_OR) {
- if ((cur->c1 != NULL) &&
- ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
- (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT)))
- cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
- if ((cur->c2 != NULL) &&
- ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
- (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT)))
- cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
- cur = cur->c2;
- }
- }
- NEXT;
- } else if (RAW == '+') {
- if (ret != NULL) {
- int found = 0;
-
- ret->ocur = XML_ELEMENT_CONTENT_PLUS;
- /*
- * Some normalization:
- * (a | b*)+ == (a | b)*
- * (a | b?)+ == (a | b)*
- */
- while (cur->type == XML_ELEMENT_CONTENT_OR) {
- if ((cur->c1 != NULL) &&
- ((cur->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
- (cur->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
- cur->c1->ocur = XML_ELEMENT_CONTENT_ONCE;
- found = 1;
- }
- if ((cur->c2 != NULL) &&
- ((cur->c2->ocur == XML_ELEMENT_CONTENT_OPT) ||
- (cur->c2->ocur == XML_ELEMENT_CONTENT_MULT))) {
- cur->c2->ocur = XML_ELEMENT_CONTENT_ONCE;
- found = 1;
- }
- cur = cur->c2;
- }
- if (found)
- ret->ocur = XML_ELEMENT_CONTENT_MULT;
- }
- NEXT;
- }
- return(ret);
-}
-
-/**
- * xmlParseElementContentDecl:
- * @ctxt: an XML parser context
- * @name: the name of the element being defined.
- * @result: the Element Content pointer will be stored here if any
- *
- * parse the declaration for an Element content either Mixed or Children,
- * the cases EMPTY and ANY are handled directly in xmlParseElementDecl
- *
- * [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
- *
- * returns: the type of element content XML_ELEMENT_TYPE_xxx
- */
-
-int
-xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, xmlChar *name,
- xmlElementContentPtr *result) {
-
- xmlElementContentPtr tree = NULL;
- xmlParserInputPtr input = ctxt->input;
- int res;
-
- *result = NULL;
-
- if (RAW != '(') {
- ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementContentDecl : %s '(' expected\n", name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(-1);
- }
- NEXT;
- GROW;
- SKIP_BLANKS;
- if ((RAW == '#') && (NXT(1) == 'P') &&
- (NXT(2) == 'C') && (NXT(3) == 'D') &&
- (NXT(4) == 'A') && (NXT(5) == 'T') &&
- (NXT(6) == 'A')) {
- tree = xmlParseElementMixedContentDecl(ctxt, input);
- res = XML_ELEMENT_TYPE_MIXED;
- } else {
- tree = xmlParseElementChildrenContentDecl(ctxt, input);
- res = XML_ELEMENT_TYPE_ELEMENT;
- }
- SKIP_BLANKS;
- *result = tree;
- return(res);
-}
-
-/**
- * xmlParseElementDecl:
- * @ctxt: an XML parser context
- *
- * parse an Element declaration.
- *
- * [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
- *
- * [ VC: Unique Element Type Declaration ]
- * No element type may be declared more than once
- *
- * Returns the type of the element, or -1 in case of error
- */
-int
-xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
- int ret = -1;
- xmlElementContentPtr content = NULL;
-
- GROW;
- if ((RAW == '<') && (NXT(1) == '!') &&
- (NXT(2) == 'E') && (NXT(3) == 'L') &&
- (NXT(4) == 'E') && (NXT(5) == 'M') &&
- (NXT(6) == 'E') && (NXT(7) == 'N') &&
- (NXT(8) == 'T')) {
- xmlParserInputPtr input = ctxt->input;
-
- SKIP(9);
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after 'ELEMENT'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- name = xmlParseName(ctxt);
- if (name == NULL) {
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementDecl: no name for Element\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(-1);
- }
- while ((RAW == 0) && (ctxt->inputNr > 1))
- xmlPopInput(ctxt);
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space required after the element name\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- if ((RAW == 'E') && (NXT(1) == 'M') &&
- (NXT(2) == 'P') && (NXT(3) == 'T') &&
- (NXT(4) == 'Y')) {
- SKIP(5);
- /*
- * Element must always be empty.
- */
- ret = XML_ELEMENT_TYPE_EMPTY;
- } else if ((RAW == 'A') && (NXT(1) == 'N') &&
- (NXT(2) == 'Y')) {
- SKIP(3);
- /*
- * Element is a generic container.
- */
- ret = XML_ELEMENT_TYPE_ANY;
- } else if (RAW == '(') {
- ret = xmlParseElementContentDecl(ctxt, name, &content);
- } else {
- /*
- * [ WFC: PEs in Internal Subset ] error handling.
- */
- if ((RAW == '%') && (ctxt->external == 0) &&
- (ctxt->inputNr == 1)) {
- ctxt->errNo = XML_ERR_PEREF_IN_INT_SUBSET;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "PEReference: forbidden within markup decl in internal subset\n");
- } else {
- ctxt->errNo = XML_ERR_ELEMCONTENT_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected\n");
- }
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- if (name != NULL) xmlFree(name);
- return(-1);
- }
-
- SKIP_BLANKS;
- /*
- * Pop-up of finished entities.
- */
- while ((RAW == 0) && (ctxt->inputNr > 1))
- xmlPopInput(ctxt);
- SKIP_BLANKS;
-
- if (RAW != '>') {
- ctxt->errNo = XML_ERR_GT_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseElementDecl: expected '>' at the end\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- if (input != ctxt->input) {
- ctxt->errNo = XML_ERR_ENTITY_BOUNDARY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
-"Element declaration doesn't start and stop in the same entity\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
- NEXT;
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
- (ctxt->sax->elementDecl != NULL))
- ctxt->sax->elementDecl(ctxt->userData, name, ret,
- content);
- }
- if (content != NULL) {
- xmlFreeElementContent(content);
- }
- if (name != NULL) {
- xmlFree(name);
- }
- }
- return(ret);
-}
-
-/**
- * xmlParseConditionalSections
- * @ctxt: an XML parser context
- *
- * [61] conditionalSect ::= includeSect | ignoreSect
- * [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
- * [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
- * [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
- * [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
- */
-
-static void
-xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
- SKIP(3);
- SKIP_BLANKS;
- if ((RAW == 'I') && (NXT(1) == 'N') && (NXT(2) == 'C') &&
- (NXT(3) == 'L') && (NXT(4) == 'U') && (NXT(5) == 'D') &&
- (NXT(6) == 'E')) {
- SKIP(7);
- SKIP_BLANKS;
- if (RAW != '[') {
- ctxt->errNo = XML_ERR_CONDSEC_INVALID;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "XML conditional section '[' expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- NEXT;
- }
- if (xmlParserDebugEntities) {
- if ((ctxt->input != NULL) && (ctxt->input->filename))
- xmlGenericError(xmlGenericErrorContext,
- "%s(%d): ", ctxt->input->filename,
- ctxt->input->line);
- xmlGenericError(xmlGenericErrorContext,
- "Entering INCLUDE Conditional Section\n");
- }
-
- while ((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
- (NXT(2) != '>'))) {
- const xmlChar *check = CUR_PTR;
- int cons = ctxt->input->consumed;
-
- if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
- xmlParseConditionalSections(ctxt);
- } else if (IS_BLANK(CUR)) {
- NEXT;
- } else if (RAW == '%') {
- xmlParsePEReference(ctxt);
- } else
- xmlParseMarkupDecl(ctxt);
-
- /*
- * Pop-up of finished entities.
- */
- while ((RAW == 0) && (ctxt->inputNr > 1))
- xmlPopInput(ctxt);
-
- if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
- ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Content error in the external subset\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- break;
- }
- }
- if (xmlParserDebugEntities) {
- if ((ctxt->input != NULL) && (ctxt->input->filename))
- xmlGenericError(xmlGenericErrorContext,
- "%s(%d): ", ctxt->input->filename,
- ctxt->input->line);
- xmlGenericError(xmlGenericErrorContext,
- "Leaving INCLUDE Conditional Section\n");
- }
-
- } else if ((RAW == 'I') && (NXT(1) == 'G') && (NXT(2) == 'N') &&
- (NXT(3) == 'O') && (NXT(4) == 'R') && (NXT(5) == 'E')) {
- int state;
- int instate;
- int depth = 0;
-
- SKIP(6);
- SKIP_BLANKS;
- if (RAW != '[') {
- ctxt->errNo = XML_ERR_CONDSEC_INVALID;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "XML conditional section '[' expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- NEXT;
- }
- if (xmlParserDebugEntities) {
- if ((ctxt->input != NULL) && (ctxt->input->filename))
- xmlGenericError(xmlGenericErrorContext,
- "%s(%d): ", ctxt->input->filename,
- ctxt->input->line);
- xmlGenericError(xmlGenericErrorContext,
- "Entering IGNORE Conditional Section\n");
- }
-
- /*
- * Parse up to the end of the conditional section
- * But disable SAX event generating DTD building in the meantime
- */
- state = ctxt->disableSAX;
- instate = ctxt->instate;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- ctxt->instate = XML_PARSER_IGNORE;
-
- while ((depth >= 0) && (RAW != 0)) {
- if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
- depth++;
- SKIP(3);
- continue;
- }
- if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
- if (--depth >= 0) SKIP(3);
- continue;
- }
- NEXT;
- continue;
- }
-
- ctxt->disableSAX = state;
- ctxt->instate = instate;
-
- if (xmlParserDebugEntities) {
- if ((ctxt->input != NULL) && (ctxt->input->filename))
- xmlGenericError(xmlGenericErrorContext,
- "%s(%d): ", ctxt->input->filename,
- ctxt->input->line);
- xmlGenericError(xmlGenericErrorContext,
- "Leaving IGNORE Conditional Section\n");
- }
-
- } else {
- ctxt->errNo = XML_ERR_CONDSEC_INVALID;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "XML conditional section INCLUDE or IGNORE keyword expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
- if (RAW == 0)
- SHRINK;
-
- if (RAW == 0) {
- ctxt->errNo = XML_ERR_CONDSEC_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "XML conditional section not closed\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- SKIP(3);
- }
-}
-
-/**
- * xmlParseMarkupDecl:
- * @ctxt: an XML parser context
- *
- * parse Markup declarations
- *
- * [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl |
- * NotationDecl | PI | Comment
- *
- * [ VC: Proper Declaration/PE Nesting ]
- * Parameter-entity replacement text must be properly nested with
- * markup declarations. That is to say, if either the first character
- * or the last character of a markup declaration (markupdecl above) is
- * contained in the replacement text for a parameter-entity reference,
- * both must be contained in the same replacement text.
- *
- * [ WFC: PEs in Internal Subset ]
- * In the internal DTD subset, parameter-entity references can occur
- * only where markup declarations can occur, not within markup declarations.
- * (This does not apply to references that occur in external parameter
- * entities or to the external subset.)
- */
-void
-xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
- GROW;
- xmlParseElementDecl(ctxt);
- xmlParseAttributeListDecl(ctxt);
- xmlParseEntityDecl(ctxt);
- xmlParseNotationDecl(ctxt);
- xmlParsePI(ctxt);
- xmlParseComment(ctxt);
- /*
- * This is only for internal subset. On external entities,
- * the replacement is done before parsing stage
- */
- if ((ctxt->external == 0) && (ctxt->inputNr == 1))
- xmlParsePEReference(ctxt);
-
- /*
- * Conditional sections are allowed from entities included
- * by PE References in the internal subset.
- */
- if ((ctxt->external == 0) && (ctxt->inputNr > 1)) {
- if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
- xmlParseConditionalSections(ctxt);
- }
- }
-
- ctxt->instate = XML_PARSER_DTD;
-}
-
-/**
- * xmlParseTextDecl:
- * @ctxt: an XML parser context
- *
- * parse an XML declaration header for external entities
- *
- * [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
- *
- * Question: Seems that EncodingDecl is mandatory ? Is that a typo ?
- */
-
-void
-xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
- xmlChar *version;
-
- /*
- * We know that '<?xml' is here.
- */
- if ((RAW == '<') && (NXT(1) == '?') &&
- (NXT(2) == 'x') && (NXT(3) == 'm') &&
- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
- SKIP(5);
- } else {
- ctxt->errNo = XML_ERR_XMLDECL_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Text declaration '<?xml' required\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
-
- return;
- }
-
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Space needed after '<?xml'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
-
- /*
- * We may have the VersionInfo here.
- */
- version = xmlParseVersionInfo(ctxt);
- if (version == NULL)
- version = xmlCharStrdup(XML_DEFAULT_VERSION);
- else {
- if (!IS_BLANK(CUR)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Space needed here\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- }
- ctxt->input->version = version;
-
- /*
- * We must have the encoding declaration
- */
- xmlParseEncodingDecl(ctxt);
- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
- /*
- * The XML REC instructs us to stop parsing right here
- */
- return;
- }
-
- SKIP_BLANKS;
- if ((RAW == '?') && (NXT(1) == '>')) {
- SKIP(2);
- } else if (RAW == '>') {
- /* Deprecated old WD ... */
- ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "XML declaration must end-up with '?>'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- NEXT;
- } else {
- ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "parsing XML declaration: '?>' expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- MOVETO_ENDTAG(CUR_PTR);
- NEXT;
- }
-}
-
-/**
- * xmlParseExternalSubset:
- * @ctxt: an XML parser context
- * @ExternalID: the external identifier
- * @SystemID: the system identifier (or URL)
- *
- * parse Markup declarations from an external subset
- *
- * [30] extSubset ::= textDecl? extSubsetDecl
- *
- * [31] extSubsetDecl ::= (markupdecl | conditionalSect | PEReference | S) *
- */
-void
-xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
- const xmlChar *SystemID) {
- GROW;
- if ((RAW == '<') && (NXT(1) == '?') &&
- (NXT(2) == 'x') && (NXT(3) == 'm') &&
- (NXT(4) == 'l')) {
- xmlParseTextDecl(ctxt);
- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
- /*
- * The XML REC instructs us to stop parsing right here
- */
- ctxt->instate = XML_PARSER_EOF;
- return;
- }
- }
- if (ctxt->myDoc == NULL) {
- ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
- }
- if ((ctxt->myDoc != NULL) && (ctxt->myDoc->intSubset == NULL))
- xmlCreateIntSubset(ctxt->myDoc, NULL, ExternalID, SystemID);
-
- ctxt->instate = XML_PARSER_DTD;
- ctxt->external = 1;
- while (((RAW == '<') && (NXT(1) == '?')) ||
- ((RAW == '<') && (NXT(1) == '!')) ||
- (RAW == '%') || IS_BLANK(CUR)) {
- const xmlChar *check = CUR_PTR;
- int cons = ctxt->input->consumed;
-
- GROW;
- if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
- xmlParseConditionalSections(ctxt);
- } else if (IS_BLANK(CUR)) {
- NEXT;
- } else if (RAW == '%') {
- xmlParsePEReference(ctxt);
- } else
- xmlParseMarkupDecl(ctxt);
-
- /*
- * Pop-up of finished entities.
- */
- while ((RAW == 0) && (ctxt->inputNr > 1))
- xmlPopInput(ctxt);
-
- if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
- ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Content error in the external subset\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- break;
- }
- }
-
- if (RAW != 0) {
- ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Extra content at the end of the document\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
-}
-
-/**
- * xmlParseReference:
- * @ctxt: an XML parser context
- *
- * parse and handle entity references in content, depending on the SAX
- * interface, this may end-up in a call to character() if this is a
- * CharRef, a predefined entity, if there is no reference() callback.
- * or if the parser was asked to switch to that mode.
- *
- * [67] Reference ::= EntityRef | CharRef
- */
-void
-xmlParseReference(xmlParserCtxtPtr ctxt) {
- xmlEntityPtr ent;
- xmlChar *val;
- if (RAW != '&') return;
-
- if (NXT(1) == '#') {
- int i = 0;
- xmlChar out[10];
- int hex = NXT(2);
- int value = xmlParseCharRef(ctxt);
-
- if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
- /*
- * So we are using non-UTF-8 buffers
- * Check that the char fit on 8bits, if not
- * generate a CharRef.
- */
- if (value <= 0xFF) {
- out[0] = value;
- out[1] = 0;
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->characters(ctxt->userData, out, 1);
- } else {
- if ((hex == 'x') || (hex == 'X'))
- snprintf((char *)out, sizeof(out), "#x%X", value);
- else
- snprintf((char *)out, sizeof(out), "#%d", value);
- if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->reference(ctxt->userData, out);
- }
- } else {
- /*
- * Just encode the value in UTF-8
- */
- COPY_BUF(0 ,out, i, value);
- out[i] = 0;
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->characters(ctxt->userData, out, i);
- }
- } else {
- ent = xmlParseEntityRef(ctxt);
- if (ent == NULL) return;
- if (!ctxt->wellFormed)
- return;
- if ((ent->name != NULL) &&
- (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
- xmlNodePtr list = NULL;
- int ret;
-
-
- /*
- * The first reference to the entity trigger a parsing phase
- * where the ent->children is filled with the result from
- * the parsing.
- */
- if (ent->children == NULL) {
- xmlChar *value;
- value = ent->content;
-
- /*
- * Check that this entity is well formed
- */
- if ((value != NULL) &&
- (value[1] == 0) && (value[0] == '<') &&
- (xmlStrEqual(ent->name, BAD_CAST "lt"))) {
- /*
- * DONE: get definite answer on this !!!
- * Lots of entity decls are used to declare a single
- * char
- * <!ENTITY lt "<">
- * Which seems to be valid since
- * 2.4: The ampersand character (&) and the left angle
- * bracket (<) may appear in their literal form only
- * when used ... They are also legal within the literal
- * entity value of an internal entity declaration;i
- * see "4.3.2 Well-Formed Parsed Entities".
- * IMHO 2.4 and 4.3.2 are directly in contradiction.
- * Looking at the OASIS test suite and James Clark
- * tests, this is broken. However the XML REC uses
- * it. Is the XML REC not well-formed ????
- * This is a hack to avoid this problem
- *
- * ANSWER: since lt gt amp .. are already defined,
- * this is a redefinition and hence the fact that the
- * content is not well balanced is not a Wf error, this
- * is lousy but acceptable.
- */
- list = xmlNewDocText(ctxt->myDoc, value);
- if (list != NULL) {
- if ((ent->etype == XML_INTERNAL_GENERAL_ENTITY) &&
- (ent->children == NULL)) {
- ent->children = list;
- ent->last = list;
- list->parent = (xmlNodePtr) ent;
- } else {
- xmlFreeNodeList(list);
- }
- } else if (list != NULL) {
- xmlFreeNodeList(list);
- }
- } else {
- /*
- * 4.3.2: An internal general parsed entity is well-formed
- * if its replacement text matches the production labeled
- * content.
- */
-
- void *user_data;
- /*
- * This is a bit hackish but this seems the best
- * way to make sure both SAX and DOM entity support
- * behaves okay.
- */
- if (ctxt->userData == ctxt)
- user_data = NULL;
- else
- user_data = ctxt->userData;
-
- if (ent->etype == XML_INTERNAL_GENERAL_ENTITY) {
- ctxt->depth++;
- ret = xmlParseBalancedChunkMemoryInternal(ctxt,
- value, user_data, &list);
- ctxt->depth--;
- } else if (ent->etype ==
- XML_EXTERNAL_GENERAL_PARSED_ENTITY) {
- ctxt->depth++;
- ret = xmlParseExternalEntityPrivate(ctxt->myDoc, ctxt,
- ctxt->sax, user_data, ctxt->depth,
- ent->URI, ent->ExternalID, &list);
- ctxt->depth--;
- } else {
- ret = -1;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Internal: invalid entity type\n");
- }
- if (ret == XML_ERR_ENTITY_LOOP) {
- ctxt->errNo = XML_ERR_ENTITY_LOOP;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Detected entity reference loop\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return;
- } else if ((ret == 0) && (list != NULL)) {
- if (((ent->etype == XML_INTERNAL_GENERAL_ENTITY) ||
- (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
- (ent->children == NULL)) {
- ent->children = list;
- if (ctxt->replaceEntities) {
- /*
- * Prune it directly in the generated document
- * except for single text nodes.
- */
- if ((list->type == XML_TEXT_NODE) &&
- (list->next == NULL)) {
- list->parent = (xmlNodePtr) ent;
- list = NULL;
- } else {
- while (list != NULL) {
- list->parent = (xmlNodePtr) ctxt->node;
- list->doc = ctxt->myDoc;
- if (list->next == NULL)
- ent->last = list;
- list = list->next;
- }
- list = ent->children;
- if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
- xmlAddEntityReference(ent, list, NULL);
- }
- } else {
- while (list != NULL) {
- list->parent = (xmlNodePtr) ent;
- if (list->next == NULL)
- ent->last = list;
- list = list->next;
- }
- }
- } else {
- xmlFreeNodeList(list);
- list = NULL;
- }
- } else if (ret > 0) {
- ctxt->errNo = ret;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity value required\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else if (list != NULL) {
- xmlFreeNodeList(list);
- list = NULL;
- }
- }
- }
- if ((ctxt->sax != NULL) && (ctxt->sax->reference != NULL) &&
- (ctxt->replaceEntities == 0) && (!ctxt->disableSAX)) {
- /*
- * Create a node.
- */
- ctxt->sax->reference(ctxt->userData, ent->name);
- return;
- } else if (ctxt->replaceEntities) {
- if ((ctxt->node != NULL) && (ent->children != NULL)) {
- /*
- * Seems we are generating the DOM content, do
- * a simple tree copy for all references except the first
- * In the first occurrence list contains the replacement
- */
- if (list == NULL) {
- xmlNodePtr new = NULL, cur, firstChild = NULL;
- cur = ent->children;
- while (cur != NULL) {
- new = xmlCopyNode(cur, 1);
- if (firstChild == NULL){
- firstChild = new;
- }
- xmlAddChild(ctxt->node, new);
- if (cur == ent->last)
- break;
- cur = cur->next;
- }
- if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
- xmlAddEntityReference(ent, firstChild, new);
- } else {
- /*
- * the name change is to avoid coalescing of the
- * node with a possible previous text one which
- * would make ent->children a dangling pointer
- */
- if (ent->children->type == XML_TEXT_NODE)
- ent->children->name = xmlStrdup(BAD_CAST "nbktext");
- if ((ent->last != ent->children) &&
- (ent->last->type == XML_TEXT_NODE))
- ent->last->name = xmlStrdup(BAD_CAST "nbktext");
- xmlAddChildList(ctxt->node, ent->children);
- }
-
- /*
- * This is to avoid a nasty side effect, see
- * characters() in SAX.c
- */
- ctxt->nodemem = 0;
- ctxt->nodelen = 0;
- return;
- } else {
- /*
- * Probably running in SAX mode
- */
- xmlParserInputPtr input;
-
- input = xmlNewEntityInputStream(ctxt, ent);
- xmlPushInput(ctxt, input);
- if ((ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY) &&
- (RAW == '<') && (NXT(1) == '?') &&
- (NXT(2) == 'x') && (NXT(3) == 'm') &&
- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
- xmlParseTextDecl(ctxt);
- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
- /*
- * The XML REC instructs us to stop parsing right here
- */
- ctxt->instate = XML_PARSER_EOF;
- return;
- }
- if (input->standalone == 1) {
- ctxt->errNo = XML_ERR_EXT_ENTITY_STANDALONE;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "external parsed entities cannot be standalone\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- }
- return;
- }
- }
- } else {
- val = ent->content;
- if (val == NULL) return;
- /*
- * inline the entity.
- */
- if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->characters(ctxt->userData, val, xmlStrlen(val));
- }
- }
-}
-
-/**
- * xmlParseEntityRef:
- * @ctxt: an XML parser context
- *
- * parse ENTITY references declarations
- *
- * [68] EntityRef ::= '&' Name ';'
- *
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an internal DTD
- * subset which contains no parameter entity references, or a document
- * with "standalone='yes'", the Name given in the entity reference
- * must match that in an entity declaration, except that well-formed
- * documents need not declare any of the following entities: amp, lt,
- * gt, apos, quot. The declaration of a parameter entity must precede
- * any reference to it. Similarly, the declaration of a general entity
- * must precede any reference to it which appears in a default value in an
- * attribute-list declaration. Note that if entities are declared in the
- * external subset or in external parameter entities, a non-validating
- * processor is not obligated to read and process their declarations;
- * for such documents, the rule that an entity must be declared is a
- * well-formedness constraint only if standalone='yes'.
- *
- * [ WFC: Parsed Entity ]
- * An entity reference must not contain the name of an unparsed entity
- *
- * Returns the xmlEntityPtr if found, or NULL otherwise.
- */
-xmlEntityPtr
-xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlEntityPtr ent = NULL;
-
- GROW;
-
- if (RAW == '&') {
- NEXT;
- name = xmlParseName(ctxt);
- if (name == NULL) {
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseEntityRef: no name\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- if (RAW == ';') {
- NEXT;
- /*
- * Ask first SAX for entity resolution, otherwise try the
- * predefined set.
- */
- if (ctxt->sax != NULL) {
- if (ctxt->sax->getEntity != NULL)
- ent = ctxt->sax->getEntity(ctxt->userData, name);
- if (ent == NULL)
- ent = xmlGetPredefinedEntity(name);
- if ((ent == NULL) && (ctxt->userData==ctxt)) {
- ent = getEntity(ctxt, name);
- }
- }
- /*
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an
- * internal DTD subset which contains no parameter entity
- * references, or a document with "standalone='yes'", the
- * Name given in the entity reference must match that in an
- * entity declaration, except that well-formed documents
- * need not declare any of the following entities: amp, lt,
- * gt, apos, quot.
- * The declaration of a parameter entity must precede any
- * reference to it.
- * Similarly, the declaration of a general entity must
- * precede any reference to it which appears in a default
- * value in an attribute-list declaration. Note that if
- * entities are declared in the external subset or in
- * external parameter entities, a non-validating processor
- * is not obligated to read and process their declarations;
- * for such documents, the rule that an entity must be
- * declared is a well-formedness constraint only if
- * standalone='yes'.
- */
- if (ent == NULL) {
- if ((ctxt->standalone == 1) ||
- ((ctxt->hasExternalSubset == 0) &&
- (ctxt->hasPErefs == 0))) {
- ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity '%s' not defined\n", name);
- ctxt->wellFormed = 0;
- ctxt->valid = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- ctxt->errNo = XML_WAR_UNDECLARED_ENTITY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity '%s' not defined\n", name);
- ctxt->valid = 0;
- }
- }
-
- /*
- * [ WFC: Parsed Entity ]
- * An entity reference must not contain the name of an
- * unparsed entity
- */
- else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
- ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity reference to unparsed entity %s\n", name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
- /*
- * [ WFC: No External Entity References ]
- * Attribute values cannot contain direct or indirect
- * entity references to external entities.
- */
- else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
- (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
- ctxt->errNo = XML_ERR_ENTITY_IS_EXTERNAL;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Attribute references external entity '%s'\n", name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- /*
- * [ WFC: No < in Attribute Values ]
- * The replacement text of any entity referred to directly or
- * indirectly in an attribute value (other than "&lt;") must
- * not contain a <.
- */
- else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
- (ent != NULL) &&
- (!xmlStrEqual(ent->name, BAD_CAST "lt")) &&
- (ent->content != NULL) &&
- (xmlStrchr(ent->content, '<'))) {
- ctxt->errNo = XML_ERR_LT_IN_ATTRIBUTE;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "'<' in entity '%s' is not allowed in attributes values\n", name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
- /*
- * Internal check, no parameter entities here ...
- */
- else {
- switch (ent->etype) {
- case XML_INTERNAL_PARAMETER_ENTITY:
- case XML_EXTERNAL_PARAMETER_ENTITY:
- ctxt->errNo = XML_ERR_ENTITY_IS_PARAMETER;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Attempt to reference the parameter entity '%s'\n", name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- break;
- default:
- break;
- }
- }
-
- /*
- * [ WFC: No Recursion ]
- * A parsed entity must not contain a recursive reference
- * to itself, either directly or indirectly.
- * Done somewhere else
- */
-
- } else {
- ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseEntityRef: expecting ';'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- xmlFree(name);
- }
- }
- return(ent);
-}
-
-/**
- * xmlParseStringEntityRef:
- * @ctxt: an XML parser context
- * @str: a pointer to an index in the string
- *
- * parse ENTITY references declarations, but this version parses it from
- * a string value.
- *
- * [68] EntityRef ::= '&' Name ';'
- *
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an internal DTD
- * subset which contains no parameter entity references, or a document
- * with "standalone='yes'", the Name given in the entity reference
- * must match that in an entity declaration, except that well-formed
- * documents need not declare any of the following entities: amp, lt,
- * gt, apos, quot. The declaration of a parameter entity must precede
- * any reference to it. Similarly, the declaration of a general entity
- * must precede any reference to it which appears in a default value in an
- * attribute-list declaration. Note that if entities are declared in the
- * external subset or in external parameter entities, a non-validating
- * processor is not obligated to read and process their declarations;
- * for such documents, the rule that an entity must be declared is a
- * well-formedness constraint only if standalone='yes'.
- *
- * [ WFC: Parsed Entity ]
- * An entity reference must not contain the name of an unparsed entity
- *
- * Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
- * is updated to the current location in the string.
- */
-xmlEntityPtr
-xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
- xmlChar *name;
- const xmlChar *ptr;
- xmlChar cur;
- xmlEntityPtr ent = NULL;
-
- if ((str == NULL) || (*str == NULL))
- return(NULL);
- ptr = *str;
- cur = *ptr;
- if (cur == '&') {
- ptr++;
- cur = *ptr;
- name = xmlParseStringName(ctxt, &ptr);
- if (name == NULL) {
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseStringEntityRef: no name\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- if (*ptr == ';') {
- ptr++;
- /*
- * Ask first SAX for entity resolution, otherwise try the
- * predefined set.
- */
- if (ctxt->sax != NULL) {
- if (ctxt->sax->getEntity != NULL)
- ent = ctxt->sax->getEntity(ctxt->userData, name);
- if (ent == NULL)
- ent = xmlGetPredefinedEntity(name);
- if ((ent == NULL) && (ctxt->userData==ctxt)) {
- ent = getEntity(ctxt, name);
- }
- }
- /*
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an
- * internal DTD subset which contains no parameter entity
- * references, or a document with "standalone='yes'", the
- * Name given in the entity reference must match that in an
- * entity declaration, except that well-formed documents
- * need not declare any of the following entities: amp, lt,
- * gt, apos, quot.
- * The declaration of a parameter entity must precede any
- * reference to it.
- * Similarly, the declaration of a general entity must
- * precede any reference to it which appears in a default
- * value in an attribute-list declaration. Note that if
- * entities are declared in the external subset or in
- * external parameter entities, a non-validating processor
- * is not obligated to read and process their declarations;
- * for such documents, the rule that an entity must be
- * declared is a well-formedness constraint only if
- * standalone='yes'.
- */
- if (ent == NULL) {
- if ((ctxt->standalone == 1) ||
- ((ctxt->hasExternalSubset == 0) &&
- (ctxt->hasPErefs == 0))) {
- ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity '%s' not defined\n", name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- ctxt->errNo = XML_WAR_UNDECLARED_ENTITY;
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "Entity '%s' not defined\n", name);
- }
- }
-
- /*
- * [ WFC: Parsed Entity ]
- * An entity reference must not contain the name of an
- * unparsed entity
- */
- else if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
- ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Entity reference to unparsed entity %s\n", name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
- /*
- * [ WFC: No External Entity References ]
- * Attribute values cannot contain direct or indirect
- * entity references to external entities.
- */
- else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
- (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
- ctxt->errNo = XML_ERR_ENTITY_IS_EXTERNAL;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Attribute references external entity '%s'\n", name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- /*
- * [ WFC: No < in Attribute Values ]
- * The replacement text of any entity referred to directly or
- * indirectly in an attribute value (other than "&lt;") must
- * not contain a <.
- */
- else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
- (ent != NULL) &&
- (!xmlStrEqual(ent->name, BAD_CAST "lt")) &&
- (ent->content != NULL) &&
- (xmlStrchr(ent->content, '<'))) {
- ctxt->errNo = XML_ERR_LT_IN_ATTRIBUTE;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "'<' in entity '%s' is not allowed in attributes values\n", name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
- /*
- * Internal check, no parameter entities here ...
- */
- else {
- switch (ent->etype) {
- case XML_INTERNAL_PARAMETER_ENTITY:
- case XML_EXTERNAL_PARAMETER_ENTITY:
- ctxt->errNo = XML_ERR_ENTITY_IS_PARAMETER;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Attempt to reference the parameter entity '%s'\n", name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- break;
- default:
- break;
- }
- }
-
- /*
- * [ WFC: No Recursion ]
- * A parsed entity must not contain a recursive reference
- * to itself, either directly or indirectly.
- * Done somewhere else
- */
-
- } else {
- ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseStringEntityRef: expecting ';'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- xmlFree(name);
- }
- }
- *str = ptr;
- return(ent);
-}
-
-/**
- * xmlParsePEReference:
- * @ctxt: an XML parser context
- *
- * parse PEReference declarations
- * The entity content is handled directly by pushing it's content as
- * a new input stream.
- *
- * [69] PEReference ::= '%' Name ';'
- *
- * [ WFC: No Recursion ]
- * A parsed entity must not contain a recursive
- * reference to itself, either directly or indirectly.
- *
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an internal DTD
- * subset which contains no parameter entity references, or a document
- * with "standalone='yes'", ... ... The declaration of a parameter
- * entity must precede any reference to it...
- *
- * [ VC: Entity Declared ]
- * In a document with an external subset or external parameter entities
- * with "standalone='no'", ... ... The declaration of a parameter entity
- * must precede any reference to it...
- *
- * [ WFC: In DTD ]
- * Parameter-entity references may only appear in the DTD.
- * NOTE: misleading but this is handled.
- */
-void
-xmlParsePEReference(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlEntityPtr entity = NULL;
- xmlParserInputPtr input;
-
- if (RAW == '%') {
- NEXT;
- name = xmlParseName(ctxt);
- if (name == NULL) {
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParsePEReference: no name\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- if (RAW == ';') {
- NEXT;
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->getParameterEntity != NULL))
- entity = ctxt->sax->getParameterEntity(ctxt->userData,
- name);
- if (entity == NULL) {
- /*
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an
- * internal DTD subset which contains no parameter entity
- * references, or a document with "standalone='yes'", ...
- * ... The declaration of a parameter entity must precede
- * any reference to it...
- */
- if ((ctxt->standalone == 1) ||
- ((ctxt->hasExternalSubset == 0) &&
- (ctxt->hasPErefs == 0))) {
- ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
- if ((!ctxt->disableSAX) &&
- (ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "PEReference: %%%s; not found\n", name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- /*
- * [ VC: Entity Declared ]
- * In a document with an external subset or external
- * parameter entities with "standalone='no'", ...
- * ... The declaration of a parameter entity must precede
- * any reference to it...
- */
- if ((!ctxt->disableSAX) &&
- (ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "PEReference: %%%s; not found\n", name);
- ctxt->valid = 0;
- }
- } else {
- /*
- * Internal checking in case the entity quest barfed
- */
- if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
- (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "Internal: %%%s; is not a parameter entity\n", name);
- } else if (ctxt->input->free != deallocblankswrapper) {
- input = xmlNewBlanksWrapperInputStream(ctxt, entity);
- xmlPushInput(ctxt, input);
- } else {
- /*
- * TODO !!!
- * handle the extra spaces added before and after
- * c.f. http://www.w3.org/TR/REC-xml#as-PE
- */
- input = xmlNewEntityInputStream(ctxt, entity);
- xmlPushInput(ctxt, input);
- if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
- (RAW == '<') && (NXT(1) == '?') &&
- (NXT(2) == 'x') && (NXT(3) == 'm') &&
- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
- xmlParseTextDecl(ctxt);
- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
- /*
- * The XML REC instructs us to stop parsing
- * right here
- */
- ctxt->instate = XML_PARSER_EOF;
- xmlFree(name);
- return;
- }
- }
- }
- }
- ctxt->hasPErefs = 1;
- } else {
- ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParsePEReference: expecting ';'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- xmlFree(name);
- }
- }
-}
-
-/**
- * xmlParseStringPEReference:
- * @ctxt: an XML parser context
- * @str: a pointer to an index in the string
- *
- * parse PEReference declarations
- *
- * [69] PEReference ::= '%' Name ';'
- *
- * [ WFC: No Recursion ]
- * A parsed entity must not contain a recursive
- * reference to itself, either directly or indirectly.
- *
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an internal DTD
- * subset which contains no parameter entity references, or a document
- * with "standalone='yes'", ... ... The declaration of a parameter
- * entity must precede any reference to it...
- *
- * [ VC: Entity Declared ]
- * In a document with an external subset or external parameter entities
- * with "standalone='no'", ... ... The declaration of a parameter entity
- * must precede any reference to it...
- *
- * [ WFC: In DTD ]
- * Parameter-entity references may only appear in the DTD.
- * NOTE: misleading but this is handled.
- *
- * Returns the string of the entity content.
- * str is updated to the current value of the index
- */
-xmlEntityPtr
-xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
- const xmlChar *ptr;
- xmlChar cur;
- xmlChar *name;
- xmlEntityPtr entity = NULL;
-
- if ((str == NULL) || (*str == NULL)) return(NULL);
- ptr = *str;
- cur = *ptr;
- if (cur == '%') {
- ptr++;
- cur = *ptr;
- name = xmlParseStringName(ctxt, &ptr);
- if (name == NULL) {
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseStringPEReference: no name\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- cur = *ptr;
- if (cur == ';') {
- ptr++;
- cur = *ptr;
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->getParameterEntity != NULL))
- entity = ctxt->sax->getParameterEntity(ctxt->userData,
- name);
- if (entity == NULL) {
- /*
- * [ WFC: Entity Declared ]
- * In a document without any DTD, a document with only an
- * internal DTD subset which contains no parameter entity
- * references, or a document with "standalone='yes'", ...
- * ... The declaration of a parameter entity must precede
- * any reference to it...
- */
- if ((ctxt->standalone == 1) ||
- ((ctxt->hasExternalSubset == 0) &&
- (ctxt->hasPErefs == 0))) {
- ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "PEReference: %%%s; not found\n", name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- /*
- * [ VC: Entity Declared ]
- * In a document with an external subset or external
- * parameter entities with "standalone='no'", ...
- * ... The declaration of a parameter entity must
- * precede any reference to it...
- */
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "PEReference: %%%s; not found\n", name);
- ctxt->valid = 0;
- }
- } else {
- /*
- * Internal checking in case the entity quest barfed
- */
- if ((entity->etype != XML_INTERNAL_PARAMETER_ENTITY) &&
- (entity->etype != XML_EXTERNAL_PARAMETER_ENTITY)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "Internal: %%%s; is not a parameter entity\n", name);
- }
- }
- ctxt->hasPErefs = 1;
- } else {
- ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseStringPEReference: expecting ';'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- xmlFree(name);
- }
- }
- *str = ptr;
- return(entity);
-}
-
-/**
- * xmlParseDocTypeDecl:
- * @ctxt: an XML parser context
- *
- * parse a DOCTYPE declaration
- *
- * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
- * ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
- *
- * [ VC: Root Element Type ]
- * The Name in the document type declaration must match the element
- * type of the root element.
- */
-
-void
-xmlParseDocTypeDecl(xmlParserCtxtPtr ctxt) {
- xmlChar *name = NULL;
- xmlChar *ExternalID = NULL;
- xmlChar *URI = NULL;
-
- /*
- * We know that '<!DOCTYPE' has been detected.
- */
- SKIP(9);
-
- SKIP_BLANKS;
-
- /*
- * Parse the DOCTYPE name.
- */
- name = xmlParseName(ctxt);
- if (name == NULL) {
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseDocTypeDecl : no DOCTYPE name !\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- ctxt->intSubName = name;
-
- SKIP_BLANKS;
-
- /*
- * Check for SystemID and ExternalID
- */
- URI = xmlParseExternalID(ctxt, &ExternalID, 1);
-
- if ((URI != NULL) || (ExternalID != NULL)) {
- ctxt->hasExternalSubset = 1;
- }
- ctxt->extSubURI = URI;
- ctxt->extSubSystem = ExternalID;
-
- SKIP_BLANKS;
-
- /*
- * Create and update the internal subset.
- */
- if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
-
- /*
- * Is there any internal subset declarations ?
- * they are handled separately in xmlParseInternalSubset()
- */
- if (RAW == '[')
- return;
-
- /*
- * We should be at the end of the DOCTYPE declaration.
- */
- if (RAW != '>') {
- ctxt->errNo = XML_ERR_DOCTYPE_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "DOCTYPE improperly terminated\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- NEXT;
-}
-
-/**
- * xmlParseInternalSubset:
- * @ctxt: an XML parser context
- *
- * parse the internal subset declaration
- *
- * [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
- */
-
-static void
-xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
- /*
- * Is there any DTD definition ?
- */
- if (RAW == '[') {
- ctxt->instate = XML_PARSER_DTD;
- NEXT;
- /*
- * Parse the succession of Markup declarations and
- * PEReferences.
- * Subsequence (markupdecl | PEReference | S)*
- */
- while (RAW != ']') {
- const xmlChar *check = CUR_PTR;
- int cons = ctxt->input->consumed;
-
- SKIP_BLANKS;
- xmlParseMarkupDecl(ctxt);
- xmlParsePEReference(ctxt);
-
- /*
- * Pop-up of finished entities.
- */
- while ((RAW == 0) && (ctxt->inputNr > 1))
- xmlPopInput(ctxt);
-
- if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseInternalSubset: error detected in Markup declaration\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- break;
- }
- }
- if (RAW == ']') {
- NEXT;
- SKIP_BLANKS;
- }
- }
-
- /*
- * We should be at the end of the DOCTYPE declaration.
- */
- if (RAW != '>') {
- ctxt->errNo = XML_ERR_DOCTYPE_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "DOCTYPE improperly terminated\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- NEXT;
-}
-
-/**
- * xmlParseAttribute:
- * @ctxt: an XML parser context
- * @value: a xmlChar ** used to store the value of the attribute
- *
- * parse an attribute
- *
- * [41] Attribute ::= Name Eq AttValue
- *
- * [ WFC: No External Entity References ]
- * Attribute values cannot contain direct or indirect entity references
- * to external entities.
- *
- * [ WFC: No < in Attribute Values ]
- * The replacement text of any entity referred to directly or indirectly in
- * an attribute value (other than "&lt;") must not contain a <.
- *
- * [ VC: Attribute Value Type ]
- * The attribute must have been declared; the value must be of the type
- * declared for it.
- *
- * [25] Eq ::= S? '=' S?
- *
- * With namespace:
- *
- * [NS 11] Attribute ::= QName Eq AttValue
- *
- * Also the case QName == xmlns:??? is handled independently as a namespace
- * definition.
- *
- * Returns the attribute name, and the value in *value.
- */
-
-xmlChar *
-xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) {
- xmlChar *name, *val;
-
- *value = NULL;
- GROW;
- name = xmlParseName(ctxt);
- if (name == NULL) {
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "error parsing attribute name\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(NULL);
- }
-
- /*
- * read the value
- */
- SKIP_BLANKS;
- if (RAW == '=') {
- NEXT;
- SKIP_BLANKS;
- val = xmlParseAttValue(ctxt);
- ctxt->instate = XML_PARSER_CONTENT;
- } else {
- ctxt->errNo = XML_ERR_ATTRIBUTE_WITHOUT_VALUE;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Specification mandate value for attribute %s\n", name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- xmlFree(name);
- return(NULL);
- }
-
- /*
- * Check that xml:lang conforms to the specification
- * No more registered as an error, just generate a warning now
- * since this was deprecated in XML second edition
- */
- if ((ctxt->pedantic) && (xmlStrEqual(name, BAD_CAST "xml:lang"))) {
- if (!xmlCheckLanguageID(val)) {
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData,
- "Malformed value for xml:lang : %s\n", val);
- }
- }
-
- /*
- * Check that xml:space conforms to the specification
- */
- if (xmlStrEqual(name, BAD_CAST "xml:space")) {
- if (xmlStrEqual(val, BAD_CAST "default"))
- *(ctxt->space) = 0;
- else if (xmlStrEqual(val, BAD_CAST "preserve"))
- *(ctxt->space) = 1;
- else {
- ctxt->errNo = XML_ERR_ATTRIBUTE_WITHOUT_VALUE;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
-"Invalid value for xml:space : \"%s\", \"default\" or \"preserve\" expected\n",
- val);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- }
-
- *value = val;
- return(name);
-}
-
-/**
- * xmlParseStartTag:
- * @ctxt: an XML parser context
- *
- * parse a start of tag either for rule element or
- * EmptyElement. In both case we don't parse the tag closing chars.
- *
- * [40] STag ::= '<' Name (S Attribute)* S? '>'
- *
- * [ WFC: Unique Att Spec ]
- * No attribute name may appear more than once in the same start-tag or
- * empty-element tag.
- *
- * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
- *
- * [ WFC: Unique Att Spec ]
- * No attribute name may appear more than once in the same start-tag or
- * empty-element tag.
- *
- * With namespace:
- *
- * [NS 8] STag ::= '<' QName (S Attribute)* S? '>'
- *
- * [NS 10] EmptyElement ::= '<' QName (S Attribute)* S? '/>'
- *
- * Returns the element name parsed
- */
-
-xmlChar *
-xmlParseStartTag(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlChar *attname;
- xmlChar *attvalue;
- const xmlChar **atts = NULL;
- int nbatts = 0;
- int maxatts = 0;
- int i;
-
- if (RAW != '<') return(NULL);
- NEXT1;
-
- name = xmlParseName(ctxt);
- if (name == NULL) {
- ctxt->errNo = XML_ERR_NAME_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseStartTag: invalid element name\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(NULL);
- }
-
- /*
- * Now parse the attributes, it ends up with the ending
- *
- * (S Attribute)* S?
- */
- SKIP_BLANKS;
- GROW;
-
- while ((RAW != '>') &&
- ((RAW != '/') || (NXT(1) != '>')) &&
- (IS_CHAR(RAW))) {
- const xmlChar *q = CUR_PTR;
- int cons = ctxt->input->consumed;
-
- attname = xmlParseAttribute(ctxt, &attvalue);
- if ((attname != NULL) && (attvalue != NULL)) {
- /*
- * [ WFC: Unique Att Spec ]
- * No attribute name may appear more than once in the same
- * start-tag or empty-element tag.
- */
- for (i = 0; i < nbatts;i += 2) {
- if (xmlStrEqual(atts[i], attname)) {
- ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Attribute %s redefined\n",
- attname);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- xmlFree(attname);
- xmlFree(attvalue);
- goto failed;
- }
- }
-
- /*
- * Add the pair to atts
- */
- if (atts == NULL) {
- maxatts = 10;
- atts = (const xmlChar **) xmlMalloc(maxatts * sizeof(xmlChar *));
- if (atts == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %ld byte failed\n",
- maxatts * (long)sizeof(xmlChar *));
- return(NULL);
- }
- } else if (nbatts + 4 > maxatts) {
- maxatts *= 2;
- atts = (const xmlChar **) xmlRealloc((void *) atts,
- maxatts * sizeof(xmlChar *));
- if (atts == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc of %ld byte failed\n",
- maxatts * (long)sizeof(xmlChar *));
- return(NULL);
- }
- }
- atts[nbatts++] = attname;
- atts[nbatts++] = attvalue;
- atts[nbatts] = NULL;
- atts[nbatts + 1] = NULL;
- } else {
- if (attname != NULL)
- xmlFree(attname);
- if (attvalue != NULL)
- xmlFree(attvalue);
- }
-
-failed:
-
- if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
- break;
- if (!IS_BLANK(RAW)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "attributes construct error\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- if ((cons == ctxt->input->consumed) && (q == CUR_PTR)) {
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseStartTag: problem parsing attributes\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- break;
- }
- GROW;
- }
-
- /*
- * SAX: Start of Element !
- */
- if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->startElement(ctxt->userData, name, atts);
-
- if (atts != NULL) {
- for (i = 0;i < nbatts;i++) xmlFree((xmlChar *) atts[i]);
- xmlFree((void *) atts);
- }
- return(name);
-}
-
-/**
- * xmlParseEndTag:
- * @ctxt: an XML parser context
- *
- * parse an end of tag
- *
- * [42] ETag ::= '</' Name S? '>'
- *
- * With namespace
- *
- * [NS 9] ETag ::= '</' QName S? '>'
- */
-
-void
-xmlParseEndTag(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlChar *oldname;
-
- GROW;
- if ((RAW != '<') || (NXT(1) != '/')) {
- ctxt->errNo = XML_ERR_LTSLASH_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "xmlParseEndTag: '</' not found\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return;
- }
- SKIP(2);
-
- name = xmlParseNameAndCompare(ctxt,ctxt->name);
-
- /*
- * We should definitely be at the ending "S? '>'" part
- */
- GROW;
- SKIP_BLANKS;
- if ((!IS_CHAR(RAW)) || (RAW != '>')) {
- ctxt->errNo = XML_ERR_GT_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "End tag : expected '>'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else
- NEXT1;
-
- /*
- * [ WFC: Element Type Match ]
- * The Name in an element's end-tag must match the element type in the
- * start-tag.
- *
- */
- if (name != (xmlChar*)1) {
- ctxt->errNo = XML_ERR_TAG_NAME_MISMATCH;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
- if (name != NULL) {
- ctxt->sax->error(ctxt->userData,
- "Opening and ending tag mismatch: %s and %s\n",
- ctxt->name, name);
- } else {
- ctxt->sax->error(ctxt->userData,
- "Ending tag error for: %s\n", ctxt->name);
- }
-
- }
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
-#if 0
- else {
- /*
- * Recover in case of one missing close
- */
- if ((ctxt->nameNr > 2) &&
- (xmlStrEqual(ctxt->nameTab[ctxt->nameNr -2], name))) {
- namePop(ctxt);
- spacePop(ctxt);
- }
- }
-#endif
- if (name != NULL)
- xmlFree(name);
- }
-
- /*
- * SAX: End of Tag
- */
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->endElement(ctxt->userData, ctxt->name);
-
- oldname = namePop(ctxt);
- spacePop(ctxt);
- if (oldname != NULL) {
-#ifdef DEBUG_STACK
- xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
-#endif
- xmlFree(oldname);
- }
- return;
-}
-
-/**
- * xmlParseCDSect:
- * @ctxt: an XML parser context
- *
- * Parse escaped pure raw content.
- *
- * [18] CDSect ::= CDStart CData CDEnd
- *
- * [19] CDStart ::= '<![CDATA['
- *
- * [20] Data ::= (Char* - (Char* ']]>' Char*))
- *
- * [21] CDEnd ::= ']]>'
- */
-void
-xmlParseCDSect(xmlParserCtxtPtr ctxt) {
- xmlChar *buf = NULL;
- int len = 0;
- int size = XML_PARSER_BUFFER_SIZE;
- int r, rl;
- int s, sl;
- int cur, l;
- int count = 0;
-
- if ((NXT(0) == '<') && (NXT(1) == '!') &&
- (NXT(2) == '[') && (NXT(3) == 'C') &&
- (NXT(4) == 'D') && (NXT(5) == 'A') &&
- (NXT(6) == 'T') && (NXT(7) == 'A') &&
- (NXT(8) == '[')) {
- SKIP(9);
- } else
- return;
-
- ctxt->instate = XML_PARSER_CDATA_SECTION;
- r = CUR_CHAR(rl);
- if (!IS_CHAR(r)) {
- ctxt->errNo = XML_ERR_CDATA_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "CData section not finished\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- ctxt->instate = XML_PARSER_CONTENT;
- return;
- }
- NEXTL(rl);
- s = CUR_CHAR(sl);
- if (!IS_CHAR(s)) {
- ctxt->errNo = XML_ERR_CDATA_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "CData section not finished\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- ctxt->instate = XML_PARSER_CONTENT;
- return;
- }
- NEXTL(sl);
- cur = CUR_CHAR(l);
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %d byte failed\n", size);
- return;
- }
- while (IS_CHAR(cur) &&
- ((r != ']') || (s != ']') || (cur != '>'))) {
- if (len + 5 >= size) {
- size *= 2;
- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc of %d byte failed\n", size);
- return;
- }
- }
- COPY_BUF(rl,buf,len,r);
- r = s;
- rl = sl;
- s = cur;
- sl = l;
- count++;
- if (count > 50) {
- GROW;
- count = 0;
- }
- NEXTL(l);
- cur = CUR_CHAR(l);
- }
- buf[len] = 0;
- ctxt->instate = XML_PARSER_CONTENT;
- if (cur != '>') {
- ctxt->errNo = XML_ERR_CDATA_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "CData section not finished\n%.50s\n", buf);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- xmlFree(buf);
- return;
- }
- NEXTL(l);
-
- /*
- * OK the buffer is to be consumed as cdata.
- */
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
- if (ctxt->sax->cdataBlock != NULL)
- ctxt->sax->cdataBlock(ctxt->userData, buf, len);
- else if (ctxt->sax->characters != NULL)
- ctxt->sax->characters(ctxt->userData, buf, len);
- }
- xmlFree(buf);
-}
-
-/**
- * xmlParseContent:
- * @ctxt: an XML parser context
- *
- * Parse a content:
- *
- * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
- */
-
-void
-xmlParseContent(xmlParserCtxtPtr ctxt) {
- GROW;
- while ((RAW != 0) &&
- ((RAW != '<') || (NXT(1) != '/'))) {
- const xmlChar *test = CUR_PTR;
- int cons = ctxt->input->consumed;
- const xmlChar *cur = ctxt->input->cur;
-
- /*
- * First case : a Processing Instruction.
- */
- if ((*cur == '<') && (cur[1] == '?')) {
- xmlParsePI(ctxt);
- }
-
- /*
- * Second case : a CDSection
- */
- else if ((*cur == '<') && (NXT(1) == '!') &&
- (NXT(2) == '[') && (NXT(3) == 'C') &&
- (NXT(4) == 'D') && (NXT(5) == 'A') &&
- (NXT(6) == 'T') && (NXT(7) == 'A') &&
- (NXT(8) == '[')) {
- xmlParseCDSect(ctxt);
- }
-
- /*
- * Third case : a comment
- */
- else if ((*cur == '<') && (NXT(1) == '!') &&
- (NXT(2) == '-') && (NXT(3) == '-')) {
- xmlParseComment(ctxt);
- ctxt->instate = XML_PARSER_CONTENT;
- }
-
- /*
- * Fourth case : a sub-element.
- */
- else if (*cur == '<') {
- xmlParseElement(ctxt);
- }
-
- /*
- * Fifth case : a reference. If if has not been resolved,
- * parsing returns it's Name, create the node
- */
-
- else if (*cur == '&') {
- xmlParseReference(ctxt);
- }
-
- /*
- * Last case, text. Note that References are handled directly.
- */
- else {
- xmlParseCharData(ctxt, 0);
- }
-
- GROW;
- /*
- * Pop-up of finished entities.
- */
- while ((RAW == 0) && (ctxt->inputNr > 1))
- xmlPopInput(ctxt);
- SHRINK;
-
- if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "detected an error in element content\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- ctxt->instate = XML_PARSER_EOF;
- break;
- }
- }
-}
-
-/**
- * xmlParseElement:
- * @ctxt: an XML parser context
- *
- * parse an XML element, this is highly recursive
- *
- * [39] element ::= EmptyElemTag | STag content ETag
- *
- * [ WFC: Element Type Match ]
- * The Name in an element's end-tag must match the element type in the
- * start-tag.
- *
- * [ VC: Element Valid ]
- * An element is valid if there is a declaration matching elementdecl
- * where the Name matches the element type and one of the following holds:
- * - The declaration matches EMPTY and the element has no content.
- * - The declaration matches children and the sequence of child elements
- * belongs to the language generated by the regular expression in the
- * content model, with optional white space (characters matching the
- * nonterminal S) between each pair of child elements.
- * - The declaration matches Mixed and the content consists of character
- * data and child elements whose types match names in the content model.
- * - The declaration matches ANY, and the types of any child elements have
- * been declared.
- */
-
-void
-xmlParseElement(xmlParserCtxtPtr ctxt) {
- xmlChar *name;
- xmlChar *oldname;
- xmlParserNodeInfo node_info;
- xmlNodePtr ret;
-
- /* Capture start position */
- if (ctxt->record_info) {
- node_info.begin_pos = ctxt->input->consumed +
- (CUR_PTR - ctxt->input->base);
- node_info.begin_line = ctxt->input->line;
- }
-
- if (ctxt->spaceNr == 0)
- spacePush(ctxt, -1);
- else
- spacePush(ctxt, *ctxt->space);
-
- name = xmlParseStartTag(ctxt);
- if (name == NULL) {
- spacePop(ctxt);
- return;
- }
- namePush(ctxt, name);
- ret = ctxt->node;
-
- /*
- * [ VC: Root Element Type ]
- * The Name in the document type declaration must match the element
- * type of the root element.
- */
- if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
- ctxt->node && (ctxt->node == ctxt->myDoc->children))
- ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
-
- /*
- * Check for an Empty Element.
- */
- if ((RAW == '/') && (NXT(1) == '>')) {
- SKIP(2);
- if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->endElement(ctxt->userData, name);
- oldname = namePop(ctxt);
- spacePop(ctxt);
- if (oldname != NULL) {
-#ifdef DEBUG_STACK
- xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
-#endif
- xmlFree(oldname);
- }
- if ( ret != NULL && ctxt->record_info ) {
- node_info.end_pos = ctxt->input->consumed +
- (CUR_PTR - ctxt->input->base);
- node_info.end_line = ctxt->input->line;
- node_info.node = ret;
- xmlParserAddNodeInfo(ctxt, &node_info);
- }
- return;
- }
- if (RAW == '>') {
- NEXT1;
- } else {
- ctxt->errNo = XML_ERR_GT_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Couldn't find end of Start Tag %s\n",
- name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
-
- /*
- * end of parsing of this node.
- */
- nodePop(ctxt);
- oldname = namePop(ctxt);
- spacePop(ctxt);
- if (oldname != NULL) {
-#ifdef DEBUG_STACK
- xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
-#endif
- xmlFree(oldname);
- }
-
- /*
- * Capture end position and add node
- */
- if ( ret != NULL && ctxt->record_info ) {
- node_info.end_pos = ctxt->input->consumed +
- (CUR_PTR - ctxt->input->base);
- node_info.end_line = ctxt->input->line;
- node_info.node = ret;
- xmlParserAddNodeInfo(ctxt, &node_info);
- }
- return;
- }
-
- /*
- * Parse the content of the element:
- */
- xmlParseContent(ctxt);
- if (!IS_CHAR(RAW)) {
- ctxt->errNo = XML_ERR_TAG_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Premature end of data in tag %s\n", name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
-
- /*
- * end of parsing of this node.
- */
- nodePop(ctxt);
- oldname = namePop(ctxt);
- spacePop(ctxt);
- if (oldname != NULL) {
-#ifdef DEBUG_STACK
- xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
-#endif
- xmlFree(oldname);
- }
- return;
- }
-
- /*
- * parse the end of tag: '</' should be here.
- */
- xmlParseEndTag(ctxt);
-
- /*
- * Capture end position and add node
- */
- if ( ret != NULL && ctxt->record_info ) {
- node_info.end_pos = ctxt->input->consumed +
- (CUR_PTR - ctxt->input->base);
- node_info.end_line = ctxt->input->line;
- node_info.node = ret;
- xmlParserAddNodeInfo(ctxt, &node_info);
- }
-}
-
-/**
- * xmlParseVersionNum:
- * @ctxt: an XML parser context
- *
- * parse the XML version value.
- *
- * [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+
- *
- * Returns the string giving the XML version number, or NULL
- */
-xmlChar *
-xmlParseVersionNum(xmlParserCtxtPtr ctxt) {
- xmlChar *buf = NULL;
- int len = 0;
- int size = 10;
- xmlChar cur;
-
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %d byte failed\n", size);
- return(NULL);
- }
- cur = CUR;
- while (((cur >= 'a') && (cur <= 'z')) ||
- ((cur >= 'A') && (cur <= 'Z')) ||
- ((cur >= '0') && (cur <= '9')) ||
- (cur == '_') || (cur == '.') ||
- (cur == ':') || (cur == '-')) {
- if (len + 1 >= size) {
- size *= 2;
- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc of %d byte failed\n", size);
- return(NULL);
- }
- }
- buf[len++] = cur;
- NEXT;
- cur=CUR;
- }
- buf[len] = 0;
- return(buf);
-}
-
-/**
- * xmlParseVersionInfo:
- * @ctxt: an XML parser context
- *
- * parse the XML version.
- *
- * [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
- *
- * [25] Eq ::= S? '=' S?
- *
- * Returns the version string, e.g. "1.0"
- */
-
-xmlChar *
-xmlParseVersionInfo(xmlParserCtxtPtr ctxt) {
- xmlChar *version = NULL;
- const xmlChar *q;
-
- if ((RAW == 'v') && (NXT(1) == 'e') &&
- (NXT(2) == 'r') && (NXT(3) == 's') &&
- (NXT(4) == 'i') && (NXT(5) == 'o') &&
- (NXT(6) == 'n')) {
- SKIP(7);
- SKIP_BLANKS;
- if (RAW != '=') {
- ctxt->errNo = XML_ERR_EQUAL_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseVersionInfo : expected '='\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(NULL);
- }
- NEXT;
- SKIP_BLANKS;
- if (RAW == '"') {
- NEXT;
- q = CUR_PTR;
- version = xmlParseVersionNum(ctxt);
- if (RAW != '"') {
- ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "String not closed\n%.50s\n", q);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else
- NEXT;
- } else if (RAW == '\''){
- NEXT;
- q = CUR_PTR;
- version = xmlParseVersionNum(ctxt);
- if (RAW != '\'') {
- ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "String not closed\n%.50s\n", q);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else
- NEXT;
- } else {
- ctxt->errNo = XML_ERR_STRING_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseVersionInfo : expected ' or \"\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- }
- return(version);
-}
-
-/**
- * xmlParseEncName:
- * @ctxt: an XML parser context
- *
- * parse the XML encoding name
- *
- * [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
- *
- * Returns the encoding name value or NULL
- */
-xmlChar *
-xmlParseEncName(xmlParserCtxtPtr ctxt) {
- xmlChar *buf = NULL;
- int len = 0;
- int size = 10;
- xmlChar cur;
-
- cur = CUR;
- if (((cur >= 'a') && (cur <= 'z')) ||
- ((cur >= 'A') && (cur <= 'Z'))) {
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %d byte failed\n", size);
- return(NULL);
- }
-
- buf[len++] = cur;
- NEXT;
- cur = CUR;
- while (((cur >= 'a') && (cur <= 'z')) ||
- ((cur >= 'A') && (cur <= 'Z')) ||
- ((cur >= '0') && (cur <= '9')) ||
- (cur == '.') || (cur == '_') ||
- (cur == '-')) {
- if (len + 1 >= size) {
- size *= 2;
- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc of %d byte failed\n", size);
- return(NULL);
- }
- }
- buf[len++] = cur;
- NEXT;
- cur = CUR;
- if (cur == 0) {
- SHRINK;
- GROW;
- cur = CUR;
- }
- }
- buf[len] = 0;
- } else {
- ctxt->errNo = XML_ERR_ENCODING_NAME;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Invalid XML encoding name\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- return(buf);
-}
-
-/**
- * xmlParseEncodingDecl:
- * @ctxt: an XML parser context
- *
- * parse the XML encoding declaration
- *
- * [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'")
- *
- * this setups the conversion filters.
- *
- * Returns the encoding value or NULL
- */
-
-xmlChar *
-xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
- xmlChar *encoding = NULL;
- const xmlChar *q;
-
- SKIP_BLANKS;
- if ((RAW == 'e') && (NXT(1) == 'n') &&
- (NXT(2) == 'c') && (NXT(3) == 'o') &&
- (NXT(4) == 'd') && (NXT(5) == 'i') &&
- (NXT(6) == 'n') && (NXT(7) == 'g')) {
- SKIP(8);
- SKIP_BLANKS;
- if (RAW != '=') {
- ctxt->errNo = XML_ERR_EQUAL_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseEncodingDecl : expected '='\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(NULL);
- }
- NEXT;
- SKIP_BLANKS;
- if (RAW == '"') {
- NEXT;
- q = CUR_PTR;
- encoding = xmlParseEncName(ctxt);
- if (RAW != '"') {
- ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "String not closed\n%.50s\n", q);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else
- NEXT;
- } else if (RAW == '\''){
- NEXT;
- q = CUR_PTR;
- encoding = xmlParseEncName(ctxt);
- if (RAW != '\'') {
- ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "String not closed\n%.50s\n", q);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else
- NEXT;
- } else {
- ctxt->errNo = XML_ERR_STRING_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseEncodingDecl : expected ' or \"\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- if (encoding != NULL) {
- xmlCharEncoding enc;
- xmlCharEncodingHandlerPtr handler;
-
- if (ctxt->input->encoding != NULL)
- xmlFree((xmlChar *) ctxt->input->encoding);
- ctxt->input->encoding = encoding;
-
- enc = xmlParseCharEncoding((const char *) encoding);
- /*
- * registered set of known encodings
- */
- if (enc != XML_CHAR_ENCODING_ERROR) {
- xmlSwitchEncoding(ctxt, enc);
- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
- ctxt->input->encoding = NULL;
- xmlFree(encoding);
- return(NULL);
- }
- } else {
- /*
- * fallback for unknown encodings
- */
- handler = xmlFindCharEncodingHandler((const char *) encoding);
- if (handler != NULL) {
- xmlSwitchToEncoding(ctxt, handler);
- } else {
- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Unsupported encoding %s\n", encoding);
- return(NULL);
- }
- }
- }
- }
- return(encoding);
-}
-
-/**
- * xmlParseSDDecl:
- * @ctxt: an XML parser context
- *
- * parse the XML standalone declaration
- *
- * [32] SDDecl ::= S 'standalone' Eq
- * (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no')'"'))
- *
- * [ VC: Standalone Document Declaration ]
- * TODO The standalone document declaration must have the value "no"
- * if any external markup declarations contain declarations of:
- * - attributes with default values, if elements to which these
- * attributes apply appear in the document without specifications
- * of values for these attributes, or
- * - entities (other than amp, lt, gt, apos, quot), if references
- * to those entities appear in the document, or
- * - attributes with values subject to normalization, where the
- * attribute appears in the document with a value which will change
- * as a result of normalization, or
- * - element types with element content, if white space occurs directly
- * within any instance of those types.
- *
- * Returns 1 if standalone, 0 otherwise
- */
-
-int
-xmlParseSDDecl(xmlParserCtxtPtr ctxt) {
- int standalone = -1;
-
- SKIP_BLANKS;
- if ((RAW == 's') && (NXT(1) == 't') &&
- (NXT(2) == 'a') && (NXT(3) == 'n') &&
- (NXT(4) == 'd') && (NXT(5) == 'a') &&
- (NXT(6) == 'l') && (NXT(7) == 'o') &&
- (NXT(8) == 'n') && (NXT(9) == 'e')) {
- SKIP(10);
- SKIP_BLANKS;
- if (RAW != '=') {
- ctxt->errNo = XML_ERR_EQUAL_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "XML standalone declaration : expected '='\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return(standalone);
- }
- NEXT;
- SKIP_BLANKS;
- if (RAW == '\''){
- NEXT;
- if ((RAW == 'n') && (NXT(1) == 'o')) {
- standalone = 0;
- SKIP(2);
- } else if ((RAW == 'y') && (NXT(1) == 'e') &&
- (NXT(2) == 's')) {
- standalone = 1;
- SKIP(3);
- } else {
- ctxt->errNo = XML_ERR_STANDALONE_VALUE;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "standalone accepts only 'yes' or 'no'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- if (RAW != '\'') {
- ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "String not closed\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else
- NEXT;
- } else if (RAW == '"'){
- NEXT;
- if ((RAW == 'n') && (NXT(1) == 'o')) {
- standalone = 0;
- SKIP(2);
- } else if ((RAW == 'y') && (NXT(1) == 'e') &&
- (NXT(2) == 's')) {
- standalone = 1;
- SKIP(3);
- } else {
- ctxt->errNo = XML_ERR_STANDALONE_VALUE;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "standalone accepts only 'yes' or 'no'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- if (RAW != '"') {
- ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "String not closed\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else
- NEXT;
- } else {
- ctxt->errNo = XML_ERR_STRING_NOT_STARTED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Standalone value not found\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- }
- return(standalone);
-}
-
-/**
- * xmlParseXMLDecl:
- * @ctxt: an XML parser context
- *
- * parse an XML declaration header
- *
- * [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
- */
-
-void
-xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
- xmlChar *version;
-
- /*
- * We know that '<?xml' is here.
- */
- SKIP(5);
-
- if (!IS_BLANK(RAW)) {
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Blank needed after '<?xml'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
-
- /*
- * We must have the VersionInfo here.
- */
- version = xmlParseVersionInfo(ctxt);
- if (version == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Malformed declaration expecting version\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- if (!xmlStrEqual(version, (const xmlChar *) XML_DEFAULT_VERSION)) {
- /*
- * TODO: Blueberry should be detected here
- */
- if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt->userData, "Unsupported version '%s'\n",
- version);
- }
- if (ctxt->version != NULL)
- xmlFree((void *) ctxt->version);
- ctxt->version = version;
- }
-
- /*
- * We may have the encoding declaration
- */
- if (!IS_BLANK(RAW)) {
- if ((RAW == '?') && (NXT(1) == '>')) {
- SKIP(2);
- return;
- }
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Blank needed here\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- xmlParseEncodingDecl(ctxt);
- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
- /*
- * The XML REC instructs us to stop parsing right here
- */
- return;
- }
-
- /*
- * We may have the standalone status.
- */
- if ((ctxt->input->encoding != NULL) && (!IS_BLANK(RAW))) {
- if ((RAW == '?') && (NXT(1) == '>')) {
- SKIP(2);
- return;
- }
- ctxt->errNo = XML_ERR_SPACE_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Blank needed here\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- SKIP_BLANKS;
- ctxt->input->standalone = xmlParseSDDecl(ctxt);
-
- SKIP_BLANKS;
- if ((RAW == '?') && (NXT(1) == '>')) {
- SKIP(2);
- } else if (RAW == '>') {
- /* Deprecated old WD ... */
- ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "XML declaration must end-up with '?>'\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- NEXT;
- } else {
- ctxt->errNo = XML_ERR_XMLDECL_NOT_FINISHED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "parsing XML declaration: '?>' expected\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- MOVETO_ENDTAG(CUR_PTR);
- NEXT;
- }
-}
-
-/**
- * xmlParseMisc:
- * @ctxt: an XML parser context
- *
- * parse an XML Misc* optional field.
- *
- * [27] Misc ::= Comment | PI | S
- */
-
-void
-xmlParseMisc(xmlParserCtxtPtr ctxt) {
- while (((RAW == '<') && (NXT(1) == '?')) ||
- ((RAW == '<') && (NXT(1) == '!') &&
- (NXT(2) == '-') && (NXT(3) == '-')) ||
- IS_BLANK(CUR)) {
- if ((RAW == '<') && (NXT(1) == '?')) {
- xmlParsePI(ctxt);
- } else if (IS_BLANK(CUR)) {
- NEXT;
- } else
- xmlParseComment(ctxt);
- }
-}
-
-/**
- * xmlParseDocument:
- * @ctxt: an XML parser context
- *
- * parse an XML document (and build a tree if using the standard SAX
- * interface).
- *
- * [1] document ::= prolog element Misc*
- *
- * [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
- *
- * Returns 0, -1 in case of error. the parser context is augmented
- * as a result of the parsing.
- */
-
-int
-xmlParseDocument(xmlParserCtxtPtr ctxt) {
- xmlChar start[4];
- xmlCharEncoding enc;
-
- xmlInitParser();
-
- GROW;
-
- /*
- * SAX: beginning of the document processing.
- */
- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
- ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
-
- if (ctxt->encoding == (const xmlChar *)XML_CHAR_ENCODING_NONE) {
- /*
- * Get the 4 first bytes and decode the charset
- * if enc != XML_CHAR_ENCODING_NONE
- * plug some encoding conversion routines.
- */
- start[0] = RAW;
- start[1] = NXT(1);
- start[2] = NXT(2);
- start[3] = NXT(3);
- enc = xmlDetectCharEncoding(start, 4);
- if (enc != XML_CHAR_ENCODING_NONE) {
- xmlSwitchEncoding(ctxt, enc);
- }
- }
-
-
- if (CUR == 0) {
- ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Document is empty\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
- /*
- * Check for the XMLDecl in the Prolog.
- */
- GROW;
- if ((RAW == '<') && (NXT(1) == '?') &&
- (NXT(2) == 'x') && (NXT(3) == 'm') &&
- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
-
- /*
- * Note that we will switch encoding on the fly.
- */
- xmlParseXMLDecl(ctxt);
- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
- /*
- * The XML REC instructs us to stop parsing right here
- */
- return(-1);
- }
- ctxt->standalone = ctxt->input->standalone;
- SKIP_BLANKS;
- } else {
- ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
- }
- if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
- ctxt->sax->startDocument(ctxt->userData);
-
- /*
- * The Misc part of the Prolog
- */
- GROW;
- xmlParseMisc(ctxt);
-
- /*
- * Then possibly doc type declaration(s) and more Misc
- * (doctypedecl Misc*)?
- */
- GROW;
- if ((RAW == '<') && (NXT(1) == '!') &&
- (NXT(2) == 'D') && (NXT(3) == 'O') &&
- (NXT(4) == 'C') && (NXT(5) == 'T') &&
- (NXT(6) == 'Y') && (NXT(7) == 'P') &&
- (NXT(8) == 'E')) {
-
- ctxt->inSubset = 1;
- xmlParseDocTypeDecl(ctxt);
- if (RAW == '[') {
- ctxt->instate = XML_PARSER_DTD;
- xmlParseInternalSubset(ctxt);
- }
-
- /*
- * Create and update the external subset.
- */
- ctxt->inSubset = 2;
- if ((ctxt->sax != NULL) && (ctxt->sax->externalSubset != NULL) &&
- (!ctxt->disableSAX))
- ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
- ctxt->extSubSystem, ctxt->extSubURI);
- ctxt->inSubset = 0;
-
-
- ctxt->instate = XML_PARSER_PROLOG;
- xmlParseMisc(ctxt);
- }
-
- /*
- * Time to start parsing the tree itself
- */
- GROW;
- if (RAW != '<') {
- ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Start tag expected, '<' not found\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- ctxt->instate = XML_PARSER_EOF;
- } else {
- ctxt->instate = XML_PARSER_CONTENT;
- xmlParseElement(ctxt);
- ctxt->instate = XML_PARSER_EPILOG;
-
-
- /*
- * The Misc part at the end
- */
- xmlParseMisc(ctxt);
-
- if (RAW != 0) {
- ctxt->errNo = XML_ERR_DOCUMENT_END;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Extra content at the end of the document\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- ctxt->instate = XML_PARSER_EOF;
- }
-
- /*
- * SAX: end of the document processing.
- */
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
-
- /*
- * Remove locally kept entity definitions if the tree was not built
- */
- if ((ctxt->myDoc != NULL) &&
- (xmlStrEqual(ctxt->myDoc->version, SAX_COMPAT_MODE))) {
- xmlFreeDoc(ctxt->myDoc);
- ctxt->myDoc = NULL;
- }
-
- if (! ctxt->wellFormed) {
- ctxt->valid = 0;
- return(-1);
- }
- return(0);
-}
-
-/**
- * xmlParseExtParsedEnt:
- * @ctxt: an XML parser context
- *
- * parse a general parsed entity
- * An external general parsed entity is well-formed if it matches the
- * production labeled extParsedEnt.
- *
- * [78] extParsedEnt ::= TextDecl? content
- *
- * Returns 0, -1 in case of error. the parser context is augmented
- * as a result of the parsing.
- */
-
-int
-xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
- xmlChar start[4];
- xmlCharEncoding enc;
-
- xmlDefaultSAXHandlerInit();
-
- GROW;
-
- /*
- * SAX: beginning of the document processing.
- */
- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
- ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
-
- /*
- * Get the 4 first bytes and decode the charset
- * if enc != XML_CHAR_ENCODING_NONE
- * plug some encoding conversion routines.
- */
- start[0] = RAW;
- start[1] = NXT(1);
- start[2] = NXT(2);
- start[3] = NXT(3);
- enc = xmlDetectCharEncoding(start, 4);
- if (enc != XML_CHAR_ENCODING_NONE) {
- xmlSwitchEncoding(ctxt, enc);
- }
-
-
- if (CUR == 0) {
- ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Document is empty\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
- /*
- * Check for the XMLDecl in the Prolog.
- */
- GROW;
- if ((RAW == '<') && (NXT(1) == '?') &&
- (NXT(2) == 'x') && (NXT(3) == 'm') &&
- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
-
- /*
- * Note that we will switch encoding on the fly.
- */
- xmlParseXMLDecl(ctxt);
- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
- /*
- * The XML REC instructs us to stop parsing right here
- */
- return(-1);
- }
- SKIP_BLANKS;
- } else {
- ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
- }
- if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
- ctxt->sax->startDocument(ctxt->userData);
-
- /*
- * Doing validity checking on chunk doesn't make sense
- */
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->validate = 0;
- ctxt->loadsubset = 0;
- ctxt->depth = 0;
-
- xmlParseContent(ctxt);
-
- if ((RAW == '<') && (NXT(1) == '/')) {
- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "chunk is not well balanced\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else if (RAW != 0) {
- ctxt->errNo = XML_ERR_EXTRA_CONTENT;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "extra content at the end of well balanced chunk\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
- /*
- * SAX: end of the document processing.
- */
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
-
- if (! ctxt->wellFormed) return(-1);
- return(0);
-}
-
-/************************************************************************
- * *
- * Progressive parsing interfaces *
- * *
- ************************************************************************/
-
-/**
- * xmlParseLookupSequence:
- * @ctxt: an XML parser context
- * @first: the first char to lookup
- * @next: the next char to lookup or zero
- * @third: the next char to lookup or zero
- *
- * Try to find if a sequence (first, next, third) or just (first next) or
- * (first) is available in the input stream.
- * This function has a side effect of (possibly) incrementing ctxt->checkIndex
- * to avoid rescanning sequences of bytes, it DOES change the state of the
- * parser, do not use liberally.
- *
- * Returns the index to the current parsing point if the full sequence
- * is available, -1 otherwise.
- */
-static int
-xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first,
- xmlChar next, xmlChar third) {
- int base, len;
- xmlParserInputPtr in;
- const xmlChar *buf;
-
- in = ctxt->input;
- if (in == NULL) return(-1);
- base = in->cur - in->base;
- if (base < 0) return(-1);
- if (ctxt->checkIndex > base)
- base = ctxt->checkIndex;
- if (in->buf == NULL) {
- buf = in->base;
- len = in->length;
- } else {
- buf = in->buf->buffer->content;
- len = in->buf->buffer->use;
- }
- /* take into account the sequence length */
- if (third) len -= 2;
- else if (next) len --;
- for (;base < len;base++) {
- if (buf[base] == first) {
- if (third != 0) {
- if ((buf[base + 1] != next) ||
- (buf[base + 2] != third)) continue;
- } else if (next != 0) {
- if (buf[base + 1] != next) continue;
- }
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- if (next == 0)
- xmlGenericError(xmlGenericErrorContext,
- "PP: lookup '%c' found at %d\n",
- first, base);
- else if (third == 0)
- xmlGenericError(xmlGenericErrorContext,
- "PP: lookup '%c%c' found at %d\n",
- first, next, base);
- else
- xmlGenericError(xmlGenericErrorContext,
- "PP: lookup '%c%c%c' found at %d\n",
- first, next, third, base);
-#endif
- return(base - (in->cur - in->base));
- }
- }
- ctxt->checkIndex = base;
-#ifdef DEBUG_PUSH
- if (next == 0)
- xmlGenericError(xmlGenericErrorContext,
- "PP: lookup '%c' failed\n", first);
- else if (third == 0)
- xmlGenericError(xmlGenericErrorContext,
- "PP: lookup '%c%c' failed\n", first, next);
- else
- xmlGenericError(xmlGenericErrorContext,
- "PP: lookup '%c%c%c' failed\n", first, next, third);
-#endif
- return(-1);
-}
-
-/**
- * xmlParseTryOrFinish:
- * @ctxt: an XML parser context
- * @terminate: last chunk indicator
- *
- * Try to progress on parsing
- *
- * Returns zero if no parsing was possible
- */
-static int
-xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
- int ret = 0;
- int avail;
- xmlChar cur, next;
-
-#ifdef DEBUG_PUSH
- switch (ctxt->instate) {
- case XML_PARSER_EOF:
- xmlGenericError(xmlGenericErrorContext,
- "PP: try EOF\n"); break;
- case XML_PARSER_START:
- xmlGenericError(xmlGenericErrorContext,
- "PP: try START\n"); break;
- case XML_PARSER_MISC:
- xmlGenericError(xmlGenericErrorContext,
- "PP: try MISC\n");break;
- case XML_PARSER_COMMENT:
- xmlGenericError(xmlGenericErrorContext,
- "PP: try COMMENT\n");break;
- case XML_PARSER_PROLOG:
- xmlGenericError(xmlGenericErrorContext,
- "PP: try PROLOG\n");break;
- case XML_PARSER_START_TAG:
- xmlGenericError(xmlGenericErrorContext,
- "PP: try START_TAG\n");break;
- case XML_PARSER_CONTENT:
- xmlGenericError(xmlGenericErrorContext,
- "PP: try CONTENT\n");break;
- case XML_PARSER_CDATA_SECTION:
- xmlGenericError(xmlGenericErrorContext,
- "PP: try CDATA_SECTION\n");break;
- case XML_PARSER_END_TAG:
- xmlGenericError(xmlGenericErrorContext,
- "PP: try END_TAG\n");break;
- case XML_PARSER_ENTITY_DECL:
- xmlGenericError(xmlGenericErrorContext,
- "PP: try ENTITY_DECL\n");break;
- case XML_PARSER_ENTITY_VALUE:
- xmlGenericError(xmlGenericErrorContext,
- "PP: try ENTITY_VALUE\n");break;
- case XML_PARSER_ATTRIBUTE_VALUE:
- xmlGenericError(xmlGenericErrorContext,
- "PP: try ATTRIBUTE_VALUE\n");break;
- case XML_PARSER_DTD:
- xmlGenericError(xmlGenericErrorContext,
- "PP: try DTD\n");break;
- case XML_PARSER_EPILOG:
- xmlGenericError(xmlGenericErrorContext,
- "PP: try EPILOG\n");break;
- case XML_PARSER_PI:
- xmlGenericError(xmlGenericErrorContext,
- "PP: try PI\n");break;
- case XML_PARSER_IGNORE:
- xmlGenericError(xmlGenericErrorContext,
- "PP: try IGNORE\n");break;
- }
-#endif
-
- while (1) {
- SHRINK;
-
- /*
- * Pop-up of finished entities.
- */
- while ((RAW == 0) && (ctxt->inputNr > 1))
- xmlPopInput(ctxt);
-
- if (ctxt->input ==NULL) break;
- if (ctxt->input->buf == NULL)
- avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
- else {
- /*
- * If we are operating on converted input, try to flush
- * remainng chars to avoid them stalling in the non-converted
- * buffer.
- */
- if ((ctxt->input->buf->raw != NULL) &&
- (ctxt->input->buf->raw->use > 0)) {
- int base = ctxt->input->base -
- ctxt->input->buf->buffer->content;
- int current = ctxt->input->cur - ctxt->input->base;
-
- xmlParserInputBufferPush(ctxt->input->buf, 0, "");
- ctxt->input->base = ctxt->input->buf->buffer->content + base;
- ctxt->input->cur = ctxt->input->base + current;
- ctxt->input->end =
- &ctxt->input->buf->buffer->content[
- ctxt->input->buf->buffer->use];
- }
- avail = ctxt->input->buf->buffer->use -
- (ctxt->input->cur - ctxt->input->base);
- }
- if (avail < 1)
- goto done;
- switch (ctxt->instate) {
- case XML_PARSER_EOF:
- /*
- * Document parsing is done !
- */
- goto done;
- case XML_PARSER_START:
- if (ctxt->charset == XML_CHAR_ENCODING_NONE) {
- xmlChar start[4];
- xmlCharEncoding enc;
-
- /*
- * Very first chars read from the document flow.
- */
- if (avail < 4)
- goto done;
-
- /*
- * Get the 4 first bytes and decode the charset
- * if enc != XML_CHAR_ENCODING_NONE
- * plug some encoding conversion routines.
- */
- start[0] = RAW;
- start[1] = NXT(1);
- start[2] = NXT(2);
- start[3] = NXT(3);
- enc = xmlDetectCharEncoding(start, 4);
- if (enc != XML_CHAR_ENCODING_NONE) {
- xmlSwitchEncoding(ctxt, enc);
- }
- break;
- }
-
- cur = ctxt->input->cur[0];
- next = ctxt->input->cur[1];
- if (cur == 0) {
- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
- ctxt->sax->setDocumentLocator(ctxt->userData,
- &xmlDefaultSAXLocator);
- ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Document is empty\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- ctxt->instate = XML_PARSER_EOF;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering EOF\n");
-#endif
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
- goto done;
- }
- if ((cur == '<') && (next == '?')) {
- /* PI or XML decl */
- if (avail < 5) return(ret);
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
- return(ret);
- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
- ctxt->sax->setDocumentLocator(ctxt->userData,
- &xmlDefaultSAXLocator);
- if ((ctxt->input->cur[2] == 'x') &&
- (ctxt->input->cur[3] == 'm') &&
- (ctxt->input->cur[4] == 'l') &&
- (IS_BLANK(ctxt->input->cur[5]))) {
- ret += 5;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing XML Decl\n");
-#endif
- xmlParseXMLDecl(ctxt);
- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
- /*
- * The XML REC instructs us to stop parsing right
- * here
- */
- ctxt->instate = XML_PARSER_EOF;
- return(0);
- }
- ctxt->standalone = ctxt->input->standalone;
- if ((ctxt->encoding == NULL) &&
- (ctxt->input->encoding != NULL))
- ctxt->encoding = xmlStrdup(ctxt->input->encoding);
- if ((ctxt->sax) && (ctxt->sax->startDocument) &&
- (!ctxt->disableSAX))
- ctxt->sax->startDocument(ctxt->userData);
- ctxt->instate = XML_PARSER_MISC;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering MISC\n");
-#endif
- } else {
- ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
- if ((ctxt->sax) && (ctxt->sax->startDocument) &&
- (!ctxt->disableSAX))
- ctxt->sax->startDocument(ctxt->userData);
- ctxt->instate = XML_PARSER_MISC;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering MISC\n");
-#endif
- }
- } else {
- if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
- ctxt->sax->setDocumentLocator(ctxt->userData,
- &xmlDefaultSAXLocator);
- ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
- if ((ctxt->sax) && (ctxt->sax->startDocument) &&
- (!ctxt->disableSAX))
- ctxt->sax->startDocument(ctxt->userData);
- ctxt->instate = XML_PARSER_MISC;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering MISC\n");
-#endif
- }
- break;
- case XML_PARSER_MISC:
- SKIP_BLANKS;
- if (ctxt->input->buf == NULL)
- avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
- else
- avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
- if (avail < 2)
- goto done;
- cur = ctxt->input->cur[0];
- next = ctxt->input->cur[1];
- if ((cur == '<') && (next == '?')) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing PI\n");
-#endif
- xmlParsePI(ctxt);
- } else if ((cur == '<') && (next == '!') &&
- (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing Comment\n");
-#endif
- xmlParseComment(ctxt);
- ctxt->instate = XML_PARSER_MISC;
- } else if ((cur == '<') && (next == '!') &&
- (ctxt->input->cur[2] == 'D') && (ctxt->input->cur[3] == 'O') &&
- (ctxt->input->cur[4] == 'C') && (ctxt->input->cur[5] == 'T') &&
- (ctxt->input->cur[6] == 'Y') && (ctxt->input->cur[7] == 'P') &&
- (ctxt->input->cur[8] == 'E')) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing internal subset\n");
-#endif
- ctxt->inSubset = 1;
- xmlParseDocTypeDecl(ctxt);
- if (RAW == '[') {
- ctxt->instate = XML_PARSER_DTD;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering DTD\n");
-#endif
- } else {
- /*
- * Create and update the external subset.
- */
- ctxt->inSubset = 2;
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
- (ctxt->sax->externalSubset != NULL))
- ctxt->sax->externalSubset(ctxt->userData,
- ctxt->intSubName, ctxt->extSubSystem,
- ctxt->extSubURI);
- ctxt->inSubset = 0;
- ctxt->instate = XML_PARSER_PROLOG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering PROLOG\n");
-#endif
- }
- } else if ((cur == '<') && (next == '!') &&
- (avail < 9)) {
- goto done;
- } else {
- ctxt->instate = XML_PARSER_START_TAG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering START_TAG\n");
-#endif
- }
- break;
- case XML_PARSER_IGNORE:
- xmlGenericError(xmlGenericErrorContext,
- "PP: internal error, state == IGNORE");
- ctxt->instate = XML_PARSER_DTD;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering DTD\n");
-#endif
- break;
- case XML_PARSER_PROLOG:
- SKIP_BLANKS;
- if (ctxt->input->buf == NULL)
- avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
- else
- avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
- if (avail < 2)
- goto done;
- cur = ctxt->input->cur[0];
- next = ctxt->input->cur[1];
- if ((cur == '<') && (next == '?')) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing PI\n");
-#endif
- xmlParsePI(ctxt);
- } else if ((cur == '<') && (next == '!') &&
- (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing Comment\n");
-#endif
- xmlParseComment(ctxt);
- ctxt->instate = XML_PARSER_PROLOG;
- } else if ((cur == '<') && (next == '!') &&
- (avail < 4)) {
- goto done;
- } else {
- ctxt->instate = XML_PARSER_START_TAG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering START_TAG\n");
-#endif
- }
- break;
- case XML_PARSER_EPILOG:
- SKIP_BLANKS;
- if (ctxt->input->buf == NULL)
- avail = ctxt->input->length - (ctxt->input->cur - ctxt->input->base);
- else
- avail = ctxt->input->buf->buffer->use - (ctxt->input->cur - ctxt->input->base);
- if (avail < 2)
- goto done;
- cur = ctxt->input->cur[0];
- next = ctxt->input->cur[1];
- if ((cur == '<') && (next == '?')) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing PI\n");
-#endif
- xmlParsePI(ctxt);
- ctxt->instate = XML_PARSER_EPILOG;
- } else if ((cur == '<') && (next == '!') &&
- (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing Comment\n");
-#endif
- xmlParseComment(ctxt);
- ctxt->instate = XML_PARSER_EPILOG;
- } else if ((cur == '<') && (next == '!') &&
- (avail < 4)) {
- goto done;
- } else {
- ctxt->errNo = XML_ERR_DOCUMENT_END;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Extra content at the end of the document\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- ctxt->instate = XML_PARSER_EOF;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering EOF\n");
-#endif
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
- goto done;
- }
- break;
- case XML_PARSER_START_TAG: {
- xmlChar *name, *oldname;
-
- if ((avail < 2) && (ctxt->inputNr == 1))
- goto done;
- cur = ctxt->input->cur[0];
- if (cur != '<') {
- ctxt->errNo = XML_ERR_DOCUMENT_EMPTY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Start tag expect, '<' not found\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- ctxt->instate = XML_PARSER_EOF;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering EOF\n");
-#endif
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
- goto done;
- }
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
- goto done;
- if (ctxt->spaceNr == 0)
- spacePush(ctxt, -1);
- else
- spacePush(ctxt, *ctxt->space);
- name = xmlParseStartTag(ctxt);
- if (name == NULL) {
- spacePop(ctxt);
- ctxt->instate = XML_PARSER_EOF;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering EOF\n");
-#endif
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
- goto done;
- }
- namePush(ctxt, xmlStrdup(name));
-
- /*
- * [ VC: Root Element Type ]
- * The Name in the document type declaration must match
- * the element type of the root element.
- */
- if (ctxt->validate && ctxt->wellFormed && ctxt->myDoc &&
- ctxt->node && (ctxt->node == ctxt->myDoc->children))
- ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
-
- /*
- * Check for an Empty Element.
- */
- if ((RAW == '/') && (NXT(1) == '>')) {
- SKIP(2);
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->endElement != NULL) && (!ctxt->disableSAX))
- ctxt->sax->endElement(ctxt->userData, name);
- xmlFree(name);
- oldname = namePop(ctxt);
- spacePop(ctxt);
- if (oldname != NULL) {
-#ifdef DEBUG_STACK
- xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
-#endif
- xmlFree(oldname);
- }
- if (ctxt->name == NULL) {
- ctxt->instate = XML_PARSER_EPILOG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering EPILOG\n");
-#endif
- } else {
- ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering CONTENT\n");
-#endif
- }
- break;
- }
- if (RAW == '>') {
- NEXT;
- } else {
- ctxt->errNo = XML_ERR_GT_REQUIRED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Couldn't find end of Start Tag %s\n",
- name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
-
- /*
- * end of parsing of this node.
- */
- nodePop(ctxt);
- oldname = namePop(ctxt);
- spacePop(ctxt);
- if (oldname != NULL) {
-#ifdef DEBUG_STACK
- xmlGenericError(xmlGenericErrorContext,"Close: popped %s\n", oldname);
-#endif
- xmlFree(oldname);
- }
- }
- xmlFree(name);
- ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering CONTENT\n");
-#endif
- break;
- }
- case XML_PARSER_CONTENT: {
- const xmlChar *test;
- int cons;
- if ((avail < 2) && (ctxt->inputNr == 1))
- goto done;
- cur = ctxt->input->cur[0];
- next = ctxt->input->cur[1];
-
- test = CUR_PTR;
- cons = ctxt->input->consumed;
- if ((cur == '<') && (next == '?')) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing PI\n");
-#endif
- xmlParsePI(ctxt);
- } else if ((cur == '<') && (next == '!') &&
- (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing Comment\n");
-#endif
- xmlParseComment(ctxt);
- ctxt->instate = XML_PARSER_CONTENT;
- } else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
- (ctxt->input->cur[2] == '[') && (NXT(3) == 'C') &&
- (ctxt->input->cur[4] == 'D') && (NXT(5) == 'A') &&
- (ctxt->input->cur[6] == 'T') && (NXT(7) == 'A') &&
- (ctxt->input->cur[8] == '[')) {
- SKIP(9);
- ctxt->instate = XML_PARSER_CDATA_SECTION;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering CDATA_SECTION\n");
-#endif
- break;
- } else if ((cur == '<') && (next == '!') &&
- (avail < 9)) {
- goto done;
- } else if ((cur == '<') && (next == '/')) {
- ctxt->instate = XML_PARSER_END_TAG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering END_TAG\n");
-#endif
- break;
- } else if (cur == '<') {
- ctxt->instate = XML_PARSER_START_TAG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering START_TAG\n");
-#endif
- break;
- } else if (cur == '&') {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0))
- goto done;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing Reference\n");
-#endif
- xmlParseReference(ctxt);
- } else {
- /* TODO Avoid the extra copy, handle directly !!! */
- /*
- * Goal of the following test is:
- * - minimize calls to the SAX 'character' callback
- * when they are mergeable
- * - handle an problem for isBlank when we only parse
- * a sequence of blank chars and the next one is
- * not available to check against '<' presence.
- * - tries to homogenize the differences in SAX
- * callbacks between the push and pull versions
- * of the parser.
- */
- if ((ctxt->inputNr == 1) &&
- (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '<', 0, 0) < 0))
- goto done;
- }
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: Parsing char data\n");
-#endif
- xmlParseCharData(ctxt, 0);
- }
- /*
- * Pop-up of finished entities.
- */
- while ((RAW == 0) && (ctxt->inputNr > 1))
- xmlPopInput(ctxt);
- if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "detected an error in element content\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- ctxt->instate = XML_PARSER_EOF;
- break;
- }
- break;
- }
- case XML_PARSER_CDATA_SECTION: {
- /*
- * The Push mode need to have the SAX callback for
- * cdataBlock merge back contiguous callbacks.
- */
- int base;
-
- base = xmlParseLookupSequence(ctxt, ']', ']', '>');
- if (base < 0) {
- if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) {
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX)) {
- if (ctxt->sax->cdataBlock != NULL)
- ctxt->sax->cdataBlock(ctxt->userData, ctxt->input->cur,
- XML_PARSER_BIG_BUFFER_SIZE);
- }
- SKIP(XML_PARSER_BIG_BUFFER_SIZE);
- ctxt->checkIndex = 0;
- }
- goto done;
- } else {
- if ((ctxt->sax != NULL) && (base > 0) &&
- (!ctxt->disableSAX)) {
- if (ctxt->sax->cdataBlock != NULL)
- ctxt->sax->cdataBlock(ctxt->userData,
- ctxt->input->cur, base);
- }
- SKIP(base + 3);
- ctxt->checkIndex = 0;
- ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering CONTENT\n");
-#endif
- }
- break;
- }
- case XML_PARSER_END_TAG:
- if (avail < 2)
- goto done;
- if ((!terminate) &&
- (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
- goto done;
- xmlParseEndTag(ctxt);
- if (ctxt->name == NULL) {
- ctxt->instate = XML_PARSER_EPILOG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering EPILOG\n");
-#endif
- } else {
- ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering CONTENT\n");
-#endif
- }
- break;
- case XML_PARSER_DTD: {
- /*
- * Sorry but progressive parsing of the internal subset
- * is not expected to be supported. We first check that
- * the full content of the internal subset is available and
- * the parsing is launched only at that point.
- * Internal subset ends up with "']' S? '>'" in an unescaped
- * section and not in a ']]>' sequence which are conditional
- * sections (whoever argued to keep that crap in XML deserve
- * a place in hell !).
- */
- int base, i;
- xmlChar *buf;
- xmlChar quote = 0;
-
- base = ctxt->input->cur - ctxt->input->base;
- if (base < 0) return(0);
- if (ctxt->checkIndex > base)
- base = ctxt->checkIndex;
- buf = ctxt->input->buf->buffer->content;
- for (;(unsigned int) base < ctxt->input->buf->buffer->use;
- base++) {
- if (quote != 0) {
- if (buf[base] == quote)
- quote = 0;
- continue;
- }
- if (buf[base] == '"') {
- quote = '"';
- continue;
- }
- if (buf[base] == '\'') {
- quote = '\'';
- continue;
- }
- if (buf[base] == ']') {
- if ((unsigned int) base +1 >=
- ctxt->input->buf->buffer->use)
- break;
- if (buf[base + 1] == ']') {
- /* conditional crap, skip both ']' ! */
- base++;
- continue;
- }
- for (i = 0;
- (unsigned int) base + i < ctxt->input->buf->buffer->use;
- i++) {
- if (buf[base + i] == '>')
- goto found_end_int_subset;
- }
- break;
- }
- }
- /*
- * We didn't found the end of the Internal subset
- */
- if (quote == 0)
- ctxt->checkIndex = base;
-#ifdef DEBUG_PUSH
- if (next == 0)
- xmlGenericError(xmlGenericErrorContext,
- "PP: lookup of int subset end filed\n");
-#endif
- goto done;
-
-found_end_int_subset:
- xmlParseInternalSubset(ctxt);
- ctxt->inSubset = 2;
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
- (ctxt->sax->externalSubset != NULL))
- ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
- ctxt->extSubSystem, ctxt->extSubURI);
- ctxt->inSubset = 0;
- ctxt->instate = XML_PARSER_PROLOG;
- ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering PROLOG\n");
-#endif
- break;
- }
- case XML_PARSER_COMMENT:
- xmlGenericError(xmlGenericErrorContext,
- "PP: internal error, state == COMMENT\n");
- ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering CONTENT\n");
-#endif
- break;
- case XML_PARSER_PI:
- xmlGenericError(xmlGenericErrorContext,
- "PP: internal error, state == PI\n");
- ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering CONTENT\n");
-#endif
- break;
- case XML_PARSER_ENTITY_DECL:
- xmlGenericError(xmlGenericErrorContext,
- "PP: internal error, state == ENTITY_DECL\n");
- ctxt->instate = XML_PARSER_DTD;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering DTD\n");
-#endif
- break;
- case XML_PARSER_ENTITY_VALUE:
- xmlGenericError(xmlGenericErrorContext,
- "PP: internal error, state == ENTITY_VALUE\n");
- ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering DTD\n");
-#endif
- break;
- case XML_PARSER_ATTRIBUTE_VALUE:
- xmlGenericError(xmlGenericErrorContext,
- "PP: internal error, state == ATTRIBUTE_VALUE\n");
- ctxt->instate = XML_PARSER_START_TAG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering START_TAG\n");
-#endif
- break;
- case XML_PARSER_SYSTEM_LITERAL:
- xmlGenericError(xmlGenericErrorContext,
- "PP: internal error, state == SYSTEM_LITERAL\n");
- ctxt->instate = XML_PARSER_START_TAG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering START_TAG\n");
-#endif
- break;
- case XML_PARSER_PUBLIC_LITERAL:
- xmlGenericError(xmlGenericErrorContext,
- "PP: internal error, state == PUBLIC_LITERAL\n");
- ctxt->instate = XML_PARSER_START_TAG;
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext,
- "PP: entering START_TAG\n");
-#endif
- break;
- }
- }
-done:
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
-#endif
- return(ret);
-}
-
-/**
- * xmlParseChunk:
- * @ctxt: an XML parser context
- * @chunk: an char array
- * @size: the size in byte of the chunk
- * @terminate: last chunk indicator
- *
- * Parse a Chunk of memory
- *
- * Returns zero if no error, the xmlParserErrors otherwise.
- */
-int
-xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
- int terminate) {
- if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
- (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF)) {
- int base = ctxt->input->base - ctxt->input->buf->buffer->content;
- int cur = ctxt->input->cur - ctxt->input->base;
-
- xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
- ctxt->input->base = ctxt->input->buf->buffer->content + base;
- ctxt->input->cur = ctxt->input->base + cur;
- ctxt->input->end =
- &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
-#endif
-
- if ((terminate) || (ctxt->input->buf->buffer->use > 80))
- xmlParseTryOrFinish(ctxt, terminate);
- } else if (ctxt->instate != XML_PARSER_EOF) {
- if ((ctxt->input != NULL) && ctxt->input->buf != NULL) {
- xmlParserInputBufferPtr in = ctxt->input->buf;
- if ((in->encoder != NULL) && (in->buffer != NULL) &&
- (in->raw != NULL)) {
- int nbchars;
-
- nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
- if (nbchars < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlParseChunk: encoder error\n");
- return(XML_ERR_INVALID_ENCODING);
- }
- }
- }
- }
- xmlParseTryOrFinish(ctxt, terminate);
- if (terminate) {
- /*
- * Check for termination
- */
- int avail = 0;
- if (ctxt->input->buf == NULL)
- avail = ctxt->input->length -
- (ctxt->input->cur - ctxt->input->base);
- else
- avail = ctxt->input->buf->buffer->use -
- (ctxt->input->cur - ctxt->input->base);
-
- if ((ctxt->instate != XML_PARSER_EOF) &&
- (ctxt->instate != XML_PARSER_EPILOG)) {
- ctxt->errNo = XML_ERR_DOCUMENT_END;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Extra content at the end of the document\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- if ((ctxt->instate == XML_PARSER_EPILOG) && (avail > 0)) {
- ctxt->errNo = XML_ERR_DOCUMENT_END;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Extra content at the end of the document\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
-
- }
- if (ctxt->instate != XML_PARSER_EOF) {
- if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
- ctxt->sax->endDocument(ctxt->userData);
- }
- ctxt->instate = XML_PARSER_EOF;
- }
- return((xmlParserErrors) ctxt->errNo);
-}
-
-/************************************************************************
- * *
- * I/O front end functions to the parser *
- * *
- ************************************************************************/
-
-/**
- * xmlStopParser:
- * @ctxt: an XML parser context
- *
- * Blocks further parser processing
- */
-void
-xmlStopParser(xmlParserCtxtPtr ctxt) {
- ctxt->instate = XML_PARSER_EOF;
- if (ctxt->input != NULL)
- ctxt->input->cur = BAD_CAST"";
-}
-
-/**
- * xmlCreatePushParserCtxt:
- * @sax: a SAX handler
- * @user_data: The user data returned on SAX callbacks
- * @chunk: a pointer to an array of chars
- * @size: number of chars in the array
- * @filename: an optional file name or URI
- *
- * Create a parser context for using the XML parser in push mode.
- * If @buffer and @size are non-NULL, the data is used to detect
- * the encoding. The remaining characters will be parsed so they
- * don't need to be fed in again through xmlParseChunk.
- * To allow content encoding detection, @size should be >= 4
- * The value of @filename is used for fetching external entities
- * and error/warning reports.
- *
- * Returns the new parser context or NULL
- */
-
-xmlParserCtxtPtr
-xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
- const char *chunk, int size, const char *filename) {
- xmlParserCtxtPtr ctxt;
- xmlParserInputPtr inputStream;
- xmlParserInputBufferPtr buf;
- xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
-
- /*
- * plug some encoding conversion routines
- */
- if ((chunk != NULL) && (size >= 4))
- enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
-
- buf = xmlAllocParserInputBuffer(enc);
- if (buf == NULL) return(NULL);
-
- ctxt = xmlNewParserCtxt();
- if (ctxt == NULL) {
- xmlFree(buf);
- return(NULL);
- }
- if (sax != NULL) {
- if (ctxt->sax != &xmlDefaultSAXHandler)
- xmlFree(ctxt->sax);
- ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
- if (ctxt->sax == NULL) {
- xmlFree(buf);
- xmlFree(ctxt);
- return(NULL);
- }
- memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
- if (user_data != NULL)
- ctxt->userData = user_data;
- }
- if (filename == NULL) {
- ctxt->directory = NULL;
- } else {
- ctxt->directory = xmlParserGetDirectory(filename);
- }
-
- inputStream = xmlNewInputStream(ctxt);
- if (inputStream == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
-
- if (filename == NULL)
- inputStream->filename = NULL;
- else
- inputStream->filename = (char *)
- xmlNormalizeWindowsPath((const xmlChar *) filename);
- inputStream->buf = buf;
- inputStream->base = inputStream->buf->buffer->content;
- inputStream->cur = inputStream->buf->buffer->content;
- inputStream->end =
- &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
-
- inputPush(ctxt, inputStream);
-
- if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
- (ctxt->input->buf != NULL)) {
- int base = ctxt->input->base - ctxt->input->buf->buffer->content;
- int cur = ctxt->input->cur - ctxt->input->base;
-
- xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
-
- ctxt->input->base = ctxt->input->buf->buffer->content + base;
- ctxt->input->cur = ctxt->input->base + cur;
- ctxt->input->end =
- &ctxt->input->buf->buffer->content[ctxt->input->buf->buffer->use];
-#ifdef DEBUG_PUSH
- xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
-#endif
- }
-
- if (enc != XML_CHAR_ENCODING_NONE) {
- xmlSwitchEncoding(ctxt, enc);
- }
-
- return(ctxt);
-}
-
-/**
- * xmlCreateIOParserCtxt:
- * @sax: a SAX handler
- * @user_data: The user data returned on SAX callbacks
- * @ioread: an I/O read function
- * @ioclose: an I/O close function
- * @ioctx: an I/O handler
- * @enc: the charset encoding if known
- *
- * Create a parser context for using the XML parser with an existing
- * I/O stream
- *
- * Returns the new parser context or NULL
- */
-xmlParserCtxtPtr
-xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
- xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
- void *ioctx, xmlCharEncoding enc) {
- xmlParserCtxtPtr ctxt;
- xmlParserInputPtr inputStream;
- xmlParserInputBufferPtr buf;
-
- buf = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, enc);
- if (buf == NULL) return(NULL);
-
- ctxt = xmlNewParserCtxt();
- if (ctxt == NULL) {
- xmlFree(buf);
- return(NULL);
- }
- if (sax != NULL) {
- if (ctxt->sax != &xmlDefaultSAXHandler)
- xmlFree(ctxt->sax);
- ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
- if (ctxt->sax == NULL) {
- xmlFree(buf);
- xmlFree(ctxt);
- return(NULL);
- }
- memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
- if (user_data != NULL)
- ctxt->userData = user_data;
- }
-
- inputStream = xmlNewIOInputStream(ctxt, buf, enc);
- if (inputStream == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
- inputPush(ctxt, inputStream);
-
- return(ctxt);
-}
-
-/************************************************************************
- * *
- * Front ends when parsing a DTD *
- * *
- ************************************************************************/
-
-/**
- * xmlIOParseDTD:
- * @sax: the SAX handler block or NULL
- * @input: an Input Buffer
- * @enc: the charset encoding if known
- *
- * Load and parse a DTD
- *
- * Returns the resulting xmlDtdPtr or NULL in case of error.
- * @input will be freed at parsing end.
- */
-
-xmlDtdPtr
-xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
- xmlCharEncoding enc) {
- xmlDtdPtr ret = NULL;
- xmlParserCtxtPtr ctxt;
- xmlParserInputPtr pinput = NULL;
- xmlChar start[4];
-
- if (input == NULL)
- return(NULL);
-
- ctxt = xmlNewParserCtxt();
- if (ctxt == NULL) {
- return(NULL);
- }
-
- /*
- * Set-up the SAX context
- */
- if (sax != NULL) {
- if (ctxt->sax != NULL)
- xmlFree(ctxt->sax);
- ctxt->sax = sax;
- ctxt->userData = NULL;
- }
-
- /*
- * generate a parser input from the I/O handler
- */
-
- pinput = xmlNewIOInputStream(ctxt, input, enc);
- if (pinput == NULL) {
- if (sax != NULL) ctxt->sax = NULL;
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
-
- /*
- * plug some encoding conversion routines here.
- */
- xmlPushInput(ctxt, pinput);
-
- pinput->filename = NULL;
- pinput->line = 1;
- pinput->col = 1;
- pinput->base = ctxt->input->cur;
- pinput->cur = ctxt->input->cur;
- pinput->free = NULL;
-
- /*
- * let's parse that entity knowing it's an external subset.
- */
- ctxt->inSubset = 2;
- ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
- ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
- BAD_CAST "none", BAD_CAST "none");
-
- if (enc == XML_CHAR_ENCODING_NONE) {
- /*
- * Get the 4 first bytes and decode the charset
- * if enc != XML_CHAR_ENCODING_NONE
- * plug some encoding conversion routines.
- */
- start[0] = RAW;
- start[1] = NXT(1);
- start[2] = NXT(2);
- start[3] = NXT(3);
- enc = xmlDetectCharEncoding(start, 4);
- if (enc != XML_CHAR_ENCODING_NONE) {
- xmlSwitchEncoding(ctxt, enc);
- }
- }
-
- xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
-
- if (ctxt->myDoc != NULL) {
- if (ctxt->wellFormed) {
- ret = ctxt->myDoc->extSubset;
- ctxt->myDoc->extSubset = NULL;
- } else {
- ret = NULL;
- }
- xmlFreeDoc(ctxt->myDoc);
- ctxt->myDoc = NULL;
- }
- if (sax != NULL) ctxt->sax = NULL;
- xmlFreeParserCtxt(ctxt);
-
- return(ret);
-}
-
-/**
- * xmlSAXParseDTD:
- * @sax: the SAX handler block
- * @ExternalID: a NAME* containing the External ID of the DTD
- * @SystemID: a NAME* containing the URL to the DTD
- *
- * Load and parse an external subset.
- *
- * Returns the resulting xmlDtdPtr or NULL in case of error.
- */
-
-xmlDtdPtr
-xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
- const xmlChar *SystemID) {
- xmlDtdPtr ret = NULL;
- xmlParserCtxtPtr ctxt;
- xmlParserInputPtr input = NULL;
- xmlCharEncoding enc;
-
- if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
-
- ctxt = xmlNewParserCtxt();
- if (ctxt == NULL) {
- return(NULL);
- }
-
- /*
- * Set-up the SAX context
- */
- if (sax != NULL) {
- if (ctxt->sax != NULL)
- xmlFree(ctxt->sax);
- ctxt->sax = sax;
- ctxt->userData = NULL;
- }
-
- /*
- * Ask the Entity resolver to load the damn thing
- */
-
- if ((ctxt->sax != NULL) && (ctxt->sax->resolveEntity != NULL))
- input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID, SystemID);
- if (input == NULL) {
- if (sax != NULL) ctxt->sax = NULL;
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
-
- /*
- * plug some encoding conversion routines here.
- */
- xmlPushInput(ctxt, input);
- enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
- xmlSwitchEncoding(ctxt, enc);
-
- if (input->filename == NULL)
- input->filename = (char *) xmlStrdup(SystemID);
- input->line = 1;
- input->col = 1;
- input->base = ctxt->input->cur;
- input->cur = ctxt->input->cur;
- input->free = NULL;
-
- /*
- * let's parse that entity knowing it's an external subset.
- */
- ctxt->inSubset = 2;
- ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0");
- ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
- ExternalID, SystemID);
- xmlParseExternalSubset(ctxt, ExternalID, SystemID);
-
- if (ctxt->myDoc != NULL) {
- if (ctxt->wellFormed) {
- ret = ctxt->myDoc->extSubset;
- ctxt->myDoc->extSubset = NULL;
- } else {
- ret = NULL;
- }
- xmlFreeDoc(ctxt->myDoc);
- ctxt->myDoc = NULL;
- }
- if (sax != NULL) ctxt->sax = NULL;
- xmlFreeParserCtxt(ctxt);
-
- return(ret);
-}
-
-/**
- * xmlParseDTD:
- * @ExternalID: a NAME* containing the External ID of the DTD
- * @SystemID: a NAME* containing the URL to the DTD
- *
- * Load and parse an external subset.
- *
- * Returns the resulting xmlDtdPtr or NULL in case of error.
- */
-
-xmlDtdPtr
-xmlParseDTD(const xmlChar *ExternalID, const xmlChar *SystemID) {
- return(xmlSAXParseDTD(NULL, ExternalID, SystemID));
-}
-
-/************************************************************************
- * *
- * Front ends when parsing an Entity *
- * *
- ************************************************************************/
-
-/**
- * xmlParseCtxtExternalEntity:
- * @ctx: the existing parsing context
- * @URL: the URL for the entity to load
- * @ID: the System ID for the entity to load
- * @lst: the return value for the set of parsed nodes
- *
- * Parse an external general entity within an existing parsing context
- * An external general parsed entity is well-formed if it matches the
- * production labeled extParsedEnt.
- *
- * [78] extParsedEnt ::= TextDecl? content
- *
- * Returns 0 if the entity is well formed, -1 in case of args problem and
- * the parser error code otherwise
- */
-
-int
-xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
- const xmlChar *ID, xmlNodePtr *lst) {
- xmlParserCtxtPtr ctxt;
- xmlDocPtr newDoc;
- xmlSAXHandlerPtr oldsax = NULL;
- int ret = 0;
- xmlChar start[4];
- xmlCharEncoding enc;
-
- if (ctx->depth > 40) {
- return(XML_ERR_ENTITY_LOOP);
- }
-
- if (lst != NULL)
- *lst = NULL;
- if ((URL == NULL) && (ID == NULL))
- return(-1);
- if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
- return(-1);
-
-
- ctxt = xmlCreateEntityParserCtxt(URL, ID, NULL);
- if (ctxt == NULL) return(-1);
- ctxt->userData = ctxt;
- oldsax = ctxt->sax;
- ctxt->sax = ctx->sax;
- newDoc = xmlNewDoc(BAD_CAST "1.0");
- if (newDoc == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(-1);
- }
- if (ctx->myDoc != NULL) {
- newDoc->intSubset = ctx->myDoc->intSubset;
- newDoc->extSubset = ctx->myDoc->extSubset;
- }
- if (ctx->myDoc->URL != NULL) {
- newDoc->URL = xmlStrdup(ctx->myDoc->URL);
- }
- newDoc->children = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
- if (newDoc->children == NULL) {
- ctxt->sax = oldsax;
- xmlFreeParserCtxt(ctxt);
- newDoc->intSubset = NULL;
- newDoc->extSubset = NULL;
- xmlFreeDoc(newDoc);
- return(-1);
- }
- nodePush(ctxt, newDoc->children);
- if (ctx->myDoc == NULL) {
- ctxt->myDoc = newDoc;
- } else {
- ctxt->myDoc = ctx->myDoc;
- newDoc->children->doc = ctx->myDoc;
- }
-
- /*
- * Get the 4 first bytes and decode the charset
- * if enc != XML_CHAR_ENCODING_NONE
- * plug some encoding conversion routines.
- */
- GROW
- start[0] = RAW;
- start[1] = NXT(1);
- start[2] = NXT(2);
- start[3] = NXT(3);
- enc = xmlDetectCharEncoding(start, 4);
- if (enc != XML_CHAR_ENCODING_NONE) {
- xmlSwitchEncoding(ctxt, enc);
- }
-
- /*
- * Parse a possible text declaration first
- */
- if ((RAW == '<') && (NXT(1) == '?') &&
- (NXT(2) == 'x') && (NXT(3) == 'm') &&
- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
- xmlParseTextDecl(ctxt);
- }
-
- /*
- * Doing validity checking on chunk doesn't make sense
- */
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->validate = ctx->validate;
- ctxt->loadsubset = ctx->loadsubset;
- ctxt->depth = ctx->depth + 1;
- ctxt->replaceEntities = ctx->replaceEntities;
- if (ctxt->validate) {
- ctxt->vctxt.error = ctx->vctxt.error;
- ctxt->vctxt.warning = ctx->vctxt.warning;
- } else {
- ctxt->vctxt.error = NULL;
- ctxt->vctxt.warning = NULL;
- }
- ctxt->vctxt.nodeTab = NULL;
- ctxt->vctxt.nodeNr = 0;
- ctxt->vctxt.nodeMax = 0;
- ctxt->vctxt.node = NULL;
-
- xmlParseContent(ctxt);
-
- if ((RAW == '<') && (NXT(1) == '/')) {
- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "chunk is not well balanced\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else if (RAW != 0) {
- ctxt->errNo = XML_ERR_EXTRA_CONTENT;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "extra content at the end of well balanced chunk\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- if (ctxt->node != newDoc->children) {
- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "chunk is not well balanced\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
- if (!ctxt->wellFormed) {
- if (ctxt->errNo == 0)
- ret = 1;
- else
- ret = ctxt->errNo;
- } else {
- if (lst != NULL) {
- xmlNodePtr cur;
-
- /*
- * Return the newly created nodeset after unlinking it from
- * they pseudo parent.
- */
- cur = newDoc->children->children;
- *lst = cur;
- while (cur != NULL) {
- cur->parent = NULL;
- cur = cur->next;
- }
- newDoc->children->children = NULL;
- }
- ret = 0;
- }
- ctxt->sax = oldsax;
- xmlFreeParserCtxt(ctxt);
- newDoc->intSubset = NULL;
- newDoc->extSubset = NULL;
- xmlFreeDoc(newDoc);
-
- return(ret);
-}
-
-/**
- * xmlParseExternalEntityPrivate:
- * @doc: the document the chunk pertains to
- * @oldctxt: the previous parser context if available
- * @sax: the SAX handler bloc (possibly NULL)
- * @user_data: The user data returned on SAX callbacks (possibly NULL)
- * @depth: Used for loop detection, use 0
- * @URL: the URL for the entity to load
- * @ID: the System ID for the entity to load
- * @list: the return value for the set of parsed nodes
- *
- * Private version of xmlParseExternalEntity()
- *
- * Returns 0 if the entity is well formed, -1 in case of args problem and
- * the parser error code otherwise
- */
-
-static int
-xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
- xmlSAXHandlerPtr sax,
- void *user_data, int depth, const xmlChar *URL,
- const xmlChar *ID, xmlNodePtr *list) {
- xmlParserCtxtPtr ctxt;
- xmlDocPtr newDoc;
- xmlSAXHandlerPtr oldsax = NULL;
- int ret = 0;
- xmlChar start[4];
- xmlCharEncoding enc;
-
- if (depth > 40) {
- return(XML_ERR_ENTITY_LOOP);
- }
-
-
-
- if (list != NULL)
- *list = NULL;
- if ((URL == NULL) && (ID == NULL))
- return(-1);
- if (doc == NULL) /* @@ relax but check for dereferences */
- return(-1);
-
-
- ctxt = xmlCreateEntityParserCtxt(URL, ID, NULL);
- if (ctxt == NULL) return(-1);
- ctxt->userData = ctxt;
- if (oldctxt != NULL) {
- ctxt->_private = oldctxt->_private;
- ctxt->loadsubset = oldctxt->loadsubset;
- ctxt->validate = oldctxt->validate;
- ctxt->external = oldctxt->external;
- } else {
- /*
- * Doing validity checking on chunk without context
- * doesn't make sense
- */
- ctxt->_private = NULL;
- ctxt->validate = 0;
- ctxt->external = 2;
- ctxt->loadsubset = 0;
- }
- if (sax != NULL) {
- oldsax = ctxt->sax;
- ctxt->sax = sax;
- if (user_data != NULL)
- ctxt->userData = user_data;
- }
- newDoc = xmlNewDoc(BAD_CAST "1.0");
- if (newDoc == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(-1);
- }
- if (doc != NULL) {
- newDoc->intSubset = doc->intSubset;
- newDoc->extSubset = doc->extSubset;
- }
- if (doc->URL != NULL) {
- newDoc->URL = xmlStrdup(doc->URL);
- }
- newDoc->children = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
- if (newDoc->children == NULL) {
- if (sax != NULL)
- ctxt->sax = oldsax;
- xmlFreeParserCtxt(ctxt);
- newDoc->intSubset = NULL;
- newDoc->extSubset = NULL;
- xmlFreeDoc(newDoc);
- return(-1);
- }
- nodePush(ctxt, newDoc->children);
- if (doc == NULL) {
- ctxt->myDoc = newDoc;
- } else {
- ctxt->myDoc = doc;
- newDoc->children->doc = doc;
- }
-
- /*
- * Get the 4 first bytes and decode the charset
- * if enc != XML_CHAR_ENCODING_NONE
- * plug some encoding conversion routines.
- */
- GROW;
- start[0] = RAW;
- start[1] = NXT(1);
- start[2] = NXT(2);
- start[3] = NXT(3);
- enc = xmlDetectCharEncoding(start, 4);
- if (enc != XML_CHAR_ENCODING_NONE) {
- xmlSwitchEncoding(ctxt, enc);
- }
-
- /*
- * Parse a possible text declaration first
- */
- if ((RAW == '<') && (NXT(1) == '?') &&
- (NXT(2) == 'x') && (NXT(3) == 'm') &&
- (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
- xmlParseTextDecl(ctxt);
- }
-
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->depth = depth;
-
- xmlParseContent(ctxt);
-
- if ((RAW == '<') && (NXT(1) == '/')) {
- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "chunk is not well balanced\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else if (RAW != 0) {
- ctxt->errNo = XML_ERR_EXTRA_CONTENT;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "extra content at the end of well balanced chunk\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- if (ctxt->node != newDoc->children) {
- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "chunk is not well balanced\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
- if (!ctxt->wellFormed) {
- if (ctxt->errNo == 0)
- ret = 1;
- else
- ret = ctxt->errNo;
- } else {
- if (list != NULL) {
- xmlNodePtr cur;
-
- /*
- * Return the newly created nodeset after unlinking it from
- * they pseudo parent.
- */
- cur = newDoc->children->children;
- *list = cur;
- while (cur != NULL) {
- cur->parent = NULL;
- cur = cur->next;
- }
- newDoc->children->children = NULL;
- }
- ret = 0;
- }
- if (sax != NULL)
- ctxt->sax = oldsax;
- xmlFreeParserCtxt(ctxt);
- newDoc->intSubset = NULL;
- newDoc->extSubset = NULL;
- xmlFreeDoc(newDoc);
-
- return(ret);
-}
-
-/**
- * xmlParseExternalEntity:
- * @doc: the document the chunk pertains to
- * @sax: the SAX handler bloc (possibly NULL)
- * @user_data: The user data returned on SAX callbacks (possibly NULL)
- * @depth: Used for loop detection, use 0
- * @URL: the URL for the entity to load
- * @ID: the System ID for the entity to load
- * @lst: the return value for the set of parsed nodes
- *
- * Parse an external general entity
- * An external general parsed entity is well-formed if it matches the
- * production labeled extParsedEnt.
- *
- * [78] extParsedEnt ::= TextDecl? content
- *
- * Returns 0 if the entity is well formed, -1 in case of args problem and
- * the parser error code otherwise
- */
-
-int
-xmlParseExternalEntity(xmlDocPtr doc, xmlSAXHandlerPtr sax, void *user_data,
- int depth, const xmlChar *URL, const xmlChar *ID, xmlNodePtr *lst) {
- return(xmlParseExternalEntityPrivate(doc, NULL, sax, user_data, depth, URL,
- ID, lst));
-}
-
-/**
- * xmlParseBalancedChunkMemory:
- * @doc: the document the chunk pertains to
- * @sax: the SAX handler bloc (possibly NULL)
- * @user_data: The user data returned on SAX callbacks (possibly NULL)
- * @depth: Used for loop detection, use 0
- * @string: the input string in UTF8 or ISO-Latin (zero terminated)
- * @lst: the return value for the set of parsed nodes
- *
- * Parse a well-balanced chunk of an XML document
- * called by the parser
- * The allowed sequence for the Well Balanced Chunk is the one defined by
- * the content production in the XML grammar:
- *
- * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
- *
- * Returns 0 if the chunk is well balanced, -1 in case of args problem and
- * the parser error code otherwise
- */
-
-int
-xmlParseBalancedChunkMemory(xmlDocPtr doc, xmlSAXHandlerPtr sax,
- void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst) {
- return xmlParseBalancedChunkMemoryRecover( doc, sax, user_data,
- depth, string, lst, 0 );
-}
-
-/**
- * xmlParseBalancedChunkMemoryInternal:
- * @oldctxt: the existing parsing context
- * @string: the input string in UTF8 or ISO-Latin (zero terminated)
- * @user_data: the user data field for the parser context
- * @lst: the return value for the set of parsed nodes
- *
- *
- * Parse a well-balanced chunk of an XML document
- * called by the parser
- * The allowed sequence for the Well Balanced Chunk is the one defined by
- * the content production in the XML grammar:
- *
- * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
- *
- * Returns 0 if the chunk is well balanced, -1 in case of args problem and
- * the parser error code otherwise
- *
- * In case recover is set to 1, the nodelist will not be empty even if
- * the parsed chunk is not well balanced.
- */
-static int
-xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
- const xmlChar *string, void *user_data, xmlNodePtr *lst) {
- xmlParserCtxtPtr ctxt;
- xmlDocPtr newDoc = NULL;
- xmlSAXHandlerPtr oldsax = NULL;
- xmlNodePtr content = NULL;
- int size;
- int ret = 0;
-
- if (oldctxt->depth > 40) {
- return(XML_ERR_ENTITY_LOOP);
- }
-
-
- if (lst != NULL)
- *lst = NULL;
- if (string == NULL)
- return(-1);
-
- size = xmlStrlen(string);
-
- ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
- if (ctxt == NULL) return(-1);
- if (user_data != NULL)
- ctxt->userData = user_data;
- else
- ctxt->userData = ctxt;
-
- oldsax = ctxt->sax;
- ctxt->sax = oldctxt->sax;
- ctxt->_private = oldctxt->_private;
- if (oldctxt->myDoc == NULL) {
- newDoc = xmlNewDoc(BAD_CAST "1.0");
- if (newDoc == NULL) {
- ctxt->sax = oldsax;
- xmlFreeParserCtxt(ctxt);
- return(-1);
- }
- ctxt->myDoc = newDoc;
- } else {
- ctxt->myDoc = oldctxt->myDoc;
- content = ctxt->myDoc->children;
- }
- ctxt->myDoc->children = xmlNewDocNode(ctxt->myDoc, NULL,
- BAD_CAST "pseudoroot", NULL);
- if (ctxt->myDoc->children == NULL) {
- ctxt->sax = oldsax;
- xmlFreeParserCtxt(ctxt);
- if (newDoc != NULL)
- xmlFreeDoc(newDoc);
- return(-1);
- }
- nodePush(ctxt, ctxt->myDoc->children);
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->depth = oldctxt->depth + 1;
-
- /*
- * Doing validity checking on chunk doesn't make sense
- */
- ctxt->validate = 0;
- ctxt->loadsubset = oldctxt->loadsubset;
-
- xmlParseContent(ctxt);
- if ((RAW == '<') && (NXT(1) == '/')) {
- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "chunk is not well balanced\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else if (RAW != 0) {
- ctxt->errNo = XML_ERR_EXTRA_CONTENT;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "extra content at the end of well balanced chunk\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- if (ctxt->node != ctxt->myDoc->children) {
- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "chunk is not well balanced\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
- if (!ctxt->wellFormed) {
- if (ctxt->errNo == 0)
- ret = 1;
- else
- ret = ctxt->errNo;
- } else {
- ret = 0;
- }
-
- if ((lst != NULL) && (ret == 0)) {
- xmlNodePtr cur;
-
- /*
- * Return the newly created nodeset after unlinking it from
- * they pseudo parent.
- */
- cur = ctxt->myDoc->children->children;
- *lst = cur;
- while (cur != NULL) {
- cur->parent = NULL;
- cur = cur->next;
- }
- ctxt->myDoc->children->children = NULL;
- }
- if (ctxt->myDoc != NULL) {
- xmlFreeNode(ctxt->myDoc->children);
- ctxt->myDoc->children = content;
- }
-
- ctxt->sax = oldsax;
- xmlFreeParserCtxt(ctxt);
- if (newDoc != NULL)
- xmlFreeDoc(newDoc);
-
- return(ret);
-}
-
-/**
- * xmlParseBalancedChunkMemoryRecover:
- * @doc: the document the chunk pertains to
- * @sax: the SAX handler bloc (possibly NULL)
- * @user_data: The user data returned on SAX callbacks (possibly NULL)
- * @depth: Used for loop detection, use 0
- * @string: the input string in UTF8 or ISO-Latin (zero terminated)
- * @lst: the return value for the set of parsed nodes
- * @recover: return nodes even if the data is broken (use 0)
- *
- *
- * Parse a well-balanced chunk of an XML document
- * called by the parser
- * The allowed sequence for the Well Balanced Chunk is the one defined by
- * the content production in the XML grammar:
- *
- * [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
- *
- * Returns 0 if the chunk is well balanced, -1 in case of args problem and
- * the parser error code otherwise
- *
- * In case recover is set to 1, the nodelist will not be empty even if
- * the parsed chunk is not well balanced.
- */
-int
-xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
- void *user_data, int depth, const xmlChar *string, xmlNodePtr *lst,
- int recover) {
- xmlParserCtxtPtr ctxt;
- xmlDocPtr newDoc;
- xmlSAXHandlerPtr oldsax = NULL;
- xmlNodePtr content;
- int size;
- int ret = 0;
-
- if (depth > 40) {
- return(XML_ERR_ENTITY_LOOP);
- }
-
-
- if (lst != NULL)
- *lst = NULL;
- if (string == NULL)
- return(-1);
-
- size = xmlStrlen(string);
-
- ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
- if (ctxt == NULL) return(-1);
- ctxt->userData = ctxt;
- if (sax != NULL) {
- oldsax = ctxt->sax;
- ctxt->sax = sax;
- if (user_data != NULL)
- ctxt->userData = user_data;
- }
- newDoc = xmlNewDoc(BAD_CAST "1.0");
- if (newDoc == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(-1);
- }
- if (doc != NULL) {
- newDoc->intSubset = doc->intSubset;
- newDoc->extSubset = doc->extSubset;
- }
- newDoc->children = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
- if (newDoc->children == NULL) {
- if (sax != NULL)
- ctxt->sax = oldsax;
- xmlFreeParserCtxt(ctxt);
- newDoc->intSubset = NULL;
- newDoc->extSubset = NULL;
- xmlFreeDoc(newDoc);
- return(-1);
- }
- nodePush(ctxt, newDoc->children);
- if (doc == NULL) {
- ctxt->myDoc = newDoc;
- } else {
- ctxt->myDoc = newDoc;
- newDoc->children->doc = doc;
- }
- ctxt->instate = XML_PARSER_CONTENT;
- ctxt->depth = depth;
-
- /*
- * Doing validity checking on chunk doesn't make sense
- */
- ctxt->validate = 0;
- ctxt->loadsubset = 0;
-
- if ( doc != NULL ){
- content = doc->children;
- doc->children = NULL;
- xmlParseContent(ctxt);
- doc->children = content;
- }
- else {
- xmlParseContent(ctxt);
- }
- if ((RAW == '<') && (NXT(1) == '/')) {
- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "chunk is not well balanced\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else if (RAW != 0) {
- ctxt->errNo = XML_ERR_EXTRA_CONTENT;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "extra content at the end of well balanced chunk\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- if (ctxt->node != newDoc->children) {
- ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "chunk is not well balanced\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
-
- if (!ctxt->wellFormed) {
- if (ctxt->errNo == 0)
- ret = 1;
- else
- ret = ctxt->errNo;
- } else {
- ret = 0;
- }
-
- if (lst != NULL && (ret == 0 || recover == 1)) {
- xmlNodePtr cur;
-
- /*
- * Return the newly created nodeset after unlinking it from
- * they pseudo parent.
- */
- cur = newDoc->children->children;
- *lst = cur;
- while (cur != NULL) {
- cur->parent = NULL;
- cur = cur->next;
- }
- newDoc->children->children = NULL;
- }
-
- if (sax != NULL)
- ctxt->sax = oldsax;
- xmlFreeParserCtxt(ctxt);
- newDoc->intSubset = NULL;
- newDoc->extSubset = NULL;
- xmlFreeDoc(newDoc);
-
- return(ret);
-}
-
-/**
- * xmlSAXParseEntity:
- * @sax: the SAX handler block
- * @filename: the filename
- *
- * parse an XML external entity out of context and build a tree.
- * It use the given SAX function block to handle the parsing callback.
- * If sax is NULL, fallback to the default DOM tree building routines.
- *
- * [78] extParsedEnt ::= TextDecl? content
- *
- * This correspond to a "Well Balanced" chunk
- *
- * Returns the resulting document tree
- */
-
-xmlDocPtr
-xmlSAXParseEntity(xmlSAXHandlerPtr sax, const char *filename) {
- xmlDocPtr ret;
- xmlParserCtxtPtr ctxt;
- char *directory = NULL;
-
- ctxt = xmlCreateFileParserCtxt(filename);
- if (ctxt == NULL) {
- return(NULL);
- }
- if (sax != NULL) {
- if (ctxt->sax != NULL)
- xmlFree(ctxt->sax);
- ctxt->sax = sax;
- ctxt->userData = NULL;
- }
-
- if ((ctxt->directory == NULL) && (directory == NULL))
- directory = xmlParserGetDirectory(filename);
-
- xmlParseExtParsedEnt(ctxt);
-
- if (ctxt->wellFormed)
- ret = ctxt->myDoc;
- else {
- ret = NULL;
- xmlFreeDoc(ctxt->myDoc);
- ctxt->myDoc = NULL;
- }
- if (sax != NULL)
- ctxt->sax = NULL;
- xmlFreeParserCtxt(ctxt);
-
- return(ret);
-}
-
-/**
- * xmlParseEntity:
- * @filename: the filename
- *
- * parse an XML external entity out of context and build a tree.
- *
- * [78] extParsedEnt ::= TextDecl? content
- *
- * This correspond to a "Well Balanced" chunk
- *
- * Returns the resulting document tree
- */
-
-xmlDocPtr
-xmlParseEntity(const char *filename) {
- return(xmlSAXParseEntity(NULL, filename));
-}
-
-/**
- * xmlCreateEntityParserCtxt:
- * @URL: the entity URL
- * @ID: the entity PUBLIC ID
- * @base: a possible base for the target URI
- *
- * Create a parser context for an external entity
- * Automatic support for ZLIB/Compress compressed document is provided
- * by default if found at compile-time.
- *
- * Returns the new parser context or NULL
- */
-xmlParserCtxtPtr
-xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
- const xmlChar *base) {
- xmlParserCtxtPtr ctxt;
- xmlParserInputPtr inputStream;
- char *directory = NULL;
- xmlChar *uri;
-
- ctxt = xmlNewParserCtxt();
- if (ctxt == NULL) {
- return(NULL);
- }
-
- uri = xmlBuildURI(URL, base);
-
- if (uri == NULL) {
- inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
- if (inputStream == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
-
- inputPush(ctxt, inputStream);
-
- if ((ctxt->directory == NULL) && (directory == NULL))
- directory = xmlParserGetDirectory((char *)URL);
- if ((ctxt->directory == NULL) && (directory != NULL))
- ctxt->directory = directory;
- } else {
- inputStream = xmlLoadExternalEntity((char *)uri, (char *)ID, ctxt);
- if (inputStream == NULL) {
- xmlFree(uri);
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
-
- inputPush(ctxt, inputStream);
-
- if ((ctxt->directory == NULL) && (directory == NULL))
- directory = xmlParserGetDirectory((char *)uri);
- if ((ctxt->directory == NULL) && (directory != NULL))
- ctxt->directory = directory;
- xmlFree(uri);
- }
-
- return(ctxt);
-}
-
-/************************************************************************
- * *
- * Front ends when parsing from a file *
- * *
- ************************************************************************/
-
-/**
- * xmlCreateFileParserCtxt:
- * @filename: the filename
- *
- * Create a parser context for a file content.
- * Automatic support for ZLIB/Compress compressed document is provided
- * by default if found at compile-time.
- *
- * Returns the new parser context or NULL
- */
-xmlParserCtxtPtr
-xmlCreateFileParserCtxt(const char *filename)
-{
- xmlParserCtxtPtr ctxt;
- xmlParserInputPtr inputStream;
- char *directory = NULL;
- xmlChar *normalized;
-
- ctxt = xmlNewParserCtxt();
- if (ctxt == NULL) {
- if (xmlDefaultSAXHandler.error != NULL) {
- xmlDefaultSAXHandler.error(NULL, "out of memory\n");
- }
- return(NULL);
- }
-
- normalized = xmlNormalizeWindowsPath((const xmlChar *) filename);
- if (normalized == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
- inputStream = xmlLoadExternalEntity((char *) normalized, NULL, ctxt);
- if (inputStream == NULL) {
- xmlFreeParserCtxt(ctxt);
- xmlFree(normalized);
- return(NULL);
- }
-
- inputPush(ctxt, inputStream);
- if ((ctxt->directory == NULL) && (directory == NULL))
- directory = xmlParserGetDirectory((char *) normalized);
- if ((ctxt->directory == NULL) && (directory != NULL))
- ctxt->directory = directory;
-
- xmlFree(normalized);
-
- return(ctxt);
-}
-
-/**
- * xmlSAXParseFileWithData:
- * @sax: the SAX handler block
- * @filename: the filename
- * @recovery: work in recovery mode, i.e. tries to read no Well Formed
- * documents
- * @data: the userdata
- *
- * parse an XML file and build a tree. Automatic support for ZLIB/Compress
- * compressed document is provided by default if found at compile-time.
- * It use the given SAX function block to handle the parsing callback.
- * If sax is NULL, fallback to the default DOM tree building routines.
- *
- * User data (void *) is stored within the parser context in the
- * context's _private member, so it is available nearly everywhere in libxml
- *
- * Returns the resulting document tree
- */
-
-xmlDocPtr
-xmlSAXParseFileWithData(xmlSAXHandlerPtr sax, const char *filename,
- int recovery, void *data) {
- xmlDocPtr ret;
- xmlParserCtxtPtr ctxt;
- char *directory = NULL;
-
- xmlInitParser();
-
- ctxt = xmlCreateFileParserCtxt(filename);
- if (ctxt == NULL) {
- return(NULL);
- }
- if (sax != NULL) {
- if (ctxt->sax != NULL)
- xmlFree(ctxt->sax);
- ctxt->sax = sax;
- }
- if (data!=NULL) {
- ctxt->_private=data;
- }
-
- if ((ctxt->directory == NULL) && (directory == NULL))
- directory = xmlParserGetDirectory(filename);
- if ((ctxt->directory == NULL) && (directory != NULL))
- ctxt->directory = (char *) xmlStrdup((xmlChar *) directory);
-
- ctxt->recovery = recovery;
-
- xmlParseDocument(ctxt);
-
- if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
- else {
- ret = NULL;
- xmlFreeDoc(ctxt->myDoc);
- ctxt->myDoc = NULL;
- }
- if (sax != NULL)
- ctxt->sax = NULL;
- xmlFreeParserCtxt(ctxt);
-
- return(ret);
-}
-
-/**
- * xmlSAXParseFile:
- * @sax: the SAX handler block
- * @filename: the filename
- * @recovery: work in recovery mode, i.e. tries to read no Well Formed
- * documents
- *
- * parse an XML file and build a tree. Automatic support for ZLIB/Compress
- * compressed document is provided by default if found at compile-time.
- * It use the given SAX function block to handle the parsing callback.
- * If sax is NULL, fallback to the default DOM tree building routines.
- *
- * Returns the resulting document tree
- */
-
-xmlDocPtr
-xmlSAXParseFile(xmlSAXHandlerPtr sax, const char *filename,
- int recovery) {
- return(xmlSAXParseFileWithData(sax,filename,recovery,NULL));
-}
-
-/**
- * xmlRecoverDoc:
- * @cur: a pointer to an array of xmlChar
- *
- * parse an XML in-memory document and build a tree.
- * In the case the document is not Well Formed, a tree is built anyway
- *
- * Returns the resulting document tree
- */
-
-xmlDocPtr
-xmlRecoverDoc(xmlChar *cur) {
- return(xmlSAXParseDoc(NULL, cur, 1));
-}
-
-/**
- * xmlParseFile:
- * @filename: the filename
- *
- * parse an XML file and build a tree. Automatic support for ZLIB/Compress
- * compressed document is provided by default if found at compile-time.
- *
- * Returns the resulting document tree if the file was wellformed,
- * NULL otherwise.
- */
-
-xmlDocPtr
-xmlParseFile(const char *filename) {
- return(xmlSAXParseFile(NULL, filename, 0));
-}
-
-/**
- * xmlRecoverFile:
- * @filename: the filename
- *
- * parse an XML file and build a tree. Automatic support for ZLIB/Compress
- * compressed document is provided by default if found at compile-time.
- * In the case the document is not Well Formed, a tree is built anyway
- *
- * Returns the resulting document tree
- */
-
-xmlDocPtr
-xmlRecoverFile(const char *filename) {
- return(xmlSAXParseFile(NULL, filename, 1));
-}
-
-
-/**
- * xmlSetupParserForBuffer:
- * @ctxt: an XML parser context
- * @buffer: a xmlChar * buffer
- * @filename: a file name
- *
- * Setup the parser context to parse a new buffer; Clears any prior
- * contents from the parser context. The buffer parameter must not be
- * NULL, but the filename parameter can be
- */
-void
-xmlSetupParserForBuffer(xmlParserCtxtPtr ctxt, const xmlChar* buffer,
- const char* filename)
-{
- xmlParserInputPtr input;
-
- input = xmlNewInputStream(ctxt);
- if (input == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc");
- xmlFree(ctxt);
- return;
- }
-
- xmlClearParserCtxt(ctxt);
- if (filename != NULL)
- input->filename = xmlMemStrdup(filename);
- input->base = buffer;
- input->cur = buffer;
- input->end = &buffer[xmlStrlen(buffer)];
- inputPush(ctxt, input);
-}
-
-/**
- * xmlSAXUserParseFile:
- * @sax: a SAX handler
- * @user_data: The user data returned on SAX callbacks
- * @filename: a file name
- *
- * parse an XML file and call the given SAX handler routines.
- * Automatic support for ZLIB/Compress compressed document is provided
- *
- * Returns 0 in case of success or a error number otherwise
- */
-int
-xmlSAXUserParseFile(xmlSAXHandlerPtr sax, void *user_data,
- const char *filename) {
- int ret = 0;
- xmlParserCtxtPtr ctxt;
-
- ctxt = xmlCreateFileParserCtxt(filename);
- if (ctxt == NULL) return -1;
- if (ctxt->sax != &xmlDefaultSAXHandler)
- xmlFree(ctxt->sax);
- ctxt->sax = sax;
- if (user_data != NULL)
- ctxt->userData = user_data;
-
- xmlParseDocument(ctxt);
-
- if (ctxt->wellFormed)
- ret = 0;
- else {
- if (ctxt->errNo != 0)
- ret = ctxt->errNo;
- else
- ret = -1;
- }
- if (sax != NULL)
- ctxt->sax = NULL;
- xmlFreeParserCtxt(ctxt);
-
- return ret;
-}
-
-/************************************************************************
- * *
- * Front ends when parsing from memory *
- * *
- ************************************************************************/
-
-/**
- * xmlCreateMemoryParserCtxt:
- * @buffer: a pointer to a char array
- * @size: the size of the array
- *
- * Create a parser context for an XML in-memory document.
- *
- * Returns the new parser context or NULL
- */
-xmlParserCtxtPtr
-xmlCreateMemoryParserCtxt(const char *buffer, int size) {
- xmlParserCtxtPtr ctxt;
- xmlParserInputPtr input;
- xmlParserInputBufferPtr buf;
-
- if (buffer == NULL)
- return(NULL);
- if (size <= 0)
- return(NULL);
-
- ctxt = xmlNewParserCtxt();
- if (ctxt == NULL)
- return(NULL);
-
- buf = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE);
- if (buf == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
-
- input = xmlNewInputStream(ctxt);
- if (input == NULL) {
- xmlFreeParserInputBuffer(buf);
- xmlFreeParserCtxt(ctxt);
- return(NULL);
- }
-
- input->filename = NULL;
- input->buf = buf;
- input->base = input->buf->buffer->content;
- input->cur = input->buf->buffer->content;
- input->end = &input->buf->buffer->content[input->buf->buffer->use];
-
- inputPush(ctxt, input);
- return(ctxt);
-}
-
-/**
- * xmlSAXParseMemoryWithData:
- * @sax: the SAX handler block
- * @buffer: an pointer to a char array
- * @size: the size of the array
- * @recovery: work in recovery mode, i.e. tries to read no Well Formed
- * documents
- * @data: the userdata
- *
- * parse an XML in-memory block and use the given SAX function block
- * to handle the parsing callback. If sax is NULL, fallback to the default
- * DOM tree building routines.
- *
- * User data (void *) is stored within the parser context in the
- * context's _private member, so it is available nearly everywhere in libxml
- *
- * Returns the resulting document tree
- */
-
-xmlDocPtr
-xmlSAXParseMemoryWithData(xmlSAXHandlerPtr sax, const char *buffer,
- int size, int recovery, void *data) {
- xmlDocPtr ret;
- xmlParserCtxtPtr ctxt;
-
- ctxt = xmlCreateMemoryParserCtxt(buffer, size);
- if (ctxt == NULL) return(NULL);
- if (sax != NULL) {
- if (ctxt->sax != NULL)
- xmlFree(ctxt->sax);
- ctxt->sax = sax;
- }
- if (data!=NULL) {
- ctxt->_private=data;
- }
-
- xmlParseDocument(ctxt);
-
- if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
- else {
- ret = NULL;
- xmlFreeDoc(ctxt->myDoc);
- ctxt->myDoc = NULL;
- }
- if (sax != NULL)
- ctxt->sax = NULL;
- xmlFreeParserCtxt(ctxt);
-
- return(ret);
-}
-
-/**
- * xmlSAXParseMemory:
- * @sax: the SAX handler block
- * @buffer: an pointer to a char array
- * @size: the size of the array
- * @recovery: work in recovery mode, i.e. tries to read not Well Formed
- * documents
- *
- * parse an XML in-memory block and use the given SAX function block
- * to handle the parsing callback. If sax is NULL, fallback to the default
- * DOM tree building routines.
- *
- * Returns the resulting document tree
- */
-xmlDocPtr
-xmlSAXParseMemory(xmlSAXHandlerPtr sax, const char *buffer,
- int size, int recovery) {
- return xmlSAXParseMemoryWithData(sax, buffer, size, recovery, NULL);
-}
-
-/**
- * xmlParseMemory:
- * @buffer: an pointer to a char array
- * @size: the size of the array
- *
- * parse an XML in-memory block and build a tree.
- *
- * Returns the resulting document tree
- */
-
-xmlDocPtr xmlParseMemory(const char *buffer, int size) {
- return(xmlSAXParseMemory(NULL, buffer, size, 0));
-}
-
-/**
- * xmlRecoverMemory:
- * @buffer: an pointer to a char array
- * @size: the size of the array
- *
- * parse an XML in-memory block and build a tree.
- * In the case the document is not Well Formed, a tree is built anyway
- *
- * Returns the resulting document tree
- */
-
-xmlDocPtr xmlRecoverMemory(const char *buffer, int size) {
- return(xmlSAXParseMemory(NULL, buffer, size, 1));
-}
-
-/**
- * xmlSAXUserParseMemory:
- * @sax: a SAX handler
- * @user_data: The user data returned on SAX callbacks
- * @buffer: an in-memory XML document input
- * @size: the length of the XML document in bytes
- *
- * A better SAX parsing routine.
- * parse an XML in-memory buffer and call the given SAX handler routines.
- *
- * Returns 0 in case of success or a error number otherwise
- */
-int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
- const char *buffer, int size) {
- int ret = 0;
- xmlParserCtxtPtr ctxt;
- xmlSAXHandlerPtr oldsax = NULL;
-
- if (sax == NULL) return -1;
- ctxt = xmlCreateMemoryParserCtxt(buffer, size);
- if (ctxt == NULL) return -1;
- oldsax = ctxt->sax;
- ctxt->sax = sax;
- if (user_data != NULL)
- ctxt->userData = user_data;
-
- xmlParseDocument(ctxt);
-
- if (ctxt->wellFormed)
- ret = 0;
- else {
- if (ctxt->errNo != 0)
- ret = ctxt->errNo;
- else
- ret = -1;
- }
- ctxt->sax = oldsax;
- xmlFreeParserCtxt(ctxt);
-
- return ret;
-}
-
-/**
- * xmlCreateDocParserCtxt:
- * @cur: a pointer to an array of xmlChar
- *
- * Creates a parser context for an XML in-memory document.
- *
- * Returns the new parser context or NULL
- */
-xmlParserCtxtPtr
-xmlCreateDocParserCtxt(xmlChar *cur) {
- int len;
-
- if (cur == NULL)
- return(NULL);
- len = xmlStrlen(cur);
- return(xmlCreateMemoryParserCtxt((char *)cur, len));
-}
-
-/**
- * xmlSAXParseDoc:
- * @sax: the SAX handler block
- * @cur: a pointer to an array of xmlChar
- * @recovery: work in recovery mode, i.e. tries to read no Well Formed
- * documents
- *
- * parse an XML in-memory document and build a tree.
- * It use the given SAX function block to handle the parsing callback.
- * If sax is NULL, fallback to the default DOM tree building routines.
- *
- * Returns the resulting document tree
- */
-
-xmlDocPtr
-xmlSAXParseDoc(xmlSAXHandlerPtr sax, xmlChar *cur, int recovery) {
- xmlDocPtr ret;
- xmlParserCtxtPtr ctxt;
-
- if (cur == NULL) return(NULL);
-
-
- ctxt = xmlCreateDocParserCtxt(cur);
- if (ctxt == NULL) return(NULL);
- if (sax != NULL) {
- ctxt->sax = sax;
- ctxt->userData = NULL;
- }
-
- xmlParseDocument(ctxt);
- if ((ctxt->wellFormed) || recovery) ret = ctxt->myDoc;
- else {
- ret = NULL;
- xmlFreeDoc(ctxt->myDoc);
- ctxt->myDoc = NULL;
- }
- if (sax != NULL)
- ctxt->sax = NULL;
- xmlFreeParserCtxt(ctxt);
-
- return(ret);
-}
-
-/**
- * xmlParseDoc:
- * @cur: a pointer to an array of xmlChar
- *
- * parse an XML in-memory document and build a tree.
- *
- * Returns the resulting document tree
- */
-
-xmlDocPtr
-xmlParseDoc(xmlChar *cur) {
- return(xmlSAXParseDoc(NULL, cur, 0));
-}
-
-/************************************************************************
- * *
- * Specific function to keep track of entities references *
- * and used by the XSLT debugger *
- * *
- ************************************************************************/
-
-static xmlEntityReferenceFunc xmlEntityRefFunc = NULL;
-
-/**
- * xmlAddEntityReference:
- * @ent : A valid entity
- * @firstNode : A valid first node for children of entity
- * @lastNode : A valid last node of children entity
- *
- * Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
- */
-static void
-xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode,
- xmlNodePtr lastNode)
-{
- if (xmlEntityRefFunc != NULL) {
- (*xmlEntityRefFunc) (ent, firstNode, lastNode);
- }
-}
-
-
-/**
- * xmlSetEntityReferenceFunc:
- * @func: A valid function
- *
- * Set the function to call call back when a xml reference has been made
- */
-void
-xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
-{
- xmlEntityRefFunc = func;
-}
-
-/************************************************************************
- * *
- * Miscellaneous *
- * *
- ************************************************************************/
-
-#ifdef LIBXML_XPATH_ENABLED
-#include <libxml/xpath.h>
-#endif
-
-extern void xmlGenericErrorDefaultFunc(void *ctx, const char *msg, ...);
-static int xmlParserInitialized = 0;
-
-/**
- * xmlInitParser:
- *
- * Initialization function for the XML parser.
- * This is not reentrant. Call once before processing in case of
- * use in multithreaded programs.
- */
-
-void
-xmlInitParser(void) {
- if (xmlParserInitialized != 0)
- return;
-
- if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
- (xmlGenericError == NULL))
- initGenericErrorDefaultFunc(NULL);
- xmlInitThreads();
- xmlInitMemory();
- xmlInitCharEncodingHandlers();
- xmlInitializePredefinedEntities();
- xmlDefaultSAXHandlerInit();
- xmlRegisterDefaultInputCallbacks();
- xmlRegisterDefaultOutputCallbacks();
-#ifdef LIBXML_HTML_ENABLED
- htmlInitAutoClose();
- htmlDefaultSAXHandlerInit();
-#endif
-#ifdef LIBXML_XPATH_ENABLED
- xmlXPathInit();
-#endif
- xmlParserInitialized = 1;
-}
-
-/**
- * xmlCleanupParser:
- *
- * Cleanup function for the XML parser. It tries to reclaim all
- * parsing related global memory allocated for the parser processing.
- * It doesn't deallocate any document related memory. Calling this
- * function should not prevent reusing the parser.
- */
-
-void
-xmlCleanupParser(void) {
- xmlCleanupCharEncodingHandlers();
- xmlCleanupPredefinedEntities();
-#ifdef LIBXML_CATALOG_ENABLED
- xmlCatalogCleanup();
-#endif
- xmlCleanupThreads();
- xmlParserInitialized = 0;
-}
diff --git a/bundle/libxml/parserInternals.c b/bundle/libxml/parserInternals.c
deleted file mode 100644
index 65551441ee..0000000000
--- a/bundle/libxml/parserInternals.c
+++ /dev/null
@@ -1,3481 +0,0 @@
-/*
- * parserInternals.c : Internal routines (and obsolete ones) needed for the
- * XML and HTML parsers.
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#if defined(WIN32) && !defined (__CYGWIN__)
-#define XML_DIR_SEP '\\'
-#else
-#define XML_DIR_SEP '/'
-#endif
-
-#include <string.h>
-#ifdef HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include <libxml/xmlmemory.h>
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/parserInternals.h>
-#include <libxml/valid.h>
-#include <libxml/entities.h>
-#include <libxml/xmlerror.h>
-#include <libxml/encoding.h>
-#include <libxml/valid.h>
-#include <libxml/xmlIO.h>
-#include <libxml/uri.h>
-#include <libxml/SAX.h>
-#ifdef LIBXML_CATALOG_ENABLED
-#include <libxml/catalog.h>
-#endif
-#include <libxml/globals.h>
-
-void xmlUpgradeOldNs(xmlDocPtr doc);
-
-/*
- * Various global defaults for parsing
- */
-
-/**
- * xmlCheckVersion:
- * @version: the include version number
- *
- * check the compiled lib version against the include one.
- * This can warn or immediately kill the application
- */
-void
-xmlCheckVersion(int version) {
- int myversion = (int) LIBXML_VERSION;
-
- xmlInitParser();
-
- if ((myversion / 10000) != (version / 10000)) {
- xmlGenericError(xmlGenericErrorContext,
- "Fatal: program compiled against libxml %d using libxml %d\n",
- (version / 10000), (myversion / 10000));
- fprintf(stderr,
- "Fatal: program compiled against libxml %d using libxml %d\n",
- (version / 10000), (myversion / 10000));
- }
- if ((myversion / 100) < (version / 100)) {
- xmlGenericError(xmlGenericErrorContext,
- "Warning: program compiled against libxml %d using older %d\n",
- (version / 100), (myversion / 100));
- }
-}
-
-
-static const char *xmlFeaturesList[] = {
- "validate",
- "load subset",
- "keep blanks",
- "disable SAX",
- "fetch external entities",
- "substitute entities",
- "gather line info",
- "user data",
- "is html",
- "is standalone",
- "stop parser",
- "document",
- "is well formed",
- "is valid",
- "SAX block",
- "SAX function internalSubset",
- "SAX function isStandalone",
- "SAX function hasInternalSubset",
- "SAX function hasExternalSubset",
- "SAX function resolveEntity",
- "SAX function getEntity",
- "SAX function entityDecl",
- "SAX function notationDecl",
- "SAX function attributeDecl",
- "SAX function elementDecl",
- "SAX function unparsedEntityDecl",
- "SAX function setDocumentLocator",
- "SAX function startDocument",
- "SAX function endDocument",
- "SAX function startElement",
- "SAX function endElement",
- "SAX function reference",
- "SAX function characters",
- "SAX function ignorableWhitespace",
- "SAX function processingInstruction",
- "SAX function comment",
- "SAX function warning",
- "SAX function error",
- "SAX function fatalError",
- "SAX function getParameterEntity",
- "SAX function cdataBlock",
- "SAX function externalSubset",
-};
-
-/**
- * xmlGetFeaturesList:
- * @len: the length of the features name array (input/output)
- * @result: an array of string to be filled with the features name.
- *
- * Copy at most *@len feature names into the @result array
- *
- * Returns -1 in case or error, or the total number of features,
- * len is updated with the number of strings copied,
- * strings must not be deallocated
- */
-int
-xmlGetFeaturesList(int *len, const char **result) {
- int ret, i;
-
- ret = sizeof(xmlFeaturesList)/sizeof(xmlFeaturesList[0]);
- if ((len == NULL) || (result == NULL))
- return(ret);
- if ((*len < 0) || (*len >= 1000))
- return(-1);
- if (*len > ret)
- *len = ret;
- for (i = 0;i < *len;i++)
- result[i] = xmlFeaturesList[i];
- return(ret);
-}
-
-/**
- * xmlGetFeature:
- * @ctxt: an XML/HTML parser context
- * @name: the feature name
- * @result: location to store the result
- *
- * Read the current value of one feature of this parser instance
- *
- * Returns -1 in case or error, 0 otherwise
- */
-int
-xmlGetFeature(xmlParserCtxtPtr ctxt, const char *name, void *result) {
- if ((ctxt == NULL) || (name == NULL) || (result == NULL))
- return(-1);
-
- if (!strcmp(name, "validate")) {
- *((int *) result) = ctxt->validate;
- } else if (!strcmp(name, "keep blanks")) {
- *((int *) result) = ctxt->keepBlanks;
- } else if (!strcmp(name, "disable SAX")) {
- *((int *) result) = ctxt->disableSAX;
- } else if (!strcmp(name, "fetch external entities")) {
- *((int *) result) = ctxt->loadsubset;
- } else if (!strcmp(name, "substitute entities")) {
- *((int *) result) = ctxt->replaceEntities;
- } else if (!strcmp(name, "gather line info")) {
- *((int *) result) = ctxt->record_info;
- } else if (!strcmp(name, "user data")) {
- *((void **)result) = ctxt->userData;
- } else if (!strcmp(name, "is html")) {
- *((int *) result) = ctxt->html;
- } else if (!strcmp(name, "is standalone")) {
- *((int *) result) = ctxt->standalone;
- } else if (!strcmp(name, "document")) {
- *((xmlDocPtr *) result) = ctxt->myDoc;
- } else if (!strcmp(name, "is well formed")) {
- *((int *) result) = ctxt->wellFormed;
- } else if (!strcmp(name, "is valid")) {
- *((int *) result) = ctxt->valid;
- } else if (!strcmp(name, "SAX block")) {
- *((xmlSAXHandlerPtr *) result) = ctxt->sax;
- } else if (!strcmp(name, "SAX function internalSubset")) {
- *((internalSubsetSAXFunc *) result) = ctxt->sax->internalSubset;
- } else if (!strcmp(name, "SAX function isStandalone")) {
- *((isStandaloneSAXFunc *) result) = ctxt->sax->isStandalone;
- } else if (!strcmp(name, "SAX function hasInternalSubset")) {
- *((hasInternalSubsetSAXFunc *) result) = ctxt->sax->hasInternalSubset;
- } else if (!strcmp(name, "SAX function hasExternalSubset")) {
- *((hasExternalSubsetSAXFunc *) result) = ctxt->sax->hasExternalSubset;
- } else if (!strcmp(name, "SAX function resolveEntity")) {
- *((resolveEntitySAXFunc *) result) = ctxt->sax->resolveEntity;
- } else if (!strcmp(name, "SAX function getEntity")) {
- *((getEntitySAXFunc *) result) = ctxt->sax->getEntity;
- } else if (!strcmp(name, "SAX function entityDecl")) {
- *((entityDeclSAXFunc *) result) = ctxt->sax->entityDecl;
- } else if (!strcmp(name, "SAX function notationDecl")) {
- *((notationDeclSAXFunc *) result) = ctxt->sax->notationDecl;
- } else if (!strcmp(name, "SAX function attributeDecl")) {
- *((attributeDeclSAXFunc *) result) = ctxt->sax->attributeDecl;
- } else if (!strcmp(name, "SAX function elementDecl")) {
- *((elementDeclSAXFunc *) result) = ctxt->sax->elementDecl;
- } else if (!strcmp(name, "SAX function unparsedEntityDecl")) {
- *((unparsedEntityDeclSAXFunc *) result) = ctxt->sax->unparsedEntityDecl;
- } else if (!strcmp(name, "SAX function setDocumentLocator")) {
- *((setDocumentLocatorSAXFunc *) result) = ctxt->sax->setDocumentLocator;
- } else if (!strcmp(name, "SAX function startDocument")) {
- *((startDocumentSAXFunc *) result) = ctxt->sax->startDocument;
- } else if (!strcmp(name, "SAX function endDocument")) {
- *((endDocumentSAXFunc *) result) = ctxt->sax->endDocument;
- } else if (!strcmp(name, "SAX function startElement")) {
- *((startElementSAXFunc *) result) = ctxt->sax->startElement;
- } else if (!strcmp(name, "SAX function endElement")) {
- *((endElementSAXFunc *) result) = ctxt->sax->endElement;
- } else if (!strcmp(name, "SAX function reference")) {
- *((referenceSAXFunc *) result) = ctxt->sax->reference;
- } else if (!strcmp(name, "SAX function characters")) {
- *((charactersSAXFunc *) result) = ctxt->sax->characters;
- } else if (!strcmp(name, "SAX function ignorableWhitespace")) {
- *((ignorableWhitespaceSAXFunc *) result) = ctxt->sax->ignorableWhitespace;
- } else if (!strcmp(name, "SAX function processingInstruction")) {
- *((processingInstructionSAXFunc *) result) = ctxt->sax->processingInstruction;
- } else if (!strcmp(name, "SAX function comment")) {
- *((commentSAXFunc *) result) = ctxt->sax->comment;
- } else if (!strcmp(name, "SAX function warning")) {
- *((warningSAXFunc *) result) = ctxt->sax->warning;
- } else if (!strcmp(name, "SAX function error")) {
- *((errorSAXFunc *) result) = ctxt->sax->error;
- } else if (!strcmp(name, "SAX function fatalError")) {
- *((fatalErrorSAXFunc *) result) = ctxt->sax->fatalError;
- } else if (!strcmp(name, "SAX function getParameterEntity")) {
- *((getParameterEntitySAXFunc *) result) = ctxt->sax->getParameterEntity;
- } else if (!strcmp(name, "SAX function cdataBlock")) {
- *((cdataBlockSAXFunc *) result) = ctxt->sax->cdataBlock;
- } else if (!strcmp(name, "SAX function externalSubset")) {
- *((externalSubsetSAXFunc *) result) = ctxt->sax->externalSubset;
- } else {
- return(-1);
- }
- return(0);
-}
-
-/**
- * xmlSetFeature:
- * @ctxt: an XML/HTML parser context
- * @name: the feature name
- * @value: pointer to the location of the new value
- *
- * Change the current value of one feature of this parser instance
- *
- * Returns -1 in case or error, 0 otherwise
- */
-int
-xmlSetFeature(xmlParserCtxtPtr ctxt, const char *name, void *value) {
- if ((ctxt == NULL) || (name == NULL) || (value == NULL))
- return(-1);
-
- if (!strcmp(name, "validate")) {
- int newvalidate = *((int *) value);
- if ((!ctxt->validate) && (newvalidate != 0)) {
- if (ctxt->vctxt.warning == NULL)
- ctxt->vctxt.warning = xmlParserValidityWarning;
- if (ctxt->vctxt.error == NULL)
- ctxt->vctxt.error = xmlParserValidityError;
- ctxt->vctxt.nodeMax = 0;
- }
- ctxt->validate = newvalidate;
- } else if (!strcmp(name, "keep blanks")) {
- ctxt->keepBlanks = *((int *) value);
- } else if (!strcmp(name, "disable SAX")) {
- ctxt->disableSAX = *((int *) value);
- } else if (!strcmp(name, "fetch external entities")) {
- ctxt->loadsubset = *((int *) value);
- } else if (!strcmp(name, "substitute entities")) {
- ctxt->replaceEntities = *((int *) value);
- } else if (!strcmp(name, "gather line info")) {
- ctxt->record_info = *((int *) value);
- } else if (!strcmp(name, "user data")) {
- ctxt->userData = *((void **)value);
- } else if (!strcmp(name, "is html")) {
- ctxt->html = *((int *) value);
- } else if (!strcmp(name, "is standalone")) {
- ctxt->standalone = *((int *) value);
- } else if (!strcmp(name, "document")) {
- ctxt->myDoc = *((xmlDocPtr *) value);
- } else if (!strcmp(name, "is well formed")) {
- ctxt->wellFormed = *((int *) value);
- } else if (!strcmp(name, "is valid")) {
- ctxt->valid = *((int *) value);
- } else if (!strcmp(name, "SAX block")) {
- ctxt->sax = *((xmlSAXHandlerPtr *) value);
- } else if (!strcmp(name, "SAX function internalSubset")) {
- ctxt->sax->internalSubset = *((internalSubsetSAXFunc *) value);
- } else if (!strcmp(name, "SAX function isStandalone")) {
- ctxt->sax->isStandalone = *((isStandaloneSAXFunc *) value);
- } else if (!strcmp(name, "SAX function hasInternalSubset")) {
- ctxt->sax->hasInternalSubset = *((hasInternalSubsetSAXFunc *) value);
- } else if (!strcmp(name, "SAX function hasExternalSubset")) {
- ctxt->sax->hasExternalSubset = *((hasExternalSubsetSAXFunc *) value);
- } else if (!strcmp(name, "SAX function resolveEntity")) {
- ctxt->sax->resolveEntity = *((resolveEntitySAXFunc *) value);
- } else if (!strcmp(name, "SAX function getEntity")) {
- ctxt->sax->getEntity = *((getEntitySAXFunc *) value);
- } else if (!strcmp(name, "SAX function entityDecl")) {
- ctxt->sax->entityDecl = *((entityDeclSAXFunc *) value);
- } else if (!strcmp(name, "SAX function notationDecl")) {
- ctxt->sax->notationDecl = *((notationDeclSAXFunc *) value);
- } else if (!strcmp(name, "SAX function attributeDecl")) {
- ctxt->sax->attributeDecl = *((attributeDeclSAXFunc *) value);
- } else if (!strcmp(name, "SAX function elementDecl")) {
- ctxt->sax->elementDecl = *((elementDeclSAXFunc *) value);
- } else if (!strcmp(name, "SAX function unparsedEntityDecl")) {
- ctxt->sax->unparsedEntityDecl = *((unparsedEntityDeclSAXFunc *) value);
- } else if (!strcmp(name, "SAX function setDocumentLocator")) {
- ctxt->sax->setDocumentLocator = *((setDocumentLocatorSAXFunc *) value);
- } else if (!strcmp(name, "SAX function startDocument")) {
- ctxt->sax->startDocument = *((startDocumentSAXFunc *) value);
- } else if (!strcmp(name, "SAX function endDocument")) {
- ctxt->sax->endDocument = *((endDocumentSAXFunc *) value);
- } else if (!strcmp(name, "SAX function startElement")) {
- ctxt->sax->startElement = *((startElementSAXFunc *) value);
- } else if (!strcmp(name, "SAX function endElement")) {
- ctxt->sax->endElement = *((endElementSAXFunc *) value);
- } else if (!strcmp(name, "SAX function reference")) {
- ctxt->sax->reference = *((referenceSAXFunc *) value);
- } else if (!strcmp(name, "SAX function characters")) {
- ctxt->sax->characters = *((charactersSAXFunc *) value);
- } else if (!strcmp(name, "SAX function ignorableWhitespace")) {
- ctxt->sax->ignorableWhitespace = *((ignorableWhitespaceSAXFunc *) value);
- } else if (!strcmp(name, "SAX function processingInstruction")) {
- ctxt->sax->processingInstruction = *((processingInstructionSAXFunc *) value);
- } else if (!strcmp(name, "SAX function comment")) {
- ctxt->sax->comment = *((commentSAXFunc *) value);
- } else if (!strcmp(name, "SAX function warning")) {
- ctxt->sax->warning = *((warningSAXFunc *) value);
- } else if (!strcmp(name, "SAX function error")) {
- ctxt->sax->error = *((errorSAXFunc *) value);
- } else if (!strcmp(name, "SAX function fatalError")) {
- ctxt->sax->fatalError = *((fatalErrorSAXFunc *) value);
- } else if (!strcmp(name, "SAX function getParameterEntity")) {
- ctxt->sax->getParameterEntity = *((getParameterEntitySAXFunc *) value);
- } else if (!strcmp(name, "SAX function cdataBlock")) {
- ctxt->sax->cdataBlock = *((cdataBlockSAXFunc *) value);
- } else if (!strcmp(name, "SAX function externalSubset")) {
- ctxt->sax->externalSubset = *((externalSubsetSAXFunc *) value);
- } else {
- return(-1);
- }
- return(0);
-}
-
-/************************************************************************
- * *
- * Some functions to avoid too large macros *
- * *
- ************************************************************************/
-
-/**
- * xmlIsChar:
- * @c: an unicode character (int)
- *
- * Check whether the character is allowed by the production
- * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
- * | [#x10000-#x10FFFF]
- * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
- * Also available as a macro IS_CHAR()
- *
- * Returns 0 if not, non-zero otherwise
- */
-int
-xmlIsChar(int c) {
- return(
- ((c) == 0x09) || ((c) == 0x0A) || ((c) == 0x0D) ||
- (((c) >= 0x20) && ((c) <= 0xD7FF)) ||
- (((c) >= 0xE000) && ((c) <= 0xFFFD)) ||
- (((c) >= 0x10000) && ((c) <= 0x10FFFF)));
-}
-
-/**
- * xmlIsBlank:
- * @c: an unicode character (int)
- *
- * Check whether the character is allowed by the production
- * [3] S ::= (#x20 | #x9 | #xD | #xA)+
- * Also available as a macro IS_BLANK()
- *
- * Returns 0 if not, non-zero otherwise
- */
-int
-xmlIsBlank(int c) {
- return(((c) == 0x20) || ((c) == 0x09) || ((c) == 0xA) || ((c) == 0x0D));
-}
-
-static int xmlBaseArray[] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0000 - 0x000F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0010 - 0x001F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0020 - 0x002F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0030 - 0x003F */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x0040 - 0x004F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x0050 - 0x005F */
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x0060 - 0x006F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x0070 - 0x007F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0080 - 0x008F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0090 - 0x009F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00A0 - 0x00AF */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00B0 - 0x00BF */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00C0 - 0x00CF */
- 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00D0 - 0x00DF */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00E0 - 0x00EF */
- 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00F0 - 0x00FF */
-};
-
-/**
- * xmlIsBaseChar:
- * @c: an unicode character (int)
- *
- * Check whether the character is allowed by the production
- * [85] BaseChar ::= ... long list see REC ...
- *
- * VI is your friend !
- * :1,$ s/\[#x\([0-9A-Z]*\)-#x\([0-9A-Z]*\)\]/ (((c) >= 0x\1) \&\& ((c) <= 0x\2)) ||/
- * and
- * :1,$ s/#x\([0-9A-Z]*\)/ ((c) == 0x\1) ||/
- *
- * Returns 0 if not, non-zero otherwise
- */
-int
-xmlIsBaseChar(int c) {
- return(
- (((c) < 0x0100) ? xmlBaseArray[c] :
- ( /* accelerator */
- (((c) >= 0x0100) && ((c) <= 0x0131)) ||
- (((c) >= 0x0134) && ((c) <= 0x013E)) ||
- (((c) >= 0x0141) && ((c) <= 0x0148)) ||
- (((c) >= 0x014A) && ((c) <= 0x017E)) ||
- (((c) >= 0x0180) && ((c) <= 0x01C3)) ||
- (((c) >= 0x01CD) && ((c) <= 0x01F0)) ||
- (((c) >= 0x01F4) && ((c) <= 0x01F5)) ||
- (((c) >= 0x01FA) && ((c) <= 0x0217)) ||
- (((c) >= 0x0250) && ((c) <= 0x02A8)) ||
- (((c) >= 0x02BB) && ((c) <= 0x02C1)) ||
- ((c) == 0x0386) ||
- (((c) >= 0x0388) && ((c) <= 0x038A)) ||
- ((c) == 0x038C) ||
- (((c) >= 0x038E) && ((c) <= 0x03A1)) ||
- (((c) >= 0x03A3) && ((c) <= 0x03CE)) ||
- (((c) >= 0x03D0) && ((c) <= 0x03D6)) ||
- ((c) == 0x03DA) ||
- ((c) == 0x03DC) ||
- ((c) == 0x03DE) ||
- ((c) == 0x03E0) ||
- (((c) >= 0x03E2) && ((c) <= 0x03F3)) ||
- (((c) >= 0x0401) && ((c) <= 0x040C)) ||
- (((c) >= 0x040E) && ((c) <= 0x044F)) ||
- (((c) >= 0x0451) && ((c) <= 0x045C)) ||
- (((c) >= 0x045E) && ((c) <= 0x0481)) ||
- (((c) >= 0x0490) && ((c) <= 0x04C4)) ||
- (((c) >= 0x04C7) && ((c) <= 0x04C8)) ||
- (((c) >= 0x04CB) && ((c) <= 0x04CC)) ||
- (((c) >= 0x04D0) && ((c) <= 0x04EB)) ||
- (((c) >= 0x04EE) && ((c) <= 0x04F5)) ||
- (((c) >= 0x04F8) && ((c) <= 0x04F9)) ||
- (((c) >= 0x0531) && ((c) <= 0x0556)) ||
- ((c) == 0x0559) ||
- (((c) >= 0x0561) && ((c) <= 0x0586)) ||
- (((c) >= 0x05D0) && ((c) <= 0x05EA)) ||
- (((c) >= 0x05F0) && ((c) <= 0x05F2)) ||
- (((c) >= 0x0621) && ((c) <= 0x063A)) ||
- (((c) >= 0x0641) && ((c) <= 0x064A)) ||
- (((c) >= 0x0671) && ((c) <= 0x06B7)) ||
- (((c) >= 0x06BA) && ((c) <= 0x06BE)) ||
- (((c) >= 0x06C0) && ((c) <= 0x06CE)) ||
- (((c) >= 0x06D0) && ((c) <= 0x06D3)) ||
- ((c) == 0x06D5) ||
- (((c) >= 0x06E5) && ((c) <= 0x06E6)) ||
- (((c) >= 0x905) && ( /* accelerator */
- (((c) >= 0x0905) && ((c) <= 0x0939)) ||
- ((c) == 0x093D) ||
- (((c) >= 0x0958) && ((c) <= 0x0961)) ||
- (((c) >= 0x0985) && ((c) <= 0x098C)) ||
- (((c) >= 0x098F) && ((c) <= 0x0990)) ||
- (((c) >= 0x0993) && ((c) <= 0x09A8)) ||
- (((c) >= 0x09AA) && ((c) <= 0x09B0)) ||
- ((c) == 0x09B2) ||
- (((c) >= 0x09B6) && ((c) <= 0x09B9)) ||
- (((c) >= 0x09DC) && ((c) <= 0x09DD)) ||
- (((c) >= 0x09DF) && ((c) <= 0x09E1)) ||
- (((c) >= 0x09F0) && ((c) <= 0x09F1)) ||
- (((c) >= 0x0A05) && ((c) <= 0x0A0A)) ||
- (((c) >= 0x0A0F) && ((c) <= 0x0A10)) ||
- (((c) >= 0x0A13) && ((c) <= 0x0A28)) ||
- (((c) >= 0x0A2A) && ((c) <= 0x0A30)) ||
- (((c) >= 0x0A32) && ((c) <= 0x0A33)) ||
- (((c) >= 0x0A35) && ((c) <= 0x0A36)) ||
- (((c) >= 0x0A38) && ((c) <= 0x0A39)) ||
- (((c) >= 0x0A59) && ((c) <= 0x0A5C)) ||
- ((c) == 0x0A5E) ||
- (((c) >= 0x0A72) && ((c) <= 0x0A74)) ||
- (((c) >= 0x0A85) && ((c) <= 0x0A8B)) ||
- ((c) == 0x0A8D) ||
- (((c) >= 0x0A8F) && ((c) <= 0x0A91)) ||
- (((c) >= 0x0A93) && ((c) <= 0x0AA8)) ||
- (((c) >= 0x0AAA) && ((c) <= 0x0AB0)) ||
- (((c) >= 0x0AB2) && ((c) <= 0x0AB3)) ||
- (((c) >= 0x0AB5) && ((c) <= 0x0AB9)) ||
- ((c) == 0x0ABD) ||
- ((c) == 0x0AE0) ||
- (((c) >= 0x0B05) && ((c) <= 0x0B0C)) ||
- (((c) >= 0x0B0F) && ((c) <= 0x0B10)) ||
- (((c) >= 0x0B13) && ((c) <= 0x0B28)) ||
- (((c) >= 0x0B2A) && ((c) <= 0x0B30)) ||
- (((c) >= 0x0B32) && ((c) <= 0x0B33)) ||
- (((c) >= 0x0B36) && ((c) <= 0x0B39)) ||
- ((c) == 0x0B3D) ||
- (((c) >= 0x0B5C) && ((c) <= 0x0B5D)) ||
- (((c) >= 0x0B5F) && ((c) <= 0x0B61)) ||
- (((c) >= 0x0B85) && ((c) <= 0x0B8A)) ||
- (((c) >= 0x0B8E) && ((c) <= 0x0B90)) ||
- (((c) >= 0x0B92) && ((c) <= 0x0B95)) ||
- (((c) >= 0x0B99) && ((c) <= 0x0B9A)) ||
- ((c) == 0x0B9C) ||
- (((c) >= 0x0B9E) && ((c) <= 0x0B9F)) ||
- (((c) >= 0x0BA3) && ((c) <= 0x0BA4)) ||
- (((c) >= 0x0BA8) && ((c) <= 0x0BAA)) ||
- (((c) >= 0x0BAE) && ((c) <= 0x0BB5)) ||
- (((c) >= 0x0BB7) && ((c) <= 0x0BB9)) ||
- (((c) >= 0x0C05) && ((c) <= 0x0C0C)) ||
- (((c) >= 0x0C0E) && ((c) <= 0x0C10)) ||
- (((c) >= 0x0C12) && ((c) <= 0x0C28)) ||
- (((c) >= 0x0C2A) && ((c) <= 0x0C33)) ||
- (((c) >= 0x0C35) && ((c) <= 0x0C39)) ||
- (((c) >= 0x0C60) && ((c) <= 0x0C61)) ||
- (((c) >= 0x0C85) && ((c) <= 0x0C8C)) ||
- (((c) >= 0x0C8E) && ((c) <= 0x0C90)) ||
- (((c) >= 0x0C92) && ((c) <= 0x0CA8)) ||
- (((c) >= 0x0CAA) && ((c) <= 0x0CB3)) ||
- (((c) >= 0x0CB5) && ((c) <= 0x0CB9)) ||
- ((c) == 0x0CDE) ||
- (((c) >= 0x0CE0) && ((c) <= 0x0CE1)) ||
- (((c) >= 0x0D05) && ((c) <= 0x0D0C)) ||
- (((c) >= 0x0D0E) && ((c) <= 0x0D10)) ||
- (((c) >= 0x0D12) && ((c) <= 0x0D28)) ||
- (((c) >= 0x0D2A) && ((c) <= 0x0D39)) ||
- (((c) >= 0x0D60) && ((c) <= 0x0D61)) ||
- (((c) >= 0x0E01) && ((c) <= 0x0E2E)) ||
- ((c) == 0x0E30) ||
- (((c) >= 0x0E32) && ((c) <= 0x0E33)) ||
- (((c) >= 0x0E40) && ((c) <= 0x0E45)) ||
- (((c) >= 0x0E81) && ((c) <= 0x0E82)) ||
- ((c) == 0x0E84) ||
- (((c) >= 0x0E87) && ((c) <= 0x0E88)) ||
- ((c) == 0x0E8A) ||
- ((c) == 0x0E8D) ||
- (((c) >= 0x0E94) && ((c) <= 0x0E97)) ||
- (((c) >= 0x0E99) && ((c) <= 0x0E9F)) ||
- (((c) >= 0x0EA1) && ((c) <= 0x0EA3)) ||
- ((c) == 0x0EA5) ||
- ((c) == 0x0EA7) ||
- (((c) >= 0x0EAA) && ((c) <= 0x0EAB)) ||
- (((c) >= 0x0EAD) && ((c) <= 0x0EAE)) ||
- ((c) == 0x0EB0) ||
- (((c) >= 0x0EB2) && ((c) <= 0x0EB3)) ||
- ((c) == 0x0EBD) ||
- (((c) >= 0x0EC0) && ((c) <= 0x0EC4)) ||
- (((c) >= 0x0F40) && ((c) <= 0x0F47)) ||
- (((c) >= 0x0F49) && ((c) <= 0x0F69)) ||
- (((c) >= 0x10A0) && ( /* accelerator */
- (((c) >= 0x10A0) && ((c) <= 0x10C5)) ||
- (((c) >= 0x10D0) && ((c) <= 0x10F6)) ||
- ((c) == 0x1100) ||
- (((c) >= 0x1102) && ((c) <= 0x1103)) ||
- (((c) >= 0x1105) && ((c) <= 0x1107)) ||
- ((c) == 0x1109) ||
- (((c) >= 0x110B) && ((c) <= 0x110C)) ||
- (((c) >= 0x110E) && ((c) <= 0x1112)) ||
- ((c) == 0x113C) ||
- ((c) == 0x113E) ||
- ((c) == 0x1140) ||
- ((c) == 0x114C) ||
- ((c) == 0x114E) ||
- ((c) == 0x1150) ||
- (((c) >= 0x1154) && ((c) <= 0x1155)) ||
- ((c) == 0x1159) ||
- (((c) >= 0x115F) && ((c) <= 0x1161)) ||
- ((c) == 0x1163) ||
- ((c) == 0x1165) ||
- ((c) == 0x1167) ||
- ((c) == 0x1169) ||
- (((c) >= 0x116D) && ((c) <= 0x116E)) ||
- (((c) >= 0x1172) && ((c) <= 0x1173)) ||
- ((c) == 0x1175) ||
- ((c) == 0x119E) ||
- ((c) == 0x11A8) ||
- ((c) == 0x11AB) ||
- (((c) >= 0x11AE) && ((c) <= 0x11AF)) ||
- (((c) >= 0x11B7) && ((c) <= 0x11B8)) ||
- ((c) == 0x11BA) ||
- (((c) >= 0x11BC) && ((c) <= 0x11C2)) ||
- ((c) == 0x11EB) ||
- ((c) == 0x11F0) ||
- ((c) == 0x11F9) ||
- (((c) >= 0x1E00) && ((c) <= 0x1E9B)) ||
- (((c) >= 0x1EA0) && ((c) <= 0x1EF9)) ||
- (((c) >= 0x1F00) && ((c) <= 0x1F15)) ||
- (((c) >= 0x1F18) && ((c) <= 0x1F1D)) ||
- (((c) >= 0x1F20) && ((c) <= 0x1F45)) ||
- (((c) >= 0x1F48) && ((c) <= 0x1F4D)) ||
- (((c) >= 0x1F50) && ((c) <= 0x1F57)) ||
- ((c) == 0x1F59) ||
- ((c) == 0x1F5B) ||
- ((c) == 0x1F5D) ||
- (((c) >= 0x1F5F) && ((c) <= 0x1F7D)) ||
- (((c) >= 0x1F80) && ((c) <= 0x1FB4)) ||
- (((c) >= 0x1FB6) && ((c) <= 0x1FBC)) ||
- ((c) == 0x1FBE) ||
- (((c) >= 0x1FC2) && ((c) <= 0x1FC4)) ||
- (((c) >= 0x1FC6) && ((c) <= 0x1FCC)) ||
- (((c) >= 0x1FD0) && ((c) <= 0x1FD3)) ||
- (((c) >= 0x1FD6) && ((c) <= 0x1FDB)) ||
- (((c) >= 0x1FE0) && ((c) <= 0x1FEC)) ||
- (((c) >= 0x1FF2) && ((c) <= 0x1FF4)) ||
- (((c) >= 0x1FF6) && ((c) <= 0x1FFC)) ||
- ((c) == 0x2126) ||
- (((c) >= 0x212A) && ((c) <= 0x212B)) ||
- ((c) == 0x212E) ||
- (((c) >= 0x2180) && ((c) <= 0x2182)) ||
- (((c) >= 0x3041) && ((c) <= 0x3094)) ||
- (((c) >= 0x30A1) && ((c) <= 0x30FA)) ||
- (((c) >= 0x3105) && ((c) <= 0x312C)) ||
- (((c) >= 0xAC00) && ((c) <= 0xD7A3))) /* accelerators */ ))))));
-}
-
-/**
- * xmlIsDigit:
- * @c: an unicode character (int)
- *
- * Check whether the character is allowed by the production
- * [88] Digit ::= ... long list see REC ...
- *
- * Returns 0 if not, non-zero otherwise
- */
-int
-xmlIsDigit(int c) {
- return(
- (((c) >= 0x0030) && ((c) <= 0x0039)) ||
- (((c) >= 0x660) && ( /* accelerator */
- (((c) >= 0x0660) && ((c) <= 0x0669)) ||
- (((c) >= 0x06F0) && ((c) <= 0x06F9)) ||
- (((c) >= 0x0966) && ((c) <= 0x096F)) ||
- (((c) >= 0x09E6) && ((c) <= 0x09EF)) ||
- (((c) >= 0x0A66) && ((c) <= 0x0A6F)) ||
- (((c) >= 0x0AE6) && ((c) <= 0x0AEF)) ||
- (((c) >= 0x0B66) && ((c) <= 0x0B6F)) ||
- (((c) >= 0x0BE7) && ((c) <= 0x0BEF)) ||
- (((c) >= 0x0C66) && ((c) <= 0x0C6F)) ||
- (((c) >= 0x0CE6) && ((c) <= 0x0CEF)) ||
- (((c) >= 0x0D66) && ((c) <= 0x0D6F)) ||
- (((c) >= 0x0E50) && ((c) <= 0x0E59)) ||
- (((c) >= 0x0ED0) && ((c) <= 0x0ED9)) ||
- (((c) >= 0x0F20) && ((c) <= 0x0F29))) /* accelerator */ ));
-}
-
-/**
- * xmlIsCombining:
- * @c: an unicode character (int)
- *
- * Check whether the character is allowed by the production
- * [87] CombiningChar ::= ... long list see REC ...
- *
- * Returns 0 if not, non-zero otherwise
- */
-int
-xmlIsCombining(int c) {
- return(
- (((c) >= 0x300) && ( /* accelerator */
- (((c) >= 0x0300) && ((c) <= 0x0345)) ||
- (((c) >= 0x0360) && ((c) <= 0x0361)) ||
- (((c) >= 0x0483) && ((c) <= 0x0486)) ||
- (((c) >= 0x0591) && ((c) <= 0x05A1)) ||
- (((c) >= 0x05A3) && ((c) <= 0x05B9)) ||
- (((c) >= 0x05BB) && ((c) <= 0x05BD)) ||
- ((c) == 0x05BF) ||
- (((c) >= 0x05C1) && ((c) <= 0x05C2)) ||
- ((c) == 0x05C4) ||
- (((c) >= 0x064B) && ((c) <= 0x0652)) ||
- ((c) == 0x0670) ||
- (((c) >= 0x06D6) && ((c) <= 0x06DC)) ||
- (((c) >= 0x06DD) && ((c) <= 0x06DF)) ||
- (((c) >= 0x06E0) && ((c) <= 0x06E4)) ||
- (((c) >= 0x06E7) && ((c) <= 0x06E8)) ||
- (((c) >= 0x06EA) && ((c) <= 0x06ED)) ||
- (((c) >= 0x0901) && ( /* accelerator */
- (((c) >= 0x0901) && ((c) <= 0x0903)) ||
- ((c) == 0x093C) ||
- (((c) >= 0x093E) && ((c) <= 0x094C)) ||
- ((c) == 0x094D) ||
- (((c) >= 0x0951) && ((c) <= 0x0954)) ||
- (((c) >= 0x0962) && ((c) <= 0x0963)) ||
- (((c) >= 0x0981) && ((c) <= 0x0983)) ||
- ((c) == 0x09BC) ||
- ((c) == 0x09BE) ||
- ((c) == 0x09BF) ||
- (((c) >= 0x09C0) && ((c) <= 0x09C4)) ||
- (((c) >= 0x09C7) && ((c) <= 0x09C8)) ||
- (((c) >= 0x09CB) && ((c) <= 0x09CD)) ||
- ((c) == 0x09D7) ||
- (((c) >= 0x09E2) && ((c) <= 0x09E3)) ||
- (((c) >= 0x0A02) && ( /* accelerator */
- ((c) == 0x0A02) ||
- ((c) == 0x0A3C) ||
- ((c) == 0x0A3E) ||
- ((c) == 0x0A3F) ||
- (((c) >= 0x0A40) && ((c) <= 0x0A42)) ||
- (((c) >= 0x0A47) && ((c) <= 0x0A48)) ||
- (((c) >= 0x0A4B) && ((c) <= 0x0A4D)) ||
- (((c) >= 0x0A70) && ((c) <= 0x0A71)) ||
- (((c) >= 0x0A81) && ((c) <= 0x0A83)) ||
- ((c) == 0x0ABC) ||
- (((c) >= 0x0ABE) && ((c) <= 0x0AC5)) ||
- (((c) >= 0x0AC7) && ((c) <= 0x0AC9)) ||
- (((c) >= 0x0ACB) && ((c) <= 0x0ACD)) ||
- (((c) >= 0x0B01) && ((c) <= 0x0B03)) ||
- ((c) == 0x0B3C) ||
- (((c) >= 0x0B3E) && ((c) <= 0x0B43)) ||
- (((c) >= 0x0B47) && ((c) <= 0x0B48)) ||
- (((c) >= 0x0B4B) && ((c) <= 0x0B4D)) ||
- (((c) >= 0x0B56) && ((c) <= 0x0B57)) ||
- (((c) >= 0x0B82) && ((c) <= 0x0B83)) ||
- (((c) >= 0x0BBE) && ((c) <= 0x0BC2)) ||
- (((c) >= 0x0BC6) && ((c) <= 0x0BC8)) ||
- (((c) >= 0x0BCA) && ((c) <= 0x0BCD)) ||
- ((c) == 0x0BD7) ||
- (((c) >= 0x0C01) && ((c) <= 0x0C03)) ||
- (((c) >= 0x0C3E) && ((c) <= 0x0C44)) ||
- (((c) >= 0x0C46) && ((c) <= 0x0C48)) ||
- (((c) >= 0x0C4A) && ((c) <= 0x0C4D)) ||
- (((c) >= 0x0C55) && ((c) <= 0x0C56)) ||
- (((c) >= 0x0C82) && ((c) <= 0x0C83)) ||
- (((c) >= 0x0CBE) && ((c) <= 0x0CC4)) ||
- (((c) >= 0x0CC6) && ((c) <= 0x0CC8)) ||
- (((c) >= 0x0CCA) && ((c) <= 0x0CCD)) ||
- (((c) >= 0x0CD5) && ((c) <= 0x0CD6)) ||
- (((c) >= 0x0D02) && ((c) <= 0x0D03)) ||
- (((c) >= 0x0D3E) && ((c) <= 0x0D43)) ||
- (((c) >= 0x0D46) && ((c) <= 0x0D48)) ||
- (((c) >= 0x0D4A) && ((c) <= 0x0D4D)) ||
- ((c) == 0x0D57) ||
- (((c) >= 0x0E31) && ( /* accelerator */
- ((c) == 0x0E31) ||
- (((c) >= 0x0E34) && ((c) <= 0x0E3A)) ||
- (((c) >= 0x0E47) && ((c) <= 0x0E4E)) ||
- ((c) == 0x0EB1) ||
- (((c) >= 0x0EB4) && ((c) <= 0x0EB9)) ||
- (((c) >= 0x0EBB) && ((c) <= 0x0EBC)) ||
- (((c) >= 0x0EC8) && ((c) <= 0x0ECD)) ||
- (((c) >= 0x0F18) && ((c) <= 0x0F19)) ||
- ((c) == 0x0F35) ||
- ((c) == 0x0F37) ||
- ((c) == 0x0F39) ||
- ((c) == 0x0F3E) ||
- ((c) == 0x0F3F) ||
- (((c) >= 0x0F71) && ((c) <= 0x0F84)) ||
- (((c) >= 0x0F86) && ((c) <= 0x0F8B)) ||
- (((c) >= 0x0F90) && ((c) <= 0x0F95)) ||
- ((c) == 0x0F97) ||
- (((c) >= 0x0F99) && ((c) <= 0x0FAD)) ||
- (((c) >= 0x0FB1) && ((c) <= 0x0FB7)) ||
- ((c) == 0x0FB9) ||
- (((c) >= 0x20D0) && ((c) <= 0x20DC)) ||
- ((c) == 0x20E1) ||
- (((c) >= 0x302A) && ((c) <= 0x302F)) ||
- ((c) == 0x3099) ||
- ((c) == 0x309A))))))))));
-}
-
-/**
- * xmlIsExtender:
- * @c: an unicode character (int)
- *
- * Check whether the character is allowed by the production
- * [89] Extender ::= #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 |
- * #x0E46 | #x0EC6 | #x3005 | [#x3031-#x3035] |
- * [#x309D-#x309E] | [#x30FC-#x30FE]
- *
- * Returns 0 if not, non-zero otherwise
- */
-int
-xmlIsExtender(int c) {
- switch (c) {
- case 0x00B7: case 0x02D0: case 0x02D1: case 0x0387:
- case 0x0640: case 0x0E46: case 0x0EC6: case 0x3005:
- case 0x3031: case 0x3032: case 0x3033: case 0x3034:
- case 0x3035: case 0x309D: case 0x309E: case 0x30FC:
- case 0x30FD: case 0x30FE:
- return 1;
- default:
- return 0;
- }
-}
-
-/**
- * xmlIsIdeographic:
- * @c: an unicode character (int)
- *
- * Check whether the character is allowed by the production
- * [86] Ideographic ::= [#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]
- *
- * Returns 0 if not, non-zero otherwise
- */
-int
-xmlIsIdeographic(int c) {
- return(((c) < 0x0100) ? 0 :
- (((c) >= 0x4e00) && ((c) <= 0x9fa5)) ||
- (((c) >= 0xf900) && ((c) <= 0xfa2d)) ||
- (((c) >= 0x3021) && ((c) <= 0x3029)) ||
- ((c) == 0x3007));
-}
-
-/**
- * xmlIsLetter:
- * @c: an unicode character (int)
- *
- * Check whether the character is allowed by the production
- * [84] Letter ::= BaseChar | Ideographic
- *
- * Returns 0 if not, non-zero otherwise
- */
-int
-xmlIsLetter(int c) {
- return(IS_BASECHAR(c) || IS_IDEOGRAPHIC(c));
-}
-
-/**
- * xmlIsPubidChar:
- * @c: an unicode character (int)
- *
- * Check whether the character is allowed by the production
- * [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
- *
- * Returns 0 if not, non-zero otherwise
- */
-int
-xmlIsPubidChar(int c) {
- return(
- ((c) == 0x20) || ((c) == 0x0D) || ((c) == 0x0A) ||
- (((c) >= 'a') && ((c) <= 'z')) ||
- (((c) >= 'A') && ((c) <= 'Z')) ||
- (((c) >= '0') && ((c) <= '9')) ||
- ((c) == '-') || ((c) == '\'') || ((c) == '(') || ((c) == ')') ||
- ((c) == '+') || ((c) == ',') || ((c) == '.') || ((c) == '/') ||
- ((c) == ':') || ((c) == '=') || ((c) == '?') || ((c) == ';') ||
- ((c) == '!') || ((c) == '*') || ((c) == '#') || ((c) == '@') ||
- ((c) == '$') || ((c) == '_') || ((c) == '%'));
-}
-
-/************************************************************************
- * *
- * Input handling functions for progressive parsing *
- * *
- ************************************************************************/
-
-/* #define DEBUG_INPUT */
-/* #define DEBUG_STACK */
-/* #define DEBUG_PUSH */
-
-
-/* we need to keep enough input to show errors in context */
-#define LINE_LEN 80
-
-#ifdef DEBUG_INPUT
-#define CHECK_BUFFER(in) check_buffer(in)
-
-static
-void check_buffer(xmlParserInputPtr in) {
- if (in->base != in->buf->buffer->content) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlParserInput: base mismatch problem\n");
- }
- if (in->cur < in->base) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlParserInput: cur < base problem\n");
- }
- if (in->cur > in->base + in->buf->buffer->use) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlParserInput: cur > base + use problem\n");
- }
- xmlGenericError(xmlGenericErrorContext,"buffer %x : content %x, cur %d, use %d, size %d\n",
- (int) in, (int) in->buf->buffer->content, in->cur - in->base,
- in->buf->buffer->use, in->buf->buffer->size);
-}
-
-#else
-#define CHECK_BUFFER(in)
-#endif
-
-
-/**
- * xmlParserInputRead:
- * @in: an XML parser input
- * @len: an indicative size for the lookahead
- *
- * This function refresh the input for the parser. It doesn't try to
- * preserve pointers to the input buffer, and discard already read data
- *
- * Returns the number of xmlChars read, or -1 in case of error, 0 indicate the
- * end of this entity
- */
-int
-xmlParserInputRead(xmlParserInputPtr in, int len) {
- int ret;
- int used;
- int indx;
-
-#ifdef DEBUG_INPUT
- xmlGenericError(xmlGenericErrorContext, "Read\n");
-#endif
- if (in->buf == NULL) return(-1);
- if (in->base == NULL) return(-1);
- if (in->cur == NULL) return(-1);
- if (in->buf->buffer == NULL) return(-1);
- if (in->buf->readcallback == NULL) return(-1);
-
- CHECK_BUFFER(in);
-
- used = in->cur - in->buf->buffer->content;
- ret = xmlBufferShrink(in->buf->buffer, used);
- if (ret > 0) {
- in->cur -= ret;
- in->consumed += ret;
- }
- ret = xmlParserInputBufferRead(in->buf, len);
- if (in->base != in->buf->buffer->content) {
- /*
- * the buffer has been reallocated
- */
- indx = in->cur - in->base;
- in->base = in->buf->buffer->content;
- in->cur = &in->buf->buffer->content[indx];
- }
- in->end = &in->buf->buffer->content[in->buf->buffer->use];
-
- CHECK_BUFFER(in);
-
- return(ret);
-}
-
-/**
- * xmlParserInputGrow:
- * @in: an XML parser input
- * @len: an indicative size for the lookahead
- *
- * This function increase the input for the parser. It tries to
- * preserve pointers to the input buffer, and keep already read data
- *
- * Returns the number of xmlChars read, or -1 in case of error, 0 indicate the
- * end of this entity
- */
-int
-xmlParserInputGrow(xmlParserInputPtr in, int len) {
- int ret;
- int indx;
-
-#ifdef DEBUG_INPUT
- xmlGenericError(xmlGenericErrorContext, "Grow\n");
-#endif
- if (in->buf == NULL) return(-1);
- if (in->base == NULL) return(-1);
- if (in->cur == NULL) return(-1);
- if (in->buf->buffer == NULL) return(-1);
-
- CHECK_BUFFER(in);
-
- indx = in->cur - in->base;
- if (in->buf->buffer->use > (unsigned int) indx + INPUT_CHUNK) {
-
- CHECK_BUFFER(in);
-
- return(0);
- }
- if (in->buf->readcallback != NULL)
- ret = xmlParserInputBufferGrow(in->buf, len);
- else
- return(0);
-
- /*
- * NOTE : in->base may be a "dangling" i.e. freed pointer in this
- * block, but we use it really as an integer to do some
- * pointer arithmetic. Insure will raise it as a bug but in
- * that specific case, that's not !
- */
- if (in->base != in->buf->buffer->content) {
- /*
- * the buffer has been reallocated
- */
- indx = in->cur - in->base;
- in->base = in->buf->buffer->content;
- in->cur = &in->buf->buffer->content[indx];
- }
- in->end = &in->buf->buffer->content[in->buf->buffer->use];
-
- CHECK_BUFFER(in);
-
- return(ret);
-}
-
-/**
- * xmlParserInputShrink:
- * @in: an XML parser input
- *
- * This function removes used input for the parser.
- */
-void
-xmlParserInputShrink(xmlParserInputPtr in) {
- int used;
- int ret;
- int indx;
-
-#ifdef DEBUG_INPUT
- xmlGenericError(xmlGenericErrorContext, "Shrink\n");
-#endif
- if (in->buf == NULL) return;
- if (in->base == NULL) return;
- if (in->cur == NULL) return;
- if (in->buf->buffer == NULL) return;
-
- CHECK_BUFFER(in);
-
- used = in->cur - in->buf->buffer->content;
- /*
- * Do not shrink on large buffers whose only a tiny fraction
- * was consumed
- */
- if ((int) in->buf->buffer->use > used + 2 * INPUT_CHUNK)
- return;
- if (used > INPUT_CHUNK) {
- ret = xmlBufferShrink(in->buf->buffer, used - LINE_LEN);
- if (ret > 0) {
- in->cur -= ret;
- in->consumed += ret;
- }
- in->end = &in->buf->buffer->content[in->buf->buffer->use];
- }
-
- CHECK_BUFFER(in);
-
- if (in->buf->buffer->use > INPUT_CHUNK) {
- return;
- }
- xmlParserInputBufferRead(in->buf, 2 * INPUT_CHUNK);
- if (in->base != in->buf->buffer->content) {
- /*
- * the buffer has been reallocated
- */
- indx = in->cur - in->base;
- in->base = in->buf->buffer->content;
- in->cur = &in->buf->buffer->content[indx];
- }
- in->end = &in->buf->buffer->content[in->buf->buffer->use];
-
- CHECK_BUFFER(in);
-}
-
-/************************************************************************
- * *
- * UTF8 character input and related functions *
- * *
- ************************************************************************/
-
-/**
- * xmlNextChar:
- * @ctxt: the XML parser context
- *
- * Skip to the next char input char.
- */
-
-void
-xmlNextChar(xmlParserCtxtPtr ctxt) {
- if (ctxt->instate == XML_PARSER_EOF)
- return;
-
- /*
- * 2.11 End-of-Line Handling
- * the literal two-character sequence "#xD#xA" or a standalone
- * literal #xD, an XML processor must pass to the application
- * the single character #xA.
- */
- if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
- if ((*ctxt->input->cur == 0) &&
- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0) &&
- (ctxt->instate != XML_PARSER_COMMENT)) {
- /*
- * If we are at the end of the current entity and
- * the context allows it, we pop consumed entities
- * automatically.
- * the auto closing should be blocked in other cases
- */
- xmlPopInput(ctxt);
- } else {
- if (*(ctxt->input->cur) == '\n') {
- ctxt->input->line++; ctxt->input->col = 1;
- } else ctxt->input->col++;
- if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
- /*
- * We are supposed to handle UTF8, check it's valid
- * From rfc2044: encoding of the Unicode values on UTF-8:
- *
- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
- * 0000 0000-0000 007F 0xxxxxxx
- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
- *
- * Check for the 0x110000 limit too
- */
- const unsigned char *cur = ctxt->input->cur;
- unsigned char c;
-
- c = *cur;
- if (c & 0x80) {
- if (cur[1] == 0)
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- if ((cur[1] & 0xc0) != 0x80)
- goto encoding_error;
- if ((c & 0xe0) == 0xe0) {
- unsigned int val;
-
- if (cur[2] == 0)
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- if ((cur[2] & 0xc0) != 0x80)
- goto encoding_error;
- if ((c & 0xf0) == 0xf0) {
- if (cur[3] == 0)
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- if (((c & 0xf8) != 0xf0) ||
- ((cur[3] & 0xc0) != 0x80))
- goto encoding_error;
- /* 4-byte code */
- ctxt->input->cur += 4;
- val = (cur[0] & 0x7) << 18;
- val |= (cur[1] & 0x3f) << 12;
- val |= (cur[2] & 0x3f) << 6;
- val |= cur[3] & 0x3f;
- } else {
- /* 3-byte code */
- ctxt->input->cur += 3;
- val = (cur[0] & 0xf) << 12;
- val |= (cur[1] & 0x3f) << 6;
- val |= cur[2] & 0x3f;
- }
- if (((val > 0xd7ff) && (val < 0xe000)) ||
- ((val > 0xfffd) && (val < 0x10000)) ||
- (val >= 0x110000)) {
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Char 0x%X out of allowed range\n", val);
- ctxt->errNo = XML_ERR_INVALID_ENCODING;
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- } else
- /* 2-byte code */
- ctxt->input->cur += 2;
- } else
- /* 1-byte code */
- ctxt->input->cur++;
- } else {
- /*
- * Assume it's a fixed length encoding (1) with
- * a compatible encoding for the ASCII set, since
- * XML constructs only use < 128 chars
- */
- ctxt->input->cur++;
- }
- ctxt->nbChars++;
- if (*ctxt->input->cur == 0)
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- }
- } else {
- ctxt->input->cur++;
- ctxt->nbChars++;
- if (*ctxt->input->cur == 0)
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- }
- if ((*ctxt->input->cur == '%') && (!ctxt->html))
- xmlParserHandlePEReference(ctxt);
- if ((*ctxt->input->cur == 0) &&
- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
- xmlPopInput(ctxt);
- return;
-encoding_error:
- /*
- * If we detect an UTF8 error that probably mean that the
- * input encoding didn't get properly advertised in the
- * declaration header. Report the error and switch the encoding
- * to ISO-Latin-1 (if you don't like this policy, just declare the
- * encoding !)
- */
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
- ctxt->sax->error(ctxt->userData,
- "Input is not proper UTF-8, indicate encoding !\n");
- ctxt->sax->error(ctxt->userData, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
- ctxt->input->cur[0], ctxt->input->cur[1],
- ctxt->input->cur[2], ctxt->input->cur[3]);
- }
- ctxt->wellFormed = 0;
- ctxt->errNo = XML_ERR_INVALID_ENCODING;
-
- ctxt->charset = XML_CHAR_ENCODING_8859_1;
- ctxt->input->cur++;
- return;
-}
-
-/**
- * xmlCurrentChar:
- * @ctxt: the XML parser context
- * @len: pointer to the length of the char read
- *
- * The current char value, if using UTF-8 this may actually span multiple
- * bytes in the input buffer. Implement the end of line normalization:
- * 2.11 End-of-Line Handling
- * Wherever an external parsed entity or the literal entity value
- * of an internal parsed entity contains either the literal two-character
- * sequence "#xD#xA" or a standalone literal #xD, an XML processor
- * must pass to the application the single character #xA.
- * This behavior can conveniently be produced by normalizing all
- * line breaks to #xA on input, before parsing.)
- *
- * Returns the current char value and its length
- */
-
-int
-xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
- if (ctxt->instate == XML_PARSER_EOF)
- return(0);
-
- if ((*ctxt->input->cur >= 0x20) && (*ctxt->input->cur <= 0x7F)) {
- *len = 1;
- return((int) *ctxt->input->cur);
- }
- if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
- /*
- * We are supposed to handle UTF8, check it's valid
- * From rfc2044: encoding of the Unicode values on UTF-8:
- *
- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
- * 0000 0000-0000 007F 0xxxxxxx
- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
- *
- * Check for the 0x110000 limit too
- */
- const unsigned char *cur = ctxt->input->cur;
- unsigned char c;
- unsigned int val;
-
- c = *cur;
- if (c & 0x80) {
- if (cur[1] == 0)
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- if ((cur[1] & 0xc0) != 0x80)
- goto encoding_error;
- if ((c & 0xe0) == 0xe0) {
-
- if (cur[2] == 0)
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- if ((cur[2] & 0xc0) != 0x80)
- goto encoding_error;
- if ((c & 0xf0) == 0xf0) {
- if (cur[3] == 0)
- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- if (((c & 0xf8) != 0xf0) ||
- ((cur[3] & 0xc0) != 0x80))
- goto encoding_error;
- /* 4-byte code */
- *len = 4;
- val = (cur[0] & 0x7) << 18;
- val |= (cur[1] & 0x3f) << 12;
- val |= (cur[2] & 0x3f) << 6;
- val |= cur[3] & 0x3f;
- } else {
- /* 3-byte code */
- *len = 3;
- val = (cur[0] & 0xf) << 12;
- val |= (cur[1] & 0x3f) << 6;
- val |= cur[2] & 0x3f;
- }
- } else {
- /* 2-byte code */
- *len = 2;
- val = (cur[0] & 0x1f) << 6;
- val |= cur[1] & 0x3f;
- }
- if (!IS_CHAR(val)) {
- if ((ctxt->sax != NULL) &&
- (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Char 0x%X out of allowed range\n", val);
- ctxt->errNo = XML_ERR_INVALID_ENCODING;
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- return(val);
- } else {
- /* 1-byte code */
- *len = 1;
- if (*ctxt->input->cur == 0xD) {
- if (ctxt->input->cur[1] == 0xA) {
- ctxt->nbChars++;
- ctxt->input->cur++;
- }
- return(0xA);
- }
- return((int) *ctxt->input->cur);
- }
- }
- /*
- * Assume it's a fixed length encoding (1) with
- * a compatible encoding for the ASCII set, since
- * XML constructs only use < 128 chars
- */
- *len = 1;
- if (*ctxt->input->cur == 0xD) {
- if (ctxt->input->cur[1] == 0xA) {
- ctxt->nbChars++;
- ctxt->input->cur++;
- }
- return(0xA);
- }
- return((int) *ctxt->input->cur);
-encoding_error:
- /*
- * An encoding problem may arise from a truncated input buffer
- * splitting a character in the middle. In that case do not raise
- * an error but return 0 to endicate an end of stream problem
- */
- if (ctxt->input->end - ctxt->input->cur < 4) {
- *len = 0;
- return(0);
- }
-
- /*
- * If we detect an UTF8 error that probably mean that the
- * input encoding didn't get properly advertised in the
- * declaration header. Report the error and switch the encoding
- * to ISO-Latin-1 (if you don't like this policy, just declare the
- * encoding !)
- */
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
- ctxt->sax->error(ctxt->userData,
- "Input is not proper UTF-8, indicate encoding !\n");
- ctxt->sax->error(ctxt->userData, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
- ctxt->input->cur[0], ctxt->input->cur[1],
- ctxt->input->cur[2], ctxt->input->cur[3]);
- }
- ctxt->wellFormed = 0;
- ctxt->errNo = XML_ERR_INVALID_ENCODING;
-
- ctxt->charset = XML_CHAR_ENCODING_8859_1;
- *len = 1;
- return((int) *ctxt->input->cur);
-}
-
-/**
- * xmlStringCurrentChar:
- * @ctxt: the XML parser context
- * @cur: pointer to the beginning of the char
- * @len: pointer to the length of the char read
- *
- * The current char value, if using UTF-8 this may actually span multiple
- * bytes in the input buffer.
- *
- * Returns the current char value and its length
- */
-
-int
-xmlStringCurrentChar(xmlParserCtxtPtr ctxt, const xmlChar * cur, int *len)
-{
- if ((ctxt == NULL) || (ctxt->charset == XML_CHAR_ENCODING_UTF8)) {
- /*
- * We are supposed to handle UTF8, check it's valid
- * From rfc2044: encoding of the Unicode values on UTF-8:
- *
- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
- * 0000 0000-0000 007F 0xxxxxxx
- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
- *
- * Check for the 0x110000 limit too
- */
- unsigned char c;
- unsigned int val;
-
- c = *cur;
- if (c & 0x80) {
- if ((cur[1] & 0xc0) != 0x80)
- goto encoding_error;
- if ((c & 0xe0) == 0xe0) {
-
- if ((cur[2] & 0xc0) != 0x80)
- goto encoding_error;
- if ((c & 0xf0) == 0xf0) {
- if (((c & 0xf8) != 0xf0) || ((cur[3] & 0xc0) != 0x80))
- goto encoding_error;
- /* 4-byte code */
- *len = 4;
- val = (cur[0] & 0x7) << 18;
- val |= (cur[1] & 0x3f) << 12;
- val |= (cur[2] & 0x3f) << 6;
- val |= cur[3] & 0x3f;
- } else {
- /* 3-byte code */
- *len = 3;
- val = (cur[0] & 0xf) << 12;
- val |= (cur[1] & 0x3f) << 6;
- val |= cur[2] & 0x3f;
- }
- } else {
- /* 2-byte code */
- *len = 2;
- val = (cur[0] & 0x1f) << 6;
- val |= cur[1] & 0x3f;
- }
- if (!IS_CHAR(val)) {
- if ((ctxt != NULL) && (ctxt->sax != NULL) &&
- (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Char 0x%X out of allowed range\n",
- val);
- if (ctxt != NULL) {
- ctxt->errNo = XML_ERR_INVALID_ENCODING;
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- }
- }
- return (val);
- } else {
- /* 1-byte code */
- *len = 1;
- return ((int) *cur);
- }
- }
- /*
- * Assume it's a fixed length encoding (1) with
- * a compatible encoding for the ASCII set, since
- * XML constructs only use < 128 chars
- */
- *len = 1;
- return ((int) *cur);
-encoding_error:
-
- /*
- * If we detect an UTF8 error that probably mean that the
- * input encoding didn't get properly advertised in the
- * declaration header. Report the error and switch the encoding
- * to ISO-Latin-1 (if you don't like this policy, just declare the
- * encoding !)
- */
- if (ctxt != NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) {
- ctxt->sax->error(ctxt->userData,
- "Input is not proper UTF-8, indicate encoding !\n");
- ctxt->sax->error(ctxt->userData,
- "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
- ctxt->input->cur[0], ctxt->input->cur[1],
- ctxt->input->cur[2], ctxt->input->cur[3]);
- }
- ctxt->errNo = XML_ERR_INVALID_ENCODING;
- ctxt->wellFormed = 0;
- }
-
- *len = 1;
- return ((int) *cur);
-}
-
-/**
- * xmlCopyCharMultiByte:
- * @out: pointer to an array of xmlChar
- * @val: the char value
- *
- * append the char value in the array
- *
- * Returns the number of xmlChar written
- */
-int
-xmlCopyCharMultiByte(xmlChar *out, int val) {
- /*
- * We are supposed to handle UTF8, check it's valid
- * From rfc2044: encoding of the Unicode values on UTF-8:
- *
- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
- * 0000 0000-0000 007F 0xxxxxxx
- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
- */
- if (val >= 0x80) {
- xmlChar *savedout = out;
- int bits;
- if (val < 0x800) { *out++= (val >> 6) | 0xC0; bits= 0; }
- else if (val < 0x10000) { *out++= (val >> 12) | 0xE0; bits= 6;}
- else if (val < 0x110000) { *out++= (val >> 18) | 0xF0; bits= 12; }
- else {
- xmlGenericError(xmlGenericErrorContext,
- "Internal error, xmlCopyCharMultiByte 0x%X out of bound\n",
- val);
- return(0);
- }
- for ( ; bits >= 0; bits-= 6)
- *out++= ((val >> bits) & 0x3F) | 0x80 ;
- return (out - savedout);
- }
- *out = (xmlChar) val;
- return 1;
-}
-
-/**
- * xmlCopyChar:
- * @len: Ignored, compatibility
- * @out: pointer to an array of xmlChar
- * @val: the char value
- *
- * append the char value in the array
- *
- * Returns the number of xmlChar written
- */
-
-int
-xmlCopyChar(int len ATTRIBUTE_UNUSED, xmlChar *out, int val) {
- /* the len parameter is ignored */
- if (val >= 0x80) {
- return(xmlCopyCharMultiByte (out, val));
- }
- *out = (xmlChar) val;
- return 1;
-}
-
-/************************************************************************
- * *
- * Commodity functions to switch encodings *
- * *
- ************************************************************************/
-
-/**
- * xmlSwitchEncoding:
- * @ctxt: the parser context
- * @enc: the encoding value (number)
- *
- * change the input functions when discovering the character encoding
- * of a given entity.
- *
- * Returns 0 in case of success, -1 otherwise
- */
-int
-xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
-{
- xmlCharEncodingHandlerPtr handler;
-
- switch (enc) {
- case XML_CHAR_ENCODING_ERROR:
- ctxt->errNo = XML_ERR_UNKNOWN_ENCODING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "encoding unknown\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- break;
- case XML_CHAR_ENCODING_NONE:
- /* let's assume it's UTF-8 without the XML decl */
- ctxt->charset = XML_CHAR_ENCODING_UTF8;
- return(0);
- case XML_CHAR_ENCODING_UTF8:
- /* default encoding, no conversion should be needed */
- ctxt->charset = XML_CHAR_ENCODING_UTF8;
-
- /*
- * Errata on XML-1.0 June 20 2001
- * Specific handling of the Byte Order Mark for
- * UTF-8
- */
- if ((ctxt->input != NULL) &&
- (ctxt->input->cur[0] == 0xEF) &&
- (ctxt->input->cur[1] == 0xBB) &&
- (ctxt->input->cur[2] == 0xBF)) {
- ctxt->input->cur += 3;
- }
- return(0);
- default:
- break;
- }
- handler = xmlGetCharEncodingHandler(enc);
- if (handler == NULL) {
- /*
- * Default handlers.
- */
- switch (enc) {
- case XML_CHAR_ENCODING_ERROR:
- ctxt->errNo = XML_ERR_UNKNOWN_ENCODING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "encoding unknown\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- ctxt->charset = XML_CHAR_ENCODING_UTF8;
- break;
- case XML_CHAR_ENCODING_NONE:
- /* let's assume it's UTF-8 without the XML decl */
- ctxt->charset = XML_CHAR_ENCODING_UTF8;
- return(0);
- case XML_CHAR_ENCODING_UTF8:
- case XML_CHAR_ENCODING_ASCII:
- /* default encoding, no conversion should be needed */
- ctxt->charset = XML_CHAR_ENCODING_UTF8;
- return(0);
- case XML_CHAR_ENCODING_UTF16LE:
- break;
- case XML_CHAR_ENCODING_UTF16BE:
- break;
- case XML_CHAR_ENCODING_UCS4LE:
- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "char encoding USC4 little endian not supported\n");
- break;
- case XML_CHAR_ENCODING_UCS4BE:
- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "char encoding USC4 big endian not supported\n");
- break;
- case XML_CHAR_ENCODING_EBCDIC:
- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "char encoding EBCDIC not supported\n");
- break;
- case XML_CHAR_ENCODING_UCS4_2143:
- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "char encoding UCS4 2143 not supported\n");
- break;
- case XML_CHAR_ENCODING_UCS4_3412:
- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "char encoding UCS4 3412 not supported\n");
- break;
- case XML_CHAR_ENCODING_UCS2:
- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "char encoding UCS2 not supported\n");
- break;
- case XML_CHAR_ENCODING_8859_1:
- case XML_CHAR_ENCODING_8859_2:
- case XML_CHAR_ENCODING_8859_3:
- case XML_CHAR_ENCODING_8859_4:
- case XML_CHAR_ENCODING_8859_5:
- case XML_CHAR_ENCODING_8859_6:
- case XML_CHAR_ENCODING_8859_7:
- case XML_CHAR_ENCODING_8859_8:
- case XML_CHAR_ENCODING_8859_9:
- /*
- * We used to keep the internal content in the
- * document encoding however this turns being unmaintainable
- * So xmlGetCharEncodingHandler() will return non-null
- * values for this now.
- */
- if ((ctxt->inputNr == 1) &&
- (ctxt->encoding == NULL) &&
- (ctxt->input->encoding != NULL)) {
- ctxt->encoding = xmlStrdup(ctxt->input->encoding);
- }
- ctxt->charset = enc;
- return(0);
- case XML_CHAR_ENCODING_2022_JP:
- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "char encoding ISO-2022-JPnot supported\n");
- break;
- case XML_CHAR_ENCODING_SHIFT_JIS:
- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "char encoding Shift_JIS not supported\n");
- break;
- case XML_CHAR_ENCODING_EUC_JP:
- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "char encoding EUC-JPnot supported\n");
- break;
- }
- }
- if (handler == NULL)
- return(-1);
- ctxt->charset = XML_CHAR_ENCODING_UTF8;
- return(xmlSwitchToEncoding(ctxt, handler));
-}
-
-/**
- * xmlSwitchToEncoding:
- * @ctxt: the parser context
- * @handler: the encoding handler
- *
- * change the input functions when discovering the character encoding
- * of a given entity.
- *
- * Returns 0 in case of success, -1 otherwise
- */
-int
-xmlSwitchToEncoding(xmlParserCtxtPtr ctxt, xmlCharEncodingHandlerPtr handler)
-{
- int nbchars;
-
- if (handler != NULL) {
- if (ctxt->input != NULL) {
- if (ctxt->input->buf != NULL) {
- if (ctxt->input->buf->encoder != NULL) {
- /*
- * Check in case the auto encoding detetection triggered
- * in already.
- */
- if (ctxt->input->buf->encoder == handler)
- return(0);
-
- /*
- * "UTF-16" can be used for both LE and BE
- */
- if ((!xmlStrncmp(BAD_CAST ctxt->input->buf->encoder->name,
- BAD_CAST "UTF-16", 6)) &&
- (!xmlStrncmp(BAD_CAST handler->name,
- BAD_CAST "UTF-16", 6))) {
- return(0);
- }
-
- /*
- * Note: this is a bit dangerous, but that's what it
- * takes to use nearly compatible signature for different
- * encodings.
- */
- xmlCharEncCloseFunc(ctxt->input->buf->encoder);
- ctxt->input->buf->encoder = handler;
- return(0);
- }
- ctxt->input->buf->encoder = handler;
-
- /*
- * Is there already some content down the pipe to convert ?
- */
- if ((ctxt->input->buf->buffer != NULL) &&
- (ctxt->input->buf->buffer->use > 0)) {
- int processed;
-
- /*
- * Specific handling of the Byte Order Mark for
- * UTF-16
- */
- if ((handler->name != NULL) &&
- (!strcmp(handler->name, "UTF-16LE")) &&
- (ctxt->input->cur[0] == 0xFF) &&
- (ctxt->input->cur[1] == 0xFE)) {
- ctxt->input->cur += 2;
- }
- if ((handler->name != NULL) &&
- (!strcmp(handler->name, "UTF-16BE")) &&
- (ctxt->input->cur[0] == 0xFE) &&
- (ctxt->input->cur[1] == 0xFF)) {
- ctxt->input->cur += 2;
- }
- /*
- * Errata on XML-1.0 June 20 2001
- * Specific handling of the Byte Order Mark for
- * UTF-8
- */
- if ((handler->name != NULL) &&
- (!strcmp(handler->name, "UTF-8")) &&
- (ctxt->input->cur[0] == 0xEF) &&
- (ctxt->input->cur[1] == 0xBB) &&
- (ctxt->input->cur[2] == 0xBF)) {
- ctxt->input->cur += 3;
- }
-
- /*
- * Shrink the current input buffer.
- * Move it as the raw buffer and create a new input buffer
- */
- processed = ctxt->input->cur - ctxt->input->base;
- xmlBufferShrink(ctxt->input->buf->buffer, processed);
- ctxt->input->buf->raw = ctxt->input->buf->buffer;
- ctxt->input->buf->buffer = xmlBufferCreate();
-
- if (ctxt->html) {
- /*
- * convert as much as possible of the buffer
- */
- nbchars = xmlCharEncInFunc(ctxt->input->buf->encoder,
- ctxt->input->buf->buffer,
- ctxt->input->buf->raw);
- } else {
- /*
- * convert just enough to get
- * '<?xml version="1.0" encoding="xxx"?>'
- * parsed with the autodetected encoding
- * into the parser reading buffer.
- */
- nbchars = xmlCharEncFirstLine(ctxt->input->buf->encoder,
- ctxt->input->buf->buffer,
- ctxt->input->buf->raw);
- }
- if (nbchars < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSwitchToEncoding: encoder error\n");
- return(-1);
- }
- ctxt->input->base =
- ctxt->input->cur = ctxt->input->buf->buffer->content;
- ctxt->input->end =
- &ctxt->input->base[ctxt->input->buf->buffer->use];
-
- }
- return(0);
- } else {
- if ((ctxt->input->length == 0) || (ctxt->input->buf == NULL)) {
- /*
- * When parsing a static memory array one must know the
- * size to be able to convert the buffer.
- */
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlSwitchToEncoding : no input\n");
- return(-1);
- } else {
- int processed;
-
- /*
- * Shrink the current input buffer.
- * Move it as the raw buffer and create a new input buffer
- */
- processed = ctxt->input->cur - ctxt->input->base;
-
- ctxt->input->buf->raw = xmlBufferCreate();
- xmlBufferAdd(ctxt->input->buf->raw, ctxt->input->cur,
- ctxt->input->length - processed);
- ctxt->input->buf->buffer = xmlBufferCreate();
-
- /*
- * convert as much as possible of the raw input
- * to the parser reading buffer.
- */
- nbchars = xmlCharEncInFunc(ctxt->input->buf->encoder,
- ctxt->input->buf->buffer,
- ctxt->input->buf->raw);
- if (nbchars < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSwitchToEncoding: encoder error\n");
- return(-1);
- }
-
- /*
- * Conversion succeeded, get rid of the old buffer
- */
- if ((ctxt->input->free != NULL) &&
- (ctxt->input->base != NULL))
- ctxt->input->free((xmlChar *) ctxt->input->base);
- ctxt->input->base =
- ctxt->input->cur = ctxt->input->buf->buffer->content;
- ctxt->input->end =
- &ctxt->input->base[ctxt->input->buf->buffer->use];
- }
- }
- } else {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlSwitchToEncoding : no input\n");
- return(-1);
- }
- /*
- * The parsing is now done in UTF8 natively
- */
- ctxt->charset = XML_CHAR_ENCODING_UTF8;
- } else
- return(-1);
- return(0);
-
-}
-
-/************************************************************************
- * *
- * Commodity functions to handle entities processing *
- * *
- ************************************************************************/
-
-/**
- * xmlFreeInputStream:
- * @input: an xmlParserInputPtr
- *
- * Free up an input stream.
- */
-void
-xmlFreeInputStream(xmlParserInputPtr input) {
- if (input == NULL) return;
-
- if (input->filename != NULL) xmlFree((char *) input->filename);
- if (input->directory != NULL) xmlFree((char *) input->directory);
- if (input->encoding != NULL) xmlFree((char *) input->encoding);
- if (input->version != NULL) xmlFree((char *) input->version);
- if ((input->free != NULL) && (input->base != NULL))
- input->free((xmlChar *) input->base);
- if (input->buf != NULL)
- xmlFreeParserInputBuffer(input->buf);
- xmlFree(input);
-}
-
-/**
- * xmlNewInputStream:
- * @ctxt: an XML parser context
- *
- * Create a new input stream structure
- * Returns the new input stream or NULL
- */
-xmlParserInputPtr
-xmlNewInputStream(xmlParserCtxtPtr ctxt) {
- xmlParserInputPtr input;
-
- input = (xmlParserInputPtr) xmlMalloc(sizeof(xmlParserInput));
- if (input == NULL) {
- if (ctxt != NULL) {
- ctxt->errNo = XML_ERR_NO_MEMORY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "malloc: couldn't allocate a new input stream\n");
- ctxt->errNo = XML_ERR_NO_MEMORY;
- }
- return(NULL);
- }
- memset(input, 0, sizeof(xmlParserInput));
- input->line = 1;
- input->col = 1;
- input->standalone = -1;
- return(input);
-}
-
-/**
- * xmlNewIOInputStream:
- * @ctxt: an XML parser context
- * @input: an I/O Input
- * @enc: the charset encoding if known
- *
- * Create a new input stream structure encapsulating the @input into
- * a stream suitable for the parser.
- *
- * Returns the new input stream or NULL
- */
-xmlParserInputPtr
-xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr input,
- xmlCharEncoding enc) {
- xmlParserInputPtr inputStream;
-
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext, "new input from I/O\n");
- inputStream = xmlNewInputStream(ctxt);
- if (inputStream == NULL) {
- return(NULL);
- }
- inputStream->filename = NULL;
- inputStream->buf = input;
- inputStream->base = inputStream->buf->buffer->content;
- inputStream->cur = inputStream->buf->buffer->content;
- inputStream->end = &inputStream->base[inputStream->buf->buffer->use];
- if (enc != XML_CHAR_ENCODING_NONE) {
- xmlSwitchEncoding(ctxt, enc);
- }
-
- return(inputStream);
-}
-
-/**
- * xmlNewEntityInputStream:
- * @ctxt: an XML parser context
- * @entity: an Entity pointer
- *
- * Create a new input stream based on an xmlEntityPtr
- *
- * Returns the new input stream or NULL
- */
-xmlParserInputPtr
-xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
- xmlParserInputPtr input;
-
- if (entity == NULL) {
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "internal: xmlNewEntityInputStream entity = NULL\n");
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- return(NULL);
- }
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext,
- "new input from entity: %s\n", entity->name);
- if (entity->content == NULL) {
- switch (entity->etype) {
- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
- ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlNewEntityInputStream unparsed entity !\n");
- break;
- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
- case XML_EXTERNAL_PARAMETER_ENTITY:
- return(xmlLoadExternalEntity((char *) entity->URI,
- (char *) entity->ExternalID, ctxt));
- case XML_INTERNAL_GENERAL_ENTITY:
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Internal entity %s without content !\n", entity->name);
- break;
- case XML_INTERNAL_PARAMETER_ENTITY:
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Internal parameter entity %s without content !\n", entity->name);
- break;
- case XML_INTERNAL_PREDEFINED_ENTITY:
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Predefined entity %s without content !\n", entity->name);
- break;
- }
- return(NULL);
- }
- input = xmlNewInputStream(ctxt);
- if (input == NULL) {
- return(NULL);
- }
- input->filename = (char *) entity->URI;
- input->base = entity->content;
- input->cur = entity->content;
- input->length = entity->length;
- input->end = &entity->content[input->length];
- return(input);
-}
-
-/**
- * xmlNewStringInputStream:
- * @ctxt: an XML parser context
- * @buffer: an memory buffer
- *
- * Create a new input stream based on a memory buffer.
- * Returns the new input stream
- */
-xmlParserInputPtr
-xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
- xmlParserInputPtr input;
-
- if (buffer == NULL) {
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "internal: xmlNewStringInputStream string = NULL\n");
- return(NULL);
- }
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext,
- "new fixed input: %.30s\n", buffer);
- input = xmlNewInputStream(ctxt);
- if (input == NULL) {
- return(NULL);
- }
- input->base = buffer;
- input->cur = buffer;
- input->length = xmlStrlen(buffer);
- input->end = &buffer[input->length];
- return(input);
-}
-
-/**
- * xmlNewInputFromFile:
- * @ctxt: an XML parser context
- * @filename: the filename to use as entity
- *
- * Create a new input stream based on a file.
- *
- * Returns the new input stream or NULL in case of error
- */
-xmlParserInputPtr
-xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) {
- xmlParserInputBufferPtr buf;
- xmlParserInputPtr inputStream;
- char *directory = NULL;
- xmlChar *URI = NULL;
-
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext,
- "new input from file: %s\n", filename);
- if (ctxt == NULL) return(NULL);
- buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
- if (buf == NULL)
- return(NULL);
-
- URI = xmlStrdup((xmlChar *) filename);
- directory = xmlParserGetDirectory((const char *) URI);
-
- inputStream = xmlNewInputStream(ctxt);
- if (inputStream == NULL) {
- if (directory != NULL) xmlFree((char *) directory);
- if (URI != NULL) xmlFree((char *) URI);
- return(NULL);
- }
-
- inputStream->filename = (const char *) URI;
- inputStream->directory = directory;
- inputStream->buf = buf;
-
- inputStream->base = inputStream->buf->buffer->content;
- inputStream->cur = inputStream->buf->buffer->content;
- inputStream->end = &inputStream->base[inputStream->buf->buffer->use];
- if ((ctxt->directory == NULL) && (directory != NULL))
- ctxt->directory = (char *) xmlStrdup((const xmlChar *) directory);
- return(inputStream);
-}
-
-/************************************************************************
- * *
- * Commodity functions to handle parser contexts *
- * *
- ************************************************************************/
-
-/**
- * xmlInitParserCtxt:
- * @ctxt: an XML parser context
- *
- * Initialize a parser context
- */
-
-void
-xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
-{
- if(ctxt==NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlInitParserCtxt: NULL context given\n");
- return;
- }
-
- xmlDefaultSAXHandlerInit();
-
- ctxt->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
- if (ctxt->sax == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlInitParserCtxt: out of memory\n");
- }
- else
- memcpy(ctxt->sax, &xmlDefaultSAXHandler, sizeof(xmlSAXHandler));
-
- /* Allocate the Input stack */
- ctxt->inputTab = (xmlParserInputPtr *)
- xmlMalloc(5 * sizeof(xmlParserInputPtr));
- if (ctxt->inputTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlInitParserCtxt: out of memory\n");
- ctxt->inputNr = 0;
- ctxt->inputMax = 0;
- ctxt->input = NULL;
- return;
- }
- ctxt->inputNr = 0;
- ctxt->inputMax = 5;
- ctxt->input = NULL;
-
- ctxt->version = NULL;
- ctxt->encoding = NULL;
- ctxt->standalone = -1;
- ctxt->hasExternalSubset = 0;
- ctxt->hasPErefs = 0;
- ctxt->html = 0;
- ctxt->external = 0;
- ctxt->instate = XML_PARSER_START;
- ctxt->token = 0;
- ctxt->directory = NULL;
-
- /* Allocate the Node stack */
- ctxt->nodeTab = (xmlNodePtr *) xmlMalloc(10 * sizeof(xmlNodePtr));
- if (ctxt->nodeTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlInitParserCtxt: out of memory\n");
- ctxt->nodeNr = 0;
- ctxt->nodeMax = 0;
- ctxt->node = NULL;
- ctxt->inputNr = 0;
- ctxt->inputMax = 0;
- ctxt->input = NULL;
- return;
- }
- ctxt->nodeNr = 0;
- ctxt->nodeMax = 10;
- ctxt->node = NULL;
-
- /* Allocate the Name stack */
- ctxt->nameTab = (xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
- if (ctxt->nameTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlInitParserCtxt: out of memory\n");
- ctxt->nodeNr = 0;
- ctxt->nodeMax = 0;
- ctxt->node = NULL;
- ctxt->inputNr = 0;
- ctxt->inputMax = 0;
- ctxt->input = NULL;
- ctxt->nameNr = 0;
- ctxt->nameMax = 0;
- ctxt->name = NULL;
- return;
- }
- ctxt->nameNr = 0;
- ctxt->nameMax = 10;
- ctxt->name = NULL;
-
- /* Allocate the space stack */
- ctxt->spaceTab = (int *) xmlMalloc(10 * sizeof(int));
- if (ctxt->spaceTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlInitParserCtxt: out of memory\n");
- ctxt->nodeNr = 0;
- ctxt->nodeMax = 0;
- ctxt->node = NULL;
- ctxt->inputNr = 0;
- ctxt->inputMax = 0;
- ctxt->input = NULL;
- ctxt->nameNr = 0;
- ctxt->nameMax = 0;
- ctxt->name = NULL;
- ctxt->spaceNr = 0;
- ctxt->spaceMax = 0;
- ctxt->space = NULL;
- return;
- }
- ctxt->spaceNr = 1;
- ctxt->spaceMax = 10;
- ctxt->spaceTab[0] = -1;
- ctxt->space = &ctxt->spaceTab[0];
- ctxt->userData = ctxt;
- ctxt->myDoc = NULL;
- ctxt->wellFormed = 1;
- ctxt->valid = 1;
- ctxt->loadsubset = xmlLoadExtDtdDefaultValue;
- ctxt->validate = xmlDoValidityCheckingDefaultValue;
- ctxt->pedantic = xmlPedanticParserDefaultValue;
- ctxt->linenumbers = xmlLineNumbersDefaultValue;
- ctxt->keepBlanks = xmlKeepBlanksDefaultValue;
- if (ctxt->keepBlanks == 0)
- ctxt->sax->ignorableWhitespace = ignorableWhitespace;
-
- ctxt->vctxt.userData = ctxt;
- ctxt->vctxt.error = xmlParserValidityError;
- ctxt->vctxt.warning = xmlParserValidityWarning;
- if (ctxt->validate) {
- if (xmlGetWarningsDefaultValue == 0)
- ctxt->vctxt.warning = NULL;
- else
- ctxt->vctxt.warning = xmlParserValidityWarning;
- ctxt->vctxt.nodeMax = 0;
- }
- ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue;
- ctxt->record_info = 0;
- ctxt->nbChars = 0;
- ctxt->checkIndex = 0;
- ctxt->inSubset = 0;
- ctxt->errNo = XML_ERR_OK;
- ctxt->depth = 0;
- ctxt->charset = XML_CHAR_ENCODING_UTF8;
- ctxt->catalogs = NULL;
- xmlInitNodeInfoSeq(&ctxt->node_seq);
-}
-
-/**
- * xmlFreeParserCtxt:
- * @ctxt: an XML parser context
- *
- * Free all the memory used by a parser context. However the parsed
- * document in ctxt->myDoc is not freed.
- */
-
-void
-xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
-{
- xmlParserInputPtr input;
- xmlChar *oldname;
-
- if (ctxt == NULL) return;
-
- while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
- xmlFreeInputStream(input);
- }
- while ((oldname = namePop(ctxt)) != NULL) { /* Non consuming */
- xmlFree(oldname);
- }
- if (ctxt->spaceTab != NULL) xmlFree(ctxt->spaceTab);
- if (ctxt->nameTab != NULL) xmlFree(ctxt->nameTab);
- if (ctxt->nodeTab != NULL) xmlFree(ctxt->nodeTab);
- if (ctxt->inputTab != NULL) xmlFree(ctxt->inputTab);
- if (ctxt->version != NULL) xmlFree((char *) ctxt->version);
- if (ctxt->encoding != NULL) xmlFree((char *) ctxt->encoding);
- if (ctxt->intSubName != NULL) xmlFree((char *) ctxt->intSubName);
- if (ctxt->extSubURI != NULL) xmlFree((char *) ctxt->extSubURI);
- if (ctxt->extSubSystem != NULL) xmlFree((char *) ctxt->extSubSystem);
- if ((ctxt->sax != NULL) && (ctxt->sax != &xmlDefaultSAXHandler))
- xmlFree(ctxt->sax);
- if (ctxt->directory != NULL) xmlFree((char *) ctxt->directory);
- if (ctxt->vctxt.nodeTab != NULL) xmlFree(ctxt->vctxt.nodeTab);
-#ifdef LIBXML_CATALOG_ENABLED
- if (ctxt->catalogs != NULL)
- xmlCatalogFreeLocal(ctxt->catalogs);
-#endif
- xmlFree(ctxt);
-}
-
-/**
- * xmlNewParserCtxt:
- *
- * Allocate and initialize a new parser context.
- *
- * Returns the xmlParserCtxtPtr or NULL
- */
-
-xmlParserCtxtPtr
-xmlNewParserCtxt()
-{
- xmlParserCtxtPtr ctxt;
-
- ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
- if (ctxt == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewParserCtxt : cannot allocate context\n");
- xmlGenericError(xmlGenericErrorContext, "malloc failed");
- return(NULL);
- }
- memset(ctxt, 0, sizeof(xmlParserCtxt));
- xmlInitParserCtxt(ctxt);
- return(ctxt);
-}
-
-/************************************************************************
- * *
- * Handling of node informations *
- * *
- ************************************************************************/
-
-/**
- * xmlClearParserCtxt:
- * @ctxt: an XML parser context
- *
- * Clear (release owned resources) and reinitialize a parser context
- */
-
-void
-xmlClearParserCtxt(xmlParserCtxtPtr ctxt)
-{
- if (ctxt==NULL)
- return;
- xmlClearNodeInfoSeq(&ctxt->node_seq);
- xmlInitParserCtxt(ctxt);
-}
-
-/**
- * xmlParserFindNodeInfo:
- * @ctx: an XML parser context
- * @node: an XML node within the tree
- *
- * Find the parser node info struct for a given node
- *
- * Returns an xmlParserNodeInfo block pointer or NULL
- */
-const xmlParserNodeInfo* xmlParserFindNodeInfo(const xmlParserCtxtPtr ctx,
- const xmlNodePtr node)
-{
- unsigned long pos;
-
- /* Find position where node should be at */
- pos = xmlParserFindNodeInfoIndex(&ctx->node_seq, node);
- if (pos < ctx->node_seq.length && ctx->node_seq.buffer[pos].node == node)
- return &ctx->node_seq.buffer[pos];
- else
- return NULL;
-}
-
-
-/**
- * xmlInitNodeInfoSeq:
- * @seq: a node info sequence pointer
- *
- * -- Initialize (set to initial state) node info sequence
- */
-void
-xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
-{
- seq->length = 0;
- seq->maximum = 0;
- seq->buffer = NULL;
-}
-
-/**
- * xmlClearNodeInfoSeq:
- * @seq: a node info sequence pointer
- *
- * -- Clear (release memory and reinitialize) node
- * info sequence
- */
-void
-xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
-{
- if ( seq->buffer != NULL )
- xmlFree(seq->buffer);
- xmlInitNodeInfoSeq(seq);
-}
-
-
-/**
- * xmlParserFindNodeInfoIndex:
- * @seq: a node info sequence pointer
- * @node: an XML node pointer
- *
- *
- * xmlParserFindNodeInfoIndex : Find the index that the info record for
- * the given node is or should be at in a sorted sequence
- *
- * Returns a long indicating the position of the record
- */
-unsigned long xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeqPtr seq,
- const xmlNodePtr node)
-{
- unsigned long upper, lower, middle;
- int found = 0;
-
- /* Do a binary search for the key */
- lower = 1;
- upper = seq->length;
- middle = 0;
- while ( lower <= upper && !found) {
- middle = lower + (upper - lower) / 2;
- if ( node == seq->buffer[middle - 1].node )
- found = 1;
- else if ( node < seq->buffer[middle - 1].node )
- upper = middle - 1;
- else
- lower = middle + 1;
- }
-
- /* Return position */
- if ( middle == 0 || seq->buffer[middle - 1].node < node )
- return middle;
- else
- return middle - 1;
-}
-
-
-/**
- * xmlParserAddNodeInfo:
- * @ctxt: an XML parser context
- * @info: a node info sequence pointer
- *
- * Insert node info record into the sorted sequence
- */
-void
-xmlParserAddNodeInfo(xmlParserCtxtPtr ctxt,
- const xmlParserNodeInfoPtr info)
-{
- unsigned long pos;
-
- /* Find pos and check to see if node is already in the sequence */
- pos = xmlParserFindNodeInfoIndex(&ctxt->node_seq, (const xmlNodePtr)
- info->node);
- if (pos < ctxt->node_seq.length
- && ctxt->node_seq.buffer[pos].node == info->node) {
- ctxt->node_seq.buffer[pos] = *info;
- }
-
- /* Otherwise, we need to add new node to buffer */
- else {
- if (ctxt->node_seq.length + 1 > ctxt->node_seq.maximum) {
- xmlParserNodeInfo *tmp_buffer;
- unsigned int byte_size;
-
- if (ctxt->node_seq.maximum == 0)
- ctxt->node_seq.maximum = 2;
- byte_size = (sizeof(*ctxt->node_seq.buffer) *
- (2 * ctxt->node_seq.maximum));
-
- if (ctxt->node_seq.buffer == NULL)
- tmp_buffer = (xmlParserNodeInfo *) xmlMalloc(byte_size);
- else
- tmp_buffer =
- (xmlParserNodeInfo *) xmlRealloc(ctxt->node_seq.buffer,
- byte_size);
-
- if (tmp_buffer == NULL) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "Out of memory\n");
- ctxt->errNo = XML_ERR_NO_MEMORY;
- return;
- }
- ctxt->node_seq.buffer = tmp_buffer;
- ctxt->node_seq.maximum *= 2;
- }
-
- /* If position is not at end, move elements out of the way */
- if (pos != ctxt->node_seq.length) {
- unsigned long i;
-
- for (i = ctxt->node_seq.length; i > pos; i--)
- ctxt->node_seq.buffer[i] = ctxt->node_seq.buffer[i - 1];
- }
-
- /* Copy element and increase length */
- ctxt->node_seq.buffer[pos] = *info;
- ctxt->node_seq.length++;
- }
-}
-
-/************************************************************************
- * *
- * Defaults settings *
- * *
- ************************************************************************/
-/**
- * xmlPedanticParserDefault:
- * @val: int 0 or 1
- *
- * Set and return the previous value for enabling pedantic warnings.
- *
- * Returns the last value for 0 for no substitution, 1 for substitution.
- */
-
-int
-xmlPedanticParserDefault(int val) {
- int old = xmlPedanticParserDefaultValue;
-
- xmlPedanticParserDefaultValue = val;
- return(old);
-}
-
-/**
- * xmlLineNumbersDefault:
- * @val: int 0 or 1
- *
- * Set and return the previous value for enabling line numbers in elements
- * contents. This may break on old application and is turned off by default.
- *
- * Returns the last value for 0 for no substitution, 1 for substitution.
- */
-
-int
-xmlLineNumbersDefault(int val) {
- int old = xmlLineNumbersDefaultValue;
-
- xmlLineNumbersDefaultValue = val;
- return(old);
-}
-
-/**
- * xmlSubstituteEntitiesDefault:
- * @val: int 0 or 1
- *
- * Set and return the previous value for default entity support.
- * Initially the parser always keep entity references instead of substituting
- * entity values in the output. This function has to be used to change the
- * default parser behavior
- * SAX::substituteEntities() has to be used for changing that on a file by
- * file basis.
- *
- * Returns the last value for 0 for no substitution, 1 for substitution.
- */
-
-int
-xmlSubstituteEntitiesDefault(int val) {
- int old = xmlSubstituteEntitiesDefaultValue;
-
- xmlSubstituteEntitiesDefaultValue = val;
- return(old);
-}
-
-/**
- * xmlKeepBlanksDefault:
- * @val: int 0 or 1
- *
- * Set and return the previous value for default blanks text nodes support.
- * The 1.x version of the parser used an heuristic to try to detect
- * ignorable white spaces. As a result the SAX callback was generating
- * ignorableWhitespace() callbacks instead of characters() one, and when
- * using the DOM output text nodes containing those blanks were not generated.
- * The 2.x and later version will switch to the XML standard way and
- * ignorableWhitespace() are only generated when running the parser in
- * validating mode and when the current element doesn't allow CDATA or
- * mixed content.
- * This function is provided as a way to force the standard behavior
- * on 1.X libs and to switch back to the old mode for compatibility when
- * running 1.X client code on 2.X . Upgrade of 1.X code should be done
- * by using xmlIsBlankNode() commodity function to detect the "empty"
- * nodes generated.
- * This value also affect autogeneration of indentation when saving code
- * if blanks sections are kept, indentation is not generated.
- *
- * Returns the last value for 0 for no substitution, 1 for substitution.
- */
-
-int
-xmlKeepBlanksDefault(int val) {
- int old = xmlKeepBlanksDefaultValue;
-
- xmlKeepBlanksDefaultValue = val;
- xmlIndentTreeOutput = !val;
- return(old);
-}
-
-/************************************************************************
- * *
- * Deprecated functions kept for compatibility *
- * *
- ************************************************************************/
-
-/**
- * xmlCheckLanguageID:
- * @lang: pointer to the string value
- *
- * Checks that the value conforms to the LanguageID production:
- *
- * NOTE: this is somewhat deprecated, those productions were removed from
- * the XML Second edition.
- *
- * [33] LanguageID ::= Langcode ('-' Subcode)*
- * [34] Langcode ::= ISO639Code | IanaCode | UserCode
- * [35] ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z])
- * [36] IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+
- * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
- * [38] Subcode ::= ([a-z] | [A-Z])+
- *
- * Returns 1 if correct 0 otherwise
- **/
-int
-xmlCheckLanguageID(const xmlChar *lang) {
- const xmlChar *cur = lang;
-
- if (cur == NULL)
- return(0);
- if (((cur[0] == 'i') && (cur[1] == '-')) ||
- ((cur[0] == 'I') && (cur[1] == '-'))) {
- /*
- * IANA code
- */
- cur += 2;
- while (((cur[0] >= 'A') && (cur[0] <= 'Z')) || /* non input consuming */
- ((cur[0] >= 'a') && (cur[0] <= 'z')))
- cur++;
- } else if (((cur[0] == 'x') && (cur[1] == '-')) ||
- ((cur[0] == 'X') && (cur[1] == '-'))) {
- /*
- * User code
- */
- cur += 2;
- while (((cur[0] >= 'A') && (cur[0] <= 'Z')) || /* non input consuming */
- ((cur[0] >= 'a') && (cur[0] <= 'z')))
- cur++;
- } else if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
- ((cur[0] >= 'a') && (cur[0] <= 'z'))) {
- /*
- * ISO639
- */
- cur++;
- if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
- ((cur[0] >= 'a') && (cur[0] <= 'z')))
- cur++;
- else
- return(0);
- } else
- return(0);
- while (cur[0] != 0) { /* non input consuming */
- if (cur[0] != '-')
- return(0);
- cur++;
- if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
- ((cur[0] >= 'a') && (cur[0] <= 'z')))
- cur++;
- else
- return(0);
- while (((cur[0] >= 'A') && (cur[0] <= 'Z')) || /* non input consuming */
- ((cur[0] >= 'a') && (cur[0] <= 'z')))
- cur++;
- }
- return(1);
-}
-
-/**
- * xmlDecodeEntities:
- * @ctxt: the parser context
- * @len: the len to decode (in bytes !), -1 for no size limit
- * @what: combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
- * @end: an end marker xmlChar, 0 if none
- * @end2: an end marker xmlChar, 0 if none
- * @end3: an end marker xmlChar, 0 if none
- *
- * This function is deprecated, we now always process entities content
- * through xmlStringDecodeEntities
- *
- * TODO: remove it in next major release.
- *
- * [67] Reference ::= EntityRef | CharRef
- *
- * [69] PEReference ::= '%' Name ';'
- *
- * Returns A newly allocated string with the substitution done. The caller
- * must deallocate it !
- */
-xmlChar *
-xmlDecodeEntities(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED, int what ATTRIBUTE_UNUSED,
- xmlChar end ATTRIBUTE_UNUSED, xmlChar end2 ATTRIBUTE_UNUSED, xmlChar end3 ATTRIBUTE_UNUSED) {
-#if 0
- xmlChar *buffer = NULL;
- unsigned int buffer_size = 0;
- unsigned int nbchars = 0;
-
- xmlChar *current = NULL;
- xmlEntityPtr ent;
- unsigned int max = (unsigned int) len;
- int c,l;
-#endif
-
- static int deprecated = 0;
- if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlDecodeEntities() deprecated function reached\n");
- deprecated = 1;
- }
-
-#if 0
- if (ctxt->depth > 40) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "Detected entity reference loop\n");
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- ctxt->errNo = XML_ERR_ENTITY_LOOP;
- return(NULL);
- }
-
- /*
- * allocate a translation buffer.
- */
- buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
- buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar));
- if (buffer == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlDecodeEntities: malloc failed");
- return(NULL);
- }
-
- /*
- * OK loop until we reach one of the ending char or a size limit.
- */
- GROW;
- c = CUR_CHAR(l);
- while ((nbchars < max) && (c != end) && /* NOTUSED */
- (c != end2) && (c != end3)) {
- GROW;
- if (c == 0) break;
- if ((c == '&') && (NXT(1) == '#')) {
- int val = xmlParseCharRef(ctxt);
- COPY_BUF(0,buffer,nbchars,val);
- NEXTL(l);
- } else if (c == '&') &&
- (what & XML_SUBSTITUTE_REF)) {
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext,
- "decoding Entity Reference\n");
- ent = xmlParseEntityRef(ctxt);
- if ((ent != NULL) &&
- (ctxt->replaceEntities != 0)) {
- current = ent->content;
- while (*current != 0) { /* non input consuming loop */
- buffer[nbchars++] = *current++;
- if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
- growBuffer(buffer);
- }
- }
- } else if (ent != NULL) {
- const xmlChar *cur = ent->name;
-
- buffer[nbchars++] = '&';
- if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
- growBuffer(buffer);
- }
- while (*cur != 0) { /* non input consuming loop */
- buffer[nbchars++] = *cur++;
- }
- buffer[nbchars++] = ';';
- }
- } else if (c == '%' && (what & XML_SUBSTITUTE_PEREF)) {
- /*
- * a PEReference induce to switch the entity flow,
- * we break here to flush the current set of chars
- * parsed if any. We will be called back later.
- */
- if (xmlParserDebugEntities)
- xmlGenericError(xmlGenericErrorContext,
- "decoding PE Reference\n");
- if (nbchars != 0) break;
-
- xmlParsePEReference(ctxt);
-
- /*
- * Pop-up of finished entities.
- */
- while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */
- xmlPopInput(ctxt);
-
- break;
- } else {
- COPY_BUF(l,buffer,nbchars,c);
- NEXTL(l);
- if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
- growBuffer(buffer);
- }
- }
- c = CUR_CHAR(l);
- }
- buffer[nbchars++] = 0;
- return(buffer);
-#endif
- return(NULL);
-}
-
-/**
- * xmlNamespaceParseNCName:
- * @ctxt: an XML parser context
- *
- * parse an XML namespace name.
- *
- * TODO: this seems not in use anymore, the namespace handling is done on
- * top of the SAX interfaces, i.e. not on raw input.
- *
- * [NS 3] NCName ::= (Letter | '_') (NCNameChar)*
- *
- * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
- * CombiningChar | Extender
- *
- * Returns the namespace name or NULL
- */
-
-xmlChar *
-xmlNamespaceParseNCName(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED) {
-#if 0
- xmlChar buf[XML_MAX_NAMELEN + 5];
- int len = 0, l;
- int cur = CUR_CHAR(l);
-#endif
-
- static int deprecated = 0;
- if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNamespaceParseNCName() deprecated function reached\n");
- deprecated = 1;
- }
-
-#if 0
- /* load first the value of the char !!! */
- GROW;
- if (!IS_LETTER(cur) && (cur != '_')) return(NULL);
-
-xmlGenericError(xmlGenericErrorContext,
- "xmlNamespaceParseNCName: reached loop 3\n");
- while ((IS_LETTER(cur)) || (IS_DIGIT(cur)) || /* NOT REACHED */
- (cur == '.') || (cur == '-') ||
- (cur == '_') ||
- (IS_COMBINING(cur)) ||
- (IS_EXTENDER(cur))) {
- COPY_BUF(l,buf,len,cur);
- NEXTL(l);
- cur = CUR_CHAR(l);
- if (len >= XML_MAX_NAMELEN) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNamespaceParseNCName: reached XML_MAX_NAMELEN limit\n");
- while ((IS_LETTER(cur)) || (IS_DIGIT(cur)) ||/* NOT REACHED */
- (cur == '.') || (cur == '-') ||
- (cur == '_') ||
- (IS_COMBINING(cur)) ||
- (IS_EXTENDER(cur))) {
- NEXTL(l);
- cur = CUR_CHAR(l);
- }
- break;
- }
- }
- return(xmlStrndup(buf, len));
-#endif
- return(NULL);
-}
-
-/**
- * xmlNamespaceParseQName:
- * @ctxt: an XML parser context
- * @prefix: a xmlChar **
- *
- * TODO: this seems not in use anymore, the namespace handling is done on
- * top of the SAX interfaces, i.e. not on raw input.
- *
- * parse an XML qualified name
- *
- * [NS 5] QName ::= (Prefix ':')? LocalPart
- *
- * [NS 6] Prefix ::= NCName
- *
- * [NS 7] LocalPart ::= NCName
- *
- * Returns the local part, and prefix is updated
- * to get the Prefix if any.
- */
-
-xmlChar *
-xmlNamespaceParseQName(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED, xmlChar **prefix ATTRIBUTE_UNUSED) {
-
- static int deprecated = 0;
- if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNamespaceParseQName() deprecated function reached\n");
- deprecated = 1;
- }
-
-#if 0
- xmlChar *ret = NULL;
-
- *prefix = NULL;
- ret = xmlNamespaceParseNCName(ctxt);
- if (RAW == ':') {
- *prefix = ret;
- NEXT;
- ret = xmlNamespaceParseNCName(ctxt);
- }
-
- return(ret);
-#endif
- return(NULL);
-}
-
-/**
- * xmlNamespaceParseNSDef:
- * @ctxt: an XML parser context
- *
- * parse a namespace prefix declaration
- *
- * TODO: this seems not in use anymore, the namespace handling is done on
- * top of the SAX interfaces, i.e. not on raw input.
- *
- * [NS 1] NSDef ::= PrefixDef Eq SystemLiteral
- *
- * [NS 2] PrefixDef ::= 'xmlns' (':' NCName)?
- *
- * Returns the namespace name
- */
-
-xmlChar *
-xmlNamespaceParseNSDef(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED) {
- static int deprecated = 0;
- if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNamespaceParseNSDef() deprecated function reached\n");
- deprecated = 1;
- }
- return(NULL);
-#if 0
- xmlChar *name = NULL;
-
- if ((RAW == 'x') && (NXT(1) == 'm') &&
- (NXT(2) == 'l') && (NXT(3) == 'n') &&
- (NXT(4) == 's')) {
- SKIP(5);
- if (RAW == ':') {
- NEXT;
- name = xmlNamespaceParseNCName(ctxt);
- }
- }
- return(name);
-#endif
-}
-
-/**
- * xmlParseQuotedString:
- * @ctxt: an XML parser context
- *
- * Parse and return a string between quotes or doublequotes
- *
- * TODO: Deprecated, to be removed at next drop of binary compatibility
- *
- * Returns the string parser or NULL.
- */
-xmlChar *
-xmlParseQuotedString(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED) {
- static int deprecated = 0;
- if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlParseQuotedString() deprecated function reached\n");
- deprecated = 1;
- }
- return(NULL);
-
-#if 0
- xmlChar *buf = NULL;
- int len = 0,l;
- int size = XML_PARSER_BUFFER_SIZE;
- int c;
-
- buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc of %d byte failed\n", size);
- return(NULL);
- }
-xmlGenericError(xmlGenericErrorContext,
- "xmlParseQuotedString: reached loop 4\n");
- if (RAW == '"') {
- NEXT;
- c = CUR_CHAR(l);
- while (IS_CHAR(c) && (c != '"')) { /* NOTUSED */
- if (len + 5 >= size) {
- size *= 2;
- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc of %d byte failed\n", size);
- return(NULL);
- }
- }
- COPY_BUF(l,buf,len,c);
- NEXTL(l);
- c = CUR_CHAR(l);
- }
- if (c != '"') {
- ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "String not closed \"%.50s\"\n", buf);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- NEXT;
- }
- } else if (RAW == '\''){
- NEXT;
- c = CUR;
- while (IS_CHAR(c) && (c != '\'')) { /* NOTUSED */
- if (len + 1 >= size) {
- size *= 2;
- buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
- if (buf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc of %d byte failed\n", size);
- return(NULL);
- }
- }
- buf[len++] = c;
- NEXT;
- c = CUR;
- }
- if (RAW != '\'') {
- ctxt->errNo = XML_ERR_STRING_NOT_CLOSED;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "String not closed \"%.50s\"\n", buf);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- } else {
- NEXT;
- }
- }
- return(buf);
-#endif
-}
-
-/**
- * xmlParseNamespace:
- * @ctxt: an XML parser context
- *
- * xmlParseNamespace: parse specific PI '<?namespace ...' constructs.
- *
- * This is what the older xml-name Working Draft specified, a bunch of
- * other stuff may still rely on it, so support is still here as
- * if it was declared on the root of the Tree:-(
- *
- * TODO: remove from library
- *
- * To be removed at next drop of binary compatibility
- */
-
-void
-xmlParseNamespace(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED) {
- static int deprecated = 0;
- if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlParseNamespace() deprecated function reached\n");
- deprecated = 1;
- }
-
-#if 0
- xmlChar *href = NULL;
- xmlChar *prefix = NULL;
- int garbage = 0;
-
- /*
- * We just skipped "namespace" or "xml:namespace"
- */
- SKIP_BLANKS;
-
-xmlGenericError(xmlGenericErrorContext,
- "xmlParseNamespace: reached loop 5\n");
- while (IS_CHAR(RAW) && (RAW != '>')) { /* NOT REACHED */
- /*
- * We can have "ns" or "prefix" attributes
- * Old encoding as 'href' or 'AS' attributes is still supported
- */
- if ((RAW == 'n') && (NXT(1) == 's')) {
- garbage = 0;
- SKIP(2);
- SKIP_BLANKS;
-
- if (RAW != '=') continue;
- NEXT;
- SKIP_BLANKS;
-
- href = xmlParseQuotedString(ctxt);
- SKIP_BLANKS;
- } else if ((RAW == 'h') && (NXT(1) == 'r') &&
- (NXT(2) == 'e') && (NXT(3) == 'f')) {
- garbage = 0;
- SKIP(4);
- SKIP_BLANKS;
-
- if (RAW != '=') continue;
- NEXT;
- SKIP_BLANKS;
-
- href = xmlParseQuotedString(ctxt);
- SKIP_BLANKS;
- } else if ((RAW == 'p') && (NXT(1) == 'r') &&
- (NXT(2) == 'e') && (NXT(3) == 'f') &&
- (NXT(4) == 'i') && (NXT(5) == 'x')) {
- garbage = 0;
- SKIP(6);
- SKIP_BLANKS;
-
- if (RAW != '=') continue;
- NEXT;
- SKIP_BLANKS;
-
- prefix = xmlParseQuotedString(ctxt);
- SKIP_BLANKS;
- } else if ((RAW == 'A') && (NXT(1) == 'S')) {
- garbage = 0;
- SKIP(2);
- SKIP_BLANKS;
-
- if (RAW != '=') continue;
- NEXT;
- SKIP_BLANKS;
-
- prefix = xmlParseQuotedString(ctxt);
- SKIP_BLANKS;
- } else if ((RAW == '?') && (NXT(1) == '>')) {
- garbage = 0;
- NEXT;
- } else {
- /*
- * Found garbage when parsing the namespace
- */
- if (!garbage) {
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData,
- "xmlParseNamespace found garbage\n");
- }
- ctxt->errNo = XML_ERR_NS_DECL_ERROR;
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- NEXT;
- }
- }
-
- MOVETO_ENDTAG(CUR_PTR);
- NEXT;
-
- /*
- * Register the DTD.
- if (href != NULL)
- if ((ctxt->sax != NULL) && (ctxt->sax->globalNamespace != NULL))
- ctxt->sax->globalNamespace(ctxt->userData, href, prefix);
- */
-
- if (prefix != NULL) xmlFree(prefix);
- if (href != NULL) xmlFree(href);
-#endif
-}
-
-/**
- * xmlScanName:
- * @ctxt: an XML parser context
- *
- * Trickery: parse an XML name but without consuming the input flow
- * Needed for rollback cases. Used only when parsing entities references.
- *
- * TODO: seems deprecated now, only used in the default part of
- * xmlParserHandleReference
- *
- * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
- * CombiningChar | Extender
- *
- * [5] Name ::= (Letter | '_' | ':') (NameChar)*
- *
- * [6] Names ::= Name (S Name)*
- *
- * Returns the Name parsed or NULL
- */
-
-xmlChar *
-xmlScanName(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED) {
- static int deprecated = 0;
- if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlScanName() deprecated function reached\n");
- deprecated = 1;
- }
- return(NULL);
-
-#if 0
- xmlChar buf[XML_MAX_NAMELEN];
- int len = 0;
-
- GROW;
- if (!IS_LETTER(RAW) && (RAW != '_') &&
- (RAW != ':')) {
- return(NULL);
- }
-
-
- while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) || /* NOT REACHED */
- (NXT(len) == '.') || (NXT(len) == '-') ||
- (NXT(len) == '_') || (NXT(len) == ':') ||
- (IS_COMBINING(NXT(len))) ||
- (IS_EXTENDER(NXT(len)))) {
- GROW;
- buf[len] = NXT(len);
- len++;
- if (len >= XML_MAX_NAMELEN) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlScanName: reached XML_MAX_NAMELEN limit\n");
- while ((IS_LETTER(NXT(len))) || /* NOT REACHED */
- (IS_DIGIT(NXT(len))) ||
- (NXT(len) == '.') || (NXT(len) == '-') ||
- (NXT(len) == '_') || (NXT(len) == ':') ||
- (IS_COMBINING(NXT(len))) ||
- (IS_EXTENDER(NXT(len))))
- len++;
- break;
- }
- }
- return(xmlStrndup(buf, len));
-#endif
-}
-
-/**
- * xmlParserHandleReference:
- * @ctxt: the parser context
- *
- * TODO: Remove, now deprecated ... the test is done directly in the
- * content parsing
- * routines.
- *
- * [67] Reference ::= EntityRef | CharRef
- *
- * [68] EntityRef ::= '&' Name ';'
- *
- * [ WFC: Entity Declared ]
- * the Name given in the entity reference must match that in an entity
- * declaration, except that well-formed documents need not declare any
- * of the following entities: amp, lt, gt, apos, quot.
- *
- * [ WFC: Parsed Entity ]
- * An entity reference must not contain the name of an unparsed entity
- *
- * [66] CharRef ::= '&#' [0-9]+ ';' |
- * '&#x' [0-9a-fA-F]+ ';'
- *
- * A PEReference may have been detected in the current input stream
- * the handling is done accordingly to
- * http://www.w3.org/TR/REC-xml#entproc
- */
-void
-xmlParserHandleReference(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED) {
- static int deprecated = 0;
- if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlParserHandleReference() deprecated function reached\n");
- deprecated = 1;
- }
-
- return;
-}
-
-/**
- * xmlHandleEntity:
- * @ctxt: an XML parser context
- * @entity: an XML entity pointer.
- *
- * Default handling of defined entities, when should we define a new input
- * stream ? When do we just handle that as a set of chars ?
- *
- * OBSOLETE: to be removed at some point.
- */
-
-void
-xmlHandleEntity(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED, xmlEntityPtr entity ATTRIBUTE_UNUSED) {
- static int deprecated = 0;
- if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlHandleEntity() deprecated function reached\n");
- deprecated = 1;
- }
-
-#if 0
- int len;
- xmlParserInputPtr input;
-
- if (entity->content == NULL) {
- ctxt->errNo = XML_ERR_INTERNAL_ERROR;
- if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt->userData, "xmlHandleEntity %s: content == NULL\n",
- entity->name);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- return;
- }
- len = xmlStrlen(entity->content);
- if (len <= 2) goto handle_as_char;
-
- /*
- * Redefine its content as an input stream.
- */
- input = xmlNewEntityInputStream(ctxt, entity);
- xmlPushInput(ctxt, input);
- return;
-
-handle_as_char:
- /*
- * Just handle the content as a set of chars.
- */
- if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
- (ctxt->sax->characters != NULL))
- ctxt->sax->characters(ctxt->userData, entity->content, len);
-#endif
-}
-
-/**
- * xmlNewGlobalNs:
- * @doc: the document carrying the namespace
- * @href: the URI associated
- * @prefix: the prefix for the namespace
- *
- * Creation of a Namespace, the old way using PI and without scoping
- * DEPRECATED !!!
- * It now create a namespace on the root element of the document if found.
- * Returns NULL this functionality had been removed
- */
-xmlNsPtr
-xmlNewGlobalNs(xmlDocPtr doc ATTRIBUTE_UNUSED, const xmlChar *href ATTRIBUTE_UNUSED,
- const xmlChar *prefix ATTRIBUTE_UNUSED) {
- static int deprecated = 0;
- if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewGlobalNs() deprecated function reached\n");
- deprecated = 1;
- }
- return(NULL);
-#if 0
- xmlNodePtr root;
-
- xmlNsPtr cur;
-
- root = xmlDocGetRootElement(doc);
- if (root != NULL)
- return(xmlNewNs(root, href, prefix));
-
- /*
- * if there is no root element yet, create an old Namespace type
- * and it will be moved to the root at save time.
- */
- cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewGlobalNs : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlNs));
- cur->type = XML_GLOBAL_NAMESPACE;
-
- if (href != NULL)
- cur->href = xmlStrdup(href);
- if (prefix != NULL)
- cur->prefix = xmlStrdup(prefix);
-
- /*
- * Add it at the end to preserve parsing order ...
- */
- if (doc != NULL) {
- if (doc->oldNs == NULL) {
- doc->oldNs = cur;
- } else {
- xmlNsPtr prev = doc->oldNs;
-
- while (prev->next != NULL) prev = prev->next;
- prev->next = cur;
- }
- }
-
- return(NULL);
-#endif
-}
-
-/**
- * xmlUpgradeOldNs:
- * @doc: a document pointer
- *
- * Upgrade old style Namespaces (PI) and move them to the root of the document.
- * DEPRECATED
- */
-void
-xmlUpgradeOldNs(xmlDocPtr doc ATTRIBUTE_UNUSED) {
- static int deprecated = 0;
- if (!deprecated) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlUpgradeOldNs() deprecated function reached\n");
- deprecated = 1;
- }
-#if 0
- xmlNsPtr cur;
-
- if ((doc == NULL) || (doc->oldNs == NULL)) return;
- if (doc->children == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlUpgradeOldNs: failed no root !\n");
-#endif
- return;
- }
-
- cur = doc->oldNs;
- while (cur->next != NULL) {
- cur->type = XML_LOCAL_NAMESPACE;
- cur = cur->next;
- }
- cur->type = XML_LOCAL_NAMESPACE;
- cur->next = doc->children->nsDef;
- doc->children->nsDef = doc->oldNs;
- doc->oldNs = NULL;
-#endif
-}
-
diff --git a/bundle/libxml/stamp-h.in b/bundle/libxml/stamp-h.in
deleted file mode 100644
index 9788f70238..0000000000
--- a/bundle/libxml/stamp-h.in
+++ /dev/null
@@ -1 +0,0 @@
-timestamp
diff --git a/bundle/libxml/threads.c b/bundle/libxml/threads.c
deleted file mode 100644
index 6aa5ecc307..0000000000
--- a/bundle/libxml/threads.c
+++ /dev/null
@@ -1,537 +0,0 @@
-/**
- * threads.c: set of generic threading related routines
- *
- * See Copyright for the status of this software.
- *
- * Gary Pennington <Gary.Pennington@uk.sun.com>
- * daniel@veillard.com
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#include <string.h>
-
-#include <libxml/threads.h>
-#include <libxml/globals.h>
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
-
-#ifdef HAVE_WIN32_THREADS
-#include <windows.h>
-#ifndef HAVE_COMPILER_TLS
-#include <process.h>
-#endif
-#endif
-
-#if defined(SOLARIS)
-#include <note.h>
-#endif
-
-/* #define DEBUG_THREADS */
-
-/*
- * TODO: this module still uses malloc/free and not xmlMalloc/xmlFree
- * to avoid some crazyness since xmlMalloc/xmlFree may actually
- * be hosted on allocated blocks needing them for the allocation ...
- */
-
-/*
- * xmlMutex are a simple mutual exception locks
- */
-struct _xmlMutex {
-#ifdef HAVE_PTHREAD_H
- pthread_mutex_t lock;
-#elif defined HAVE_WIN32_THREADS
- HANDLE mutex;
-#else
- int empty;
-#endif
-};
-
-/*
- * xmlRMutex are reentrant mutual exception locks
- */
-struct _xmlRMutex {
-#ifdef HAVE_PTHREAD_H
- pthread_mutex_t lock;
- unsigned int held;
- unsigned int waiters;
- pthread_t tid;
- pthread_cond_t cv;
-#elif defined HAVE_WIN32_THREADS
- CRITICAL_SECTION cs;
- unsigned int count;
-#else
- int empty;
-#endif
-};
-/*
- * This module still has some internal static data.
- * - xmlLibraryLock a global lock
- * - globalkey used for per-thread data
- */
-
-#ifdef HAVE_PTHREAD_H
-static pthread_key_t globalkey;
-static pthread_t mainthread;
-static pthread_once_t once_control = PTHREAD_ONCE_INIT;
-#elif defined HAVE_WIN32_THREADS
-#if defined(HAVE_COMPILER_TLS)
-static __declspec(thread) xmlGlobalState tlstate;
-static __declspec(thread) int tlstate_inited = 0;
-#else /* HAVE_COMPILER_TLS */
-static DWORD globalkey;
-#endif /* HAVE_COMPILER_TLS */
-static DWORD mainthread;
-static int run_once_init = 1;
-#endif /* HAVE_WIN32_THREADS */
-
-static xmlRMutexPtr xmlLibraryLock = NULL;
-static void xmlOnceInit(void);
-
-/**
- * xmlNewMutex:
- *
- * xmlNewMutex() is used to allocate a libxml2 token struct for use in
- * synchronizing access to data.
- *
- * Returns a new simple mutex pointer or NULL in case of error
- */
-xmlMutexPtr
-xmlNewMutex(void)
-{
- xmlMutexPtr tok;
-
- if ((tok = malloc(sizeof(xmlMutex))) == NULL)
- return (NULL);
-#ifdef HAVE_PTHREAD_H
- pthread_mutex_init(&tok->lock, NULL);
-#elif defined HAVE_WIN32_THREADS
- tok->mutex = CreateMutex(NULL, FALSE, NULL);
-#endif
- return (tok);
-}
-
-/**
- * xmlFreeMutex:
- * @tok: the simple mutex
- *
- * xmlFreeMutex() is used to reclaim resources associated with a libxml2 token
- * struct.
- */
-void
-xmlFreeMutex(xmlMutexPtr tok)
-{
-#ifdef HAVE_PTHREAD_H
- pthread_mutex_destroy(&tok->lock);
-#elif defined HAVE_WIN32_THREADS
- CloseHandle(tok->mutex);
-#endif
- free(tok);
-}
-
-/**
- * xmlMutexLock:
- * @tok: the simple mutex
- *
- * xmlMutexLock() is used to lock a libxml2 token.
- */
-void
-xmlMutexLock(xmlMutexPtr tok ATTRIBUTE_UNUSED)
-{
-#ifdef HAVE_PTHREAD_H
- pthread_mutex_lock(&tok->lock);
-#elif defined HAVE_WIN32_THREADS
- WaitForSingleObject(tok->mutex, INFINITE);
-#endif
-
-}
-
-/**
- * xmlMutexUnlock:
- * @tok: the simple mutex
- *
- * xmlMutexUnlock() is used to unlock a libxml2 token.
- */
-void
-xmlMutexUnlock(xmlMutexPtr tok ATTRIBUTE_UNUSED)
-{
-#ifdef HAVE_PTHREAD_H
- pthread_mutex_unlock(&tok->lock);
-#elif defined HAVE_WIN32_THREADS
- ReleaseMutex(tok->mutex);
-#endif
-}
-
-/**
- * xmlNewRMutex:
- *
- * xmlRNewMutex() is used to allocate a reentrant mutex for use in
- * synchronizing access to data. token_r is a re-entrant lock and thus useful
- * for synchronizing access to data structures that may be manipulated in a
- * recursive fashion.
- *
- * Returns the new reentrant mutex pointer or NULL in case of error
- */
-xmlRMutexPtr
-xmlNewRMutex(void)
-{
- xmlRMutexPtr tok;
-
- if ((tok = malloc(sizeof(xmlRMutex))) == NULL)
- return (NULL);
-#ifdef HAVE_PTHREAD_H
- pthread_mutex_init(&tok->lock, NULL);
- tok->held = 0;
- tok->waiters = 0;
-#elif defined HAVE_WIN32_THREADS
- InitializeCriticalSection(&tok->cs);
- tok->count = 0;
-#endif
- return (tok);
-}
-
-/**
- * xmlFreeRMutex:
- * @tok: the reentrant mutex
- *
- * xmlRFreeMutex() is used to reclaim resources associated with a
- * reentrant mutex.
- */
-void
-xmlFreeRMutex(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
-{
-#ifdef HAVE_PTHREAD_H
- pthread_mutex_destroy(&tok->lock);
-#elif defined HAVE_WIN32_THREADS
- DeleteCriticalSection(&tok->cs);
-#endif
- free(tok);
-}
-
-/**
- * xmlRMutexLock:
- * @tok: the reentrant mutex
- *
- * xmlRMutexLock() is used to lock a libxml2 token_r.
- */
-void
-xmlRMutexLock(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
-{
-#ifdef HAVE_PTHREAD_H
- pthread_mutex_lock(&tok->lock);
- if (tok->held) {
- if (pthread_equal(tok->tid, pthread_self())) {
- tok->held++;
- pthread_mutex_unlock(&tok->lock);
- return;
- } else {
- tok->waiters++;
- while (tok->held)
- pthread_cond_wait(&tok->cv, &tok->lock);
- tok->waiters--;
- }
- }
- tok->tid = pthread_self();
- tok->held = 1;
- pthread_mutex_unlock(&tok->lock);
-#elif defined HAVE_WIN32_THREADS
- EnterCriticalSection(&tok->cs);
- ++tok->count;
-#endif
-}
-
-/**
- * xmlRMutexUnlock:
- * @tok: the reentrant mutex
- *
- * xmlRMutexUnlock() is used to unlock a libxml2 token_r.
- */
-void
-xmlRMutexUnlock(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
-{
-#ifdef HAVE_PTHREAD_H
- pthread_mutex_lock(&tok->lock);
- tok->held--;
- if (tok->held == 0) {
- if (tok->waiters)
- pthread_cond_signal(&tok->cv);
- tok->tid = 0;
- }
- pthread_mutex_unlock(&tok->lock);
-#elif defined HAVE_WIN32_THREADS
- if (!--tok->count)
- LeaveCriticalSection(&tok->cs);
-#endif
-}
-
-/************************************************************************
- * *
- * Per thread global state handling *
- * *
- ************************************************************************/
-
-#ifdef LIBXML_THREAD_ENABLED
-/**
- * xmlFreeGlobalState:
- * @state: a thread global state
- *
- * xmlFreeGlobalState() is called when a thread terminates with a non-NULL
- * global state. It is is used here to reclaim memory resources.
- */
-static void
-xmlFreeGlobalState(void *state)
-{
- free(state);
-}
-
-/**
- * xmlNewGlobalState:
- *
- * xmlNewGlobalState() allocates a global state. This structure is used to
- * hold all data for use by a thread when supporting backwards compatibility
- * of libxml2 to pre-thread-safe behaviour.
- *
- * Returns the newly allocated xmlGlobalStatePtr or NULL in case of error
- */
-static xmlGlobalStatePtr
-xmlNewGlobalState(void)
-{
- xmlGlobalState *gs;
-
- gs = malloc(sizeof(xmlGlobalState));
- if (gs == NULL)
- return(NULL);
-
- memset(gs, 0, sizeof(xmlGlobalState));
- xmlInitializeGlobalState(gs);
- return (gs);
-}
-#endif /* LIBXML_THREAD_ENABLED */
-
-
-#ifdef HAVE_WIN32_THREADS
-#if !defined(HAVE_COMPILER_TLS)
-typedef struct _xmlGlobalStateCleanupHelperParams
-{
- HANDLE thread;
- void *memory;
-} xmlGlobalStateCleanupHelperParams;
-
-static void xmlGlobalStateCleanupHelper (void *p)
-{
- xmlGlobalStateCleanupHelperParams *params = (xmlGlobalStateCleanupHelperParams *) p;
- WaitForSingleObject(params->thread, INFINITE);
- CloseHandle(params->thread);
- xmlFreeGlobalState(params->memory);
- free(params);
- _endthread();
-}
-#endif /* HAVE_COMPILER_TLS */
-#endif /* HAVE_WIN32_THREADS */
-
-/**
- * xmlGetGlobalState:
- *
- * xmlGetGlobalState() is called to retrieve the global state for a thread.
- *
- * Returns the thread global state or NULL in case of error
- */
-xmlGlobalStatePtr
-xmlGetGlobalState(void)
-{
-#ifdef HAVE_PTHREAD_H
- xmlGlobalState *globalval;
-
- pthread_once(&once_control, xmlOnceInit);
-
- if ((globalval = (xmlGlobalState *)
- pthread_getspecific(globalkey)) == NULL) {
- xmlGlobalState *tsd = xmlNewGlobalState();
-
- pthread_setspecific(globalkey, tsd);
- return (tsd);
- }
- return (globalval);
-#elif defined HAVE_WIN32_THREADS
-#if defined(HAVE_COMPILER_TLS)
- if (!tlstate_inited) {
- tlstate_inited = 1;
- xmlInitializeGlobalState(&tlstate);
- }
- return &tlstate;
-#else /* HAVE_COMPILER_TLS */
- xmlGlobalState *globalval;
-
- if (run_once_init) {
- run_once_init = 0;
- xmlOnceInit();
- }
- if ((globalval = (xmlGlobalState *) TlsGetValue(globalkey)) == NULL) {
- xmlGlobalState *tsd = xmlNewGlobalState();
- xmlGlobalStateCleanupHelperParams *p =
- (xmlGlobalStateCleanupHelperParams *) malloc(sizeof(xmlGlobalStateCleanupHelperParams));
- p->memory = tsd;
- DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
- GetCurrentProcess(), &p->thread, 0, TRUE, DUPLICATE_SAME_ACCESS);
- TlsSetValue(globalkey, tsd);
- _beginthread(xmlGlobalStateCleanupHelper, 0, p);
-
- return (tsd);
- }
- return (globalval);
-#endif /* HAVE_COMPILER_TLS */
-#else
- return(NULL);
-#endif
-}
-
-/************************************************************************
- * *
- * Library wide thread interfaces *
- * *
- ************************************************************************/
-
-/**
- * xmlGetThreadId:
- *
- * xmlGetThreadId() find the current thread ID number
- *
- * Returns the current thread ID number
- */
-int
-xmlGetThreadId(void)
-{
-#ifdef HAVE_PTHREAD_H
- return((int) pthread_self());
-#elif defined HAVE_WIN32_THREADS
- return GetCurrentThreadId();
-#else
- return((int) 0);
-#endif
-}
-
-/**
- * xmlIsMainThread:
- *
- * xmlIsMainThread() check whether the current thread is the main thread.
- *
- * Returns 1 if the current thread is the main thread, 0 otherwise
- */
-int
-xmlIsMainThread(void)
-{
-#ifdef HAVE_PTHREAD_H
- pthread_once(&once_control, xmlOnceInit);
-#elif defined HAVE_WIN32_THREADS
- if (run_once_init) {
- run_once_init = 0;
- xmlOnceInit ();
- }
-#endif
-
-#ifdef DEBUG_THREADS
- xmlGenericError(xmlGenericErrorContext, "xmlIsMainThread()\n");
-#endif
-#ifdef HAVE_PTHREAD_H
- return(mainthread == pthread_self());
-#elif defined HAVE_WIN32_THREADS
- return(mainthread == GetCurrentThreadId ());
-#else
- return(1);
-#endif
-}
-
-/**
- * xmlLockLibrary:
- *
- * xmlLockLibrary() is used to take out a re-entrant lock on the libxml2
- * library.
- */
-void
-xmlLockLibrary(void)
-{
-#ifdef DEBUG_THREADS
- xmlGenericError(xmlGenericErrorContext, "xmlLockLibrary()\n");
-#endif
- xmlRMutexLock(xmlLibraryLock);
-}
-
-/**
- * xmlUnlockLibrary:
- *
- * xmlUnlockLibrary() is used to release a re-entrant lock on the libxml2
- * library.
- */
-void
-xmlUnlockLibrary(void)
-{
-#ifdef DEBUG_THREADS
- xmlGenericError(xmlGenericErrorContext, "xmlUnlockLibrary()\n");
-#endif
- xmlRMutexUnlock(xmlLibraryLock);
-}
-
-/**
- * xmlInitThreads:
- *
- * xmlInitThreads() is used to to initialize all the thread related
- * data of the libxml2 library.
- */
-void
-xmlInitThreads(void)
-{
-#ifdef DEBUG_THREADS
- xmlGenericError(xmlGenericErrorContext, "xmlInitThreads()\n");
-#endif
-}
-
-/**
- * xmlCleanupThreads:
- *
- * xmlCleanupThreads() is used to to cleanup all the thread related
- * data of the libxml2 library once processing has ended.
- */
-void
-xmlCleanupThreads(void)
-{
-#ifdef DEBUG_THREADS
- xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n");
-#endif
-}
-
-/**
- * xmlOnceInit
- *
- * xmlOnceInit() is used to initialize the value of mainthread for use
- * in other routines. This function should only be called using
- * pthread_once() in association with the once_control variable to ensure
- * that the function is only called once. See man pthread_once for more
- * details.
- */
-static void
-xmlOnceInit(void) {
-#ifdef HAVE_PTHREAD_H
- (void) pthread_key_create(&globalkey, xmlFreeGlobalState);
- mainthread = pthread_self();
-#endif
-
-#if defined(HAVE_WIN32_THREADS)
-#if !defined(HAVE_COMPILER_TLS)
- globalkey = TlsAlloc();
-#endif
- mainthread = GetCurrentThreadId();
-#endif
-}
diff --git a/bundle/libxml/tree.c b/bundle/libxml/tree.c
deleted file mode 100644
index c3d304501f..0000000000
--- a/bundle/libxml/tree.c
+++ /dev/null
@@ -1,7566 +0,0 @@
-/*
- * tree.c : implementation of access function for an XML tree.
- *
- * References:
- * XHTML 1.0 W3C REC: http://www.w3.org/TR/2002/REC-xhtml1-20020801/
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- *
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#include <string.h> /* for memset() only ! */
-
-#ifdef HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include <libxml/xmlmemory.h>
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/uri.h>
-#include <libxml/entities.h>
-#include <libxml/valid.h>
-#include <libxml/xmlerror.h>
-#include <libxml/parserInternals.h>
-#include <libxml/globals.h>
-#ifdef LIBXML_HTML_ENABLED
-#include <libxml/HTMLtree.h>
-#endif
-
-xmlNsPtr xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns);
-
-/************************************************************************
- * *
- * A few static variables and macros *
- * *
- ************************************************************************/
-/* #undef xmlStringText */
-const xmlChar xmlStringText[] = { 't', 'e', 'x', 't', 0 };
-/* #undef xmlStringTextNoenc */
-const xmlChar xmlStringTextNoenc[] =
- { 't', 'e', 'x', 't', 'n', 'o', 'e', 'n', 'c', 0 };
-/* #undef xmlStringComment */
-const xmlChar xmlStringComment[] = { 'c', 'o', 'm', 'm', 'e', 'n', 't', 0 };
-
-static int xmlCompressMode = 0;
-static int xmlCheckDTD = 1;
-
-#define UPDATE_LAST_CHILD_AND_PARENT(n) if ((n) != NULL) { \
- xmlNodePtr ulccur = (n)->children; \
- if (ulccur == NULL) { \
- (n)->last = NULL; \
- } else { \
- while (ulccur->next != NULL) { \
- ulccur->parent = (n); \
- ulccur = ulccur->next; \
- } \
- ulccur->parent = (n); \
- (n)->last = ulccur; \
-}}
-
-/* #define DEBUG_BUFFER */
-/* #define DEBUG_TREE */
-
-/************************************************************************
- * *
- * Functions to move to entities.c once the *
- * API freeze is smoothen and they can be made public. *
- * *
- ************************************************************************/
-#include <libxml/hash.h>
-
-/**
- * xmlGetEntityFromDtd:
- * @dtd: A pointer to the DTD to search
- * @name: The entity name
- *
- * Do an entity lookup in the DTD entity hash table and
- * return the corresponding entity, if found.
- *
- * Returns A pointer to the entity structure or NULL if not found.
- */
-static xmlEntityPtr
-xmlGetEntityFromDtd(xmlDtdPtr dtd, const xmlChar *name) {
- xmlEntitiesTablePtr table;
-
- if((dtd != NULL) && (dtd->entities != NULL)) {
- table = (xmlEntitiesTablePtr) dtd->entities;
- return((xmlEntityPtr) xmlHashLookup(table, name));
- /* return(xmlGetEntityFromTable(table, name)); */
- }
- return(NULL);
-}
-/**
- * xmlGetParameterEntityFromDtd:
- * @dtd: A pointer to the DTD to search
- * @name: The entity name
- *
- * Do an entity lookup in the DTD pararmeter entity hash table and
- * return the corresponding entity, if found.
- *
- * Returns A pointer to the entity structure or NULL if not found.
- */
-static xmlEntityPtr
-xmlGetParameterEntityFromDtd(xmlDtdPtr dtd, const xmlChar *name) {
- xmlEntitiesTablePtr table;
-
- if ((dtd != NULL) && (dtd->pentities != NULL)) {
- table = (xmlEntitiesTablePtr) dtd->pentities;
- return((xmlEntityPtr) xmlHashLookup(table, name));
- /* return(xmlGetEntityFromTable(table, name)); */
- }
- return(NULL);
-}
-
-/************************************************************************
- * *
- * Allocation and deallocation of basic structures *
- * *
- ************************************************************************/
-
-/**
- * xmlSetBufferAllocationScheme:
- * @scheme: allocation method to use
- *
- * Set the buffer allocation method. Types are
- * XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
- * XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
- * improves performance
- */
-void
-xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme) {
- xmlBufferAllocScheme = scheme;
-}
-
-/**
- * xmlGetBufferAllocationScheme:
- *
- * Types are
- * XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
- * XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
- * improves performance
- *
- * Returns the current allocation scheme
- */
-xmlBufferAllocationScheme
-xmlGetBufferAllocationScheme(void) {
- return(xmlBufferAllocScheme);
-}
-
-/**
- * xmlNewNs:
- * @node: the element carrying the namespace
- * @href: the URI associated
- * @prefix: the prefix for the namespace
- *
- * Creation of a new Namespace. This function will refuse to create
- * a namespace with a similar prefix than an existing one present on this
- * node.
- * We use href==NULL in the case of an element creation where the namespace
- * was not defined.
- * Returns a new namespace pointer or NULL
- */
-xmlNsPtr
-xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix) {
- xmlNsPtr cur;
-
- if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
- return(NULL);
-
- if ((prefix != NULL) && (xmlStrEqual(prefix, BAD_CAST "xml")))
- return(NULL);
-
- /*
- * Allocate a new Namespace and fill the fields.
- */
- cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewNs : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlNs));
- cur->type = XML_LOCAL_NAMESPACE;
-
- if (href != NULL)
- cur->href = xmlStrdup(href);
- if (prefix != NULL)
- cur->prefix = xmlStrdup(prefix);
-
- /*
- * Add it at the end to preserve parsing order ...
- * and checks for existing use of the prefix
- */
- if (node != NULL) {
- if (node->nsDef == NULL) {
- node->nsDef = cur;
- } else {
- xmlNsPtr prev = node->nsDef;
-
- if (((prev->prefix == NULL) && (cur->prefix == NULL)) ||
- (xmlStrEqual(prev->prefix, cur->prefix))) {
- xmlFreeNs(cur);
- return(NULL);
- }
- while (prev->next != NULL) {
- prev = prev->next;
- if (((prev->prefix == NULL) && (cur->prefix == NULL)) ||
- (xmlStrEqual(prev->prefix, cur->prefix))) {
- xmlFreeNs(cur);
- return(NULL);
- }
- }
- prev->next = cur;
- }
- }
- return(cur);
-}
-
-/**
- * xmlSetNs:
- * @node: a node in the document
- * @ns: a namespace pointer
- *
- * Associate a namespace to a node, a posteriori.
- */
-void
-xmlSetNs(xmlNodePtr node, xmlNsPtr ns) {
- if (node == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlSetNs: node == NULL\n");
-#endif
- return;
- }
- node->ns = ns;
-}
-
-/**
- * xmlFreeNs:
- * @cur: the namespace pointer
- *
- * Free up the structures associated to a namespace
- */
-void
-xmlFreeNs(xmlNsPtr cur) {
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlFreeNs : ns == NULL\n");
-#endif
- return;
- }
- if (cur->href != NULL) xmlFree((char *) cur->href);
- if (cur->prefix != NULL) xmlFree((char *) cur->prefix);
- xmlFree(cur);
-}
-
-/**
- * xmlFreeNsList:
- * @cur: the first namespace pointer
- *
- * Free up all the structures associated to the chained namespaces.
- */
-void
-xmlFreeNsList(xmlNsPtr cur) {
- xmlNsPtr next;
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlFreeNsList : ns == NULL\n");
-#endif
- return;
- }
- while (cur != NULL) {
- next = cur->next;
- xmlFreeNs(cur);
- cur = next;
- }
-}
-
-/**
- * xmlNewDtd:
- * @doc: the document pointer
- * @name: the DTD name
- * @ExternalID: the external ID
- * @SystemID: the system ID
- *
- * Creation of a new DTD for the external subset. To create an
- * internal subset, use xmlCreateIntSubset().
- *
- * Returns a pointer to the new DTD structure
- */
-xmlDtdPtr
-xmlNewDtd(xmlDocPtr doc, const xmlChar *name,
- const xmlChar *ExternalID, const xmlChar *SystemID) {
- xmlDtdPtr cur;
-
- if ((doc != NULL) && (doc->extSubset != NULL)) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewDtd(%s): document %s already have a DTD %s\n",
- /* !!! */ (char *) name, doc->name,
- /* !!! */ (char *)doc->extSubset->name);
-#endif
- return(NULL);
- }
-
- /*
- * Allocate a new DTD and fill the fields.
- */
- cur = (xmlDtdPtr) xmlMalloc(sizeof(xmlDtd));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewDtd : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0 , sizeof(xmlDtd));
- cur->type = XML_DTD_NODE;
-
- if (name != NULL)
- cur->name = xmlStrdup(name);
- if (ExternalID != NULL)
- cur->ExternalID = xmlStrdup(ExternalID);
- if (SystemID != NULL)
- cur->SystemID = xmlStrdup(SystemID);
- if (doc != NULL)
- doc->extSubset = cur;
- cur->doc = doc;
-
- return(cur);
-}
-
-/**
- * xmlGetIntSubset:
- * @doc: the document pointer
- *
- * Get the internal subset of a document
- * Returns a pointer to the DTD structure or NULL if not found
- */
-
-xmlDtdPtr
-xmlGetIntSubset(xmlDocPtr doc) {
- xmlNodePtr cur;
-
- if (doc == NULL)
- return(NULL);
- cur = doc->children;
- while (cur != NULL) {
- if (cur->type == XML_DTD_NODE)
- return((xmlDtdPtr) cur);
- cur = cur->next;
- }
- return((xmlDtdPtr) doc->intSubset);
-}
-
-/**
- * xmlCreateIntSubset:
- * @doc: the document pointer
- * @name: the DTD name
- * @ExternalID: the external (PUBLIC) ID
- * @SystemID: the system ID
- *
- * Create the internal subset of a document
- * Returns a pointer to the new DTD structure
- */
-xmlDtdPtr
-xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name,
- const xmlChar *ExternalID, const xmlChar *SystemID) {
- xmlDtdPtr cur;
-
- if ((doc != NULL) && (xmlGetIntSubset(doc) != NULL)) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
-
- "xmlCreateIntSubset(): document %s already have an internal subset\n",
- doc->name);
-#endif
- return(NULL);
- }
-
- /*
- * Allocate a new DTD and fill the fields.
- */
- cur = (xmlDtdPtr) xmlMalloc(sizeof(xmlDtd));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlCreateIntSubset : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlDtd));
- cur->type = XML_DTD_NODE;
-
- if (name != NULL)
- cur->name = xmlStrdup(name);
- if (ExternalID != NULL)
- cur->ExternalID = xmlStrdup(ExternalID);
- if (SystemID != NULL)
- cur->SystemID = xmlStrdup(SystemID);
- if (doc != NULL) {
- doc->intSubset = cur;
- cur->parent = doc;
- cur->doc = doc;
- if (doc->children == NULL) {
- doc->children = (xmlNodePtr) cur;
- doc->last = (xmlNodePtr) cur;
- } else {
- if (doc->type == XML_HTML_DOCUMENT_NODE) {
- xmlNodePtr prev;
-
- prev = doc->children;
- prev->prev = (xmlNodePtr) cur;
- cur->next = prev;
- doc->children = (xmlNodePtr) cur;
- } else {
- xmlNodePtr next;
-
- next = doc->children;
- while ((next != NULL) && (next->type != XML_ELEMENT_NODE))
- next = next->next;
- if (next == NULL) {
- cur->prev = doc->last;
- cur->prev->next = (xmlNodePtr) cur;
- cur->next = NULL;
- doc->last = (xmlNodePtr) cur;
- } else {
- cur->next = next;
- cur->prev = next->prev;
- if (cur->prev == NULL)
- doc->children = (xmlNodePtr) cur;
- else
- cur->prev->next = (xmlNodePtr) cur;
- next->prev = (xmlNodePtr) cur;
- }
- }
- }
- }
- return(cur);
-}
-
-/**
- * xmlFreeDtd:
- * @cur: the DTD structure to free up
- *
- * Free a DTD structure.
- */
-void
-xmlFreeDtd(xmlDtdPtr cur) {
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlFreeDtd : DTD == NULL\n");
-#endif
- return;
- }
- if (cur->children != NULL) {
- xmlNodePtr next, c = cur->children;
-
- /*
- * Cleanup all the DTD comments they are not in the DTD
- * indexes.
- */
- while (c != NULL) {
- next = c->next;
- if (c->type == XML_COMMENT_NODE) {
- xmlUnlinkNode(c);
- xmlFreeNode(c);
- }
- c = next;
- }
- }
- if (cur->name != NULL) xmlFree((char *) cur->name);
- if (cur->SystemID != NULL) xmlFree((char *) cur->SystemID);
- if (cur->ExternalID != NULL) xmlFree((char *) cur->ExternalID);
- /* TODO !!! */
- if (cur->notations != NULL)
- xmlFreeNotationTable((xmlNotationTablePtr) cur->notations);
-
- if (cur->elements != NULL)
- xmlFreeElementTable((xmlElementTablePtr) cur->elements);
- if (cur->attributes != NULL)
- xmlFreeAttributeTable((xmlAttributeTablePtr) cur->attributes);
- if (cur->entities != NULL)
- xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->entities);
- if (cur->pentities != NULL)
- xmlFreeEntitiesTable((xmlEntitiesTablePtr) cur->pentities);
-
- xmlFree(cur);
-}
-
-/**
- * xmlNewDoc:
- * @version: xmlChar string giving the version of XML "1.0"
- *
- * Creates a new XML document
- *
- * Returns a new document
- */
-xmlDocPtr
-xmlNewDoc(const xmlChar *version) {
- xmlDocPtr cur;
-
- if (version == NULL)
- version = (const xmlChar *) "1.0";
-
- /*
- * Allocate a new document and fill the fields.
- */
- cur = (xmlDocPtr) xmlMalloc(sizeof(xmlDoc));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewDoc : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlDoc));
- cur->type = XML_DOCUMENT_NODE;
-
- cur->version = xmlStrdup(version);
- cur->standalone = -1;
- cur->compression = -1; /* not initialized */
- cur->doc = cur;
- cur->charset = XML_CHAR_ENCODING_UTF8;
- return(cur);
-}
-
-/**
- * xmlFreeDoc:
- * @cur: pointer to the document
- *
- * Free up all the structures used by a document, tree included.
- */
-void
-xmlFreeDoc(xmlDocPtr cur) {
- xmlDtdPtr extSubset, intSubset;
-
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlFreeDoc : document == NULL\n");
-#endif
- return;
- }
- /*
- * Do this before freeing the children list to avoid ID lookups
- */
- if (cur->ids != NULL) xmlFreeIDTable((xmlIDTablePtr) cur->ids);
- cur->ids = NULL;
- if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs);
- cur->refs = NULL;
- extSubset = cur->extSubset;
- intSubset = cur->intSubset;
- if (intSubset == extSubset)
- extSubset = NULL;
- if (extSubset != NULL) {
- xmlUnlinkNode((xmlNodePtr) cur->extSubset);
- cur->extSubset = NULL;
- xmlFreeDtd(extSubset);
- }
- if (intSubset != NULL) {
- xmlUnlinkNode((xmlNodePtr) cur->intSubset);
- cur->intSubset = NULL;
- xmlFreeDtd(intSubset);
- }
-
- if (cur->children != NULL) xmlFreeNodeList(cur->children);
-
- if (cur->version != NULL) xmlFree((char *) cur->version);
- if (cur->name != NULL) xmlFree((char *) cur->name);
- if (cur->encoding != NULL) xmlFree((char *) cur->encoding);
- if (cur->oldNs != NULL) xmlFreeNsList(cur->oldNs);
- if (cur->URL != NULL) xmlFree((char *) cur->URL);
- xmlFree(cur);
-}
-
-/**
- * xmlStringLenGetNodeList:
- * @doc: the document
- * @value: the value of the text
- * @len: the length of the string value
- *
- * Parse the value string and build the node list associated. Should
- * produce a flat tree with only TEXTs and ENTITY_REFs.
- * Returns a pointer to the first child
- */
-xmlNodePtr
-xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *value, int len) {
- xmlNodePtr ret = NULL, last = NULL;
- xmlNodePtr node;
- xmlChar *val;
- const xmlChar *cur = value;
- const xmlChar *q;
- xmlEntityPtr ent;
-
- if (value == NULL) return(NULL);
-
- q = cur;
- while ((*cur != 0) && (cur - value < len)) {
- if (*cur == '&') {
- /*
- * Save the current text.
- */
- if (cur != q) {
- if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
- xmlNodeAddContentLen(last, q, cur - q);
- } else {
- node = xmlNewDocTextLen(doc, q, cur - q);
- if (node == NULL) return(ret);
- if (last == NULL)
- last = ret = node;
- else {
- last->next = node;
- node->prev = last;
- last = node;
- }
- }
- }
- /*
- * Read the entity string
- */
- cur++;
- q = cur;
- while ((*cur != 0) && (cur - value < len) && (*cur != ';')) cur++;
- if ((*cur == 0) || (cur - value >= len)) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlStringLenGetNodeList: unterminated entity %30s\n", q);
-#endif
- return(ret);
- }
- if (cur != q) {
- /*
- * Predefined entities don't generate nodes
- */
- val = xmlStrndup(q, cur - q);
- ent = xmlGetDocEntity(doc, val);
- if ((ent != NULL) &&
- (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
- if (last == NULL) {
- node = xmlNewDocText(doc, ent->content);
- last = ret = node;
- } else
- xmlNodeAddContent(last, ent->content);
-
- } else {
- /*
- * Create a new REFERENCE_REF node
- */
- node = xmlNewReference(doc, val);
- if (node == NULL) {
- if (val != NULL) xmlFree(val);
- return(ret);
- }
- else if ((ent != NULL) && (ent->children == NULL)) {
- xmlNodePtr tmp;
-
- ent->children =
- xmlStringGetNodeList(doc, (const xmlChar*)node->content);
- tmp = ent->children;
- while (tmp) {
- tmp->parent = (xmlNodePtr)ent;
- tmp = tmp->next;
- }
- }
- if (last == NULL)
- last = ret = node;
- else {
- last->next = node;
- node->prev = last;
- last = node;
- }
- }
- xmlFree(val);
- }
- cur++;
- q = cur;
- } else
- cur++;
- }
- if (cur != q) {
- /*
- * Handle the last piece of text.
- */
- if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
- xmlNodeAddContentLen(last, q, cur - q);
- } else {
- node = xmlNewDocTextLen(doc, q, cur - q);
- if (node == NULL) return(ret);
- if (last == NULL)
- last = ret = node;
- else {
- last->next = node;
- node->prev = last;
- last = node;
- }
- }
- }
- return(ret);
-}
-
-/**
- * xmlStringGetNodeList:
- * @doc: the document
- * @value: the value of the attribute
- *
- * Parse the value string and build the node list associated. Should
- * produce a flat tree with only TEXTs and ENTITY_REFs.
- * Returns a pointer to the first child
- */
-xmlNodePtr
-xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *value) {
- xmlNodePtr ret = NULL, last = NULL;
- xmlNodePtr node;
- xmlChar *val;
- const xmlChar *cur = value;
- const xmlChar *q;
- xmlEntityPtr ent;
-
- if (value == NULL) return(NULL);
-
- q = cur;
- while (*cur != 0) {
- if (cur[0] == '&') {
- int charval = 0;
- xmlChar tmp;
-
- /*
- * Save the current text.
- */
- if (cur != q) {
- if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
- xmlNodeAddContentLen(last, q, cur - q);
- } else {
- node = xmlNewDocTextLen(doc, q, cur - q);
- if (node == NULL) return(ret);
- if (last == NULL)
- last = ret = node;
- else {
- last->next = node;
- node->prev = last;
- last = node;
- }
- }
- }
- q = cur;
- if ((cur[1] == '#') && (cur[2] == 'x')) {
- cur += 3;
- tmp = *cur;
- while (tmp != ';') { /* Non input consuming loop */
- if ((tmp >= '0') && (tmp <= '9'))
- charval = charval * 16 + (tmp - '0');
- else if ((tmp >= 'a') && (tmp <= 'f'))
- charval = charval * 16 + (tmp - 'a') + 10;
- else if ((tmp >= 'A') && (tmp <= 'F'))
- charval = charval * 16 + (tmp - 'A') + 10;
- else {
- xmlGenericError(xmlGenericErrorContext,
- "xmlStringGetNodeList: invalid hexadecimal charvalue\n");
- charval = 0;
- break;
- }
- cur++;
- tmp = *cur;
- }
- if (tmp == ';')
- cur++;
- q = cur;
- } else if (cur[1] == '#') {
- cur += 2;
- tmp = *cur;
- while (tmp != ';') { /* Non input consuming loops */
- if ((tmp >= '0') && (tmp <= '9'))
- charval = charval * 10 + (tmp - '0');
- else {
- xmlGenericError(xmlGenericErrorContext,
- "xmlStringGetNodeList: invalid decimal charvalue\n");
- charval = 0;
- break;
- }
- cur++;
- tmp = *cur;
- }
- if (tmp == ';')
- cur++;
- q = cur;
- } else {
- /*
- * Read the entity string
- */
- cur++;
- q = cur;
- while ((*cur != 0) && (*cur != ';')) cur++;
- if (*cur == 0) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlStringGetNodeList: unterminated entity %30s\n", q);
-#endif
- return(ret);
- }
- if (cur != q) {
- /*
- * Predefined entities don't generate nodes
- */
- val = xmlStrndup(q, cur - q);
- ent = xmlGetDocEntity(doc, val);
- if ((ent != NULL) &&
- (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
- if (last == NULL) {
- node = xmlNewDocText(doc, ent->content);
- last = ret = node;
- } else if (last->type != XML_TEXT_NODE) {
- node = xmlNewDocText(doc, ent->content);
- last = xmlAddNextSibling(last, node);
- } else
- xmlNodeAddContent(last, ent->content);
-
- } else {
- /*
- * Create a new REFERENCE_REF node
- */
- node = xmlNewReference(doc, val);
- if (node == NULL) {
- if (val != NULL) xmlFree(val);
- return(ret);
- }
- else if ((ent != NULL) && (ent->children == NULL)) {
- xmlNodePtr temp;
-
- ent->children = xmlStringGetNodeList(doc,
- (const xmlChar*)node->content);
- temp = ent->children;
- while (temp) {
- temp->parent = (xmlNodePtr)ent;
- temp = temp->next;
- }
- }
- if (last == NULL) {
- last = ret = node;
- } else {
- last = xmlAddNextSibling(last, node);
- }
- }
- xmlFree(val);
- }
- cur++;
- q = cur;
- }
- if (charval != 0) {
- xmlChar buf[10];
- int len;
-
- len = xmlCopyCharMultiByte(buf, charval);
- buf[len] = 0;
- node = xmlNewDocText(doc, buf);
- if (node != NULL) {
- if (last == NULL) {
- last = ret = node;
- } else {
- last = xmlAddNextSibling(last, node);
- }
- }
-
- charval = 0;
- }
- } else
- cur++;
- }
- if ((cur != q) || (ret == NULL)) {
- /*
- * Handle the last piece of text.
- */
- if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
- xmlNodeAddContentLen(last, q, cur - q);
- } else {
- node = xmlNewDocTextLen(doc, q, cur - q);
- if (node == NULL) return(ret);
- if (last == NULL) {
- last = ret = node;
- } else {
- last = xmlAddNextSibling(last, node);
- }
- }
- }
- return(ret);
-}
-
-/**
- * xmlNodeListGetString:
- * @doc: the document
- * @list: a Node list
- * @inLine: should we replace entity contents or show their external form
- *
- * Build the string equivalent to the text contained in the Node list
- * made of TEXTs and ENTITY_REFs
- *
- * Returns a pointer to the string copy, the caller must free it with xmlFree().
- */
-xmlChar *
-xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine)
-{
- xmlNodePtr node = list;
- xmlChar *ret = NULL;
- xmlEntityPtr ent;
-
- if (list == NULL)
- return (NULL);
-
- while (node != NULL) {
- if ((node->type == XML_TEXT_NODE) ||
- (node->type == XML_CDATA_SECTION_NODE)) {
- if (inLine) {
- ret = xmlStrcat(ret, node->content);
- } else {
- xmlChar *buffer;
-
- buffer = xmlEncodeEntitiesReentrant(doc, node->content);
- if (buffer != NULL) {
- ret = xmlStrcat(ret, buffer);
- xmlFree(buffer);
- }
- }
- } else if (node->type == XML_ENTITY_REF_NODE) {
- if (inLine) {
- ent = xmlGetDocEntity(doc, node->name);
- if (ent != NULL) {
- xmlChar *buffer;
-
- /* an entity content can be any "well balanced chunk",
- * i.e. the result of the content [43] production:
- * http://www.w3.org/TR/REC-xml#NT-content.
- * So it can contain text, CDATA section or nested
- * entity reference nodes (among others).
- * -> we recursive call xmlNodeListGetString()
- * which handles these types */
- buffer = xmlNodeListGetString(doc, ent->children, 1);
- if (buffer != NULL) {
- ret = xmlStrcat(ret, buffer);
- xmlFree(buffer);
- }
- } else {
- ret = xmlStrcat(ret, node->content);
- }
- } else {
- xmlChar buf[2];
-
- buf[0] = '&';
- buf[1] = 0;
- ret = xmlStrncat(ret, buf, 1);
- ret = xmlStrcat(ret, node->name);
- buf[0] = ';';
- buf[1] = 0;
- ret = xmlStrncat(ret, buf, 1);
- }
- }
-#if 0
- else {
- xmlGenericError(xmlGenericErrorContext,
- "xmlGetNodeListString : invalid node type %d\n",
- node->type);
- }
-#endif
- node = node->next;
- }
- return (ret);
-}
-/**
- * xmlNodeListGetRawString:
- * @doc: the document
- * @list: a Node list
- * @inLine: should we replace entity contents or show their external form
- *
- * Builds the string equivalent to the text contained in the Node list
- * made of TEXTs and ENTITY_REFs, contrary to xmlNodeListGetString()
- * this function doesn't do any character encoding handling.
- *
- * Returns a pointer to the string copy, the caller must free it with xmlFree().
- */
-xmlChar *
-xmlNodeListGetRawString(xmlDocPtr doc, xmlNodePtr list, int inLine)
-{
- xmlNodePtr node = list;
- xmlChar *ret = NULL;
- xmlEntityPtr ent;
-
- if (list == NULL)
- return (NULL);
-
- while (node != NULL) {
- if ((node->type == XML_TEXT_NODE) ||
- (node->type == XML_CDATA_SECTION_NODE)) {
- if (inLine) {
- ret = xmlStrcat(ret, node->content);
- } else {
- xmlChar *buffer;
-
- buffer = xmlEncodeSpecialChars(doc, node->content);
- if (buffer != NULL) {
- ret = xmlStrcat(ret, buffer);
- xmlFree(buffer);
- }
- }
- } else if (node->type == XML_ENTITY_REF_NODE) {
- if (inLine) {
- ent = xmlGetDocEntity(doc, node->name);
- if (ent != NULL) {
- xmlChar *buffer;
-
- /* an entity content can be any "well balanced chunk",
- * i.e. the result of the content [43] production:
- * http://www.w3.org/TR/REC-xml#NT-content.
- * So it can contain text, CDATA section or nested
- * entity reference nodes (among others).
- * -> we recursive call xmlNodeListGetRawString()
- * which handles these types */
- buffer =
- xmlNodeListGetRawString(doc, ent->children, 1);
- if (buffer != NULL) {
- ret = xmlStrcat(ret, buffer);
- xmlFree(buffer);
- }
- } else {
- ret = xmlStrcat(ret, node->content);
- }
- } else {
- xmlChar buf[2];
-
- buf[0] = '&';
- buf[1] = 0;
- ret = xmlStrncat(ret, buf, 1);
- ret = xmlStrcat(ret, node->name);
- buf[0] = ';';
- buf[1] = 0;
- ret = xmlStrncat(ret, buf, 1);
- }
- }
-#if 0
- else {
- xmlGenericError(xmlGenericErrorContext,
- "xmlGetNodeListString : invalid node type %d\n",
- node->type);
- }
-#endif
- node = node->next;
- }
- return (ret);
-}
-
-/**
- * xmlNewProp:
- * @node: the holding node
- * @name: the name of the attribute
- * @value: the value of the attribute
- *
- * Create a new property carried by a node.
- * Returns a pointer to the attribute
- */
-xmlAttrPtr
-xmlNewProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
- xmlAttrPtr cur;
- xmlDocPtr doc = NULL;
-
- if (name == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewProp : name == NULL\n");
-#endif
- return(NULL);
- }
-
- /*
- * Allocate a new property and fill the fields.
- */
- cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewProp : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlAttr));
- cur->type = XML_ATTRIBUTE_NODE;
-
- cur->parent = node;
- if (node != NULL) {
- doc = node->doc;
- cur->doc = doc;
- }
- cur->name = xmlStrdup(name);
- if (value != NULL) {
- xmlChar *buffer;
- xmlNodePtr tmp;
-
- buffer = xmlEncodeEntitiesReentrant(doc, value);
- cur->children = xmlStringGetNodeList(doc, buffer);
- cur->last = NULL;
- tmp = cur->children;
- while (tmp != NULL) {
- tmp->parent = (xmlNodePtr) cur;
- tmp->doc = doc;
- if (tmp->next == NULL)
- cur->last = tmp;
- tmp = tmp->next;
- }
- xmlFree(buffer);
- }
-
- /*
- * Add it at the end to preserve parsing order ...
- */
- if (node != NULL) {
- if (node->properties == NULL) {
- node->properties = cur;
- } else {
- xmlAttrPtr prev = node->properties;
-
- while (prev->next != NULL) prev = prev->next;
- prev->next = cur;
- cur->prev = prev;
- }
- }
- return(cur);
-}
-
-/**
- * xmlNewNsProp:
- * @node: the holding node
- * @ns: the namespace
- * @name: the name of the attribute
- * @value: the value of the attribute
- *
- * Create a new property tagged with a namespace and carried by a node.
- * Returns a pointer to the attribute
- */
-xmlAttrPtr
-xmlNewNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
- const xmlChar *value) {
- xmlAttrPtr cur;
- xmlDocPtr doc = NULL;
-
- if (name == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewNsProp : name == NULL\n");
-#endif
- return(NULL);
- }
-
- /*
- * Allocate a new property and fill the fields.
- */
- cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewNsProp : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlAttr));
- cur->type = XML_ATTRIBUTE_NODE;
-
- cur->parent = node;
- if (node != NULL) {
- doc = node->doc;
- cur->doc = doc;
- }
- cur->ns = ns;
- cur->name = xmlStrdup(name);
- if (value != NULL) {
- xmlChar *buffer;
- xmlNodePtr tmp;
-
- buffer = xmlEncodeEntitiesReentrant(doc, value);
- cur->children = xmlStringGetNodeList(doc, buffer);
- cur->last = NULL;
- tmp = cur->children;
- while (tmp != NULL) {
- tmp->parent = (xmlNodePtr) cur;
- if (tmp->next == NULL)
- cur->last = tmp;
- tmp = tmp->next;
- }
- xmlFree(buffer);
- }
-
- /*
- * Add it at the end to preserve parsing order ...
- */
- if (node != NULL) {
- if (node->properties == NULL) {
- node->properties = cur;
- } else {
- xmlAttrPtr prev = node->properties;
-
- while (prev->next != NULL) prev = prev->next;
- prev->next = cur;
- cur->prev = prev;
- }
- }
- return(cur);
-}
-
-/**
- * xmlNewNsPropEatName:
- * @node: the holding node
- * @ns: the namespace
- * @name: the name of the attribute
- * @value: the value of the attribute
- *
- * Create a new property tagged with a namespace and carried by a node.
- * Returns a pointer to the attribute
- */
-xmlAttrPtr
-xmlNewNsPropEatName(xmlNodePtr node, xmlNsPtr ns, xmlChar *name,
- const xmlChar *value) {
- xmlAttrPtr cur;
- xmlDocPtr doc = NULL;
-
- if (name == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewNsPropEatName : name == NULL\n");
-#endif
- return(NULL);
- }
-
- /*
- * Allocate a new property and fill the fields.
- */
- cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewNsPropEatName : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlAttr));
- cur->type = XML_ATTRIBUTE_NODE;
-
- cur->parent = node;
- if (node != NULL) {
- doc = node->doc;
- cur->doc = doc;
- }
- cur->ns = ns;
- cur->name = name;
- if (value != NULL) {
- xmlChar *buffer;
- xmlNodePtr tmp;
-
- buffer = xmlEncodeEntitiesReentrant(doc, value);
- cur->children = xmlStringGetNodeList(doc, buffer);
- cur->last = NULL;
- tmp = cur->children;
- while (tmp != NULL) {
- tmp->parent = (xmlNodePtr) cur;
- if (tmp->next == NULL)
- cur->last = tmp;
- tmp = tmp->next;
- }
- xmlFree(buffer);
- }
-
- /*
- * Add it at the end to preserve parsing order ...
- */
- if (node != NULL) {
- if (node->properties == NULL) {
- node->properties = cur;
- } else {
- xmlAttrPtr prev = node->properties;
-
- while (prev->next != NULL) prev = prev->next;
- prev->next = cur;
- cur->prev = prev;
- }
- }
- return(cur);
-}
-
-/**
- * xmlNewDocProp:
- * @doc: the document
- * @name: the name of the attribute
- * @value: the value of the attribute
- *
- * Create a new property carried by a document.
- * Returns a pointer to the attribute
- */
-xmlAttrPtr
-xmlNewDocProp(xmlDocPtr doc, const xmlChar *name, const xmlChar *value) {
- xmlAttrPtr cur;
-
- if (name == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewDocProp : name == NULL\n");
-#endif
- return(NULL);
- }
-
- /*
- * Allocate a new property and fill the fields.
- */
- cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewDocProp : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlAttr));
- cur->type = XML_ATTRIBUTE_NODE;
-
- cur->name = xmlStrdup(name);
- cur->doc = doc;
- if (value != NULL) {
- xmlNodePtr tmp;
-
- cur->children = xmlStringGetNodeList(doc, value);
- cur->last = NULL;
-
- tmp = cur->children;
- while (tmp != NULL) {
- tmp->parent = (xmlNodePtr) cur;
- if (tmp->next == NULL)
- cur->last = tmp;
- tmp = tmp->next;
- }
- }
- return(cur);
-}
-
-/**
- * xmlFreePropList:
- * @cur: the first property in the list
- *
- * Free a property and all its siblings, all the children are freed too.
- */
-void
-xmlFreePropList(xmlAttrPtr cur) {
- xmlAttrPtr next;
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlFreePropList : property == NULL\n");
-#endif
- return;
- }
- while (cur != NULL) {
- next = cur->next;
- xmlFreeProp(cur);
- cur = next;
- }
-}
-
-/**
- * xmlFreeProp:
- * @cur: an attribute
- *
- * Free one attribute, all the content is freed too
- */
-void
-xmlFreeProp(xmlAttrPtr cur) {
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlFreeProp : property == NULL\n");
-#endif
- return;
- }
- /* Check for ID removal -> leading to invalid references ! */
- if ((cur->parent != NULL) && (cur->parent->doc != NULL) &&
- ((cur->parent->doc->intSubset != NULL) ||
- (cur->parent->doc->extSubset != NULL))) {
- if (xmlIsID(cur->parent->doc, cur->parent, cur))
- xmlRemoveID(cur->parent->doc, cur);
- }
- if (cur->name != NULL) xmlFree((char *) cur->name);
- if (cur->children != NULL) xmlFreeNodeList(cur->children);
- xmlFree(cur);
-}
-
-/**
- * xmlRemoveProp:
- * @cur: an attribute
- *
- * Unlink and free one attribute, all the content is freed too
- * Note this doesn't work for namespace definition attributes
- *
- * Returns 0 if success and -1 in case of error.
- */
-int
-xmlRemoveProp(xmlAttrPtr cur) {
- xmlAttrPtr tmp;
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlRemoveProp : cur == NULL\n");
-#endif
- return(-1);
- }
- if (cur->parent == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlRemoveProp : cur->parent == NULL\n");
-#endif
- return(-1);
- }
- tmp = cur->parent->properties;
- if (tmp == cur) {
- cur->parent->properties = cur->next;
- xmlFreeProp(cur);
- return(0);
- }
- while (tmp != NULL) {
- if (tmp->next == cur) {
- tmp->next = cur->next;
- if (tmp->next != NULL)
- tmp->next->prev = tmp;
- xmlFreeProp(cur);
- return(0);
- }
- tmp = tmp->next;
- }
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlRemoveProp : attribute not owned by its node\n");
-#endif
- return(-1);
-}
-
-/**
- * xmlNewPI:
- * @name: the processing instruction name
- * @content: the PI content
- *
- * Creation of a processing instruction element.
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewPI(const xmlChar *name, const xmlChar *content) {
- xmlNodePtr cur;
-
- if (name == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewPI : name == NULL\n");
-#endif
- return(NULL);
- }
-
- /*
- * Allocate a new node and fill the fields.
- */
- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewPI : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlNode));
- cur->type = XML_PI_NODE;
-
- cur->name = xmlStrdup(name);
- if (content != NULL) {
- cur->content = xmlStrdup(content);
- }
- return(cur);
-}
-
-/**
- * xmlNewNode:
- * @ns: namespace if any
- * @name: the node name
- *
- * Creation of a new node element. @ns is optional (NULL).
- *
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewNode(xmlNsPtr ns, const xmlChar *name) {
- xmlNodePtr cur;
-
- if (name == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewNode : name == NULL\n");
-#endif
- return(NULL);
- }
-
- /*
- * Allocate a new node and fill the fields.
- */
- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewNode : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlNode));
- cur->type = XML_ELEMENT_NODE;
-
- cur->name = xmlStrdup(name);
- cur->ns = ns;
- return(cur);
-}
-
-/**
- * xmlNewNodeEatName:
- * @ns: namespace if any
- * @name: the node name
- *
- * Creation of a new node element. @ns is optional (NULL).
- *
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewNodeEatName(xmlNsPtr ns, xmlChar *name) {
- xmlNodePtr cur;
-
- if (name == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewNode : name == NULL\n");
-#endif
- return(NULL);
- }
-
- /*
- * Allocate a new node and fill the fields.
- */
- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewNode : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlNode));
- cur->type = XML_ELEMENT_NODE;
-
- cur->name = name;
- cur->ns = ns;
- return(cur);
-}
-
-/**
- * xmlNewDocNode:
- * @doc: the document
- * @ns: namespace if any
- * @name: the node name
- * @content: the XML text content if any
- *
- * Creation of a new node element within a document. @ns and @content
- * are optional (NULL).
- * NOTE: @content is supposed to be a piece of XML CDATA, so it allow entities
- * references, but XML special chars need to be escaped first by using
- * xmlEncodeEntitiesReentrant(). Use xmlNewDocRawNode() if you don't
- * need entities support.
- *
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns,
- const xmlChar *name, const xmlChar *content) {
- xmlNodePtr cur;
-
- cur = xmlNewNode(ns, name);
- if (cur != NULL) {
- cur->doc = doc;
- if (content != NULL) {
- cur->children = xmlStringGetNodeList(doc, content);
- UPDATE_LAST_CHILD_AND_PARENT(cur)
- }
- }
- return(cur);
-}
-
-/**
- * xmlNewDocNodeEatName:
- * @doc: the document
- * @ns: namespace if any
- * @name: the node name
- * @content: the XML text content if any
- *
- * Creation of a new node element within a document. @ns and @content
- * are optional (NULL).
- * NOTE: @content is supposed to be a piece of XML CDATA, so it allow entities
- * references, but XML special chars need to be escaped first by using
- * xmlEncodeEntitiesReentrant(). Use xmlNewDocRawNode() if you don't
- * need entities support.
- *
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewDocNodeEatName(xmlDocPtr doc, xmlNsPtr ns,
- xmlChar *name, const xmlChar *content) {
- xmlNodePtr cur;
-
- cur = xmlNewNodeEatName(ns, name);
- if (cur != NULL) {
- cur->doc = doc;
- if (content != NULL) {
- cur->children = xmlStringGetNodeList(doc, content);
- UPDATE_LAST_CHILD_AND_PARENT(cur)
- }
- }
- return(cur);
-}
-
-
-/**
- * xmlNewDocRawNode:
- * @doc: the document
- * @ns: namespace if any
- * @name: the node name
- * @content: the text content if any
- *
- * Creation of a new node element within a document. @ns and @content
- * are optional (NULL).
- *
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewDocRawNode(xmlDocPtr doc, xmlNsPtr ns,
- const xmlChar *name, const xmlChar *content) {
- xmlNodePtr cur;
-
- cur = xmlNewNode(ns, name);
- if (cur != NULL) {
- cur->doc = doc;
- if (content != NULL) {
- cur->children = xmlNewDocText(doc, content);
- UPDATE_LAST_CHILD_AND_PARENT(cur)
- }
- }
- return(cur);
-}
-
-/**
- * xmlNewDocFragment:
- * @doc: the document owning the fragment
- *
- * Creation of a new Fragment node.
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewDocFragment(xmlDocPtr doc) {
- xmlNodePtr cur;
-
- /*
- * Allocate a new DocumentFragment node and fill the fields.
- */
- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewDocFragment : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlNode));
- cur->type = XML_DOCUMENT_FRAG_NODE;
-
- cur->doc = doc;
- return(cur);
-}
-
-/**
- * xmlNewText:
- * @content: the text content
- *
- * Creation of a new text node.
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewText(const xmlChar *content) {
- xmlNodePtr cur;
-
- /*
- * Allocate a new node and fill the fields.
- */
- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewText : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlNode));
- cur->type = XML_TEXT_NODE;
-
- cur->name = xmlStringText;
- if (content != NULL) {
- cur->content = xmlStrdup(content);
- }
- return(cur);
-}
-
-/**
- * xmlNewTextChild:
- * @parent: the parent node
- * @ns: a namespace if any
- * @name: the name of the child
- * @content: the text content of the child if any.
- *
- * Creation of a new child element, added at the end of @parent children list.
- * @ns and @content parameters are optional (NULL). If content is non NULL,
- * a child TEXT node will be created containing the string content.
- *
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewTextChild(xmlNodePtr parent, xmlNsPtr ns,
- const xmlChar *name, const xmlChar *content) {
- xmlNodePtr cur, prev;
-
- if (parent == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewTextChild : parent == NULL\n");
-#endif
- return(NULL);
- }
-
- if (name == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewTextChild : name == NULL\n");
-#endif
- return(NULL);
- }
-
- /*
- * Allocate a new node
- */
- if (ns == NULL)
- cur = xmlNewDocRawNode(parent->doc, parent->ns, name, content);
- else
- cur = xmlNewDocRawNode(parent->doc, ns, name, content);
- if (cur == NULL) return(NULL);
-
- /*
- * add the new element at the end of the children list.
- */
- cur->type = XML_ELEMENT_NODE;
- cur->parent = parent;
- cur->doc = parent->doc;
- if (parent->children == NULL) {
- parent->children = cur;
- parent->last = cur;
- } else {
- prev = parent->last;
- prev->next = cur;
- cur->prev = prev;
- parent->last = cur;
- }
-
- return(cur);
-}
-
-/**
- * xmlNewCharRef:
- * @doc: the document
- * @name: the char ref string, starting with # or "&# ... ;"
- *
- * Creation of a new character reference node.
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewCharRef(xmlDocPtr doc, const xmlChar *name) {
- xmlNodePtr cur;
-
- /*
- * Allocate a new node and fill the fields.
- */
- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewCharRef : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlNode));
- cur->type = XML_ENTITY_REF_NODE;
-
- cur->doc = doc;
- if (name[0] == '&') {
- int len;
- name++;
- len = xmlStrlen(name);
- if (name[len - 1] == ';')
- cur->name = xmlStrndup(name, len - 1);
- else
- cur->name = xmlStrndup(name, len);
- } else
- cur->name = xmlStrdup(name);
- return(cur);
-}
-
-/**
- * xmlNewReference:
- * @doc: the document
- * @name: the reference name, or the reference string with & and ;
- *
- * Creation of a new reference node.
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewReference(xmlDocPtr doc, const xmlChar *name) {
- xmlNodePtr cur;
- xmlEntityPtr ent;
-
- /*
- * Allocate a new node and fill the fields.
- */
- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewReference : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlNode));
- cur->type = XML_ENTITY_REF_NODE;
-
- cur->doc = doc;
- if (name[0] == '&') {
- int len;
- name++;
- len = xmlStrlen(name);
- if (name[len - 1] == ';')
- cur->name = xmlStrndup(name, len - 1);
- else
- cur->name = xmlStrndup(name, len);
- } else
- cur->name = xmlStrdup(name);
-
- ent = xmlGetDocEntity(doc, cur->name);
- if (ent != NULL) {
- cur->content = ent->content;
- /*
- * The parent pointer in entity is a DTD pointer and thus is NOT
- * updated. Not sure if this is 100% correct.
- * -George
- */
- cur->children = (xmlNodePtr) ent;
- cur->last = (xmlNodePtr) ent;
- }
- return(cur);
-}
-
-/**
- * xmlNewDocText:
- * @doc: the document
- * @content: the text content
- *
- * Creation of a new text node within a document.
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewDocText(xmlDocPtr doc, const xmlChar *content) {
- xmlNodePtr cur;
-
- cur = xmlNewText(content);
- if (cur != NULL) cur->doc = doc;
- return(cur);
-}
-
-/**
- * xmlNewTextLen:
- * @content: the text content
- * @len: the text len.
- *
- * Creation of a new text node with an extra parameter for the content's length
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewTextLen(const xmlChar *content, int len) {
- xmlNodePtr cur;
-
- /*
- * Allocate a new node and fill the fields.
- */
- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewTextLen : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlNode));
- cur->type = XML_TEXT_NODE;
-
- cur->name = xmlStringText;
- if (content != NULL) {
- cur->content = xmlStrndup(content, len);
- }
- return(cur);
-}
-
-/**
- * xmlNewDocTextLen:
- * @doc: the document
- * @content: the text content
- * @len: the text len.
- *
- * Creation of a new text node with an extra content length parameter. The
- * text node pertain to a given document.
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewDocTextLen(xmlDocPtr doc, const xmlChar *content, int len) {
- xmlNodePtr cur;
-
- cur = xmlNewTextLen(content, len);
- if (cur != NULL) cur->doc = doc;
- return(cur);
-}
-
-/**
- * xmlNewComment:
- * @content: the comment content
- *
- * Creation of a new node containing a comment.
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewComment(const xmlChar *content) {
- xmlNodePtr cur;
-
- /*
- * Allocate a new node and fill the fields.
- */
- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewComment : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlNode));
- cur->type = XML_COMMENT_NODE;
-
- cur->name = xmlStringComment;
- if (content != NULL) {
- cur->content = xmlStrdup(content);
- }
- return(cur);
-}
-
-/**
- * xmlNewCDataBlock:
- * @doc: the document
- * @content: the CDATA block content content
- * @len: the length of the block
- *
- * Creation of a new node containing a CDATA block.
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewCDataBlock(xmlDocPtr doc, const xmlChar *content, int len) {
- xmlNodePtr cur;
-
- /*
- * Allocate a new node and fill the fields.
- */
- cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewCDataBlock : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlNode));
- cur->type = XML_CDATA_SECTION_NODE;
- cur->doc = doc;
-
- if (content != NULL) {
- cur->content = xmlStrndup(content, len);
- }
- return(cur);
-}
-
-/**
- * xmlNewDocComment:
- * @doc: the document
- * @content: the comment content
- *
- * Creation of a new node containing a comment within a document.
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewDocComment(xmlDocPtr doc, const xmlChar *content) {
- xmlNodePtr cur;
-
- cur = xmlNewComment(content);
- if (cur != NULL) cur->doc = doc;
- return(cur);
-}
-
-/**
- * xmlSetTreeDoc:
- * @tree: the top element
- * @doc: the document
- *
- * update all nodes under the tree to point to the right document
- */
-void
-xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) {
- xmlAttrPtr prop;
-
- if (tree == NULL)
- return;
- if (tree->doc != doc) {
- if(tree->type == XML_ELEMENT_NODE) {
- prop = tree->properties;
- while (prop != NULL) {
- prop->doc = doc;
- xmlSetListDoc(prop->children, doc);
- prop = prop->next;
- }
- }
- if (tree->children != NULL)
- xmlSetListDoc(tree->children, doc);
- tree->doc = doc;
- }
-}
-
-/**
- * xmlSetListDoc:
- * @list: the first element
- * @doc: the document
- *
- * update all nodes in the list to point to the right document
- */
-void
-xmlSetListDoc(xmlNodePtr list, xmlDocPtr doc) {
- xmlNodePtr cur;
-
- if (list == NULL)
- return;
- cur = list;
- while (cur != NULL) {
- if (cur->doc != doc)
- xmlSetTreeDoc(cur, doc);
- cur = cur->next;
- }
-}
-
-
-/**
- * xmlNewChild:
- * @parent: the parent node
- * @ns: a namespace if any
- * @name: the name of the child
- * @content: the XML content of the child if any.
- *
- * Creation of a new child element, added at the end of @parent children list.
- * @ns and @content parameters are optional (NULL). If content is non NULL,
- * a child list containing the TEXTs and ENTITY_REFs node will be created.
- * NOTE: @content is supposed to be a piece of XML CDATA, so it allow entities
- * references, but XML special chars need to be escaped first by using
- * xmlEncodeEntitiesReentrant(). Use xmlNewTextChild() if entities
- * support is not needed.
- *
- * Returns a pointer to the new node object.
- */
-xmlNodePtr
-xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
- const xmlChar *name, const xmlChar *content) {
- xmlNodePtr cur, prev;
-
- if (parent == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewChild : parent == NULL\n");
-#endif
- return(NULL);
- }
-
- if (name == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewChild : name == NULL\n");
-#endif
- return(NULL);
- }
-
- /*
- * Allocate a new node
- */
- if (parent->type == XML_ELEMENT_NODE) {
- if (ns == NULL)
- cur = xmlNewDocNode(parent->doc, parent->ns, name, content);
- else
- cur = xmlNewDocNode(parent->doc, ns, name, content);
- } else if ((parent->type == XML_DOCUMENT_NODE) ||
- (parent->type == XML_HTML_DOCUMENT_NODE)) {
- if (ns == NULL)
- cur = xmlNewDocNode((xmlDocPtr) parent, NULL, name, content);
- else
- cur = xmlNewDocNode((xmlDocPtr) parent, ns, name, content);
- } else if (parent->type == XML_DOCUMENT_FRAG_NODE) {
- cur = xmlNewDocNode( parent->doc, ns, name, content);
- } else {
- return(NULL);
- }
- if (cur == NULL) return(NULL);
-
- /*
- * add the new element at the end of the children list.
- */
- cur->type = XML_ELEMENT_NODE;
- cur->parent = parent;
- cur->doc = parent->doc;
- if (parent->children == NULL) {
- parent->children = cur;
- parent->last = cur;
- } else {
- prev = parent->last;
- prev->next = cur;
- cur->prev = prev;
- parent->last = cur;
- }
-
- return(cur);
-}
-
-/**
- * xmlAddNextSibling:
- * @cur: the child node
- * @elem: the new node
- *
- * Add a new node @elem as the next sibling of @cur
- * If the new node was already inserted in a document it is
- * first unlinked from its existing context.
- * As a result of text merging @elem may be freed.
- * If the new node is ATTRIBUTE, it is added into properties instead of children.
- * If there is an attribute with equal name, it is first destroyed.
- *
- * Returns the new node or NULL in case of error.
- */
-xmlNodePtr
-xmlAddNextSibling(xmlNodePtr cur, xmlNodePtr elem) {
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddNextSibling : cur == NULL\n");
-#endif
- return(NULL);
- }
- if (elem == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddNextSibling : elem == NULL\n");
-#endif
- return(NULL);
- }
-
- xmlUnlinkNode(elem);
-
- if (elem->type == XML_TEXT_NODE) {
- if (cur->type == XML_TEXT_NODE) {
- xmlNodeAddContent(cur, elem->content);
- xmlFreeNode(elem);
- return(cur);
- }
- if ((cur->next != NULL) && (cur->next->type == XML_TEXT_NODE) &&
- (cur->name == cur->next->name)) {
- xmlChar *tmp;
-
- tmp = xmlStrdup(elem->content);
- tmp = xmlStrcat(tmp, cur->next->content);
- xmlNodeSetContent(cur->next, tmp);
- xmlFree(tmp);
- xmlFreeNode(elem);
- return(cur->next);
- }
- } else if (elem->type == XML_ATTRIBUTE_NODE) {
- /* check if an attribute with the same name exists */
- xmlAttrPtr attr;
-
- if (elem->ns == NULL)
- attr = xmlHasProp(cur->parent, elem->name);
- else
- attr = xmlHasNsProp(cur->parent, elem->name, elem->ns->href);
- if ((attr != NULL) && (attr != (xmlAttrPtr) elem)) {
- /* different instance, destroy it (attributes must be unique) */
- xmlFreeProp(attr);
- }
- }
-
- if (elem->doc != cur->doc) {
- xmlSetTreeDoc(elem, cur->doc);
- }
- elem->parent = cur->parent;
- elem->prev = cur;
- elem->next = cur->next;
- cur->next = elem;
- if (elem->next != NULL)
- elem->next->prev = elem;
- if ((elem->parent != NULL) && (elem->parent->last == cur) && (elem->type != XML_ATTRIBUTE_NODE))
- elem->parent->last = elem;
- return(elem);
-}
-
-/**
- * xmlAddPrevSibling:
- * @cur: the child node
- * @elem: the new node
- *
- * Add a new node @elem as the previous sibling of @cur
- * merging adjacent TEXT nodes (@elem may be freed)
- * If the new node was already inserted in a document it is
- * first unlinked from its existing context.
- * If the new node is ATTRIBUTE, it is added into properties instead of children.
- * If there is an attribute with equal name, it is first destroyed.
- *
- * Returns the new node or NULL in case of error.
- */
-xmlNodePtr
-xmlAddPrevSibling(xmlNodePtr cur, xmlNodePtr elem) {
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddPrevSibling : cur == NULL\n");
-#endif
- return(NULL);
- }
- if (elem == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddPrevSibling : elem == NULL\n");
-#endif
- return(NULL);
- }
-
- xmlUnlinkNode(elem);
-
- if (elem->type == XML_TEXT_NODE) {
- if (cur->type == XML_TEXT_NODE) {
- xmlChar *tmp;
-
- tmp = xmlStrdup(elem->content);
- tmp = xmlStrcat(tmp, cur->content);
- xmlNodeSetContent(cur, tmp);
- xmlFree(tmp);
- xmlFreeNode(elem);
- return(cur);
- }
- if ((cur->prev != NULL) && (cur->prev->type == XML_TEXT_NODE) &&
- (cur->name == cur->prev->name)) {
- xmlNodeAddContent(cur->prev, elem->content);
- xmlFreeNode(elem);
- return(cur->prev);
- }
- } else if (elem->type == XML_ATTRIBUTE_NODE) {
- /* check if an attribute with the same name exists */
- xmlAttrPtr attr;
-
- if (elem->ns == NULL)
- attr = xmlHasProp(cur->parent, elem->name);
- else
- attr = xmlHasNsProp(cur->parent, elem->name, elem->ns->href);
- if ((attr != NULL) && (attr != (xmlAttrPtr) elem)) {
- /* different instance, destroy it (attributes must be unique) */
- xmlFreeProp(attr);
- }
- }
-
- if (elem->doc != cur->doc) {
- xmlSetTreeDoc(elem, cur->doc);
- }
- elem->parent = cur->parent;
- elem->next = cur;
- elem->prev = cur->prev;
- cur->prev = elem;
- if (elem->prev != NULL)
- elem->prev->next = elem;
- if (elem->parent != NULL) {
- if (elem->type == XML_ATTRIBUTE_NODE) {
- if (elem->parent->properties == (xmlAttrPtr) cur) {
- elem->parent->properties = (xmlAttrPtr) elem;
- }
- } else {
- if (elem->parent->children == cur) {
- elem->parent->children = elem;
- }
- }
- }
- return(elem);
-}
-
-/**
- * xmlAddSibling:
- * @cur: the child node
- * @elem: the new node
- *
- * Add a new element @elem to the list of siblings of @cur
- * merging adjacent TEXT nodes (@elem may be freed)
- * If the new element was already inserted in a document it is
- * first unlinked from its existing context.
- *
- * Returns the new element or NULL in case of error.
- */
-xmlNodePtr
-xmlAddSibling(xmlNodePtr cur, xmlNodePtr elem) {
- xmlNodePtr parent;
-
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddSibling : cur == NULL\n");
-#endif
- return(NULL);
- }
-
- if (elem == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddSibling : elem == NULL\n");
-#endif
- return(NULL);
- }
-
- /*
- * Constant time is we can rely on the ->parent->last to find
- * the last sibling.
- */
- if ((cur->parent != NULL) &&
- (cur->parent->children != NULL) &&
- (cur->parent->last != NULL) &&
- (cur->parent->last->next == NULL)) {
- cur = cur->parent->last;
- } else {
- while (cur->next != NULL) cur = cur->next;
- }
-
- xmlUnlinkNode(elem);
-
- if ((cur->type == XML_TEXT_NODE) && (elem->type == XML_TEXT_NODE)) {
- xmlNodeAddContent(cur, elem->content);
- xmlFreeNode(elem);
- return(cur);
- }
-
- if (elem->doc != cur->doc) {
- xmlSetTreeDoc(elem, cur->doc);
- }
- parent = cur->parent;
- elem->prev = cur;
- elem->next = NULL;
- elem->parent = parent;
- cur->next = elem;
- if (parent != NULL)
- parent->last = elem;
-
- return(elem);
-}
-
-/**
- * xmlAddChildList:
- * @parent: the parent node
- * @cur: the first node in the list
- *
- * Add a list of node at the end of the child list of the parent
- * merging adjacent TEXT nodes (@cur may be freed)
- *
- * Returns the last child or NULL in case of error.
- */
-xmlNodePtr
-xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur) {
- xmlNodePtr prev;
-
- if (parent == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddChildList : parent == NULL\n");
-#endif
- return(NULL);
- }
-
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddChildList : child == NULL\n");
-#endif
- return(NULL);
- }
-
- if ((cur->doc != NULL) && (parent->doc != NULL) &&
- (cur->doc != parent->doc)) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "Elements moved to a different document\n");
-#endif
- }
-
- /*
- * add the first element at the end of the children list.
- */
- if (parent->children == NULL) {
- parent->children = cur;
- } else {
- /*
- * If cur and parent->last both are TEXT nodes, then merge them.
- */
- if ((cur->type == XML_TEXT_NODE) &&
- (parent->last->type == XML_TEXT_NODE) &&
- (cur->name == parent->last->name)) {
- xmlNodeAddContent(parent->last, cur->content);
- /*
- * if it's the only child, nothing more to be done.
- */
- if (cur->next == NULL) {
- xmlFreeNode(cur);
- return(parent->last);
- }
- prev = cur;
- cur = cur->next;
- xmlFreeNode(prev);
- }
- prev = parent->last;
- prev->next = cur;
- cur->prev = prev;
- }
- while (cur->next != NULL) {
- cur->parent = parent;
- if (cur->doc != parent->doc) {
- xmlSetTreeDoc(cur, parent->doc);
- }
- cur = cur->next;
- }
- cur->parent = parent;
- cur->doc = parent->doc; /* the parent may not be linked to a doc ! */
- parent->last = cur;
-
- return(cur);
-}
-
-/**
- * xmlAddChild:
- * @parent: the parent node
- * @cur: the child node
- *
- * Add a new node to @parent, at the end of the child (or property) list
- * merging adjacent TEXT nodes (in which case @cur is freed)
- * If the new node was already inserted in a document it is
- * first unlinked from its existing context.
- * If the new node is ATTRIBUTE, it is added into properties instead of children.
- * If there is an attribute with equal name, it is first destroyed.
- *
- * Returns the child or NULL in case of error.
- */
-xmlNodePtr
-xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
- xmlNodePtr prev;
-
- if (parent == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddChild : parent == NULL\n");
-#endif
- return(NULL);
- }
-
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddChild : child == NULL\n");
-#endif
- return(NULL);
- }
-
- /*
- * If cur is a TEXT node, merge its content with adjacent TEXT nodes
- * cur is then freed.
- */
- if (cur->type == XML_TEXT_NODE) {
- if ((parent->type == XML_TEXT_NODE) &&
- (parent->content != NULL)) {
- xmlNodeAddContent(parent, cur->content);
- xmlFreeNode(cur);
- return(parent);
- }
- if ((parent->last != NULL) && (parent->last->type == XML_TEXT_NODE) &&
- (parent->last->name == cur->name)) {
- xmlNodeAddContent(parent->last, cur->content);
- xmlFreeNode(cur);
- return(parent->last);
- }
- }
-
- /*
- * add the new element at the end of the children list.
- */
- cur->parent = parent;
- if (cur->doc != parent->doc) {
- xmlSetTreeDoc(cur, parent->doc);
- }
-
- /*
- * Coalescing
- */
- if ((parent->type == XML_TEXT_NODE) &&
- (parent->content != NULL)) {
- xmlNodeAddContent(parent, cur->content);
- xmlFreeNode(cur);
- return(parent);
- }
- if (cur->type == XML_ATTRIBUTE_NODE) {
- if (parent->properties == NULL) {
- parent->properties = (xmlAttrPtr) cur;
- } else {
- /* check if an attribute with the same name exists */
- xmlAttrPtr lastattr;
-
- if (cur->ns == NULL)
- lastattr = xmlHasProp(parent, cur->name);
- else
- lastattr = xmlHasNsProp(parent, cur->name, cur->ns->href);
- if ((lastattr != NULL) && (lastattr != (xmlAttrPtr) cur)) {
- /* different instance, destroy it (attributes must be unique) */
- xmlFreeProp(lastattr);
- }
- /* find the end */
- lastattr = parent->properties;
- while (lastattr->next != NULL) {
- lastattr = lastattr->next;
- }
- lastattr->next = (xmlAttrPtr) cur;
- ((xmlAttrPtr) cur)->prev = lastattr;
- }
- } else {
- if (parent->children == NULL) {
- parent->children = cur;
- parent->last = cur;
- } else {
- prev = parent->last;
- prev->next = cur;
- cur->prev = prev;
- parent->last = cur;
- }
- }
- return(cur);
-}
-
-/**
- * xmlGetLastChild:
- * @parent: the parent node
- *
- * Search the last child of a node.
- * Returns the last child or NULL if none.
- */
-xmlNodePtr
-xmlGetLastChild(xmlNodePtr parent) {
- if (parent == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlGetLastChild : parent == NULL\n");
-#endif
- return(NULL);
- }
- return(parent->last);
-}
-
-/**
- * xmlFreeNodeList:
- * @cur: the first node in the list
- *
- * Free a node and all its siblings, this is a recursive behaviour, all
- * the children are freed too.
- */
-void
-xmlFreeNodeList(xmlNodePtr cur) {
- xmlNodePtr next;
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlFreeNodeList : node == NULL\n");
-#endif
- return;
- }
- if (cur->type == XML_NAMESPACE_DECL) {
- xmlFreeNsList((xmlNsPtr) cur);
- return;
- }
- while (cur != NULL) {
- next = cur->next;
- /* unroll to speed up freeing the document */
- if (cur->type != XML_DTD_NODE) {
- if ((cur->children != NULL) &&
- (cur->type != XML_ENTITY_REF_NODE))
- xmlFreeNodeList(cur->children);
- if (((cur->type == XML_ELEMENT_NODE) ||
- (cur->type == XML_XINCLUDE_START) ||
- (cur->type == XML_XINCLUDE_END)) &&
- (cur->properties != NULL))
- xmlFreePropList(cur->properties);
- if ((cur->type != XML_ELEMENT_NODE) &&
- (cur->type != XML_XINCLUDE_START) &&
- (cur->type != XML_XINCLUDE_END) &&
- (cur->type != XML_ENTITY_REF_NODE)) {
- if (cur->content != NULL) xmlFree(cur->content);
- }
- if (((cur->type == XML_ELEMENT_NODE) ||
- (cur->type == XML_XINCLUDE_START) ||
- (cur->type == XML_XINCLUDE_END)) &&
- (cur->nsDef != NULL))
- xmlFreeNsList(cur->nsDef);
-
- /*
- * When a node is a text node or a comment, it uses a global static
- * variable for the name of the node.
- *
- * The xmlStrEqual comparisons need to be done when (happened with
- * XML::libXML and XML::libXSLT) the library is included twice
- * statically in the binary and a tree allocated by one occurrence
- * of the lib gets freed by the other occurrence, in this case
- * the string addresses compare are not sufficient.
- */
- if ((cur->name != NULL) &&
- (cur->name != xmlStringText) &&
- (cur->name != xmlStringTextNoenc) &&
- (cur->name != xmlStringComment)) {
- if (cur->type == XML_TEXT_NODE) {
- if ((!xmlStrEqual(cur->name, xmlStringText)) &&
- (!xmlStrEqual(cur->name, xmlStringTextNoenc)))
- xmlFree((char *) cur->name);
- } else if (cur->type == XML_COMMENT_NODE) {
- if (!xmlStrEqual(cur->name, xmlStringComment))
- xmlFree((char *) cur->name);
- } else
- xmlFree((char *) cur->name);
- }
- /* TODO : derecursivate this function */
- xmlFree(cur);
- }
- cur = next;
- }
-}
-
-/**
- * xmlFreeNode:
- * @cur: the node
- *
- * Free a node, this is a recursive behaviour, all the children are freed too.
- * This doesn't unlink the child from the list, use xmlUnlinkNode() first.
- */
-void
-xmlFreeNode(xmlNodePtr cur) {
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlFreeNode : node == NULL\n");
-#endif
- return;
- }
- /* use xmlFreeDtd for DTD nodes */
- if (cur->type == XML_DTD_NODE) {
- xmlFreeDtd((xmlDtdPtr) cur);
- return;
- }
- if (cur->type == XML_NAMESPACE_DECL) {
- xmlFreeNs((xmlNsPtr) cur);
- return;
- }
- if (cur->type == XML_ATTRIBUTE_NODE) {
- xmlFreeProp((xmlAttrPtr) cur);
- return;
- }
- if ((cur->children != NULL) &&
- (cur->type != XML_ENTITY_REF_NODE))
- xmlFreeNodeList(cur->children);
- if (((cur->type == XML_ELEMENT_NODE) ||
- (cur->type == XML_XINCLUDE_START) ||
- (cur->type == XML_XINCLUDE_END)) &&
- (cur->properties != NULL))
- xmlFreePropList(cur->properties);
- if ((cur->type != XML_ELEMENT_NODE) &&
- (cur->content != NULL) &&
- (cur->type != XML_ENTITY_REF_NODE) &&
- (cur->type != XML_XINCLUDE_END) &&
- (cur->type != XML_XINCLUDE_START)) {
- xmlFree(cur->content);
- }
-
- /*
- * When a node is a text node or a comment, it uses a global static
- * variable for the name of the node.
- *
- * The xmlStrEqual comparisons need to be done when (happened with
- * XML::libXML and XML::libXSLT) the library is included twice statically
- * in the binary and a tree allocated by one occurence of the lib gets
- * freed by the other occurrence, in this case the string addresses compare
- * are not sufficient.
- */
- if ((cur->name != NULL) &&
- (cur->name != xmlStringText) &&
- (cur->name != xmlStringTextNoenc) &&
- (cur->name != xmlStringComment)) {
- if (cur->type == XML_TEXT_NODE) {
- if ((!xmlStrEqual(cur->name, xmlStringText)) &&
- (!xmlStrEqual(cur->name, xmlStringTextNoenc)))
- xmlFree((char *) cur->name);
- } else if (cur->type == XML_COMMENT_NODE) {
- if (!xmlStrEqual(cur->name, xmlStringComment))
- xmlFree((char *) cur->name);
- } else
- xmlFree((char *) cur->name);
- }
-
- if (((cur->type == XML_ELEMENT_NODE) ||
- (cur->type == XML_XINCLUDE_START) ||
- (cur->type == XML_XINCLUDE_END)) &&
- (cur->nsDef != NULL))
- xmlFreeNsList(cur->nsDef);
- xmlFree(cur);
-}
-
-/**
- * xmlUnlinkNode:
- * @cur: the node
- *
- * Unlink a node from it's current context, the node is not freed
- */
-void
-xmlUnlinkNode(xmlNodePtr cur) {
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlUnlinkNode : node == NULL\n");
-#endif
- return;
- }
- if (cur->type == XML_DTD_NODE) {
- xmlDocPtr doc;
- doc = cur->doc;
- if (doc->intSubset == (xmlDtdPtr) cur)
- doc->intSubset = NULL;
- if (doc->extSubset == (xmlDtdPtr) cur)
- doc->extSubset = NULL;
- }
- if (cur->parent != NULL) {
- xmlNodePtr parent;
- parent = cur->parent;
- if (cur->type == XML_ATTRIBUTE_NODE) {
- if (parent->properties == (xmlAttrPtr) cur)
- parent->properties = ((xmlAttrPtr) cur)->next;
- } else {
- if (parent->children == cur)
- parent->children = cur->next;
- if (parent->last == cur)
- parent->last = cur->prev;
- }
- cur->parent = NULL;
- }
- if (cur->next != NULL)
- cur->next->prev = cur->prev;
- if (cur->prev != NULL)
- cur->prev->next = cur->next;
- cur->next = cur->prev = NULL;
-}
-
-/**
- * xmlReplaceNode:
- * @old: the old node
- * @cur: the node
- *
- * Unlink the old node from it's current context, prune the new one
- * at the same place. If @cur was already inserted in a document it is
- * first unlinked from its existing context.
- *
- * Returns the @old node
- */
-xmlNodePtr
-xmlReplaceNode(xmlNodePtr old, xmlNodePtr cur) {
- if (old == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlReplaceNode : old == NULL\n");
-#endif
- return(NULL);
- }
- if (cur == NULL) {
- xmlUnlinkNode(old);
- return(old);
- }
- if (cur == old) {
- return(old);
- }
- if ((old->type==XML_ATTRIBUTE_NODE) && (cur->type!=XML_ATTRIBUTE_NODE)) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlReplaceNode : Trying to replace attribute node with other node type\n");
-#endif
- return(old);
- }
- if ((cur->type==XML_ATTRIBUTE_NODE) && (old->type!=XML_ATTRIBUTE_NODE)) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlReplaceNode : Trying to replace a non-attribute node with attribute node\n");
-#endif
- return(old);
- }
- if ((old->type==XML_ATTRIBUTE_NODE) && (cur->type!=XML_ATTRIBUTE_NODE)) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlReplaceNode : Trying to replace attribute node with other node type\n");
-#endif
- return(old);
- }
- if ((cur->type==XML_ATTRIBUTE_NODE) && (old->type!=XML_ATTRIBUTE_NODE)) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlReplaceNode : Trying to replace a non-attribute node with attribute node\n");
-#endif
- return(old);
- }
- xmlUnlinkNode(cur);
- cur->doc = old->doc;
- cur->parent = old->parent;
- cur->next = old->next;
- if (cur->next != NULL)
- cur->next->prev = cur;
- cur->prev = old->prev;
- if (cur->prev != NULL)
- cur->prev->next = cur;
- if (cur->parent != NULL) {
- if (cur->type == XML_ATTRIBUTE_NODE) {
- if (cur->parent->properties == (xmlAttrPtr)old)
- cur->parent->properties = ((xmlAttrPtr) cur);
- } else {
- if (cur->parent->children == old)
- cur->parent->children = cur;
- if (cur->parent->last == old)
- cur->parent->last = cur;
- }
- }
- old->next = old->prev = NULL;
- old->parent = NULL;
- return(old);
-}
-
-/************************************************************************
- * *
- * Copy operations *
- * *
- ************************************************************************/
-
-/**
- * xmlCopyNamespace:
- * @cur: the namespace
- *
- * Do a copy of the namespace.
- *
- * Returns: a new #xmlNsPtr, or NULL in case of error.
- */
-xmlNsPtr
-xmlCopyNamespace(xmlNsPtr cur) {
- xmlNsPtr ret;
-
- if (cur == NULL) return(NULL);
- switch (cur->type) {
- case XML_LOCAL_NAMESPACE:
- ret = xmlNewNs(NULL, cur->href, cur->prefix);
- break;
- default:
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlCopyNamespace: invalid type %d\n", cur->type);
-#endif
- return(NULL);
- }
- return(ret);
-}
-
-/**
- * xmlCopyNamespaceList:
- * @cur: the first namespace
- *
- * Do a copy of an namespace list.
- *
- * Returns: a new #xmlNsPtr, or NULL in case of error.
- */
-xmlNsPtr
-xmlCopyNamespaceList(xmlNsPtr cur) {
- xmlNsPtr ret = NULL;
- xmlNsPtr p = NULL,q;
-
- while (cur != NULL) {
- q = xmlCopyNamespace(cur);
- if (p == NULL) {
- ret = p = q;
- } else {
- p->next = q;
- p = q;
- }
- cur = cur->next;
- }
- return(ret);
-}
-
-static xmlNodePtr
-xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent);
-/**
- * xmlCopyProp:
- * @target: the element where the attribute will be grafted
- * @cur: the attribute
- *
- * Do a copy of the attribute.
- *
- * Returns: a new #xmlAttrPtr, or NULL in case of error.
- */
-xmlAttrPtr
-xmlCopyProp(xmlNodePtr target, xmlAttrPtr cur) {
- xmlAttrPtr ret;
-
- if (cur == NULL) return(NULL);
- if (target != NULL)
- ret = xmlNewDocProp(target->doc, cur->name, NULL);
- else if (cur->parent != NULL)
- ret = xmlNewDocProp(cur->parent->doc, cur->name, NULL);
- else if (cur->children != NULL)
- ret = xmlNewDocProp(cur->children->doc, cur->name, NULL);
- else
- ret = xmlNewDocProp(NULL, cur->name, NULL);
- if (ret == NULL) return(NULL);
- ret->parent = target;
-
- if ((cur->ns != NULL) && (target != NULL)) {
- xmlNsPtr ns;
-/*
- * if (target->doc)
- * ns = xmlSearchNs(target->doc, target, cur->ns->prefix);
- * else if (cur->doc) / * target may not yet have a doc : KPI * /
- * ns = xmlSearchNs(cur->doc, target, cur->ns->prefix);
- * else
- * ns = NULL;
- * ret->ns = ns;
- */
- ns = xmlSearchNs(target->doc, target, cur->ns->prefix);
- if (ns == NULL) {
- /*
- * Humm, we are copying an element whose namespace is defined
- * out of the new tree scope. Search it in the original tree
- * and add it at the top of the new tree
- */
- ns = xmlSearchNs(cur->doc, cur->parent, cur->ns->prefix);
- if (ns != NULL) {
- xmlNodePtr root = target;
- xmlNodePtr pred = NULL;
-
- while (root->parent != NULL) {
- pred = root;
- root = root->parent;
- }
- if (root == (xmlNodePtr) target->doc) {
- /* correct possibly cycling above the document elt */
- root = pred;
- }
- ret->ns = xmlNewNs(root, ns->href, ns->prefix);
- }
- } else {
- /*
- * we have to find something appropriate here since
- * we cant be sure, that the namespce we found is identified
- * by the prefix
- */
- if (xmlStrEqual(ns->href, cur->ns->href)) {
- /* this is the nice case */
- ret->ns = ns;
- } else {
- /*
- * we are in trouble: we need a new reconcilied namespace.
- * This is expensive
- */
- ret->ns = xmlNewReconciliedNs(target->doc, target, cur->ns);
- }
- }
-
- } else
- ret->ns = NULL;
-
- if (cur->children != NULL) {
- xmlNodePtr tmp;
-
- ret->children = xmlStaticCopyNodeList(cur->children, ret->doc, (xmlNodePtr) ret);
- ret->last = NULL;
- tmp = ret->children;
- while (tmp != NULL) {
- /* tmp->parent = (xmlNodePtr)ret; */
- if (tmp->next == NULL)
- ret->last = tmp;
- tmp = tmp->next;
- }
- }
- /*
- * Try to handle IDs
- */
- if ((target!= NULL) && (cur!= NULL) &&
- (target->doc != NULL) && (cur->doc != NULL) &&
- (cur->doc->ids != NULL) && (cur->parent != NULL)) {
- if (xmlIsID(cur->doc, cur->parent, cur)) {
- xmlChar *id;
-
- id = xmlNodeListGetString(cur->doc, cur->children, 1);
- if (id != NULL) {
- xmlAddID(NULL, target->doc, id, ret);
- xmlFree(id);
- }
- }
- }
- return(ret);
-}
-
-/**
- * xmlCopyPropList:
- * @target: the element where the attributes will be grafted
- * @cur: the first attribute
- *
- * Do a copy of an attribute list.
- *
- * Returns: a new #xmlAttrPtr, or NULL in case of error.
- */
-xmlAttrPtr
-xmlCopyPropList(xmlNodePtr target, xmlAttrPtr cur) {
- xmlAttrPtr ret = NULL;
- xmlAttrPtr p = NULL,q;
-
- while (cur != NULL) {
- q = xmlCopyProp(target, cur);
- if (p == NULL) {
- ret = p = q;
- } else {
- p->next = q;
- q->prev = p;
- p = q;
- }
- cur = cur->next;
- }
- return(ret);
-}
-
-/*
- * NOTE about the CopyNode operations !
- *
- * They are split into external and internal parts for one
- * tricky reason: namespaces. Doing a direct copy of a node
- * say RPM:Copyright without changing the namespace pointer to
- * something else can produce stale links. One way to do it is
- * to keep a reference counter but this doesn't work as soon
- * as one move the element or the subtree out of the scope of
- * the existing namespace. The actual solution seems to add
- * a copy of the namespace at the top of the copied tree if
- * not available in the subtree.
- * Hence two functions, the public front-end call the inner ones
- */
-
-static xmlNodePtr
-xmlStaticCopyNode(const xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
- int recursive) {
- xmlNodePtr ret;
-
- if (node == NULL) return(NULL);
- switch (node->type) {
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_ELEMENT_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- break;
- case XML_ATTRIBUTE_NODE:
- return((xmlNodePtr) xmlCopyProp(parent, (xmlAttrPtr) node));
- case XML_NAMESPACE_DECL:
- return((xmlNodePtr) xmlCopyNamespaceList((xmlNsPtr) node));
-
- case XML_DOCUMENT_NODE:
- case XML_HTML_DOCUMENT_NODE:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- return((xmlNodePtr) xmlCopyDoc((xmlDocPtr) node, recursive));
- case XML_DOCUMENT_TYPE_NODE:
- case XML_NOTATION_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- return(NULL);
- }
-
- /*
- * Allocate a new node and fill the fields.
- */
- ret = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlStaticCopyNode : malloc failed\n");
- return(NULL);
- }
- memset(ret, 0, sizeof(xmlNode));
- ret->type = node->type;
-
- ret->doc = doc;
- ret->parent = parent;
- if (node->name == xmlStringText)
- ret->name = xmlStringText;
- else if (node->name == xmlStringTextNoenc)
- ret->name = xmlStringTextNoenc;
- else if (node->name == xmlStringComment)
- ret->name = xmlStringComment;
- else if (node->name != NULL)
- ret->name = xmlStrdup(node->name);
- if ((node->type != XML_ELEMENT_NODE) &&
- (node->content != NULL) &&
- (node->type != XML_ENTITY_REF_NODE) &&
- (node->type != XML_XINCLUDE_END) &&
- (node->type != XML_XINCLUDE_START)) {
- ret->content = xmlStrdup(node->content);
- }else{
- if (node->type == XML_ELEMENT_NODE)
- ret->content = (void*)(long) node->content;
- }
- if (parent != NULL) {
- xmlNodePtr tmp;
-
- tmp = xmlAddChild(parent, ret);
- /* node could have coalesced */
- if (tmp != ret)
- return(tmp);
- }
-
- if (!recursive) return(ret);
- if (node->nsDef != NULL)
- ret->nsDef = xmlCopyNamespaceList(node->nsDef);
-
- if (node->ns != NULL) {
- xmlNsPtr ns;
-
- ns = xmlSearchNs(doc, ret, node->ns->prefix);
- if (ns == NULL) {
- /*
- * Humm, we are copying an element whose namespace is defined
- * out of the new tree scope. Search it in the original tree
- * and add it at the top of the new tree
- */
- ns = xmlSearchNs(node->doc, node, node->ns->prefix);
- if (ns != NULL) {
- xmlNodePtr root = ret;
-
- while (root->parent != NULL) root = root->parent;
- ret->ns = xmlNewNs(root, ns->href, ns->prefix);
- }
- } else {
- /*
- * reference the existing namespace definition in our own tree.
- */
- ret->ns = ns;
- }
- }
- if (node->properties != NULL)
- ret->properties = xmlCopyPropList(ret, node->properties);
- if (node->type == XML_ENTITY_REF_NODE) {
- if ((doc == NULL) || (node->doc != doc)) {
- /*
- * The copied node will go into a separate document, so
- * to avoid dangling references to the ENTITY_DECL node
- * we cannot keep the reference. Try to find it in the
- * target document.
- */
- ret->children = (xmlNodePtr) xmlGetDocEntity(doc, ret->name);
- } else {
- ret->children = node->children;
- }
- ret->last = ret->children;
- } else if (node->children != NULL) {
- ret->children = xmlStaticCopyNodeList(node->children, doc, ret);
- UPDATE_LAST_CHILD_AND_PARENT(ret)
- }
- return(ret);
-}
-
-static xmlNodePtr
-xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
- xmlNodePtr ret = NULL;
- xmlNodePtr p = NULL,q;
-
- while (node != NULL) {
- if (node->type == XML_DTD_NODE ) {
- if (doc == NULL) {
- node = node->next;
- continue;
- }
- if (doc->intSubset == NULL) {
- q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
- q->doc = doc;
- q->parent = parent;
- doc->intSubset = (xmlDtdPtr) q;
- xmlAddChild(parent, q);
- } else {
- q = (xmlNodePtr) doc->intSubset;
- xmlAddChild(parent, q);
- }
- } else
- q = xmlStaticCopyNode(node, doc, parent, 1);
- if (ret == NULL) {
- q->prev = NULL;
- ret = p = q;
- } else if (p != q) {
- /* the test is required if xmlStaticCopyNode coalesced 2 text nodes */
- p->next = q;
- q->prev = p;
- p = q;
- }
- node = node->next;
- }
- return(ret);
-}
-
-/**
- * xmlCopyNode:
- * @node: the node
- * @recursive: if 1 do a recursive copy.
- *
- * Do a copy of the node.
- *
- * Returns: a new #xmlNodePtr, or NULL in case of error.
- */
-xmlNodePtr
-xmlCopyNode(const xmlNodePtr node, int recursive) {
- xmlNodePtr ret;
-
- ret = xmlStaticCopyNode(node, NULL, NULL, recursive);
- return(ret);
-}
-
-/**
- * xmlDocCopyNode:
- * @node: the node
- * @doc: the document
- * @recursive: if 1 do a recursive copy.
- *
- * Do a copy of the node to a given document.
- *
- * Returns: a new #xmlNodePtr, or NULL in case of error.
- */
-xmlNodePtr
-xmlDocCopyNode(const xmlNodePtr node, xmlDocPtr doc, int recursive) {
- xmlNodePtr ret;
-
- ret = xmlStaticCopyNode(node, doc, NULL, recursive);
- return(ret);
-}
-
-/**
- * xmlCopyNodeList:
- * @node: the first node in the list.
- *
- * Do a recursive copy of the node list.
- *
- * Returns: a new #xmlNodePtr, or NULL in case of error.
- */
-xmlNodePtr xmlCopyNodeList(const xmlNodePtr node) {
- xmlNodePtr ret = xmlStaticCopyNodeList(node, NULL, NULL);
- return(ret);
-}
-
-/**
- * xmlCopyDtd:
- * @dtd: the dtd
- *
- * Do a copy of the dtd.
- *
- * Returns: a new #xmlDtdPtr, or NULL in case of error.
- */
-xmlDtdPtr
-xmlCopyDtd(xmlDtdPtr dtd) {
- xmlDtdPtr ret;
- xmlNodePtr cur, p = NULL, q;
-
- if (dtd == NULL) return(NULL);
- ret = xmlNewDtd(NULL, dtd->name, dtd->ExternalID, dtd->SystemID);
- if (ret == NULL) return(NULL);
- if (dtd->entities != NULL)
- ret->entities = (void *) xmlCopyEntitiesTable(
- (xmlEntitiesTablePtr) dtd->entities);
- if (dtd->notations != NULL)
- ret->notations = (void *) xmlCopyNotationTable(
- (xmlNotationTablePtr) dtd->notations);
- if (dtd->elements != NULL)
- ret->elements = (void *) xmlCopyElementTable(
- (xmlElementTablePtr) dtd->elements);
- if (dtd->attributes != NULL)
- ret->attributes = (void *) xmlCopyAttributeTable(
- (xmlAttributeTablePtr) dtd->attributes);
- if (dtd->pentities != NULL)
- ret->pentities = (void *) xmlCopyEntitiesTable(
- (xmlEntitiesTablePtr) dtd->pentities);
-
- cur = dtd->children;
- while (cur != NULL) {
- q = NULL;
-
- if (cur->type == XML_ENTITY_DECL) {
- xmlEntityPtr tmp = (xmlEntityPtr) cur;
- switch (tmp->etype) {
- case XML_INTERNAL_GENERAL_ENTITY:
- case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
- case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
- q = (xmlNodePtr) xmlGetEntityFromDtd(ret, tmp->name);
- break;
- case XML_INTERNAL_PARAMETER_ENTITY:
- case XML_EXTERNAL_PARAMETER_ENTITY:
- q = (xmlNodePtr)
- xmlGetParameterEntityFromDtd(ret, tmp->name);
- break;
- case XML_INTERNAL_PREDEFINED_ENTITY:
- break;
- }
- } else if (cur->type == XML_ELEMENT_DECL) {
- xmlElementPtr tmp = (xmlElementPtr) cur;
- q = (xmlNodePtr)
- xmlGetDtdQElementDesc(ret, tmp->name, tmp->prefix);
- } else if (cur->type == XML_ATTRIBUTE_DECL) {
- xmlAttributePtr tmp = (xmlAttributePtr) cur;
- q = (xmlNodePtr)
- xmlGetDtdQAttrDesc(ret, tmp->elem, tmp->name, tmp->prefix);
- } else if (cur->type == XML_COMMENT_NODE) {
- q = xmlCopyNode(cur, 0);
- }
-
- if (q == NULL) {
- cur = cur->next;
- continue;
- }
-
- if (p == NULL)
- ret->children = q;
- else
- p->next = q;
-
- q->prev = p;
- q->parent = (xmlNodePtr) ret;
- q->next = NULL;
- ret->last = q;
- p = q;
- cur = cur->next;
- }
-
- return(ret);
-}
-
-/**
- * xmlCopyDoc:
- * @doc: the document
- * @recursive: if 1 do a recursive copy.
- *
- * Do a copy of the document info. If recursive, the content tree will
- * be copied too as well as DTD, namespaces and entities.
- *
- * Returns: a new #xmlDocPtr, or NULL in case of error.
- */
-xmlDocPtr
-xmlCopyDoc(xmlDocPtr doc, int recursive) {
- xmlDocPtr ret;
-
- if (doc == NULL) return(NULL);
- ret = xmlNewDoc(doc->version);
- if (ret == NULL) return(NULL);
- if (doc->name != NULL)
- ret->name = xmlMemStrdup(doc->name);
- if (doc->encoding != NULL)
- ret->encoding = xmlStrdup(doc->encoding);
- ret->charset = doc->charset;
- ret->compression = doc->compression;
- ret->standalone = doc->standalone;
- if (!recursive) return(ret);
-
- ret->last = NULL;
- ret->children = NULL;
- if (doc->intSubset != NULL) {
- ret->intSubset = xmlCopyDtd(doc->intSubset);
- xmlSetTreeDoc((xmlNodePtr)ret->intSubset, ret);
- ret->intSubset->parent = ret;
- }
- if (doc->oldNs != NULL)
- ret->oldNs = xmlCopyNamespaceList(doc->oldNs);
- if (doc->children != NULL) {
- xmlNodePtr tmp;
-
- ret->children = xmlStaticCopyNodeList(doc->children, ret,
- (xmlNodePtr)ret);
- ret->last = NULL;
- tmp = ret->children;
- while (tmp != NULL) {
- if (tmp->next == NULL)
- ret->last = tmp;
- tmp = tmp->next;
- }
- }
- return(ret);
-}
-
-/************************************************************************
- * *
- * Content access functions *
- * *
- ************************************************************************/
-
-/**
- * xmlGetLineNo:
- * @node: valid node
- *
- * Get line number of node. this requires activation of this option
- * before invoking the parser by calling xmlLineNumbersDefault(1)
- *
- * Returns the line number if successful, -1 otherwise
- */
-long
-xmlGetLineNo(xmlNodePtr node)
-{
- long result = -1;
-
- if (!node)
- return result;
- if (node->type == XML_ELEMENT_NODE)
- result = (long) node->content;
- else if ((node->prev != NULL) &&
- ((node->prev->type == XML_ELEMENT_NODE) ||
- (node->prev->type == XML_TEXT_NODE)))
- result = xmlGetLineNo(node->prev);
- else if ((node->parent != NULL) &&
- ((node->parent->type == XML_ELEMENT_NODE) ||
- (node->parent->type == XML_TEXT_NODE)))
- result = xmlGetLineNo(node->parent);
-
- return result;
-}
-
-/**
- * xmlGetNodePath:
- * @node: a node
- *
- * Build a structure based Path for the given node
- *
- * Returns the new path or NULL in case of error. The caller must free
- * the returned string
- */
-xmlChar *
-xmlGetNodePath(xmlNodePtr node)
-{
- xmlNodePtr cur, tmp, next;
- xmlChar *buffer = NULL, *temp;
- size_t buf_len;
- xmlChar *buf;
- const char *sep;
- const char *name;
- char nametemp[100];
- int occur = 0;
-
- if (node == NULL)
- return (NULL);
-
- buf_len = 500;
- buffer = (xmlChar *) xmlMalloc(buf_len * sizeof(xmlChar));
- if (buffer == NULL)
- return (NULL);
- buf = (xmlChar *) xmlMalloc(buf_len * sizeof(xmlChar));
- if (buf == NULL) {
- xmlFree(buffer);
- return (NULL);
- }
-
- buffer[0] = 0;
- cur = node;
- do {
- name = "";
- sep = "?";
- occur = 0;
- if ((cur->type == XML_DOCUMENT_NODE) ||
- (cur->type == XML_HTML_DOCUMENT_NODE)) {
- if (buffer[0] == '/')
- break;
- sep = "/";
- next = NULL;
- } else if (cur->type == XML_ELEMENT_NODE) {
- sep = "/";
- name = (const char *) cur->name;
- if (cur->ns) {
- snprintf(nametemp, sizeof(nametemp) - 1,
- "%s:%s", cur->ns->prefix, cur->name);
- nametemp[sizeof(nametemp) - 1] = 0;
- name = nametemp;
- }
- next = cur->parent;
-
- /*
- * Thumbler index computation
- */
- tmp = cur->prev;
- while (tmp != NULL) {
- if ((tmp->type == XML_ELEMENT_NODE) &&
- (xmlStrEqual(cur->name, tmp->name)))
- occur++;
- tmp = tmp->prev;
- }
- if (occur == 0) {
- tmp = cur->next;
- while (tmp != NULL && occur == 0) {
- if ((tmp->type == XML_ELEMENT_NODE) &&
- (xmlStrEqual(cur->name, tmp->name)))
- occur++;
- tmp = tmp->next;
- }
- if (occur != 0)
- occur = 1;
- } else
- occur++;
- } else if (cur->type == XML_COMMENT_NODE) {
- sep = "/";
- name = "comment()";
- next = cur->parent;
-
- /*
- * Thumbler index computation
- */
- tmp = cur->prev;
- while (tmp != NULL) {
- if (tmp->type == XML_COMMENT_NODE)
- occur++;
- tmp = tmp->prev;
- }
- if (occur == 0) {
- tmp = cur->next;
- while (tmp != NULL && occur == 0) {
- if (tmp->type == XML_COMMENT_NODE)
- occur++;
- tmp = tmp->next;
- }
- if (occur != 0)
- occur = 1;
- } else
- occur++;
- } else if ((cur->type == XML_TEXT_NODE) ||
- (cur->type == XML_CDATA_SECTION_NODE)) {
- sep = "/";
- name = "text()";
- next = cur->parent;
-
- /*
- * Thumbler index computation
- */
- tmp = cur->prev;
- while (tmp != NULL) {
- if ((cur->type == XML_TEXT_NODE) ||
- (cur->type == XML_CDATA_SECTION_NODE))
- occur++;
- tmp = tmp->prev;
- }
- if (occur == 0) {
- tmp = cur->next;
- while (tmp != NULL && occur == 0) {
- if ((cur->type == XML_TEXT_NODE) ||
- (cur->type == XML_CDATA_SECTION_NODE))
- occur++;
- tmp = tmp->next;
- }
- if (occur != 0)
- occur = 1;
- } else
- occur++;
- } else if (cur->type == XML_PI_NODE) {
- sep = "/";
- snprintf(nametemp, sizeof(nametemp) - 1,
- "processing-instruction('%s')", cur->name);
- nametemp[sizeof(nametemp) - 1] = 0;
- name = nametemp;
-
- next = cur->parent;
-
- /*
- * Thumbler index computation
- */
- tmp = cur->prev;
- while (tmp != NULL) {
- if ((tmp->type == XML_PI_NODE) &&
- (xmlStrEqual(cur->name, tmp->name)))
- occur++;
- tmp = tmp->prev;
- }
- if (occur == 0) {
- tmp = cur->next;
- while (tmp != NULL && occur == 0) {
- if ((tmp->type == XML_PI_NODE) &&
- (xmlStrEqual(cur->name, tmp->name)))
- occur++;
- tmp = tmp->next;
- }
- if (occur != 0)
- occur = 1;
- } else
- occur++;
-
- } else if (cur->type == XML_ATTRIBUTE_NODE) {
- sep = "/@";
- name = (const char *) (((xmlAttrPtr) cur)->name);
- next = ((xmlAttrPtr) cur)->parent;
- } else {
- next = cur->parent;
- }
-
- /*
- * Make sure there is enough room
- */
- if (xmlStrlen(buffer) + sizeof(nametemp) + 20 > buf_len) {
- buf_len =
- 2 * buf_len + xmlStrlen(buffer) + sizeof(nametemp) + 20;
- temp = (xmlChar *) xmlRealloc(buffer, buf_len);
- if (temp == NULL) {
- xmlFree(buf);
- xmlFree(buffer);
- return (NULL);
- }
- buffer = temp;
- temp = (xmlChar *) xmlRealloc(buf, buf_len);
- if (temp == NULL) {
- xmlFree(buf);
- xmlFree(buffer);
- return (NULL);
- }
- buf = temp;
- }
- if (occur == 0)
- snprintf((char *) buf, buf_len, "%s%s%s",
- sep, name, (char *) buffer);
- else
- snprintf((char *) buf, buf_len, "%s%s[%d]%s",
- sep, name, occur, (char *) buffer);
- snprintf((char *) buffer, buf_len, "%s", buf);
- cur = next;
- } while (cur != NULL);
- xmlFree(buf);
- return (buffer);
-}
-
-/**
- * xmlDocGetRootElement:
- * @doc: the document
- *
- * Get the root element of the document (doc->children is a list
- * containing possibly comments, PIs, etc ...).
- *
- * Returns the #xmlNodePtr for the root or NULL
- */
-xmlNodePtr
-xmlDocGetRootElement(xmlDocPtr doc) {
- xmlNodePtr ret;
-
- if (doc == NULL) return(NULL);
- ret = doc->children;
- while (ret != NULL) {
- if (ret->type == XML_ELEMENT_NODE)
- return(ret);
- ret = ret->next;
- }
- return(ret);
-}
-
-/**
- * xmlDocSetRootElement:
- * @doc: the document
- * @root: the new document root element
- *
- * Set the root element of the document (doc->children is a list
- * containing possibly comments, PIs, etc ...).
- *
- * Returns the old root element if any was found
- */
-xmlNodePtr
-xmlDocSetRootElement(xmlDocPtr doc, xmlNodePtr root) {
- xmlNodePtr old = NULL;
-
- if (doc == NULL) return(NULL);
- if (root == NULL)
- return(NULL);
- xmlUnlinkNode(root);
- root->doc = doc;
- root->parent = (xmlNodePtr) doc;
- old = doc->children;
- while (old != NULL) {
- if (old->type == XML_ELEMENT_NODE)
- break;
- old = old->next;
- }
- if (old == NULL) {
- if (doc->children == NULL) {
- doc->children = root;
- doc->last = root;
- } else {
- xmlAddSibling(doc->children, root);
- }
- } else {
- xmlReplaceNode(old, root);
- }
- return(old);
-}
-
-/**
- * xmlNodeSetLang:
- * @cur: the node being changed
- * @lang: the language description
- *
- * Set the language of a node, i.e. the values of the xml:lang
- * attribute.
- */
-void
-xmlNodeSetLang(xmlNodePtr cur, const xmlChar *lang) {
- xmlNsPtr ns;
-
- if (cur == NULL) return;
- switch(cur->type) {
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_COMMENT_NODE:
- case XML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_NOTATION_NODE:
- case XML_HTML_DOCUMENT_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_PI_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_NAMESPACE_DECL:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- return;
- case XML_ELEMENT_NODE:
- case XML_ATTRIBUTE_NODE:
- break;
- }
- ns = xmlSearchNsByHref(cur->doc, cur, XML_XML_NAMESPACE);
- if (ns == NULL)
- return;
- xmlSetNsProp(cur, ns, BAD_CAST "lang", lang);
-}
-
-/**
- * xmlNodeGetLang:
- * @cur: the node being checked
- *
- * Searches the language of a node, i.e. the values of the xml:lang
- * attribute or the one carried by the nearest ancestor.
- *
- * Returns a pointer to the lang value, or NULL if not found
- * It's up to the caller to free the memory with xmlFree().
- */
-xmlChar *
-xmlNodeGetLang(xmlNodePtr cur) {
- xmlChar *lang;
-
- while (cur != NULL) {
- lang = xmlGetNsProp(cur, BAD_CAST "lang", XML_XML_NAMESPACE);
- if (lang != NULL)
- return(lang);
- cur = cur->parent;
- }
- return(NULL);
-}
-
-
-/**
- * xmlNodeSetSpacePreserve:
- * @cur: the node being changed
- * @val: the xml:space value ("0": default, 1: "preserve")
- *
- * Set (or reset) the space preserving behaviour of a node, i.e. the
- * value of the xml:space attribute.
- */
-void
-xmlNodeSetSpacePreserve(xmlNodePtr cur, int val) {
- xmlNsPtr ns;
-
- if (cur == NULL) return;
- switch(cur->type) {
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_COMMENT_NODE:
- case XML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_NOTATION_NODE:
- case XML_HTML_DOCUMENT_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_PI_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_NAMESPACE_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- return;
- case XML_ELEMENT_NODE:
- case XML_ATTRIBUTE_NODE:
- break;
- }
- ns = xmlSearchNsByHref(cur->doc, cur, XML_XML_NAMESPACE);
- if (ns == NULL)
- return;
- switch (val) {
- case 0:
- xmlSetNsProp(cur, ns, BAD_CAST "space", BAD_CAST "default");
- break;
- case 1:
- xmlSetNsProp(cur, ns, BAD_CAST "space", BAD_CAST "preserve");
- break;
- }
-}
-
-/**
- * xmlNodeGetSpacePreserve:
- * @cur: the node being checked
- *
- * Searches the space preserving behaviour of a node, i.e. the values
- * of the xml:space attribute or the one carried by the nearest
- * ancestor.
- *
- * Returns -1 if xml:space is not inherited, 0 if "default", 1 if "preserve"
- */
-int
-xmlNodeGetSpacePreserve(xmlNodePtr cur) {
- xmlChar *space;
-
- while (cur != NULL) {
- space = xmlGetNsProp(cur, BAD_CAST "space", XML_XML_NAMESPACE);
- if (space != NULL) {
- if (xmlStrEqual(space, BAD_CAST "preserve")) {
- xmlFree(space);
- return(1);
- }
- if (xmlStrEqual(space, BAD_CAST "default")) {
- xmlFree(space);
- return(0);
- }
- xmlFree(space);
- }
- cur = cur->parent;
- }
- return(-1);
-}
-
-/**
- * xmlNodeSetName:
- * @cur: the node being changed
- * @name: the new tag name
- *
- * Set (or reset) the name of a node.
- */
-void
-xmlNodeSetName(xmlNodePtr cur, const xmlChar *name) {
- if (cur == NULL) return;
- if (name == NULL) return;
- switch(cur->type) {
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_COMMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_NOTATION_NODE:
- case XML_HTML_DOCUMENT_NODE:
- case XML_NAMESPACE_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- return;
- case XML_ELEMENT_NODE:
- case XML_ATTRIBUTE_NODE:
- case XML_PI_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_DTD_NODE:
- case XML_DOCUMENT_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- break;
- }
- if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
- cur->name = xmlStrdup(name);
-}
-
-/**
- * xmlNodeSetBase:
- * @cur: the node being changed
- * @uri: the new base URI
- *
- * Set (or reset) the base URI of a node, i.e. the value of the
- * xml:base attribute.
- */
-void
-xmlNodeSetBase(xmlNodePtr cur, xmlChar* uri) {
- xmlNsPtr ns;
-
- if (cur == NULL) return;
- switch(cur->type) {
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_COMMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_NOTATION_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_PI_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_NAMESPACE_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- return;
- case XML_ELEMENT_NODE:
- case XML_ATTRIBUTE_NODE:
- break;
- case XML_DOCUMENT_NODE:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- case XML_HTML_DOCUMENT_NODE: {
- xmlDocPtr doc = (xmlDocPtr) cur;
-
- if (doc->URL != NULL)
- xmlFree((xmlChar *) doc->URL);
- if (uri == NULL)
- doc->URL = NULL;
- else
- doc->URL = xmlStrdup(uri);
- return;
- }
- }
-
- ns = xmlSearchNsByHref(cur->doc, cur, XML_XML_NAMESPACE);
- if (ns == NULL)
- return;
- xmlSetNsProp(cur, ns, BAD_CAST "base", uri);
-}
-
-/**
- * xmlNodeGetBase:
- * @doc: the document the node pertains to
- * @cur: the node being checked
- *
- * Searches for the BASE URL. The code should work on both XML
- * and HTML document even if base mechanisms are completely different.
- * It returns the base as defined in RFC 2396 sections
- * 5.1.1. Base URI within Document Content
- * and
- * 5.1.2. Base URI from the Encapsulating Entity
- * However it does not return the document base (5.1.3), use
- * xmlDocumentGetBase() for this
- *
- * Returns a pointer to the base URL, or NULL if not found
- * It's up to the caller to free the memory with xmlFree().
- */
-xmlChar *
-xmlNodeGetBase(xmlDocPtr doc, xmlNodePtr cur) {
- xmlChar *oldbase = NULL;
- xmlChar *base, *newbase;
-
- if ((cur == NULL) && (doc == NULL))
- return(NULL);
- if (doc == NULL) doc = cur->doc;
- if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
- cur = doc->children;
- while ((cur != NULL) && (cur->name != NULL)) {
- if (cur->type != XML_ELEMENT_NODE) {
- cur = cur->next;
- continue;
- }
- if (!xmlStrcasecmp(cur->name, BAD_CAST "html")) {
- cur = cur->children;
- continue;
- }
- if (!xmlStrcasecmp(cur->name, BAD_CAST "head")) {
- cur = cur->children;
- continue;
- }
- if (!xmlStrcasecmp(cur->name, BAD_CAST "base")) {
- return(xmlGetProp(cur, BAD_CAST "href"));
- }
- cur = cur->next;
- }
- return(NULL);
- }
- while (cur != NULL) {
- if (cur->type == XML_ENTITY_DECL) {
- xmlEntityPtr ent = (xmlEntityPtr) cur;
- return(xmlStrdup(ent->URI));
- }
- if (cur->type == XML_ELEMENT_NODE) {
- base = xmlGetNsProp(cur, BAD_CAST "base", XML_XML_NAMESPACE);
- if (base != NULL) {
- if (oldbase != NULL) {
- newbase = xmlBuildURI(oldbase, base);
- if (newbase != NULL) {
- xmlFree(oldbase);
- xmlFree(base);
- oldbase = newbase;
- } else {
- xmlFree(oldbase);
- xmlFree(base);
- return(NULL);
- }
- } else {
- oldbase = base;
- }
- if ((!xmlStrncmp(oldbase, BAD_CAST "http://", 7)) ||
- (!xmlStrncmp(oldbase, BAD_CAST "ftp://", 6)) ||
- (!xmlStrncmp(oldbase, BAD_CAST "urn:", 4)))
- return(oldbase);
- }
- }
- cur = cur->parent;
- }
- if ((doc != NULL) && (doc->URL != NULL)) {
- if (oldbase == NULL)
- return(xmlStrdup(doc->URL));
- newbase = xmlBuildURI(oldbase, doc->URL);
- xmlFree(oldbase);
- return(newbase);
- }
- return(oldbase);
-}
-
-/**
- * xmlNodeGetContent:
- * @cur: the node being read
- *
- * Read the value of a node, this can be either the text carried
- * directly by this node if it's a TEXT node or the aggregate string
- * of the values carried by this node child's (TEXT and ENTITY_REF).
- * Entity references are substituted.
- * Returns a new #xmlChar * or NULL if no content is available.
- * It's up to the caller to free the memory with xmlFree().
- */
-xmlChar *
-xmlNodeGetContent(xmlNodePtr cur)
-{
- if (cur == NULL)
- return (NULL);
- switch (cur->type) {
- case XML_DOCUMENT_FRAG_NODE:
- case XML_ELEMENT_NODE:{
- xmlNodePtr tmp = cur;
- xmlBufferPtr buffer;
- xmlChar *ret;
-
- buffer = xmlBufferCreate();
- if (buffer == NULL)
- return (NULL);
- while (tmp != NULL) {
- switch (tmp->type) {
- case XML_CDATA_SECTION_NODE:
- case XML_TEXT_NODE:
- if (tmp->content != NULL)
- xmlBufferCat(buffer, tmp->content);
- break;
- case XML_ENTITY_REF_NODE:{
- /* recursive substitution of entity references */
- xmlChar *cont = xmlNodeGetContent(tmp);
-
- if (cont) {
- xmlBufferCat(buffer,
- (const xmlChar *) cont);
- xmlFree(cont);
- }
- break;
- }
- default:
- break;
- }
- /*
- * Skip to next node
- */
- if (tmp->children != NULL) {
- if (tmp->children->type != XML_ENTITY_DECL) {
- tmp = tmp->children;
- continue;
- }
- }
- if (tmp == cur)
- break;
-
- if (tmp->next != NULL) {
- tmp = tmp->next;
- continue;
- }
-
- do {
- tmp = tmp->parent;
- if (tmp == NULL)
- break;
- if (tmp == cur) {
- tmp = NULL;
- break;
- }
- if (tmp->next != NULL) {
- tmp = tmp->next;
- break;
- }
- } while (tmp != NULL);
- }
- ret = buffer->content;
- buffer->content = NULL;
- xmlBufferFree(buffer);
- return (ret);
- }
- case XML_ATTRIBUTE_NODE:{
- xmlAttrPtr attr = (xmlAttrPtr) cur;
-
- if (attr->parent != NULL)
- return (xmlNodeListGetString
- (attr->parent->doc, attr->children, 1));
- else
- return (xmlNodeListGetString(NULL, attr->children, 1));
- break;
- }
- case XML_COMMENT_NODE:
- case XML_PI_NODE:
- if (cur->content != NULL)
- return (xmlStrdup(cur->content));
- return (NULL);
- case XML_ENTITY_REF_NODE:{
- xmlEntityPtr ent;
- xmlNodePtr tmp;
- xmlBufferPtr buffer;
- xmlChar *ret;
-
- /* lookup entity declaration */
- ent = xmlGetDocEntity(cur->doc, cur->name);
- if (ent == NULL)
- return (NULL);
-
- buffer = xmlBufferCreate();
- if (buffer == NULL)
- return (NULL);
-
- /* an entity content can be any "well balanced chunk",
- * i.e. the result of the content [43] production:
- * http://www.w3.org/TR/REC-xml#NT-content
- * -> we iterate through child nodes and recursive call
- * xmlNodeGetContent() which handles all possible node types */
- tmp = ent->children;
- while (tmp) {
- xmlChar *cont = xmlNodeGetContent(tmp);
-
- if (cont) {
- xmlBufferCat(buffer, (const xmlChar *) cont);
- xmlFree(cont);
- }
- tmp = tmp->next;
- }
-
- ret = buffer->content;
- buffer->content = NULL;
- xmlBufferFree(buffer);
- return (ret);
- }
- case XML_ENTITY_NODE:
- case XML_DOCUMENT_NODE:
- case XML_HTML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_NOTATION_NODE:
- case XML_DTD_NODE:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- return (NULL);
- case XML_NAMESPACE_DECL: {
- xmlChar *tmp;
-
- tmp = xmlStrdup(((xmlNsPtr) cur)->href);
- return (tmp);
- }
- case XML_ELEMENT_DECL:
- /* TODO !!! */
- return (NULL);
- case XML_ATTRIBUTE_DECL:
- /* TODO !!! */
- return (NULL);
- case XML_ENTITY_DECL:
- /* TODO !!! */
- return (NULL);
- case XML_CDATA_SECTION_NODE:
- case XML_TEXT_NODE:
- if (cur->content != NULL)
- return (xmlStrdup(cur->content));
- return (NULL);
- }
- return (NULL);
-}
-/**
- * xmlNodeSetContent:
- * @cur: the node being modified
- * @content: the new value of the content
- *
- * Replace the content of a node.
- */
-void
-xmlNodeSetContent(xmlNodePtr cur, const xmlChar *content) {
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNodeSetContent : node == NULL\n");
-#endif
- return;
- }
- switch (cur->type) {
- case XML_DOCUMENT_FRAG_NODE:
- case XML_ELEMENT_NODE:
- case XML_ATTRIBUTE_NODE:
- if (cur->children != NULL) xmlFreeNodeList(cur->children);
- cur->children = xmlStringGetNodeList(cur->doc, content);
- UPDATE_LAST_CHILD_AND_PARENT(cur)
- break;
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- if (cur->content != NULL) {
- xmlFree(cur->content);
- }
- if (cur->children != NULL) xmlFreeNodeList(cur->children);
- cur->last = cur->children = NULL;
- if (content != NULL) {
- cur->content = xmlStrdup(content);
- } else
- cur->content = NULL;
- break;
- case XML_DOCUMENT_NODE:
- case XML_HTML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- break;
- case XML_NOTATION_NODE:
- break;
- case XML_DTD_NODE:
- break;
- case XML_NAMESPACE_DECL:
- break;
- case XML_ELEMENT_DECL:
- /* TODO !!! */
- break;
- case XML_ATTRIBUTE_DECL:
- /* TODO !!! */
- break;
- case XML_ENTITY_DECL:
- /* TODO !!! */
- break;
- }
-}
-
-/**
- * xmlNodeSetContentLen:
- * @cur: the node being modified
- * @content: the new value of the content
- * @len: the size of @content
- *
- * Replace the content of a node.
- */
-void
-xmlNodeSetContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNodeSetContentLen : node == NULL\n");
-#endif
- return;
- }
- switch (cur->type) {
- case XML_DOCUMENT_FRAG_NODE:
- case XML_ELEMENT_NODE:
- case XML_ATTRIBUTE_NODE:
- if (cur->children != NULL) xmlFreeNodeList(cur->children);
- cur->children = xmlStringLenGetNodeList(cur->doc, content, len);
- UPDATE_LAST_CHILD_AND_PARENT(cur)
- break;
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- case XML_NOTATION_NODE:
- if (cur->content != NULL) {
- xmlFree(cur->content);
- }
- if (cur->children != NULL) xmlFreeNodeList(cur->children);
- cur->children = cur->last = NULL;
- if (content != NULL) {
- cur->content = xmlStrndup(content, len);
- } else
- cur->content = NULL;
- break;
- case XML_DOCUMENT_NODE:
- case XML_DTD_NODE:
- case XML_HTML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_NAMESPACE_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- break;
- case XML_ELEMENT_DECL:
- /* TODO !!! */
- break;
- case XML_ATTRIBUTE_DECL:
- /* TODO !!! */
- break;
- case XML_ENTITY_DECL:
- /* TODO !!! */
- break;
- }
-}
-
-/**
- * xmlNodeAddContentLen:
- * @cur: the node being modified
- * @content: extra content
- * @len: the size of @content
- *
- * Append the extra substring to the node content.
- */
-void
-xmlNodeAddContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNodeAddContentLen : node == NULL\n");
-#endif
- return;
- }
- if (len <= 0) return;
- switch (cur->type) {
- case XML_DOCUMENT_FRAG_NODE:
- case XML_ELEMENT_NODE: {
- xmlNodePtr last, newNode, tmp;
-
- last = cur->last;
- newNode = xmlNewTextLen(content, len);
- if (newNode != NULL) {
- tmp = xmlAddChild(cur, newNode);
- if (tmp != newNode)
- return;
- if ((last != NULL) && (last->next == newNode)) {
- xmlTextMerge(last, newNode);
- }
- }
- break;
- }
- case XML_ATTRIBUTE_NODE:
- break;
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- case XML_NOTATION_NODE:
- if (content != NULL) {
- cur->content = xmlStrncat(cur->content, content, len);
- }
- case XML_DOCUMENT_NODE:
- case XML_DTD_NODE:
- case XML_HTML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_NAMESPACE_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- break;
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- break;
- }
-}
-
-/**
- * xmlNodeAddContent:
- * @cur: the node being modified
- * @content: extra content
- *
- * Append the extra substring to the node content.
- */
-void
-xmlNodeAddContent(xmlNodePtr cur, const xmlChar *content) {
- int len;
-
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNodeAddContent : node == NULL\n");
-#endif
- return;
- }
- if (content == NULL) return;
- len = xmlStrlen(content);
- xmlNodeAddContentLen(cur, content, len);
-}
-
-/**
- * xmlTextMerge:
- * @first: the first text node
- * @second: the second text node being merged
- *
- * Merge two text nodes into one
- * Returns the first text node augmented
- */
-xmlNodePtr
-xmlTextMerge(xmlNodePtr first, xmlNodePtr second) {
- if (first == NULL) return(second);
- if (second == NULL) return(first);
- if (first->type != XML_TEXT_NODE) return(first);
- if (second->type != XML_TEXT_NODE) return(first);
- if (second->name != first->name)
- return(first);
- xmlNodeAddContent(first, second->content);
- xmlUnlinkNode(second);
- xmlFreeNode(second);
- return(first);
-}
-
-/**
- * xmlGetNsList:
- * @doc: the document
- * @node: the current node
- *
- * Search all the namespace applying to a given element.
- * Returns an NULL terminated array of all the #xmlNsPtr found
- * that need to be freed by the caller or NULL if no
- * namespace if defined
- */
-xmlNsPtr *
-xmlGetNsList(xmlDocPtr doc ATTRIBUTE_UNUSED, xmlNodePtr node)
-{
- xmlNsPtr cur;
- xmlNsPtr *ret = NULL;
- int nbns = 0;
- int maxns = 10;
- int i;
-
- while (node != NULL) {
- if (node->type == XML_ELEMENT_NODE) {
- cur = node->nsDef;
- while (cur != NULL) {
- if (ret == NULL) {
- ret =
- (xmlNsPtr *) xmlMalloc((maxns + 1) *
- sizeof(xmlNsPtr));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlGetNsList : out of memory!\n");
- return (NULL);
- }
- ret[nbns] = NULL;
- }
- for (i = 0; i < nbns; i++) {
- if ((cur->prefix == ret[i]->prefix) ||
- (xmlStrEqual(cur->prefix, ret[i]->prefix)))
- break;
- }
- if (i >= nbns) {
- if (nbns >= maxns) {
- maxns *= 2;
- ret = (xmlNsPtr *) xmlRealloc(ret,
- (maxns +
- 1) *
- sizeof(xmlNsPtr));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlGetNsList : realloc failed!\n");
- return (NULL);
- }
- }
- ret[nbns++] = cur;
- ret[nbns] = NULL;
- }
-
- cur = cur->next;
- }
- }
- node = node->parent;
- }
- return (ret);
-}
-
-/**
- * xmlSearchNs:
- * @doc: the document
- * @node: the current node
- * @nameSpace: the namespace prefix
- *
- * Search a Ns registered under a given name space for a document.
- * recurse on the parents until it finds the defined namespace
- * or return NULL otherwise.
- * @nameSpace can be NULL, this is a search for the default namespace.
- * We don't allow to cross entities boundaries. If you don't declare
- * the namespace within those you will be in troubles !!! A warning
- * is generated to cover this case.
- *
- * Returns the namespace pointer or NULL.
- */
-xmlNsPtr
-xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace) {
- xmlNsPtr cur;
-
- if (node == NULL) return(NULL);
- if ((nameSpace != NULL) &&
- (xmlStrEqual(nameSpace, (const xmlChar *)"xml"))) {
- if ((doc == NULL) && (node->type == XML_ELEMENT_NODE)) {
- /*
- * The XML-1.0 namespace is normally held on the root
- * element. In this case exceptionally create it on the
- * node element.
- */
- cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSearchNs : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlNs));
- cur->type = XML_LOCAL_NAMESPACE;
- cur->href = xmlStrdup(XML_XML_NAMESPACE);
- cur->prefix = xmlStrdup((const xmlChar *)"xml");
- cur->next = node->nsDef;
- node->nsDef = cur;
- return(cur);
- }
- if (doc->oldNs == NULL) {
- /*
- * Allocate a new Namespace and fill the fields.
- */
- doc->oldNs = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
- if (doc->oldNs == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSearchNs : malloc failed\n");
- return(NULL);
- }
- memset(doc->oldNs, 0, sizeof(xmlNs));
- doc->oldNs->type = XML_LOCAL_NAMESPACE;
-
- doc->oldNs->href = xmlStrdup(XML_XML_NAMESPACE);
- doc->oldNs->prefix = xmlStrdup((const xmlChar *)"xml");
- }
- return(doc->oldNs);
- }
- while (node != NULL) {
- if ((node->type == XML_ENTITY_REF_NODE) ||
- (node->type == XML_ENTITY_NODE) ||
- (node->type == XML_ENTITY_DECL))
- return(NULL);
- if (node->type == XML_ELEMENT_NODE) {
- cur = node->nsDef;
- while (cur != NULL) {
- if ((cur->prefix == NULL) && (nameSpace == NULL) &&
- (cur->href != NULL))
- return(cur);
- if ((cur->prefix != NULL) && (nameSpace != NULL) &&
- (cur->href != NULL) &&
- (xmlStrEqual(cur->prefix, nameSpace)))
- return(cur);
- cur = cur->next;
- }
- }
- node = node->parent;
- }
- return(NULL);
-}
-
-/**
- * xmlSearchNsByHref:
- * @doc: the document
- * @node: the current node
- * @href: the namespace value
- *
- * Search a Ns aliasing a given URI. Recurse on the parents until it finds
- * the defined namespace or return NULL otherwise.
- * Returns the namespace pointer or NULL.
- */
-xmlNsPtr
-xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar *href) {
- xmlNsPtr cur;
- xmlNodePtr orig = node;
-
- if ((node == NULL) || (href == NULL)) return(NULL);
- if (xmlStrEqual(href, XML_XML_NAMESPACE)) {
- /*
- * Only the document can hold the XML spec namespace.
- */
- if ((doc == NULL) && (node->type == XML_ELEMENT_NODE)) {
- /*
- * The XML-1.0 namespace is normally held on the root
- * element. In this case exceptionally create it on the
- * node element.
- */
- cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSearchNs : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlNs));
- cur->type = XML_LOCAL_NAMESPACE;
- cur->href = xmlStrdup(XML_XML_NAMESPACE);
- cur->prefix = xmlStrdup((const xmlChar *)"xml");
- cur->next = node->nsDef;
- node->nsDef = cur;
- return(cur);
- }
- if (doc->oldNs == NULL) {
- /*
- * Allocate a new Namespace and fill the fields.
- */
- doc->oldNs = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
- if (doc->oldNs == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSearchNsByHref : malloc failed\n");
- return(NULL);
- }
- memset(doc->oldNs, 0, sizeof(xmlNs));
- doc->oldNs->type = XML_LOCAL_NAMESPACE;
-
- doc->oldNs->href = xmlStrdup(XML_XML_NAMESPACE);
- doc->oldNs->prefix = xmlStrdup((const xmlChar *)"xml");
- }
- return(doc->oldNs);
- }
- while (node != NULL) {
- cur = node->nsDef;
- while (cur != NULL) {
- if ((cur->href != NULL) && (href != NULL) &&
- (xmlStrEqual(cur->href, href))) {
- /*
- * Check that the prefix is not shadowed between orig and node
- */
- xmlNodePtr check = orig;
- xmlNsPtr tst;
-
- while (check != node) {
- tst = check->nsDef;
- while (tst != NULL) {
- if ((tst->prefix == NULL) && (cur->prefix == NULL))
- goto shadowed;
- if ((tst->prefix != NULL) && (cur->prefix != NULL) &&
- (xmlStrEqual(tst->prefix, cur->prefix)))
- goto shadowed;
- tst = tst->next;
- }
- check = check->parent;
- }
- return(cur);
- }
-shadowed:
- cur = cur->next;
- }
- node = node->parent;
- }
- return(NULL);
-}
-
-/**
- * xmlNewReconciliedNs:
- * @doc: the document
- * @tree: a node expected to hold the new namespace
- * @ns: the original namespace
- *
- * This function tries to locate a namespace definition in a tree
- * ancestors, or create a new namespace definition node similar to
- * @ns trying to reuse the same prefix. However if the given prefix is
- * null (default namespace) or reused within the subtree defined by
- * @tree or on one of its ancestors then a new prefix is generated.
- * Returns the (new) namespace definition or NULL in case of error
- */
-xmlNsPtr
-xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
- xmlNsPtr def;
- xmlChar prefix[50];
- int counter = 1;
-
- if (tree == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewReconciliedNs : tree == NULL\n");
-#endif
- return(NULL);
- }
- if (ns == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewReconciliedNs : ns == NULL\n");
-#endif
- return(NULL);
- }
- /*
- * Search an existing namespace definition inherited.
- */
- def = xmlSearchNsByHref(doc, tree, ns->href);
- if (def != NULL)
- return(def);
-
- /*
- * Find a close prefix which is not already in use.
- * Let's strip namespace prefixes longer than 20 chars !
- */
- if (ns->prefix == NULL)
- snprintf((char *) prefix, sizeof(prefix), "default");
- else
- snprintf((char *) prefix, sizeof(prefix), "%.20s", ns->prefix);
-
- def = xmlSearchNs(doc, tree, prefix);
- while (def != NULL) {
- if (counter > 1000) return(NULL);
- if (ns->prefix == NULL)
- snprintf((char *) prefix, sizeof(prefix), "default%d", counter++);
- else
- snprintf((char *) prefix, sizeof(prefix), "%.20s%d", ns->prefix, counter++);
- def = xmlSearchNs(doc, tree, prefix);
- }
-
- /*
- * OK, now we are ready to create a new one.
- */
- def = xmlNewNs(tree, ns->href, prefix);
- return(def);
-}
-
-/**
- * xmlReconciliateNs:
- * @doc: the document
- * @tree: a node defining the subtree to reconciliate
- *
- * This function checks that all the namespaces declared within the given
- * tree are properly declared. This is needed for example after Copy or Cut
- * and then paste operations. The subtree may still hold pointers to
- * namespace declarations outside the subtree or invalid/masked. As much
- * as possible the function try to reuse the existing namespaces found in
- * the new environment. If not possible the new namespaces are redeclared
- * on @tree at the top of the given subtree.
- * Returns the number of namespace declarations created or -1 in case of error.
- */
-int
-xmlReconciliateNs(xmlDocPtr doc, xmlNodePtr tree) {
- xmlNsPtr *oldNs = NULL;
- xmlNsPtr *newNs = NULL;
- int sizeCache = 0;
- int nbCache = 0;
-
- xmlNsPtr n;
- xmlNodePtr node = tree;
- xmlAttrPtr attr;
- int ret = 0, i;
-
- while (node != NULL) {
- /*
- * Reconciliate the node namespace
- */
- if (node->ns != NULL) {
- /*
- * initialize the cache if needed
- */
- if (sizeCache == 0) {
- sizeCache = 10;
- oldNs = (xmlNsPtr *) xmlMalloc(sizeCache *
- sizeof(xmlNsPtr));
- if (oldNs == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlReconciliateNs : memory pbm\n");
- return(-1);
- }
- newNs = (xmlNsPtr *) xmlMalloc(sizeCache *
- sizeof(xmlNsPtr));
- if (newNs == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlReconciliateNs : memory pbm\n");
- xmlFree(oldNs);
- return(-1);
- }
- }
- for (i = 0;i < nbCache;i++) {
- if (oldNs[i] == node->ns) {
- node->ns = newNs[i];
- break;
- }
- }
- if (i == nbCache) {
- /*
- * OK we need to recreate a new namespace definition
- */
- n = xmlNewReconciliedNs(doc, tree, node->ns);
- if (n != NULL) { /* :-( what if else ??? */
- /*
- * check if we need to grow the cache buffers.
- */
- if (sizeCache <= nbCache) {
- sizeCache *= 2;
- oldNs = (xmlNsPtr *) xmlRealloc(oldNs, sizeCache *
- sizeof(xmlNsPtr));
- if (oldNs == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlReconciliateNs : memory pbm\n");
- xmlFree(newNs);
- return(-1);
- }
- newNs = (xmlNsPtr *) xmlRealloc(newNs, sizeCache *
- sizeof(xmlNsPtr));
- if (newNs == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlReconciliateNs : memory pbm\n");
- xmlFree(oldNs);
- return(-1);
- }
- }
- newNs[nbCache] = n;
- oldNs[nbCache++] = node->ns;
- node->ns = n;
- }
- }
- }
- /*
- * now check for namespace hold by attributes on the node.
- */
- attr = node->properties;
- while (attr != NULL) {
- if (attr->ns != NULL) {
- /*
- * initialize the cache if needed
- */
- if (sizeCache == 0) {
- sizeCache = 10;
- oldNs = (xmlNsPtr *) xmlMalloc(sizeCache *
- sizeof(xmlNsPtr));
- if (oldNs == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlReconciliateNs : memory pbm\n");
- return(-1);
- }
- newNs = (xmlNsPtr *) xmlMalloc(sizeCache *
- sizeof(xmlNsPtr));
- if (newNs == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlReconciliateNs : memory pbm\n");
- xmlFree(oldNs);
- return(-1);
- }
- }
- for (i = 0;i < nbCache;i++) {
- if (oldNs[i] == attr->ns) {
- attr->ns = newNs[i];
- break;
- }
- }
- if (i == nbCache) {
- /*
- * OK we need to recreate a new namespace definition
- */
- n = xmlNewReconciliedNs(doc, tree, attr->ns);
- if (n != NULL) { /* :-( what if else ??? */
- /*
- * check if we need to grow the cache buffers.
- */
- if (sizeCache <= nbCache) {
- sizeCache *= 2;
- oldNs = (xmlNsPtr *) xmlRealloc(oldNs, sizeCache *
- sizeof(xmlNsPtr));
- if (oldNs == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlReconciliateNs : memory pbm\n");
- xmlFree(newNs);
- return(-1);
- }
- newNs = (xmlNsPtr *) xmlRealloc(newNs, sizeCache *
- sizeof(xmlNsPtr));
- if (newNs == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlReconciliateNs : memory pbm\n");
- xmlFree(oldNs);
- return(-1);
- }
- }
- newNs[nbCache] = n;
- oldNs[nbCache++] = attr->ns;
- attr->ns = n;
- }
- }
- }
- attr = attr->next;
- }
-
- /*
- * Browse the full subtree, deep first
- */
- if (node->children != NULL) {
- /* deep first */
- node = node->children;
- } else if ((node != tree) && (node->next != NULL)) {
- /* then siblings */
- node = node->next;
- } else if (node != tree) {
- /* go up to parents->next if needed */
- while (node != tree) {
- if (node->parent != NULL)
- node = node->parent;
- if ((node != tree) && (node->next != NULL)) {
- node = node->next;
- break;
- }
- if (node->parent == NULL) {
- node = NULL;
- break;
- }
- }
- /* exit condition */
- if (node == tree)
- node = NULL;
- } else
- break;
- }
- if (oldNs != NULL)
- xmlFree(oldNs);
- if (newNs != NULL)
- xmlFree(newNs);
- return(ret);
-}
-
-/**
- * xmlHasProp:
- * @node: the node
- * @name: the attribute name
- *
- * Search an attribute associated to a node
- * This function also looks in DTD attribute declaration for #FIXED or
- * default declaration values unless DTD use has been turned off.
- *
- * Returns the attribute or the attribute declaration or NULL if
- * neither was found.
- */
-xmlAttrPtr
-xmlHasProp(xmlNodePtr node, const xmlChar *name) {
- xmlAttrPtr prop;
- xmlDocPtr doc;
-
- if ((node == NULL) || (name == NULL)) return(NULL);
- /*
- * Check on the properties attached to the node
- */
- prop = node->properties;
- while (prop != NULL) {
- if (xmlStrEqual(prop->name, name)) {
- return(prop);
- }
- prop = prop->next;
- }
- if (!xmlCheckDTD) return(NULL);
-
- /*
- * Check if there is a default declaration in the internal
- * or external subsets
- */
- doc = node->doc;
- if (doc != NULL) {
- xmlAttributePtr attrDecl;
- if (doc->intSubset != NULL) {
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name);
- if (attrDecl != NULL)
- return((xmlAttrPtr) attrDecl);
- }
- }
- return(NULL);
-}
-
-/**
- * xmlHasNsProp:
- * @node: the node
- * @name: the attribute name
- * @nameSpace: the URI of the namespace
- *
- * Search for an attribute associated to a node
- * This attribute has to be anchored in the namespace specified.
- * This does the entity substitution.
- * This function looks in DTD attribute declaration for #FIXED or
- * default declaration values unless DTD use has been turned off.
- *
- * Returns the attribute or the attribute declaration or NULL
- * if neither was found.
- */
-xmlAttrPtr
-xmlHasNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) {
- xmlAttrPtr prop;
- xmlDocPtr doc;
-
- if (node == NULL)
- return(NULL);
-
- prop = node->properties;
- if (nameSpace == NULL)
- return(xmlHasProp(node, name));
- while (prop != NULL) {
- /*
- * One need to have
- * - same attribute names
- * - and the attribute carrying that namespace
- */
- if ((xmlStrEqual(prop->name, name)) &&
- ((prop->ns != NULL) && (xmlStrEqual(prop->ns->href, nameSpace)))) {
- return(prop);
- }
- prop = prop->next;
- }
- if (!xmlCheckDTD) return(NULL);
-
- /*
- * Check if there is a default declaration in the internal
- * or external subsets
- */
- doc = node->doc;
- if (doc != NULL) {
- if (doc->intSubset != NULL) {
- xmlAttributePtr attrDecl = NULL;
- xmlNsPtr *nsList, *cur;
- xmlChar *ename;
-
- nsList = xmlGetNsList(node->doc, node);
- if (nsList == NULL)
- return(NULL);
- if ((node->ns != NULL) && (node->ns->prefix != NULL)) {
- ename = xmlStrdup(node->ns->prefix);
- ename = xmlStrcat(ename, BAD_CAST ":");
- ename = xmlStrcat(ename, node->name);
- } else {
- ename = xmlStrdup(node->name);
- }
- if (ename == NULL) {
- xmlFree(nsList);
- return(NULL);
- }
-
- cur = nsList;
- while (*cur != NULL) {
- if (xmlStrEqual((*cur)->href, nameSpace)) {
- attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, ename,
- name, (*cur)->prefix);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, ename,
- name, (*cur)->prefix);
- }
- cur++;
- }
- xmlFree(nsList);
- xmlFree(ename);
- return((xmlAttrPtr) attrDecl);
- }
- }
- return(NULL);
-}
-
-/**
- * xmlGetProp:
- * @node: the node
- * @name: the attribute name
- *
- * Search and get the value of an attribute associated to a node
- * This does the entity substitution.
- * This function looks in DTD attribute declaration for #FIXED or
- * default declaration values unless DTD use has been turned off.
- *
- * Returns the attribute value or NULL if not found.
- * It's up to the caller to free the memory with xmlFree().
- */
-xmlChar *
-xmlGetProp(xmlNodePtr node, const xmlChar *name) {
- xmlAttrPtr prop;
- xmlDocPtr doc;
-
- if ((node == NULL) || (name == NULL)) return(NULL);
- /*
- * Check on the properties attached to the node
- */
- prop = node->properties;
- while (prop != NULL) {
- if (xmlStrEqual(prop->name, name)) {
- xmlChar *ret;
-
- ret = xmlNodeListGetString(node->doc, prop->children, 1);
- if (ret == NULL) return(xmlStrdup((xmlChar *)""));
- return(ret);
- }
- prop = prop->next;
- }
- if (!xmlCheckDTD) return(NULL);
-
- /*
- * Check if there is a default declaration in the internal
- * or external subsets
- */
- doc = node->doc;
- if (doc != NULL) {
- xmlAttributePtr attrDecl;
- if (doc->intSubset != NULL) {
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name);
- if (attrDecl != NULL)
- return(xmlStrdup(attrDecl->defaultValue));
- }
- }
- return(NULL);
-}
-
-/**
- * xmlGetNsProp:
- * @node: the node
- * @name: the attribute name
- * @nameSpace: the URI of the namespace
- *
- * Search and get the value of an attribute associated to a node
- * This attribute has to be anchored in the namespace specified.
- * This does the entity substitution.
- * This function looks in DTD attribute declaration for #FIXED or
- * default declaration values unless DTD use has been turned off.
- *
- * Returns the attribute value or NULL if not found.
- * It's up to the caller to free the memory with xmlFree().
- */
-xmlChar *
-xmlGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) {
- xmlAttrPtr prop;
- xmlDocPtr doc;
- xmlNsPtr ns;
-
- if (node == NULL)
- return(NULL);
-
- prop = node->properties;
- if (nameSpace == NULL)
- return(xmlGetProp(node, name));
- while (prop != NULL) {
- /*
- * One need to have
- * - same attribute names
- * - and the attribute carrying that namespace
- */
- if ((xmlStrEqual(prop->name, name)) &&
- ((prop->ns != NULL) &&
- (xmlStrEqual(prop->ns->href, nameSpace)))) {
- xmlChar *ret;
-
- ret = xmlNodeListGetString(node->doc, prop->children, 1);
- if (ret == NULL) return(xmlStrdup((xmlChar *)""));
- return(ret);
- }
- prop = prop->next;
- }
- if (!xmlCheckDTD) return(NULL);
-
- /*
- * Check if there is a default declaration in the internal
- * or external subsets
- */
- doc = node->doc;
- if (doc != NULL) {
- if (doc->intSubset != NULL) {
- xmlAttributePtr attrDecl;
-
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, node->name, name);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, node->name, name);
-
- if ((attrDecl != NULL) && (attrDecl->prefix != NULL)) {
- /*
- * The DTD declaration only allows a prefix search
- */
- ns = xmlSearchNs(doc, node, attrDecl->prefix);
- if ((ns != NULL) && (xmlStrEqual(ns->href, nameSpace)))
- return(xmlStrdup(attrDecl->defaultValue));
- }
- }
- }
- return(NULL);
-}
-
-/**
- * xmlSetProp:
- * @node: the node
- * @name: the attribute name
- * @value: the attribute value
- *
- * Set (or reset) an attribute carried by a node.
- * Returns the attribute pointer.
- */
-xmlAttrPtr
-xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
- xmlAttrPtr prop;
- xmlDocPtr doc;
-
- if ((node == NULL) || (name == NULL))
- return(NULL);
- doc = node->doc;
- prop = node->properties;
- while (prop != NULL) {
- if ((xmlStrEqual(prop->name, name)) &&
- (prop->ns == NULL)){
- xmlNodePtr oldprop = prop->children;
-
- prop->children = NULL;
- prop->last = NULL;
- if (value != NULL) {
- xmlChar *buffer;
- xmlNodePtr tmp;
-
- buffer = xmlEncodeEntitiesReentrant(node->doc, value);
- prop->children = xmlStringGetNodeList(node->doc, buffer);
- prop->last = NULL;
- prop->doc = doc;
- tmp = prop->children;
- while (tmp != NULL) {
- tmp->parent = (xmlNodePtr) prop;
- tmp->doc = doc;
- if (tmp->next == NULL)
- prop->last = tmp;
- tmp = tmp->next;
- }
- xmlFree(buffer);
- }
- if (oldprop != NULL)
- xmlFreeNodeList(oldprop);
- return(prop);
- }
- prop = prop->next;
- }
- prop = xmlNewProp(node, name, value);
- return(prop);
-}
-
-/**
- * xmlUnsetProp:
- * @node: the node
- * @name: the attribute name
- *
- * Remove an attribute carried by a node.
- * Returns 0 if successful, -1 if not found
- */
-int
-xmlUnsetProp(xmlNodePtr node, const xmlChar *name) {
- xmlAttrPtr prop = node->properties, prev = NULL;;
-
- if ((node == NULL) || (name == NULL))
- return(-1);
- while (prop != NULL) {
- if ((xmlStrEqual(prop->name, name)) &&
- (prop->ns == NULL)) {
- if (prev == NULL)
- node->properties = prop->next;
- else
- prev->next = prop->next;
- xmlFreeProp(prop);
- return(0);
- }
- prev = prop;
- prop = prop->next;
- }
- return(-1);
-}
-
-/**
- * xmlSetNsProp:
- * @node: the node
- * @ns: the namespace definition
- * @name: the attribute name
- * @value: the attribute value
- *
- * Set (or reset) an attribute carried by a node.
- * The ns structure must be in scope, this is not checked.
- *
- * Returns the attribute pointer.
- */
-xmlAttrPtr
-xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
- const xmlChar *value) {
- xmlAttrPtr prop;
-
- if ((node == NULL) || (name == NULL))
- return(NULL);
-
- if (ns == NULL)
- return(xmlSetProp(node, name, value));
- if (ns->href == NULL)
- return(NULL);
- prop = node->properties;
-
- while (prop != NULL) {
- /*
- * One need to have
- * - same attribute names
- * - and the attribute carrying that namespace
- */
- if ((xmlStrEqual(prop->name, name)) &&
- (prop->ns != NULL) && (xmlStrEqual(prop->ns->href, ns->href))) {
- if (prop->children != NULL)
- xmlFreeNodeList(prop->children);
- prop->children = NULL;
- prop->last = NULL;
- prop->ns = ns;
- if (value != NULL) {
- xmlChar *buffer;
- xmlNodePtr tmp;
-
- buffer = xmlEncodeEntitiesReentrant(node->doc, value);
- prop->children = xmlStringGetNodeList(node->doc, buffer);
- prop->last = NULL;
- tmp = prop->children;
- while (tmp != NULL) {
- tmp->parent = (xmlNodePtr) prop;
- if (tmp->next == NULL)
- prop->last = tmp;
- tmp = tmp->next;
- }
- xmlFree(buffer);
- }
- return(prop);
- }
- prop = prop->next;
- }
- prop = xmlNewNsProp(node, ns, name, value);
- return(prop);
-}
-
-/**
- * xmlUnsetNsProp:
- * @node: the node
- * @ns: the namespace definition
- * @name: the attribute name
- *
- * Remove an attribute carried by a node.
- * Returns 0 if successful, -1 if not found
- */
-int
-xmlUnsetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name) {
- xmlAttrPtr prop = node->properties, prev = NULL;;
-
- if ((node == NULL) || (name == NULL))
- return(-1);
- if (ns == NULL)
- return(xmlUnsetProp(node, name));
- if (ns->href == NULL)
- return(-1);
- while (prop != NULL) {
- if ((xmlStrEqual(prop->name, name)) &&
- (prop->ns != NULL) && (xmlStrEqual(prop->ns->href, ns->href))) {
- if (prev == NULL)
- node->properties = prop->next;
- else
- prev->next = prop->next;
- xmlFreeProp(prop);
- return(0);
- }
- prev = prop;
- prop = prop->next;
- }
- return(-1);
-}
-
-/**
- * xmlNodeIsText:
- * @node: the node
- *
- * Is this node a Text node ?
- * Returns 1 yes, 0 no
- */
-int
-xmlNodeIsText(xmlNodePtr node) {
- if (node == NULL) return(0);
-
- if (node->type == XML_TEXT_NODE) return(1);
- return(0);
-}
-
-/**
- * xmlIsBlankNode:
- * @node: the node
- *
- * Checks whether this node is an empty or whitespace only
- * (and possibly ignorable) text-node.
- *
- * Returns 1 yes, 0 no
- */
-int
-xmlIsBlankNode(xmlNodePtr node) {
- const xmlChar *cur;
- if (node == NULL) return(0);
-
- if ((node->type != XML_TEXT_NODE) &&
- (node->type != XML_CDATA_SECTION_NODE))
- return(0);
- if (node->content == NULL) return(1);
- cur = node->content;
- while (*cur != 0) {
- if (!IS_BLANK(*cur)) return(0);
- cur++;
- }
-
- return(1);
-}
-
-/**
- * xmlTextConcat:
- * @node: the node
- * @content: the content
- * @len: @content length
- *
- * Concat the given string at the end of the existing node content
- */
-
-void
-xmlTextConcat(xmlNodePtr node, const xmlChar *content, int len) {
- if (node == NULL) return;
-
- if ((node->type != XML_TEXT_NODE) &&
- (node->type != XML_CDATA_SECTION_NODE)) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlTextConcat: node is not text nor CDATA\n");
-#endif
- return;
- }
- node->content = xmlStrncat(node->content, content, len);
-}
-
-/************************************************************************
- * *
- * Output : to a FILE or in memory *
- * *
- ************************************************************************/
-
-/**
- * xmlBufferCreate:
- *
- * routine to create an XML buffer.
- * returns the new structure.
- */
-xmlBufferPtr
-xmlBufferCreate(void) {
- xmlBufferPtr ret;
-
- ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferCreate : out of memory!\n");
- return(NULL);
- }
- ret->use = 0;
- ret->size = xmlDefaultBufferSize;
- ret->alloc = xmlBufferAllocScheme;
- ret->content = (xmlChar *) xmlMalloc(ret->size * sizeof(xmlChar));
- if (ret->content == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferCreate : out of memory!\n");
- xmlFree(ret);
- return(NULL);
- }
- ret->content[0] = 0;
- return(ret);
-}
-
-/**
- * xmlBufferCreateSize:
- * @size: initial size of buffer
- *
- * routine to create an XML buffer.
- * returns the new structure.
- */
-xmlBufferPtr
-xmlBufferCreateSize(size_t size) {
- xmlBufferPtr ret;
-
- ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferCreate : out of memory!\n");
- return(NULL);
- }
- ret->use = 0;
- ret->alloc = xmlBufferAllocScheme;
- ret->size = (size ? size+2 : 0); /* +1 for ending null */
- if (ret->size){
- ret->content = (xmlChar *) xmlMalloc(ret->size * sizeof(xmlChar));
- if (ret->content == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferCreate : out of memory!\n");
- xmlFree(ret);
- return(NULL);
- }
- ret->content[0] = 0;
- } else
- ret->content = NULL;
- return(ret);
-}
-
-/**
- * xmlBufferSetAllocationScheme:
- * @buf: the buffer to tune
- * @scheme: allocation scheme to use
- *
- * Sets the allocation scheme for this buffer
- */
-void
-xmlBufferSetAllocationScheme(xmlBufferPtr buf,
- xmlBufferAllocationScheme scheme) {
- if (buf == NULL) {
-#ifdef DEBUG_BUFFER
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferSetAllocationScheme: buf == NULL\n");
-#endif
- return;
- }
-
- buf->alloc = scheme;
-}
-
-/**
- * xmlBufferFree:
- * @buf: the buffer to free
- *
- * Frees an XML buffer. It frees both the content and the structure which
- * encapsulate it.
- */
-void
-xmlBufferFree(xmlBufferPtr buf) {
- if (buf == NULL) {
-#ifdef DEBUG_BUFFER
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferFree: buf == NULL\n");
-#endif
- return;
- }
- if (buf->content != NULL) {
- xmlFree(buf->content);
- }
- xmlFree(buf);
-}
-
-/**
- * xmlBufferEmpty:
- * @buf: the buffer
- *
- * empty a buffer.
- */
-void
-xmlBufferEmpty(xmlBufferPtr buf) {
- if (buf->content == NULL) return;
- buf->use = 0;
- memset(buf->content, 0, buf->size);
-}
-
-/**
- * xmlBufferShrink:
- * @buf: the buffer to dump
- * @len: the number of xmlChar to remove
- *
- * Remove the beginning of an XML buffer.
- *
- * Returns the number of #xmlChar removed, or -1 in case of failure.
- */
-int
-xmlBufferShrink(xmlBufferPtr buf, unsigned int len) {
- if (len == 0) return(0);
- if (len > buf->use) return(-1);
-
- buf->use -= len;
- memmove(buf->content, &buf->content[len], buf->use * sizeof(xmlChar));
-
- buf->content[buf->use] = 0;
- return(len);
-}
-
-/**
- * xmlBufferGrow:
- * @buf: the buffer
- * @len: the minimum free size to allocate
- *
- * Grow the available space of an XML buffer.
- *
- * Returns the new available space or -1 in case of error
- */
-int
-xmlBufferGrow(xmlBufferPtr buf, unsigned int len) {
- int size;
- xmlChar *newbuf;
-
- if (len + buf->use < buf->size) return(0);
-
- size = buf->use + len + 100;
-
- newbuf = (xmlChar *) xmlRealloc(buf->content, size);
- if (newbuf == NULL) return(-1);
- buf->content = newbuf;
- buf->size = size;
- return(buf->size - buf->use);
-}
-
-/**
- * xmlBufferDump:
- * @file: the file output
- * @buf: the buffer to dump
- *
- * Dumps an XML buffer to a FILE *.
- * Returns the number of #xmlChar written
- */
-int
-xmlBufferDump(FILE *file, xmlBufferPtr buf) {
- int ret;
-
- if (buf == NULL) {
-#ifdef DEBUG_BUFFER
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferDump: buf == NULL\n");
-#endif
- return(0);
- }
- if (buf->content == NULL) {
-#ifdef DEBUG_BUFFER
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferDump: buf->content == NULL\n");
-#endif
- return(0);
- }
- if (file == NULL)
- file = stdout;
- ret = fwrite(buf->content, sizeof(xmlChar), buf->use, file);
- return(ret);
-}
-
-/**
- * xmlBufferContent:
- * @buf: the buffer
- *
- * Function to extract the content of a buffer
- *
- * Returns the internal content
- */
-
-const xmlChar *
-xmlBufferContent(const xmlBufferPtr buf)
-{
- if(!buf)
- return NULL;
-
- return buf->content;
-}
-
-/**
- * xmlBufferLength:
- * @buf: the buffer
- *
- * Function to get the length of a buffer
- *
- * Returns the length of data in the internal content
- */
-
-int
-xmlBufferLength(const xmlBufferPtr buf)
-{
- if(!buf)
- return 0;
-
- return buf->use;
-}
-
-/**
- * xmlBufferResize:
- * @buf: the buffer to resize
- * @size: the desired size
- *
- * Resize a buffer to accommodate minimum size of @size.
- *
- * Returns 0 in case of problems, 1 otherwise
- */
-int
-xmlBufferResize(xmlBufferPtr buf, unsigned int size)
-{
- unsigned int newSize;
- xmlChar* rebuf = NULL;
-
- /*take care of empty case*/
- newSize = (buf->size ? buf->size*2 : size);
-
- /* Don't resize if we don't have to */
- if (size < buf->size)
- return 1;
-
- /* figure out new size */
- switch (buf->alloc){
- case XML_BUFFER_ALLOC_DOUBLEIT:
- while (size > newSize) newSize *= 2;
- break;
- case XML_BUFFER_ALLOC_EXACT:
- newSize = size+10;
- break;
- default:
- newSize = size+10;
- break;
- }
-
- if (buf->content == NULL)
- rebuf = (xmlChar *) xmlMalloc(newSize * sizeof(xmlChar));
- else
- rebuf = (xmlChar *) xmlRealloc(buf->content,
- newSize * sizeof(xmlChar));
- if (rebuf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferResize : out of memory!\n");
- return 0;
- }
- buf->content = rebuf;
- buf->size = newSize;
-
- return 1;
-}
-
-/**
- * xmlBufferAdd:
- * @buf: the buffer to dump
- * @str: the #xmlChar string
- * @len: the number of #xmlChar to add
- *
- * Add a string range to an XML buffer. if len == -1, the length of
- * str is recomputed.
- */
-void
-xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) {
- unsigned int needSize;
-
- if (str == NULL) {
-#ifdef DEBUG_BUFFER
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferAdd: str == NULL\n");
-#endif
- return;
- }
- if (len < -1) {
-#ifdef DEBUG_BUFFER
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferAdd: len < 0\n");
-#endif
- return;
- }
- if (len == 0) return;
-
- if (len < 0)
- len = xmlStrlen(str);
-
- if (len <= 0) return;
-
- needSize = buf->use + len + 2;
- if (needSize > buf->size){
- if (!xmlBufferResize(buf, needSize)){
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferAdd : out of memory!\n");
- return;
- }
- }
-
- memmove(&buf->content[buf->use], str, len*sizeof(xmlChar));
- buf->use += len;
- buf->content[buf->use] = 0;
-}
-
-/**
- * xmlBufferAddHead:
- * @buf: the buffer
- * @str: the #xmlChar string
- * @len: the number of #xmlChar to add
- *
- * Add a string range to the beginning of an XML buffer.
- * if len == -1, the length of @str is recomputed.
- */
-void
-xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len) {
- unsigned int needSize;
-
- if (str == NULL) {
-#ifdef DEBUG_BUFFER
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferAddHead: str == NULL\n");
-#endif
- return;
- }
- if (len < -1) {
-#ifdef DEBUG_BUFFER
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferAddHead: len < 0\n");
-#endif
- return;
- }
- if (len == 0) return;
-
- if (len < 0)
- len = xmlStrlen(str);
-
- if (len <= 0) return;
-
- needSize = buf->use + len + 2;
- if (needSize > buf->size){
- if (!xmlBufferResize(buf, needSize)){
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferAddHead : out of memory!\n");
- return;
- }
- }
-
- memmove(&buf->content[len], &buf->content[0], buf->use * sizeof(xmlChar));
- memmove(&buf->content[0], str, len * sizeof(xmlChar));
- buf->use += len;
- buf->content[buf->use] = 0;
-}
-
-/**
- * xmlBufferCat:
- * @buf: the buffer to dump
- * @str: the #xmlChar string
- *
- * Append a zero terminated string to an XML buffer.
- */
-void
-xmlBufferCat(xmlBufferPtr buf, const xmlChar *str) {
- if (str != NULL)
- xmlBufferAdd(buf, str, -1);
-}
-
-/**
- * xmlBufferCCat:
- * @buf: the buffer to dump
- * @str: the C char string
- *
- * Append a zero terminated C string to an XML buffer.
- */
-void
-xmlBufferCCat(xmlBufferPtr buf, const char *str) {
- const char *cur;
-
- if (str == NULL) {
-#ifdef DEBUG_BUFFER
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferCCat: str == NULL\n");
-#endif
- return;
- }
- for (cur = str;*cur != 0;cur++) {
- if (buf->use + 10 >= buf->size) {
- if (!xmlBufferResize(buf, buf->use+10)){
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferCCat : out of memory!\n");
- return;
- }
- }
- buf->content[buf->use++] = *cur;
- }
- buf->content[buf->use] = 0;
-}
-
-/**
- * xmlBufferWriteCHAR:
- * @buf: the XML buffer
- * @string: the string to add
- *
- * routine which manages and grows an output buffer. This one adds
- * xmlChars at the end of the buffer.
- */
-void
-xmlBufferWriteCHAR
-(xmlBufferPtr buf, const xmlChar *string) {
- xmlBufferCat(buf, string);
-}
-
-/**
- * xmlBufferWriteChar:
- * @buf: the XML buffer output
- * @string: the string to add
- *
- * routine which manage and grows an output buffer. This one add
- * C chars at the end of the array.
- */
-void
-xmlBufferWriteChar(xmlBufferPtr buf, const char *string) {
- xmlBufferCCat(buf, string);
-}
-
-
-/**
- * xmlBufferWriteQuotedString:
- * @buf: the XML buffer output
- * @string: the string to add
- *
- * routine which manage and grows an output buffer. This one writes
- * a quoted or double quoted #xmlChar string, checking first if it holds
- * quote or double-quotes internally
- */
-void
-xmlBufferWriteQuotedString(xmlBufferPtr buf, const xmlChar *string) {
- if (xmlStrchr(string, '"')) {
- if (xmlStrchr(string, '\'')) {
-#ifdef DEBUG_BUFFER
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferWriteQuotedString: string contains quote and double-quotes !\n");
-#endif
- }
- xmlBufferCCat(buf, "'");
- xmlBufferCat(buf, string);
- xmlBufferCCat(buf, "'");
- } else {
- xmlBufferCCat(buf, "\"");
- xmlBufferCat(buf, string);
- xmlBufferCCat(buf, "\"");
- }
-}
-
-
-/************************************************************************
- * *
- * Dumping XML tree content to a simple buffer *
- * *
- ************************************************************************/
-
-/**
- * xmlAttrSerializeContent:
- * @buf: the XML buffer output
- * @doc: the document
- * @attr: the attribute pointer
- *
- * Serialize the attribute in the buffer
- */
-static void
-xmlAttrSerializeContent(xmlBufferPtr buf, xmlDocPtr doc, xmlAttrPtr attr)
-{
- const xmlChar *cur, *base;
- xmlNodePtr children;
-
- children = attr->children;
- while (children != NULL) {
- switch (children->type) {
- case XML_TEXT_NODE:
- base = cur = children->content;
- while (*cur != 0) {
- if (*cur == '\n') {
- if (base != cur)
- xmlBufferAdd(buf, base, cur - base);
- xmlBufferAdd(buf, BAD_CAST "&#10;", 5);
- cur++;
- base = cur;
-#if 0
- } else if (*cur == '\'') {
- if (base != cur)
- xmlBufferAdd(buf, base, cur - base);
- xmlBufferAdd(buf, BAD_CAST "&apos;", 6);
- cur++;
- base = cur;
-#endif
- } else if (*cur == '"') {
- if (base != cur)
- xmlBufferAdd(buf, base, cur - base);
- xmlBufferAdd(buf, BAD_CAST "&quot;", 6);
- cur++;
- base = cur;
- } else if (*cur == '<') {
- if (base != cur)
- xmlBufferAdd(buf, base, cur - base);
- xmlBufferAdd(buf, BAD_CAST "&lt;", 4);
- cur++;
- base = cur;
- } else if (*cur == '>') {
- if (base != cur)
- xmlBufferAdd(buf, base, cur - base);
- xmlBufferAdd(buf, BAD_CAST "&gt;", 4);
- cur++;
- base = cur;
- } else if (*cur == '&') {
- if (base != cur)
- xmlBufferAdd(buf, base, cur - base);
- xmlBufferAdd(buf, BAD_CAST "&amp;", 5);
- cur++;
- base = cur;
- } else if ((*cur >= 0x80) && ((doc == NULL) ||
- (doc->encoding ==
- NULL))) {
- /*
- * We assume we have UTF-8 content.
- */
- char tmp[10];
- int val = 0, l = 1;
-
- if (base != cur)
- xmlBufferAdd(buf, base, cur - base);
- if (*cur < 0xC0) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAttrSerializeContent : input not UTF-8\n");
- if (doc != NULL)
- doc->encoding =
- xmlStrdup(BAD_CAST "ISO-8859-1");
- snprintf(tmp, sizeof(tmp), "&#%d;", *cur);
- tmp[sizeof(tmp) - 1] = 0;
- xmlBufferAdd(buf, (xmlChar *) tmp, -1);
- cur++;
- base = cur;
- continue;
- } else if (*cur < 0xE0) {
- val = (cur[0]) & 0x1F;
- val <<= 6;
- val |= (cur[1]) & 0x3F;
- l = 2;
- } else if (*cur < 0xF0) {
- val = (cur[0]) & 0x0F;
- val <<= 6;
- val |= (cur[1]) & 0x3F;
- val <<= 6;
- val |= (cur[2]) & 0x3F;
- l = 3;
- } else if (*cur < 0xF8) {
- val = (cur[0]) & 0x07;
- val <<= 6;
- val |= (cur[1]) & 0x3F;
- val <<= 6;
- val |= (cur[2]) & 0x3F;
- val <<= 6;
- val |= (cur[3]) & 0x3F;
- l = 4;
- }
- if ((l == 1) || (!IS_CHAR(val))) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAttrSerializeContent : char out of range\n");
- if (doc != NULL)
- doc->encoding =
- xmlStrdup(BAD_CAST "ISO-8859-1");
- snprintf(tmp, sizeof(tmp), "&#%d;", *cur);
- tmp[sizeof(tmp) - 1] = 0;
- xmlBufferAdd(buf, (xmlChar *) tmp, -1);
- cur++;
- base = cur;
- continue;
- }
- /*
- * We could do multiple things here. Just save
- * as a char ref
- */
- snprintf(tmp, sizeof(tmp), "&#x%X;", val);
- tmp[sizeof(tmp) - 1] = 0;
- xmlBufferAdd(buf, (xmlChar *) tmp, -1);
- cur += l;
- base = cur;
- } else {
- cur++;
- }
- }
- if (base != cur)
- xmlBufferAdd(buf, base, cur - base);
- break;
- case XML_ENTITY_REF_NODE:
- xmlBufferAdd(buf, BAD_CAST "&", 1);
- xmlBufferAdd(buf, children->name,
- xmlStrlen(children->name));
- xmlBufferAdd(buf, BAD_CAST ";", 1);
- break;
- default:
- /* should not happen unless we have a badly built tree */
- break;
- }
- children = children->next;
- }
-}
-
-/**
- * xmlNodeDump:
- * @buf: the XML buffer output
- * @doc: the document
- * @cur: the current node
- * @level: the imbrication level for indenting
- * @format: is formatting allowed
- *
- * Dump an XML node, recursive behaviour,children are printed too.
- * Note that format = 1 provide node indenting only if xmlIndentTreeOutput = 1
- * or xmlKeepBlanksDefault(0) was called
- *
- * Returns the number of bytes written to the buffer or -1 in case of error
- */
-int
-xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
- int format)
-{
- unsigned int use;
- int ret;
- xmlOutputBufferPtr outbuf;
-
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNodeDump : node == NULL\n");
-#endif
- return (-1);
- }
- if (buf == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNodeDump : buf == NULL\n");
-#endif
- return (-1);
- }
- outbuf = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
- if (outbuf == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNodeDump: out of memory!\n");
- return (-1);
- }
- memset(outbuf, 0, (size_t) sizeof(xmlOutputBuffer));
- outbuf->buffer = buf;
- outbuf->encoder = NULL;
- outbuf->writecallback = NULL;
- outbuf->closecallback = NULL;
- outbuf->context = NULL;
- outbuf->written = 0;
-
- use = buf->use;
- xmlNodeDumpOutput(outbuf, doc, cur, level, format, NULL);
- xmlFree(outbuf);
- ret = buf->use - use;
- return (ret);
-}
-
-/**
- * xmlElemDump:
- * @f: the FILE * for the output
- * @doc: the document
- * @cur: the current node
- *
- * Dump an XML/HTML node, recursive behaviour, children are printed too.
- */
-void
-xmlElemDump(FILE * f, xmlDocPtr doc, xmlNodePtr cur)
-{
- xmlOutputBufferPtr outbuf;
-
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlElemDump : cur == NULL\n");
-#endif
- return;
- }
-#ifdef DEBUG_TREE
- if (doc == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlElemDump : doc == NULL\n");
- }
-#endif
-
- outbuf = xmlOutputBufferCreateFile(f, NULL);
- if (outbuf == NULL)
- return;
- if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
-#ifdef LIBXML_HTML_ENABLED
- htmlNodeDumpOutput(outbuf, doc, cur, NULL);
-#else
- xmlGenericError(xmlGenericErrorContext,
- "HTML support not compiled in\n");
-#endif /* LIBXML_HTML_ENABLED */
- } else
- xmlNodeDumpOutput(outbuf, doc, cur, 0, 1, NULL);
- xmlOutputBufferClose(outbuf);
-}
-
-/************************************************************************
- * *
- * Dumping XML tree content to an I/O output buffer *
- * *
- ************************************************************************/
-
-static void
-xhtmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
- int level, int format, const char *encoding);
-static void
-xmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
- int level, int format, const char *encoding);
-static void
-xmlNodeDumpOutputInternal(xmlOutputBufferPtr buf, xmlDocPtr doc,
- xmlNodePtr cur, int level, int format, const char *encoding);
-
-/**
- * xmlNsDumpOutput:
- * @buf: the XML buffer output
- * @cur: a namespace
- *
- * Dump a local Namespace definition.
- * Should be called in the context of attributes dumps.
- */
-static void
-xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNsDumpOutput : Ns == NULL\n");
-#endif
- return;
- }
- if ((cur->type == XML_LOCAL_NAMESPACE) && (cur->href != NULL)) {
- if (xmlStrEqual(cur->prefix, BAD_CAST "xml"))
- return;
-
- /* Within the context of an element attributes */
- if (cur->prefix != NULL) {
- xmlOutputBufferWriteString(buf, " xmlns:");
- xmlOutputBufferWriteString(buf, (const char *)cur->prefix);
- } else
- xmlOutputBufferWriteString(buf, " xmlns");
- xmlOutputBufferWriteString(buf, "=");
- xmlBufferWriteQuotedString(buf->buffer, cur->href);
- }
-}
-
-/**
- * xmlNsListDumpOutput:
- * @buf: the XML buffer output
- * @cur: the first namespace
- *
- * Dump a list of local Namespace definitions.
- * Should be called in the context of attributes dumps.
- */
-static void
-xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
- while (cur != NULL) {
- xmlNsDumpOutput(buf, cur);
- cur = cur->next;
- }
-}
-
-/**
- * xmlDtdDumpOutput:
- * @buf: the XML buffer output
- * @doc: the document
- * @encoding: an optional encoding string
- *
- * Dump the XML document DTD, if any.
- */
-static void
-xmlDtdDumpOutput(xmlOutputBufferPtr buf, xmlDtdPtr dtd, const char *encoding) {
- if (dtd == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlDtdDumpOutput : no internal subset\n");
-#endif
- return;
- }
- xmlOutputBufferWriteString(buf, "<!DOCTYPE ");
- xmlOutputBufferWriteString(buf, (const char *)dtd->name);
- if (dtd->ExternalID != NULL) {
- xmlOutputBufferWriteString(buf, " PUBLIC ");
- xmlBufferWriteQuotedString(buf->buffer, dtd->ExternalID);
- xmlOutputBufferWriteString(buf, " ");
- xmlBufferWriteQuotedString(buf->buffer, dtd->SystemID);
- } else if (dtd->SystemID != NULL) {
- xmlOutputBufferWriteString(buf, " SYSTEM ");
- xmlBufferWriteQuotedString(buf->buffer, dtd->SystemID);
- }
- if ((dtd->entities == NULL) && (dtd->elements == NULL) &&
- (dtd->attributes == NULL) && (dtd->notations == NULL)) {
- xmlOutputBufferWriteString(buf, ">");
- return;
- }
- xmlOutputBufferWriteString(buf, " [\n");
- xmlNodeListDumpOutput(buf, dtd->doc, dtd->children, -1, 0, encoding);
- xmlOutputBufferWriteString(buf, "]>");
-}
-
-/**
- * xmlAttrDumpOutput:
- * @buf: the XML buffer output
- * @doc: the document
- * @cur: the attribute pointer
- * @encoding: an optional encoding string
- *
- * Dump an XML attribute
- */
-static void
-xmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlAttrPtr cur,
- const char *encoding ATTRIBUTE_UNUSED) {
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlAttrDumpOutput : property == NULL\n");
-#endif
- return;
- }
- xmlOutputBufferWriteString(buf, " ");
- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
- xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
- xmlOutputBufferWriteString(buf, ":");
- }
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- xmlOutputBufferWriteString(buf, "=\"");
- xmlAttrSerializeContent(buf->buffer, doc, cur);
- xmlOutputBufferWriteString(buf, "\"");
-}
-
-/**
- * xmlAttrListDumpOutput:
- * @buf: the XML buffer output
- * @doc: the document
- * @cur: the first attribute pointer
- * @encoding: an optional encoding string
- *
- * Dump a list of XML attributes
- */
-static void
-xmlAttrListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
- xmlAttrPtr cur, const char *encoding) {
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlAttrListDumpOutput : property == NULL\n");
-#endif
- return;
- }
- while (cur != NULL) {
- xmlAttrDumpOutput(buf, doc, cur, encoding);
- cur = cur->next;
- }
-}
-
-
-
-/**
- * xmlNodeListDumpOutput:
- * @buf: the XML buffer output
- * @doc: the document
- * @cur: the first node
- * @level: the imbrication level for indenting
- * @format: is formatting allowed
- * @encoding: an optional encoding string
- *
- * Dump an XML node list, recursive behaviour, children are printed too.
- * Note that format = 1 provide node indenting only if xmlIndentTreeOutput = 1
- * or xmlKeepBlanksDefault(0) was called
- */
-static void
-xmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
- xmlNodePtr cur, int level, int format, const char *encoding) {
- int i;
-
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNodeListDumpOutput : node == NULL\n");
-#endif
- return;
- }
- while (cur != NULL) {
- if ((format) && (xmlIndentTreeOutput) &&
- (cur->type == XML_ELEMENT_NODE))
- for (i = 0;i < level;i++)
- xmlOutputBufferWriteString(buf, xmlTreeIndentString);
- xmlNodeDumpOutputInternal(buf, doc, cur, level, format, encoding);
- if (format) {
- xmlOutputBufferWriteString(buf, "\n");
- }
- cur = cur->next;
- }
-}
-
-/**
- * xmlNodeDumpOutputInternal:
- * @buf: the XML buffer output
- * @doc: the document
- * @cur: the current node
- * @level: the imbrication level for indenting
- * @format: is formatting allowed
- * @encoding: an optional encoding string
- *
- * Dump an XML node, recursive behaviour, children are printed too.
- * Note that format = 1 provide node indenting only if xmlIndentTreeOutput = 1
- * or xmlKeepBlanksDefault(0) was called
- */
-static void
-xmlNodeDumpOutputInternal(xmlOutputBufferPtr buf, xmlDocPtr doc,
- xmlNodePtr cur, int level, int format, const char *encoding) {
- int i;
- xmlNodePtr tmp;
-
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNodeDumpOutput : node == NULL\n");
-#endif
- return;
- }
- if (cur->type == XML_XINCLUDE_START)
- return;
- if (cur->type == XML_XINCLUDE_END)
- return;
- if (cur->type == XML_DTD_NODE) {
- xmlDtdDumpOutput(buf, (xmlDtdPtr) cur, encoding);
- return;
- }
- if (cur->type == XML_ELEMENT_DECL) {
- xmlDumpElementDecl(buf->buffer, (xmlElementPtr) cur);
- return;
- }
- if (cur->type == XML_ATTRIBUTE_DECL) {
- xmlDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur);
- return;
- }
- if (cur->type == XML_ENTITY_DECL) {
- xmlDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur);
- return;
- }
- if (cur->type == XML_TEXT_NODE) {
- if (cur->content != NULL) {
- if ((cur->name == xmlStringText) ||
- (cur->name != xmlStringTextNoenc)) {
- xmlChar *buffer;
-
- if (encoding == NULL)
- buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
- else
- buffer = xmlEncodeSpecialChars(doc, cur->content);
- if (buffer != NULL) {
- xmlOutputBufferWriteString(buf, (const char *)buffer);
- xmlFree(buffer);
- }
- } else {
- /*
- * Disable escaping, needed for XSLT
- */
- xmlOutputBufferWriteString(buf, (const char *) cur->content);
- }
- }
-
- return;
- }
- if (cur->type == XML_PI_NODE) {
- if (cur->content != NULL) {
- xmlOutputBufferWriteString(buf, "<?");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- if (cur->content != NULL) {
- xmlOutputBufferWriteString(buf, " ");
- xmlOutputBufferWriteString(buf, (const char *)cur->content);
- }
- xmlOutputBufferWriteString(buf, "?>");
- } else {
- xmlOutputBufferWriteString(buf, "<?");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- xmlOutputBufferWriteString(buf, "?>");
- }
- return;
- }
- if (cur->type == XML_COMMENT_NODE) {
- if (cur->content != NULL) {
- xmlOutputBufferWriteString(buf, "<!--");
- xmlOutputBufferWriteString(buf, (const char *)cur->content);
- xmlOutputBufferWriteString(buf, "-->");
- }
- return;
- }
- if (cur->type == XML_ENTITY_REF_NODE) {
- xmlOutputBufferWriteString(buf, "&");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- xmlOutputBufferWriteString(buf, ";");
- return;
- }
- if (cur->type == XML_CDATA_SECTION_NODE) {
- xmlOutputBufferWriteString(buf, "<![CDATA[");
- if (cur->content != NULL)
- xmlOutputBufferWriteString(buf, (const char *)cur->content);
- xmlOutputBufferWriteString(buf, "]]>");
- return;
- }
-
- if (format == 1) {
- tmp = cur->children;
- while (tmp != NULL) {
- if ((tmp->type == XML_TEXT_NODE) ||
- (tmp->type == XML_ENTITY_REF_NODE)) {
- format = 0;
- break;
- }
- tmp = tmp->next;
- }
- }
- xmlOutputBufferWriteString(buf, "<");
- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
- xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
- xmlOutputBufferWriteString(buf, ":");
- }
-
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- if (cur->nsDef)
- xmlNsListDumpOutput(buf, cur->nsDef);
- if (cur->properties != NULL)
- xmlAttrListDumpOutput(buf, doc, cur->properties, encoding);
-
- if (((cur->type == XML_ELEMENT_NODE) || (cur->content == NULL)) &&
- (cur->children == NULL) && (!xmlSaveNoEmptyTags)) {
- xmlOutputBufferWriteString(buf, "/>");
- return;
- }
- xmlOutputBufferWriteString(buf, ">");
- if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) {
- xmlChar *buffer;
-
- if (encoding == NULL)
- buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
- else
- buffer = xmlEncodeSpecialChars(doc, cur->content);
- if (buffer != NULL) {
- xmlOutputBufferWriteString(buf, (const char *)buffer);
- xmlFree(buffer);
- }
- }
- if (cur->children != NULL) {
- if (format) xmlOutputBufferWriteString(buf, "\n");
- xmlNodeListDumpOutput(buf, doc, cur->children,
- (level >= 0?level+1:-1), format, encoding);
- if ((xmlIndentTreeOutput) && (format))
- for (i = 0;i < level;i++)
- xmlOutputBufferWriteString(buf, xmlTreeIndentString);
- }
- xmlOutputBufferWriteString(buf, "</");
- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
- xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
- xmlOutputBufferWriteString(buf, ":");
- }
-
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- xmlOutputBufferWriteString(buf, ">");
-}
-
-/**
- * xmlNodeDumpOutput:
- * @buf: the XML buffer output
- * @doc: the document
- * @cur: the current node
- * @level: the imbrication level for indenting
- * @format: is formatting allowed
- * @encoding: an optional encoding string
- *
- * Dump an XML node, recursive behaviour, children are printed too.
- * Note that format = 1 provide node indenting only if xmlIndentTreeOutput = 1
- * or xmlKeepBlanksDefault(0) was called
- */
-void
-xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
- int level, int format, const char *encoding)
-{
-#ifdef LIBXML_HTML_ENABLED
- xmlDtdPtr dtd;
- int is_xhtml = 0;
-
- dtd = xmlGetIntSubset(doc);
- if (dtd != NULL) {
- is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID);
- if (is_xhtml < 0)
- is_xhtml = 0;
- if ((is_xhtml) && (cur->parent == (xmlNodePtr) doc) &&
- (cur->type == XML_ELEMENT_NODE) &&
- (xmlStrEqual(cur->name, BAD_CAST "html"))) {
- if (encoding != NULL)
- htmlSetMetaEncoding((htmlDocPtr) cur,
- (const xmlChar *) encoding);
- else
- htmlSetMetaEncoding((htmlDocPtr) cur, BAD_CAST "UTF-8");
- }
- }
-
- if (is_xhtml)
- xhtmlNodeDumpOutput(buf, doc, cur, level, format, encoding);
- else
-#endif
- xmlNodeDumpOutputInternal(buf, doc, cur, level, format, encoding);
-}
-
-/**
- * xmlDocContentDumpOutput:
- * @buf: the XML buffer output
- * @cur: the document
- * @encoding: an optional encoding string
- * @format: should formatting spaces been added
- *
- * Dump an XML document.
- * Note that format = 1 provide node indenting only if xmlIndentTreeOutput = 1
- * or xmlKeepBlanksDefault(0) was called
- */
-static void
-xmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
- const char *encoding, int format) {
-#ifdef LIBXML_HTML_ENABLED
- xmlDtdPtr dtd;
- int is_xhtml = 0;
-#endif
-
- xmlOutputBufferWriteString(buf, "<?xml version=");
- if (cur->version != NULL)
- xmlBufferWriteQuotedString(buf->buffer, cur->version);
- else
- xmlOutputBufferWriteString(buf, "\"1.0\"");
- if (encoding == NULL) {
- if (cur->encoding != NULL)
- encoding = (const char *) cur->encoding;
- else if (cur->charset != XML_CHAR_ENCODING_UTF8)
- encoding = xmlGetCharEncodingName((xmlCharEncoding) cur->charset);
- }
- if (encoding != NULL) {
- xmlOutputBufferWriteString(buf, " encoding=");
- xmlBufferWriteQuotedString(buf->buffer, (xmlChar *) encoding);
- }
- switch (cur->standalone) {
- case 0:
- xmlOutputBufferWriteString(buf, " standalone=\"no\"");
- break;
- case 1:
- xmlOutputBufferWriteString(buf, " standalone=\"yes\"");
- break;
- }
- xmlOutputBufferWriteString(buf, "?>\n");
-
-#ifdef LIBXML_HTML_ENABLED
- dtd = xmlGetIntSubset(cur);
- if (dtd != NULL) {
- is_xhtml = xmlIsXHTML(dtd->SystemID, dtd->ExternalID);
- if (is_xhtml < 0) is_xhtml = 0;
- }
- if (is_xhtml) {
- if (encoding != NULL)
- htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
- else
- htmlSetMetaEncoding(cur, BAD_CAST "UTF-8");
- }
-#endif
- if (cur->children != NULL) {
- xmlNodePtr child = cur->children;
-
- while (child != NULL) {
-#ifdef LIBXML_HTML_ENABLED
- if (is_xhtml)
- xhtmlNodeDumpOutput(buf, cur, child, 0, format, encoding);
- else
-#endif
- xmlNodeDumpOutputInternal(buf, cur, child, 0, format, encoding);
- xmlOutputBufferWriteString(buf, "\n");
- child = child->next;
- }
- }
-}
-
-#ifdef LIBXML_HTML_ENABLED
-/************************************************************************
- * *
- * Functions specific to XHTML serialization *
- * *
- ************************************************************************/
-
-#define XHTML_STRICT_PUBLIC_ID BAD_CAST \
- "-//W3C//DTD XHTML 1.0 Strict//EN"
-#define XHTML_STRICT_SYSTEM_ID BAD_CAST \
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
-#define XHTML_FRAME_PUBLIC_ID BAD_CAST \
- "-//W3C//DTD XHTML 1.0 Frameset//EN"
-#define XHTML_FRAME_SYSTEM_ID BAD_CAST \
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"
-#define XHTML_TRANS_PUBLIC_ID BAD_CAST \
- "-//W3C//DTD XHTML 1.0 Transitional//EN"
-#define XHTML_TRANS_SYSTEM_ID BAD_CAST \
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
-
-#define XHTML_NS_NAME BAD_CAST "http://www.w3.org/1999/xhtml"
-/**
- * xmlIsXHTML:
- * @systemID: the system identifier
- * @publicID: the public identifier
- *
- * Try to find if the document correspond to an XHTML DTD
- *
- * Returns 1 if true, 0 if not and -1 in case of error
- */
-int
-xmlIsXHTML(const xmlChar *systemID, const xmlChar *publicID) {
- if ((systemID == NULL) && (publicID == NULL))
- return(-1);
- if (publicID != NULL) {
- if (xmlStrEqual(publicID, XHTML_STRICT_PUBLIC_ID)) return(1);
- if (xmlStrEqual(publicID, XHTML_FRAME_PUBLIC_ID)) return(1);
- if (xmlStrEqual(publicID, XHTML_TRANS_PUBLIC_ID)) return(1);
- }
- if (systemID != NULL) {
- if (xmlStrEqual(systemID, XHTML_STRICT_SYSTEM_ID)) return(1);
- if (xmlStrEqual(systemID, XHTML_FRAME_SYSTEM_ID)) return(1);
- if (xmlStrEqual(systemID, XHTML_TRANS_SYSTEM_ID)) return(1);
- }
- return(0);
-}
-
-/**
- * xhtmlIsEmpty:
- * @node: the node
- *
- * Check if a node is an empty xhtml node
- *
- * Returns 1 if the node is an empty node, 0 if not and -1 in case of error
- */
-static int
-xhtmlIsEmpty(xmlNodePtr node) {
- if (node == NULL)
- return(-1);
- if (node->type != XML_ELEMENT_NODE)
- return(0);
- if ((node->ns != NULL) && (!xmlStrEqual(node->ns->href, XHTML_NS_NAME)))
- return(0);
- if (node->children != NULL)
- return(0);
- switch (node->name[0]) {
- case 'a':
- if (xmlStrEqual(node->name, BAD_CAST "area"))
- return(1);
- return(0);
- case 'b':
- if (xmlStrEqual(node->name, BAD_CAST "br"))
- return(1);
- if (xmlStrEqual(node->name, BAD_CAST "base"))
- return(1);
- if (xmlStrEqual(node->name, BAD_CAST "basefont"))
- return(1);
- return(0);
- case 'c':
- if (xmlStrEqual(node->name, BAD_CAST "col"))
- return(1);
- return(0);
- case 'f':
- if (xmlStrEqual(node->name, BAD_CAST "frame"))
- return(1);
- return(0);
- case 'h':
- if (xmlStrEqual(node->name, BAD_CAST "hr"))
- return(1);
- return(0);
- case 'i':
- if (xmlStrEqual(node->name, BAD_CAST "img"))
- return(1);
- if (xmlStrEqual(node->name, BAD_CAST "input"))
- return(1);
- if (xmlStrEqual(node->name, BAD_CAST "isindex"))
- return(1);
- return(0);
- case 'l':
- if (xmlStrEqual(node->name, BAD_CAST "link"))
- return(1);
- return(0);
- case 'm':
- if (xmlStrEqual(node->name, BAD_CAST "meta"))
- return(1);
- return(0);
- case 'p':
- if (xmlStrEqual(node->name, BAD_CAST "param"))
- return(1);
- return(0);
- }
- return(0);
-}
-
-/**
- * xhtmlAttrListDumpOutput:
- * @buf: the XML buffer output
- * @doc: the document
- * @cur: the first attribute pointer
- * @encoding: an optional encoding string
- *
- * Dump a list of XML attributes
- */
-static void
-xhtmlAttrListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
- xmlAttrPtr cur, const char *encoding) {
- xmlAttrPtr xml_lang = NULL;
- xmlAttrPtr lang = NULL;
- xmlAttrPtr name = NULL;
- xmlAttrPtr id = NULL;
-
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlAttrListDumpOutput : property == NULL\n");
-#endif
- return;
- }
- while (cur != NULL) {
- if ((cur->ns == NULL) && (xmlStrEqual(cur->name, BAD_CAST "id")))
- id = cur;
- else
- if ((cur->ns == NULL) && (xmlStrEqual(cur->name, BAD_CAST "name")))
- name = cur;
- else
- if ((cur->ns == NULL) && (xmlStrEqual(cur->name, BAD_CAST "lang")))
- lang = cur;
- else
- if ((cur->ns != NULL) && (xmlStrEqual(cur->name, BAD_CAST "lang")) &&
- (xmlStrEqual(cur->ns->prefix, BAD_CAST "xml")))
- xml_lang = cur;
- else if ((cur->ns == NULL) &&
- ((cur->children == NULL) ||
- (cur->children->content == NULL) ||
- (cur->children->content[0] == 0)) &&
- (htmlIsBooleanAttr(cur->name))) {
- if (cur->children != NULL)
- xmlFreeNode(cur->children);
- cur->children = xmlNewText(cur->name);
- if (cur->children != NULL)
- cur->children->parent = (xmlNodePtr) cur;
- }
- xmlAttrDumpOutput(buf, doc, cur, encoding);
- cur = cur->next;
- }
- /*
- * C.8
- */
- if ((name != NULL) && (id == NULL)) {
- xmlOutputBufferWriteString(buf, " id=\"");
- xmlAttrSerializeContent(buf->buffer, doc, name);
- xmlOutputBufferWriteString(buf, "\"");
- }
- /*
- * C.7.
- */
- if ((lang != NULL) && (xml_lang == NULL)) {
- xmlOutputBufferWriteString(buf, " xml:lang=\"");
- xmlAttrSerializeContent(buf->buffer, doc, lang);
- xmlOutputBufferWriteString(buf, "\"");
- } else
- if ((xml_lang != NULL) && (lang == NULL)) {
- xmlOutputBufferWriteString(buf, " lang=\"");
- xmlAttrSerializeContent(buf->buffer, doc, xml_lang);
- xmlOutputBufferWriteString(buf, "\"");
- }
-}
-
-/**
- * xhtmlNodeListDumpOutput:
- * @buf: the XML buffer output
- * @doc: the XHTML document
- * @cur: the first node
- * @level: the imbrication level for indenting
- * @format: is formatting allowed
- * @encoding: an optional encoding string
- *
- * Dump an XML node list, recursive behaviour, children are printed too.
- * Note that format = 1 provide node indenting only if xmlIndentTreeOutput = 1
- * or xmlKeepBlanksDefault(0) was called
- */
-static void
-xhtmlNodeListDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
- xmlNodePtr cur, int level, int format, const char *encoding) {
- int i;
-
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xhtmlNodeListDumpOutput : node == NULL\n");
-#endif
- return;
- }
- while (cur != NULL) {
- if ((format) && (xmlIndentTreeOutput) &&
- (cur->type == XML_ELEMENT_NODE))
- for (i = 0;i < level;i++)
- xmlOutputBufferWriteString(buf, xmlTreeIndentString);
- xhtmlNodeDumpOutput(buf, doc, cur, level, format, encoding);
- if (format) {
- xmlOutputBufferWriteString(buf, "\n");
- }
- cur = cur->next;
- }
-}
-
-/**
- * xhtmlNodeDumpOutput:
- * @buf: the XML buffer output
- * @doc: the XHTML document
- * @cur: the current node
- * @level: the imbrication level for indenting
- * @format: is formatting allowed
- * @encoding: an optional encoding string
- *
- * Dump an XHTML node, recursive behaviour, children are printed too.
- * Note that format = 1 provide node indenting only if xmlIndentTreeOutput = 1
- * or xmlKeepBlanksDefault(0) was called
- */
-static void
-xhtmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
- int level, int format, const char *encoding) {
- int i;
- xmlNodePtr tmp;
-
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlNodeDumpOutput : node == NULL\n");
-#endif
- return;
- }
- if (cur->type == XML_XINCLUDE_START)
- return;
- if (cur->type == XML_XINCLUDE_END)
- return;
- if (cur->type == XML_DTD_NODE) {
- xmlDtdDumpOutput(buf, (xmlDtdPtr) cur, encoding);
- return;
- }
- if (cur->type == XML_ELEMENT_DECL) {
- xmlDumpElementDecl(buf->buffer, (xmlElementPtr) cur);
- return;
- }
- if (cur->type == XML_ATTRIBUTE_DECL) {
- xmlDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur);
- return;
- }
- if (cur->type == XML_ENTITY_DECL) {
- xmlDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur);
- return;
- }
- if (cur->type == XML_TEXT_NODE) {
- if (cur->content != NULL) {
- if ((cur->name == xmlStringText) ||
- (cur->name != xmlStringTextNoenc)) {
- xmlChar *buffer;
-
- if (encoding == NULL)
- buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
- else
- buffer = xmlEncodeSpecialChars(doc, cur->content);
- if (buffer != NULL) {
- xmlOutputBufferWriteString(buf, (const char *)buffer);
- xmlFree(buffer);
- }
- } else {
- /*
- * Disable escaping, needed for XSLT
- */
- xmlOutputBufferWriteString(buf, (const char *) cur->content);
- }
- }
-
- return;
- }
- if (cur->type == XML_PI_NODE) {
- if (cur->content != NULL) {
- xmlOutputBufferWriteString(buf, "<?");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- if (cur->content != NULL) {
- xmlOutputBufferWriteString(buf, " ");
- xmlOutputBufferWriteString(buf, (const char *)cur->content);
- }
- xmlOutputBufferWriteString(buf, "?>");
- } else {
- xmlOutputBufferWriteString(buf, "<?");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- xmlOutputBufferWriteString(buf, "?>");
- }
- return;
- }
- if (cur->type == XML_COMMENT_NODE) {
- if (cur->content != NULL) {
- xmlOutputBufferWriteString(buf, "<!--");
- xmlOutputBufferWriteString(buf, (const char *)cur->content);
- xmlOutputBufferWriteString(buf, "-->");
- }
- return;
- }
- if (cur->type == XML_ENTITY_REF_NODE) {
- xmlOutputBufferWriteString(buf, "&");
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- xmlOutputBufferWriteString(buf, ";");
- return;
- }
- if (cur->type == XML_CDATA_SECTION_NODE) {
- xmlOutputBufferWriteString(buf, "<![CDATA[");
- if (cur->content != NULL)
- xmlOutputBufferWriteString(buf, (const char *)cur->content);
- xmlOutputBufferWriteString(buf, "]]>");
- return;
- }
-
- if (format == 1) {
- tmp = cur->children;
- while (tmp != NULL) {
- if ((tmp->type == XML_TEXT_NODE) ||
- (tmp->type == XML_ENTITY_REF_NODE)) {
- format = 0;
- break;
- }
- tmp = tmp->next;
- }
- }
- xmlOutputBufferWriteString(buf, "<");
- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
- xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
- xmlOutputBufferWriteString(buf, ":");
- }
-
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- if (cur->nsDef)
- xmlNsListDumpOutput(buf, cur->nsDef);
- if ((xmlStrEqual(cur->name, BAD_CAST "html") &&
- (cur->ns == NULL) && (cur->nsDef == NULL))) {
- /*
- * 3.1.1. Strictly Conforming Documents A.3.1.1 3/
- */
- xmlOutputBufferWriteString(buf,
- " xmlns=\"http://www.w3.org/1999/xhtml\"");
- }
- if (cur->properties != NULL)
- xhtmlAttrListDumpOutput(buf, doc, cur->properties, encoding);
-
- if ((cur->type == XML_ELEMENT_NODE) && (cur->children == NULL)) {
- if (((cur->ns == NULL) || (cur->ns->prefix == NULL)) &&
- (xhtmlIsEmpty(cur) == 1)) {
- /*
- * C.2. Empty Elements
- */
- xmlOutputBufferWriteString(buf, " />");
- } else {
- /*
- * C.3. Element Minimization and Empty Element Content
- */
- xmlOutputBufferWriteString(buf, "></");
- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
- xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
- xmlOutputBufferWriteString(buf, ":");
- }
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- xmlOutputBufferWriteString(buf, ">");
- }
- return;
- }
- xmlOutputBufferWriteString(buf, ">");
- if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) {
- xmlChar *buffer;
-
- if (encoding == NULL)
- buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
- else
- buffer = xmlEncodeSpecialChars(doc, cur->content);
- if (buffer != NULL) {
- xmlOutputBufferWriteString(buf, (const char *)buffer);
- xmlFree(buffer);
- }
- }
-
- /*
- * 4.8. Script and Style elements
- */
- if ((cur->type == XML_ELEMENT_NODE) &&
- ((xmlStrEqual(cur->name, BAD_CAST "script")) ||
- (xmlStrEqual(cur->name, BAD_CAST "style"))) &&
- ((cur->ns == NULL) ||
- (xmlStrEqual(cur->ns->href, XHTML_NS_NAME)))) {
- xmlNodePtr child = cur->children;
-
- while (child != NULL) {
- if ((child->type == XML_TEXT_NODE) ||
- (child->type == XML_CDATA_SECTION_NODE)) {
- /*
- * Apparently CDATA escaping for style just break on IE,
- * mozilla and galeon, so ...
- */
- if (xmlStrEqual(cur->name, BAD_CAST "style") &&
- (xmlStrchr(child->content, '<') == NULL) &&
- (xmlStrchr(child->content, '>') == NULL) &&
- (xmlStrchr(child->content, '&') == NULL)) {
- xhtmlNodeDumpOutput(buf, doc, child, 0, 0, encoding);
- } else {
- xmlOutputBufferWriteString(buf, "<![CDATA[");
- if (child->content != NULL)
- xmlOutputBufferWriteString(buf,
- (const char *)child->content);
- xmlOutputBufferWriteString(buf, "]]>");
- }
- } else {
- xhtmlNodeDumpOutput(buf, doc, child, 0, 0, encoding);
- }
- child = child->next;
- }
- } else if (cur->children != NULL) {
- if (format) xmlOutputBufferWriteString(buf, "\n");
- xhtmlNodeListDumpOutput(buf, doc, cur->children,
- (level >= 0?level+1:-1), format, encoding);
- if ((xmlIndentTreeOutput) && (format))
- for (i = 0;i < level;i++)
- xmlOutputBufferWriteString(buf, xmlTreeIndentString);
- }
- xmlOutputBufferWriteString(buf, "</");
- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
- xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
- xmlOutputBufferWriteString(buf, ":");
- }
-
- xmlOutputBufferWriteString(buf, (const char *)cur->name);
- xmlOutputBufferWriteString(buf, ">");
-}
-#endif
-
-/************************************************************************
- * *
- * Saving functions front-ends *
- * *
- ************************************************************************/
-
-/**
- * xmlDocDumpFormatMemoryEnc:
- * @out_doc: Document to generate XML text from
- * @doc_txt_ptr: Memory pointer for allocated XML text
- * @doc_txt_len: Length of the generated XML text
- * @txt_encoding: Character encoding to use when generating XML text
- * @format: should formatting spaces been added
- *
- * Dump the current DOM tree into memory using the character encoding specified
- * by the caller. Note it is up to the caller of this function to free the
- * allocated memory with xmlFree().
- * Note that format = 1 provide node indenting only if xmlIndentTreeOutput = 1
- * or xmlKeepBlanksDefault(0) was called
- */
-
-void
-xmlDocDumpFormatMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
- int * doc_txt_len, const char * txt_encoding,
- int format) {
- int dummy = 0;
-
- xmlCharEncoding doc_charset;
- xmlOutputBufferPtr out_buff = NULL;
- xmlCharEncodingHandlerPtr conv_hdlr = NULL;
-
- if (doc_txt_len == NULL) {
- doc_txt_len = &dummy; /* Continue, caller just won't get length */
- }
-
- if (doc_txt_ptr == NULL) {
- *doc_txt_len = 0;
- xmlGenericError(xmlGenericErrorContext,
- "xmlDocDumpFormatMemoryEnc: Null return buffer pointer.");
- return;
- }
-
- *doc_txt_ptr = NULL;
- *doc_txt_len = 0;
-
- if (out_doc == NULL) {
- /* No document, no output */
- xmlGenericError(xmlGenericErrorContext,
- "xmlDocDumpFormatMemoryEnc: Null DOM tree document pointer.\n");
- return;
- }
-
- /*
- * Validate the encoding value, if provided.
- * This logic is copied from xmlSaveFileEnc.
- */
-
- if (txt_encoding == NULL)
- txt_encoding = (const char *) out_doc->encoding;
- if (txt_encoding != NULL) {
- doc_charset = xmlParseCharEncoding(txt_encoding);
-
- if (out_doc->charset != XML_CHAR_ENCODING_UTF8) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlDocDumpFormatMemoryEnc: Source document not in UTF8\n");
- return;
-
- } else if (doc_charset != XML_CHAR_ENCODING_UTF8) {
- conv_hdlr = xmlFindCharEncodingHandler(txt_encoding);
- if ( conv_hdlr == NULL ) {
- xmlGenericError(xmlGenericErrorContext,
- "%s: %s %s '%s'\n",
- "xmlDocDumpFormatMemoryEnc",
- "Failed to identify encoding handler for",
- "character set",
- txt_encoding);
- return;
- }
- }
- }
-
- if ((out_buff = xmlAllocOutputBuffer(conv_hdlr)) == NULL ) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlDocDumpFormatMemoryEnc: Failed to allocate output buffer.\n");
- return;
- }
-
- xmlDocContentDumpOutput(out_buff, out_doc, txt_encoding, format);
- xmlOutputBufferFlush(out_buff);
- if (out_buff->conv != NULL) {
- *doc_txt_len = out_buff->conv->use;
- *doc_txt_ptr = xmlStrndup(out_buff->conv->content, *doc_txt_len);
- } else {
- *doc_txt_len = out_buff->buffer->use;
- *doc_txt_ptr = xmlStrndup(out_buff->buffer->content, *doc_txt_len);
- }
- (void)xmlOutputBufferClose(out_buff);
-
- if ((*doc_txt_ptr == NULL) && (*doc_txt_len > 0)) {
- *doc_txt_len = 0;
- xmlGenericError(xmlGenericErrorContext,
- "xmlDocDumpFormatMemoryEnc: %s\n",
- "Failed to allocate memory for document text representation.");
- }
-
- return;
-}
-
-/**
- * xmlDocDumpMemory:
- * @cur: the document
- * @mem: OUT: the memory pointer
- * @size: OUT: the memory length
- *
- * Dump an XML document in memory and return the #xmlChar * and it's size.
- * It's up to the caller to free the memory with xmlFree().
- */
-void
-xmlDocDumpMemory(xmlDocPtr cur, xmlChar**mem, int *size) {
- xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL, 0);
-}
-
-/**
- * xmlDocDumpFormatMemory:
- * @cur: the document
- * @mem: OUT: the memory pointer
- * @size: OUT: the memory length
- * @format: should formatting spaces been added
- *
- *
- * Dump an XML document in memory and return the #xmlChar * and it's size.
- * It's up to the caller to free the memory with xmlFree().
- * Note that format = 1 provide node indenting only if xmlIndentTreeOutput = 1
- * or xmlKeepBlanksDefault(0) was called
- */
-void
-xmlDocDumpFormatMemory(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
- xmlDocDumpFormatMemoryEnc(cur, mem, size, NULL, format);
-}
-
-/**
- * xmlDocDumpMemoryEnc:
- * @out_doc: Document to generate XML text from
- * @doc_txt_ptr: Memory pointer for allocated XML text
- * @doc_txt_len: Length of the generated XML text
- * @txt_encoding: Character encoding to use when generating XML text
- *
- * Dump the current DOM tree into memory using the character encoding specified
- * by the caller. Note it is up to the caller of this function to free the
- * allocated memory with xmlFree().
- */
-
-void
-xmlDocDumpMemoryEnc(xmlDocPtr out_doc, xmlChar **doc_txt_ptr,
- int * doc_txt_len, const char * txt_encoding) {
- xmlDocDumpFormatMemoryEnc(out_doc, doc_txt_ptr, doc_txt_len,
- txt_encoding, 0);
-}
-
-/**
- * xmlGetDocCompressMode:
- * @doc: the document
- *
- * get the compression ratio for a document, ZLIB based
- * Returns 0 (uncompressed) to 9 (max compression)
- */
-int
-xmlGetDocCompressMode (xmlDocPtr doc) {
- if (doc == NULL) return(-1);
- return(doc->compression);
-}
-
-/**
- * xmlSetDocCompressMode:
- * @doc: the document
- * @mode: the compression ratio
- *
- * set the compression ratio for a document, ZLIB based
- * Correct values: 0 (uncompressed) to 9 (max compression)
- */
-void
-xmlSetDocCompressMode (xmlDocPtr doc, int mode) {
- if (doc == NULL) return;
- if (mode < 0) doc->compression = 0;
- else if (mode > 9) doc->compression = 9;
- else doc->compression = mode;
-}
-
-/**
- * xmlGetCompressMode:
- *
- * get the default compression mode used, ZLIB based.
- * Returns 0 (uncompressed) to 9 (max compression)
- */
-int
-xmlGetCompressMode(void)
-{
- return (xmlCompressMode);
-}
-
-/**
- * xmlSetCompressMode:
- * @mode: the compression ratio
- *
- * set the default compression mode used, ZLIB based
- * Correct values: 0 (uncompressed) to 9 (max compression)
- */
-void
-xmlSetCompressMode(int mode) {
- if (mode < 0) xmlCompressMode = 0;
- else if (mode > 9) xmlCompressMode = 9;
- else xmlCompressMode = mode;
-}
-
-/**
- * xmlDocFormatDump:
- * @f: the FILE*
- * @cur: the document
- * @format: should formatting spaces been added
- *
- * Dump an XML document to an open FILE.
- *
- * returns: the number of bytes written or -1 in case of failure.
- */
-int
-xmlDocFormatDump(FILE *f, xmlDocPtr cur, int format) {
- xmlOutputBufferPtr buf;
- const char * encoding;
- xmlCharEncodingHandlerPtr handler = NULL;
- int ret;
-
- if (cur == NULL) {
-#ifdef DEBUG_TREE
- xmlGenericError(xmlGenericErrorContext,
- "xmlDocDump : document == NULL\n");
-#endif
- return(-1);
- }
- encoding = (const char *) cur->encoding;
-
- if (encoding != NULL) {
- xmlCharEncoding enc;
-
- enc = xmlParseCharEncoding(encoding);
-
- if (cur->charset != XML_CHAR_ENCODING_UTF8) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlDocDump: document not in UTF8\n");
- return(-1);
- }
- if (enc != XML_CHAR_ENCODING_UTF8) {
- handler = xmlFindCharEncodingHandler(encoding);
- if (handler == NULL) {
- xmlFree((char *) cur->encoding);
- cur->encoding = NULL;
- }
- }
- }
- buf = xmlOutputBufferCreateFile(f, handler);
- if (buf == NULL) return(-1);
- xmlDocContentDumpOutput(buf, cur, NULL, format);
-
- ret = xmlOutputBufferClose(buf);
- return(ret);
-}
-
-/**
- * xmlDocDump:
- * @f: the FILE*
- * @cur: the document
- *
- * Dump an XML document to an open FILE.
- *
- * returns: the number of bytes written or -1 in case of failure.
- */
-int
-xmlDocDump(FILE *f, xmlDocPtr cur) {
- return(xmlDocFormatDump (f, cur, 0));
-}
-
-/**
- * xmlSaveFileTo:
- * @buf: an output I/O buffer
- * @cur: the document
- * @encoding: the encoding if any assuming the I/O layer handles the trancoding
- *
- * Dump an XML document to an I/O buffer.
- *
- * returns: the number of bytes written or -1 in case of failure.
- */
-int
-xmlSaveFileTo(xmlOutputBufferPtr buf, xmlDocPtr cur, const char *encoding) {
- int ret;
-
- if (buf == NULL) return(0);
- xmlDocContentDumpOutput(buf, cur, encoding, 0);
- ret = xmlOutputBufferClose(buf);
- return(ret);
-}
-
-/**
- * xmlSaveFormatFileTo:
- * @buf: an output I/O buffer
- * @cur: the document
- * @encoding: the encoding if any assuming the I/O layer handles the trancoding
- * @format: should formatting spaces been added
- *
- * Dump an XML document to an I/O buffer.
- *
- * returns: the number of bytes written or -1 in case of failure.
- */
-int
-xmlSaveFormatFileTo(xmlOutputBufferPtr buf, xmlDocPtr cur, const char *encoding, int format) {
- int ret;
-
- if (buf == NULL) return(0);
- xmlDocContentDumpOutput(buf, cur, encoding, format);
- ret = xmlOutputBufferClose(buf);
- return(ret);
-}
-
-/**
- * xmlSaveFormatFileEnc:
- * @filename: the filename or URL to output
- * @cur: the document being saved
- * @encoding: the name of the encoding to use or NULL.
- * @format: should formatting spaces be added.
- *
- * Dump an XML document to a file or an URL.
- *
- * Returns the number of bytes written or -1 in case of error.
- */
-int
-xmlSaveFormatFileEnc( const char * filename, xmlDocPtr cur,
- const char * encoding, int format ) {
- xmlOutputBufferPtr buf;
- xmlCharEncodingHandlerPtr handler = NULL;
- xmlCharEncoding enc;
- int ret;
-
- if (encoding == NULL)
- encoding = (const char *) cur->encoding;
-
- if (encoding != NULL) {
-
- enc = xmlParseCharEncoding(encoding);
- if (cur->charset != XML_CHAR_ENCODING_UTF8) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveFormatFileEnc: document not in UTF8\n");
- return(-1);
- }
- if (enc != XML_CHAR_ENCODING_UTF8) {
- handler = xmlFindCharEncodingHandler(encoding);
- if (handler == NULL)
- return(-1);
- }
- }
-
-#ifdef HAVE_ZLIB_H
- if (cur->compression < 0) cur->compression = xmlCompressMode;
-#endif
- /*
- * save the content to a temp buffer.
- */
- buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
- if (buf == NULL) return(-1);
-
- xmlDocContentDumpOutput(buf, cur, encoding, format);
-
- ret = xmlOutputBufferClose(buf);
- return(ret);
-}
-
-
-/**
- * xmlSaveFileEnc:
- * @filename: the filename (or URL)
- * @cur: the document
- * @encoding: the name of an encoding (or NULL)
- *
- * Dump an XML document, converting it to the given encoding
- *
- * returns: the number of bytes written or -1 in case of failure.
- */
-int
-xmlSaveFileEnc(const char *filename, xmlDocPtr cur, const char *encoding) {
- return ( xmlSaveFormatFileEnc( filename, cur, encoding, 0 ) );
-}
-
-/**
- * xmlSaveFormatFile:
- * @filename: the filename (or URL)
- * @cur: the document
- * @format: should formatting spaces been added
- *
- * Dump an XML document to a file. Will use compression if
- * compiled in and enabled. If @filename is "-" the stdout file is
- * used. If @format is set then the document will be indented on output.
- *
- * returns: the number of bytes written or -1 in case of failure.
- */
-int
-xmlSaveFormatFile(const char *filename, xmlDocPtr cur, int format) {
- return ( xmlSaveFormatFileEnc( filename, cur, NULL, format ) );
-}
-
-/**
- * xmlSaveFile:
- * @filename: the filename (or URL)
- * @cur: the document
- *
- * Dump an XML document to a file. Will use compression if
- * compiled in and enabled. If @filename is "-" the stdout file is
- * used.
- * returns: the number of bytes written or -1 in case of failure.
- */
-int
-xmlSaveFile(const char *filename, xmlDocPtr cur) {
- return(xmlSaveFormatFileEnc(filename, cur, NULL, 0));
-}
-
diff --git a/bundle/libxml/trio.c b/bundle/libxml/trio.c
deleted file mode 100644
index 7593e58180..0000000000
--- a/bundle/libxml/trio.c
+++ /dev/null
@@ -1,6760 +0,0 @@
-/*************************************************************************
- *
- * $Id$
- *
- * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- *************************************************************************
- *
- * A note to trio contributors:
- *
- * Avoid heap allocation at all costs to ensure that the trio functions
- * are async-safe. The exceptions are the printf/fprintf functions, which
- * uses fputc, and the asprintf functions and the <alloc> modifier, which
- * by design are required to allocate form the heap.
- *
- ************************************************************************/
-
-/*
- * TODO:
- * - Scan is probably too permissive about its modifiers.
- * - C escapes in %#[] ?
- * - Multibyte characters (done for format parsing, except scan groups)
- * - Complex numbers? (C99 _Complex)
- * - Boolean values? (C99 _Bool)
- * - C99 NaN(n-char-sequence) missing
- * - Should we support the GNU %a alloc modifier? GNU has an ugly hack
- * for %a, because C99 used %a for other purposes. If specified as
- * %as or %a[ it is interpreted as the alloc modifier, otherwise as
- * the C99 hex-float. This means that you cannot scan %as as a hex-float
- * immediately followed by an 's'.
- * - Scanning of collating symbols.
- */
-
-/*************************************************************************
- * Trio include files
- */
-#include "triodef.h"
-#include "trio.h"
-#include "triop.h"
-#include "trionan.h"
-#if !defined(TRIO_MINIMAL)
-# include "triostr.h"
-#endif
-
-/**************************************************************************
- *
- * Definitions
- *
- *************************************************************************/
-
-#if defined(__STDC_ISO_10646__) || defined(MB_LEN_MAX) || defined(USE_MULTIBYTE) || TRIO_WIDECHAR
-# define TRIO_COMPILER_SUPPORTS_MULTIBYTE
-# if !defined(MB_LEN_MAX)
-# define MB_LEN_MAX 6
-# endif
-#endif
-
-/*************************************************************************
- * Generic definitions
- */
-
-#if !(defined(DEBUG) || defined(NDEBUG))
-# define NDEBUG
-#endif
-#include <assert.h>
-#include <ctype.h>
-#if !defined(TRIO_COMPILER_SUPPORTS_C99)
-# define isblank(x) (((x)==32) || ((x)==9))
-#endif
-#include <math.h>
-#include <limits.h>
-#include <float.h>
-#if defined(TRIO_COMPILER_ANCIENT)
-# include <varargs.h>
-#else
-# include <stdarg.h>
-#endif
-#include <stddef.h>
-#include <errno.h>
-
-#ifndef NULL
-# define NULL 0
-#endif
-#define NIL ((char)0)
-#ifndef FALSE
-# define FALSE (1 == 0)
-# define TRUE (! FALSE)
-#endif
-#define BOOLEAN_T int
-
-/* mincore() can be used for debugging purposes */
-#define VALID(x) (NULL != (x))
-
-#if TRIO_ERRORS
- /*
- * Encode the error code and the position. This is decoded
- * with TRIO_ERROR_CODE and TRIO_ERROR_POSITION.
- */
-# define TRIO_ERROR_RETURN(x,y) (- ((x) + ((y) << 8)))
-#else
-# define TRIO_ERROR_RETURN(x,y) (-1)
-#endif
-
-
-/*************************************************************************
- * Platform specific definitions
- */
-#if defined(TRIO_PLATFORM_UNIX)
-# include <unistd.h>
-# include <signal.h>
-# include <locale.h>
-# define USE_LOCALE
-#endif /* TRIO_PLATFORM_UNIX */
-#if defined(TRIO_PLATFORM_VMS)
-# include <unistd.h>
-#endif
-#if defined(TRIO_PLATFORM_WIN32)
-# include <io.h>
-# define read _read
-# define write _write
-#endif /* TRIO_PLATFORM_WIN32 */
-
-#define TRIO_MSVC_VERSION_5 1100
-
-#if TRIO_WIDECHAR
-# if defined(TRIO_COMPILER_SUPPORTS_ISO94)
-# include <wchar.h>
-# include <wctype.h>
-typedef wchar_t trio_wchar_t;
-typedef wint_t trio_wint_t;
-# else
-typedef char trio_wchar_t;
-typedef int trio_wint_t;
-# define WCONST(x) L ## x
-# define WEOF EOF
-# define iswalnum(x) isalnum(x)
-# define iswalpha(x) isalpha(x)
-# define iswblank(x) isblank(x)
-# define iswcntrl(x) iscntrl(x)
-# define iswdigit(x) isdigit(x)
-# define iswgraph(x) isgraph(x)
-# define iswlower(x) islower(x)
-# define iswprint(x) isprint(x)
-# define iswpunct(x) ispunct(x)
-# define iswspace(x) isspace(x)
-# define iswupper(x) isupper(x)
-# define iswxdigit(x) isxdigit(x)
-# endif
-#endif
-
-
-/*************************************************************************
- * Compiler dependent definitions
- */
-
-/* Support for long long */
-#ifndef __cplusplus
-# if !defined(USE_LONGLONG)
-# if defined(TRIO_COMPILER_GCC) && !defined(__STRICT_ANSI__)
-# define USE_LONGLONG
-# elif defined(TRIO_COMPILER_SUNPRO)
-# define USE_LONGLONG
-# elif defined(_LONG_LONG) || defined(_LONGLONG)
-# define USE_LONGLONG
-# endif
-# endif
-#endif
-
-/* The extra long numbers */
-#if defined(USE_LONGLONG)
-typedef signed long long int trio_longlong_t;
-typedef unsigned long long int trio_ulonglong_t;
-#elif defined(TRIO_COMPILER_MSVC)
-# if (_MSC_VER >= TRIO_MSVC_VERSION_5)
-typedef signed __int64 trio_longlong_t;
-typedef unsigned __int64 trio_ulonglong_t;
-# else
-typedef signed long int trio_longlong_t;
-typedef unsigned long int trio_ulonglong_t;
-# endif
-#else
-typedef TRIO_SIGNED long int trio_longlong_t;
-typedef unsigned long int trio_ulonglong_t;
-#endif
-
-/* Maximal and fixed integer types */
-#if defined(TRIO_COMPILER_SUPPORTS_C99)
-# include <stdint.h>
-typedef intmax_t trio_intmax_t;
-typedef uintmax_t trio_uintmax_t;
-typedef int8_t trio_int8_t;
-typedef int16_t trio_int16_t;
-typedef int32_t trio_int32_t;
-typedef int64_t trio_int64_t;
-#elif defined(TRIO_COMPILER_SUPPORTS_UNIX98)
-# include <inttypes.h>
-typedef intmax_t trio_intmax_t;
-typedef uintmax_t trio_uintmax_t;
-typedef int8_t trio_int8_t;
-typedef int16_t trio_int16_t;
-typedef int32_t trio_int32_t;
-typedef int64_t trio_int64_t;
-#elif defined(TRIO_COMPILER_MSVC) && (_MSC_VER >= TRIO_MSVC_VERSION_5)
-typedef trio_longlong_t trio_intmax_t;
-typedef trio_ulonglong_t trio_uintmax_t;
-typedef __int8 trio_int8_t;
-typedef __int16 trio_int16_t;
-typedef __int32 trio_int32_t;
-typedef __int64 trio_int64_t;
-#else
-typedef trio_longlong_t trio_intmax_t;
-typedef trio_ulonglong_t trio_uintmax_t;
-# if defined(TRIO_INT8_T)
-typedef TRIO_INT8_T trio_int8_t;
-# else
-typedef TRIO_SIGNED char trio_int8_t;
-# endif
-# if defined(TRIO_INT16_T)
-typedef TRIO_INT16_T trio_int16_t;
-# else
-typedef TRIO_SIGNED short trio_int16_t;
-# endif
-# if defined(TRIO_INT32_T)
-typedef TRIO_INT32_T trio_int32_t;
-# else
-typedef TRIO_SIGNED int trio_int32_t;
-# endif
-# if defined(TRIO_INT64_T)
-typedef TRIO_INT64_T trio_int64_t;
-# else
-typedef trio_longlong_t trio_int64_t;
-# endif
-#endif
-
-#if !(defined(TRIO_COMPILER_SUPPORTS_C99) \
- || defined(TRIO_COMPILER_SUPPORTS_UNIX01))
-# define floorl(x) floor((double)(x))
-# define fmodl(x,y) fmod((double)(x),(double)(y))
-# define powl(x,y) pow((double)(x),(double)(y))
-#endif
-
-#define TRIO_FABS(x) (((x) < 0.0) ? -(x) : (x))
-
-/*************************************************************************
- * Internal Definitions
- */
-
-#ifndef DECIMAL_DIG
-# define DECIMAL_DIG DBL_DIG
-#endif
-
-/* Long double sizes */
-#ifdef LDBL_DIG
-# define MAX_MANTISSA_DIGITS LDBL_DIG
-# define MAX_EXPONENT_DIGITS 4
-# define MAX_DOUBLE_DIGITS LDBL_MAX_10_EXP
-#else
-# define MAX_MANTISSA_DIGITS DECIMAL_DIG
-# define MAX_EXPONENT_DIGITS 3
-# define MAX_DOUBLE_DIGITS DBL_MAX_10_EXP
-#endif
-
-#if defined(TRIO_COMPILER_ANCIENT) || !defined(LDBL_DIG)
-# undef LDBL_DIG
-# undef LDBL_MANT_DIG
-# undef LDBL_EPSILON
-# define LDBL_DIG DBL_DIG
-# define LDBL_MANT_DIG DBL_MANT_DIG
-# define LDBL_EPSILON DBL_EPSILON
-#endif
-
-/* The maximal number of digits is for base 2 */
-#define MAX_CHARS_IN(x) (sizeof(x) * CHAR_BIT)
-/* The width of a pointer. The number of bits in a hex digit is 4 */
-#define POINTER_WIDTH ((sizeof("0x") - 1) + sizeof(trio_pointer_t) * CHAR_BIT / 4)
-
-/* Infinite and Not-A-Number for floating-point */
-#define INFINITE_LOWER "inf"
-#define INFINITE_UPPER "INF"
-#define LONG_INFINITE_LOWER "infinite"
-#define LONG_INFINITE_UPPER "INFINITE"
-#define NAN_LOWER "nan"
-#define NAN_UPPER "NAN"
-
-/* Various constants */
-enum {
- TYPE_PRINT = 1,
- TYPE_SCAN = 2,
-
- /* Flags. Use maximum 32 */
- FLAGS_NEW = 0,
- FLAGS_STICKY = 1,
- FLAGS_SPACE = 2 * FLAGS_STICKY,
- FLAGS_SHOWSIGN = 2 * FLAGS_SPACE,
- FLAGS_LEFTADJUST = 2 * FLAGS_SHOWSIGN,
- FLAGS_ALTERNATIVE = 2 * FLAGS_LEFTADJUST,
- FLAGS_SHORT = 2 * FLAGS_ALTERNATIVE,
- FLAGS_SHORTSHORT = 2 * FLAGS_SHORT,
- FLAGS_LONG = 2 * FLAGS_SHORTSHORT,
- FLAGS_QUAD = 2 * FLAGS_LONG,
- FLAGS_LONGDOUBLE = 2 * FLAGS_QUAD,
- FLAGS_SIZE_T = 2 * FLAGS_LONGDOUBLE,
- FLAGS_PTRDIFF_T = 2 * FLAGS_SIZE_T,
- FLAGS_INTMAX_T = 2 * FLAGS_PTRDIFF_T,
- FLAGS_NILPADDING = 2 * FLAGS_INTMAX_T,
- FLAGS_UNSIGNED = 2 * FLAGS_NILPADDING,
- FLAGS_UPPER = 2 * FLAGS_UNSIGNED,
- FLAGS_WIDTH = 2 * FLAGS_UPPER,
- FLAGS_WIDTH_PARAMETER = 2 * FLAGS_WIDTH,
- FLAGS_PRECISION = 2 * FLAGS_WIDTH_PARAMETER,
- FLAGS_PRECISION_PARAMETER = 2 * FLAGS_PRECISION,
- FLAGS_BASE = 2 * FLAGS_PRECISION_PARAMETER,
- FLAGS_BASE_PARAMETER = 2 * FLAGS_BASE,
- FLAGS_FLOAT_E = 2 * FLAGS_BASE_PARAMETER,
- FLAGS_FLOAT_G = 2 * FLAGS_FLOAT_E,
- FLAGS_QUOTE = 2 * FLAGS_FLOAT_G,
- FLAGS_WIDECHAR = 2 * FLAGS_QUOTE,
- FLAGS_ALLOC = 2 * FLAGS_WIDECHAR,
- FLAGS_IGNORE = 2 * FLAGS_ALLOC,
- FLAGS_IGNORE_PARAMETER = 2 * FLAGS_IGNORE,
- FLAGS_VARSIZE_PARAMETER = 2 * FLAGS_IGNORE_PARAMETER,
- FLAGS_FIXED_SIZE = 2 * FLAGS_VARSIZE_PARAMETER,
- /* Reused flags */
- FLAGS_EXCLUDE = FLAGS_SHORT,
- FLAGS_USER_DEFINED = FLAGS_IGNORE,
- FLAGS_ROUNDING = FLAGS_INTMAX_T,
- /* Compounded flags */
- FLAGS_ALL_VARSIZES = FLAGS_LONG | FLAGS_QUAD | FLAGS_INTMAX_T | FLAGS_PTRDIFF_T | FLAGS_SIZE_T,
- FLAGS_ALL_SIZES = FLAGS_ALL_VARSIZES | FLAGS_SHORTSHORT | FLAGS_SHORT,
-
- NO_POSITION = -1,
- NO_WIDTH = 0,
- NO_PRECISION = -1,
- NO_SIZE = -1,
-
- /* Do not change these */
- NO_BASE = -1,
- MIN_BASE = 2,
- MAX_BASE = 36,
- BASE_BINARY = 2,
- BASE_OCTAL = 8,
- BASE_DECIMAL = 10,
- BASE_HEX = 16,
-
- /* Maximal number of allowed parameters */
- MAX_PARAMETERS = 64,
- /* Maximal number of characters in class */
- MAX_CHARACTER_CLASS = UCHAR_MAX + 1,
-
- /* Maximal string lengths for user-defined specifiers */
- MAX_USER_NAME = 64,
- MAX_USER_DATA = 256,
-
- /* Maximal length of locale separator strings */
- MAX_LOCALE_SEPARATOR_LENGTH = MB_LEN_MAX,
- /* Maximal number of integers in grouping */
- MAX_LOCALE_GROUPS = 64,
-
- /* Initial size of asprintf buffer */
- DYNAMIC_START_SIZE = 32
-};
-
-#define NO_GROUPING ((int)CHAR_MAX)
-
-/* Fundamental formatting parameter types */
-#define FORMAT_UNKNOWN 0
-#define FORMAT_INT 1
-#define FORMAT_DOUBLE 2
-#define FORMAT_CHAR 3
-#define FORMAT_STRING 4
-#define FORMAT_POINTER 5
-#define FORMAT_COUNT 6
-#define FORMAT_PARAMETER 7
-#define FORMAT_GROUP 8
-#if TRIO_GNU
-# define FORMAT_ERRNO 9
-#endif
-#if TRIO_EXTENSION
-# define FORMAT_USER_DEFINED 10
-#endif
-
-/* Character constants */
-#define CHAR_IDENTIFIER '%'
-#define CHAR_BACKSLASH '\\'
-#define CHAR_QUOTE '\"'
-#define CHAR_ADJUST ' '
-
-/* Character class expressions */
-#define CLASS_ALNUM "[:alnum:]"
-#define CLASS_ALPHA "[:alpha:]"
-#define CLASS_BLANK "[:blank:]"
-#define CLASS_CNTRL "[:cntrl:]"
-#define CLASS_DIGIT "[:digit:]"
-#define CLASS_GRAPH "[:graph:]"
-#define CLASS_LOWER "[:lower:]"
-#define CLASS_PRINT "[:print:]"
-#define CLASS_PUNCT "[:punct:]"
-#define CLASS_SPACE "[:space:]"
-#define CLASS_UPPER "[:upper:]"
-#define CLASS_XDIGIT "[:xdigit:]"
-
-/*
- * SPECIFIERS:
- *
- *
- * a Hex-float
- * A Hex-float
- * c Character
- * C Widechar character (wint_t)
- * d Decimal
- * e Float
- * E Float
- * F Float
- * F Float
- * g Float
- * G Float
- * i Integer
- * m Error message
- * n Count
- * o Octal
- * p Pointer
- * s String
- * S Widechar string (wchar_t *)
- * u Unsigned
- * x Hex
- * X Hex
- * [] Group
- * <> User-defined
- *
- * Reserved:
- *
- * D Binary Coded Decimal %D(length,precision) (OS/390)
- */
-#define SPECIFIER_CHAR 'c'
-#define SPECIFIER_STRING 's'
-#define SPECIFIER_DECIMAL 'd'
-#define SPECIFIER_INTEGER 'i'
-#define SPECIFIER_UNSIGNED 'u'
-#define SPECIFIER_OCTAL 'o'
-#define SPECIFIER_HEX 'x'
-#define SPECIFIER_HEX_UPPER 'X'
-#define SPECIFIER_FLOAT_E 'e'
-#define SPECIFIER_FLOAT_E_UPPER 'E'
-#define SPECIFIER_FLOAT_F 'f'
-#define SPECIFIER_FLOAT_F_UPPER 'F'
-#define SPECIFIER_FLOAT_G 'g'
-#define SPECIFIER_FLOAT_G_UPPER 'G'
-#define SPECIFIER_POINTER 'p'
-#define SPECIFIER_GROUP '['
-#define SPECIFIER_UNGROUP ']'
-#define SPECIFIER_COUNT 'n'
-#if TRIO_UNIX98
-# define SPECIFIER_CHAR_UPPER 'C'
-# define SPECIFIER_STRING_UPPER 'S'
-#endif
-#if TRIO_C99
-# define SPECIFIER_HEXFLOAT 'a'
-# define SPECIFIER_HEXFLOAT_UPPER 'A'
-#endif
-#if TRIO_GNU
-# define SPECIFIER_ERRNO 'm'
-#endif
-#if TRIO_EXTENSION
-# define SPECIFIER_BINARY 'b'
-# define SPECIFIER_BINARY_UPPER 'B'
-# define SPECIFIER_USER_DEFINED_BEGIN '<'
-# define SPECIFIER_USER_DEFINED_END '>'
-# define SPECIFIER_USER_DEFINED_SEPARATOR ':'
-#endif
-
-/*
- * QUALIFIERS:
- *
- *
- * Numbers = d,i,o,u,x,X
- * Float = a,A,e,E,f,F,g,G
- * String = s
- * Char = c
- *
- *
- * 9$ Position
- * Use the 9th parameter. 9 can be any number between 1 and
- * the maximal argument
- *
- * 9 Width
- * Set width to 9. 9 can be any number, but must not be postfixed
- * by '$'
- *
- * h Short
- * Numbers:
- * (unsigned) short int
- *
- * hh Short short
- * Numbers:
- * (unsigned) char
- *
- * l Long
- * Numbers:
- * (unsigned) long int
- * String:
- * as the S specifier
- * Char:
- * as the C specifier
- *
- * ll Long Long
- * Numbers:
- * (unsigned) long long int
- *
- * L Long Double
- * Float
- * long double
- *
- * # Alternative
- * Float:
- * Decimal-point is always present
- * String:
- * non-printable characters are handled as \number
- *
- * Spacing
- *
- * + Sign
- *
- * - Alignment
- *
- * . Precision
- *
- * * Parameter
- * print: use parameter
- * scan: no parameter (ignore)
- *
- * q Quad
- *
- * Z size_t
- *
- * w Widechar
- *
- * ' Thousands/quote
- * Numbers:
- * Integer part grouped in thousands
- * Binary numbers:
- * Number grouped in nibbles (4 bits)
- * String:
- * Quoted string
- *
- * j intmax_t
- * t prtdiff_t
- * z size_t
- *
- * ! Sticky
- * @ Parameter (for both print and scan)
- *
- * I n-bit Integer
- * Numbers:
- * The following options exists
- * I8 = 8-bit integer
- * I16 = 16-bit integer
- * I32 = 32-bit integer
- * I64 = 64-bit integer
- */
-#define QUALIFIER_POSITION '$'
-#define QUALIFIER_SHORT 'h'
-#define QUALIFIER_LONG 'l'
-#define QUALIFIER_LONG_UPPER 'L'
-#define QUALIFIER_ALTERNATIVE '#'
-#define QUALIFIER_SPACE ' '
-#define QUALIFIER_PLUS '+'
-#define QUALIFIER_MINUS '-'
-#define QUALIFIER_DOT '.'
-#define QUALIFIER_STAR '*'
-#define QUALIFIER_CIRCUMFLEX '^' /* For scanlists */
-#if TRIO_C99
-# define QUALIFIER_SIZE_T 'z'
-# define QUALIFIER_PTRDIFF_T 't'
-# define QUALIFIER_INTMAX_T 'j'
-#endif
-#if TRIO_BSD || TRIO_GNU
-# define QUALIFIER_QUAD 'q'
-#endif
-#if TRIO_GNU
-# define QUALIFIER_SIZE_T_UPPER 'Z'
-#endif
-#if TRIO_MISC
-# define QUALIFIER_WIDECHAR 'w'
-#endif
-#if TRIO_MICROSOFT
-# define QUALIFIER_FIXED_SIZE 'I'
-#endif
-#if TRIO_EXTENSION
-# define QUALIFIER_QUOTE '\''
-# define QUALIFIER_STICKY '!'
-# define QUALIFIER_VARSIZE '&' /* This should remain undocumented */
-# define QUALIFIER_PARAM '@' /* Experimental */
-# define QUALIFIER_COLON ':' /* For scanlists */
-# define QUALIFIER_EQUAL '=' /* For scanlists */
-# define QUALIFIER_ROUNDING_UPPER 'R'
-#endif
-
-
-/*************************************************************************
- *
- * Internal Structures
- *
- *************************************************************************/
-
-/* Parameters */
-typedef struct {
- /* An indication of which entry in the data union is used */
- int type;
- /* The flags */
- unsigned long flags;
- /* The width qualifier */
- int width;
- /* The precision qualifier */
- int precision;
- /* The base qualifier */
- int base;
- /* The size for the variable size qualifier */
- int varsize;
- /* The marker of the end of the specifier */
- int indexAfterSpecifier;
- /* The data from the argument list */
- union {
- char *string;
-#if TRIO_WIDECHAR
- trio_wchar_t *wstring;
-#endif
- trio_pointer_t pointer;
- union {
- trio_intmax_t as_signed;
- trio_uintmax_t as_unsigned;
- } number;
- double doubleNumber;
- double *doublePointer;
- trio_long_double_t longdoubleNumber;
- trio_long_double_t *longdoublePointer;
- int errorNumber;
- } data;
- /* For the user-defined specifier */
- char user_name[MAX_USER_NAME];
- char user_data[MAX_USER_DATA];
-} trio_parameter_t;
-
-/* Container for customized functions */
-typedef struct {
- union {
- trio_outstream_t out;
- trio_instream_t in;
- } stream;
- trio_pointer_t closure;
-} trio_custom_t;
-
-/* General trio "class" */
-typedef struct _trio_class_t {
- /*
- * The function to write characters to a stream.
- */
- void (*OutStream) TRIO_PROTO((struct _trio_class_t *, int));
- /*
- * The function to read characters from a stream.
- */
- void (*InStream) TRIO_PROTO((struct _trio_class_t *, int *));
- /*
- * The current location in the stream.
- */
- trio_pointer_t location;
- /*
- * The character currently being processed.
- */
- int current;
- /*
- * The number of characters that would have been written/read
- * if there had been sufficient space.
- */
- int processed;
- /*
- * The number of characters that are actually written/read.
- * Processed and committed will only differ for the *nprintf
- * and *nscanf functions.
- */
- int committed;
- /*
- * The upper limit of characters that may be written/read.
- */
- int max;
- /*
- * The last output error that was detected.
- */
- int error;
-} trio_class_t;
-
-/* References (for user-defined callbacks) */
-typedef struct _trio_reference_t {
- trio_class_t *data;
- trio_parameter_t *parameter;
-} trio_reference_t;
-
-/* Registered entries (for user-defined callbacks) */
-typedef struct _trio_userdef_t {
- struct _trio_userdef_t *next;
- trio_callback_t callback;
- char *name;
-} trio_userdef_t;
-
-
-/*************************************************************************
- *
- * Internal Variables
- *
- *************************************************************************/
-
-static TRIO_CONST char rcsid[] = "@(#)$Id$";
-
-/*
- * Need this to workaround a parser bug in HP C/iX compiler that fails
- * to resolves macro definitions that includes type 'long double',
- * e.g: va_arg(arg_ptr, long double)
- */
-#if defined(TRIO_PLATFORM_MPEIX)
-static TRIO_CONST trio_long_double_t ___dummy_long_double = 0;
-#endif
-
-static TRIO_CONST char internalNullString[] = "(nil)";
-
-#if defined(USE_LOCALE)
-static struct lconv *internalLocaleValues = NULL;
-#endif
-
-/*
- * UNIX98 says "in a locale where the radix character is not defined,
- * the radix character defaults to a period (.)"
- */
-static int internalDecimalPointLength = 1;
-static int internalThousandSeparatorLength = 1;
-static char internalDecimalPoint = '.';
-static char internalDecimalPointString[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ".";
-static char internalThousandSeparator[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ",";
-static char internalGrouping[MAX_LOCALE_GROUPS] = { (char)NO_GROUPING };
-
-static TRIO_CONST char internalDigitsLower[] = "0123456789abcdefghijklmnopqrstuvwxyz";
-static TRIO_CONST char internalDigitsUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-static BOOLEAN_T internalDigitsUnconverted = TRUE;
-static int internalDigitArray[128];
-#if TRIO_EXTENSION
-static BOOLEAN_T internalCollationUnconverted = TRUE;
-static char internalCollationArray[MAX_CHARACTER_CLASS][MAX_CHARACTER_CLASS];
-#endif
-
-#if TRIO_EXTENSION
-static TRIO_VOLATILE trio_callback_t internalEnterCriticalRegion = NULL;
-static TRIO_VOLATILE trio_callback_t internalLeaveCriticalRegion = NULL;
-static trio_userdef_t *internalUserDef = NULL;
-#endif
-
-
-/*************************************************************************
- *
- * Internal Functions
- *
- ************************************************************************/
-
-#if defined(TRIO_MINIMAL)
-# define TRIO_STRING_PUBLIC static
-# include "triostr.c"
-#endif /* defined(TRIO_MINIMAL) */
-
-/*************************************************************************
- * TrioIsQualifier
- *
- * Description:
- * Remember to add all new qualifiers to this function.
- * QUALIFIER_POSITION must not be added.
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioIsQualifier
-TRIO_ARGS1((character),
- TRIO_CONST char character)
-{
- /* QUALIFIER_POSITION is not included */
- switch (character)
- {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- case QUALIFIER_PLUS:
- case QUALIFIER_MINUS:
- case QUALIFIER_SPACE:
- case QUALIFIER_DOT:
- case QUALIFIER_STAR:
- case QUALIFIER_ALTERNATIVE:
- case QUALIFIER_SHORT:
- case QUALIFIER_LONG:
- case QUALIFIER_LONG_UPPER:
- case QUALIFIER_CIRCUMFLEX:
-#if defined(QUALIFIER_SIZE_T)
- case QUALIFIER_SIZE_T:
-#endif
-#if defined(QUALIFIER_PTRDIFF_T)
- case QUALIFIER_PTRDIFF_T:
-#endif
-#if defined(QUALIFIER_INTMAX_T)
- case QUALIFIER_INTMAX_T:
-#endif
-#if defined(QUALIFIER_QUAD)
- case QUALIFIER_QUAD:
-#endif
-#if defined(QUALIFIER_SIZE_T_UPPER)
- case QUALIFIER_SIZE_T_UPPER:
-#endif
-#if defined(QUALIFIER_WIDECHAR)
- case QUALIFIER_WIDECHAR:
-#endif
-#if defined(QUALIFIER_QUOTE)
- case QUALIFIER_QUOTE:
-#endif
-#if defined(QUALIFIER_STICKY)
- case QUALIFIER_STICKY:
-#endif
-#if defined(QUALIFIER_VARSIZE)
- case QUALIFIER_VARSIZE:
-#endif
-#if defined(QUALIFIER_PARAM)
- case QUALIFIER_PARAM:
-#endif
-#if defined(QUALIFIER_FIXED_SIZE)
- case QUALIFIER_FIXED_SIZE:
-#endif
-#if defined(QUALIFIER_ROUNDING_UPPER)
- case QUALIFIER_ROUNDING_UPPER:
-#endif
- return TRUE;
- default:
- return FALSE;
- }
-}
-
-/*************************************************************************
- * TrioSetLocale
- */
-#if defined(USE_LOCALE)
-TRIO_PRIVATE void
-TrioSetLocale(TRIO_NOARGS)
-{
- internalLocaleValues = (struct lconv *)localeconv();
- if (internalLocaleValues)
- {
- if ((internalLocaleValues->decimal_point) &&
- (internalLocaleValues->decimal_point[0] != NIL))
- {
- internalDecimalPointLength = trio_length(internalLocaleValues->decimal_point);
- if (internalDecimalPointLength == 1)
- {
- internalDecimalPoint = internalLocaleValues->decimal_point[0];
- }
- else
- {
- internalDecimalPoint = NIL;
- trio_copy_max(internalDecimalPointString,
- sizeof(internalDecimalPointString),
- internalLocaleValues->decimal_point);
- }
- }
- if ((internalLocaleValues->thousands_sep) &&
- (internalLocaleValues->thousands_sep[0] != NIL))
- {
- trio_copy_max(internalThousandSeparator,
- sizeof(internalThousandSeparator),
- internalLocaleValues->thousands_sep);
- internalThousandSeparatorLength = trio_length(internalThousandSeparator);
- }
- if ((internalLocaleValues->grouping) &&
- (internalLocaleValues->grouping[0] != NIL))
- {
- trio_copy_max(internalGrouping,
- sizeof(internalGrouping),
- internalLocaleValues->grouping);
- }
- }
-}
-#endif /* defined(USE_LOCALE) */
-
-TRIO_PRIVATE int
-TrioCalcThousandSeparatorLength
-TRIO_ARGS1((digits),
- int digits)
-{
-#if TRIO_EXTENSION
- int count = 0;
- int step = NO_GROUPING;
- char *groupingPointer = internalGrouping;
-
- while (digits > 0)
- {
- if (*groupingPointer == CHAR_MAX)
- {
- /* Disable grouping */
- break; /* while */
- }
- else if (*groupingPointer == 0)
- {
- /* Repeat last group */
- if (step == NO_GROUPING)
- {
- /* Error in locale */
- break; /* while */
- }
- }
- else
- {
- step = *groupingPointer++;
- }
- if (digits > step)
- count += internalThousandSeparatorLength;
- digits -= step;
- }
- return count;
-#else
- return 0;
-#endif
-}
-
-TRIO_PRIVATE BOOLEAN_T
-TrioFollowedBySeparator
-TRIO_ARGS1((position),
- int position)
-{
-#if TRIO_EXTENSION
- int step = 0;
- char *groupingPointer = internalGrouping;
-
- position--;
- if (position == 0)
- return FALSE;
- while (position > 0)
- {
- if (*groupingPointer == CHAR_MAX)
- {
- /* Disable grouping */
- break; /* while */
- }
- else if (*groupingPointer != 0)
- {
- step = *groupingPointer++;
- }
- if (step == 0)
- break;
- position -= step;
- }
- return (position == 0);
-#else
- return FALSE;
-#endif
-}
-
-/*************************************************************************
- * TrioGetPosition
- *
- * Get the %n$ position.
- */
-TRIO_PRIVATE int
-TrioGetPosition
-TRIO_ARGS2((format, indexPointer),
- TRIO_CONST char *format,
- int *indexPointer)
-{
-#if TRIO_UNIX98
- char *tmpformat;
- int number = 0;
- int index = *indexPointer;
-
- number = (int)trio_to_long(&format[index], &tmpformat, BASE_DECIMAL);
- index = (int)(tmpformat - format);
- if ((number != 0) && (QUALIFIER_POSITION == format[index++]))
- {
- *indexPointer = index;
- /*
- * number is decreased by 1, because n$ starts from 1, whereas
- * the array it is indexing starts from 0.
- */
- return number - 1;
- }
-#endif
- return NO_POSITION;
-}
-
-#if TRIO_EXTENSION
-/*************************************************************************
- * TrioFindNamespace
- *
- * Find registered user-defined specifier.
- * The prev argument is used for optimization only.
- */
-TRIO_PRIVATE trio_userdef_t *
-TrioFindNamespace
-TRIO_ARGS2((name, prev),
- TRIO_CONST char *name,
- trio_userdef_t **prev)
-{
- trio_userdef_t *def;
-
- if (internalEnterCriticalRegion)
- (void)internalEnterCriticalRegion(NULL);
-
- for (def = internalUserDef; def; def = def->next)
- {
- /* Case-sensitive string comparison */
- if (trio_equal_case(def->name, name))
- break;
-
- if (prev)
- *prev = def;
- }
-
- if (internalLeaveCriticalRegion)
- (void)internalLeaveCriticalRegion(NULL);
-
- return def;
-}
-#endif
-
-/*************************************************************************
- * TrioPower
- *
- * Description:
- * Calculate pow(base, exponent), where number and exponent are integers.
- */
-TRIO_PRIVATE trio_long_double_t
-TrioPower
-TRIO_ARGS2((number, exponent),
- int number,
- int exponent)
-{
- trio_long_double_t result;
-
- if (number == 10)
- {
- switch (exponent)
- {
- /* Speed up calculation of common cases */
- case 0:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E-1);
- break;
- case 1:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+0);
- break;
- case 2:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+1);
- break;
- case 3:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+2);
- break;
- case 4:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+3);
- break;
- case 5:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+4);
- break;
- case 6:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+5);
- break;
- case 7:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+6);
- break;
- case 8:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+7);
- break;
- case 9:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+8);
- break;
- default:
- result = powl((trio_long_double_t)number,
- (trio_long_double_t)exponent);
- break;
- }
- }
- else
- {
- return powl((trio_long_double_t)number, (trio_long_double_t)exponent);
- }
- return result;
-}
-
-/*************************************************************************
- * TrioLogarithm
- */
-TRIO_PRIVATE double
-TrioLogarithm
-TRIO_ARGS2((number, base),
- double number,
- int base)
-{
- double result;
-
- if (number <= 0.0)
- {
- /* xlC crashes on log(0) */
- result = (number == 0.0) ? trio_ninf() : trio_nan();
- }
- else
- {
- if (base == 10)
- {
- result = log10(number);
- }
- else
- {
- result = log10(number) / log10((double)base);
- }
- }
- return result;
-}
-
-/*************************************************************************
- * TrioLogarithmBase
- */
-TRIO_PRIVATE double
-TrioLogarithmBase
-TRIO_ARGS1((base),
- int base)
-{
- switch (base)
- {
- case BASE_BINARY : return 1.0;
- case BASE_OCTAL : return 3.0;
- case BASE_DECIMAL: return 3.321928094887362345;
- case BASE_HEX : return 4.0;
- default : return TrioLogarithm((double)base, 2);
- }
-}
-
-/*************************************************************************
- * TrioParse
- *
- * Description:
- * Parse the format string
- */
-TRIO_PRIVATE int
-TrioParse
-TRIO_ARGS5((type, format, parameters, arglist, argarray),
- int type,
- TRIO_CONST char *format,
- trio_parameter_t *parameters,
- va_list *arglist,
- trio_pointer_t *argarray)
-{
- /* Count the number of times a parameter is referenced */
- unsigned short usedEntries[MAX_PARAMETERS];
- /* Parameter counters */
- int parameterPosition;
- int currentParam;
- int maxParam = -1;
- /* Utility variables */
- unsigned long flags;
- int width;
- int precision;
- int varsize;
- int base;
- int index; /* Index into formatting string */
- int dots; /* Count number of dots in modifier part */
- BOOLEAN_T positional; /* Does the specifier have a positional? */
- BOOLEAN_T gotSticky = FALSE; /* Are there any sticky modifiers at all? */
- /*
- * indices specifies the order in which the parameters must be
- * read from the va_args (this is necessary to handle positionals)
- */
- int indices[MAX_PARAMETERS];
- int pos = 0;
- /* Various variables */
- char ch;
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- int charlen;
-#endif
- int save_errno;
- int i = -1;
- int num;
- char *tmpformat;
-
- /* One and only one of arglist and argarray must be used */
- assert((arglist != NULL) ^ (argarray != NULL));
-
- /*
- * The 'parameters' array is not initialized, but we need to
- * know which entries we have used.
- */
- memset(usedEntries, 0, sizeof(usedEntries));
-
- save_errno = errno;
- index = 0;
- parameterPosition = 0;
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- (void)mblen(NULL, 0);
-#endif
-
- while (format[index])
- {
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- if (! isascii(format[index]))
- {
- /*
- * Multibyte characters cannot be legal specifiers or
- * modifiers, so we skip over them.
- */
- charlen = mblen(&format[index], MB_LEN_MAX);
- index += (charlen > 0) ? charlen : 1;
- continue; /* while */
- }
-#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
- if (CHAR_IDENTIFIER == format[index++])
- {
- if (CHAR_IDENTIFIER == format[index])
- {
- index++;
- continue; /* while */
- }
-
- flags = FLAGS_NEW;
- dots = 0;
- currentParam = TrioGetPosition(format, &index);
- positional = (NO_POSITION != currentParam);
- if (!positional)
- {
- /* We have no positional, get the next counter */
- currentParam = parameterPosition;
- }
- if(currentParam >= MAX_PARAMETERS)
- {
- /* Bail out completely to make the error more obvious */
- return TRIO_ERROR_RETURN(TRIO_ETOOMANY, index);
- }
-
- if (currentParam > maxParam)
- maxParam = currentParam;
-
- /* Default values */
- width = NO_WIDTH;
- precision = NO_PRECISION;
- base = NO_BASE;
- varsize = NO_SIZE;
-
- while (TrioIsQualifier(format[index]))
- {
- ch = format[index++];
-
- switch (ch)
- {
- case QUALIFIER_SPACE:
- flags |= FLAGS_SPACE;
- break;
-
- case QUALIFIER_PLUS:
- flags |= FLAGS_SHOWSIGN;
- break;
-
- case QUALIFIER_MINUS:
- flags |= FLAGS_LEFTADJUST;
- flags &= ~FLAGS_NILPADDING;
- break;
-
- case QUALIFIER_ALTERNATIVE:
- flags |= FLAGS_ALTERNATIVE;
- break;
-
- case QUALIFIER_DOT:
- if (dots == 0) /* Precision */
- {
- dots++;
-
- /* Skip if no precision */
- if (QUALIFIER_DOT == format[index])
- break;
-
- /* After the first dot we have the precision */
- flags |= FLAGS_PRECISION;
- if ((QUALIFIER_STAR == format[index])
-#if defined(QUALIFIER_PARAM)
- || (QUALIFIER_PARAM == format[index])
-#endif
- )
- {
- index++;
- flags |= FLAGS_PRECISION_PARAMETER;
-
- precision = TrioGetPosition(format, &index);
- if (precision == NO_POSITION)
- {
- parameterPosition++;
- if (positional)
- precision = parameterPosition;
- else
- {
- precision = currentParam;
- currentParam = precision + 1;
- }
- }
- else
- {
- if (! positional)
- currentParam = precision + 1;
- if (width > maxParam)
- maxParam = precision;
- }
- if (currentParam > maxParam)
- maxParam = currentParam;
- }
- else
- {
- precision = trio_to_long(&format[index],
- &tmpformat,
- BASE_DECIMAL);
- index = (int)(tmpformat - format);
- }
- }
- else if (dots == 1) /* Base */
- {
- dots++;
-
- /* After the second dot we have the base */
- flags |= FLAGS_BASE;
- if ((QUALIFIER_STAR == format[index])
-#if defined(QUALIFIER_PARAM)
- || (QUALIFIER_PARAM == format[index])
-#endif
- )
- {
- index++;
- flags |= FLAGS_BASE_PARAMETER;
- base = TrioGetPosition(format, &index);
- if (base == NO_POSITION)
- {
- parameterPosition++;
- if (positional)
- base = parameterPosition;
- else
- {
- base = currentParam;
- currentParam = base + 1;
- }
- }
- else
- {
- if (! positional)
- currentParam = base + 1;
- if (base > maxParam)
- maxParam = base;
- }
- if (currentParam > maxParam)
- maxParam = currentParam;
- }
- else
- {
- base = trio_to_long(&format[index],
- &tmpformat,
- BASE_DECIMAL);
- if (base > MAX_BASE)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- index = (int)(tmpformat - format);
- }
- }
- else
- {
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- }
- break; /* QUALIFIER_DOT */
-
-#if defined(QUALIFIER_PARAM)
- case QUALIFIER_PARAM:
- type = TYPE_PRINT;
- /* FALLTHROUGH */
-#endif
- case QUALIFIER_STAR:
- /* This has different meanings for print and scan */
- if (TYPE_PRINT == type)
- {
- /* Read with from parameter */
- flags |= (FLAGS_WIDTH | FLAGS_WIDTH_PARAMETER);
- width = TrioGetPosition(format, &index);
- if (width == NO_POSITION)
- {
- parameterPosition++;
- if (positional)
- width = parameterPosition;
- else
- {
- width = currentParam;
- currentParam = width + 1;
- }
- }
- else
- {
- if (! positional)
- currentParam = width + 1;
- if (width > maxParam)
- maxParam = width;
- }
- if (currentParam > maxParam)
- maxParam = currentParam;
- }
- else
- {
- /* Scan, but do not store result */
- flags |= FLAGS_IGNORE;
- }
-
- break; /* QUALIFIER_STAR */
-
- case '0':
- if (! (flags & FLAGS_LEFTADJUST))
- flags |= FLAGS_NILPADDING;
- /* FALLTHROUGH */
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- flags |= FLAGS_WIDTH;
- /* &format[index - 1] is used to "rewind" the read
- * character from format
- */
- width = trio_to_long(&format[index - 1],
- &tmpformat,
- BASE_DECIMAL);
- index = (int)(tmpformat - format);
- break;
-
- case QUALIFIER_SHORT:
- if (flags & FLAGS_SHORTSHORT)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- else if (flags & FLAGS_SHORT)
- flags |= FLAGS_SHORTSHORT;
- else
- flags |= FLAGS_SHORT;
- break;
-
- case QUALIFIER_LONG:
- if (flags & FLAGS_QUAD)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- else if (flags & FLAGS_LONG)
- flags |= FLAGS_QUAD;
- else
- flags |= FLAGS_LONG;
- break;
-
- case QUALIFIER_LONG_UPPER:
- flags |= FLAGS_LONGDOUBLE;
- break;
-
-#if defined(QUALIFIER_SIZE_T)
- case QUALIFIER_SIZE_T:
- flags |= FLAGS_SIZE_T;
- /* Modify flags for later truncation of number */
- if (sizeof(size_t) == sizeof(trio_ulonglong_t))
- flags |= FLAGS_QUAD;
- else if (sizeof(size_t) == sizeof(long))
- flags |= FLAGS_LONG;
- break;
-#endif
-
-#if defined(QUALIFIER_PTRDIFF_T)
- case QUALIFIER_PTRDIFF_T:
- flags |= FLAGS_PTRDIFF_T;
- if (sizeof(ptrdiff_t) == sizeof(trio_ulonglong_t))
- flags |= FLAGS_QUAD;
- else if (sizeof(ptrdiff_t) == sizeof(long))
- flags |= FLAGS_LONG;
- break;
-#endif
-
-#if defined(QUALIFIER_INTMAX_T)
- case QUALIFIER_INTMAX_T:
- flags |= FLAGS_INTMAX_T;
- if (sizeof(trio_intmax_t) == sizeof(trio_ulonglong_t))
- flags |= FLAGS_QUAD;
- else if (sizeof(trio_intmax_t) == sizeof(long))
- flags |= FLAGS_LONG;
- break;
-#endif
-
-#if defined(QUALIFIER_QUAD)
- case QUALIFIER_QUAD:
- flags |= FLAGS_QUAD;
- break;
-#endif
-
-#if defined(QUALIFIER_FIXED_SIZE)
- case QUALIFIER_FIXED_SIZE:
- if (flags & FLAGS_FIXED_SIZE)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
-
- if (flags & (FLAGS_ALL_SIZES | FLAGS_LONGDOUBLE |
- FLAGS_WIDECHAR | FLAGS_VARSIZE_PARAMETER))
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
-
- if ((format[index] == '6') &&
- (format[index + 1] == '4'))
- {
- varsize = sizeof(trio_int64_t);
- index += 2;
- }
- else if ((format[index] == '3') &&
- (format[index + 1] == '2'))
- {
- varsize = sizeof(trio_int32_t);
- index += 2;
- }
- else if ((format[index] == '1') &&
- (format[index + 1] == '6'))
- {
- varsize = sizeof(trio_int16_t);
- index += 2;
- }
- else if (format[index] == '8')
- {
- varsize = sizeof(trio_int8_t);
- index++;
- }
- else
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
-
- flags |= FLAGS_FIXED_SIZE;
- break;
-#endif
-
-#if defined(QUALIFIER_WIDECHAR)
- case QUALIFIER_WIDECHAR:
- flags |= FLAGS_WIDECHAR;
- break;
-#endif
-
-#if defined(QUALIFIER_SIZE_T_UPPER)
- case QUALIFIER_SIZE_T_UPPER:
- break;
-#endif
-
-#if defined(QUALIFIER_QUOTE)
- case QUALIFIER_QUOTE:
- flags |= FLAGS_QUOTE;
- break;
-#endif
-
-#if defined(QUALIFIER_STICKY)
- case QUALIFIER_STICKY:
- flags |= FLAGS_STICKY;
- gotSticky = TRUE;
- break;
-#endif
-
-#if defined(QUALIFIER_VARSIZE)
- case QUALIFIER_VARSIZE:
- flags |= FLAGS_VARSIZE_PARAMETER;
- parameterPosition++;
- if (positional)
- varsize = parameterPosition;
- else
- {
- varsize = currentParam;
- currentParam = varsize + 1;
- }
- if (currentParam > maxParam)
- maxParam = currentParam;
- break;
-#endif
-
-#if defined(QUALIFIER_ROUNDING_UPPER)
- case QUALIFIER_ROUNDING_UPPER:
- flags |= FLAGS_ROUNDING;
- break;
-#endif
-
- default:
- /* Bail out completely to make the error more obvious */
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- }
- } /* while qualifier */
-
- /*
- * Parameters only need the type and value. The value is
- * read later.
- */
- if (flags & FLAGS_WIDTH_PARAMETER)
- {
- usedEntries[width] += 1;
- parameters[pos].type = FORMAT_PARAMETER;
- parameters[pos].flags = 0;
- indices[width] = pos;
- width = pos++;
- }
- if (flags & FLAGS_PRECISION_PARAMETER)
- {
- usedEntries[precision] += 1;
- parameters[pos].type = FORMAT_PARAMETER;
- parameters[pos].flags = 0;
- indices[precision] = pos;
- precision = pos++;
- }
- if (flags & FLAGS_BASE_PARAMETER)
- {
- usedEntries[base] += 1;
- parameters[pos].type = FORMAT_PARAMETER;
- parameters[pos].flags = 0;
- indices[base] = pos;
- base = pos++;
- }
- if (flags & FLAGS_VARSIZE_PARAMETER)
- {
- usedEntries[varsize] += 1;
- parameters[pos].type = FORMAT_PARAMETER;
- parameters[pos].flags = 0;
- indices[varsize] = pos;
- varsize = pos++;
- }
-
- indices[currentParam] = pos;
-
- switch (format[index++])
- {
-#if defined(SPECIFIER_CHAR_UPPER)
- case SPECIFIER_CHAR_UPPER:
- flags |= FLAGS_WIDECHAR;
- /* FALLTHROUGH */
-#endif
- case SPECIFIER_CHAR:
- if (flags & FLAGS_LONG)
- flags |= FLAGS_WIDECHAR;
- else if (flags & FLAGS_SHORT)
- flags &= ~FLAGS_WIDECHAR;
- parameters[pos].type = FORMAT_CHAR;
- break;
-
-#if defined(SPECIFIER_STRING_UPPER)
- case SPECIFIER_STRING_UPPER:
- flags |= FLAGS_WIDECHAR;
- /* FALLTHROUGH */
-#endif
- case SPECIFIER_STRING:
- if (flags & FLAGS_LONG)
- flags |= FLAGS_WIDECHAR;
- else if (flags & FLAGS_SHORT)
- flags &= ~FLAGS_WIDECHAR;
- parameters[pos].type = FORMAT_STRING;
- break;
-
- case SPECIFIER_GROUP:
- if (TYPE_SCAN == type)
- {
- int depth = 1;
- parameters[pos].type = FORMAT_GROUP;
- if (format[index] == QUALIFIER_CIRCUMFLEX)
- index++;
- if (format[index] == SPECIFIER_UNGROUP)
- index++;
- if (format[index] == QUALIFIER_MINUS)
- index++;
- /* Skip nested brackets */
- while (format[index] != NIL)
- {
- if (format[index] == SPECIFIER_GROUP)
- {
- depth++;
- }
- else if (format[index] == SPECIFIER_UNGROUP)
- {
- if (--depth <= 0)
- {
- index++;
- break;
- }
- }
- index++;
- }
- }
- break;
-
- case SPECIFIER_INTEGER:
- parameters[pos].type = FORMAT_INT;
- break;
-
- case SPECIFIER_UNSIGNED:
- flags |= FLAGS_UNSIGNED;
- parameters[pos].type = FORMAT_INT;
- break;
-
- case SPECIFIER_DECIMAL:
- /* Disable base modifier */
- flags &= ~FLAGS_BASE_PARAMETER;
- base = BASE_DECIMAL;
- parameters[pos].type = FORMAT_INT;
- break;
-
- case SPECIFIER_OCTAL:
- flags &= ~FLAGS_BASE_PARAMETER;
- base = BASE_OCTAL;
- parameters[pos].type = FORMAT_INT;
- break;
-
-#if defined(SPECIFIER_BINARY)
- case SPECIFIER_BINARY_UPPER:
- flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
- case SPECIFIER_BINARY:
- flags |= FLAGS_NILPADDING;
- flags &= ~FLAGS_BASE_PARAMETER;
- base = BASE_BINARY;
- parameters[pos].type = FORMAT_INT;
- break;
-#endif
-
- case SPECIFIER_HEX_UPPER:
- flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
- case SPECIFIER_HEX:
- flags |= FLAGS_UNSIGNED;
- flags &= ~FLAGS_BASE_PARAMETER;
- base = BASE_HEX;
- parameters[pos].type = FORMAT_INT;
- break;
-
- case SPECIFIER_FLOAT_E_UPPER:
- flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
- case SPECIFIER_FLOAT_E:
- flags |= FLAGS_FLOAT_E;
- parameters[pos].type = FORMAT_DOUBLE;
- break;
-
- case SPECIFIER_FLOAT_G_UPPER:
- flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
- case SPECIFIER_FLOAT_G:
- flags |= FLAGS_FLOAT_G;
- parameters[pos].type = FORMAT_DOUBLE;
- break;
-
- case SPECIFIER_FLOAT_F_UPPER:
- flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
- case SPECIFIER_FLOAT_F:
- parameters[pos].type = FORMAT_DOUBLE;
- break;
-
- case SPECIFIER_POINTER:
- if (sizeof(trio_pointer_t) == sizeof(trio_ulonglong_t))
- flags |= FLAGS_QUAD;
- else if (sizeof(trio_pointer_t) == sizeof(long))
- flags |= FLAGS_LONG;
- parameters[pos].type = FORMAT_POINTER;
- break;
-
- case SPECIFIER_COUNT:
- parameters[pos].type = FORMAT_COUNT;
- break;
-
-#if defined(SPECIFIER_HEXFLOAT)
-# if defined(SPECIFIER_HEXFLOAT_UPPER)
- case SPECIFIER_HEXFLOAT_UPPER:
- flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
-# endif
- case SPECIFIER_HEXFLOAT:
- base = BASE_HEX;
- parameters[pos].type = FORMAT_DOUBLE;
- break;
-#endif
-
-#if defined(FORMAT_ERRNO)
- case SPECIFIER_ERRNO:
- parameters[pos].type = FORMAT_ERRNO;
- break;
-#endif
-
-#if defined(SPECIFIER_USER_DEFINED_BEGIN)
- case SPECIFIER_USER_DEFINED_BEGIN:
- {
- unsigned int max;
- int without_namespace = TRUE;
-
- parameters[pos].type = FORMAT_USER_DEFINED;
- parameters[pos].user_name[0] = NIL;
- tmpformat = (char *)&format[index];
-
- while ((ch = format[index]))
- {
- index++;
- if (ch == SPECIFIER_USER_DEFINED_END)
- {
- if (without_namespace)
- {
- /* We must get the handle first */
- parameters[pos].type = FORMAT_PARAMETER;
- parameters[pos].indexAfterSpecifier = index;
- parameters[pos].flags = FLAGS_USER_DEFINED;
- /* Adjust parameters for insertion of new one */
- pos++;
- usedEntries[currentParam] += 1;
- parameters[pos].type = FORMAT_USER_DEFINED;
- currentParam++;
- indices[currentParam] = pos;
- if (currentParam > maxParam)
- maxParam = currentParam;
- }
- /* Copy the user data */
- max = (unsigned int)(&format[index] - tmpformat);
- if (max > MAX_USER_DATA)
- max = MAX_USER_DATA;
- trio_copy_max(parameters[pos].user_data,
- max,
- tmpformat);
- break; /* while */
- }
- if (ch == SPECIFIER_USER_DEFINED_SEPARATOR)
- {
- without_namespace = FALSE;
- /* Copy the namespace for later looking-up */
- max = (int)(&format[index] - tmpformat);
- if (max > MAX_USER_NAME)
- max = MAX_USER_NAME;
- trio_copy_max(parameters[pos].user_name,
- max,
- tmpformat);
- tmpformat = (char *)&format[index];
- }
- }
- if (ch != SPECIFIER_USER_DEFINED_END)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- }
- break;
-#endif /* defined(SPECIFIER_USER_DEFINED_BEGIN) */
-
- default:
- /* Bail out completely to make the error more obvious */
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- }
-
- /* Count the number of times this entry has been used */
- usedEntries[currentParam] += 1;
-
- /* Find last sticky parameters */
- if (gotSticky && !(flags & FLAGS_STICKY))
- {
- for (i = pos - 1; i >= 0; i--)
- {
- if (parameters[i].type == FORMAT_PARAMETER)
- continue;
- if ((parameters[i].flags & FLAGS_STICKY) &&
- (parameters[i].type == parameters[pos].type))
- {
- /* Do not overwrite current qualifiers */
- flags |= (parameters[i].flags & (unsigned long)~FLAGS_STICKY);
- if (width == NO_WIDTH)
- width = parameters[i].width;
- if (precision == NO_PRECISION)
- precision = parameters[i].precision;
- if (base == NO_BASE)
- base = parameters[i].base;
- break;
- }
- }
- }
-
- parameters[pos].indexAfterSpecifier = index;
- parameters[pos].flags = flags;
- parameters[pos].width = width;
- parameters[pos].precision = precision;
- parameters[pos].base = (base == NO_BASE) ? BASE_DECIMAL : base;
- parameters[pos].varsize = varsize;
- pos++;
-
- if (! positional)
- parameterPosition++;
-
- } /* if identifier */
-
- } /* while format characters left */
-
- for (num = 0; num <= maxParam; num++)
- {
- if (usedEntries[num] != 1)
- {
- if (usedEntries[num] == 0) /* gap detected */
- return TRIO_ERROR_RETURN(TRIO_EGAP, num);
- else /* double references detected */
- return TRIO_ERROR_RETURN(TRIO_EDBLREF, num);
- }
-
- i = indices[num];
-
- /*
- * FORMAT_PARAMETERS are only present if they must be read,
- * so it makes no sense to check the ignore flag (besides,
- * the flags variable is not set for that particular type)
- */
- if ((parameters[i].type != FORMAT_PARAMETER) &&
- (parameters[i].flags & FLAGS_IGNORE))
- continue; /* for all arguments */
-
- /*
- * The stack arguments are read according to ANSI C89
- * default argument promotions:
- *
- * char = int
- * short = int
- * unsigned char = unsigned int
- * unsigned short = unsigned int
- * float = double
- *
- * In addition to the ANSI C89 these types are read (the
- * default argument promotions of C99 has not been
- * considered yet)
- *
- * long long
- * long double
- * size_t
- * ptrdiff_t
- * intmax_t
- */
- switch (parameters[i].type)
- {
- case FORMAT_GROUP:
- case FORMAT_STRING:
-#if TRIO_WIDECHAR
- if (flags & FLAGS_WIDECHAR)
- {
- parameters[i].data.wstring = (argarray == NULL)
- ? va_arg(*arglist, trio_wchar_t *)
- : (trio_wchar_t *)(argarray[num]);
- }
- else
-#endif
- {
- parameters[i].data.string = (argarray == NULL)
- ? va_arg(*arglist, char *)
- : (char *)(argarray[num]);
- }
- break;
-
-#if defined(FORMAT_USER_DEFINED)
- case FORMAT_USER_DEFINED:
-#endif
- case FORMAT_POINTER:
- case FORMAT_COUNT:
- case FORMAT_UNKNOWN:
- parameters[i].data.pointer = (argarray == NULL)
- ? va_arg(*arglist, trio_pointer_t )
- : argarray[num];
- break;
-
- case FORMAT_CHAR:
- case FORMAT_INT:
- if (TYPE_SCAN == type)
- {
- if (argarray == NULL)
- parameters[i].data.pointer =
- (trio_pointer_t)va_arg(*arglist, trio_pointer_t);
- else
- {
- if (parameters[i].type == FORMAT_CHAR)
- parameters[i].data.pointer =
- (trio_pointer_t)((char *)argarray[num]);
- else if (parameters[i].flags & FLAGS_SHORT)
- parameters[i].data.pointer =
- (trio_pointer_t)((short *)argarray[num]);
- else
- parameters[i].data.pointer =
- (trio_pointer_t)((int *)argarray[num]);
- }
- }
- else
- {
-#if defined(QUALIFIER_VARSIZE) || defined(QUALIFIER_FIXED_SIZE)
- if (parameters[i].flags
- & (FLAGS_VARSIZE_PARAMETER | FLAGS_FIXED_SIZE))
- {
- if (parameters[i].flags & FLAGS_VARSIZE_PARAMETER)
- {
- /*
- * Variable sizes are mapped onto the fixed sizes, in
- * accordance with integer promotion.
- *
- * Please note that this may not be portable, as we
- * only guess the size, not the layout of the numbers.
- * For example, if int is little-endian, and long is
- * big-endian, then this will fail.
- */
- varsize = (int)parameters[parameters[i].varsize].data.number.as_unsigned;
- }
- else
- {
- /* Used for the I<bits> modifiers */
- varsize = parameters[i].varsize;
- }
- parameters[i].flags &= ~FLAGS_ALL_VARSIZES;
-
- if (varsize <= (int)sizeof(int))
- ;
- else if (varsize <= (int)sizeof(long))
- parameters[i].flags |= FLAGS_LONG;
-#if defined(QUALIFIER_INTMAX_T)
- else if (varsize <= (int)sizeof(trio_longlong_t))
- parameters[i].flags |= FLAGS_QUAD;
- else
- parameters[i].flags |= FLAGS_INTMAX_T;
-#else
- else
- parameters[i].flags |= FLAGS_QUAD;
-#endif
- }
-#endif /* defined(QUALIFIER_VARSIZE) */
-#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
- if (parameters[i].flags & FLAGS_SIZE_T)
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, size_t)
- : (trio_uintmax_t)(*((size_t *)argarray[num]));
- else
-#endif
-#if defined(QUALIFIER_PTRDIFF_T)
- if (parameters[i].flags & FLAGS_PTRDIFF_T)
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, ptrdiff_t)
- : (trio_uintmax_t)(*((ptrdiff_t *)argarray[num]));
- else
-#endif
-#if defined(QUALIFIER_INTMAX_T)
- if (parameters[i].flags & FLAGS_INTMAX_T)
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, trio_intmax_t)
- : (trio_uintmax_t)(*((trio_intmax_t *)argarray[num]));
- else
-#endif
- if (parameters[i].flags & FLAGS_QUAD)
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, trio_ulonglong_t)
- : (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num]));
- else if (parameters[i].flags & FLAGS_LONG)
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, long)
- : (trio_uintmax_t)(*((long *)argarray[num]));
- else
- {
- if (argarray == NULL)
- parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(*arglist, int);
- else
- {
- if (parameters[i].type == FORMAT_CHAR)
- parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((char *)argarray[num]));
- else if (parameters[i].flags & FLAGS_SHORT)
- parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((short *)argarray[num]));
- else
- parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((int *)argarray[num]));
- }
- }
- }
- break;
-
- case FORMAT_PARAMETER:
- /*
- * The parameter for the user-defined specifier is a pointer,
- * whereas the rest (width, precision, base) uses an integer.
- */
- if (parameters[i].flags & FLAGS_USER_DEFINED)
- parameters[i].data.pointer = (argarray == NULL)
- ? va_arg(*arglist, trio_pointer_t )
- : argarray[num];
- else
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, int)
- : (trio_uintmax_t)(*((int *)argarray[num]));
- break;
-
- case FORMAT_DOUBLE:
- if (TYPE_SCAN == type)
- {
- if (parameters[i].flags & FLAGS_LONGDOUBLE)
- parameters[i].data.longdoublePointer = (argarray == NULL)
- ? va_arg(*arglist, trio_long_double_t *)
- : (trio_long_double_t *)argarray[num];
- else
- {
- if (parameters[i].flags & FLAGS_LONG)
- parameters[i].data.doublePointer = (argarray == NULL)
- ? va_arg(*arglist, double *)
- : (double *)argarray[num];
- else
- parameters[i].data.doublePointer = (argarray == NULL)
- ? (double *)va_arg(*arglist, float *)
- : (double *)((float *)argarray[num]);
- }
- }
- else
- {
- if (parameters[i].flags & FLAGS_LONGDOUBLE)
- parameters[i].data.longdoubleNumber = (argarray == NULL)
- ? va_arg(*arglist, trio_long_double_t)
- : (trio_long_double_t)(*((trio_long_double_t *)argarray[num]));
- else
- {
- if (argarray == NULL)
- parameters[i].data.longdoubleNumber =
- (trio_long_double_t)va_arg(*arglist, double);
- else
- {
- if (parameters[i].flags & FLAGS_SHORT)
- parameters[i].data.longdoubleNumber =
- (trio_long_double_t)(*((float *)argarray[num]));
- else
- parameters[i].data.longdoubleNumber =
- (trio_long_double_t)(*((double *)argarray[num]));
- }
- }
- }
- break;
-
-#if defined(FORMAT_ERRNO)
- case FORMAT_ERRNO:
- parameters[i].data.errorNumber = save_errno;
- break;
-#endif
-
- default:
- break;
- }
- } /* for all specifiers */
- return num;
-}
-
-
-/*************************************************************************
- *
- * FORMATTING
- *
- ************************************************************************/
-
-
-/*************************************************************************
- * TrioWriteNumber
- *
- * Description:
- * Output a number.
- * The complexity of this function is a result of the complexity
- * of the dependencies of the flags.
- */
-TRIO_PRIVATE void
-TrioWriteNumber
-TRIO_ARGS6((self, number, flags, width, precision, base),
- trio_class_t *self,
- trio_uintmax_t number,
- unsigned long flags,
- int width,
- int precision,
- int base)
-{
- BOOLEAN_T isNegative;
- char buffer[MAX_CHARS_IN(trio_uintmax_t) * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1];
- char *bufferend;
- char *pointer;
- TRIO_CONST char *digits;
- int i;
- int length;
- char *p;
- int count;
-
- assert(VALID(self));
- assert(VALID(self->OutStream));
- assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE));
-
- digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower;
- if (base == NO_BASE)
- base = BASE_DECIMAL;
-
- isNegative = (flags & FLAGS_UNSIGNED)
- ? FALSE
- : ((trio_intmax_t)number < 0);
- if (isNegative)
- number = -((trio_intmax_t)number);
-
- if (flags & FLAGS_QUAD)
- number &= (trio_ulonglong_t)-1;
- else if (flags & FLAGS_LONG)
- number &= (unsigned long)-1;
- else
- number &= (unsigned int)-1;
-
- /* Build number */
- pointer = bufferend = &buffer[sizeof(buffer) - 1];
- *pointer-- = NIL;
- for (i = 1; i < (int)sizeof(buffer); i++)
- {
- *pointer-- = digits[number % base];
- number /= base;
- if (number == 0)
- break;
-
- if ((flags & FLAGS_QUOTE) && TrioFollowedBySeparator(i + 1))
- {
- /*
- * We are building the number from the least significant
- * to the most significant digit, so we have to copy the
- * thousand separator backwards
- */
- length = internalThousandSeparatorLength;
- if (((int)(pointer - buffer) - length) > 0)
- {
- p = &internalThousandSeparator[length - 1];
- while (length-- > 0)
- *pointer-- = *p--;
- }
- }
- }
-
- /* Adjust width */
- width -= (bufferend - pointer) - 1;
-
- /* Adjust precision */
- if (NO_PRECISION != precision)
- {
- precision -= (bufferend - pointer) - 1;
- if (precision < 0)
- precision = 0;
- flags |= FLAGS_NILPADDING;
- }
-
- /* Adjust width further */
- if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE))
- width--;
- if (flags & FLAGS_ALTERNATIVE)
- {
- switch (base)
- {
- case BASE_BINARY:
- case BASE_HEX:
- width -= 2;
- break;
- case BASE_OCTAL:
- width--;
- break;
- default:
- break;
- }
- }
-
- /* Output prefixes spaces if needed */
- if (! ((flags & FLAGS_LEFTADJUST) ||
- ((flags & FLAGS_NILPADDING) && (precision == NO_PRECISION))))
- {
- count = (precision == NO_PRECISION) ? 0 : precision;
- while (width-- > count)
- self->OutStream(self, CHAR_ADJUST);
- }
-
- /* width has been adjusted for signs and alternatives */
- if (isNegative)
- self->OutStream(self, '-');
- else if (flags & FLAGS_SHOWSIGN)
- self->OutStream(self, '+');
- else if (flags & FLAGS_SPACE)
- self->OutStream(self, ' ');
-
- if (flags & FLAGS_ALTERNATIVE)
- {
- switch (base)
- {
- case BASE_BINARY:
- self->OutStream(self, '0');
- self->OutStream(self, (flags & FLAGS_UPPER) ? 'B' : 'b');
- break;
-
- case BASE_OCTAL:
- self->OutStream(self, '0');
- break;
-
- case BASE_HEX:
- self->OutStream(self, '0');
- self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
- break;
-
- default:
- break;
- } /* switch base */
- }
-
- /* Output prefixed zero padding if needed */
- if (flags & FLAGS_NILPADDING)
- {
- if (precision == NO_PRECISION)
- precision = width;
- while (precision-- > 0)
- {
- self->OutStream(self, '0');
- width--;
- }
- }
-
- /* Output the number itself */
- while (*(++pointer))
- {
- self->OutStream(self, *pointer);
- }
-
- /* Output trailing spaces if needed */
- if (flags & FLAGS_LEFTADJUST)
- {
- while (width-- > 0)
- self->OutStream(self, CHAR_ADJUST);
- }
-}
-
-/*************************************************************************
- * TrioWriteStringCharacter
- *
- * Description:
- * Output a single character of a string
- */
-TRIO_PRIVATE void
-TrioWriteStringCharacter
-TRIO_ARGS3((self, ch, flags),
- trio_class_t *self,
- int ch,
- unsigned long flags)
-{
- if (flags & FLAGS_ALTERNATIVE)
- {
- if (! isprint(ch))
- {
- /*
- * Non-printable characters are converted to C escapes or
- * \number, if no C escape exists.
- */
- self->OutStream(self, CHAR_BACKSLASH);
- switch (ch)
- {
- case '\007': self->OutStream(self, 'a'); break;
- case '\b': self->OutStream(self, 'b'); break;
- case '\f': self->OutStream(self, 'f'); break;
- case '\n': self->OutStream(self, 'n'); break;
- case '\r': self->OutStream(self, 'r'); break;
- case '\t': self->OutStream(self, 't'); break;
- case '\v': self->OutStream(self, 'v'); break;
- case '\\': self->OutStream(self, '\\'); break;
- default:
- self->OutStream(self, 'x');
- TrioWriteNumber(self, (trio_uintmax_t)ch,
- FLAGS_UNSIGNED | FLAGS_NILPADDING,
- 2, 2, BASE_HEX);
- break;
- }
- }
- else if (ch == CHAR_BACKSLASH)
- {
- self->OutStream(self, CHAR_BACKSLASH);
- self->OutStream(self, CHAR_BACKSLASH);
- }
- else
- {
- self->OutStream(self, ch);
- }
- }
- else
- {
- self->OutStream(self, ch);
- }
-}
-
-/*************************************************************************
- * TrioWriteString
- *
- * Description:
- * Output a string
- */
-TRIO_PRIVATE void
-TrioWriteString
-TRIO_ARGS5((self, string, flags, width, precision),
- trio_class_t *self,
- TRIO_CONST char *string,
- unsigned long flags,
- int width,
- int precision)
-{
- int length;
- int ch;
-
- assert(VALID(self));
- assert(VALID(self->OutStream));
-
- if (string == NULL)
- {
- string = internalNullString;
- length = sizeof(internalNullString) - 1;
- /* Disable quoting for the null pointer */
- flags &= (~FLAGS_QUOTE);
- width = 0;
- }
- else
- {
- length = trio_length(string);
- }
- if ((NO_PRECISION != precision) &&
- (precision < length))
- {
- length = precision;
- }
- width -= length;
-
- if (flags & FLAGS_QUOTE)
- self->OutStream(self, CHAR_QUOTE);
-
- if (! (flags & FLAGS_LEFTADJUST))
- {
- while (width-- > 0)
- self->OutStream(self, CHAR_ADJUST);
- }
-
- while (length-- > 0)
- {
- /* The ctype parameters must be an unsigned char (or EOF) */
- ch = (int)((unsigned char)(*string++));
- TrioWriteStringCharacter(self, ch, flags);
- }
-
- if (flags & FLAGS_LEFTADJUST)
- {
- while (width-- > 0)
- self->OutStream(self, CHAR_ADJUST);
- }
- if (flags & FLAGS_QUOTE)
- self->OutStream(self, CHAR_QUOTE);
-}
-
-/*************************************************************************
- * TrioWriteWideStringCharacter
- *
- * Description:
- * Output a wide string as a multi-byte sequence
- */
-#if TRIO_WIDECHAR
-TRIO_PRIVATE int
-TrioWriteWideStringCharacter
-TRIO_ARGS4((self, wch, flags, width),
- trio_class_t *self,
- trio_wchar_t wch,
- unsigned long flags,
- int width)
-{
- int size;
- int i;
- int ch;
- char *string;
- char buffer[MB_LEN_MAX + 1];
-
- if (width == NO_WIDTH)
- width = sizeof(buffer);
-
- size = wctomb(buffer, wch);
- if ((size <= 0) || (size > width) || (buffer[0] == NIL))
- return 0;
-
- string = buffer;
- i = size;
- while ((width >= i) && (width-- > 0) && (i-- > 0))
- {
- /* The ctype parameters must be an unsigned char (or EOF) */
- ch = (int)((unsigned char)(*string++));
- TrioWriteStringCharacter(self, ch, flags);
- }
- return size;
-}
-#endif /* TRIO_WIDECHAR */
-
-/*************************************************************************
- * TrioWriteWideString
- *
- * Description:
- * Output a wide character string as a multi-byte string
- */
-#if TRIO_WIDECHAR
-TRIO_PRIVATE void
-TrioWriteWideString
-TRIO_ARGS5((self, wstring, flags, width, precision),
- trio_class_t *self,
- TRIO_CONST trio_wchar_t *wstring,
- unsigned long flags,
- int width,
- int precision)
-{
- int length;
- int size;
-
- assert(VALID(self));
- assert(VALID(self->OutStream));
-
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- (void)mblen(NULL, 0);
-#endif
-
- if (wstring == NULL)
- {
- TrioWriteString(self, NULL, flags, width, precision);
- return;
- }
-
- if (NO_PRECISION == precision)
- {
- length = INT_MAX;
- }
- else
- {
- length = precision;
- width -= length;
- }
-
- if (flags & FLAGS_QUOTE)
- self->OutStream(self, CHAR_QUOTE);
-
- if (! (flags & FLAGS_LEFTADJUST))
- {
- while (width-- > 0)
- self->OutStream(self, CHAR_ADJUST);
- }
-
- while (length > 0)
- {
- size = TrioWriteWideStringCharacter(self, *wstring++, flags, length);
- if (size == 0)
- break; /* while */
- length -= size;
- }
-
- if (flags & FLAGS_LEFTADJUST)
- {
- while (width-- > 0)
- self->OutStream(self, CHAR_ADJUST);
- }
- if (flags & FLAGS_QUOTE)
- self->OutStream(self, CHAR_QUOTE);
-}
-#endif /* TRIO_WIDECHAR */
-
-/*************************************************************************
- * TrioWriteDouble
- *
- * http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_211.htm
- *
- * "5.2.4.2.2 paragraph #4
- *
- * The accuracy [...] is implementation defined, as is the accuracy
- * of the conversion between floating-point internal representations
- * and string representations performed by the libray routine in
- * <stdio.h>"
- */
-/* FIXME: handle all instances of constant long-double number (L)
- * and *l() math functions.
- */
-TRIO_PRIVATE void
-TrioWriteDouble
-TRIO_ARGS6((self, number, flags, width, precision, base),
- trio_class_t *self,
- trio_long_double_t number,
- unsigned long flags,
- int width,
- int precision,
- int base)
-{
- trio_long_double_t integerNumber;
- trio_long_double_t fractionNumber;
- trio_long_double_t workNumber;
- int integerDigits;
- int fractionDigits;
- int exponentDigits;
- int baseDigits;
- int integerThreshold;
- int fractionThreshold;
- int expectedWidth;
- int exponent = 0;
- unsigned int uExponent = 0;
- int exponentBase;
- trio_long_double_t dblBase;
- trio_long_double_t dblIntegerBase;
- trio_long_double_t dblFractionBase;
- trio_long_double_t integerAdjust;
- trio_long_double_t fractionAdjust;
- BOOLEAN_T isNegative;
- BOOLEAN_T isExponentNegative = FALSE;
- BOOLEAN_T requireTwoDigitExponent;
- BOOLEAN_T isHex;
- TRIO_CONST char *digits;
- char *groupingPointer;
- int i;
- int index;
- BOOLEAN_T hasOnlyZeroes;
- int zeroes = 0;
- register int trailingZeroes;
- BOOLEAN_T keepTrailingZeroes;
- BOOLEAN_T keepDecimalPoint;
- trio_long_double_t epsilon;
-
- assert(VALID(self));
- assert(VALID(self->OutStream));
- assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE));
-
- /* Determine sign and look for special quantities */
- switch (trio_fpclassify_and_signbit(number, &isNegative))
- {
- case TRIO_FP_NAN:
- TrioWriteString(self,
- (flags & FLAGS_UPPER)
- ? NAN_UPPER
- : NAN_LOWER,
- flags, width, precision);
- return;
-
- case TRIO_FP_INFINITE:
- if (isNegative)
- {
- /* Negative infinity */
- TrioWriteString(self,
- (flags & FLAGS_UPPER)
- ? "-" INFINITE_UPPER
- : "-" INFINITE_LOWER,
- flags, width, precision);
- return;
- }
- else
- {
- /* Positive infinity */
- TrioWriteString(self,
- (flags & FLAGS_UPPER)
- ? INFINITE_UPPER
- : INFINITE_LOWER,
- flags, width, precision);
- return;
- }
-
- default:
- /* Finitude */
- break;
- }
-
- /* Normal numbers */
- if (flags & FLAGS_LONGDOUBLE)
- {
- baseDigits = (base == 10)
- ? LDBL_DIG
- : (int)floor(LDBL_MANT_DIG / TrioLogarithmBase(base));
- epsilon = LDBL_EPSILON;
- }
- else if (flags & FLAGS_SHORT)
- {
- baseDigits = (base == BASE_DECIMAL)
- ? FLT_DIG
- : (int)floor(FLT_MANT_DIG / TrioLogarithmBase(base));
- epsilon = FLT_EPSILON;
- }
- else
- {
- baseDigits = (base == BASE_DECIMAL)
- ? DBL_DIG
- : (int)floor(DBL_MANT_DIG / TrioLogarithmBase(base));
- epsilon = DBL_EPSILON;
- }
-
- digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower;
- isHex = (base == BASE_HEX);
- if (base == NO_BASE)
- base = BASE_DECIMAL;
- dblBase = (trio_long_double_t)base;
- keepTrailingZeroes = !( (flags & FLAGS_ROUNDING) ||
- ( (flags & FLAGS_FLOAT_G) &&
- !(flags & FLAGS_ALTERNATIVE) ) );
-
- if (flags & FLAGS_ROUNDING)
- precision = baseDigits;
-
- if (precision == NO_PRECISION)
- precision = FLT_DIG;
-
- if (isNegative)
- number = -number;
-
- if (isHex)
- flags |= FLAGS_FLOAT_E;
-
- if (flags & FLAGS_FLOAT_G)
- {
- if (precision == 0)
- precision = 1;
-
- if ((number < 1.0E-4) || (number > powl(base,
- (trio_long_double_t)precision)))
- {
- /* Use scientific notation */
- flags |= FLAGS_FLOAT_E;
- }
- else if (number < 1.0)
- {
- /*
- * Use normal notation. If the integer part of the number is
- * zero, then adjust the precision to include leading fractional
- * zeros.
- */
- workNumber = TrioLogarithm(number, base);
- workNumber = TRIO_FABS(workNumber);
- if (workNumber - floorl(workNumber) < 0.001)
- workNumber--;
- zeroes = (int)floorl(workNumber);
- }
- }
-
- if (flags & FLAGS_FLOAT_E)
- {
- /* Scale the number */
- workNumber = TrioLogarithm(number, base);
- if (trio_isinf(workNumber) == -1)
- {
- exponent = 0;
- /* Undo setting */
- if (flags & FLAGS_FLOAT_G)
- flags &= ~FLAGS_FLOAT_E;
- }
- else
- {
- exponent = (int)floorl(workNumber);
- number /= powl(dblBase, (trio_long_double_t)exponent);
- isExponentNegative = (exponent < 0);
- uExponent = (isExponentNegative) ? -exponent : exponent;
- /* No thousand separators */
- flags &= ~FLAGS_QUOTE;
- }
- }
-
- integerNumber = floorl(number);
- fractionNumber = number - integerNumber;
-
- /*
- * Truncated number.
- *
- * Precision is number of significant digits for FLOAT_G
- * and number of fractional digits for others.
- */
- integerDigits = (integerNumber > epsilon)
- ? 1 + (int)TrioLogarithm(integerNumber, base)
- : 1;
- fractionDigits = ((flags & FLAGS_FLOAT_G) && (zeroes == 0))
- ? precision - integerDigits
- : zeroes + precision;
-
- dblFractionBase = TrioPower(base, fractionDigits);
-
- workNumber = number + 0.5 / dblFractionBase;
- if (floorl(number) != floorl(workNumber))
- {
- if (flags & FLAGS_FLOAT_E)
- {
- /* Adjust if number was rounded up one digit (ie. 0.99 to 1.00) */
- exponent++;
- isExponentNegative = (exponent < 0);
- uExponent = (isExponentNegative) ? -exponent : exponent;
- workNumber = (number + 0.5 / dblFractionBase) / dblBase;
- integerNumber = floorl(workNumber);
- fractionNumber = workNumber - integerNumber;
- }
- else
- {
- /* Adjust if number was rounded up one digit (ie. 99 to 100) */
- integerNumber = floorl(number + 0.5);
- fractionNumber = 0.0;
- integerDigits = (integerNumber > epsilon)
- ? 1 + (int)TrioLogarithm(integerNumber, base)
- : 1;
- }
- }
-
- /* Estimate accuracy */
- integerAdjust = fractionAdjust = 0.5;
- if (flags & FLAGS_ROUNDING)
- {
- if (integerDigits > baseDigits)
- {
- integerThreshold = baseDigits;
- fractionDigits = 0;
- dblFractionBase = 1.0;
- fractionThreshold = 0;
- precision = 0; /* Disable decimal-point */
- integerAdjust = TrioPower(base, integerDigits - integerThreshold - 1);
- fractionAdjust = 0.0;
- }
- else
- {
- integerThreshold = integerDigits;
- fractionThreshold = fractionDigits - integerThreshold;
- fractionAdjust = 1.0;
- }
- }
- else
- {
- integerThreshold = INT_MAX;
- fractionThreshold = INT_MAX;
- }
-
- /*
- * Calculate expected width.
- * sign + integer part + thousands separators + decimal point
- * + fraction + exponent
- */
- fractionAdjust /= dblFractionBase;
- hasOnlyZeroes = (floorl((fractionNumber + fractionAdjust) * dblFractionBase) < epsilon);
- keepDecimalPoint = ( (flags & FLAGS_ALTERNATIVE) ||
- !((precision == 0) ||
- (!keepTrailingZeroes && hasOnlyZeroes)) );
- if (flags & FLAGS_FLOAT_E)
- {
- exponentDigits = (uExponent == 0)
- ? 1
- : (int)ceil(TrioLogarithm((double)(uExponent + 1), base));
- }
- else
- exponentDigits = 0;
- requireTwoDigitExponent = ((base == BASE_DECIMAL) && (exponentDigits == 1));
-
- expectedWidth = integerDigits + fractionDigits
- + (keepDecimalPoint
- ? internalDecimalPointLength
- : 0)
- + ((flags & FLAGS_QUOTE)
- ? TrioCalcThousandSeparatorLength(integerDigits)
- : 0);
- if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE))
- expectedWidth += sizeof("-") - 1;
- if (exponentDigits > 0)
- expectedWidth += exponentDigits +
- ((requireTwoDigitExponent ? sizeof("E+0") : sizeof("E+")) - 1);
- if (isHex)
- expectedWidth += sizeof("0X") - 1;
-
- /* Output prefixing */
- if (flags & FLAGS_NILPADDING)
- {
- /* Leading zeros must be after sign */
- if (isNegative)
- self->OutStream(self, '-');
- else if (flags & FLAGS_SHOWSIGN)
- self->OutStream(self, '+');
- else if (flags & FLAGS_SPACE)
- self->OutStream(self, ' ');
- if (isHex)
- {
- self->OutStream(self, '0');
- self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
- }
- if (!(flags & FLAGS_LEFTADJUST))
- {
- for (i = expectedWidth; i < width; i++)
- {
- self->OutStream(self, '0');
- }
- }
- }
- else
- {
- /* Leading spaces must be before sign */
- if (!(flags & FLAGS_LEFTADJUST))
- {
- for (i = expectedWidth; i < width; i++)
- {
- self->OutStream(self, CHAR_ADJUST);
- }
- }
- if (isNegative)
- self->OutStream(self, '-');
- else if (flags & FLAGS_SHOWSIGN)
- self->OutStream(self, '+');
- else if (flags & FLAGS_SPACE)
- self->OutStream(self, ' ');
- if (isHex)
- {
- self->OutStream(self, '0');
- self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
- }
- }
-
- /* Output the integer part and thousand separators */
- dblIntegerBase = 1.0 / TrioPower(base, integerDigits - 1);
- for (i = 0; i < integerDigits; i++)
- {
- workNumber = floorl(((integerNumber + integerAdjust) * dblIntegerBase));
- if (i > integerThreshold)
- {
- /* Beyond accuracy */
- self->OutStream(self, digits[0]);
- }
- else
- {
- self->OutStream(self, digits[(int)fmodl(workNumber, dblBase)]);
- }
- dblIntegerBase *= dblBase;
-
- if (((flags & (FLAGS_FLOAT_E | FLAGS_QUOTE)) == FLAGS_QUOTE)
- && TrioFollowedBySeparator(integerDigits - i))
- {
- for (groupingPointer = internalThousandSeparator;
- *groupingPointer != NIL;
- groupingPointer++)
- {
- self->OutStream(self, *groupingPointer);
- }
- }
- }
-
- /* Insert decimal point and build the fraction part */
- trailingZeroes = 0;
-
- if (keepDecimalPoint)
- {
- if (internalDecimalPoint)
- {
- self->OutStream(self, internalDecimalPoint);
- }
- else
- {
- for (i = 0; i < internalDecimalPointLength; i++)
- {
- self->OutStream(self, internalDecimalPointString[i]);
- }
- }
- }
-
- for (i = 0; i < fractionDigits; i++)
- {
- if ((integerDigits > integerThreshold) || (i > fractionThreshold))
- {
- /* Beyond accuracy */
- trailingZeroes++;
- }
- else
- {
- fractionNumber *= dblBase;
- fractionAdjust *= dblBase;
- workNumber = floorl(fractionNumber + fractionAdjust);
- fractionNumber -= workNumber;
- index = (int)fmodl(workNumber, dblBase);
- if (index == 0)
- {
- trailingZeroes++;
- }
- else
- {
- while (trailingZeroes > 0)
- {
- /* Not trailing zeroes after all */
- self->OutStream(self, digits[0]);
- trailingZeroes--;
- }
- self->OutStream(self, digits[index]);
- }
- }
- }
-
- if (keepTrailingZeroes)
- {
- while (trailingZeroes > 0)
- {
- self->OutStream(self, digits[0]);
- trailingZeroes--;
- }
- }
-
- /* Output exponent */
- if (exponentDigits > 0)
- {
- self->OutStream(self,
- isHex
- ? ((flags & FLAGS_UPPER) ? 'P' : 'p')
- : ((flags & FLAGS_UPPER) ? 'E' : 'e'));
- self->OutStream(self, (isExponentNegative) ? '-' : '+');
-
- /* The exponent must contain at least two digits */
- if (requireTwoDigitExponent)
- self->OutStream(self, '0');
-
- exponentBase = (int)TrioPower(base, exponentDigits - 1);
- for (i = 0; i < exponentDigits; i++)
- {
- self->OutStream(self, digits[(uExponent / exponentBase) % base]);
- exponentBase /= base;
- }
- }
- /* Output trailing spaces */
- if (flags & FLAGS_LEFTADJUST)
- {
- for (i = expectedWidth; i < width; i++)
- {
- self->OutStream(self, CHAR_ADJUST);
- }
- }
-}
-
-/*************************************************************************
- * TrioFormatProcess
- *
- * Description:
- * This is the main engine for formatting output
- */
-TRIO_PRIVATE int
-TrioFormatProcess
-TRIO_ARGS3((data, format, parameters),
- trio_class_t *data,
- TRIO_CONST char *format,
- trio_parameter_t *parameters)
-{
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- int charlen;
-#endif
- int i;
- TRIO_CONST char *string;
- trio_pointer_t pointer;
- unsigned long flags;
- int width;
- int precision;
- int base;
- int index;
-
- index = 0;
- i = 0;
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- (void)mblen(NULL, 0);
-#endif
-
- while (format[index])
- {
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- if (! isascii(format[index]))
- {
- charlen = mblen(&format[index], MB_LEN_MAX);
- /*
- * Only valid multibyte characters are handled here. Invalid
- * multibyte characters (charlen == -1) are handled as normal
- * characters.
- */
- if (charlen != -1)
- {
- while (charlen-- > 0)
- {
- data->OutStream(data, format[index++]);
- }
- continue; /* while characters left in formatting string */
- }
- }
-#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
- if (CHAR_IDENTIFIER == format[index])
- {
- if (CHAR_IDENTIFIER == format[index + 1])
- {
- data->OutStream(data, CHAR_IDENTIFIER);
- index += 2;
- }
- else
- {
- /* Skip the parameter entries */
- while (parameters[i].type == FORMAT_PARAMETER)
- i++;
-
- flags = parameters[i].flags;
-
- /* Find width */
- width = parameters[i].width;
- if (flags & FLAGS_WIDTH_PARAMETER)
- {
- /* Get width from parameter list */
- width = (int)parameters[width].data.number.as_signed;
- }
-
- /* Find precision */
- if (flags & FLAGS_PRECISION)
- {
- precision = parameters[i].precision;
- if (flags & FLAGS_PRECISION_PARAMETER)
- {
- /* Get precision from parameter list */
- precision = (int)parameters[precision].data.number.as_signed;
- }
- }
- else
- {
- precision = NO_PRECISION;
- }
-
- /* Find base */
- base = parameters[i].base;
- if (flags & FLAGS_BASE_PARAMETER)
- {
- /* Get base from parameter list */
- base = (int)parameters[base].data.number.as_signed;
- }
-
- switch (parameters[i].type)
- {
- case FORMAT_CHAR:
- if (flags & FLAGS_QUOTE)
- data->OutStream(data, CHAR_QUOTE);
- if (! (flags & FLAGS_LEFTADJUST))
- {
- while (--width > 0)
- data->OutStream(data, CHAR_ADJUST);
- }
-#if TRIO_WIDECHAR
- if (flags & FLAGS_WIDECHAR)
- {
- TrioWriteWideStringCharacter(data,
- (trio_wchar_t)parameters[i].data.number.as_signed,
- flags,
- NO_WIDTH);
- }
- else
-#endif
- {
- TrioWriteStringCharacter(data,
- (int)parameters[i].data.number.as_signed,
- flags);
- }
-
- if (flags & FLAGS_LEFTADJUST)
- {
- while(--width > 0)
- data->OutStream(data, CHAR_ADJUST);
- }
- if (flags & FLAGS_QUOTE)
- data->OutStream(data, CHAR_QUOTE);
-
- break; /* FORMAT_CHAR */
-
- case FORMAT_INT:
- TrioWriteNumber(data,
- parameters[i].data.number.as_unsigned,
- flags,
- width,
- precision,
- base);
-
- break; /* FORMAT_INT */
-
- case FORMAT_DOUBLE:
- TrioWriteDouble(data,
- parameters[i].data.longdoubleNumber,
- flags,
- width,
- precision,
- base);
- break; /* FORMAT_DOUBLE */
-
- case FORMAT_STRING:
-#if TRIO_WIDECHAR
- if (flags & FLAGS_WIDECHAR)
- {
- TrioWriteWideString(data,
- parameters[i].data.wstring,
- flags,
- width,
- precision);
- }
- else
-#endif
- {
- TrioWriteString(data,
- parameters[i].data.string,
- flags,
- width,
- precision);
- }
- break; /* FORMAT_STRING */
-
- case FORMAT_POINTER:
- {
- trio_reference_t reference;
-
- reference.data = data;
- reference.parameter = &parameters[i];
- trio_print_pointer(&reference, parameters[i].data.pointer);
- }
- break; /* FORMAT_POINTER */
-
- case FORMAT_COUNT:
- pointer = parameters[i].data.pointer;
- if (NULL != pointer)
- {
- /*
- * C99 paragraph 7.19.6.1.8 says "the number of
- * characters written to the output stream so far by
- * this call", which is data->committed
- */
-#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
- if (flags & FLAGS_SIZE_T)
- *(size_t *)pointer = (size_t)data->committed;
- else
-#endif
-#if defined(QUALIFIER_PTRDIFF_T)
- if (flags & FLAGS_PTRDIFF_T)
- *(ptrdiff_t *)pointer = (ptrdiff_t)data->committed;
- else
-#endif
-#if defined(QUALIFIER_INTMAX_T)
- if (flags & FLAGS_INTMAX_T)
- *(trio_intmax_t *)pointer = (trio_intmax_t)data->committed;
- else
-#endif
- if (flags & FLAGS_QUAD)
- {
- *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->committed;
- }
- else if (flags & FLAGS_LONG)
- {
- *(long int *)pointer = (long int)data->committed;
- }
- else if (flags & FLAGS_SHORT)
- {
- *(short int *)pointer = (short int)data->committed;
- }
- else
- {
- *(int *)pointer = (int)data->committed;
- }
- }
- break; /* FORMAT_COUNT */
-
- case FORMAT_PARAMETER:
- break; /* FORMAT_PARAMETER */
-
-#if defined(FORMAT_ERRNO)
- case FORMAT_ERRNO:
- string = trio_error(parameters[i].data.errorNumber);
- if (string)
- {
- TrioWriteString(data,
- string,
- flags,
- width,
- precision);
- }
- else
- {
- data->OutStream(data, '#');
- TrioWriteNumber(data,
- (trio_uintmax_t)parameters[i].data.errorNumber,
- flags,
- width,
- precision,
- BASE_DECIMAL);
- }
- break; /* FORMAT_ERRNO */
-#endif /* defined(FORMAT_ERRNO) */
-
-#if defined(FORMAT_USER_DEFINED)
- case FORMAT_USER_DEFINED:
- {
- trio_reference_t reference;
- trio_userdef_t *def = NULL;
-
- if (parameters[i].user_name[0] == NIL)
- {
- /* Use handle */
- if ((i > 0) ||
- (parameters[i - 1].type == FORMAT_PARAMETER))
- def = (trio_userdef_t *)parameters[i - 1].data.pointer;
- }
- else
- {
- /* Look up namespace */
- def = TrioFindNamespace(parameters[i].user_name, NULL);
- }
- if (def) {
- reference.data = data;
- reference.parameter = &parameters[i];
- def->callback(&reference);
- }
- }
- break;
-#endif /* defined(FORMAT_USER_DEFINED) */
-
- default:
- break;
- } /* switch parameter type */
-
- /* Prepare for next */
- index = parameters[i].indexAfterSpecifier;
- i++;
- }
- }
- else /* not identifier */
- {
- data->OutStream(data, format[index++]);
- }
- }
- return data->processed;
-}
-
-/*************************************************************************
- * TrioFormatRef
- */
-TRIO_PRIVATE int
-TrioFormatRef
-TRIO_ARGS4((reference, format, arglist, argarray),
- trio_reference_t *reference,
- TRIO_CONST char *format,
- va_list *arglist,
- trio_pointer_t *argarray)
-{
- int status;
- trio_parameter_t parameters[MAX_PARAMETERS];
-
- status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray);
- if (status < 0)
- return status;
-
- status = TrioFormatProcess(reference->data, format, parameters);
- if (reference->data->error != 0)
- {
- status = reference->data->error;
- }
- return status;
-}
-
-/*************************************************************************
- * TrioFormat
- */
-TRIO_PRIVATE int
-TrioFormat
-TRIO_ARGS6((destination, destinationSize, OutStream, format, arglist, argarray),
- trio_pointer_t destination,
- size_t destinationSize,
- void (*OutStream) TRIO_PROTO((trio_class_t *, int)),
- TRIO_CONST char *format,
- va_list *arglist,
- trio_pointer_t *argarray)
-{
- int status;
- trio_class_t data;
- trio_parameter_t parameters[MAX_PARAMETERS];
-
- assert(VALID(OutStream));
- assert(VALID(format));
-
- memset(&data, 0, sizeof(data));
- data.OutStream = OutStream;
- data.location = destination;
- data.max = destinationSize;
- data.error = 0;
-
-#if defined(USE_LOCALE)
- if (NULL == internalLocaleValues)
- {
- TrioSetLocale();
- }
-#endif
-
- status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray);
- if (status < 0)
- return status;
-
- status = TrioFormatProcess(&data, format, parameters);
- if (data.error != 0)
- {
- status = data.error;
- }
- return status;
-}
-
-/*************************************************************************
- * TrioOutStreamFile
- */
-TRIO_PRIVATE void
-TrioOutStreamFile
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- FILE *file;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- file = (FILE *)self->location;
- self->processed++;
- if (fputc(output, file) == EOF)
- {
- self->error = TRIO_ERROR_RETURN(TRIO_EOF, 0);
- }
- else
- {
- self->committed++;
- }
-}
-
-/*************************************************************************
- * TrioOutStreamFileDescriptor
- */
-TRIO_PRIVATE void
-TrioOutStreamFileDescriptor
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- int fd;
- char ch;
-
- assert(VALID(self));
-
- fd = *((int *)self->location);
- ch = (char)output;
- self->processed++;
- if (write(fd, &ch, sizeof(char)) == -1)
- {
- self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0);
- }
- else
- {
- self->committed++;
- }
-}
-
-/*************************************************************************
- * TrioOutStreamCustom
- */
-TRIO_PRIVATE void
-TrioOutStreamCustom
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- int status;
- trio_custom_t *data;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- data = (trio_custom_t *)self->location;
- if (data->stream.out)
- {
- status = (data->stream.out)(data->closure, output);
- if (status >= 0)
- {
- self->committed++;
- }
- else
- {
- if (self->error == 0)
- {
- self->error = TRIO_ERROR_RETURN(TRIO_ECUSTOM, -status);
- }
- }
- }
- self->processed++;
-}
-
-/*************************************************************************
- * TrioOutStreamString
- */
-TRIO_PRIVATE void
-TrioOutStreamString
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- char **buffer;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- buffer = (char **)self->location;
- **buffer = (char)output;
- (*buffer)++;
- self->processed++;
- self->committed++;
-}
-
-/*************************************************************************
- * TrioOutStreamStringMax
- */
-TRIO_PRIVATE void
-TrioOutStreamStringMax
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- char **buffer;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- buffer = (char **)self->location;
-
- if (self->processed < self->max)
- {
- **buffer = (char)output;
- (*buffer)++;
- self->committed++;
- }
- self->processed++;
-}
-
-/*************************************************************************
- * TrioOutStreamStringDynamic
- */
-TRIO_PRIVATE void
-TrioOutStreamStringDynamic
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- assert(VALID(self));
- assert(VALID(self->location));
-
- if (self->error == 0)
- {
- trio_xstring_append_char((trio_string_t *)self->location,
- (char)output);
- self->committed++;
- }
- /* The processed variable must always be increased */
- self->processed++;
-}
-
-/*************************************************************************
- *
- * Formatted printing functions
- *
- ************************************************************************/
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_printf.h"
-#endif
-/** @addtogroup Printf
- @{
-*/
-
-/*************************************************************************
- * printf
- */
-
-/**
- Print to standard output stream.
-
- @param format Formatting string.
- @param ... Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_printf
-TRIO_VARGS2((format, va_alist),
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioFormat(stdout, 0, TrioOutStreamFile, format, &args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-/**
- Print to standard output stream.
-
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_vprintf
-TRIO_ARGS2((format, args),
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(format));
-
- return TrioFormat(stdout, 0, TrioOutStreamFile, format, &args, NULL);
-}
-
-/**
- Print to standard output stream.
-
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_printfv
-TRIO_ARGS2((format, args),
- TRIO_CONST char *format,
- trio_pointer_t * args)
-{
- assert(VALID(format));
-
- return TrioFormat(stdout, 0, TrioOutStreamFile, format, NULL, args);
-}
-
-/*************************************************************************
- * fprintf
- */
-
-/**
- Print to file.
-
- @param file File pointer.
- @param format Formatting string.
- @param ... Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_fprintf
-TRIO_VARGS3((file, format, va_alist),
- FILE *file,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(file));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioFormat(file, 0, TrioOutStreamFile, format, &args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-/**
- Print to file.
-
- @param file File pointer.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_vfprintf
-TRIO_ARGS3((file, format, args),
- FILE *file,
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(file));
- assert(VALID(format));
-
- return TrioFormat(file, 0, TrioOutStreamFile, format, &args, NULL);
-}
-
-/**
- Print to file.
-
- @param file File pointer.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_fprintfv
-TRIO_ARGS3((file, format, args),
- FILE *file,
- TRIO_CONST char *format,
- trio_pointer_t * args)
-{
- assert(VALID(file));
- assert(VALID(format));
-
- return TrioFormat(file, 0, TrioOutStreamFile, format, NULL, args);
-}
-
-/*************************************************************************
- * dprintf
- */
-
-/**
- Print to file descriptor.
-
- @param fd File descriptor.
- @param format Formatting string.
- @param ... Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_dprintf
-TRIO_VARGS3((fd, format, va_alist),
- int fd,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, &args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-/**
- Print to file descriptor.
-
- @param fd File descriptor.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_vdprintf
-TRIO_ARGS3((fd, format, args),
- int fd,
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(format));
-
- return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, &args, NULL);
-}
-
-/**
- Print to file descriptor.
-
- @param fd File descriptor.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_dprintfv
-TRIO_ARGS3((fd, format, args),
- int fd,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- assert(VALID(format));
-
- return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, NULL, args);
-}
-
-/*************************************************************************
- * cprintf
- */
-TRIO_PUBLIC int
-trio_cprintf
-TRIO_VARGS4((stream, closure, format, va_alist),
- trio_outstream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- data.stream.out = stream;
- data.closure = closure;
- status = TrioFormat(&data, 0, TrioOutStreamCustom, format, &args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-TRIO_PUBLIC int
-trio_vcprintf
-TRIO_ARGS4((stream, closure, format, args),
- trio_outstream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- va_list args)
-{
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- data.stream.out = stream;
- data.closure = closure;
- return TrioFormat(&data, 0, TrioOutStreamCustom, format, &args, NULL);
-}
-
-TRIO_PUBLIC int
-trio_cprintfv
-TRIO_ARGS4((stream, closure, format, args),
- trio_outstream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- void **args)
-{
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- data.stream.out = stream;
- data.closure = closure;
- return TrioFormat(&data, 0, TrioOutStreamCustom, format, NULL, args);
-}
-
-/*************************************************************************
- * sprintf
- */
-
-/**
- Print to string.
-
- @param buffer Output string.
- @param format Formatting string.
- @param ... Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_sprintf
-TRIO_VARGS3((buffer, format, va_alist),
- char *buffer,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioFormat(&buffer, 0, TrioOutStreamString, format, &args, NULL);
- *buffer = NIL; /* Terminate with NIL character */
- TRIO_VA_END(args);
- return status;
-}
-
-/**
- Print to string.
-
- @param buffer Output string.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_vsprintf
-TRIO_ARGS3((buffer, format, args),
- char *buffer,
- TRIO_CONST char *format,
- va_list args)
-{
- int status;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- status = TrioFormat(&buffer, 0, TrioOutStreamString, format, &args, NULL);
- *buffer = NIL;
- return status;
-}
-
-/**
- Print to string.
-
- @param buffer Output string.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_sprintfv
-TRIO_ARGS3((buffer, format, args),
- char *buffer,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- int status;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- status = TrioFormat(&buffer, 0, TrioOutStreamString, format, NULL, args);
- *buffer = NIL;
- return status;
-}
-
-/*************************************************************************
- * snprintf
- */
-
-/**
- Print at most @p max characters to string.
-
- @param buffer Output string.
- @param max Maximum number of characters to print.
- @param format Formatting string.
- @param ... Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_snprintf
-TRIO_VARGS4((buffer, max, format, va_alist),
- char *buffer,
- size_t max,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
- TrioOutStreamStringMax, format, &args, NULL);
- if (max > 0)
- *buffer = NIL;
- TRIO_VA_END(args);
- return status;
-}
-
-/**
- Print at most @p max characters to string.
-
- @param buffer Output string.
- @param max Maximum number of characters to print.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_vsnprintf
-TRIO_ARGS4((buffer, max, format, args),
- char *buffer,
- size_t max,
- TRIO_CONST char *format,
- va_list args)
-{
- int status;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
- TrioOutStreamStringMax, format, &args, NULL);
- if (max > 0)
- *buffer = NIL;
- return status;
-}
-
-/**
- Print at most @p max characters to string.
-
- @param buffer Output string.
- @param max Maximum number of characters to print.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_snprintfv
-TRIO_ARGS4((buffer, max, format, args),
- char *buffer,
- size_t max,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- int status;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
- TrioOutStreamStringMax, format, NULL, args);
- if (max > 0)
- *buffer = NIL;
- return status;
-}
-
-/*************************************************************************
- * snprintfcat
- * Appends the new string to the buffer string overwriting the '\0'
- * character at the end of buffer.
- */
-TRIO_PUBLIC int
-trio_snprintfcat
-TRIO_VARGS4((buffer, max, format, va_alist),
- char *buffer,
- size_t max,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
- size_t buf_len;
-
- TRIO_VA_START(args, format);
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- buf_len = trio_length(buffer);
- buffer = &buffer[buf_len];
-
- status = TrioFormat(&buffer, max - 1 - buf_len,
- TrioOutStreamStringMax, format, &args, NULL);
- TRIO_VA_END(args);
- *buffer = NIL;
- return status;
-}
-
-TRIO_PUBLIC int
-trio_vsnprintfcat
-TRIO_ARGS4((buffer, max, format, args),
- char *buffer,
- size_t max,
- TRIO_CONST char *format,
- va_list args)
-{
- int status;
- size_t buf_len;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- buf_len = trio_length(buffer);
- buffer = &buffer[buf_len];
- status = TrioFormat(&buffer, max - 1 - buf_len,
- TrioOutStreamStringMax, format, &args, NULL);
- *buffer = NIL;
- return status;
-}
-
-/*************************************************************************
- * trio_aprintf
- */
-
-/* Deprecated */
-TRIO_PUBLIC char *
-trio_aprintf
-TRIO_VARGS2((format, va_alist),
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- va_list args;
- trio_string_t *info;
- char *result = NULL;
-
- assert(VALID(format));
-
- info = trio_xstring_duplicate("");
- if (info)
- {
- TRIO_VA_START(args, format);
- (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, &args, NULL);
- TRIO_VA_END(args);
-
- trio_string_terminate(info);
- result = trio_string_extract(info);
- trio_string_destroy(info);
- }
- return result;
-}
-
-/* Deprecated */
-TRIO_PUBLIC char *
-trio_vaprintf
-TRIO_ARGS2((format, args),
- TRIO_CONST char *format,
- va_list args)
-{
- trio_string_t *info;
- char *result = NULL;
-
- assert(VALID(format));
-
- info = trio_xstring_duplicate("");
- if (info)
- {
- (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, &args, NULL);
- trio_string_terminate(info);
- result = trio_string_extract(info);
- trio_string_destroy(info);
- }
- return result;
-}
-
-TRIO_PUBLIC int
-trio_asprintf
-TRIO_VARGS3((result, format, va_alist),
- char **result,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- va_list args;
- int status;
- trio_string_t *info;
-
- assert(VALID(format));
-
- *result = NULL;
-
- info = trio_xstring_duplicate("");
- if (info == NULL)
- {
- status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);
- }
- else
- {
- TRIO_VA_START(args, format);
- status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, &args, NULL);
- TRIO_VA_END(args);
- if (status >= 0)
- {
- trio_string_terminate(info);
- *result = trio_string_extract(info);
- }
- trio_string_destroy(info);
- }
- return status;
-}
-
-TRIO_PUBLIC int
-trio_vasprintf
-TRIO_ARGS3((result, format, args),
- char **result,
- TRIO_CONST char *format,
- va_list args)
-{
- int status;
- trio_string_t *info;
-
- assert(VALID(format));
-
- *result = NULL;
-
- info = trio_xstring_duplicate("");
- if (info == NULL)
- {
- status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);
- }
- else
- {
- status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, &args, NULL);
- if (status >= 0)
- {
- trio_string_terminate(info);
- *result = trio_string_extract(info);
- }
- trio_string_destroy(info);
- }
- return status;
-}
-
-/** @} End of Printf documentation module */
-
-/*************************************************************************
- *
- * CALLBACK
- *
- ************************************************************************/
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_register.h"
-#endif
-/**
- @addtogroup UserDefined
- @{
-*/
-
-#if TRIO_EXTENSION
-
-/*************************************************************************
- * trio_register
- */
-
-/**
- Register new user-defined specifier.
-
- @param callback
- @param name
- @return Handle.
- */
-TRIO_PUBLIC trio_pointer_t
-trio_register
-TRIO_ARGS2((callback, name),
- trio_callback_t callback,
- TRIO_CONST char *name)
-{
- trio_userdef_t *def;
- trio_userdef_t *prev = NULL;
-
- if (callback == NULL)
- return NULL;
-
- if (name)
- {
- /* Handle built-in namespaces */
- if (name[0] == ':')
- {
- if (trio_equal(name, ":enter"))
- {
- internalEnterCriticalRegion = callback;
- }
- else if (trio_equal(name, ":leave"))
- {
- internalLeaveCriticalRegion = callback;
- }
- return NULL;
- }
-
- /* Bail out if namespace is too long */
- if (trio_length(name) >= MAX_USER_NAME)
- return NULL;
-
- /* Bail out if namespace already is registered */
- def = TrioFindNamespace(name, &prev);
- if (def)
- return NULL;
- }
-
- def = (trio_userdef_t *)TRIO_MALLOC(sizeof(trio_userdef_t));
- if (def)
- {
- if (internalEnterCriticalRegion)
- (void)internalEnterCriticalRegion(NULL);
-
- if (name)
- {
- /* Link into internal list */
- if (prev == NULL)
- internalUserDef = def;
- else
- prev->next = def;
- }
- /* Initialize */
- def->callback = callback;
- def->name = (name == NULL)
- ? NULL
- : trio_duplicate(name);
- def->next = NULL;
-
- if (internalLeaveCriticalRegion)
- (void)internalLeaveCriticalRegion(NULL);
- }
- return (trio_pointer_t)def;
-}
-
-/**
- Unregister an existing user-defined specifier.
-
- @param handle
- */
-void
-trio_unregister
-TRIO_ARGS1((handle),
- trio_pointer_t handle)
-{
- trio_userdef_t *self = (trio_userdef_t *)handle;
- trio_userdef_t *def;
- trio_userdef_t *prev = NULL;
-
- assert(VALID(self));
-
- if (self->name)
- {
- def = TrioFindNamespace(self->name, &prev);
- if (def)
- {
- if (internalEnterCriticalRegion)
- (void)internalEnterCriticalRegion(NULL);
-
- if (prev == NULL)
- internalUserDef = NULL;
- else
- prev->next = def->next;
-
- if (internalLeaveCriticalRegion)
- (void)internalLeaveCriticalRegion(NULL);
- }
- trio_destroy(self->name);
- }
- TRIO_FREE(self);
-}
-
-/*************************************************************************
- * trio_get_format [public]
- */
-TRIO_CONST char *
-trio_get_format
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
-#if defined(FORMAT_USER_DEFINED)
- assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);
-#endif
-
- return (((trio_reference_t *)ref)->parameter->user_data);
-}
-
-/*************************************************************************
- * trio_get_argument [public]
- */
-trio_pointer_t
-trio_get_argument
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
-#if defined(FORMAT_USER_DEFINED)
- assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);
-#endif
-
- return ((trio_reference_t *)ref)->parameter->data.pointer;
-}
-
-/*************************************************************************
- * trio_get_width / trio_set_width [public]
- */
-int
-trio_get_width
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return ((trio_reference_t *)ref)->parameter->width;
-}
-
-void
-trio_set_width
-TRIO_ARGS2((ref, width),
- trio_pointer_t ref,
- int width)
-{
- ((trio_reference_t *)ref)->parameter->width = width;
-}
-
-/*************************************************************************
- * trio_get_precision / trio_set_precision [public]
- */
-int
-trio_get_precision
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->precision);
-}
-
-void
-trio_set_precision
-TRIO_ARGS2((ref, precision),
- trio_pointer_t ref,
- int precision)
-{
- ((trio_reference_t *)ref)->parameter->precision = precision;
-}
-
-/*************************************************************************
- * trio_get_base / trio_set_base [public]
- */
-int
-trio_get_base
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->base);
-}
-
-void
-trio_set_base
-TRIO_ARGS2((ref, base),
- trio_pointer_t ref,
- int base)
-{
- ((trio_reference_t *)ref)->parameter->base = base;
-}
-
-/*************************************************************************
- * trio_get_long / trio_set_long [public]
- */
-int
-trio_get_long
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONG);
-}
-
-void
-trio_set_long
-TRIO_ARGS2((ref, is_long),
- trio_pointer_t ref,
- int is_long)
-{
- if (is_long)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONG;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONG;
-}
-
-/*************************************************************************
- * trio_get_longlong / trio_set_longlong [public]
- */
-int
-trio_get_longlong
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUAD);
-}
-
-void
-trio_set_longlong
-TRIO_ARGS2((ref, is_longlong),
- trio_pointer_t ref,
- int is_longlong)
-{
- if (is_longlong)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUAD;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUAD;
-}
-
-/*************************************************************************
- * trio_get_longdouble / trio_set_longdouble [public]
- */
-int
-trio_get_longdouble
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONGDOUBLE);
-}
-
-void
-trio_set_longdouble
-TRIO_ARGS2((ref, is_longdouble),
- trio_pointer_t ref,
- int is_longdouble)
-{
- if (is_longdouble)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONGDOUBLE;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONGDOUBLE;
-}
-
-/*************************************************************************
- * trio_get_short / trio_set_short [public]
- */
-int
-trio_get_short
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORT);
-}
-
-void
-trio_set_short
-TRIO_ARGS2((ref, is_short),
- trio_pointer_t ref,
- int is_short)
-{
- if (is_short)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORT;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORT;
-}
-
-/*************************************************************************
- * trio_get_shortshort / trio_set_shortshort [public]
- */
-int
-trio_get_shortshort
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORTSHORT);
-}
-
-void
-trio_set_shortshort
-TRIO_ARGS2((ref, is_shortshort),
- trio_pointer_t ref,
- int is_shortshort)
-{
- if (is_shortshort)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORTSHORT;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORTSHORT;
-}
-
-/*************************************************************************
- * trio_get_alternative / trio_set_alternative [public]
- */
-int
-trio_get_alternative
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_ALTERNATIVE);
-}
-
-void
-trio_set_alternative
-TRIO_ARGS2((ref, is_alternative),
- trio_pointer_t ref,
- int is_alternative)
-{
- if (is_alternative)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_ALTERNATIVE;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_ALTERNATIVE;
-}
-
-/*************************************************************************
- * trio_get_alignment / trio_set_alignment [public]
- */
-int
-trio_get_alignment
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LEFTADJUST);
-}
-
-void
-trio_set_alignment
-TRIO_ARGS2((ref, is_leftaligned),
- trio_pointer_t ref,
- int is_leftaligned)
-{
- if (is_leftaligned)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LEFTADJUST;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LEFTADJUST;
-}
-
-/*************************************************************************
- * trio_get_spacing /trio_set_spacing [public]
- */
-int
-trio_get_spacing
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SPACE);
-}
-
-void
-trio_set_spacing
-TRIO_ARGS2((ref, is_space),
- trio_pointer_t ref,
- int is_space)
-{
- if (is_space)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SPACE;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SPACE;
-}
-
-/*************************************************************************
- * trio_get_sign / trio_set_sign [public]
- */
-int
-trio_get_sign
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHOWSIGN);
-}
-
-void
-trio_set_sign
-TRIO_ARGS2((ref, is_sign),
- trio_pointer_t ref,
- int is_sign)
-{
- if (is_sign)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHOWSIGN;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHOWSIGN;
-}
-
-/*************************************************************************
- * trio_get_padding / trio_set_padding [public]
- */
-int
-trio_get_padding
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_NILPADDING);
-}
-
-void
-trio_set_padding
-TRIO_ARGS2((ref, is_padding),
- trio_pointer_t ref,
- int is_padding)
-{
- if (is_padding)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_NILPADDING;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_NILPADDING;
-}
-
-/*************************************************************************
- * trio_get_quote / trio_set_quote [public]
- */
-int
-trio_get_quote
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUOTE);
-}
-
-void
-trio_set_quote
-TRIO_ARGS2((ref, is_quote),
- trio_pointer_t ref,
- int is_quote)
-{
- if (is_quote)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUOTE;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUOTE;
-}
-
-/*************************************************************************
- * trio_get_upper / trio_set_upper [public]
- */
-int
-trio_get_upper
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_UPPER);
-}
-
-void
-trio_set_upper
-TRIO_ARGS2((ref, is_upper),
- trio_pointer_t ref,
- int is_upper)
-{
- if (is_upper)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_UPPER;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_UPPER;
-}
-
-/*************************************************************************
- * trio_get_largest / trio_set_largest [public]
- */
-#if TRIO_C99
-int
-trio_get_largest
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_INTMAX_T);
-}
-
-void
-trio_set_largest
-TRIO_ARGS2((ref, is_largest),
- trio_pointer_t ref,
- int is_largest)
-{
- if (is_largest)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_INTMAX_T;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_INTMAX_T;
-}
-#endif
-
-/*************************************************************************
- * trio_get_ptrdiff / trio_set_ptrdiff [public]
- */
-int
-trio_get_ptrdiff
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_PTRDIFF_T);
-}
-
-void
-trio_set_ptrdiff
-TRIO_ARGS2((ref, is_ptrdiff),
- trio_pointer_t ref,
- int is_ptrdiff)
-{
- if (is_ptrdiff)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_PTRDIFF_T;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_PTRDIFF_T;
-}
-
-/*************************************************************************
- * trio_get_size / trio_set_size [public]
- */
-#if TRIO_C99
-int
-trio_get_size
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SIZE_T);
-}
-
-void
-trio_set_size
-TRIO_ARGS2((ref, is_size),
- trio_pointer_t ref,
- int is_size)
-{
- if (is_size)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SIZE_T;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SIZE_T;
-}
-#endif
-
-/*************************************************************************
- * trio_print_int [public]
- */
-void
-trio_print_int
-TRIO_ARGS2((ref, number),
- trio_pointer_t ref,
- int number)
-{
- trio_reference_t *self = (trio_reference_t *)ref;
-
- TrioWriteNumber(self->data,
- (trio_uintmax_t)number,
- self->parameter->flags,
- self->parameter->width,
- self->parameter->precision,
- self->parameter->base);
-}
-
-/*************************************************************************
- * trio_print_uint [public]
- */
-void
-trio_print_uint
-TRIO_ARGS2((ref, number),
- trio_pointer_t ref,
- unsigned int number)
-{
- trio_reference_t *self = (trio_reference_t *)ref;
-
- TrioWriteNumber(self->data,
- (trio_uintmax_t)number,
- self->parameter->flags | FLAGS_UNSIGNED,
- self->parameter->width,
- self->parameter->precision,
- self->parameter->base);
-}
-
-/*************************************************************************
- * trio_print_double [public]
- */
-void
-trio_print_double
-TRIO_ARGS2((ref, number),
- trio_pointer_t ref,
- double number)
-{
- trio_reference_t *self = (trio_reference_t *)ref;
-
- TrioWriteDouble(self->data,
- number,
- self->parameter->flags,
- self->parameter->width,
- self->parameter->precision,
- self->parameter->base);
-}
-
-/*************************************************************************
- * trio_print_string [public]
- */
-void
-trio_print_string
-TRIO_ARGS2((ref, string),
- trio_pointer_t ref,
- char *string)
-{
- trio_reference_t *self = (trio_reference_t *)ref;
-
- TrioWriteString(self->data,
- string,
- self->parameter->flags,
- self->parameter->width,
- self->parameter->precision);
-}
-
-/*************************************************************************
- * trio_print_ref [public]
- */
-int
-trio_print_ref
-TRIO_VARGS3((ref, format, va_alist),
- trio_pointer_t ref,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list arglist;
-
- assert(VALID(format));
-
- TRIO_VA_START(arglist, format);
- status = TrioFormatRef((trio_reference_t *)ref, format, &arglist, NULL);
- TRIO_VA_END(arglist);
- return status;
-}
-
-/*************************************************************************
- * trio_vprint_ref [public]
- */
-int
-trio_vprint_ref
-TRIO_ARGS3((ref, format, arglist),
- trio_pointer_t ref,
- TRIO_CONST char *format,
- va_list arglist)
-{
- assert(VALID(format));
-
- return TrioFormatRef((trio_reference_t *)ref, format, &arglist, NULL);
-}
-
-/*************************************************************************
- * trio_printv_ref [public]
- */
-int
-trio_printv_ref
-TRIO_ARGS3((ref, format, argarray),
- trio_pointer_t ref,
- TRIO_CONST char *format,
- trio_pointer_t *argarray)
-{
- assert(VALID(format));
-
- return TrioFormatRef((trio_reference_t *)ref, format, NULL, argarray);
-}
-
-#endif /* TRIO_EXTENSION */
-
-/*************************************************************************
- * trio_print_pointer [public]
- */
-void
-trio_print_pointer
-TRIO_ARGS2((ref, pointer),
- trio_pointer_t ref,
- trio_pointer_t pointer)
-{
- trio_reference_t *self = (trio_reference_t *)ref;
- unsigned long flags;
- trio_uintmax_t number;
-
- if (NULL == pointer)
- {
- TRIO_CONST char *string = internalNullString;
- while (*string)
- self->data->OutStream(self->data, *string++);
- }
- else
- {
- /*
- * The subtraction of the null pointer is a workaround
- * to avoid a compiler warning. The performance overhead
- * is negligible (and likely to be removed by an
- * optimizing compiler). The (char *) casting is done
- * to please ANSI C++.
- */
- number = (trio_uintmax_t)((char *)pointer - (char *)0);
- /* Shrink to size of pointer */
- number &= (trio_uintmax_t)-1;
- flags = self->parameter->flags;
- flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE |
- FLAGS_NILPADDING);
- TrioWriteNumber(self->data,
- number,
- flags,
- POINTER_WIDTH,
- NO_PRECISION,
- BASE_HEX);
- }
-}
-
-/** @} End of UserDefined documentation module */
-
-/*************************************************************************
- *
- * LOCALES
- *
- ************************************************************************/
-
-/*************************************************************************
- * trio_locale_set_decimal_point
- *
- * Decimal point can only be one character. The input argument is a
- * string to enable multibyte characters. At most MB_LEN_MAX characters
- * will be used.
- */
-TRIO_PUBLIC void
-trio_locale_set_decimal_point
-TRIO_ARGS1((decimalPoint),
- char *decimalPoint)
-{
-#if defined(USE_LOCALE)
- if (NULL == internalLocaleValues)
- {
- TrioSetLocale();
- }
-#endif
- internalDecimalPointLength = trio_length(decimalPoint);
- if (internalDecimalPointLength == 1)
- {
- internalDecimalPoint = *decimalPoint;
- }
- else
- {
- internalDecimalPoint = NIL;
- trio_copy_max(internalDecimalPointString,
- sizeof(internalDecimalPointString),
- decimalPoint);
- }
-}
-
-/*************************************************************************
- * trio_locale_set_thousand_separator
- *
- * See trio_locale_set_decimal_point
- */
-TRIO_PUBLIC void
-trio_locale_set_thousand_separator
-TRIO_ARGS1((thousandSeparator),
- char *thousandSeparator)
-{
-#if defined(USE_LOCALE)
- if (NULL == internalLocaleValues)
- {
- TrioSetLocale();
- }
-#endif
- trio_copy_max(internalThousandSeparator,
- sizeof(internalThousandSeparator),
- thousandSeparator);
- internalThousandSeparatorLength = trio_length(internalThousandSeparator);
-}
-
-/*************************************************************************
- * trio_locale_set_grouping
- *
- * Array of bytes. Reversed order.
- *
- * CHAR_MAX : No further grouping
- * 0 : Repeat last group for the remaining digits (not necessary
- * as C strings are zero-terminated)
- * n : Set current group to n
- *
- * Same order as the grouping attribute in LC_NUMERIC.
- */
-TRIO_PUBLIC void
-trio_locale_set_grouping
-TRIO_ARGS1((grouping),
- char *grouping)
-{
-#if defined(USE_LOCALE)
- if (NULL == internalLocaleValues)
- {
- TrioSetLocale();
- }
-#endif
- trio_copy_max(internalGrouping,
- sizeof(internalGrouping),
- grouping);
-}
-
-
-/*************************************************************************
- *
- * SCANNING
- *
- ************************************************************************/
-
-/*************************************************************************
- * TrioSkipWhitespaces
- */
-TRIO_PRIVATE int
-TrioSkipWhitespaces
-TRIO_ARGS1((self),
- trio_class_t *self)
-{
- int ch;
-
- ch = self->current;
- while (isspace(ch))
- {
- self->InStream(self, &ch);
- }
- return ch;
-}
-
-/*************************************************************************
- * TrioGetCollation
- */
-#if TRIO_EXTENSION
-TRIO_PRIVATE void
-TrioGetCollation(TRIO_NOARGS)
-{
- int i;
- int j;
- int k;
- char first[2];
- char second[2];
-
- /* This is computational expensive */
- first[1] = NIL;
- second[1] = NIL;
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- {
- k = 0;
- first[0] = (char)i;
- for (j = 0; j < MAX_CHARACTER_CLASS; j++)
- {
- second[0] = (char)j;
- if (trio_equal_locale(first, second))
- internalCollationArray[i][k++] = (char)j;
- }
- internalCollationArray[i][k] = NIL;
- }
-}
-#endif
-
-/*************************************************************************
- * TrioGetCharacterClass
- *
- * FIXME:
- * multibyte
- */
-TRIO_PRIVATE int
-TrioGetCharacterClass
-TRIO_ARGS4((format, indexPointer, flagsPointer, characterclass),
- TRIO_CONST char *format,
- int *indexPointer,
- unsigned long *flagsPointer,
- int *characterclass)
-{
- int index = *indexPointer;
- int i;
- char ch;
- char range_begin;
- char range_end;
-
- *flagsPointer &= ~FLAGS_EXCLUDE;
-
- if (format[index] == QUALIFIER_CIRCUMFLEX)
- {
- *flagsPointer |= FLAGS_EXCLUDE;
- index++;
- }
- /*
- * If the ungroup character is at the beginning of the scanlist,
- * it will be part of the class, and a second ungroup character
- * must follow to end the group.
- */
- if (format[index] == SPECIFIER_UNGROUP)
- {
- characterclass[(int)SPECIFIER_UNGROUP]++;
- index++;
- }
- /*
- * Minus is used to specify ranges. To include minus in the class,
- * it must be at the beginning of the list
- */
- if (format[index] == QUALIFIER_MINUS)
- {
- characterclass[(int)QUALIFIER_MINUS]++;
- index++;
- }
- /* Collect characters */
- for (ch = format[index];
- (ch != SPECIFIER_UNGROUP) && (ch != NIL);
- ch = format[++index])
- {
- switch (ch)
- {
- case QUALIFIER_MINUS: /* Scanlist ranges */
-
- /*
- * Both C99 and UNIX98 describes ranges as implementation-
- * defined.
- *
- * We support the following behaviour (although this may
- * change as we become wiser)
- * - only increasing ranges, ie. [a-b] but not [b-a]
- * - transitive ranges, ie. [a-b-c] == [a-c]
- * - trailing minus, ie. [a-] is interpreted as an 'a'
- * and a '-'
- * - duplicates (although we can easily convert these
- * into errors)
- */
- range_begin = format[index - 1];
- range_end = format[++index];
- if (range_end == SPECIFIER_UNGROUP)
- {
- /* Trailing minus is included */
- characterclass[(int)ch]++;
- ch = range_end;
- break; /* for */
- }
- if (range_end == NIL)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- if (range_begin > range_end)
- return TRIO_ERROR_RETURN(TRIO_ERANGE, index);
-
- for (i = (int)range_begin; i <= (int)range_end; i++)
- characterclass[i]++;
-
- ch = range_end;
- break;
-
-#if TRIO_EXTENSION
-
- case SPECIFIER_GROUP:
-
- switch (format[index + 1])
- {
- case QUALIFIER_DOT: /* Collating symbol */
- /*
- * FIXME: This will be easier to implement when multibyte
- * characters have been implemented. Until now, we ignore
- * this feature.
- */
- for (i = index + 2; ; i++)
- {
- if (format[i] == NIL)
- /* Error in syntax */
- return -1;
- else if (format[i] == QUALIFIER_DOT)
- break; /* for */
- }
- if (format[++i] != SPECIFIER_UNGROUP)
- return -1;
-
- index = i;
- break;
-
- case QUALIFIER_EQUAL: /* Equivalence class expressions */
- {
- unsigned int j;
- unsigned int k;
-
- if (internalCollationUnconverted)
- {
- /* Lazy evaluation of collation array */
- TrioGetCollation();
- internalCollationUnconverted = FALSE;
- }
- for (i = index + 2; ; i++)
- {
- if (format[i] == NIL)
- /* Error in syntax */
- return -1;
- else if (format[i] == QUALIFIER_EQUAL)
- break; /* for */
- else
- {
- /* Mark any equivalent character */
- k = (unsigned int)format[i];
- for (j = 0; internalCollationArray[k][j] != NIL; j++)
- characterclass[(int)internalCollationArray[k][j]]++;
- }
- }
- if (format[++i] != SPECIFIER_UNGROUP)
- return -1;
-
- index = i;
- }
- break;
-
- case QUALIFIER_COLON: /* Character class expressions */
-
- if (trio_equal_max(CLASS_ALNUM, sizeof(CLASS_ALNUM) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isalnum(i))
- characterclass[i]++;
- index += sizeof(CLASS_ALNUM) - 1;
- }
- else if (trio_equal_max(CLASS_ALPHA, sizeof(CLASS_ALPHA) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isalpha(i))
- characterclass[i]++;
- index += sizeof(CLASS_ALPHA) - 1;
- }
- else if (trio_equal_max(CLASS_CNTRL, sizeof(CLASS_CNTRL) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (iscntrl(i))
- characterclass[i]++;
- index += sizeof(CLASS_CNTRL) - 1;
- }
- else if (trio_equal_max(CLASS_DIGIT, sizeof(CLASS_DIGIT) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isdigit(i))
- characterclass[i]++;
- index += sizeof(CLASS_DIGIT) - 1;
- }
- else if (trio_equal_max(CLASS_GRAPH, sizeof(CLASS_GRAPH) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isgraph(i))
- characterclass[i]++;
- index += sizeof(CLASS_GRAPH) - 1;
- }
- else if (trio_equal_max(CLASS_LOWER, sizeof(CLASS_LOWER) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (islower(i))
- characterclass[i]++;
- index += sizeof(CLASS_LOWER) - 1;
- }
- else if (trio_equal_max(CLASS_PRINT, sizeof(CLASS_PRINT) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isprint(i))
- characterclass[i]++;
- index += sizeof(CLASS_PRINT) - 1;
- }
- else if (trio_equal_max(CLASS_PUNCT, sizeof(CLASS_PUNCT) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (ispunct(i))
- characterclass[i]++;
- index += sizeof(CLASS_PUNCT) - 1;
- }
- else if (trio_equal_max(CLASS_SPACE, sizeof(CLASS_SPACE) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isspace(i))
- characterclass[i]++;
- index += sizeof(CLASS_SPACE) - 1;
- }
- else if (trio_equal_max(CLASS_UPPER, sizeof(CLASS_UPPER) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isupper(i))
- characterclass[i]++;
- index += sizeof(CLASS_UPPER) - 1;
- }
- else if (trio_equal_max(CLASS_XDIGIT, sizeof(CLASS_XDIGIT) - 1,
- &format[index]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isxdigit(i))
- characterclass[i]++;
- index += sizeof(CLASS_XDIGIT) - 1;
- }
- else
- {
- characterclass[(int)ch]++;
- }
- break;
-
- default:
- characterclass[(int)ch]++;
- break;
- }
- break;
-
-#endif /* TRIO_EXTENSION */
-
- default:
- characterclass[(int)ch]++;
- break;
- }
- }
- return 0;
-}
-
-/*************************************************************************
- * TrioReadNumber
- *
- * We implement our own number conversion in preference of strtol and
- * strtoul, because we must handle 'long long' and thousand separators.
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadNumber
-TRIO_ARGS5((self, target, flags, width, base),
- trio_class_t *self,
- trio_uintmax_t *target,
- unsigned long flags,
- int width,
- int base)
-{
- trio_uintmax_t number = 0;
- int digit;
- int count;
- BOOLEAN_T isNegative = FALSE;
- BOOLEAN_T gotNumber = FALSE;
- int j;
-
- assert(VALID(self));
- assert(VALID(self->InStream));
- assert((base >= MIN_BASE && base <= MAX_BASE) || (base == NO_BASE));
-
- if (internalDigitsUnconverted)
- {
- /* Lazy evaluation of digits array */
- memset(internalDigitArray, -1, sizeof(internalDigitArray));
- for (j = 0; j < (int)sizeof(internalDigitsLower) - 1; j++)
- {
- internalDigitArray[(int)internalDigitsLower[j]] = j;
- internalDigitArray[(int)internalDigitsUpper[j]] = j;
- }
- internalDigitsUnconverted = FALSE;
- }
-
- TrioSkipWhitespaces(self);
-
- if (!(flags & FLAGS_UNSIGNED))
- {
- /* Leading sign */
- if (self->current == '+')
- {
- self->InStream(self, NULL);
- }
- else if (self->current == '-')
- {
- self->InStream(self, NULL);
- isNegative = TRUE;
- }
- }
-
- count = self->processed;
-
- if (flags & FLAGS_ALTERNATIVE)
- {
- switch (base)
- {
- case NO_BASE:
- case BASE_OCTAL:
- case BASE_HEX:
- case BASE_BINARY:
- if (self->current == '0')
- {
- self->InStream(self, NULL);
- if (self->current)
- {
- if ((base == BASE_HEX) &&
- (toupper(self->current) == 'X'))
- {
- self->InStream(self, NULL);
- }
- else if ((base == BASE_BINARY) &&
- (toupper(self->current) == 'B'))
- {
- self->InStream(self, NULL);
- }
- }
- }
- else
- return FALSE;
- break;
- default:
- break;
- }
- }
-
- while (((width == NO_WIDTH) || (self->processed - count < width)) &&
- (! ((self->current == EOF) || isspace(self->current))))
- {
- if (isascii(self->current))
- {
- digit = internalDigitArray[self->current];
- /* Abort if digit is not allowed in the specified base */
- if ((digit == -1) || (digit >= base))
- break;
- }
- else if (flags & FLAGS_QUOTE)
- {
- /* Compare with thousands separator */
- for (j = 0; internalThousandSeparator[j] && self->current; j++)
- {
- if (internalThousandSeparator[j] != self->current)
- break;
-
- self->InStream(self, NULL);
- }
- if (internalThousandSeparator[j])
- break; /* Mismatch */
- else
- continue; /* Match */
- }
- else
- break;
-
- number *= base;
- number += digit;
- gotNumber = TRUE; /* we need at least one digit */
-
- self->InStream(self, NULL);
- }
-
- /* Was anything read at all? */
- if (!gotNumber)
- return FALSE;
-
- if (target)
- *target = (isNegative) ? -((trio_intmax_t)number) : number;
- return TRUE;
-}
-
-/*************************************************************************
- * TrioReadChar
- */
-TRIO_PRIVATE int
-TrioReadChar
-TRIO_ARGS4((self, target, flags, width),
- trio_class_t *self,
- char *target,
- unsigned long flags,
- int width)
-{
- int i;
- char ch;
- trio_uintmax_t number;
-
- assert(VALID(self));
- assert(VALID(self->InStream));
-
- for (i = 0;
- (self->current != EOF) && (i < width);
- i++)
- {
- ch = (char)self->current;
- self->InStream(self, NULL);
- if ((flags & FLAGS_ALTERNATIVE) && (ch == CHAR_BACKSLASH))
- {
- switch (self->current)
- {
- case '\\': ch = '\\'; break;
- case 'a': ch = '\007'; break;
- case 'b': ch = '\b'; break;
- case 'f': ch = '\f'; break;
- case 'n': ch = '\n'; break;
- case 'r': ch = '\r'; break;
- case 't': ch = '\t'; break;
- case 'v': ch = '\v'; break;
- default:
- if (isdigit(self->current))
- {
- /* Read octal number */
- if (!TrioReadNumber(self, &number, 0, 3, BASE_OCTAL))
- return 0;
- ch = (char)number;
- }
- else if (toupper(self->current) == 'X')
- {
- /* Read hexadecimal number */
- self->InStream(self, NULL);
- if (!TrioReadNumber(self, &number, 0, 2, BASE_HEX))
- return 0;
- ch = (char)number;
- }
- else
- {
- ch = (char)self->current;
- }
- break;
- }
- }
-
- if (target)
- target[i] = ch;
- }
- return i + 1;
-}
-
-/*************************************************************************
- * TrioReadString
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadString
-TRIO_ARGS4((self, target, flags, width),
- trio_class_t *self,
- char *target,
- unsigned long flags,
- int width)
-{
- int i;
-
- assert(VALID(self));
- assert(VALID(self->InStream));
-
- TrioSkipWhitespaces(self);
-
- /*
- * Continue until end of string is reached, a whitespace is encountered,
- * or width is exceeded
- */
- for (i = 0;
- ((width == NO_WIDTH) || (i < width)) &&
- (! ((self->current == EOF) || isspace(self->current)));
- i++)
- {
- if (TrioReadChar(self, (target ? &target[i] : 0), flags, 1) == 0)
- break; /* for */
- }
- if (target)
- target[i] = NIL;
- return TRUE;
-}
-
-/*************************************************************************
- * TrioReadWideChar
- */
-#if TRIO_WIDECHAR
-TRIO_PRIVATE int
-TrioReadWideChar
-TRIO_ARGS4((self, target, flags, width),
- trio_class_t *self,
- trio_wchar_t *target,
- unsigned long flags,
- int width)
-{
- int i;
- int j;
- int size;
- int amount = 0;
- trio_wchar_t wch;
- char buffer[MB_LEN_MAX + 1];
-
- assert(VALID(self));
- assert(VALID(self->InStream));
-
- for (i = 0;
- (self->current != EOF) && (i < width);
- i++)
- {
- if (isascii(self->current))
- {
- if (TrioReadChar(self, buffer, flags, 1) == 0)
- return 0;
- buffer[1] = NIL;
- }
- else
- {
- /*
- * Collect a multibyte character, by enlarging buffer until
- * it contains a fully legal multibyte character, or the
- * buffer is full.
- */
- j = 0;
- do
- {
- buffer[j++] = (char)self->current;
- buffer[j] = NIL;
- self->InStream(self, NULL);
- }
- while ((j < (int)sizeof(buffer)) && (mblen(buffer, (size_t)j) != j));
- }
- if (target)
- {
- size = mbtowc(&wch, buffer, sizeof(buffer));
- if (size > 0)
- target[i] = wch;
- }
- amount += size;
- self->InStream(self, NULL);
- }
- return amount;
-}
-#endif /* TRIO_WIDECHAR */
-
-/*************************************************************************
- * TrioReadWideString
- */
-#if TRIO_WIDECHAR
-TRIO_PRIVATE BOOLEAN_T
-TrioReadWideString
-TRIO_ARGS4((self, target, flags, width),
- trio_class_t *self,
- trio_wchar_t *target,
- unsigned long flags,
- int width)
-{
- int i;
- int size;
-
- assert(VALID(self));
- assert(VALID(self->InStream));
-
- TrioSkipWhitespaces(self);
-
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- (void)mblen(NULL, 0);
-#endif
-
- /*
- * Continue until end of string is reached, a whitespace is encountered,
- * or width is exceeded
- */
- for (i = 0;
- ((width == NO_WIDTH) || (i < width)) &&
- (! ((self->current == EOF) || isspace(self->current)));
- )
- {
- size = TrioReadWideChar(self, &target[i], flags, 1);
- if (size == 0)
- break; /* for */
-
- i += size;
- }
- if (target)
- target[i] = WCONST('\0');
- return TRUE;
-}
-#endif /* TRIO_WIDECHAR */
-
-/*************************************************************************
- * TrioReadGroup
- *
- * FIXME: characterclass does not work with multibyte characters
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadGroup
-TRIO_ARGS5((self, target, characterclass, flags, width),
- trio_class_t *self,
- char *target,
- int *characterclass,
- unsigned long flags,
- int width)
-{
- int ch;
- int i;
-
- assert(VALID(self));
- assert(VALID(self->InStream));
-
- ch = self->current;
- for (i = 0;
- ((width == NO_WIDTH) || (i < width)) &&
- (! ((ch == EOF) ||
- (((flags & FLAGS_EXCLUDE) != 0) ^ (characterclass[ch] == 0))));
- i++)
- {
- if (target)
- target[i] = (char)ch;
- self->InStream(self, &ch);
- }
-
- if (target)
- target[i] = NIL;
- return TRUE;
-}
-
-/*************************************************************************
- * TrioReadDouble
- *
- * FIXME:
- * add long double
- * handle base
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadDouble
-TRIO_ARGS4((self, target, flags, width),
- trio_class_t *self,
- trio_pointer_t target,
- unsigned long flags,
- int width)
-{
- int ch;
- char doubleString[512];
- int index = 0;
- int start;
- int j;
- BOOLEAN_T isHex = FALSE;
-
- doubleString[0] = 0;
-
- if ((width == NO_WIDTH) || (width > (int)sizeof(doubleString) - 1))
- width = sizeof(doubleString) - 1;
-
- TrioSkipWhitespaces(self);
-
- /*
- * Read entire double number from stream. trio_to_double requires
- * a string as input, but InStream can be anything, so we have to
- * collect all characters.
- */
- ch = self->current;
- if ((ch == '+') || (ch == '-'))
- {
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- width--;
- }
-
- start = index;
- switch (ch)
- {
- case 'n':
- case 'N':
- /* Not-a-number */
- if (index != 0)
- break;
- /* FALLTHROUGH */
- case 'i':
- case 'I':
- /* Infinity */
- while (isalpha(ch) && (index - start < width))
- {
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- }
- doubleString[index] = NIL;
-
- /* Case insensitive string comparison */
- if (trio_equal(&doubleString[start], INFINITE_UPPER) ||
- trio_equal(&doubleString[start], LONG_INFINITE_UPPER))
- {
- if (flags & FLAGS_LONGDOUBLE)
- {
- if ((start == 1) && (doubleString[0] == '-'))
- {
- *((trio_long_double_t *)target) = trio_ninf();
- }
- else
- {
- *((trio_long_double_t *)target) = trio_pinf();
- }
- }
- else
- {
- if ((start == 1) && (doubleString[0] == '-'))
- {
- *((double *)target) = trio_ninf();
- }
- else
- {
- *((double *)target) = trio_pinf();
- }
- }
- return TRUE;
- }
- if (trio_equal(doubleString, NAN_UPPER))
- {
- /* NaN must not have a preceeding + nor - */
- if (flags & FLAGS_LONGDOUBLE)
- {
- *((trio_long_double_t *)target) = trio_nan();
- }
- else
- {
- *((double *)target) = trio_nan();
- }
- return TRUE;
- }
- return FALSE;
-
- case '0':
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- if (toupper(ch) == 'X')
- {
- isHex = TRUE;
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- }
- break;
-
- default:
- break;
- }
-
- while ((ch != EOF) && (index - start < width))
- {
- /* Integer part */
- if (isHex ? isxdigit(ch) : isdigit(ch))
- {
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- }
- else if (flags & FLAGS_QUOTE)
- {
- /* Compare with thousands separator */
- for (j = 0; internalThousandSeparator[j] && self->current; j++)
- {
- if (internalThousandSeparator[j] != self->current)
- break;
-
- self->InStream(self, &ch);
- }
- if (internalThousandSeparator[j])
- break; /* Mismatch */
- else
- continue; /* Match */
- }
- else
- break; /* while */
- }
- if (ch == '.')
- {
- /* Decimal part */
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- while ((isHex ? isxdigit(ch) : isdigit(ch)) &&
- (index - start < width))
- {
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- }
- if (isHex ? (toupper(ch) == 'P') : (toupper(ch) == 'E'))
- {
- /* Exponent */
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- if ((ch == '+') || (ch == '-'))
- {
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- }
- while ((isHex ? isxdigit(ch) : isdigit(ch)) &&
- (index - start < width))
- {
- doubleString[index++] = (char)ch;
- self->InStream(self, &ch);
- }
- }
- }
-
- if ((index == start) || (*doubleString == NIL))
- return FALSE;
-
- doubleString[index] = 0;
-
- if (flags & FLAGS_LONGDOUBLE)
- {
- *((trio_long_double_t *)target) = trio_to_long_double(doubleString, NULL);
- }
- else
- {
- *((double *)target) = trio_to_double(doubleString, NULL);
- }
- return TRUE;
-}
-
-/*************************************************************************
- * TrioReadPointer
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadPointer
-TRIO_ARGS3((self, target, flags),
- trio_class_t *self,
- trio_pointer_t *target,
- unsigned long flags)
-{
- trio_uintmax_t number;
- char buffer[sizeof(internalNullString)];
-
- flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | FLAGS_NILPADDING);
-
- if (TrioReadNumber(self,
- &number,
- flags,
- POINTER_WIDTH,
- BASE_HEX))
- {
- /*
- * The strange assignment of number is a workaround for a compiler
- * warning
- */
- if (target)
- *target = (char *)0 + number;
- return TRUE;
- }
- else if (TrioReadString(self,
- (flags & FLAGS_IGNORE)
- ? NULL
- : buffer,
- 0,
- sizeof(internalNullString) - 1))
- {
- if (trio_equal_case(buffer, internalNullString))
- {
- if (target)
- *target = NULL;
- return TRUE;
- }
- }
- return FALSE;
-}
-
-/*************************************************************************
- * TrioScanProcess
- */
-TRIO_PRIVATE int
-TrioScanProcess
-TRIO_ARGS3((data, format, parameters),
- trio_class_t *data,
- TRIO_CONST char *format,
- trio_parameter_t *parameters)
-{
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- int charlen;
- int cnt;
-#endif
- int assignment;
- int ch;
- int index; /* Index of format string */
- int i; /* Index of current parameter */
- unsigned long flags;
- int width;
- int base;
- trio_pointer_t pointer;
-
- assignment = 0;
- i = 0;
- index = 0;
- data->InStream(data, &ch);
-
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- (void)mblen(NULL, 0);
-#endif
-
- while (format[index])
- {
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- if (! isascii(format[index]))
- {
- charlen = mblen(&format[index], MB_LEN_MAX);
- if (charlen != -1)
- {
- /* Compare multibyte characters in format string */
- for (cnt = 0; cnt < charlen - 1; cnt++)
- {
- if (ch != format[index + cnt])
- {
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- }
- data->InStream(data, &ch);
- }
- continue; /* while characters left in formatting string */
- }
- }
-#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
-
- if ((EOF == ch) && (parameters[i].type != FORMAT_COUNT))
- {
- return (assignment > 0) ? assignment : EOF;
- }
-
- if (CHAR_IDENTIFIER == format[index])
- {
- if (CHAR_IDENTIFIER == format[index + 1])
- {
- /* Two % in format matches one % in input stream */
- if (CHAR_IDENTIFIER == ch)
- {
- data->InStream(data, &ch);
- index += 2;
- continue; /* while format chars left */
- }
- else
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- }
-
- /* Skip the parameter entries */
- while (parameters[i].type == FORMAT_PARAMETER)
- i++;
-
- flags = parameters[i].flags;
- /* Find width */
- width = parameters[i].width;
- if (flags & FLAGS_WIDTH_PARAMETER)
- {
- /* Get width from parameter list */
- width = (int)parameters[width].data.number.as_signed;
- }
- /* Find base */
- base = parameters[i].base;
- if (flags & FLAGS_BASE_PARAMETER)
- {
- /* Get base from parameter list */
- base = (int)parameters[base].data.number.as_signed;
- }
-
- switch (parameters[i].type)
- {
- case FORMAT_INT:
- {
- trio_uintmax_t number;
-
- if (0 == base)
- base = BASE_DECIMAL;
-
- if (!TrioReadNumber(data,
- &number,
- flags,
- width,
- base))
- return assignment;
-
- if (!(flags & FLAGS_IGNORE))
- {
- assignment++;
-
- pointer = parameters[i].data.pointer;
-#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
- if (flags & FLAGS_SIZE_T)
- *(size_t *)pointer = (size_t)number;
- else
-#endif
-#if defined(QUALIFIER_PTRDIFF_T)
- if (flags & FLAGS_PTRDIFF_T)
- *(ptrdiff_t *)pointer = (ptrdiff_t)number;
- else
-#endif
-#if defined(QUALIFIER_INTMAX_T)
- if (flags & FLAGS_INTMAX_T)
- *(trio_intmax_t *)pointer = (trio_intmax_t)number;
- else
-#endif
- if (flags & FLAGS_QUAD)
- *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)number;
- else if (flags & FLAGS_LONG)
- *(long int *)pointer = (long int)number;
- else if (flags & FLAGS_SHORT)
- *(short int *)pointer = (short int)number;
- else
- *(int *)pointer = (int)number;
- }
- }
- break; /* FORMAT_INT */
-
- case FORMAT_STRING:
-#if TRIO_WIDECHAR
- if (flags & FLAGS_WIDECHAR)
- {
- if (!TrioReadWideString(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : parameters[i].data.wstring,
- flags,
- width))
- return assignment;
- }
- else
-#endif
- {
- if (!TrioReadString(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : parameters[i].data.string,
- flags,
- width))
- return assignment;
- }
- if (!(flags & FLAGS_IGNORE))
- assignment++;
- break; /* FORMAT_STRING */
-
- case FORMAT_DOUBLE:
- {
- trio_pointer_t pointer;
-
- if (flags & FLAGS_IGNORE)
- {
- pointer = NULL;
- }
- else
- {
- pointer = (flags & FLAGS_LONGDOUBLE)
- ? (trio_pointer_t)parameters[i].data.longdoublePointer
- : (trio_pointer_t)parameters[i].data.doublePointer;
- }
- if (!TrioReadDouble(data, pointer, flags, width))
- {
- return assignment;
- }
- if (!(flags & FLAGS_IGNORE))
- {
- assignment++;
- }
- break; /* FORMAT_DOUBLE */
- }
- case FORMAT_GROUP:
- {
- int characterclass[MAX_CHARACTER_CLASS + 1];
- int rc;
-
- /* Skip over modifiers */
- while (format[index] != SPECIFIER_GROUP)
- {
- index++;
- }
- /* Skip over group specifier */
- index++;
-
- memset(characterclass, 0, sizeof(characterclass));
- rc = TrioGetCharacterClass(format,
- &index,
- &flags,
- characterclass);
- if (rc < 0)
- return rc;
-
- if (!TrioReadGroup(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : parameters[i].data.string,
- characterclass,
- flags,
- parameters[i].width))
- return assignment;
- if (!(flags & FLAGS_IGNORE))
- assignment++;
- }
- break; /* FORMAT_GROUP */
-
- case FORMAT_COUNT:
- pointer = parameters[i].data.pointer;
- if (NULL != pointer)
- {
- int count = data->committed;
- if (ch != EOF)
- count--; /* a character is read, but is not consumed yet */
-#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
- if (flags & FLAGS_SIZE_T)
- *(size_t *)pointer = (size_t)count;
- else
-#endif
-#if defined(QUALIFIER_PTRDIFF_T)
- if (flags & FLAGS_PTRDIFF_T)
- *(ptrdiff_t *)pointer = (ptrdiff_t)count;
- else
-#endif
-#if defined(QUALIFIER_INTMAX_T)
- if (flags & FLAGS_INTMAX_T)
- *(trio_intmax_t *)pointer = (trio_intmax_t)count;
- else
-#endif
- if (flags & FLAGS_QUAD)
- {
- *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)count;
- }
- else if (flags & FLAGS_LONG)
- {
- *(long int *)pointer = (long int)count;
- }
- else if (flags & FLAGS_SHORT)
- {
- *(short int *)pointer = (short int)count;
- }
- else
- {
- *(int *)pointer = (int)count;
- }
- }
- break; /* FORMAT_COUNT */
-
- case FORMAT_CHAR:
-#if TRIO_WIDECHAR
- if (flags & FLAGS_WIDECHAR)
- {
- if (TrioReadWideChar(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : parameters[i].data.wstring,
- flags,
- (width == NO_WIDTH) ? 1 : width) == 0)
- return assignment;
- }
- else
-#endif
- {
- if (TrioReadChar(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : parameters[i].data.string,
- flags,
- (width == NO_WIDTH) ? 1 : width) == 0)
- return assignment;
- }
- if (!(flags & FLAGS_IGNORE))
- assignment++;
- break; /* FORMAT_CHAR */
-
- case FORMAT_POINTER:
- if (!TrioReadPointer(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : (trio_pointer_t *)parameters[i].data.pointer,
- flags))
- return assignment;
- if (!(flags & FLAGS_IGNORE))
- assignment++;
- break; /* FORMAT_POINTER */
-
- case FORMAT_PARAMETER:
- break; /* FORMAT_PARAMETER */
-
- default:
- return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
- }
- ch = data->current;
- index = parameters[i].indexAfterSpecifier;
- i++;
- }
- else /* Not an % identifier */
- {
- if (isspace((int)format[index]))
- {
- /* Whitespaces may match any amount of whitespaces */
- ch = TrioSkipWhitespaces(data);
- }
- else if (ch == format[index])
- {
- data->InStream(data, &ch);
- }
- else
- return assignment;
-
- index++;
- }
- }
- return assignment;
-}
-
-/*************************************************************************
- * TrioScan
- */
-TRIO_PRIVATE int
-TrioScan
-TRIO_ARGS6((source, sourceSize, InStream, format, arglist, argarray),
- trio_pointer_t source,
- size_t sourceSize,
- void (*InStream) TRIO_PROTO((trio_class_t *, int *)),
- TRIO_CONST char *format,
- va_list *arglist,
- trio_pointer_t *argarray)
-{
- int status;
- trio_parameter_t parameters[MAX_PARAMETERS];
- trio_class_t data;
-
- assert(VALID(InStream));
- assert(VALID(format));
-
- memset(&data, 0, sizeof(data));
- data.InStream = InStream;
- data.location = (trio_pointer_t)source;
- data.max = sourceSize;
- data.error = 0;
-
-#if defined(USE_LOCALE)
- if (NULL == internalLocaleValues)
- {
- TrioSetLocale();
- }
-#endif
-
- status = TrioParse(TYPE_SCAN, format, parameters, arglist, argarray);
- if (status < 0)
- return status;
-
- status = TrioScanProcess(&data, format, parameters);
- if (data.error != 0)
- {
- status = data.error;
- }
- return status;
-}
-
-/*************************************************************************
- * TrioInStreamFile
- */
-TRIO_PRIVATE void
-TrioInStreamFile
-TRIO_ARGS2((self, intPointer),
- trio_class_t *self,
- int *intPointer)
-{
- FILE *file = (FILE *)self->location;
-
- assert(VALID(self));
- assert(VALID(file));
-
- self->current = fgetc(file);
- if (self->current == EOF)
- {
- self->error = (ferror(file))
- ? TRIO_ERROR_RETURN(TRIO_ERRNO, 0)
- : TRIO_ERROR_RETURN(TRIO_EOF, 0);
- }
- else
- {
- self->processed++;
- self->committed++;
- }
-
- if (VALID(intPointer))
- {
- *intPointer = self->current;
- }
-}
-
-/*************************************************************************
- * TrioInStreamFileDescriptor
- */
-TRIO_PRIVATE void
-TrioInStreamFileDescriptor
-TRIO_ARGS2((self, intPointer),
- trio_class_t *self,
- int *intPointer)
-{
- int fd = *((int *)self->location);
- int size;
- unsigned char input;
-
- assert(VALID(self));
-
- size = read(fd, &input, sizeof(char));
- if (size == -1)
- {
- self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0);
- self->current = EOF;
- }
- else
- {
- self->current = (size == 0) ? EOF : input;
- }
- if (self->current != EOF)
- {
- self->committed++;
- self->processed++;
- }
-
- if (VALID(intPointer))
- {
- *intPointer = self->current;
- }
-}
-
-/*************************************************************************
- * TrioInStreamCustom
- */
-TRIO_PRIVATE void
-TrioInStreamCustom
-TRIO_ARGS2((self, intPointer),
- trio_class_t *self,
- int *intPointer)
-{
- trio_custom_t *data;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- data = (trio_custom_t *)self->location;
-
- self->current = (data->stream.in == NULL)
- ? NIL
- : (data->stream.in)(data->closure);
-
- if (self->current == NIL)
- {
- self->current = EOF;
- }
- else
- {
- self->processed++;
- self->committed++;
- }
-
- if (VALID(intPointer))
- {
- *intPointer = self->current;
- }
-}
-
-/*************************************************************************
- * TrioInStreamString
- */
-TRIO_PRIVATE void
-TrioInStreamString
-TRIO_ARGS2((self, intPointer),
- trio_class_t *self,
- int *intPointer)
-{
- unsigned char **buffer;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- buffer = (unsigned char **)self->location;
- self->current = (*buffer)[0];
- if (self->current == NIL)
- {
- self->current = EOF;
- }
- else
- {
- (*buffer)++;
- self->processed++;
- self->committed++;
- }
-
- if (VALID(intPointer))
- {
- *intPointer = self->current;
- }
-}
-
-/*************************************************************************
- *
- * Formatted scanning functions
- *
- ************************************************************************/
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_scanf.h"
-#endif
-/** @addtogroup Scanf
- @{
-*/
-
-/*************************************************************************
- * scanf
- */
-
-/**
- Scan characters from standard input stream.
-
- @param format Formatting string.
- @param ... Arguments.
- @return Number of scanned characters.
- */
-TRIO_PUBLIC int
-trio_scanf
-TRIO_VARGS2((format, va_alist),
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioScan((trio_pointer_t)stdin, 0,
- TrioInStreamFile,
- format, &args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-TRIO_PUBLIC int
-trio_vscanf
-TRIO_ARGS2((format, args),
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)stdin, 0,
- TrioInStreamFile,
- format, &args, NULL);
-}
-
-TRIO_PUBLIC int
-trio_scanfv
-TRIO_ARGS2((format, args),
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)stdin, 0,
- TrioInStreamFile,
- format, NULL, args);
-}
-
-/*************************************************************************
- * fscanf
- */
-TRIO_PUBLIC int
-trio_fscanf
-TRIO_VARGS3((file, format, va_alist),
- FILE *file,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(file));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioScan((trio_pointer_t)file, 0,
- TrioInStreamFile,
- format, &args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-TRIO_PUBLIC int
-trio_vfscanf
-TRIO_ARGS3((file, format, args),
- FILE *file,
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(file));
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)file, 0,
- TrioInStreamFile,
- format, &args, NULL);
-}
-
-TRIO_PUBLIC int
-trio_fscanfv
-TRIO_ARGS3((file, format, args),
- FILE *file,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- assert(VALID(file));
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)file, 0,
- TrioInStreamFile,
- format, NULL, args);
-}
-
-/*************************************************************************
- * dscanf
- */
-TRIO_PUBLIC int
-trio_dscanf
-TRIO_VARGS3((fd, format, va_alist),
- int fd,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioScan((trio_pointer_t)&fd, 0,
- TrioInStreamFileDescriptor,
- format, &args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-TRIO_PUBLIC int
-trio_vdscanf
-TRIO_ARGS3((fd, format, args),
- int fd,
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)&fd, 0,
- TrioInStreamFileDescriptor,
- format, &args, NULL);
-}
-
-TRIO_PUBLIC int
-trio_dscanfv
-TRIO_ARGS3((fd, format, args),
- int fd,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)&fd, 0,
- TrioInStreamFileDescriptor,
- format, NULL, args);
-}
-
-/*************************************************************************
- * cscanf
- */
-TRIO_PUBLIC int
-trio_cscanf
-TRIO_VARGS4((stream, closure, format, va_alist),
- trio_instream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- data.stream.in = stream;
- data.closure = closure;
- status = TrioScan(&data, 0, TrioInStreamCustom, format, &args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-TRIO_PUBLIC int
-trio_vcscanf
-TRIO_ARGS4((stream, closure, format, args),
- trio_instream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- va_list args)
-{
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- data.stream.in = stream;
- data.closure = closure;
- return TrioScan(&data, 0, TrioInStreamCustom, format, &args, NULL);
-}
-
-TRIO_PUBLIC int
-trio_cscanfv
-TRIO_ARGS4((stream, closure, format, args),
- trio_instream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- data.stream.in = stream;
- data.closure = closure;
- return TrioScan(&data, 0, TrioInStreamCustom, format, NULL, args);
-}
-
-/*************************************************************************
- * sscanf
- */
-TRIO_PUBLIC int
-trio_sscanf
-TRIO_VARGS3((buffer, format, va_alist),
- TRIO_CONST char *buffer,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioScan((trio_pointer_t)&buffer, 0,
- TrioInStreamString,
- format, &args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-TRIO_PUBLIC int
-trio_vsscanf
-TRIO_ARGS3((buffer, format, args),
- TRIO_CONST char *buffer,
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(buffer));
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)&buffer, 0,
- TrioInStreamString,
- format, &args, NULL);
-}
-
-TRIO_PUBLIC int
-trio_sscanfv
-TRIO_ARGS3((buffer, format, args),
- TRIO_CONST char *buffer,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- assert(VALID(buffer));
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)&buffer, 0,
- TrioInStreamString,
- format, NULL, args);
-}
-
-/** @} End of Scanf documentation module */
-
-/*************************************************************************
- * trio_strerror
- */
-TRIO_PUBLIC TRIO_CONST char *
-trio_strerror
-TRIO_ARGS1((errorcode),
- int errorcode)
-{
- /* Textual versions of the error codes */
- switch (TRIO_ERROR_CODE(errorcode))
- {
- case TRIO_EOF:
- return "End of file";
- case TRIO_EINVAL:
- return "Invalid argument";
- case TRIO_ETOOMANY:
- return "Too many arguments";
- case TRIO_EDBLREF:
- return "Double reference";
- case TRIO_EGAP:
- return "Reference gap";
- case TRIO_ENOMEM:
- return "Out of memory";
- case TRIO_ERANGE:
- return "Invalid range";
- case TRIO_ECUSTOM:
- return "Custom error";
- default:
- return "Unknown";
- }
-}
diff --git a/bundle/libxml/trio.h b/bundle/libxml/trio.h
deleted file mode 100644
index 770c6a6f58..0000000000
--- a/bundle/libxml/trio.h
+++ /dev/null
@@ -1,216 +0,0 @@
-/*************************************************************************
- *
- * $Id$
- *
- * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- *************************************************************************
- *
- * http://ctrio.sourceforge.net/
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIO_H
-#define TRIO_TRIO_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#if defined(TRIO_COMPILER_ANCIENT)
-# include <varargs.h>
-#else
-# include <stdarg.h>
-#endif
-
-#if !defined(WITHOUT_TRIO)
-
-/*
- * Use autoconf defines if present. Packages using trio must define
- * HAVE_CONFIG_H as a compiler option themselves.
- */
-#if defined(HAVE_CONFIG_H)
-# include <config.h>
-#endif
-
-#include "triodef.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Error codes.
- *
- * Remember to add a textual description to trio_strerror.
- */
-enum {
- TRIO_EOF = 1,
- TRIO_EINVAL = 2,
- TRIO_ETOOMANY = 3,
- TRIO_EDBLREF = 4,
- TRIO_EGAP = 5,
- TRIO_ENOMEM = 6,
- TRIO_ERANGE = 7,
- TRIO_ERRNO = 8,
- TRIO_ECUSTOM = 9
-};
-
-/* Error macros */
-#define TRIO_ERROR_CODE(x) ((-(x)) & 0x00FF)
-#define TRIO_ERROR_POSITION(x) ((-(x)) >> 8)
-#define TRIO_ERROR_NAME(x) trio_strerror(x)
-
-typedef int (*trio_outstream_t) TRIO_PROTO((trio_pointer_t, int));
-typedef int (*trio_instream_t) TRIO_PROTO((trio_pointer_t));
-
-TRIO_CONST char *trio_strerror TRIO_PROTO((int));
-
-/*************************************************************************
- * Print Functions
- */
-
-int trio_printf TRIO_PROTO((TRIO_CONST char *format, ...));
-int trio_vprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));
-int trio_printfv TRIO_PROTO((TRIO_CONST char *format, void **args));
-
-int trio_fprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));
-int trio_vfprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));
-int trio_fprintfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));
-
-int trio_dprintf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));
-int trio_vdprintf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));
-int trio_dprintfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));
-
-int trio_cprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, ...));
-int trio_vcprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, va_list args));
-int trio_cprintfv TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, void **args));
-
-int trio_sprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, ...));
-int trio_vsprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, va_list args));
-int trio_sprintfv TRIO_PROTO((char *buffer, TRIO_CONST char *format, void **args));
-
-int trio_snprintf TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));
-int trio_vsnprintf TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
- va_list args));
-int trio_snprintfv TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
- void **args));
-
-int trio_snprintfcat TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));
-int trio_vsnprintfcat TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
- va_list args));
-
-char *trio_aprintf TRIO_PROTO((TRIO_CONST char *format, ...));
-char *trio_vaprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));
-
-int trio_asprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, ...));
-int trio_vasprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, va_list args));
-
-/*************************************************************************
- * Scan Functions
- */
-int trio_scanf TRIO_PROTO((TRIO_CONST char *format, ...));
-int trio_vscanf TRIO_PROTO((TRIO_CONST char *format, va_list args));
-int trio_scanfv TRIO_PROTO((TRIO_CONST char *format, void **args));
-
-int trio_fscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));
-int trio_vfscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));
-int trio_fscanfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));
-
-int trio_dscanf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));
-int trio_vdscanf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));
-int trio_dscanfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));
-
-int trio_cscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, ...));
-int trio_vcscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, va_list args));
-int trio_cscanfv TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, void **args));
-
-int trio_sscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, ...));
-int trio_vsscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, va_list args));
-int trio_sscanfv TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, void **args));
-
-/*************************************************************************
- * Locale Functions
- */
-void trio_locale_set_decimal_point TRIO_PROTO((char *decimalPoint));
-void trio_locale_set_thousand_separator TRIO_PROTO((char *thousandSeparator));
-void trio_locale_set_grouping TRIO_PROTO((char *grouping));
-
-/*************************************************************************
- * Renaming
- */
-#ifdef TRIO_REPLACE_STDIO
-/* Replace the <stdio.h> functions */
-#ifndef HAVE_PRINTF
-# define printf trio_printf
-#endif
-#ifndef HAVE_VPRINTF
-# define vprintf trio_vprintf
-#endif
-#ifndef HAVE_FPRINTF
-# define fprintf trio_fprintf
-#endif
-#ifndef HAVE_VFPRINTF
-# define vfprintf trio_vfprintf
-#endif
-#ifndef HAVE_SPRINTF
-# define sprintf trio_sprintf
-#endif
-#ifndef HAVE_VSPRINTF
-# define vsprintf trio_vsprintf
-#endif
-#ifndef HAVE_SNPRINTF
-# define snprintf trio_snprintf
-#endif
-#ifndef HAVE_VSNPRINTF
-# define vsnprintf trio_vsnprintf
-#endif
-#ifndef HAVE_SCANF
-# define scanf trio_scanf
-#endif
-#ifndef HAVE_VSCANF
-# define vscanf trio_vscanf
-#endif
-#ifndef HAVE_FSCANF
-# define fscanf trio_fscanf
-#endif
-#ifndef HAVE_VFSCANF
-# define vfscanf trio_vfscanf
-#endif
-#ifndef HAVE_SSCANF
-# define sscanf trio_sscanf
-#endif
-#ifndef HAVE_VSSCANF
-# define vsscanf trio_vsscanf
-#endif
-/* These aren't stdio functions, but we make them look similar */
-#define dprintf trio_dprintf
-#define vdprintf trio_vdprintf
-#define aprintf trio_aprintf
-#define vaprintf trio_vaprintf
-#define asprintf trio_asprintf
-#define vasprintf trio_vasprintf
-#define dscanf trio_dscanf
-#define vdscanf trio_vdscanf
-#endif
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* WITHOUT_TRIO */
-
-#endif /* TRIO_TRIO_H */
diff --git a/bundle/libxml/triodef.h b/bundle/libxml/triodef.h
deleted file mode 100644
index 73d64311a7..0000000000
--- a/bundle/libxml/triodef.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*************************************************************************
- *
- * $Id$
- *
- * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIODEF_H
-#define TRIO_TRIODEF_H
-
-/*************************************************************************
- * Platform and compiler support detection
- */
-#if defined(__GNUC__)
-# define TRIO_COMPILER_GCC
-#elif defined(__SUNPRO_C)
-# define TRIO_COMPILER_SUNPRO
-#elif defined(__SUNPRO_CC)
-# define TRIO_COMPILER_SUNPRO
-# define __SUNPRO_C __SUNPRO_CC
-#elif defined(__xlC__) || defined(__IBMC__) || defined(__IBMCPP__)
-# define TRIO_COMPILER_XLC
-#elif defined(_AIX) && !defined(__GNUC__)
-# define TRIO_COMPILER_XLC /* Workaround for old xlc */
-#elif defined(__DECC) || defined(__DECCXX)
-# define TRIO_COMPILER_DECC
-#elif defined(__osf__) && defined(__LANGUAGE_C__)
-# define TRIO_COMPILER_DECC /* Workaround for old DEC C compilers */
-#elif defined(_MSC_VER)
-# define TRIO_COMPILER_MSVC
-#elif defined(__BORLANDC__)
-# define TRIO_COMPILER_BCB
-#endif
-
-#if defined(unix) || defined(__unix) || defined(__unix__)
-# define TRIO_PLATFORM_UNIX
-#elif defined(TRIO_COMPILER_XLC) || defined(_AIX)
-# define TRIO_PLATFORM_UNIX
-#elif ( defined(TRIO_COMPILER_DECC) && !defined(__VMS) ) || defined(__osf__)
-# define TRIO_PLATFORM_UNIX
-#elif defined(__NetBSD__)
-# define TRIO_PLATFORM_UNIX
-#elif defined(__QNX__)
-# define TRIO_PLATFORM_UNIX
-# define TRIO_PLATFORM_QNX
-#elif defined(__CYGWIN__)
-# define TRIO_PLATFORM_UNIX
-#elif defined(AMIGA) && defined(TRIO_COMPILER_GCC)
-# define TRIO_PLATFORM_UNIX
-#elif defined(TRIO_COMPILER_MSVC) || defined(WIN32) || defined(_WIN32)
-# define TRIO_PLATFORM_WIN32
-#elif defined(VMS) || defined(__VMS)
-# define TRIO_PLATFORM_VMS
-#elif defined(mpeix) || defined(__mpexl)
-# define TRIO_PLATFORM_MPEIX
-#endif
-
-#if defined(__STDC__) || defined(TRIO_COMPILER_MSVC)
-# define TRIO_COMPILER_SUPPORTS_C89
-# if defined(__STDC_VERSION__)
-# define TRIO_COMPILER_SUPPORTS_C90
-# if (__STDC_VERSION__ >= 199409L)
-# define TRIO_COMPILER_SUPPORTS_C94
-# endif
-# if (__STDC_VERSION__ >= 199901L)
-# define TRIO_COMPILER_SUPPORTS_C99
-# endif
-# elif defined(TRIO_COMPILER_SUNPRO)
-# if (__SUNPRO_C >= 0x420)
-# define TRIO_COMPILER_SUPPORTS_C94
-# endif
-# endif
-#endif
-
-#if defined(TRIO_PLATFORM_VMS)
- /* The compiler does support C99 but the library still does not have things
- * the standard requires (like nan() and strtof()) as of __CRTL_VER 70300022.
- */
-# undef TRIO_COMPILER_SUPPORTS_C99
-
- /* Computations done with constants at compile time can trigger these
- * even when compiling with IEEE enabled.
- */
-# pragma message disable (UNDERFLOW,FLOATOVERFL)
-#endif /* TRIO_PLATFORM_VMS */
-
-#if defined(_XOPEN_SOURCE)
-# if defined(_XOPEN_SOURCE_EXTENDED)
-# define TRIO_COMPILER_SUPPORTS_UNIX95
-# endif
-# if (_XOPEN_VERSION >= 500)
-# define TRIO_COMPILER_SUPPORTS_UNIX98
-# endif
-# if (_XOPEN_VERSION >= 600)
-# define TRIO_COMPILER_SUPPORTS_UNIX01
-# endif
-#endif
-
-/*************************************************************************
- * Generic defines
- */
-
-#if !defined(TRIO_PUBLIC)
-# define TRIO_PUBLIC
-#endif
-#if !defined(TRIO_PRIVATE)
-# define TRIO_PRIVATE static
-#endif
-
-#if !(defined(TRIO_COMPILER_SUPPORTS_C89) || defined(__cplusplus))
-# define TRIO_COMPILER_ANCIENT
-#endif
-
-#if defined(TRIO_COMPILER_ANCIENT)
-# define TRIO_CONST
-# define TRIO_VOLATILE
-# define TRIO_SIGNED
-typedef double trio_long_double_t;
-typedef char * trio_pointer_t;
-# define TRIO_SUFFIX_LONG(x) x
-# define TRIO_PROTO(x) ()
-# define TRIO_NOARGS
-# define TRIO_ARGS1(list,a1) list a1;
-# define TRIO_ARGS2(list,a1,a2) list a1; a2;
-# define TRIO_ARGS3(list,a1,a2,a3) list a1; a2; a3;
-# define TRIO_ARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4;
-# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5;
-# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) list a1; a2; a3; a4; a5; a6;
-# define TRIO_VARGS2(list,a1,a2) list a1; a2
-# define TRIO_VARGS3(list,a1,a2,a3) list a1; a2; a3
-# define TRIO_VARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4
-# define TRIO_VARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5
-# define TRIO_VA_DECL va_dcl
-# define TRIO_VA_START(x,y) va_start((x))
-# define TRIO_VA_END(x) va_end(x)
-#else /* ANSI C */
-# define TRIO_CONST const
-# define TRIO_VOLATILE volatile
-# define TRIO_SIGNED signed
-typedef long double trio_long_double_t;
-typedef void * trio_pointer_t;
-# define TRIO_SUFFIX_LONG(x) x ## L
-# define TRIO_PROTO(x) x
-# define TRIO_NOARGS void
-# define TRIO_ARGS1(list,a1) (a1)
-# define TRIO_ARGS2(list,a1,a2) (a1,a2)
-# define TRIO_ARGS3(list,a1,a2,a3) (a1,a2,a3)
-# define TRIO_ARGS4(list,a1,a2,a3,a4) (a1,a2,a3,a4)
-# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) (a1,a2,a3,a4,a5)
-# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) (a1,a2,a3,a4,a5,a6)
-# define TRIO_VARGS2 TRIO_ARGS2
-# define TRIO_VARGS3 TRIO_ARGS3
-# define TRIO_VARGS4 TRIO_ARGS4
-# define TRIO_VARGS5 TRIO_ARGS5
-# define TRIO_VA_DECL ...
-# define TRIO_VA_START(x,y) va_start((x),(y))
-# define TRIO_VA_END(x) va_end(x)
-#endif
-
-#if defined(TRIO_COMPILER_SUPPORTS_C99) || defined(__cplusplus)
-# define TRIO_INLINE inline
-#elif defined(TRIO_COMPILER_GCC)
-# define TRIO_INLINE __inline__
-#elif defined(TRIO_COMPILER_MSVC)
-# define TRIO_INLINE _inline
-#elif defined(TRIO_COMPILER_BCB)
-# define TRIO_INLINE __inline
-#else
-# define TRIO_INLINE
-#endif
-
-#endif /* TRIO_TRIODEF_H */
diff --git a/bundle/libxml/trionan.c b/bundle/libxml/trionan.c
deleted file mode 100644
index 3a65986b85..0000000000
--- a/bundle/libxml/trionan.c
+++ /dev/null
@@ -1,913 +0,0 @@
-/*************************************************************************
- *
- * $Id$
- *
- * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************
- *
- * Functions to handle special quantities in floating-point numbers
- * (that is, NaNs and infinity). They provide the capability to detect
- * and fabricate special quantities.
- *
- * Although written to be as portable as possible, it can never be
- * guaranteed to work on all platforms, as not all hardware supports
- * special quantities.
- *
- * The approach used here (approximately) is to:
- *
- * 1. Use C99 functionality when available.
- * 2. Use IEEE 754 bit-patterns if possible.
- * 3. Use platform-specific techniques.
- *
- ************************************************************************/
-
-/*
- * TODO:
- * o Put all the magic into trio_fpclassify_and_signbit(), and use this from
- * trio_isnan() etc.
- */
-
-/*************************************************************************
- * Include files
- */
-#include "triodef.h"
-#include "trionan.h"
-
-#include <math.h>
-#include <string.h>
-#include <limits.h>
-#include <float.h>
-#if defined(TRIO_PLATFORM_UNIX)
-# include <signal.h>
-#endif
-#if defined(TRIO_COMPILER_DECC)
-# include <fp_class.h>
-#endif
-#include <assert.h>
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_nan.h"
-#endif
-/** @addtogroup SpecialQuantities
- @{
-*/
-
-/*************************************************************************
- * Definitions
- */
-
-#define TRIO_TRUE (1 == 1)
-#define TRIO_FALSE (0 == 1)
-
-/* We must enable IEEE floating-point on Alpha */
-#if defined(__alpha) && !defined(_IEEE_FP)
-# if defined(TRIO_COMPILER_DECC)
-# if defined(TRIO_PLATFORM_VMS)
-# error "Must be compiled with option /IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE"
-# else
-# if !defined(_CFE)
-# error "Must be compiled with option -ieee"
-# endif
-# endif
-# elif defined(TRIO_COMPILER_GCC) && (defined(__osf__) || defined(__linux__))
-# error "Must be compiled with option -mieee"
-# endif
-#endif /* __alpha && ! _IEEE_FP */
-
-/*
- * In ANSI/IEEE 754-1985 64-bits double format numbers have the
- * following properties (amoungst others)
- *
- * o FLT_RADIX == 2: binary encoding
- * o DBL_MAX_EXP == 1024: 11 bits exponent, where one bit is used
- * to indicate special numbers (e.g. NaN and Infinity), so the
- * maximum exponent is 10 bits wide (2^10 == 1024).
- * o DBL_MANT_DIG == 53: The mantissa is 52 bits wide, but because
- * numbers are normalized the initial binary 1 is represented
- * implicitly (the so-called "hidden bit"), which leaves us with
- * the ability to represent 53 bits wide mantissa.
- */
-#if (FLT_RADIX == 2) && (DBL_MAX_EXP == 1024) && (DBL_MANT_DIG == 53)
-# define USE_IEEE_754
-#endif
-
-
-/*************************************************************************
- * Constants
- */
-
-static TRIO_CONST char rcsid[] = "@(#)$Id$";
-
-#if defined(USE_IEEE_754)
-
-/*
- * Endian-agnostic indexing macro.
- *
- * The value of internalEndianMagic, when converted into a 64-bit
- * integer, becomes 0x0706050403020100 (we could have used a 64-bit
- * integer value instead of a double, but not all platforms supports
- * that type). The value is automatically encoded with the correct
- * endianess by the compiler, which means that we can support any
- * kind of endianess. The individual bytes are then used as an index
- * for the IEEE 754 bit-patterns and masks.
- */
-#define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)])
-
-static TRIO_CONST double internalEndianMagic = 7.949928895127363e-275;
-
-/* Mask for the exponent */
-static TRIO_CONST unsigned char ieee_754_exponent_mask[] = {
- 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* Mask for the mantissa */
-static TRIO_CONST unsigned char ieee_754_mantissa_mask[] = {
- 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
-};
-
-/* Mask for the sign bit */
-static TRIO_CONST unsigned char ieee_754_sign_mask[] = {
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* Bit-pattern for negative zero */
-static TRIO_CONST unsigned char ieee_754_negzero_array[] = {
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* Bit-pattern for infinity */
-static TRIO_CONST unsigned char ieee_754_infinity_array[] = {
- 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* Bit-pattern for quiet NaN */
-static TRIO_CONST unsigned char ieee_754_qnan_array[] = {
- 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-
-/*************************************************************************
- * Functions
- */
-
-/*
- * trio_make_double
- */
-TRIO_PRIVATE double
-trio_make_double
-TRIO_ARGS1((values),
- TRIO_CONST unsigned char *values)
-{
- TRIO_VOLATILE double result;
- int i;
-
- for (i = 0; i < (int)sizeof(double); i++) {
- ((TRIO_VOLATILE unsigned char *)&result)[TRIO_DOUBLE_INDEX(i)] = values[i];
- }
- return result;
-}
-
-/*
- * trio_is_special_quantity
- */
-TRIO_PRIVATE int
-trio_is_special_quantity
-TRIO_ARGS2((number, has_mantissa),
- double number,
- int *has_mantissa)
-{
- unsigned int i;
- unsigned char current;
- int is_special_quantity = TRIO_TRUE;
-
- *has_mantissa = 0;
-
- for (i = 0; i < (unsigned int)sizeof(double); i++) {
- current = ((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)];
- is_special_quantity
- &= ((current & ieee_754_exponent_mask[i]) == ieee_754_exponent_mask[i]);
- *has_mantissa |= (current & ieee_754_mantissa_mask[i]);
- }
- return is_special_quantity;
-}
-
-/*
- * trio_is_negative
- */
-TRIO_PRIVATE int
-trio_is_negative
-TRIO_ARGS1((number),
- double number)
-{
- unsigned int i;
- int is_negative = TRIO_FALSE;
-
- for (i = 0; i < (unsigned int)sizeof(double); i++) {
- is_negative |= (((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)]
- & ieee_754_sign_mask[i]);
- }
- return is_negative;
-}
-
-#endif /* USE_IEEE_754 */
-
-
-/**
- Generate negative zero.
-
- @return Floating-point representation of negative zero.
-*/
-TRIO_PUBLIC double
-trio_nzero(TRIO_NOARGS)
-{
-#if defined(USE_IEEE_754)
- return trio_make_double(ieee_754_negzero_array);
-#else
- TRIO_VOLATILE double zero = 0.0;
-
- return -zero;
-#endif
-}
-
-/**
- Generate positive infinity.
-
- @return Floating-point representation of positive infinity.
-*/
-TRIO_PUBLIC double
-trio_pinf(TRIO_NOARGS)
-{
- /* Cache the result */
- static double result = 0.0;
-
- if (result == 0.0) {
-
-#if defined(INFINITY) && defined(__STDC_IEC_559__)
- result = (double)INFINITY;
-
-#elif defined(USE_IEEE_754)
- result = trio_make_double(ieee_754_infinity_array);
-
-#else
- /*
- * If HUGE_VAL is different from DBL_MAX, then HUGE_VAL is used
- * as infinity. Otherwise we have to resort to an overflow
- * operation to generate infinity.
- */
-# if defined(TRIO_PLATFORM_UNIX)
- void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-# endif
-
- result = HUGE_VAL;
- if (HUGE_VAL == DBL_MAX) {
- /* Force overflow */
- result += HUGE_VAL;
- }
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal(SIGFPE, signal_handler);
-# endif
-
-#endif
- }
- return result;
-}
-
-/**
- Generate negative infinity.
-
- @return Floating-point value of negative infinity.
-*/
-TRIO_PUBLIC double
-trio_ninf(TRIO_NOARGS)
-{
- static double result = 0.0;
-
- if (result == 0.0) {
- /*
- * Negative infinity is calculated by negating positive infinity,
- * which can be done because it is legal to do calculations on
- * infinity (for example, 1 / infinity == 0).
- */
- result = -trio_pinf();
- }
- return result;
-}
-
-/**
- Generate NaN.
-
- @return Floating-point representation of NaN.
-*/
-TRIO_PUBLIC double
-trio_nan(TRIO_NOARGS)
-{
- /* Cache the result */
- static double result = 0.0;
-
- if (result == 0.0) {
-
-#if defined(TRIO_COMPILER_SUPPORTS_C99)
- result = nan("");
-
-#elif defined(NAN) && defined(__STDC_IEC_559__)
- result = (double)NAN;
-
-#elif defined(USE_IEEE_754)
- result = trio_make_double(ieee_754_qnan_array);
-
-#else
- /*
- * There are several ways to generate NaN. The one used here is
- * to divide infinity by infinity. I would have preferred to add
- * negative infinity to positive infinity, but that yields wrong
- * result (infinity) on FreeBSD.
- *
- * This may fail if the hardware does not support NaN, or if
- * the Invalid Operation floating-point exception is unmasked.
- */
-# if defined(TRIO_PLATFORM_UNIX)
- void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-# endif
-
- result = trio_pinf() / trio_pinf();
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal(SIGFPE, signal_handler);
-# endif
-
-#endif
- }
- return result;
-}
-
-/**
- Check for NaN.
-
- @param number An arbitrary floating-point number.
- @return Boolean value indicating whether or not the number is a NaN.
-*/
-TRIO_PUBLIC int
-trio_isnan
-TRIO_ARGS1((number),
- double number)
-{
-#if (defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isnan)) \
- || defined(TRIO_COMPILER_SUPPORTS_UNIX95)
- /*
- * C99 defines isnan() as a macro. UNIX95 defines isnan() as a
- * function. This function was already present in XPG4, but this
- * is a bit tricky to detect with compiler defines, so we choose
- * the conservative approach and only use it for UNIX95.
- */
- return isnan(number);
-
-#elif defined(TRIO_COMPILER_MSVC)
- /*
- * MSVC has an _isnan() function
- */
- return _isnan(number);
-
-#elif defined(USE_IEEE_754)
- /*
- * Examine IEEE 754 bit-pattern. A NaN must have a special exponent
- * pattern, and a non-empty mantissa.
- */
- int has_mantissa;
- int is_special_quantity;
-
- is_special_quantity = trio_is_special_quantity(number, &has_mantissa);
-
- return (is_special_quantity && has_mantissa);
-
-#else
- /*
- * Fallback solution
- */
- int status;
- double integral, fraction;
-
-# if defined(TRIO_PLATFORM_UNIX)
- void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-# endif
-
- status = (/*
- * NaN is the only number which does not compare to itself
- */
- ((TRIO_VOLATILE double)number != (TRIO_VOLATILE double)number) ||
- /*
- * Fallback solution if NaN compares to NaN
- */
- ((number != 0.0) &&
- (fraction = modf(number, &integral),
- integral == fraction)));
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal(SIGFPE, signal_handler);
-# endif
-
- return status;
-
-#endif
-}
-
-/**
- Check for infinity.
-
- @param number An arbitrary floating-point number.
- @return 1 if positive infinity, -1 if negative infinity, 0 otherwise.
-*/
-TRIO_PUBLIC int
-trio_isinf
-TRIO_ARGS1((number),
- double number)
-{
-#if defined(TRIO_COMPILER_DECC)
- /*
- * DECC has an isinf() macro, but it works differently than that
- * of C99, so we use the fp_class() function instead.
- */
- return ((fp_class(number) == FP_POS_INF)
- ? 1
- : ((fp_class(number) == FP_NEG_INF) ? -1 : 0));
-
-#elif defined(isinf)
- /*
- * C99 defines isinf() as a macro.
- */
- return isinf(number)
- ? ((number > 0.0) ? 1 : -1)
- : 0;
-
-#elif defined(TRIO_COMPILER_MSVC)
- /*
- * MSVC has an _fpclass() function that can be used to detect infinity.
- */
- return ((_fpclass(number) == _FPCLASS_PINF)
- ? 1
- : ((_fpclass(number) == _FPCLASS_NINF) ? -1 : 0));
-
-#elif defined(USE_IEEE_754)
- /*
- * Examine IEEE 754 bit-pattern. Infinity must have a special exponent
- * pattern, and an empty mantissa.
- */
- int has_mantissa;
- int is_special_quantity;
-
- is_special_quantity = trio_is_special_quantity(number, &has_mantissa);
-
- return (is_special_quantity && !has_mantissa)
- ? ((number < 0.0) ? -1 : 1)
- : 0;
-
-#else
- /*
- * Fallback solution.
- */
- int status;
-
-# if defined(TRIO_PLATFORM_UNIX)
- void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-# endif
-
- double infinity = trio_pinf();
-
- status = ((number == infinity)
- ? 1
- : ((number == -infinity) ? -1 : 0));
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal(SIGFPE, signal_handler);
-# endif
-
- return status;
-
-#endif
-}
-
-
-/**
- Check for finity.
-
- @param number An arbitrary floating-point number.
- @return Boolean value indicating whether or not the number is a finite.
-*/
-TRIO_PUBLIC int
-trio_isfinite
-TRIO_ARGS1((number),
- double number)
-{
-#if defined(TRIO_COMPILER_SUPPORTS_C99) && defined(isfinite)
- /*
- * C99 defines isfinite() as a macro.
- */
- return isfinite(number);
-
-#elif defined(TRIO_COMPILER_MSVC)
- /*
- * MSVC uses _finite().
- */
- return _finite(number);
-
-#elif defined(USE_IEEE_754)
- /*
- * Examine IEEE 754 bit-pattern. For finity we do not care about the
- * mantissa.
- */
- int dummy;
-
- return (! trio_is_special_quantity(number, &dummy));
-
-#else
- /*
- * Fallback solution.
- */
- return ((trio_isinf(number) == 0) && (trio_isnan(number) == 0));
-
-#endif
-}
-
-/*
- * The sign of NaN is always false
- */
-TRIO_PUBLIC int
-trio_fpclassify_and_signbit
-TRIO_ARGS2((number, is_negative),
- double number,
- int *is_negative)
-{
-#if defined(fpclassify) && defined(signbit)
- /*
- * C99 defines fpclassify() and signbit() as a macros
- */
- *is_negative = signbit(number);
- switch (fpclassify(number)) {
- case FP_NAN:
- return TRIO_FP_NAN;
- case FP_INFINITE:
- return TRIO_FP_INFINITE;
- case FP_SUBNORMAL:
- return TRIO_FP_SUBNORMAL;
- case FP_ZERO:
- return TRIO_FP_ZERO;
- default:
- return TRIO_FP_NORMAL;
- }
-
-#elif defined(TRIO_COMPILER_DECC)
- /*
- * DECC has an fp_class() function.
- */
- switch (fp_class(number)) {
- case FP_QNAN:
- case FP_SNAN:
- *is_negative = TRIO_FALSE; /* NaN has no sign */
- return TRIO_FP_NAN;
- case FP_POS_INF:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_INFINITE;
- case FP_NEG_INF:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_INFINITE;
- case FP_POS_DENORM:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_SUBNORMAL;
- case FP_NEG_DENORM:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_SUBNORMAL;
- case FP_POS_ZERO:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_ZERO;
- case FP_NEG_ZERO:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_ZERO;
- case FP_POS_NORM:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_NORMAL;
- case FP_NEG_NORM:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_NORMAL;
- default:
- /* Just in case... */
- *is_negative = (number < 0.0);
- return TRIO_FP_NORMAL;
- }
-
-#elif defined(TRIO_COMPILER_MSVC)
- /*
- * MSVC has an _fpclass() function.
- */
- switch (_fpclass(number)) {
- case _FPCLASS_QNAN:
- case _FPCLASS_SNAN:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_NAN;
- case _FPCLASS_PINF:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_INFINITE;
- case _FPCLASS_NINF:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_INFINITE;
- case _FPCLASS_PD:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_SUBNORMAL;
- case _FPCLASS_ND:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_SUBNORMAL;
- case _FPCLASS_PZ:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_ZERO;
- case _FPCLASS_NZ:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_ZERO;
- case _FPCLASS_PN:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_NORMAL;
- case _FPCLASS_NN:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_NORMAL;
- default:
- /* Just in case... */
- *is_negative = (number < 0.0);
- return TRIO_FP_NORMAL;
- }
-
-#elif defined(FP_PLUS_NORM) || defined(__hpux)
-
- /*
- * HP-UX 9.x and 10.x have an fpclassify() function, that is different
- * from the C99 fpclassify() macro supported on HP-UX 11.x.
- */
- switch (fpclassify(number)) {
- case FP_QNAN:
- case FP_SNAN:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_NAN;
- case FP_PLUS_INF:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_INFINITE;
- case FP_MINUS_INF:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_INFINITE;
- case FP_PLUS_DENORM:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_SUBNORMAL;
- case FP_MINUS_DENORM:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_SUBNORMAL;
- case FP_PLUS_ZERO:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_ZERO;
- case FP_MINUS_ZERO:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_ZERO;
- case FP_PLUS_NORM:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_NORMAL;
- case FP_MINUS_NORM:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_NORMAL;
- default:
- assert(0);
- }
-
-#else
- /*
- * Fallback solution.
- */
- int rc;
-
- if (number == 0.0) {
- /*
- * In IEEE 754 the sign of zero is ignored in comparisons, so we
- * have to handle this as a special case by examining the sign bit
- * directly.
- */
-#if defined(USE_IEEE_754)
- *is_negative = trio_is_negative(number);
-#else
- *is_negative = TRIO_FALSE; /* FIXME */
-#endif
- return TRIO_FP_ZERO;
- }
- if (trio_isnan(number)) {
- *is_negative = TRIO_FALSE;
- return TRIO_FP_NAN;
- }
- if ((rc = trio_isinf(number))) {
- *is_negative = (rc == -1);
- return TRIO_FP_INFINITE;
- }
- if ((number > 0.0) && (number < DBL_MIN)) {
- *is_negative = TRIO_FALSE;
- return TRIO_FP_SUBNORMAL;
- }
- if ((number < 0.0) && (number > -DBL_MIN)) {
- *is_negative = TRIO_TRUE;
- return TRIO_FP_SUBNORMAL;
- }
- *is_negative = (number < 0.0);
- return TRIO_FP_NORMAL;
-
-#endif
-}
-
-/**
- Examine the sign of a number.
-
- @param number An arbitrary floating-point number.
- @return Boolean value indicating whether or not the number has the
- sign bit set (i.e. is negative).
-*/
-TRIO_PUBLIC int
-trio_signbit
-TRIO_ARGS1((number),
- double number)
-{
- int is_negative;
-
- (void)trio_fpclassify_and_signbit(number, &is_negative);
- return is_negative;
-}
-
-/**
- Examine the class of a number.
-
- @param number An arbitrary floating-point number.
- @return Enumerable value indicating the class of @p number
-*/
-TRIO_PUBLIC int
-trio_fpclassify
-TRIO_ARGS1((number),
- double number)
-{
- int dummy;
-
- return trio_fpclassify_and_signbit(number, &dummy);
-}
-
-
-/** @} SpecialQuantities */
-
-/*************************************************************************
- * For test purposes.
- *
- * Add the following compiler option to include this test code.
- *
- * Unix : -DSTANDALONE
- * VMS : /DEFINE=(STANDALONE)
- */
-#if defined(STANDALONE)
-# include <stdio.h>
-
-static TRIO_CONST char *
-getClassification
-TRIO_ARGS1((type),
- int type)
-{
- switch (type) {
- case TRIO_FP_INFINITE:
- return "FP_INFINITE";
- case TRIO_FP_NAN:
- return "FP_NAN";
- case TRIO_FP_NORMAL:
- return "FP_NORMAL";
- case TRIO_FP_SUBNORMAL:
- return "FP_SUBNORMAL";
- case TRIO_FP_ZERO:
- return "FP_ZERO";
- default:
- return "FP_UNKNOWN";
- }
-}
-
-static void
-print_class
-TRIO_ARGS2((prefix, number),
- TRIO_CONST char *prefix,
- double number)
-{
- printf("%-6s: %s %-15s %g\n",
- prefix,
- trio_signbit(number) ? "-" : "+",
- getClassification(trio_fpclassify(number)),
- number);
-}
-
-int main(TRIO_NOARGS)
-{
- double my_nan;
- double my_pinf;
- double my_ninf;
-# if defined(TRIO_PLATFORM_UNIX)
- void (*signal_handler) TRIO_PROTO((int));
-# endif
-
- my_nan = trio_nan();
- my_pinf = trio_pinf();
- my_ninf = trio_ninf();
-
- print_class("Nan", my_nan);
- print_class("PInf", my_pinf);
- print_class("NInf", my_ninf);
- print_class("PZero", 0.0);
- print_class("NZero", -0.0);
- print_class("PNorm", 1.0);
- print_class("NNorm", -1.0);
- print_class("PSub", 1.01e-307 - 1.00e-307);
- print_class("NSub", 1.00e-307 - 1.01e-307);
-
- printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
- my_nan,
- ((unsigned char *)&my_nan)[0],
- ((unsigned char *)&my_nan)[1],
- ((unsigned char *)&my_nan)[2],
- ((unsigned char *)&my_nan)[3],
- ((unsigned char *)&my_nan)[4],
- ((unsigned char *)&my_nan)[5],
- ((unsigned char *)&my_nan)[6],
- ((unsigned char *)&my_nan)[7],
- trio_isnan(my_nan), trio_isinf(my_nan));
- printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
- my_pinf,
- ((unsigned char *)&my_pinf)[0],
- ((unsigned char *)&my_pinf)[1],
- ((unsigned char *)&my_pinf)[2],
- ((unsigned char *)&my_pinf)[3],
- ((unsigned char *)&my_pinf)[4],
- ((unsigned char *)&my_pinf)[5],
- ((unsigned char *)&my_pinf)[6],
- ((unsigned char *)&my_pinf)[7],
- trio_isnan(my_pinf), trio_isinf(my_pinf));
- printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
- my_ninf,
- ((unsigned char *)&my_ninf)[0],
- ((unsigned char *)&my_ninf)[1],
- ((unsigned char *)&my_ninf)[2],
- ((unsigned char *)&my_ninf)[3],
- ((unsigned char *)&my_ninf)[4],
- ((unsigned char *)&my_ninf)[5],
- ((unsigned char *)&my_ninf)[6],
- ((unsigned char *)&my_ninf)[7],
- trio_isnan(my_ninf), trio_isinf(my_ninf));
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal_handler = signal(SIGFPE, SIG_IGN);
-# endif
-
- my_pinf = DBL_MAX + DBL_MAX;
- my_ninf = -my_pinf;
- my_nan = my_pinf / my_pinf;
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal(SIGFPE, signal_handler);
-# endif
-
- printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
- my_nan,
- ((unsigned char *)&my_nan)[0],
- ((unsigned char *)&my_nan)[1],
- ((unsigned char *)&my_nan)[2],
- ((unsigned char *)&my_nan)[3],
- ((unsigned char *)&my_nan)[4],
- ((unsigned char *)&my_nan)[5],
- ((unsigned char *)&my_nan)[6],
- ((unsigned char *)&my_nan)[7],
- trio_isnan(my_nan), trio_isinf(my_nan));
- printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
- my_pinf,
- ((unsigned char *)&my_pinf)[0],
- ((unsigned char *)&my_pinf)[1],
- ((unsigned char *)&my_pinf)[2],
- ((unsigned char *)&my_pinf)[3],
- ((unsigned char *)&my_pinf)[4],
- ((unsigned char *)&my_pinf)[5],
- ((unsigned char *)&my_pinf)[6],
- ((unsigned char *)&my_pinf)[7],
- trio_isnan(my_pinf), trio_isinf(my_pinf));
- printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
- my_ninf,
- ((unsigned char *)&my_ninf)[0],
- ((unsigned char *)&my_ninf)[1],
- ((unsigned char *)&my_ninf)[2],
- ((unsigned char *)&my_ninf)[3],
- ((unsigned char *)&my_ninf)[4],
- ((unsigned char *)&my_ninf)[5],
- ((unsigned char *)&my_ninf)[6],
- ((unsigned char *)&my_ninf)[7],
- trio_isnan(my_ninf), trio_isinf(my_ninf));
-
- return 0;
-}
-#endif
diff --git a/bundle/libxml/trionan.h b/bundle/libxml/trionan.h
deleted file mode 100644
index bed0c120f9..0000000000
--- a/bundle/libxml/trionan.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*************************************************************************
- *
- * $Id$
- *
- * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-#ifndef TRIO_NAN_H
-#define TRIO_NAN_H
-
-#include "triodef.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum {
- TRIO_FP_INFINITE,
- TRIO_FP_NAN,
- TRIO_FP_NORMAL,
- TRIO_FP_SUBNORMAL,
- TRIO_FP_ZERO
-};
-
-/*
- * Return NaN (Not-a-Number).
- */
-TRIO_PUBLIC double trio_nan TRIO_PROTO((void));
-
-/*
- * Return positive infinity.
- */
-TRIO_PUBLIC double trio_pinf TRIO_PROTO((void));
-
-/*
- * Return negative infinity.
- */
-TRIO_PUBLIC double trio_ninf TRIO_PROTO((void));
-
-/*
- * Return negative zero.
- */
-TRIO_PUBLIC double trio_nzero TRIO_PROTO((TRIO_NOARGS));
-
-/*
- * If number is a NaN return non-zero, otherwise return zero.
- */
-TRIO_PUBLIC int trio_isnan TRIO_PROTO((double number));
-
-/*
- * If number is positive infinity return 1, if number is negative
- * infinity return -1, otherwise return 0.
- */
-TRIO_PUBLIC int trio_isinf TRIO_PROTO((double number));
-
-/*
- * If number is finite return non-zero, otherwise return zero.
- */
-TRIO_PUBLIC int trio_isfinite TRIO_PROTO((double number));
-
-TRIO_PUBLIC int trio_signbit TRIO_PROTO((double number));
-
-TRIO_PUBLIC int trio_fpclassify TRIO_PROTO((double number));
-
-TRIO_PUBLIC int trio_fpclassify_and_signbit TRIO_PROTO((double number, int *is_negative));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TRIO_NAN_H */
diff --git a/bundle/libxml/triop.h b/bundle/libxml/triop.h
deleted file mode 100644
index 8462c56f87..0000000000
--- a/bundle/libxml/triop.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*************************************************************************
- *
- * $Id$
- *
- * Copyright (C) 2000 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************
- *
- * Private functions, types, etc. used for callback functions.
- *
- * The ref pointer is an opaque type and should remain as such.
- * Private data must only be accessible through the getter and
- * setter functions.
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIOP_H
-#define TRIO_TRIOP_H
-
-#include "triodef.h"
-
-#include <stdlib.h>
-#if defined(TRIO_COMPILER_ANCIENT)
-# include <varargs.h>
-#else
-# include <stdarg.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef TRIO_C99
-# define TRIO_C99 1
-#endif
-#ifndef TRIO_BSD
-# define TRIO_BSD 1
-#endif
-#ifndef TRIO_GNU
-# define TRIO_GNU 1
-#endif
-#ifndef TRIO_MISC
-# define TRIO_MISC 1
-#endif
-#ifndef TRIO_UNIX98
-# define TRIO_UNIX98 1
-#endif
-#ifndef TRIO_MICROSOFT
-# define TRIO_MICROSOFT 1
-#endif
-#ifndef TRIO_EXTENSION
-# define TRIO_EXTENSION 1
-#endif
-#ifndef TRIO_WIDECHAR /* Does not work yet. Do not enable */
-# define TRIO_WIDECHAR 0
-#endif
-#ifndef TRIO_ERRORS
-# define TRIO_ERRORS 1
-#endif
-
-#ifndef TRIO_MALLOC
-# define TRIO_MALLOC(n) malloc(n)
-#endif
-#ifndef TRIO_REALLOC
-# define TRIO_REALLOC(x,n) realloc((x),(n))
-#endif
-#ifndef TRIO_FREE
-# define TRIO_FREE(x) free(x)
-#endif
-
-
-/*************************************************************************
- * User-defined specifiers
- */
-
-typedef int (*trio_callback_t) TRIO_PROTO((trio_pointer_t));
-
-trio_pointer_t trio_register TRIO_PROTO((trio_callback_t callback, const char *name));
-void trio_unregister TRIO_PROTO((trio_pointer_t handle));
-
-TRIO_CONST char *trio_get_format TRIO_PROTO((trio_pointer_t ref));
-trio_pointer_t trio_get_argument TRIO_PROTO((trio_pointer_t ref));
-
-/* Modifiers */
-int trio_get_width TRIO_PROTO((trio_pointer_t ref));
-void trio_set_width TRIO_PROTO((trio_pointer_t ref, int width));
-int trio_get_precision TRIO_PROTO((trio_pointer_t ref));
-void trio_set_precision TRIO_PROTO((trio_pointer_t ref, int precision));
-int trio_get_base TRIO_PROTO((trio_pointer_t ref));
-void trio_set_base TRIO_PROTO((trio_pointer_t ref, int base));
-int trio_get_padding TRIO_PROTO((trio_pointer_t ref));
-void trio_set_padding TRIO_PROTO((trio_pointer_t ref, int is_padding));
-int trio_get_short TRIO_PROTO((trio_pointer_t ref)); /* h */
-void trio_set_shortshort TRIO_PROTO((trio_pointer_t ref, int is_shortshort));
-int trio_get_shortshort TRIO_PROTO((trio_pointer_t ref)); /* hh */
-void trio_set_short TRIO_PROTO((trio_pointer_t ref, int is_short));
-int trio_get_long TRIO_PROTO((trio_pointer_t ref)); /* l */
-void trio_set_long TRIO_PROTO((trio_pointer_t ref, int is_long));
-int trio_get_longlong TRIO_PROTO((trio_pointer_t ref)); /* ll */
-void trio_set_longlong TRIO_PROTO((trio_pointer_t ref, int is_longlong));
-int trio_get_longdouble TRIO_PROTO((trio_pointer_t ref)); /* L */
-void trio_set_longdouble TRIO_PROTO((trio_pointer_t ref, int is_longdouble));
-int trio_get_alternative TRIO_PROTO((trio_pointer_t ref)); /* # */
-void trio_set_alternative TRIO_PROTO((trio_pointer_t ref, int is_alternative));
-int trio_get_alignment TRIO_PROTO((trio_pointer_t ref)); /* - */
-void trio_set_alignment TRIO_PROTO((trio_pointer_t ref, int is_leftaligned));
-int trio_get_spacing TRIO_PROTO((trio_pointer_t ref)); /* TRIO_PROTO((space) */
-void trio_set_spacing TRIO_PROTO((trio_pointer_t ref, int is_space));
-int trio_get_sign TRIO_PROTO((trio_pointer_t ref)); /* + */
-void trio_set_sign TRIO_PROTO((trio_pointer_t ref, int is_showsign));
-int trio_get_quote TRIO_PROTO((trio_pointer_t ref)); /* ' */
-void trio_set_quote TRIO_PROTO((trio_pointer_t ref, int is_quote));
-int trio_get_upper TRIO_PROTO((trio_pointer_t ref));
-void trio_set_upper TRIO_PROTO((trio_pointer_t ref, int is_upper));
-#if TRIO_C99
-int trio_get_largest TRIO_PROTO((trio_pointer_t ref)); /* j */
-void trio_set_largest TRIO_PROTO((trio_pointer_t ref, int is_largest));
-int trio_get_ptrdiff TRIO_PROTO((trio_pointer_t ref)); /* t */
-void trio_set_ptrdiff TRIO_PROTO((trio_pointer_t ref, int is_ptrdiff));
-int trio_get_size TRIO_PROTO((trio_pointer_t ref)); /* z / Z */
-void trio_set_size TRIO_PROTO((trio_pointer_t ref, int is_size));
-#endif
-
-/* Printing */
-int trio_print_ref TRIO_PROTO((trio_pointer_t ref, const char *format, ...));
-int trio_vprint_ref TRIO_PROTO((trio_pointer_t ref, const char *format, va_list args));
-int trio_printv_ref TRIO_PROTO((trio_pointer_t ref, const char *format, trio_pointer_t *args));
-
-void trio_print_int TRIO_PROTO((trio_pointer_t ref, int number));
-void trio_print_uint TRIO_PROTO((trio_pointer_t ref, unsigned int number));
-/* void trio_print_long TRIO_PROTO((trio_pointer_t ref, long number)); */
-/* void trio_print_ulong TRIO_PROTO((trio_pointer_t ref, unsigned long number)); */
-void trio_print_double TRIO_PROTO((trio_pointer_t ref, double number));
-void trio_print_string TRIO_PROTO((trio_pointer_t ref, char *string));
-void trio_print_pointer TRIO_PROTO((trio_pointer_t ref, trio_pointer_t pointer));
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* TRIO_TRIOP_H */
diff --git a/bundle/libxml/triostr.c b/bundle/libxml/triostr.c
deleted file mode 100644
index 43a30dad9f..0000000000
--- a/bundle/libxml/triostr.c
+++ /dev/null
@@ -1,2024 +0,0 @@
-/*************************************************************************
- *
- * $Id$
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/*************************************************************************
- * Include files
- */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <math.h>
-#include "triodef.h"
-#include "triostr.h"
-
-/*************************************************************************
- * Definitions
- */
-
-#if !defined(TRIO_STRING_PUBLIC)
-# define TRIO_STRING_PUBLIC TRIO_PUBLIC
-#endif
-#if !defined(TRIO_STRING_PRIVATE)
-# define TRIO_STRING_PRIVATE TRIO_PRIVATE
-#endif
-
-#if !defined(NULL)
-# define NULL 0
-#endif
-#if !defined(NIL)
-# define NIL ((char)0)
-#endif
-#if !defined(FALSE)
-# define FALSE (1 == 0)
-# define TRUE (! FALSE)
-#endif
-#if !defined(BOOLEAN_T)
-# define BOOLEAN_T int
-#endif
-
-#if defined(TRIO_COMPILER_SUPPORTS_C99)
-# define USE_STRTOD
-# define USE_STRTOF
-#elif defined(TRIO_COMPILER_MSVC)
-# define USE_STRTOD
-#endif
-
-#if defined(TRIO_PLATFORM_UNIX)
-# define USE_STRCASECMP
-# define USE_STRNCASECMP
-# define USE_STRERROR
-# if defined(TRIO_PLATFORM_QNX)
-# define strcasecmp(x,y) stricmp(x,y)
-# define strncasecmp(x,y,n) strnicmp(x,y,n)
-# endif
-#elif defined(TRIO_PLATFORM_WIN32)
-# define USE_STRCASECMP
-# define strcasecmp(x,y) strcmpi(x,y)
-#endif
-
-/*************************************************************************
- * Structures
- */
-
-struct _trio_string_t
-{
- char *content;
- size_t length;
- size_t allocated;
-};
-
-/*************************************************************************
- * Constants
- */
-
-#if !defined(TRIO_MINIMAL)
-static TRIO_CONST char rcsid[] = "@(#)$Id$";
-#endif
-
-/*************************************************************************
- * Static String Functions
- */
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_static.h"
-#endif
-/** @addtogroup StaticStrings
- @{
-*/
-
-/**
- Create new string.
-
- @param size Size of new string.
- @return Pointer to string, or NULL if allocation failed.
-*/
-TRIO_STRING_PUBLIC char *
-trio_create
-TRIO_ARGS1((size),
- size_t size)
-{
- return (char *)TRIO_MALLOC(size);
-}
-
-
-/**
- Destroy string.
-
- @param string String to be freed.
-*/
-TRIO_STRING_PUBLIC void
-trio_destroy
-TRIO_ARGS1((string),
- char *string)
-{
- if (string)
- {
- TRIO_FREE(string);
- }
-}
-
-
-/**
- Count the number of characters in a string.
-
- @param string String to measure.
- @return Number of characters in @string.
-*/
-TRIO_STRING_PUBLIC size_t
-trio_length
-TRIO_ARGS1((string),
- TRIO_CONST char *string)
-{
- return strlen(string);
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Append @p source at the end of @p target.
-
- @param target Target string.
- @param source Source string.
- @return Boolean value indicating success or failure.
-
- @pre @p target must point to a memory chunk with sufficient room to
- contain the @p target string and @p source string.
- @pre No boundary checking is performed, so insufficient memory will
- result in a buffer overrun.
- @post @p target will be zero terminated.
-*/
-TRIO_STRING_PUBLIC int
-trio_append
-TRIO_ARGS2((target, source),
- char *target,
- TRIO_CONST char *source)
-{
- assert(target);
- assert(source);
-
- return (strcat(target, source) != NULL);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-#if !defined(TRIO_MINIMAL)
-/**
- Append at most @p max characters from @p source to @p target.
-
- @param target Target string.
- @param max Maximum number of characters to append.
- @param source Source string.
- @return Boolean value indicating success or failure.
-
- @pre @p target must point to a memory chuck with sufficient room to
- contain the @p target string and the @p source string (at most @p max
- characters).
- @pre No boundary checking is performed, so insufficient memory will
- result in a buffer overrun.
- @post @p target will be zero terminated.
-*/
-TRIO_STRING_PUBLIC int
-trio_append_max
-TRIO_ARGS3((target, max, source),
- char *target,
- size_t max,
- TRIO_CONST char *source)
-{
- size_t length;
-
- assert(target);
- assert(source);
-
- length = trio_length(target);
-
- if (max > length)
- {
- strncat(target, source, max - length - 1);
- }
- return TRUE;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Determine if a string contains a substring.
-
- @param string String to be searched.
- @param substring String to be found.
- @return Boolean value indicating success or failure.
-*/
-TRIO_STRING_PUBLIC int
-trio_contains
-TRIO_ARGS2((string, substring),
- TRIO_CONST char *string,
- TRIO_CONST char *substring)
-{
- assert(string);
- assert(substring);
-
- return (0 != strstr(string, substring));
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Copy @p source to @p target.
-
- @param target Target string.
- @param source Source string.
- @return Boolean value indicating success or failure.
-
- @pre @p target must point to a memory chunk with sufficient room to
- contain the @p source string.
- @pre No boundary checking is performed, so insufficient memory will
- result in a buffer overrun.
- @post @p target will be zero terminated.
-*/
-TRIO_STRING_PUBLIC int
-trio_copy
-TRIO_ARGS2((target, source),
- char *target,
- TRIO_CONST char *source)
-{
- assert(target);
- assert(source);
-
- (void)strcpy(target, source);
- return TRUE;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/**
- Copy at most @p max characters from @p source to @p target.
-
- @param target Target string.
- @param max Maximum number of characters to append.
- @param source Source string.
- @return Boolean value indicating success or failure.
-
- @pre @p target must point to a memory chunk with sufficient room to
- contain the @p source string (at most @p max characters).
- @pre No boundary checking is performed, so insufficient memory will
- result in a buffer overrun.
- @post @p target will be zero terminated.
-*/
-TRIO_STRING_PUBLIC int
-trio_copy_max
-TRIO_ARGS3((target, max, source),
- char *target,
- size_t max,
- TRIO_CONST char *source)
-{
- assert(target);
- assert(source);
- assert(max > 0); /* Includes != 0 */
-
- (void)strncpy(target, source, max - 1);
- target[max - 1] = (char)0;
- return TRUE;
-}
-
-
-/*
- * TrioDuplicateMax
- */
-TRIO_STRING_PRIVATE char *
-TrioDuplicateMax
-TRIO_ARGS2((source, size),
- TRIO_CONST char *source,
- size_t size)
-{
- char *target;
-
- assert(source);
-
- /* Make room for string plus a terminating zero */
- size++;
- target = trio_create(size);
- if (target)
- {
- trio_copy_max(target, size, source);
- }
- return target;
-}
-
-
-/**
- Duplicate @p source.
-
- @param source Source string.
- @return A copy of the @p source string.
-
- @post @p target will be zero terminated.
-*/
-TRIO_STRING_PUBLIC char *
-trio_duplicate
-TRIO_ARGS1((source),
- TRIO_CONST char *source)
-{
- return TrioDuplicateMax(source, trio_length(source));
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Duplicate at most @p max characters of @p source.
-
- @param source Source string.
- @param max Maximum number of characters to duplicate.
- @return A copy of the @p source string.
-
- @post @p target will be zero terminated.
-*/
-TRIO_STRING_PUBLIC char *
-trio_duplicate_max TRIO_ARGS2((source, max),
- TRIO_CONST char *source,
- size_t max)
-{
- size_t length;
-
- assert(source);
- assert(max > 0);
-
- length = trio_length(source);
- if (length > max)
- {
- length = max;
- }
- return TrioDuplicateMax(source, length);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/**
- Compare if two strings are equal.
-
- @param first First string.
- @param second Second string.
- @return Boolean indicating whether the two strings are equal or not.
-
- Case-insensitive comparison.
-*/
-TRIO_STRING_PUBLIC int
-trio_equal
-TRIO_ARGS2((first, second),
- TRIO_CONST char *first,
- TRIO_CONST char *second)
-{
- assert(first);
- assert(second);
-
- if ((first != NULL) && (second != NULL))
- {
-#if defined(USE_STRCASECMP)
- return (0 == strcasecmp(first, second));
-#else
- while ((*first != NIL) && (*second != NIL))
- {
- if (toupper(*first) != toupper(*second))
- {
- break;
- }
- first++;
- second++;
- }
- return ((*first == NIL) && (*second == NIL));
-#endif
- }
- return FALSE;
-}
-
-
-/**
- Compare if two strings are equal.
-
- @param first First string.
- @param second Second string.
- @return Boolean indicating whether the two strings are equal or not.
-
- Case-sensitive comparison.
-*/
-TRIO_STRING_PUBLIC int
-trio_equal_case
-TRIO_ARGS2((first, second),
- TRIO_CONST char *first,
- TRIO_CONST char *second)
-{
- assert(first);
- assert(second);
-
- if ((first != NULL) && (second != NULL))
- {
- return (0 == strcmp(first, second));
- }
- return FALSE;
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Compare if two strings up until the first @p max characters are equal.
-
- @param first First string.
- @param max Maximum number of characters to compare.
- @param second Second string.
- @return Boolean indicating whether the two strings are equal or not.
-
- Case-sensitive comparison.
-*/
-TRIO_STRING_PUBLIC int
-trio_equal_case_max
-TRIO_ARGS3((first, max, second),
- TRIO_CONST char *first,
- size_t max,
- TRIO_CONST char *second)
-{
- assert(first);
- assert(second);
-
- if ((first != NULL) && (second != NULL))
- {
- return (0 == strncmp(first, second, max));
- }
- return FALSE;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/**
- Compare if two strings are equal.
-
- @param first First string.
- @param second Second string.
- @return Boolean indicating whether the two strings are equal or not.
-
- Collating characters are considered equal.
-*/
-TRIO_STRING_PUBLIC int
-trio_equal_locale
-TRIO_ARGS2((first, second),
- TRIO_CONST char *first,
- TRIO_CONST char *second)
-{
- assert(first);
- assert(second);
-
-#if defined(LC_COLLATE)
- return (strcoll(first, second) == 0);
-#else
- return trio_equal(first, second);
-#endif
-}
-
-
-/**
- Compare if two strings up until the first @p max characters are equal.
-
- @param first First string.
- @param max Maximum number of characters to compare.
- @param second Second string.
- @return Boolean indicating whether the two strings are equal or not.
-
- Case-insensitive comparison.
-*/
-TRIO_STRING_PUBLIC int
-trio_equal_max
-TRIO_ARGS3((first, max, second),
- TRIO_CONST char *first,
- size_t max,
- TRIO_CONST char *second)
-{
- assert(first);
- assert(second);
-
- if ((first != NULL) && (second != NULL))
- {
-#if defined(USE_STRNCASECMP)
- return (0 == strncasecmp(first, second, max));
-#else
- /* Not adequately tested yet */
- size_t cnt = 0;
- while ((*first != NIL) && (*second != NIL) && (cnt <= max))
- {
- if (toupper(*first) != toupper(*second))
- {
- break;
- }
- first++;
- second++;
- cnt++;
- }
- return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
-#endif
- }
- return FALSE;
-}
-
-
-/**
- Provide a textual description of an error code (errno).
-
- @param error_number Error number.
- @return Textual description of @p error_number.
-*/
-TRIO_STRING_PUBLIC TRIO_CONST char *
-trio_error
-TRIO_ARGS1((error_number),
- int error_number)
-{
-#if defined(USE_STRERROR)
- return strerror(error_number);
-#else
- return "unknown";
-#endif
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Format the date/time according to @p format.
-
- @param target Target string.
- @param max Maximum number of characters to format.
- @param format Formatting string.
- @param datetime Date/time structure.
- @return Number of formatted characters.
-
- The formatting string accepts the same specifiers as the standard C
- function strftime.
-*/
-TRIO_STRING_PUBLIC size_t
-trio_format_date_max
-TRIO_ARGS4((target, max, format, datetime),
- char *target,
- size_t max,
- TRIO_CONST char *format,
- TRIO_CONST struct tm *datetime)
-{
- assert(target);
- assert(format);
- assert(datetime);
- assert(max > 0);
-
- return strftime(target, max, format, datetime);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Calculate a hash value for a string.
-
- @param string String to be calculated on.
- @param type Hash function.
- @return Calculated hash value.
-
- @p type can be one of the following
- @li @c TRIO_HASH_PLAIN Plain hash function.
-*/
-TRIO_STRING_PUBLIC unsigned long
-trio_hash
-TRIO_ARGS2((string, type),
- TRIO_CONST char *string,
- int type)
-{
- unsigned long value = 0L;
- char ch;
-
- assert(string);
-
- switch (type)
- {
- case TRIO_HASH_PLAIN:
- while ( (ch = *string++) != NIL )
- {
- value *= 31;
- value += (unsigned long)ch;
- }
- break;
- default:
- assert(FALSE);
- break;
- }
- return value;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Find first occurrence of a character in a string.
-
- @param string String to be searched.
- @param character Character to be found.
- @param A pointer to the found character, or NULL if character was not found.
- */
-TRIO_STRING_PUBLIC char *
-trio_index
-TRIO_ARGS2((string, character),
- TRIO_CONST char *string,
- int character)
-{
- assert(string);
-
- return strchr(string, character);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Find last occurrence of a character in a string.
-
- @param string String to be searched.
- @param character Character to be found.
- @param A pointer to the found character, or NULL if character was not found.
- */
-TRIO_STRING_PUBLIC char *
-trio_index_last
-TRIO_ARGS2((string, character),
- TRIO_CONST char *string,
- int character)
-{
- assert(string);
-
- return strchr(string, character);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Convert the alphabetic letters in the string to lower-case.
-
- @param target String to be converted.
- @return Number of processed characters (converted or not).
-*/
-TRIO_STRING_PUBLIC int
-trio_lower
-TRIO_ARGS1((target),
- char *target)
-{
- assert(target);
-
- return trio_span_function(target, target, tolower);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Compare two strings using wildcards.
-
- @param string String to be searched.
- @param pattern Pattern, including wildcards, to search for.
- @return Boolean value indicating success or failure.
-
- Case-insensitive comparison.
-
- The following wildcards can be used
- @li @c * Match any number of characters.
- @li @c ? Match a single character.
-*/
-TRIO_STRING_PUBLIC int
-trio_match
-TRIO_ARGS2((string, pattern),
- TRIO_CONST char *string,
- TRIO_CONST char *pattern)
-{
- assert(string);
- assert(pattern);
-
- for (; ('*' != *pattern); ++pattern, ++string)
- {
- if (NIL == *string)
- {
- return (NIL == *pattern);
- }
- if ((toupper((int)*string) != toupper((int)*pattern))
- && ('?' != *pattern))
- {
- return FALSE;
- }
- }
- /* two-line patch to prevent *too* much recursiveness: */
- while ('*' == pattern[1])
- pattern++;
-
- do
- {
- if ( trio_match(string, &pattern[1]) )
- {
- return TRUE;
- }
- }
- while (*string++);
-
- return FALSE;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Compare two strings using wildcards.
-
- @param string String to be searched.
- @param pattern Pattern, including wildcards, to search for.
- @return Boolean value indicating success or failure.
-
- Case-sensitive comparison.
-
- The following wildcards can be used
- @li @c * Match any number of characters.
- @li @c ? Match a single character.
-*/
-TRIO_STRING_PUBLIC int
-trio_match_case
-TRIO_ARGS2((string, pattern),
- TRIO_CONST char *string,
- TRIO_CONST char *pattern)
-{
- assert(string);
- assert(pattern);
-
- for (; ('*' != *pattern); ++pattern, ++string)
- {
- if (NIL == *string)
- {
- return (NIL == *pattern);
- }
- if ((*string != *pattern)
- && ('?' != *pattern))
- {
- return FALSE;
- }
- }
- /* two-line patch to prevent *too* much recursiveness: */
- while ('*' == pattern[1])
- pattern++;
-
- do
- {
- if ( trio_match_case(string, &pattern[1]) )
- {
- return TRUE;
- }
- }
- while (*string++);
-
- return FALSE;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Execute a function on each character in string.
-
- @param target Target string.
- @param source Source string.
- @param Function Function to be executed.
- @return Number of processed characters.
-*/
-TRIO_STRING_PUBLIC size_t
-trio_span_function
-TRIO_ARGS3((target, source, Function),
- char *target,
- TRIO_CONST char *source,
- int (*Function) TRIO_PROTO((int)))
-{
- size_t count = 0;
-
- assert(target);
- assert(source);
- assert(Function);
-
- while (*source != NIL)
- {
- *target++ = Function(*source++);
- count++;
- }
- return count;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Search for a substring in a string.
-
- @param string String to be searched.
- @param substring String to be found.
- @return Pointer to first occurrence of @p substring in @p string, or NULL
- if no match was found.
-*/
-TRIO_STRING_PUBLIC char *
-trio_substring
-TRIO_ARGS2((string, substring),
- TRIO_CONST char *string,
- TRIO_CONST char *substring)
-{
- assert(string);
- assert(substring);
-
- return strstr(string, substring);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Search for a substring in the first @p max characters of a string.
-
- @param string String to be searched.
- @param max Maximum characters to be searched.
- @param substring String to be found.
- @return Pointer to first occurrence of @p substring in @p string, or NULL
- if no match was found.
-*/
-TRIO_STRING_PUBLIC char *
-trio_substring_max
-TRIO_ARGS3((string, max, substring),
- TRIO_CONST char *string,
- size_t max,
- TRIO_CONST char *substring)
-{
- size_t count;
- size_t size;
- char *result = NULL;
-
- assert(string);
- assert(substring);
-
- size = trio_length(substring);
- if (size <= max)
- {
- for (count = 0; count <= max - size; count++)
- {
- if (trio_equal_max(substring, size, &string[count]))
- {
- result = (char *)&string[count];
- break;
- }
- }
- }
- return result;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Tokenize string.
-
- @param string String to be tokenized.
- @param tokens String containing list of delimiting characters.
- @return Start of new token.
-
- @warning @p string will be destroyed.
-*/
-TRIO_STRING_PUBLIC char *
-trio_tokenize
-TRIO_ARGS2((string, delimiters),
- char *string,
- TRIO_CONST char *delimiters)
-{
- assert(delimiters);
-
- return strtok(string, delimiters);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/**
- Convert string to floating-point number.
-
- @param source String to be converted.
- @param endp Pointer to end of the converted string.
- @return A floating-point number.
-
- The following Extended Backus-Naur form is used
- @verbatim
- double ::= [ <sign> ]
- ( <number> |
- <number> <decimal_point> <number> |
- <decimal_point> <number> )
- [ <exponential> [ <sign> ] <number> ]
- number ::= 1*( <digit> )
- digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
- exponential ::= ( 'e' | 'E' )
- sign ::= ( '-' | '+' )
- decimal_point ::= '.'
- @endverbatim
-*/
-/* FIXME: Add EBNF for hex-floats */
-TRIO_STRING_PUBLIC trio_long_double_t
-trio_to_long_double
-TRIO_ARGS2((source, endp),
- TRIO_CONST char *source,
- char **endp)
-{
-#if defined(USE_STRTOLD)
- return strtold(source, endp);
-#else
- int isNegative = FALSE;
- int isExponentNegative = FALSE;
- trio_long_double_t integer = 0.0;
- trio_long_double_t fraction = 0.0;
- unsigned long exponent = 0;
- trio_long_double_t base;
- trio_long_double_t fracdiv = 1.0;
- trio_long_double_t value = 0.0;
-
- /* First try hex-floats */
- if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
- {
- base = 16.0;
- source += 2;
- while (isxdigit((int)*source))
- {
- integer *= base;
- integer += (isdigit((int)*source)
- ? (*source - '0')
- : 10 + (toupper((int)*source) - 'A'));
- source++;
- }
- if (*source == '.')
- {
- source++;
- while (isxdigit((int)*source))
- {
- fracdiv /= base;
- fraction += fracdiv * (isdigit((int)*source)
- ? (*source - '0')
- : 10 + (toupper((int)*source) - 'A'));
- source++;
- }
- if ((*source == 'p') || (*source == 'P'))
- {
- source++;
- if ((*source == '+') || (*source == '-'))
- {
- isExponentNegative = (*source == '-');
- source++;
- }
- while (isdigit((int)*source))
- {
- exponent *= (int)base;
- exponent += (*source - '0');
- source++;
- }
- }
- }
- }
- else /* Then try normal decimal floats */
- {
- base = 10.0;
- isNegative = (*source == '-');
- /* Skip sign */
- if ((*source == '+') || (*source == '-'))
- source++;
-
- /* Integer part */
- while (isdigit((int)*source))
- {
- integer *= base;
- integer += (*source - '0');
- source++;
- }
-
- if (*source == '.')
- {
- source++; /* skip decimal point */
- while (isdigit((int)*source))
- {
- fracdiv /= base;
- fraction += (*source - '0') * fracdiv;
- source++;
- }
- }
- if ((*source == 'e')
- || (*source == 'E')
-#if TRIO_MICROSOFT
- || (*source == 'd')
- || (*source == 'D')
-#endif
- )
- {
- source++; /* Skip exponential indicator */
- isExponentNegative = (*source == '-');
- if ((*source == '+') || (*source == '-'))
- source++;
- while (isdigit((int)*source))
- {
- exponent *= (int)base;
- exponent += (*source - '0');
- source++;
- }
- }
- }
-
- value = integer + fraction;
- if (exponent != 0)
- {
- if (isExponentNegative)
- value /= pow(base, (double)exponent);
- else
- value *= pow(base, (double)exponent);
- }
- if (isNegative)
- value = -value;
-
- if (endp)
- *endp = (char *)source;
- return value;
-#endif
-}
-
-
-/**
- Convert string to floating-point number.
-
- @param source String to be converted.
- @param endp Pointer to end of the converted string.
- @return A floating-point number.
-
- See @ref trio_to_long_double.
-*/
-TRIO_STRING_PUBLIC double
-trio_to_double
-TRIO_ARGS2((source, endp),
- TRIO_CONST char *source,
- char **endp)
-{
-#if defined(USE_STRTOD)
- return strtod(source, endp);
-#else
- return (double)trio_to_long_double(source, endp);
-#endif
-}
-
-#if !defined(TRIO_MINIMAL)
-/**
- Convert string to floating-point number.
-
- @param source String to be converted.
- @param endp Pointer to end of the converted string.
- @return A floating-point number.
-
- See @ref trio_to_long_double.
-*/
-TRIO_STRING_PUBLIC float
-trio_to_float
-TRIO_ARGS2((source, endp),
- TRIO_CONST char *source,
- char **endp)
-{
-#if defined(USE_STRTOF)
- return strtof(source, endp);
-#else
- return (float)trio_to_long_double(source, endp);
-#endif
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/**
- Convert string to signed integer.
-
- @param string String to be converted.
- @param endp Pointer to end of converted string.
- @param base Radix number of number.
-*/
-TRIO_STRING_PUBLIC long
-trio_to_long
-TRIO_ARGS3((string, endp, base),
- TRIO_CONST char *string,
- char **endp,
- int base)
-{
- assert(string);
- assert((base >= 2) && (base <= 36));
-
- return strtol(string, endp, base);
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Convert string to unsigned integer.
-
- @param string String to be converted.
- @param endp Pointer to end of converted string.
- @param base Radix number of number.
-*/
-TRIO_STRING_PUBLIC unsigned long
-trio_to_unsigned_long
-TRIO_ARGS3((string, endp, base),
- TRIO_CONST char *string,
- char **endp,
- int base)
-{
- assert(string);
- assert((base >= 2) && (base <= 36));
-
- return strtoul(string, endp, base);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Convert the alphabetic letters in the string to upper-case.
-
- @param target The string to be converted.
- @return The number of processed characters (converted or not).
-*/
-TRIO_STRING_PUBLIC int
-trio_upper
-TRIO_ARGS1((target),
- char *target)
-{
- assert(target);
-
- return trio_span_function(target, target, toupper);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/** @} End of StaticStrings */
-
-
-/*************************************************************************
- * Dynamic String Functions
- */
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_dynamic.h"
-#endif
-/** @addtogroup DynamicStrings
- @{
-*/
-
-/*
- * TrioStringAlloc
- */
-TRIO_STRING_PRIVATE trio_string_t *
-TrioStringAlloc(TRIO_NOARGS)
-{
- trio_string_t *self;
-
- self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
- if (self)
- {
- self->content = NULL;
- self->length = 0;
- self->allocated = 0;
- }
- return self;
-}
-
-
-/*
- * TrioStringGrow
- *
- * The size of the string will be increased by 'delta' characters. If
- * 'delta' is zero, the size will be doubled.
- */
-TRIO_STRING_PRIVATE BOOLEAN_T
-TrioStringGrow
-TRIO_ARGS2((self, delta),
- trio_string_t *self,
- size_t delta)
-{
- BOOLEAN_T status = FALSE;
- char *new_content;
- size_t new_size;
-
- new_size = (delta == 0)
- ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
- : self->allocated + delta;
-
- new_content = (char *)TRIO_REALLOC(self->content, new_size);
- if (new_content)
- {
- self->content = new_content;
- self->allocated = new_size;
- status = TRUE;
- }
- return status;
-}
-
-
-/*
- * TrioStringGrowTo
- *
- * The size of the string will be increased to 'length' plus one characters.
- * If 'length' is less than the original size, the original size will be
- * used (that is, the size of the string is never decreased).
- */
-TRIO_STRING_PRIVATE BOOLEAN_T
-TrioStringGrowTo
-TRIO_ARGS2((self, length),
- trio_string_t *self,
- size_t length)
-{
- length++; /* Room for terminating zero */
- return (self->allocated < length)
- ? TrioStringGrow(self, length - self->allocated)
- : TRUE;
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Create a new dynamic string.
-
- @param initial_size Initial size of the buffer.
- @return Newly allocated dynamic string, or NULL if memory allocation failed.
-*/
-TRIO_STRING_PUBLIC trio_string_t *
-trio_string_create
-TRIO_ARGS1((initial_size),
- int initial_size)
-{
- trio_string_t *self;
-
- self = TrioStringAlloc();
- if (self)
- {
- if (TrioStringGrow(self,
- (size_t)((initial_size > 0) ? initial_size : 1)))
- {
- self->content[0] = (char)0;
- self->allocated = initial_size;
- }
- else
- {
- trio_string_destroy(self);
- self = NULL;
- }
- }
- return self;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/**
- Deallocate the dynamic string and its contents.
-
- @param self Dynamic string
-*/
-TRIO_STRING_PUBLIC void
-trio_string_destroy
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- assert(self);
-
- if (self)
- {
- trio_destroy(self->content);
- TRIO_FREE(self);
- }
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Get a pointer to the content.
-
- @param self Dynamic string.
- @param offset Offset into content.
- @return Pointer to the content.
-
- @p Offset can be zero, positive, or negative. If @p offset is zero,
- then the start of the content will be returned. If @p offset is positive,
- then a pointer to @p offset number of characters from the beginning of the
- content is returned. If @p offset is negative, then a pointer to @p offset
- number of characters from the ending of the string, starting at the
- terminating zero, is returned.
-*/
-TRIO_STRING_PUBLIC char *
-trio_string_get
-TRIO_ARGS2((self, offset),
- trio_string_t *self,
- int offset)
-{
- char *result = NULL;
-
- assert(self);
-
- if (self->content != NULL)
- {
- if (self->length == 0)
- {
- (void)trio_string_length(self);
- }
- if (offset >= 0)
- {
- if (offset > (int)self->length)
- {
- offset = self->length;
- }
- }
- else
- {
- offset += self->length + 1;
- if (offset < 0)
- {
- offset = 0;
- }
- }
- result = &(self->content[offset]);
- }
- return result;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/**
- Extract the content.
-
- @param self Dynamic String
- @return Content of dynamic string.
-
- The content is removed from the dynamic string. This enables destruction
- of the dynamic string without deallocation of the content.
-*/
-TRIO_STRING_PUBLIC char *
-trio_string_extract
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- char *result;
-
- assert(self);
-
- result = self->content;
- /* FIXME: Allocate new empty buffer? */
- self->content = NULL;
- self->length = self->allocated = 0;
- return result;
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Set the content of the dynamic string.
-
- @param self Dynamic String
- @param buffer The new content.
-
- Sets the content of the dynamic string to a copy @p buffer.
- An existing content will be deallocated first, if necessary.
-
- @remark
- This function will make a copy of @p buffer.
- You are responsible for deallocating @p buffer yourself.
-*/
-TRIO_STRING_PUBLIC void
-trio_xstring_set
-TRIO_ARGS2((self, buffer),
- trio_string_t *self,
- char *buffer)
-{
- assert(self);
-
- trio_destroy(self->content);
- self->content = trio_duplicate(buffer);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/*
- * trio_string_size
- */
-TRIO_STRING_PUBLIC int
-trio_string_size
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- assert(self);
-
- return self->allocated;
-}
-
-
-/*
- * trio_string_terminate
- */
-TRIO_STRING_PUBLIC void
-trio_string_terminate
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- trio_xstring_append_char(self, 0);
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Append the second string to the first.
-
- @param self Dynamic string to be modified.
- @param other Dynamic string to copy from.
- @return Boolean value indicating success or failure.
-*/
-TRIO_STRING_PUBLIC int
-trio_string_append
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- size_t length;
-
- assert(self);
- assert(other);
-
- length = self->length + other->length;
- if (!TrioStringGrowTo(self, length))
- goto error;
- trio_copy(&self->content[self->length], other->content);
- self->length = length;
- return TRUE;
-
- error:
- return FALSE;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_append
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_append
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- size_t length;
-
- assert(self);
- assert(other);
-
- length = self->length + trio_length(other);
- if (!TrioStringGrowTo(self, length))
- goto error;
- trio_copy(&self->content[self->length], other);
- self->length = length;
- return TRUE;
-
- error:
- return FALSE;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/*
- * trio_xstring_append_char
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_append_char
-TRIO_ARGS2((self, character),
- trio_string_t *self,
- char character)
-{
- assert(self);
-
- if ((int)self->length >= trio_string_size(self))
- {
- if (!TrioStringGrow(self, 0))
- goto error;
- }
- self->content[self->length] = character;
- self->length++;
- return TRUE;
-
- error:
- return FALSE;
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/**
- Search for the first occurrence of second parameter in the first.
-
- @param self Dynamic string to be modified.
- @param other Dynamic string to copy from.
- @return Boolean value indicating success or failure.
-*/
-TRIO_STRING_PUBLIC int
-trio_string_contains
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_contains(self->content, other->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_contains
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_contains
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_contains(self->content, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_copy
- */
-TRIO_STRING_PUBLIC int
-trio_string_copy
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- self->length = 0;
- return trio_string_append(self, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_copy
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_copy
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- self->length = 0;
- return trio_xstring_append(self, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_duplicate
- */
-TRIO_STRING_PUBLIC trio_string_t *
-trio_string_duplicate
-TRIO_ARGS1((other),
- trio_string_t *other)
-{
- trio_string_t *self;
-
- assert(other);
-
- self = TrioStringAlloc();
- if (self)
- {
- self->content = TrioDuplicateMax(other->content, other->length);
- if (self->content)
- {
- self->length = other->length;
- self->allocated = self->length + 1;
- }
- else
- {
- self->length = self->allocated = 0;
- }
- }
- return self;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-/*
- * trio_xstring_duplicate
- */
-TRIO_STRING_PUBLIC trio_string_t *
-trio_xstring_duplicate
-TRIO_ARGS1((other),
- TRIO_CONST char *other)
-{
- trio_string_t *self;
-
- assert(other);
-
- self = TrioStringAlloc();
- if (self)
- {
- self->content = TrioDuplicateMax(other, trio_length(other));
- if (self->content)
- {
- self->length = trio_length(self->content);
- self->allocated = self->length + 1;
- }
- else
- {
- self->length = self->allocated = 0;
- }
- }
- return self;
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_equal
- */
-TRIO_STRING_PUBLIC int
-trio_string_equal
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal(self->content, other->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_equal
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_equal
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal(self->content, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_equal_max
- */
-TRIO_STRING_PUBLIC int
-trio_string_equal_max
-TRIO_ARGS3((self, max, other),
- trio_string_t *self,
- size_t max,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_max(self->content, max, other->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_equal_max
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_equal_max
-TRIO_ARGS3((self, max, other),
- trio_string_t *self,
- size_t max,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_max(self->content, max, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_equal_case
- */
-TRIO_STRING_PUBLIC int
-trio_string_equal_case
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_case(self->content, other->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_equal_case
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_equal_case
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_case(self->content, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_equal_case_max
- */
-TRIO_STRING_PUBLIC int
-trio_string_equal_case_max
-TRIO_ARGS3((self, max, other),
- trio_string_t *self,
- size_t max,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_case_max(self->content, max, other->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_equal_case_max
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_equal_case_max
-TRIO_ARGS3((self, max, other),
- trio_string_t *self,
- size_t max,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_case_max(self->content, max, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_format_data_max
- */
-TRIO_STRING_PUBLIC size_t
-trio_string_format_date_max
-TRIO_ARGS4((self, max, format, datetime),
- trio_string_t *self,
- size_t max,
- TRIO_CONST char *format,
- TRIO_CONST struct tm *datetime)
-{
- assert(self);
-
- return trio_format_date_max(self->content, max, format, datetime);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_index
- */
-TRIO_STRING_PUBLIC char *
-trio_string_index
-TRIO_ARGS2((self, character),
- trio_string_t *self,
- int character)
-{
- assert(self);
-
- return trio_index(self->content, character);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_index_last
- */
-TRIO_STRING_PUBLIC char *
-trio_string_index_last
-TRIO_ARGS2((self, character),
- trio_string_t *self,
- int character)
-{
- assert(self);
-
- return trio_index_last(self->content, character);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_length
- */
-TRIO_STRING_PUBLIC int
-trio_string_length
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- assert(self);
-
- if (self->length == 0)
- {
- self->length = trio_length(self->content);
- }
- return self->length;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_lower
- */
-TRIO_STRING_PUBLIC int
-trio_string_lower
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- assert(self);
-
- return trio_lower(self->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_match
- */
-TRIO_STRING_PUBLIC int
-trio_string_match
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_match(self->content, other->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_match
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_match
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_match(self->content, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_match_case
- */
-TRIO_STRING_PUBLIC int
-trio_string_match_case
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_match_case(self->content, other->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_match_case
- */
-TRIO_STRING_PUBLIC int
-trio_xstring_match_case
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_match_case(self->content, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_substring
- */
-TRIO_STRING_PUBLIC char *
-trio_string_substring
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_substring(self->content, other->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_xstring_substring
- */
-TRIO_STRING_PUBLIC char *
-trio_xstring_substring
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_substring(self->content, other);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * trio_string_upper
- */
-TRIO_STRING_PUBLIC int
-trio_string_upper
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- assert(self);
-
- return trio_upper(self->content);
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-/** @} End of DynamicStrings */
diff --git a/bundle/libxml/triostr.h b/bundle/libxml/triostr.h
deleted file mode 100644
index 083e2a52ff..0000000000
--- a/bundle/libxml/triostr.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*************************************************************************
- *
- * $Id$
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIOSTR_H
-#define TRIO_TRIOSTR_H
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include "triodef.h"
-#include "triop.h"
-
-enum {
- TRIO_HASH_NONE = 0,
- TRIO_HASH_PLAIN,
- TRIO_HASH_TWOSIGNED
-};
-
-#if !defined(TRIO_STRING_PUBLIC)
-# if !defined(TRIO_PUBLIC)
-# define TRIO_PUBLIC
-# endif
-# define TRIO_STRING_PUBLIC TRIO_PUBLIC
-#endif
-
-/*************************************************************************
- * String functions
- */
-
-TRIO_STRING_PUBLIC int trio_append TRIO_PROTO((char *target, const char *source));
-TRIO_STRING_PUBLIC int trio_append_max TRIO_PROTO((char *target, size_t max, const char *source));
-TRIO_STRING_PUBLIC int trio_contains TRIO_PROTO((const char *string, const char *substring));
-TRIO_STRING_PUBLIC int trio_copy TRIO_PROTO((char *target, const char *source));
-TRIO_STRING_PUBLIC int trio_copy_max TRIO_PROTO((char *target, size_t max, const char *source));
-TRIO_STRING_PUBLIC char *trio_create TRIO_PROTO((size_t size));
-TRIO_STRING_PUBLIC void trio_destroy TRIO_PROTO((char *string));
-TRIO_STRING_PUBLIC char *trio_duplicate TRIO_PROTO((const char *source));
-TRIO_STRING_PUBLIC char *trio_duplicate_max TRIO_PROTO((const char *source, size_t max));
-TRIO_STRING_PUBLIC int trio_equal TRIO_PROTO((const char *first, const char *second));
-TRIO_STRING_PUBLIC int trio_equal_case TRIO_PROTO((const char *first, const char *second));
-TRIO_STRING_PUBLIC int trio_equal_case_max TRIO_PROTO((const char *first, size_t max, const char *second));
-TRIO_STRING_PUBLIC int trio_equal_locale TRIO_PROTO((const char *first, const char *second));
-TRIO_STRING_PUBLIC int trio_equal_max TRIO_PROTO((const char *first, size_t max, const char *second));
-TRIO_STRING_PUBLIC TRIO_CONST char *trio_error TRIO_PROTO((int));
-TRIO_STRING_PUBLIC size_t trio_format_date_max TRIO_PROTO((char *target, size_t max, const char *format, const struct tm *datetime));
-TRIO_STRING_PUBLIC unsigned long trio_hash TRIO_PROTO((const char *string, int type));
-TRIO_STRING_PUBLIC char *trio_index TRIO_PROTO((const char *string, int character));
-TRIO_STRING_PUBLIC char *trio_index_last TRIO_PROTO((const char *string, int character));
-TRIO_STRING_PUBLIC size_t trio_length TRIO_PROTO((const char *string));
-TRIO_STRING_PUBLIC int trio_lower TRIO_PROTO((char *target));
-TRIO_STRING_PUBLIC int trio_match TRIO_PROTO((const char *string, const char *pattern));
-TRIO_STRING_PUBLIC int trio_match_case TRIO_PROTO((const char *string, const char *pattern));
-TRIO_STRING_PUBLIC size_t trio_span_function TRIO_PROTO((char *target, const char *source, int (*Function) TRIO_PROTO((int))));
-TRIO_STRING_PUBLIC char *trio_substring TRIO_PROTO((const char *string, const char *substring));
-TRIO_STRING_PUBLIC char *trio_substring_max TRIO_PROTO((const char *string, size_t max, const char *substring));
-TRIO_STRING_PUBLIC double trio_to_double TRIO_PROTO((const char *source, char **endp));
-TRIO_STRING_PUBLIC float trio_to_float TRIO_PROTO((const char *source, char **endp));
-TRIO_STRING_PUBLIC trio_long_double_t trio_to_long_double TRIO_PROTO((const char *source, char **endp));
-TRIO_STRING_PUBLIC long trio_to_long TRIO_PROTO((const char *source, char **endp, int base));
-TRIO_STRING_PUBLIC unsigned long trio_to_unsigned_long TRIO_PROTO((const char *source, char **endp, int base));
-TRIO_STRING_PUBLIC char *trio_tokenize TRIO_PROTO((char *string, const char *delimiters));
-TRIO_STRING_PUBLIC int trio_upper TRIO_PROTO((char *target));
-
-/*************************************************************************
- * Dynamic string functions
- */
-
-/*
- * Opaque type for dynamic strings
- */
-typedef struct _trio_string_t trio_string_t;
-
-TRIO_STRING_PUBLIC trio_string_t *trio_string_create TRIO_PROTO((int initial_size));
-TRIO_STRING_PUBLIC void trio_string_destroy TRIO_PROTO((trio_string_t *self));
-TRIO_STRING_PUBLIC char *trio_string_get TRIO_PROTO((trio_string_t *self, int offset));
-TRIO_STRING_PUBLIC void trio_xstring_set TRIO_PROTO((trio_string_t *self, char *buffer));
-TRIO_STRING_PUBLIC char *trio_string_extract TRIO_PROTO((trio_string_t *self));
-TRIO_STRING_PUBLIC int trio_string_size TRIO_PROTO((trio_string_t *self));
-TRIO_STRING_PUBLIC void trio_string_terminate TRIO_PROTO((trio_string_t *self));
-
-TRIO_STRING_PUBLIC int trio_string_append TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-TRIO_STRING_PUBLIC int trio_string_contains TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-TRIO_STRING_PUBLIC int trio_string_copy TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-TRIO_STRING_PUBLIC trio_string_t *trio_string_duplicate TRIO_PROTO((trio_string_t *other));
-TRIO_STRING_PUBLIC int trio_string_equal TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-TRIO_STRING_PUBLIC int trio_string_equal_max TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *second));
-TRIO_STRING_PUBLIC int trio_string_equal_case TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-TRIO_STRING_PUBLIC int trio_string_equal_case_max TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *other));
-TRIO_STRING_PUBLIC size_t trio_string_format_date_max TRIO_PROTO((trio_string_t *self, size_t max, const char *format, const struct tm *datetime));
-TRIO_STRING_PUBLIC char *trio_string_index TRIO_PROTO((trio_string_t *self, int character));
-TRIO_STRING_PUBLIC char *trio_string_index_last TRIO_PROTO((trio_string_t *self, int character));
-TRIO_STRING_PUBLIC int trio_string_length TRIO_PROTO((trio_string_t *self));
-TRIO_STRING_PUBLIC int trio_string_lower TRIO_PROTO((trio_string_t *self));
-TRIO_STRING_PUBLIC int trio_string_match TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-TRIO_STRING_PUBLIC int trio_string_match_case TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-TRIO_STRING_PUBLIC char *trio_string_substring TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-TRIO_STRING_PUBLIC int trio_string_upper TRIO_PROTO((trio_string_t *self));
-
-TRIO_STRING_PUBLIC int trio_xstring_append_char TRIO_PROTO((trio_string_t *self, char character));
-TRIO_STRING_PUBLIC int trio_xstring_append TRIO_PROTO((trio_string_t *self, const char *other));
-TRIO_STRING_PUBLIC int trio_xstring_contains TRIO_PROTO((trio_string_t *self, const char *other));
-TRIO_STRING_PUBLIC int trio_xstring_copy TRIO_PROTO((trio_string_t *self, const char *other));
-TRIO_STRING_PUBLIC trio_string_t *trio_xstring_duplicate TRIO_PROTO((const char *other));
-TRIO_STRING_PUBLIC int trio_xstring_equal TRIO_PROTO((trio_string_t *self, const char *other));
-TRIO_STRING_PUBLIC int trio_xstring_equal_max TRIO_PROTO((trio_string_t *self, size_t max, const char *other));
-TRIO_STRING_PUBLIC int trio_xstring_equal_case TRIO_PROTO((trio_string_t *self, const char *other));
-TRIO_STRING_PUBLIC int trio_xstring_equal_case_max TRIO_PROTO((trio_string_t *self, size_t max, const char *other));
-TRIO_STRING_PUBLIC int trio_xstring_match TRIO_PROTO((trio_string_t *self, const char *other));
-TRIO_STRING_PUBLIC int trio_xstring_match_case TRIO_PROTO((trio_string_t *self, const char *other));
-TRIO_STRING_PUBLIC char *trio_xstring_substring TRIO_PROTO((trio_string_t *self, const char *other));
-
-#endif /* TRIO_TRIOSTR_H */
diff --git a/bundle/libxml/uri.c b/bundle/libxml/uri.c
deleted file mode 100644
index 1f4ab600bd..0000000000
--- a/bundle/libxml/uri.c
+++ /dev/null
@@ -1,1962 +0,0 @@
-/**
- * uri.c: set of generic URI related routines
- *
- * Reference: RFC 2396
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#include <string.h>
-
-#include <libxml/xmlmemory.h>
-#include <libxml/uri.h>
-#include <libxml/globals.h>
-#include <libxml/xmlerror.h>
-
-/************************************************************************
- * *
- * Macros to differentiate various character type *
- * directly extracted from RFC 2396 *
- * *
- ************************************************************************/
-
-/*
- * alpha = lowalpha | upalpha
- */
-#define IS_ALPHA(x) (IS_LOWALPHA(x) || IS_UPALPHA(x))
-
-
-/*
- * lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" |
- * "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" |
- * "u" | "v" | "w" | "x" | "y" | "z"
- */
-
-#define IS_LOWALPHA(x) (((x) >= 'a') && ((x) <= 'z'))
-
-/*
- * upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" |
- * "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" |
- * "U" | "V" | "W" | "X" | "Y" | "Z"
- */
-#define IS_UPALPHA(x) (((x) >= 'A') && ((x) <= 'Z'))
-
-/*
- * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
- */
-
-#define IS_DIGIT(x) (((x) >= '0') && ((x) <= '9'))
-
-/*
- * alphanum = alpha | digit
- */
-
-#define IS_ALPHANUM(x) (IS_ALPHA(x) || IS_DIGIT(x))
-
-/*
- * hex = digit | "A" | "B" | "C" | "D" | "E" | "F" |
- * "a" | "b" | "c" | "d" | "e" | "f"
- */
-
-#define IS_HEX(x) ((IS_DIGIT(x)) || (((x) >= 'a') && ((x) <= 'f')) || \
- (((x) >= 'A') && ((x) <= 'F')))
-
-/*
- * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
- */
-
-#define IS_MARK(x) (((x) == '-') || ((x) == '_') || ((x) == '.') || \
- ((x) == '!') || ((x) == '~') || ((x) == '*') || ((x) == '\'') || \
- ((x) == '(') || ((x) == ')'))
-
-
-/*
- * reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
- */
-
-#define IS_RESERVED(x) (((x) == ';') || ((x) == '/') || ((x) == '?') || \
- ((x) == ':') || ((x) == '@') || ((x) == '&') || ((x) == '=') || \
- ((x) == '+') || ((x) == '$') || ((x) == ','))
-
-/*
- * unreserved = alphanum | mark
- */
-
-#define IS_UNRESERVED(x) (IS_ALPHANUM(x) || IS_MARK(x))
-
-/*
- * escaped = "%" hex hex
- */
-
-#define IS_ESCAPED(p) ((*(p) == '%') && (IS_HEX((p)[1])) && \
- (IS_HEX((p)[2])))
-
-/*
- * uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
- * "&" | "=" | "+" | "$" | ","
- */
-#define IS_URIC_NO_SLASH(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) ||\
- ((*(p) == ';')) || ((*(p) == '?')) || ((*(p) == ':')) ||\
- ((*(p) == '@')) || ((*(p) == '&')) || ((*(p) == '=')) ||\
- ((*(p) == '+')) || ((*(p) == '$')) || ((*(p) == ',')))
-
-/*
- * pchar = unreserved | escaped | ":" | "@" | "&" | "=" | "+" | "$" | ","
- */
-#define IS_PCHAR(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
- ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) ||\
- ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) ||\
- ((*(p) == ',')))
-
-/*
- * rel_segment = 1*( unreserved | escaped |
- * ";" | "@" | "&" | "=" | "+" | "$" | "," )
- */
-
-#define IS_SEGMENT(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
- ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) || \
- ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) || \
- ((*(p) == ',')))
-
-/*
- * scheme = alpha *( alpha | digit | "+" | "-" | "." )
- */
-
-#define IS_SCHEME(x) ((IS_ALPHA(x)) || (IS_DIGIT(x)) || \
- ((x) == '+') || ((x) == '-') || ((x) == '.'))
-
-/*
- * reg_name = 1*( unreserved | escaped | "$" | "," |
- * ";" | ":" | "@" | "&" | "=" | "+" )
- */
-
-#define IS_REG_NAME(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
- ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) || \
- ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) || \
- ((*(p) == '=')) || ((*(p) == '+')))
-
-/*
- * userinfo = *( unreserved | escaped | ";" | ":" | "&" | "=" |
- * "+" | "$" | "," )
- */
-#define IS_USERINFO(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
- ((*(p) == ';')) || ((*(p) == ':')) || ((*(p) == '&')) || \
- ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) || \
- ((*(p) == ',')))
-
-/*
- * uric = reserved | unreserved | escaped
- */
-
-#define IS_URIC(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \
- (IS_RESERVED(*(p))))
-
-/*
-* unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
-*/
-
-#define IS_UNWISE(p) \
- (((*(p) == '{')) || ((*(p) == '}')) || ((*(p) == '|')) || \
- ((*(p) == '\\')) || ((*(p) == '^')) || ((*(p) == '[')) || \
- ((*(p) == ']')) || ((*(p) == '`')))
-
-/*
- * Skip to next pointer char, handle escaped sequences
- */
-
-#define NEXT(p) ((*p == '%')? p += 3 : p++)
-
-/*
- * Productions from the spec.
- *
- * authority = server | reg_name
- * reg_name = 1*( unreserved | escaped | "$" | "," |
- * ";" | ":" | "@" | "&" | "=" | "+" )
- *
- * path = [ abs_path | opaque_part ]
- */
-
-/************************************************************************
- * *
- * Generic URI structure functions *
- * *
- ************************************************************************/
-
-/**
- * xmlCreateURI:
- *
- * Simply creates an empty xmlURI
- *
- * Returns the new structure or NULL in case of error
- */
-xmlURIPtr
-xmlCreateURI(void) {
- xmlURIPtr ret;
-
- ret = (xmlURIPtr) xmlMalloc(sizeof(xmlURI));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlCreateURI: out of memory\n");
- return(NULL);
- }
- memset(ret, 0, sizeof(xmlURI));
- return(ret);
-}
-
-/**
- * xmlSaveUri:
- * @uri: pointer to an xmlURI
- *
- * Save the URI as an escaped string
- *
- * Returns a new string (to be deallocated by caller)
- */
-xmlChar *
-xmlSaveUri(xmlURIPtr uri) {
- xmlChar *ret = NULL;
- const char *p;
- int len;
- int max;
-
- if (uri == NULL) return(NULL);
-
-
- max = 80;
- ret = (xmlChar *) xmlMalloc((max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- len = 0;
-
- if (uri->scheme != NULL) {
- p = uri->scheme;
- while (*p != 0) {
- if (len >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- }
- ret[len++] = *p++;
- }
- if (len >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- }
- ret[len++] = ':';
- }
- if (uri->opaque != NULL) {
- p = uri->opaque;
- while (*p != 0) {
- if (len + 3 >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- }
- if ((IS_UNRESERVED(*(p))) ||
- ((*(p) == ';')) || ((*(p) == '?')) || ((*(p) == ':')) ||
- ((*(p) == '@')) || ((*(p) == '&')) || ((*(p) == '=')) ||
- ((*(p) == '+')) || ((*(p) == '$')) || ((*(p) == ',')))
- ret[len++] = *p++;
- else {
- int val = *(unsigned char *)p++;
- int hi = val / 0x10, lo = val % 0x10;
- ret[len++] = '%';
- ret[len++] = hi + (hi > 9? 'A'-10 : '0');
- ret[len++] = lo + (lo > 9? 'A'-10 : '0');
- }
- }
- } else {
- if (uri->server != NULL) {
- if (len + 3 >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- }
- ret[len++] = '/';
- ret[len++] = '/';
- if (uri->user != NULL) {
- p = uri->user;
- while (*p != 0) {
- if (len + 3 >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- }
- if ((IS_UNRESERVED(*(p))) ||
- ((*(p) == ';')) || ((*(p) == ':')) ||
- ((*(p) == '&')) || ((*(p) == '=')) ||
- ((*(p) == '+')) || ((*(p) == '$')) ||
- ((*(p) == ',')))
- ret[len++] = *p++;
- else {
- int val = *(unsigned char *)p++;
- int hi = val / 0x10, lo = val % 0x10;
- ret[len++] = '%';
- ret[len++] = hi + (hi > 9? 'A'-10 : '0');
- ret[len++] = lo + (lo > 9? 'A'-10 : '0');
- }
- }
- if (len + 3 >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- }
- ret[len++] = '@';
- }
- p = uri->server;
- while (*p != 0) {
- if (len >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- }
- ret[len++] = *p++;
- }
- if (uri->port > 0) {
- if (len + 10 >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- }
- len += snprintf((char *) &ret[len], max - len, ":%d", uri->port);
- }
- } else if (uri->authority != NULL) {
- if (len + 3 >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- }
- ret[len++] = '/';
- ret[len++] = '/';
- p = uri->authority;
- while (*p != 0) {
- if (len + 3 >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- }
- if ((IS_UNRESERVED(*(p))) ||
- ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) ||
- ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) ||
- ((*(p) == '=')) || ((*(p) == '+')))
- ret[len++] = *p++;
- else {
- int val = *(unsigned char *)p++;
- int hi = val / 0x10, lo = val % 0x10;
- ret[len++] = '%';
- ret[len++] = hi + (hi > 9? 'A'-10 : '0');
- ret[len++] = lo + (lo > 9? 'A'-10 : '0');
- }
- }
- } else if (uri->scheme != NULL) {
- if (len + 3 >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- }
- ret[len++] = '/';
- ret[len++] = '/';
- }
- if (uri->path != NULL) {
- p = uri->path;
- while (*p != 0) {
- if (len + 3 >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- }
- if ((IS_UNRESERVED(*(p))) || ((*(p) == '/')) ||
- ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) ||
- ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) ||
- ((*(p) == ',')))
- ret[len++] = *p++;
- else {
- int val = *(unsigned char *)p++;
- int hi = val / 0x10, lo = val % 0x10;
- ret[len++] = '%';
- ret[len++] = hi + (hi > 9? 'A'-10 : '0');
- ret[len++] = lo + (lo > 9? 'A'-10 : '0');
- }
- }
- }
- if (uri->query != NULL) {
- if (len + 3 >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- }
- ret[len++] = '?';
- p = uri->query;
- while (*p != 0) {
- if (len + 3 >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- }
- if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p))))
- ret[len++] = *p++;
- else {
- int val = *(unsigned char *)p++;
- int hi = val / 0x10, lo = val % 0x10;
- ret[len++] = '%';
- ret[len++] = hi + (hi > 9? 'A'-10 : '0');
- ret[len++] = lo + (lo > 9? 'A'-10 : '0');
- }
- }
- }
- }
- if (uri->fragment != NULL) {
- if (len + 3 >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- }
- ret[len++] = '#';
- p = uri->fragment;
- while (*p != 0) {
- if (len + 3 >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret,
- (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- }
- if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p))))
- ret[len++] = *p++;
- else {
- int val = *(unsigned char *)p++;
- int hi = val / 0x10, lo = val % 0x10;
- ret[len++] = '%';
- ret[len++] = hi + (hi > 9? 'A'-10 : '0');
- ret[len++] = lo + (lo > 9? 'A'-10 : '0');
- }
- }
- }
- if (len >= max) {
- max *= 2;
- ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlSaveUri: out of memory\n");
- return(NULL);
- }
- }
- ret[len++] = 0;
- return(ret);
-}
-
-/**
- * xmlPrintURI:
- * @stream: a FILE* for the output
- * @uri: pointer to an xmlURI
- *
- * Prints the URI in the stream @steam.
- */
-void
-xmlPrintURI(FILE *stream, xmlURIPtr uri) {
- xmlChar *out;
-
- out = xmlSaveUri(uri);
- if (out != NULL) {
- fprintf(stream, "%s", out);
- xmlFree(out);
- }
-}
-
-/**
- * xmlCleanURI:
- * @uri: pointer to an xmlURI
- *
- * Make sure the xmlURI struct is free of content
- */
-static void
-xmlCleanURI(xmlURIPtr uri) {
- if (uri == NULL) return;
-
- if (uri->scheme != NULL) xmlFree(uri->scheme);
- uri->scheme = NULL;
- if (uri->server != NULL) xmlFree(uri->server);
- uri->server = NULL;
- if (uri->user != NULL) xmlFree(uri->user);
- uri->user = NULL;
- if (uri->path != NULL) xmlFree(uri->path);
- uri->path = NULL;
- if (uri->fragment != NULL) xmlFree(uri->fragment);
- uri->fragment = NULL;
- if (uri->opaque != NULL) xmlFree(uri->opaque);
- uri->opaque = NULL;
- if (uri->authority != NULL) xmlFree(uri->authority);
- uri->authority = NULL;
- if (uri->query != NULL) xmlFree(uri->query);
- uri->query = NULL;
-}
-
-/**
- * xmlFreeURI:
- * @uri: pointer to an xmlURI
- *
- * Free up the xmlURI struct
- */
-void
-xmlFreeURI(xmlURIPtr uri) {
- if (uri == NULL) return;
-
- if (uri->scheme != NULL) xmlFree(uri->scheme);
- if (uri->server != NULL) xmlFree(uri->server);
- if (uri->user != NULL) xmlFree(uri->user);
- if (uri->path != NULL) xmlFree(uri->path);
- if (uri->fragment != NULL) xmlFree(uri->fragment);
- if (uri->opaque != NULL) xmlFree(uri->opaque);
- if (uri->authority != NULL) xmlFree(uri->authority);
- if (uri->query != NULL) xmlFree(uri->query);
- xmlFree(uri);
-}
-
-/************************************************************************
- * *
- * Helper functions *
- * *
- ************************************************************************/
-
-/**
- * xmlNormalizeURIPath:
- * @path: pointer to the path string
- *
- * Applies the 5 normalization steps to a path string--that is, RFC 2396
- * Section 5.2, steps 6.c through 6.g.
- *
- * Normalization occurs directly on the string, no new allocation is done
- *
- * Returns 0 or an error code
- */
-int
-xmlNormalizeURIPath(char *path) {
- char *cur, *out;
-
- if (path == NULL)
- return(-1);
-
- /* Skip all initial "/" chars. We want to get to the beginning of the
- * first non-empty segment.
- */
- cur = path;
- while (cur[0] == '/')
- ++cur;
- if (cur[0] == '\0')
- return(0);
-
- /* Keep everything we've seen so far. */
- out = cur;
-
- /*
- * Analyze each segment in sequence for cases (c) and (d).
- */
- while (cur[0] != '\0') {
- /*
- * c) All occurrences of "./", where "." is a complete path segment,
- * are removed from the buffer string.
- */
- if ((cur[0] == '.') && (cur[1] == '/')) {
- cur += 2;
- /* '//' normalization should be done at this point too */
- while (cur[0] == '/')
- cur++;
- continue;
- }
-
- /*
- * d) If the buffer string ends with "." as a complete path segment,
- * that "." is removed.
- */
- if ((cur[0] == '.') && (cur[1] == '\0'))
- break;
-
- /* Otherwise keep the segment. */
- while (cur[0] != '/') {
- if (cur[0] == '\0')
- goto done_cd;
- (out++)[0] = (cur++)[0];
- }
- /* nomalize // */
- while ((cur[0] == '/') && (cur[1] == '/'))
- cur++;
-
- (out++)[0] = (cur++)[0];
- }
- done_cd:
- out[0] = '\0';
-
- /* Reset to the beginning of the first segment for the next sequence. */
- cur = path;
- while (cur[0] == '/')
- ++cur;
- if (cur[0] == '\0')
- return(0);
-
- /*
- * Analyze each segment in sequence for cases (e) and (f).
- *
- * e) All occurrences of "<segment>/../", where <segment> is a
- * complete path segment not equal to "..", are removed from the
- * buffer string. Removal of these path segments is performed
- * iteratively, removing the leftmost matching pattern on each
- * iteration, until no matching pattern remains.
- *
- * f) If the buffer string ends with "<segment>/..", where <segment>
- * is a complete path segment not equal to "..", that
- * "<segment>/.." is removed.
- *
- * To satisfy the "iterative" clause in (e), we need to collapse the
- * string every time we find something that needs to be removed. Thus,
- * we don't need to keep two pointers into the string: we only need a
- * "current position" pointer.
- */
- while (1) {
- char *segp;
-
- /* At the beginning of each iteration of this loop, "cur" points to
- * the first character of the segment we want to examine.
- */
-
- /* Find the end of the current segment. */
- segp = cur;
- while ((segp[0] != '/') && (segp[0] != '\0'))
- ++segp;
-
- /* If this is the last segment, we're done (we need at least two
- * segments to meet the criteria for the (e) and (f) cases).
- */
- if (segp[0] == '\0')
- break;
-
- /* If the first segment is "..", or if the next segment _isn't_ "..",
- * keep this segment and try the next one.
- */
- ++segp;
- if (((cur[0] == '.') && (cur[1] == '.') && (segp == cur+3))
- || ((segp[0] != '.') || (segp[1] != '.')
- || ((segp[2] != '/') && (segp[2] != '\0')))) {
- cur = segp;
- continue;
- }
-
- /* If we get here, remove this segment and the next one and back up
- * to the previous segment (if there is one), to implement the
- * "iteratively" clause. It's pretty much impossible to back up
- * while maintaining two pointers into the buffer, so just compact
- * the whole buffer now.
- */
-
- /* If this is the end of the buffer, we're done. */
- if (segp[2] == '\0') {
- cur[0] = '\0';
- break;
- }
- strcpy(cur, segp + 3);
-
- /* If there are no previous segments, then keep going from here. */
- segp = cur;
- while ((segp > path) && ((--segp)[0] == '/'))
- ;
- if (segp == path)
- continue;
-
- /* "segp" is pointing to the end of a previous segment; find it's
- * start. We need to back up to the previous segment and start
- * over with that to handle things like "foo/bar/../..". If we
- * don't do this, then on the first pass we'll remove the "bar/..",
- * but be pointing at the second ".." so we won't realize we can also
- * remove the "foo/..".
- */
- cur = segp;
- while ((cur > path) && (cur[-1] != '/'))
- --cur;
- }
- out[0] = '\0';
-
- /*
- * g) If the resulting buffer string still begins with one or more
- * complete path segments of "..", then the reference is
- * considered to be in error. Implementations may handle this
- * error by retaining these components in the resolved path (i.e.,
- * treating them as part of the final URI), by removing them from
- * the resolved path (i.e., discarding relative levels above the
- * root), or by avoiding traversal of the reference.
- *
- * We discard them from the final path.
- */
- if (path[0] == '/') {
- cur = path;
- while ((cur[1] == '.') && (cur[2] == '.')
- && ((cur[3] == '/') || (cur[3] == '\0')))
- cur += 3;
-
- if (cur != path) {
- out = path;
- while (cur[0] != '\0')
- (out++)[0] = (cur++)[0];
- out[0] = 0;
- }
- }
-
- return(0);
-}
-
-/**
- * xmlURIUnescapeString:
- * @str: the string to unescape
- * @len: the length in bytes to unescape (or <= 0 to indicate full string)
- * @target: optional destination buffer
- *
- * Unescaping routine, does not do validity checks !
- * Output is direct unsigned char translation of %XX values (no encoding)
- *
- * Returns an copy of the string, but unescaped
- */
-char *
-xmlURIUnescapeString(const char *str, int len, char *target) {
- char *ret, *out;
- const char *in;
-
- if (str == NULL)
- return(NULL);
- if (len <= 0) len = strlen(str);
- if (len <= 0) return(NULL);
-
- if (target == NULL) {
- ret = (char *) xmlMalloc(len + 1);
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlURIUnescapeString: out of memory\n");
- return(NULL);
- }
- } else
- ret = target;
- in = str;
- out = ret;
- while(len > 0) {
- if (*in == '%') {
- in++;
- if ((*in >= '0') && (*in <= '9'))
- *out = (*in - '0');
- else if ((*in >= 'a') && (*in <= 'f'))
- *out = (*in - 'a') + 10;
- else if ((*in >= 'A') && (*in <= 'F'))
- *out = (*in - 'A') + 10;
- in++;
- if ((*in >= '0') && (*in <= '9'))
- *out = *out * 16 + (*in - '0');
- else if ((*in >= 'a') && (*in <= 'f'))
- *out = *out * 16 + (*in - 'a') + 10;
- else if ((*in >= 'A') && (*in <= 'F'))
- *out = *out * 16 + (*in - 'A') + 10;
- in++;
- len -= 3;
- out++;
- } else {
- *out++ = *in++;
- len--;
- }
- }
- *out = 0;
- return(ret);
-}
-
-/**
- * xmlURIEscapeStr:
- * @str: string to escape
- * @list: exception list string of chars not to escape
- *
- * This routine escapes a string to hex, ignoring reserved characters (a-z)
- * and the characters in the exception list.
- *
- * Returns a new escaped string or NULL in case of error.
- */
-xmlChar *
-xmlURIEscapeStr(const xmlChar *str, const xmlChar *list) {
- xmlChar *ret, ch;
- const xmlChar *in;
-
- unsigned int len, out;
-
- if (str == NULL)
- return(NULL);
- len = xmlStrlen(str);
- if (!(len > 0)) return(NULL);
-
- len += 20;
- ret = (xmlChar *) xmlMalloc(len);
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlURIEscapeStr: out of memory\n");
- return(NULL);
- }
- in = (const xmlChar *) str;
- out = 0;
- while(*in != 0) {
- if (len - out <= 3) {
- len += 20;
- ret = (xmlChar *) xmlRealloc(ret, len);
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlURIEscapeStr: out of memory\n");
- return(NULL);
- }
- }
-
- ch = *in;
-
- if ((ch != '@') && (!IS_UNRESERVED(ch)) && (!xmlStrchr(list, ch))) {
- unsigned char val;
- ret[out++] = '%';
- val = ch >> 4;
- if (val <= 9)
- ret[out++] = '0' + val;
- else
- ret[out++] = 'A' + val - 0xA;
- val = ch & 0xF;
- if (val <= 9)
- ret[out++] = '0' + val;
- else
- ret[out++] = 'A' + val - 0xA;
- in++;
- } else {
- ret[out++] = *in++;
- }
-
- }
- ret[out] = 0;
- return(ret);
-}
-
-/**
- * xmlURIEscape:
- * @str: the string of the URI to escape
- *
- * Escaping routine, does not do validity checks !
- * It will try to escape the chars needing this, but this is heuristic
- * based it's impossible to be sure.
- *
- * Returns an copy of the string, but escaped
- *
- * 25 May 2001
- * Uses xmlParseURI and xmlURIEscapeStr to try to escape correctly
- * according to RFC2396.
- * - Carl Douglas
- */
-xmlChar *
-xmlURIEscape(const xmlChar * str)
-{
- xmlChar *ret, *segment = NULL;
- xmlURIPtr uri;
- int ret2;
-
-#define NULLCHK(p) if(!p) { \
- xmlGenericError(xmlGenericErrorContext, \
- "xmlURIEscape: out of memory\n"); \
- return NULL; }
-
- if (str == NULL)
- return (NULL);
-
- uri = xmlCreateURI();
- if (uri != NULL) {
- /*
- * Allow escaping errors in the unescaped form
- */
- uri->cleanup = 1;
- ret2 = xmlParseURIReference(uri, (const char *)str);
- if (ret2) {
- xmlFreeURI(uri);
- return (NULL);
- }
- }
-
- if (!uri)
- return NULL;
-
- ret = NULL;
-
- if (uri->scheme) {
- segment = xmlURIEscapeStr(BAD_CAST uri->scheme, BAD_CAST "+-.");
- NULLCHK(segment)
- ret = xmlStrcat(ret, segment);
- ret = xmlStrcat(ret, BAD_CAST ":");
- xmlFree(segment);
- }
-
- if (uri->authority) {
- segment =
- xmlURIEscapeStr(BAD_CAST uri->authority, BAD_CAST "/?;:@");
- NULLCHK(segment)
- ret = xmlStrcat(ret, BAD_CAST "//");
- ret = xmlStrcat(ret, segment);
- xmlFree(segment);
- }
-
- if (uri->user) {
- segment = xmlURIEscapeStr(BAD_CAST uri->user, BAD_CAST ";:&=+$,");
- NULLCHK(segment)
- ret = xmlStrcat(ret, segment);
- ret = xmlStrcat(ret, BAD_CAST "@");
- xmlFree(segment);
- }
-
- if (uri->server) {
- segment = xmlURIEscapeStr(BAD_CAST uri->server, BAD_CAST "/?;:@");
- NULLCHK(segment)
- ret = xmlStrcat(ret, BAD_CAST "//");
- ret = xmlStrcat(ret, segment);
- xmlFree(segment);
- }
-
- if (uri->port) {
- xmlChar port[10];
-
- snprintf((char *) port, 10, "%d", uri->port);
- ret = xmlStrcat(ret, BAD_CAST ":");
- ret = xmlStrcat(ret, port);
- }
-
- if (uri->path) {
- segment =
- xmlURIEscapeStr(BAD_CAST uri->path, BAD_CAST ":@&=+$,/?;");
- NULLCHK(segment)
- ret = xmlStrcat(ret, segment);
- xmlFree(segment);
- }
-
- if (uri->query) {
- segment =
- xmlURIEscapeStr(BAD_CAST uri->query, BAD_CAST ";/?:@&=+,$");
- NULLCHK(segment)
- ret = xmlStrcat(ret, BAD_CAST "?");
- ret = xmlStrcat(ret, segment);
- xmlFree(segment);
- }
-
- if (uri->opaque) {
- segment = xmlURIEscapeStr(BAD_CAST uri->opaque, BAD_CAST "");
- NULLCHK(segment)
- ret = xmlStrcat(ret, segment);
- xmlFree(segment);
- }
-
- if (uri->fragment) {
- segment = xmlURIEscapeStr(BAD_CAST uri->fragment, BAD_CAST "#");
- NULLCHK(segment)
- ret = xmlStrcat(ret, BAD_CAST "#");
- ret = xmlStrcat(ret, segment);
- xmlFree(segment);
- }
-
- xmlFreeURI(uri);
-#undef NULLCHK
-
- return (ret);
-}
-
-/************************************************************************
- * *
- * Escaped URI parsing *
- * *
- ************************************************************************/
-
-/**
- * xmlParseURIFragment:
- * @uri: pointer to an URI structure
- * @str: pointer to the string to analyze
- *
- * Parse an URI fragment string and fills in the appropriate fields
- * of the @uri structure.
- *
- * fragment = *uric
- *
- * Returns 0 or the error code
- */
-static int
-xmlParseURIFragment(xmlURIPtr uri, const char **str)
-{
- const char *cur = *str;
-
- if (str == NULL)
- return (-1);
-
- while (IS_URIC(cur) || IS_UNWISE(cur))
- NEXT(cur);
- if (uri != NULL) {
- if (uri->fragment != NULL)
- xmlFree(uri->fragment);
- uri->fragment = xmlURIUnescapeString(*str, cur - *str, NULL);
- }
- *str = cur;
- return (0);
-}
-
-/**
- * xmlParseURIQuery:
- * @uri: pointer to an URI structure
- * @str: pointer to the string to analyze
- *
- * Parse the query part of an URI
- *
- * query = *uric
- *
- * Returns 0 or the error code
- */
-static int
-xmlParseURIQuery(xmlURIPtr uri, const char **str)
-{
- const char *cur = *str;
-
- if (str == NULL)
- return (-1);
-
- while (IS_URIC(cur) || ((uri->cleanup) && (IS_UNWISE(cur))))
- NEXT(cur);
- if (uri != NULL) {
- if (uri->query != NULL)
- xmlFree(uri->query);
- uri->query = xmlURIUnescapeString(*str, cur - *str, NULL);
- }
- *str = cur;
- return (0);
-}
-
-/**
- * xmlParseURIScheme:
- * @uri: pointer to an URI structure
- * @str: pointer to the string to analyze
- *
- * Parse an URI scheme
- *
- * scheme = alpha *( alpha | digit | "+" | "-" | "." )
- *
- * Returns 0 or the error code
- */
-static int
-xmlParseURIScheme(xmlURIPtr uri, const char **str) {
- const char *cur;
-
- if (str == NULL)
- return(-1);
-
- cur = *str;
- if (!IS_ALPHA(*cur))
- return(2);
- cur++;
- while (IS_SCHEME(*cur)) cur++;
- if (uri != NULL) {
- if (uri->scheme != NULL) xmlFree(uri->scheme);
- /* !!! strndup */
- uri->scheme = xmlURIUnescapeString(*str, cur - *str, NULL);
- }
- *str = cur;
- return(0);
-}
-
-/**
- * xmlParseURIOpaquePart:
- * @uri: pointer to an URI structure
- * @str: pointer to the string to analyze
- *
- * Parse an URI opaque part
- *
- * opaque_part = uric_no_slash *uric
- *
- * Returns 0 or the error code
- */
-static int
-xmlParseURIOpaquePart(xmlURIPtr uri, const char **str)
-{
- const char *cur;
-
- if (str == NULL)
- return (-1);
-
- cur = *str;
- if (!(IS_URIC_NO_SLASH(cur) || ((uri->cleanup) && (IS_UNWISE(cur))))) {
- return (3);
- }
- NEXT(cur);
- while (IS_URIC(cur) || ((uri->cleanup) && (IS_UNWISE(cur))))
- NEXT(cur);
- if (uri != NULL) {
- if (uri->opaque != NULL)
- xmlFree(uri->opaque);
- uri->opaque = xmlURIUnescapeString(*str, cur - *str, NULL);
- }
- *str = cur;
- return (0);
-}
-
-/**
- * xmlParseURIServer:
- * @uri: pointer to an URI structure
- * @str: pointer to the string to analyze
- *
- * Parse a server subpart of an URI, it's a finer grain analysis
- * of the authority part.
- *
- * server = [ [ userinfo "@" ] hostport ]
- * userinfo = *( unreserved | escaped |
- * ";" | ":" | "&" | "=" | "+" | "$" | "," )
- * hostport = host [ ":" port ]
- * host = hostname | IPv4address
- * hostname = *( domainlabel "." ) toplabel [ "." ]
- * domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
- * toplabel = alpha | alpha *( alphanum | "-" ) alphanum
- * IPv4address = 1*digit "." 1*digit "." 1*digit "." 1*digit
- * port = *digit
- *
- * Returns 0 or the error code
- */
-static int
-xmlParseURIServer(xmlURIPtr uri, const char **str) {
- const char *cur;
- const char *host, *tmp;
-
- if (str == NULL)
- return(-1);
-
- cur = *str;
-
- /*
- * is there an userinfo ?
- */
- while (IS_USERINFO(cur)) NEXT(cur);
- if (*cur == '@') {
- if (uri != NULL) {
- if (uri->user != NULL) xmlFree(uri->user);
- uri->user = xmlURIUnescapeString(*str, cur - *str, NULL);
- }
- cur++;
- } else {
- if (uri != NULL) {
- if (uri->user != NULL) xmlFree(uri->user);
- uri->user = NULL;
- }
- cur = *str;
- }
- /*
- * This can be empty in the case where there is no server
- */
- host = cur;
- if (*cur == '/') {
- if (uri != NULL) {
- if (uri->authority != NULL) xmlFree(uri->authority);
- uri->authority = NULL;
- if (uri->server != NULL) xmlFree(uri->server);
- uri->server = NULL;
- uri->port = 0;
- }
- return(0);
- }
- /*
- * host part of hostport can derive either an IPV4 address
- * or an unresolved name. Check the IP first, it easier to detect
- * errors if wrong one
- */
- if (IS_DIGIT(*cur)) {
- while(IS_DIGIT(*cur)) cur++;
- if (*cur != '.')
- goto host_name;
- cur++;
- if (!IS_DIGIT(*cur))
- goto host_name;
- while(IS_DIGIT(*cur)) cur++;
- if (*cur != '.')
- goto host_name;
- cur++;
- if (!IS_DIGIT(*cur))
- goto host_name;
- while(IS_DIGIT(*cur)) cur++;
- if (*cur != '.')
- goto host_name;
- cur++;
- if (!IS_DIGIT(*cur))
- goto host_name;
- while(IS_DIGIT(*cur)) cur++;
- if (uri != NULL) {
- if (uri->authority != NULL) xmlFree(uri->authority);
- uri->authority = NULL;
- if (uri->server != NULL) xmlFree(uri->server);
- uri->server = xmlURIUnescapeString(host, cur - host, NULL);
- }
- goto host_done;
- }
-host_name:
- /*
- * the hostname production as-is is a parser nightmare.
- * simplify it to
- * hostname = *( domainlabel "." ) domainlabel [ "." ]
- * and just make sure the last label starts with a non numeric char.
- */
- if (!IS_ALPHANUM(*cur))
- return(6);
- while (IS_ALPHANUM(*cur)) {
- while ((IS_ALPHANUM(*cur)) || (*cur == '-')) cur++;
- if (*cur == '.')
- cur++;
- }
- tmp = cur;
- tmp--;
- while (IS_ALPHANUM(*tmp) && (*tmp != '.') && (tmp >= host)) tmp--;
- tmp++;
- if (!IS_ALPHA(*tmp))
- return(7);
- if (uri != NULL) {
- if (uri->authority != NULL) xmlFree(uri->authority);
- uri->authority = NULL;
- if (uri->server != NULL) xmlFree(uri->server);
- uri->server = xmlURIUnescapeString(host, cur - host, NULL);
- }
-
-host_done:
-
- /*
- * finish by checking for a port presence.
- */
- if (*cur == ':') {
- cur++;
- if (IS_DIGIT(*cur)) {
- if (uri != NULL)
- uri->port = 0;
- while (IS_DIGIT(*cur)) {
- if (uri != NULL)
- uri->port = uri->port * 10 + (*cur - '0');
- cur++;
- }
- }
- }
- *str = cur;
- return(0);
-}
-
-/**
- * xmlParseURIRelSegment:
- * @uri: pointer to an URI structure
- * @str: pointer to the string to analyze
- *
- * Parse an URI relative segment
- *
- * rel_segment = 1*( unreserved | escaped | ";" | "@" | "&" | "=" |
- * "+" | "$" | "," )
- *
- * Returns 0 or the error code
- */
-static int
-xmlParseURIRelSegment(xmlURIPtr uri, const char **str)
-{
- const char *cur;
-
- if (str == NULL)
- return (-1);
-
- cur = *str;
- if (!(IS_SEGMENT(cur) || ((uri->cleanup) && (IS_UNWISE(cur))))) {
- return (3);
- }
- NEXT(cur);
- while (IS_SEGMENT(cur) || ((uri->cleanup) && (IS_UNWISE(cur))))
- NEXT(cur);
- if (uri != NULL) {
- if (uri->path != NULL)
- xmlFree(uri->path);
- uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
- }
- *str = cur;
- return (0);
-}
-
-/**
- * xmlParseURIPathSegments:
- * @uri: pointer to an URI structure
- * @str: pointer to the string to analyze
- * @slash: should we add a leading slash
- *
- * Parse an URI set of path segments
- *
- * path_segments = segment *( "/" segment )
- * segment = *pchar *( ";" param )
- * param = *pchar
- *
- * Returns 0 or the error code
- */
-static int
-xmlParseURIPathSegments(xmlURIPtr uri, const char **str, int slash)
-{
- const char *cur;
-
- if (str == NULL)
- return (-1);
-
- cur = *str;
-
- do {
- while (IS_PCHAR(cur) || ((uri->cleanup) && (IS_UNWISE(cur))))
- NEXT(cur);
- while (*cur == ';') {
- cur++;
- while (IS_PCHAR(cur) || ((uri->cleanup) && (IS_UNWISE(cur))))
- NEXT(cur);
- }
- if (*cur != '/')
- break;
- cur++;
- } while (1);
- if (uri != NULL) {
- int len, len2 = 0;
- char *path;
-
- /*
- * Concat the set of path segments to the current path
- */
- len = cur - *str;
- if (slash)
- len++;
-
- if (uri->path != NULL) {
- len2 = strlen(uri->path);
- len += len2;
- }
- path = (char *) xmlMalloc(len + 1);
- if (path == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlParseURIPathSegments: out of memory\n");
- *str = cur;
- return (-1);
- }
- if (uri->path != NULL)
- memcpy(path, uri->path, len2);
- if (slash) {
- path[len2] = '/';
- len2++;
- }
- path[len2] = 0;
- if (cur - *str > 0)
- xmlURIUnescapeString(*str, cur - *str, &path[len2]);
- if (uri->path != NULL)
- xmlFree(uri->path);
- uri->path = path;
- }
- *str = cur;
- return (0);
-}
-
-/**
- * xmlParseURIAuthority:
- * @uri: pointer to an URI structure
- * @str: pointer to the string to analyze
- *
- * Parse the authority part of an URI.
- *
- * authority = server | reg_name
- * server = [ [ userinfo "@" ] hostport ]
- * reg_name = 1*( unreserved | escaped | "$" | "," | ";" | ":" |
- * "@" | "&" | "=" | "+" )
- *
- * Note : this is completely ambiguous since reg_name is allowed to
- * use the full set of chars in use by server:
- *
- * 3.2.1. Registry-based Naming Authority
- *
- * The structure of a registry-based naming authority is specific
- * to the URI scheme, but constrained to the allowed characters
- * for an authority component.
- *
- * Returns 0 or the error code
- */
-static int
-xmlParseURIAuthority(xmlURIPtr uri, const char **str) {
- const char *cur;
- int ret;
-
- if (str == NULL)
- return(-1);
-
- cur = *str;
-
- /*
- * try first to parse it as a server string.
- */
- ret = xmlParseURIServer(uri, str);
- if (ret == 0)
- return(0);
-
- /*
- * failed, fallback to reg_name
- */
- if (!IS_REG_NAME(cur)) {
- return(5);
- }
- NEXT(cur);
- while (IS_REG_NAME(cur)) NEXT(cur);
- if (uri != NULL) {
- if (uri->server != NULL) xmlFree(uri->server);
- uri->server = NULL;
- if (uri->user != NULL) xmlFree(uri->user);
- uri->user = NULL;
- if (uri->authority != NULL) xmlFree(uri->authority);
- uri->authority = xmlURIUnescapeString(*str, cur - *str, NULL);
- }
- *str = cur;
- return(0);
-}
-
-/**
- * xmlParseURIHierPart:
- * @uri: pointer to an URI structure
- * @str: pointer to the string to analyze
- *
- * Parse an URI hierarchical part
- *
- * hier_part = ( net_path | abs_path ) [ "?" query ]
- * abs_path = "/" path_segments
- * net_path = "//" authority [ abs_path ]
- *
- * Returns 0 or the error code
- */
-static int
-xmlParseURIHierPart(xmlURIPtr uri, const char **str) {
- int ret;
- const char *cur;
-
- if (str == NULL)
- return(-1);
-
- cur = *str;
-
- if ((cur[0] == '/') && (cur[1] == '/')) {
- cur += 2;
- ret = xmlParseURIAuthority(uri, &cur);
- if (ret != 0)
- return(ret);
- if (cur[0] == '/') {
- cur++;
- ret = xmlParseURIPathSegments(uri, &cur, 1);
- }
- } else if (cur[0] == '/') {
- cur++;
- ret = xmlParseURIPathSegments(uri, &cur, 1);
- } else {
- return(4);
- }
- if (ret != 0)
- return(ret);
- if (*cur == '?') {
- cur++;
- ret = xmlParseURIQuery(uri, &cur);
- if (ret != 0)
- return(ret);
- }
- *str = cur;
- return(0);
-}
-
-/**
- * xmlParseAbsoluteURI:
- * @uri: pointer to an URI structure
- * @str: pointer to the string to analyze
- *
- * Parse an URI reference string and fills in the appropriate fields
- * of the @uri structure
- *
- * absoluteURI = scheme ":" ( hier_part | opaque_part )
- *
- * Returns 0 or the error code
- */
-static int
-xmlParseAbsoluteURI(xmlURIPtr uri, const char **str) {
- int ret;
- const char *cur;
-
- if (str == NULL)
- return(-1);
-
- cur = *str;
-
- ret = xmlParseURIScheme(uri, str);
- if (ret != 0) return(ret);
- if (**str != ':') {
- *str = cur;
- return(1);
- }
- (*str)++;
- if (**str == '/')
- return(xmlParseURIHierPart(uri, str));
- return(xmlParseURIOpaquePart(uri, str));
-}
-
-/**
- * xmlParseRelativeURI:
- * @uri: pointer to an URI structure
- * @str: pointer to the string to analyze
- *
- * Parse an relative URI string and fills in the appropriate fields
- * of the @uri structure
- *
- * relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
- * abs_path = "/" path_segments
- * net_path = "//" authority [ abs_path ]
- * rel_path = rel_segment [ abs_path ]
- *
- * Returns 0 or the error code
- */
-static int
-xmlParseRelativeURI(xmlURIPtr uri, const char **str) {
- int ret = 0;
- const char *cur;
-
- if (str == NULL)
- return(-1);
-
- cur = *str;
- if ((cur[0] == '/') && (cur[1] == '/')) {
- cur += 2;
- ret = xmlParseURIAuthority(uri, &cur);
- if (ret != 0)
- return(ret);
- if (cur[0] == '/') {
- cur++;
- ret = xmlParseURIPathSegments(uri, &cur, 1);
- }
- } else if (cur[0] == '/') {
- cur++;
- ret = xmlParseURIPathSegments(uri, &cur, 1);
- } else if (cur[0] != '#' && cur[0] != '?') {
- ret = xmlParseURIRelSegment(uri, &cur);
- if (ret != 0)
- return(ret);
- if (cur[0] == '/') {
- cur++;
- ret = xmlParseURIPathSegments(uri, &cur, 1);
- }
- }
- if (ret != 0)
- return(ret);
- if (*cur == '?') {
- cur++;
- ret = xmlParseURIQuery(uri, &cur);
- if (ret != 0)
- return(ret);
- }
- *str = cur;
- return(ret);
-}
-
-/**
- * xmlParseURIReference:
- * @uri: pointer to an URI structure
- * @str: the string to analyze
- *
- * Parse an URI reference string and fills in the appropriate fields
- * of the @uri structure
- *
- * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
- *
- * Returns 0 or the error code
- */
-int
-xmlParseURIReference(xmlURIPtr uri, const char *str) {
- int ret;
- const char *tmp = str;
-
- if (str == NULL)
- return(-1);
- xmlCleanURI(uri);
-
- /*
- * Try first to parse absolute refs, then fallback to relative if
- * it fails.
- */
- ret = xmlParseAbsoluteURI(uri, &str);
- if (ret != 0) {
- xmlCleanURI(uri);
- str = tmp;
- ret = xmlParseRelativeURI(uri, &str);
- }
- if (ret != 0) {
- xmlCleanURI(uri);
- return(ret);
- }
-
- if (*str == '#') {
- str++;
- ret = xmlParseURIFragment(uri, &str);
- if (ret != 0) return(ret);
- }
- if (*str != 0) {
- xmlCleanURI(uri);
- return(1);
- }
- return(0);
-}
-
-/**
- * xmlParseURI:
- * @str: the URI string to analyze
- *
- * Parse an URI
- *
- * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
- *
- * Returns a newly build xmlURIPtr or NULL in case of error
- */
-xmlURIPtr
-xmlParseURI(const char *str) {
- xmlURIPtr uri;
- int ret;
-
- if (str == NULL)
- return(NULL);
- uri = xmlCreateURI();
- if (uri != NULL) {
- ret = xmlParseURIReference(uri, str);
- if (ret) {
- xmlFreeURI(uri);
- return(NULL);
- }
- }
- return(uri);
-}
-
-/************************************************************************
- * *
- * Public functions *
- * *
- ************************************************************************/
-
-/**
- * xmlBuildURI:
- * @URI: the URI instance found in the document
- * @base: the base value
- *
- * Computes he final URI of the reference done by checking that
- * the given URI is valid, and building the final URI using the
- * base URI. This is processed according to section 5.2 of the
- * RFC 2396
- *
- * 5.2. Resolving Relative References to Absolute Form
- *
- * Returns a new URI string (to be freed by the caller) or NULL in case
- * of error.
- */
-xmlChar *
-xmlBuildURI(const xmlChar *URI, const xmlChar *base) {
- xmlChar *val = NULL;
- int ret, len, indx, cur, out;
- xmlURIPtr ref = NULL;
- xmlURIPtr bas = NULL;
- xmlURIPtr res = NULL;
-
- /*
- * 1) The URI reference is parsed into the potential four components and
- * fragment identifier, as described in Section 4.3.
- *
- * NOTE that a completely empty URI is treated by modern browsers
- * as a reference to "." rather than as a synonym for the current
- * URI. Should we do that here?
- */
- if (URI == NULL)
- ret = -1;
- else {
- if (*URI) {
- ref = xmlCreateURI();
- if (ref == NULL)
- goto done;
- ret = xmlParseURIReference(ref, (const char *) URI);
- }
- else
- ret = 0;
- }
- if (ret != 0)
- goto done;
- if (base == NULL)
- ret = -1;
- else {
- bas = xmlCreateURI();
- if (bas == NULL)
- goto done;
- ret = xmlParseURIReference(bas, (const char *) base);
- }
- if (ret != 0) {
- if (ref)
- val = xmlSaveUri(ref);
- goto done;
- }
- if (ref == NULL) {
- /*
- * the base fragment must be ignored
- */
- if (bas->fragment != NULL) {
- xmlFree(bas->fragment);
- bas->fragment = NULL;
- }
- val = xmlSaveUri(bas);
- goto done;
- }
-
- /*
- * 2) If the path component is empty and the scheme, authority, and
- * query components are undefined, then it is a reference to the
- * current document and we are done. Otherwise, the reference URI's
- * query and fragment components are defined as found (or not found)
- * within the URI reference and not inherited from the base URI.
- *
- * NOTE that in modern browsers, the parsing differs from the above
- * in the following aspect: the query component is allowed to be
- * defined while still treating this as a reference to the current
- * document.
- */
- res = xmlCreateURI();
- if (res == NULL)
- goto done;
- if ((ref->scheme == NULL) && (ref->path == NULL) &&
- ((ref->authority == NULL) && (ref->server == NULL))) {
- if (bas->scheme != NULL)
- res->scheme = xmlMemStrdup(bas->scheme);
- if (bas->authority != NULL)
- res->authority = xmlMemStrdup(bas->authority);
- else if (bas->server != NULL) {
- res->server = xmlMemStrdup(bas->server);
- if (bas->user != NULL)
- res->user = xmlMemStrdup(bas->user);
- res->port = bas->port;
- }
- if (bas->path != NULL)
- res->path = xmlMemStrdup(bas->path);
- if (ref->query != NULL)
- res->query = xmlMemStrdup(ref->query);
- else if (bas->query != NULL)
- res->query = xmlMemStrdup(bas->query);
- if (ref->fragment != NULL)
- res->fragment = xmlMemStrdup(ref->fragment);
- goto step_7;
- }
-
- if (ref->query != NULL)
- res->query = xmlMemStrdup(ref->query);
- if (ref->fragment != NULL)
- res->fragment = xmlMemStrdup(ref->fragment);
-
- /*
- * 3) If the scheme component is defined, indicating that the reference
- * starts with a scheme name, then the reference is interpreted as an
- * absolute URI and we are done. Otherwise, the reference URI's
- * scheme is inherited from the base URI's scheme component.
- */
- if (ref->scheme != NULL) {
- val = xmlSaveUri(ref);
- goto done;
- }
- if (bas->scheme != NULL)
- res->scheme = xmlMemStrdup(bas->scheme);
-
- /*
- * 4) If the authority component is defined, then the reference is a
- * network-path and we skip to step 7. Otherwise, the reference
- * URI's authority is inherited from the base URI's authority
- * component, which will also be undefined if the URI scheme does not
- * use an authority component.
- */
- if ((ref->authority != NULL) || (ref->server != NULL)) {
- if (ref->authority != NULL)
- res->authority = xmlMemStrdup(ref->authority);
- else {
- res->server = xmlMemStrdup(ref->server);
- if (ref->user != NULL)
- res->user = xmlMemStrdup(ref->user);
- res->port = ref->port;
- }
- if (ref->path != NULL)
- res->path = xmlMemStrdup(ref->path);
- goto step_7;
- }
- if (bas->authority != NULL)
- res->authority = xmlMemStrdup(bas->authority);
- else if (bas->server != NULL) {
- res->server = xmlMemStrdup(bas->server);
- if (bas->user != NULL)
- res->user = xmlMemStrdup(bas->user);
- res->port = bas->port;
- }
-
- /*
- * 5) If the path component begins with a slash character ("/"), then
- * the reference is an absolute-path and we skip to step 7.
- */
- if ((ref->path != NULL) && (ref->path[0] == '/')) {
- res->path = xmlMemStrdup(ref->path);
- goto step_7;
- }
-
-
- /*
- * 6) If this step is reached, then we are resolving a relative-path
- * reference. The relative path needs to be merged with the base
- * URI's path. Although there are many ways to do this, we will
- * describe a simple method using a separate string buffer.
- *
- * Allocate a buffer large enough for the result string.
- */
- len = 2; /* extra / and 0 */
- if (ref->path != NULL)
- len += strlen(ref->path);
- if (bas->path != NULL)
- len += strlen(bas->path);
- res->path = (char *) xmlMalloc(len);
- if (res->path == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlBuildURI: out of memory\n");
- goto done;
- }
- res->path[0] = 0;
-
- /*
- * a) All but the last segment of the base URI's path component is
- * copied to the buffer. In other words, any characters after the
- * last (right-most) slash character, if any, are excluded.
- */
- cur = 0;
- out = 0;
- if (bas->path != NULL) {
- while (bas->path[cur] != 0) {
- while ((bas->path[cur] != 0) && (bas->path[cur] != '/'))
- cur++;
- if (bas->path[cur] == 0)
- break;
-
- cur++;
- while (out < cur) {
- res->path[out] = bas->path[out];
- out++;
- }
- }
- }
- res->path[out] = 0;
-
- /*
- * b) The reference's path component is appended to the buffer
- * string.
- */
- if (ref->path != NULL && ref->path[0] != 0) {
- indx = 0;
- /*
- * Ensure the path includes a '/'
- */
- if ((out == 0) && (bas->server != NULL))
- res->path[out++] = '/';
- while (ref->path[indx] != 0) {
- res->path[out++] = ref->path[indx++];
- }
- }
- res->path[out] = 0;
-
- /*
- * Steps c) to h) are really path normalization steps
- */
- xmlNormalizeURIPath(res->path);
-
-step_7:
-
- /*
- * 7) The resulting URI components, including any inherited from the
- * base URI, are recombined to give the absolute form of the URI
- * reference.
- */
- val = xmlSaveUri(res);
-
-done:
- if (ref != NULL)
- xmlFreeURI(ref);
- if (bas != NULL)
- xmlFreeURI(bas);
- if (res != NULL)
- xmlFreeURI(res);
- return(val);
-}
-
-
diff --git a/bundle/libxml/valid.c b/bundle/libxml/valid.c
deleted file mode 100644
index 421a29aae5..0000000000
--- a/bundle/libxml/valid.c
+++ /dev/null
@@ -1,5968 +0,0 @@
-/*
- * valid.c : part of the code use to do the DTD handling and the validity
- * checking
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#include <string.h>
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#include <libxml/xmlmemory.h>
-#include <libxml/hash.h>
-#include <libxml/valid.h>
-#include <libxml/parser.h>
-#include <libxml/parserInternals.h>
-#include <libxml/xmlerror.h>
-#include <libxml/list.h>
-#include <libxml/globals.h>
-
-/* #define DEBUG_VALID_ALGO */
-/* #define DEBUG_REGEXP_ALGO */
-
-#define TODO \
- xmlGenericError(xmlGenericErrorContext, \
- "Unimplemented block at %s:%d\n", \
- __FILE__, __LINE__);
-
-
-#ifndef LIBXML_REGEXP_ENABLED
-/*
- * If regexp are not enabled, it uses a home made algorithm less
- * complex and easier to
- * debug/maintain than a generic NFA -> DFA state based algo. The
- * only restriction is on the deepness of the tree limited by the
- * size of the occurs bitfield
- *
- * this is the content of a saved state for rollbacks
- */
-
-#define ROLLBACK_OR 0
-#define ROLLBACK_PARENT 1
-
-typedef struct _xmlValidState {
- xmlElementContentPtr cont; /* pointer to the content model subtree */
- xmlNodePtr node; /* pointer to the current node in the list */
- long occurs;/* bitfield for multiple occurrences */
- unsigned char depth; /* current depth in the overall tree */
- unsigned char state; /* ROLLBACK_XXX */
-} _xmlValidState;
-
-#define MAX_RECURSE 25000
-#define MAX_DEPTH ((sizeof(_xmlValidState.occurs)) * 8)
-#define CONT ctxt->vstate->cont
-#define NODE ctxt->vstate->node
-#define DEPTH ctxt->vstate->depth
-#define OCCURS ctxt->vstate->occurs
-#define STATE ctxt->vstate->state
-
-#define OCCURRENCE (ctxt->vstate->occurs & (1 << DEPTH))
-#define PARENT_OCCURRENCE (ctxt->vstate->occurs & ((1 << DEPTH) - 1))
-
-#define SET_OCCURRENCE ctxt->vstate->occurs |= (1 << DEPTH)
-#define RESET_OCCURRENCE ctxt->vstate->occurs &= ((1 << DEPTH) - 1)
-
-static int
-vstateVPush(xmlValidCtxtPtr ctxt, xmlElementContentPtr cont,
- xmlNodePtr node, unsigned char depth, long occurs,
- unsigned char state) {
- int i = ctxt->vstateNr - 1;
-
- if (ctxt->vstateNr > MAX_RECURSE) {
- return(-1);
- }
- if (ctxt->vstateNr >= ctxt->vstateMax) {
- ctxt->vstateMax *= 2;
- ctxt->vstateTab = (xmlValidState *) xmlRealloc(ctxt->vstateTab,
- ctxt->vstateMax * sizeof(ctxt->vstateTab[0]));
- if (ctxt->vstateTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc failed !n");
- return(-1);
- }
- ctxt->vstate = &ctxt->vstateTab[0];
- }
- /*
- * Don't push on the stack a state already here
- */
- if ((i >= 0) && (ctxt->vstateTab[i].cont == cont) &&
- (ctxt->vstateTab[i].node == node) &&
- (ctxt->vstateTab[i].depth == depth) &&
- (ctxt->vstateTab[i].occurs == occurs) &&
- (ctxt->vstateTab[i].state == state))
- return(ctxt->vstateNr);
- ctxt->vstateTab[ctxt->vstateNr].cont = cont;
- ctxt->vstateTab[ctxt->vstateNr].node = node;
- ctxt->vstateTab[ctxt->vstateNr].depth = depth;
- ctxt->vstateTab[ctxt->vstateNr].occurs = occurs;
- ctxt->vstateTab[ctxt->vstateNr].state = state;
- return(ctxt->vstateNr++);
-}
-
-static int
-vstateVPop(xmlValidCtxtPtr ctxt) {
- if (ctxt->vstateNr <= 1) return(-1);
- ctxt->vstateNr--;
- ctxt->vstate = &ctxt->vstateTab[0];
- ctxt->vstate->cont = ctxt->vstateTab[ctxt->vstateNr].cont;
- ctxt->vstate->node = ctxt->vstateTab[ctxt->vstateNr].node;
- ctxt->vstate->depth = ctxt->vstateTab[ctxt->vstateNr].depth;
- ctxt->vstate->occurs = ctxt->vstateTab[ctxt->vstateNr].occurs;
- ctxt->vstate->state = ctxt->vstateTab[ctxt->vstateNr].state;
- return(ctxt->vstateNr);
-}
-
-#endif /* LIBXML_REGEXP_ENABLED */
-
-static int
-nodeVPush(xmlValidCtxtPtr ctxt, xmlNodePtr value)
-{
- if (ctxt->nodeMax <= 0) {
- ctxt->nodeMax = 4;
- ctxt->nodeTab =
- (xmlNodePtr *) xmlMalloc(ctxt->nodeMax *
- sizeof(ctxt->nodeTab[0]));
- if (ctxt->nodeTab == NULL) {
- xmlGenericError(xmlGenericErrorContext, "malloc failed !\n");
- ctxt->nodeMax = 0;
- return (0);
- }
- }
- if (ctxt->nodeNr >= ctxt->nodeMax) {
- ctxt->nodeMax *= 2;
- ctxt->nodeTab =
- (xmlNodePtr *) xmlRealloc(ctxt->nodeTab,
- ctxt->nodeMax *
- sizeof(ctxt->nodeTab[0]));
- if (ctxt->nodeTab == NULL) {
- xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
- return (0);
- }
- }
- ctxt->nodeTab[ctxt->nodeNr] = value;
- ctxt->node = value;
- return (ctxt->nodeNr++);
-}
-static xmlNodePtr
-nodeVPop(xmlValidCtxtPtr ctxt)
-{
- xmlNodePtr ret;
-
- if (ctxt->nodeNr <= 0)
- return (0);
- ctxt->nodeNr--;
- if (ctxt->nodeNr > 0)
- ctxt->node = ctxt->nodeTab[ctxt->nodeNr - 1];
- else
- ctxt->node = NULL;
- ret = ctxt->nodeTab[ctxt->nodeNr];
- ctxt->nodeTab[ctxt->nodeNr] = 0;
- return (ret);
-}
-
-#ifdef DEBUG_VALID_ALGO
-static void
-xmlValidPrintNode(xmlNodePtr cur) {
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext, "null");
- return;
- }
- switch (cur->type) {
- case XML_ELEMENT_NODE:
- xmlGenericError(xmlGenericErrorContext, "%s ", cur->name);
- break;
- case XML_TEXT_NODE:
- xmlGenericError(xmlGenericErrorContext, "text ");
- break;
- case XML_CDATA_SECTION_NODE:
- xmlGenericError(xmlGenericErrorContext, "cdata ");
- break;
- case XML_ENTITY_REF_NODE:
- xmlGenericError(xmlGenericErrorContext, "&%s; ", cur->name);
- break;
- case XML_PI_NODE:
- xmlGenericError(xmlGenericErrorContext, "pi(%s) ", cur->name);
- break;
- case XML_COMMENT_NODE:
- xmlGenericError(xmlGenericErrorContext, "comment ");
- break;
- case XML_ATTRIBUTE_NODE:
- xmlGenericError(xmlGenericErrorContext, "?attr? ");
- break;
- case XML_ENTITY_NODE:
- xmlGenericError(xmlGenericErrorContext, "?ent? ");
- break;
- case XML_DOCUMENT_NODE:
- xmlGenericError(xmlGenericErrorContext, "?doc? ");
- break;
- case XML_DOCUMENT_TYPE_NODE:
- xmlGenericError(xmlGenericErrorContext, "?doctype? ");
- break;
- case XML_DOCUMENT_FRAG_NODE:
- xmlGenericError(xmlGenericErrorContext, "?frag? ");
- break;
- case XML_NOTATION_NODE:
- xmlGenericError(xmlGenericErrorContext, "?nota? ");
- break;
- case XML_HTML_DOCUMENT_NODE:
- xmlGenericError(xmlGenericErrorContext, "?html? ");
- break;
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
- xmlGenericError(xmlGenericErrorContext, "?docb? ");
- break;
-#endif
- case XML_DTD_NODE:
- xmlGenericError(xmlGenericErrorContext, "?dtd? ");
- break;
- case XML_ELEMENT_DECL:
- xmlGenericError(xmlGenericErrorContext, "?edecl? ");
- break;
- case XML_ATTRIBUTE_DECL:
- xmlGenericError(xmlGenericErrorContext, "?adecl? ");
- break;
- case XML_ENTITY_DECL:
- xmlGenericError(xmlGenericErrorContext, "?entdecl? ");
- break;
- case XML_NAMESPACE_DECL:
- xmlGenericError(xmlGenericErrorContext, "?nsdecl? ");
- break;
- case XML_XINCLUDE_START:
- xmlGenericError(xmlGenericErrorContext, "incstart ");
- break;
- case XML_XINCLUDE_END:
- xmlGenericError(xmlGenericErrorContext, "incend ");
- break;
- }
-}
-
-static void
-xmlValidPrintNodeList(xmlNodePtr cur) {
- if (cur == NULL)
- xmlGenericError(xmlGenericErrorContext, "null ");
- while (cur != NULL) {
- xmlValidPrintNode(cur);
- cur = cur->next;
- }
-}
-
-static void
-xmlValidDebug(xmlNodePtr cur, xmlElementContentPtr cont) {
- char expr[1000];
-
- expr[0] = 0;
- xmlGenericError(xmlGenericErrorContext, "valid: ");
- xmlValidPrintNodeList(cur);
- xmlGenericError(xmlGenericErrorContext, "against ");
- xmlSnprintfElementContent(expr, 5000, cont, 1);
- xmlGenericError(xmlGenericErrorContext, "%s\n", expr);
-}
-
-static void
-xmlValidDebugState(xmlValidStatePtr state) {
- xmlGenericError(xmlGenericErrorContext, "(");
- if (state->cont == NULL)
- xmlGenericError(xmlGenericErrorContext, "null,");
- else
- switch (state->cont->type) {
- case XML_ELEMENT_CONTENT_PCDATA:
- xmlGenericError(xmlGenericErrorContext, "pcdata,");
- break;
- case XML_ELEMENT_CONTENT_ELEMENT:
- xmlGenericError(xmlGenericErrorContext, "%s,",
- state->cont->name);
- break;
- case XML_ELEMENT_CONTENT_SEQ:
- xmlGenericError(xmlGenericErrorContext, "seq,");
- break;
- case XML_ELEMENT_CONTENT_OR:
- xmlGenericError(xmlGenericErrorContext, "or,");
- break;
- }
- xmlValidPrintNode(state->node);
- xmlGenericError(xmlGenericErrorContext, ",%d,%X,%d)",
- state->depth, state->occurs, state->state);
-}
-
-static void
-xmlValidStateDebug(xmlValidCtxtPtr ctxt) {
- int i, j;
-
- xmlGenericError(xmlGenericErrorContext, "state: ");
- xmlValidDebugState(ctxt->vstate);
- xmlGenericError(xmlGenericErrorContext, " stack: %d ",
- ctxt->vstateNr - 1);
- for (i = 0, j = ctxt->vstateNr - 1;(i < 3) && (j > 0);i++,j--)
- xmlValidDebugState(&ctxt->vstateTab[j]);
- xmlGenericError(xmlGenericErrorContext, "\n");
-}
-
-/*****
-#define DEBUG_VALID_STATE(n,c) xmlValidDebug(n,c);
- *****/
-
-#define DEBUG_VALID_STATE(n,c) xmlValidStateDebug(ctxt);
-#define DEBUG_VALID_MSG(m) \
- xmlGenericError(xmlGenericErrorContext, "%s\n", m);
-
-#else
-#define DEBUG_VALID_STATE(n,c)
-#define DEBUG_VALID_MSG(m)
-#endif
-
-/* TODO: use hash table for accesses to elem and attribute definitions */
-
-#define VECTXT(ctxt, node) \
- if ((ctxt != NULL) && (ctxt->error != NULL) && \
- (node != NULL)) { \
- xmlChar *base = xmlNodeGetBase(NULL,node); \
- if (base != NULL) { \
- ctxt->error(ctxt->userData, "%s:%d: ", base, \
- (int) (long) node->content); \
- xmlFree(base); \
- } else \
- ctxt->error(ctxt->userData, ":%d: ", \
- (int) (long) node->content); \
- }
-
-#define VWCTXT(ctxt, node) \
- if ((ctxt != NULL) && (ctxt->warning != NULL) && \
- (node != NULL)) { \
- xmlChar *base = xmlNodeGetBase(NULL,node); \
- if (base != NULL) { \
- ctxt->warning(ctxt->userData, "%s:%d: ", base, \
- (int) (long) node->content); \
- xmlFree(base); \
- } else \
- ctxt->warning(ctxt->userData, ":%d: ", \
- (int) (long) node->content); \
- }
-
-#define VERROR \
- if ((ctxt != NULL) && (ctxt->error != NULL)) ctxt->error
-
-#define VWARNING \
- if ((ctxt != NULL) && (ctxt->warning != NULL)) ctxt->warning
-
-#define CHECK_DTD \
- if (doc == NULL) return(0); \
- else if ((doc->intSubset == NULL) && \
- (doc->extSubset == NULL)) return(0)
-
-static xmlElementPtr xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name,
- int create);
-xmlAttributePtr xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem);
-
-#ifdef LIBXML_REGEXP_ENABLED
-
-/************************************************************************
- * *
- * Content model validation based on the regexps *
- * *
- ************************************************************************/
-
-/**
- * xmlValidBuildAContentModel:
- * @content: the content model
- * @ctxt: the schema parser context
- * @name: the element name whose content is being built
- *
- * Generate the automata sequence needed for that type
- *
- * Returns 1 if successful or 0 in case of error.
- */
-static int
-xmlValidBuildAContentModel(xmlElementContentPtr content,
- xmlValidCtxtPtr ctxt,
- const xmlChar *name) {
- if (content == NULL) {
- VERROR(ctxt->userData,
- "Found unexpected type = NULL in %s content model\n", name);
- return(0);
- }
- switch (content->type) {
- case XML_ELEMENT_CONTENT_PCDATA:
- VERROR(ctxt->userData, "ContentModel found PCDATA for element %s\n",
- name);
- return(0);
- break;
- case XML_ELEMENT_CONTENT_ELEMENT: {
- xmlAutomataStatePtr oldstate = ctxt->state;
- xmlChar *QName = NULL;
- const xmlChar *fname = content->name;
-
- if (content->prefix != NULL) {
- int len;
-
- len = xmlStrlen(content->name) +
- xmlStrlen(content->prefix) + 2;
- QName = xmlMalloc(len);
- if (QName == NULL) {
- VERROR(ctxt->userData,
- "ContentModel %s : alloc failed\n", name);
- return(0);
- }
- snprintf((char *) QName, len, "%s:%s",
- (char *)content->prefix,
- (char *)content->name);
- fname = QName;
- }
-
- switch (content->ocur) {
- case XML_ELEMENT_CONTENT_ONCE:
- ctxt->state = xmlAutomataNewTransition(ctxt->am,
- ctxt->state, NULL, fname, NULL);
- break;
- case XML_ELEMENT_CONTENT_OPT:
- ctxt->state = xmlAutomataNewTransition(ctxt->am,
- ctxt->state, NULL, fname, NULL);
- xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
- break;
- case XML_ELEMENT_CONTENT_PLUS:
- ctxt->state = xmlAutomataNewTransition(ctxt->am,
- ctxt->state, NULL, fname, NULL);
- xmlAutomataNewTransition(ctxt->am, ctxt->state,
- ctxt->state, fname, NULL);
- break;
- case XML_ELEMENT_CONTENT_MULT:
- xmlAutomataNewTransition(ctxt->am, ctxt->state,
- ctxt->state, fname, NULL);
- break;
- }
- if (QName != NULL)
- xmlFree(QName);
- break;
- }
- case XML_ELEMENT_CONTENT_SEQ: {
- xmlAutomataStatePtr oldstate, oldend;
- xmlElementContentOccur ocur;
-
- /*
- * Simply iterate over the content
- */
- oldstate = ctxt->state;
- ocur = content->ocur;
- do {
- xmlValidBuildAContentModel(content->c1, ctxt, name);
- content = content->c2;
- } while ((content->type == XML_ELEMENT_CONTENT_SEQ) &&
- (content->ocur == XML_ELEMENT_CONTENT_ONCE));
- xmlValidBuildAContentModel(content, ctxt, name);
- oldend = ctxt->state;
- ctxt->state = xmlAutomataNewEpsilon(ctxt->am, oldend, NULL);
- switch (ocur) {
- case XML_ELEMENT_CONTENT_ONCE:
- break;
- case XML_ELEMENT_CONTENT_OPT:
- xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
- break;
- case XML_ELEMENT_CONTENT_MULT:
- xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
- xmlAutomataNewEpsilon(ctxt->am, oldend, oldstate);
- break;
- case XML_ELEMENT_CONTENT_PLUS:
- xmlAutomataNewEpsilon(ctxt->am, oldend, oldstate);
- break;
- }
- break;
- }
- case XML_ELEMENT_CONTENT_OR: {
- xmlAutomataStatePtr oldstate, oldend;
- xmlElementContentOccur ocur;
-
- ocur = content->ocur;
- if ((ocur == XML_ELEMENT_CONTENT_PLUS) ||
- (ocur == XML_ELEMENT_CONTENT_MULT)) {
- ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
- ctxt->state, NULL);
- }
- oldstate = ctxt->state;
- oldend = xmlAutomataNewState(ctxt->am);
-
- /*
- * iterate over the subtypes and remerge the end with an
- * epsilon transition
- */
- do {
- ctxt->state = oldstate;
- xmlValidBuildAContentModel(content->c1, ctxt, name);
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldend);
- content = content->c2;
- } while ((content->type == XML_ELEMENT_CONTENT_OR) &&
- (content->ocur == XML_ELEMENT_CONTENT_ONCE));
- ctxt->state = oldstate;
- xmlValidBuildAContentModel(content, ctxt, name);
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldend);
- ctxt->state = xmlAutomataNewEpsilon(ctxt->am, oldend, NULL);
- switch (ocur) {
- case XML_ELEMENT_CONTENT_ONCE:
- break;
- case XML_ELEMENT_CONTENT_OPT:
- xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
- break;
- case XML_ELEMENT_CONTENT_MULT:
- xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
- xmlAutomataNewEpsilon(ctxt->am, oldend, oldstate);
- break;
- case XML_ELEMENT_CONTENT_PLUS:
- xmlAutomataNewEpsilon(ctxt->am, oldend, oldstate);
- break;
- }
- break;
- }
- default:
- VERROR(ctxt->userData, "ContentModel broken for element %s\n",
- name);
- return(0);
- }
- return(1);
-}
-/**
- * xmlValidBuildContentModel:
- * @ctxt: a validation context
- * @elem: an element declaration node
- *
- * (Re)Build the automata associated to the content model of this
- * element
- *
- * Returns 1 in case of success, 0 in case of error
- */
-int
-xmlValidBuildContentModel(xmlValidCtxtPtr ctxt, xmlElementPtr elem) {
- xmlAutomataStatePtr start;
-
- if ((ctxt == NULL) || (elem == NULL))
- return(0);
- if (elem->type != XML_ELEMENT_DECL)
- return(0);
- if (elem->etype != XML_ELEMENT_TYPE_ELEMENT)
- return(1);
- /* TODO: should we rebuild in this case ? */
- if (elem->contModel != NULL)
- return(1);
-
- ctxt->am = xmlNewAutomata();
- if (ctxt->am == NULL) {
- VERROR(ctxt->userData, "Cannot create automata for element %s\n",
- elem->name);
- return(0);
- }
- start = ctxt->state = xmlAutomataGetInitState(ctxt->am);
- xmlValidBuildAContentModel(elem->content, ctxt, elem->name);
- xmlAutomataSetFinalState(ctxt->am, ctxt->state);
- elem->contModel = xmlAutomataCompile(ctxt->am);
- if (!xmlRegexpIsDeterminist(elem->contModel)) {
- char expr[5000];
- expr[0] = 0;
- xmlSnprintfElementContent(expr, 5000, elem->content, 1);
- VERROR(ctxt->userData, "Content model of %s is not determinist: %s\n",
- elem->name, expr);
-#ifdef DEBUG_REGEXP_ALGO
- xmlRegexpPrint(stderr, elem->contModel);
-#endif
- ctxt->valid = 0;
- }
- ctxt->state = NULL;
- xmlFreeAutomata(ctxt->am);
- ctxt->am = NULL;
- return(1);
-}
-
-#endif /* LIBXML_REGEXP_ENABLED */
-
-/************************************************************************
- * *
- * QName handling helper *
- * *
- ************************************************************************/
-
-/**
- * xmlSplitQName2:
- * @name: an XML parser context
- * @prefix: a xmlChar **
- *
- * parse an XML qualified name string
- *
- * [NS 5] QName ::= (Prefix ':')? LocalPart
- *
- * [NS 6] Prefix ::= NCName
- *
- * [NS 7] LocalPart ::= NCName
- *
- * Returns NULL if not a QName, otherwise the local part, and prefix
- * is updated to get the Prefix if any.
- */
-
-xmlChar *
-xmlSplitQName2(const xmlChar *name, xmlChar **prefix) {
- int len = 0;
- xmlChar *ret = NULL;
-
- *prefix = NULL;
-
-#ifndef XML_XML_NAMESPACE
- /* xml: prefix is not really a namespace */
- if ((name[0] == 'x') && (name[1] == 'm') &&
- (name[2] == 'l') && (name[3] == ':'))
- return(NULL);
-#endif
-
- /* nasty but valid */
- if (name[0] == ':')
- return(NULL);
-
- /*
- * we are not trying to validate but just to cut, and yes it will
- * work even if this is as set of UTF-8 encoded chars
- */
- while ((name[len] != 0) && (name[len] != ':'))
- len++;
-
- if (name[len] == 0)
- return(NULL);
-
- *prefix = xmlStrndup(name, len);
- ret = xmlStrdup(&name[len + 1]);
-
- return(ret);
-}
-
-/****************************************************************
- * *
- * Util functions for data allocation/deallocation *
- * *
- ****************************************************************/
-
-/**
- * xmlNewElementContent:
- * @name: the subelement name or NULL
- * @type: the type of element content decl
- *
- * Allocate an element content structure.
- *
- * Returns NULL if not, otherwise the new element content structure
- */
-xmlElementContentPtr
-xmlNewElementContent(xmlChar *name, xmlElementContentType type) {
- xmlElementContentPtr ret;
-
- switch(type) {
- case XML_ELEMENT_CONTENT_ELEMENT:
- if (name == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewElementContent : name == NULL !\n");
- }
- break;
- case XML_ELEMENT_CONTENT_PCDATA:
- case XML_ELEMENT_CONTENT_SEQ:
- case XML_ELEMENT_CONTENT_OR:
- if (name != NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewElementContent : name != NULL !\n");
- }
- break;
- default:
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewElementContent: unknown type %d\n", type);
- return(NULL);
- }
- ret = (xmlElementContentPtr) xmlMalloc(sizeof(xmlElementContent));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewElementContent : out of memory!\n");
- return(NULL);
- }
- memset(ret, 0, sizeof(xmlElementContent));
- ret->type = type;
- ret->ocur = XML_ELEMENT_CONTENT_ONCE;
- if (name != NULL) {
- xmlChar *prefix = NULL;
- ret->name = xmlSplitQName2(name, &prefix);
- if (ret->name == NULL)
- ret->name = xmlStrdup(name);
- ret->prefix = prefix;
- } else {
- ret->name = NULL;
- ret->prefix = NULL;
- }
- ret->c1 = ret->c2 = ret->parent = NULL;
- return(ret);
-}
-
-/**
- * xmlCopyElementContent:
- * @cur: An element content pointer.
- *
- * Build a copy of an element content description.
- *
- * Returns the new xmlElementContentPtr or NULL in case of error.
- */
-xmlElementContentPtr
-xmlCopyElementContent(xmlElementContentPtr cur) {
- xmlElementContentPtr ret;
-
- if (cur == NULL) return(NULL);
- ret = xmlNewElementContent((xmlChar *) cur->name, cur->type);
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlCopyElementContent : out of memory\n");
- return(NULL);
- }
- if (cur->prefix != NULL)
- ret->prefix = xmlStrdup(cur->prefix);
- ret->ocur = cur->ocur;
- if (cur->c1 != NULL) ret->c1 = xmlCopyElementContent(cur->c1);
- if (ret->c1 != NULL)
- ret->c1->parent = ret;
- if (cur->c2 != NULL) ret->c2 = xmlCopyElementContent(cur->c2);
- if (ret->c2 != NULL)
- ret->c2->parent = ret;
- return(ret);
-}
-
-/**
- * xmlFreeElementContent:
- * @cur: the element content tree to free
- *
- * Free an element content structure. This is a recursive call !
- */
-void
-xmlFreeElementContent(xmlElementContentPtr cur) {
- if (cur == NULL) return;
- switch (cur->type) {
- case XML_ELEMENT_CONTENT_PCDATA:
- case XML_ELEMENT_CONTENT_ELEMENT:
- case XML_ELEMENT_CONTENT_SEQ:
- case XML_ELEMENT_CONTENT_OR:
- break;
- default:
- xmlGenericError(xmlGenericErrorContext,
- "xmlFreeElementContent : type %d\n", cur->type);
- return;
- }
- if (cur->c1 != NULL) xmlFreeElementContent(cur->c1);
- if (cur->c2 != NULL) xmlFreeElementContent(cur->c2);
- if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
- if (cur->prefix != NULL) xmlFree((xmlChar *) cur->prefix);
- xmlFree(cur);
-}
-
-/**
- * xmlDumpElementContent:
- * @buf: An XML buffer
- * @content: An element table
- * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
- *
- * This will dump the content of the element table as an XML DTD definition
- */
-static void
-xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content, int glob) {
- if (content == NULL) return;
-
- if (glob) xmlBufferWriteChar(buf, "(");
- switch (content->type) {
- case XML_ELEMENT_CONTENT_PCDATA:
- xmlBufferWriteChar(buf, "#PCDATA");
- break;
- case XML_ELEMENT_CONTENT_ELEMENT:
- if (content->prefix != NULL) {
- xmlBufferWriteCHAR(buf, content->prefix);
- xmlBufferWriteChar(buf, ":");
- }
- xmlBufferWriteCHAR(buf, content->name);
- break;
- case XML_ELEMENT_CONTENT_SEQ:
- if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
- (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
- xmlDumpElementContent(buf, content->c1, 1);
- else
- xmlDumpElementContent(buf, content->c1, 0);
- xmlBufferWriteChar(buf, " , ");
- if (content->c2->type == XML_ELEMENT_CONTENT_OR)
- xmlDumpElementContent(buf, content->c2, 1);
- else
- xmlDumpElementContent(buf, content->c2, 0);
- break;
- case XML_ELEMENT_CONTENT_OR:
- if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
- (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
- xmlDumpElementContent(buf, content->c1, 1);
- else
- xmlDumpElementContent(buf, content->c1, 0);
- xmlBufferWriteChar(buf, " | ");
- if (content->c2->type == XML_ELEMENT_CONTENT_SEQ)
- xmlDumpElementContent(buf, content->c2, 1);
- else
- xmlDumpElementContent(buf, content->c2, 0);
- break;
- default:
- xmlGenericError(xmlGenericErrorContext,
- "xmlDumpElementContent: unknown type %d\n",
- content->type);
- }
- if (glob)
- xmlBufferWriteChar(buf, ")");
- switch (content->ocur) {
- case XML_ELEMENT_CONTENT_ONCE:
- break;
- case XML_ELEMENT_CONTENT_OPT:
- xmlBufferWriteChar(buf, "?");
- break;
- case XML_ELEMENT_CONTENT_MULT:
- xmlBufferWriteChar(buf, "*");
- break;
- case XML_ELEMENT_CONTENT_PLUS:
- xmlBufferWriteChar(buf, "+");
- break;
- }
-}
-
-/**
- * xmlSprintfElementContent:
- * @buf: an output buffer
- * @content: An element table
- * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
- *
- * Deprecated, unsafe, use xmlSnprintfElementContent
- */
-void
-xmlSprintfElementContent(char *buf ATTRIBUTE_UNUSED,
- xmlElementContentPtr content ATTRIBUTE_UNUSED,
- int glob ATTRIBUTE_UNUSED) {
-}
-
-/**
- * xmlSnprintfElementContent:
- * @buf: an output buffer
- * @size: the buffer size
- * @content: An element table
- * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
- *
- * This will dump the content of the element content definition
- * Intended just for the debug routine
- */
-void
-xmlSnprintfElementContent(char *buf, int size, xmlElementContentPtr content, int glob) {
- int len;
-
- if (content == NULL) return;
- len = strlen(buf);
- if (size - len < 50) {
- if ((size - len > 4) && (buf[len - 1] != '.'))
- strcat(buf, " ...");
- return;
- }
- if (glob) strcat(buf, "(");
- switch (content->type) {
- case XML_ELEMENT_CONTENT_PCDATA:
- strcat(buf, "#PCDATA");
- break;
- case XML_ELEMENT_CONTENT_ELEMENT:
- if (content->prefix != NULL) {
- if (size - len < xmlStrlen(content->prefix) + 10) {
- strcat(buf, " ...");
- return;
- }
- strcat(buf, (char *) content->prefix);
- strcat(buf, ":");
- }
- if (size - len < xmlStrlen(content->name) + 10) {
- strcat(buf, " ...");
- return;
- }
- strcat(buf, (char *) content->name);
- break;
- case XML_ELEMENT_CONTENT_SEQ:
- if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
- (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
- xmlSnprintfElementContent(buf, size, content->c1, 1);
- else
- xmlSnprintfElementContent(buf, size, content->c1, 0);
- len = strlen(buf);
- if (size - len < 50) {
- if ((size - len > 4) && (buf[len - 1] != '.'))
- strcat(buf, " ...");
- return;
- }
- strcat(buf, " , ");
- if (((content->c2->type == XML_ELEMENT_CONTENT_OR) ||
- (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)) &&
- (content->c2->type != XML_ELEMENT_CONTENT_ELEMENT))
- xmlSnprintfElementContent(buf, size, content->c2, 1);
- else
- xmlSnprintfElementContent(buf, size, content->c2, 0);
- break;
- case XML_ELEMENT_CONTENT_OR:
- if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
- (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
- xmlSnprintfElementContent(buf, size, content->c1, 1);
- else
- xmlSnprintfElementContent(buf, size, content->c1, 0);
- len = strlen(buf);
- if (size - len < 50) {
- if ((size - len > 4) && (buf[len - 1] != '.'))
- strcat(buf, " ...");
- return;
- }
- strcat(buf, " | ");
- if (((content->c2->type == XML_ELEMENT_CONTENT_SEQ) ||
- (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)) &&
- (content->c2->type != XML_ELEMENT_CONTENT_ELEMENT))
- xmlSnprintfElementContent(buf, size, content->c2, 1);
- else
- xmlSnprintfElementContent(buf, size, content->c2, 0);
- break;
- }
- if (glob)
- strcat(buf, ")");
- switch (content->ocur) {
- case XML_ELEMENT_CONTENT_ONCE:
- break;
- case XML_ELEMENT_CONTENT_OPT:
- strcat(buf, "?");
- break;
- case XML_ELEMENT_CONTENT_MULT:
- strcat(buf, "*");
- break;
- case XML_ELEMENT_CONTENT_PLUS:
- strcat(buf, "+");
- break;
- }
-}
-
-/****************************************************************
- * *
- * Registration of DTD declarations *
- * *
- ****************************************************************/
-
-/**
- * xmlCreateElementTable:
- *
- * create and initialize an empty element hash table.
- *
- * Returns the xmlElementTablePtr just created or NULL in case of error.
- */
-static xmlElementTablePtr
-xmlCreateElementTable(void) {
- return(xmlHashCreate(0));
-}
-
-/**
- * xmlFreeElement:
- * @elem: An element
- *
- * Deallocate the memory used by an element definition
- */
-static void
-xmlFreeElement(xmlElementPtr elem) {
- if (elem == NULL) return;
- xmlUnlinkNode((xmlNodePtr) elem);
- xmlFreeElementContent(elem->content);
- if (elem->name != NULL)
- xmlFree((xmlChar *) elem->name);
- if (elem->prefix != NULL)
- xmlFree((xmlChar *) elem->prefix);
-#ifdef LIBXML_REGEXP_ENABLED
- if (elem->contModel != NULL)
- xmlRegFreeRegexp(elem->contModel);
-#endif
- xmlFree(elem);
-}
-
-
-/**
- * xmlAddElementDecl:
- * @ctxt: the validation context
- * @dtd: pointer to the DTD
- * @name: the entity name
- * @type: the element type
- * @content: the element content tree or NULL
- *
- * Register a new element declaration
- *
- * Returns NULL if not, otherwise the entity
- */
-xmlElementPtr
-xmlAddElementDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
- xmlElementTypeVal type,
- xmlElementContentPtr content) {
- xmlElementPtr ret;
- xmlElementTablePtr table;
- xmlAttributePtr oldAttributes = NULL;
- xmlChar *ns, *uqname;
-
- if (dtd == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddElementDecl: dtd == NULL\n");
- return(NULL);
- }
- if (name == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddElementDecl: name == NULL\n");
- return(NULL);
- }
- switch (type) {
- case XML_ELEMENT_TYPE_EMPTY:
- if (content != NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddElementDecl: content != NULL for EMPTY\n");
- return(NULL);
- }
- break;
- case XML_ELEMENT_TYPE_ANY:
- if (content != NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddElementDecl: content != NULL for ANY\n");
- return(NULL);
- }
- break;
- case XML_ELEMENT_TYPE_MIXED:
- if (content == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddElementDecl: content == NULL for MIXED\n");
- return(NULL);
- }
- break;
- case XML_ELEMENT_TYPE_ELEMENT:
- if (content == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddElementDecl: content == NULL for ELEMENT\n");
- return(NULL);
- }
- break;
- default:
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddElementDecl: unknown type %d\n", type);
- return(NULL);
- }
-
- /*
- * check if name is a QName
- */
- uqname = xmlSplitQName2(name, &ns);
- if (uqname != NULL)
- name = uqname;
-
- /*
- * Create the Element table if needed.
- */
- table = (xmlElementTablePtr) dtd->elements;
- if (table == NULL) {
- table = xmlCreateElementTable();
- dtd->elements = (void *) table;
- }
- if (table == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddElementDecl: Table creation failed!\n");
- return(NULL);
- }
-
- /*
- * lookup old attributes inserted on an undefined element in the
- * internal subset.
- */
- if ((dtd->doc != NULL) && (dtd->doc->intSubset != NULL)) {
- ret = xmlHashLookup2(dtd->doc->intSubset->elements, name, ns);
- if ((ret != NULL) && (ret->etype == XML_ELEMENT_TYPE_UNDEFINED)) {
- oldAttributes = ret->attributes;
- ret->attributes = NULL;
- xmlHashRemoveEntry2(dtd->doc->intSubset->elements, name, ns, NULL);
- xmlFreeElement(ret);
- }
- }
-
- /*
- * The element may already be present if one of its attribute
- * was registered first
- */
- ret = xmlHashLookup2(table, name, ns);
- if (ret != NULL) {
- if (ret->etype != XML_ELEMENT_TYPE_UNDEFINED) {
- /*
- * The element is already defined in this DTD.
- */
- VERROR(ctxt->userData, "Redefinition of element %s\n", name);
- if (uqname != NULL)
- xmlFree(uqname);
- return(NULL);
- }
- } else {
- ret = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddElementDecl: out of memory\n");
- return(NULL);
- }
- memset(ret, 0, sizeof(xmlElement));
- ret->type = XML_ELEMENT_DECL;
-
- /*
- * fill the structure.
- */
- ret->name = xmlStrdup(name);
- ret->prefix = ns;
-
- /*
- * Validity Check:
- * Insertion must not fail
- */
- if (xmlHashAddEntry2(table, name, ns, ret)) {
- /*
- * The element is already defined in this DTD.
- */
- VERROR(ctxt->userData, "Redefinition of element %s\n", name);
- xmlFreeElement(ret);
- if (uqname != NULL)
- xmlFree(uqname);
- return(NULL);
- }
- }
-
- /*
- * Finish to fill the structure.
- */
- ret->etype = type;
- ret->content = xmlCopyElementContent(content);
- ret->attributes = oldAttributes;
-
- /*
- * Link it to the DTD
- */
- ret->parent = dtd;
- ret->doc = dtd->doc;
- if (dtd->last == NULL) {
- dtd->children = dtd->last = (xmlNodePtr) ret;
- } else {
- dtd->last->next = (xmlNodePtr) ret;
- ret->prev = dtd->last;
- dtd->last = (xmlNodePtr) ret;
- }
- if (uqname != NULL)
- xmlFree(uqname);
- return(ret);
-}
-
-/**
- * xmlFreeElementTable:
- * @table: An element table
- *
- * Deallocate the memory used by an element hash table.
- */
-void
-xmlFreeElementTable(xmlElementTablePtr table) {
- xmlHashFree(table, (xmlHashDeallocator) xmlFreeElement);
-}
-
-/**
- * xmlCopyElement:
- * @elem: An element
- *
- * Build a copy of an element.
- *
- * Returns the new xmlElementPtr or NULL in case of error.
- */
-static xmlElementPtr
-xmlCopyElement(xmlElementPtr elem) {
- xmlElementPtr cur;
-
- cur = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlCopyElement: out of memory !\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlElement));
- cur->type = XML_ELEMENT_DECL;
- cur->etype = elem->etype;
- if (elem->name != NULL)
- cur->name = xmlStrdup(elem->name);
- else
- cur->name = NULL;
- if (elem->prefix != NULL)
- cur->prefix = xmlStrdup(elem->prefix);
- else
- cur->prefix = NULL;
- cur->content = xmlCopyElementContent(elem->content);
- /* TODO : rebuild the attribute list on the copy */
- cur->attributes = NULL;
- return(cur);
-}
-
-/**
- * xmlCopyElementTable:
- * @table: An element table
- *
- * Build a copy of an element table.
- *
- * Returns the new xmlElementTablePtr or NULL in case of error.
- */
-xmlElementTablePtr
-xmlCopyElementTable(xmlElementTablePtr table) {
- return((xmlElementTablePtr) xmlHashCopy(table,
- (xmlHashCopier) xmlCopyElement));
-}
-
-/**
- * xmlDumpElementDecl:
- * @buf: the XML buffer output
- * @elem: An element table
- *
- * This will dump the content of the element declaration as an XML
- * DTD definition
- */
-void
-xmlDumpElementDecl(xmlBufferPtr buf, xmlElementPtr elem) {
- switch (elem->etype) {
- case XML_ELEMENT_TYPE_EMPTY:
- xmlBufferWriteChar(buf, "<!ELEMENT ");
- if (elem->prefix != NULL) {
- xmlBufferWriteCHAR(buf, elem->prefix);
- xmlBufferWriteChar(buf, ":");
- }
- xmlBufferWriteCHAR(buf, elem->name);
- xmlBufferWriteChar(buf, " EMPTY>\n");
- break;
- case XML_ELEMENT_TYPE_ANY:
- xmlBufferWriteChar(buf, "<!ELEMENT ");
- if (elem->prefix != NULL) {
- xmlBufferWriteCHAR(buf, elem->prefix);
- xmlBufferWriteChar(buf, ":");
- }
- xmlBufferWriteCHAR(buf, elem->name);
- xmlBufferWriteChar(buf, " ANY>\n");
- break;
- case XML_ELEMENT_TYPE_MIXED:
- xmlBufferWriteChar(buf, "<!ELEMENT ");
- if (elem->prefix != NULL) {
- xmlBufferWriteCHAR(buf, elem->prefix);
- xmlBufferWriteChar(buf, ":");
- }
- xmlBufferWriteCHAR(buf, elem->name);
- xmlBufferWriteChar(buf, " ");
- xmlDumpElementContent(buf, elem->content, 1);
- xmlBufferWriteChar(buf, ">\n");
- break;
- case XML_ELEMENT_TYPE_ELEMENT:
- xmlBufferWriteChar(buf, "<!ELEMENT ");
- if (elem->prefix != NULL) {
- xmlBufferWriteCHAR(buf, elem->prefix);
- xmlBufferWriteChar(buf, ":");
- }
- xmlBufferWriteCHAR(buf, elem->name);
- xmlBufferWriteChar(buf, " ");
- xmlDumpElementContent(buf, elem->content, 1);
- xmlBufferWriteChar(buf, ">\n");
- break;
- default:
- xmlGenericError(xmlGenericErrorContext,
- "xmlDumpElementDecl: internal: unknown type %d\n",
- elem->etype);
- }
-}
-
-/**
- * xmlDumpElementTable:
- * @buf: the XML buffer output
- * @table: An element table
- *
- * This will dump the content of the element table as an XML DTD definition
- */
-void
-xmlDumpElementTable(xmlBufferPtr buf, xmlElementTablePtr table) {
- xmlHashScan(table, (xmlHashScanner) xmlDumpElementDecl, buf);
-}
-
-/**
- * xmlCreateEnumeration:
- * @name: the enumeration name or NULL
- *
- * create and initialize an enumeration attribute node.
- *
- * Returns the xmlEnumerationPtr just created or NULL in case
- * of error.
- */
-xmlEnumerationPtr
-xmlCreateEnumeration(xmlChar *name) {
- xmlEnumerationPtr ret;
-
- ret = (xmlEnumerationPtr) xmlMalloc(sizeof(xmlEnumeration));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlCreateEnumeration : xmlMalloc(%ld) failed\n",
- (long)sizeof(xmlEnumeration));
- return(NULL);
- }
- memset(ret, 0, sizeof(xmlEnumeration));
-
- if (name != NULL)
- ret->name = xmlStrdup(name);
- return(ret);
-}
-
-/**
- * xmlFreeEnumeration:
- * @cur: the tree to free.
- *
- * free an enumeration attribute node (recursive).
- */
-void
-xmlFreeEnumeration(xmlEnumerationPtr cur) {
- if (cur == NULL) return;
-
- if (cur->next != NULL) xmlFreeEnumeration(cur->next);
-
- if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
- xmlFree(cur);
-}
-
-/**
- * xmlCopyEnumeration:
- * @cur: the tree to copy.
- *
- * Copy an enumeration attribute node (recursive).
- *
- * Returns the xmlEnumerationPtr just created or NULL in case
- * of error.
- */
-xmlEnumerationPtr
-xmlCopyEnumeration(xmlEnumerationPtr cur) {
- xmlEnumerationPtr ret;
-
- if (cur == NULL) return(NULL);
- ret = xmlCreateEnumeration((xmlChar *) cur->name);
-
- if (cur->next != NULL) ret->next = xmlCopyEnumeration(cur->next);
- else ret->next = NULL;
-
- return(ret);
-}
-
-/**
- * xmlDumpEnumeration:
- * @buf: the XML buffer output
- * @enum: An enumeration
- *
- * This will dump the content of the enumeration
- */
-static void
-xmlDumpEnumeration(xmlBufferPtr buf, xmlEnumerationPtr cur) {
- if (cur == NULL) return;
-
- xmlBufferWriteCHAR(buf, cur->name);
- if (cur->next == NULL)
- xmlBufferWriteChar(buf, ")");
- else {
- xmlBufferWriteChar(buf, " | ");
- xmlDumpEnumeration(buf, cur->next);
- }
-}
-
-/**
- * xmlCreateAttributeTable:
- *
- * create and initialize an empty attribute hash table.
- *
- * Returns the xmlAttributeTablePtr just created or NULL in case
- * of error.
- */
-static xmlAttributeTablePtr
-xmlCreateAttributeTable(void) {
- return(xmlHashCreate(0));
-}
-
-/**
- * xmlScanAttributeDeclCallback:
- * @attr: the attribute decl
- * @list: the list to update
- *
- * Callback called by xmlScanAttributeDecl when a new attribute
- * has to be entered in the list.
- */
-static void
-xmlScanAttributeDeclCallback(xmlAttributePtr attr, xmlAttributePtr *list,
- const xmlChar* name ATTRIBUTE_UNUSED) {
- attr->nexth = *list;
- *list = attr;
-}
-
-/**
- * xmlScanAttributeDecl:
- * @dtd: pointer to the DTD
- * @elem: the element name
- *
- * When inserting a new element scan the DtD for existing attributes
- * for that element and initialize the Attribute chain
- *
- * Returns the pointer to the first attribute decl in the chain,
- * possibly NULL.
- */
-xmlAttributePtr
-xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem) {
- xmlAttributePtr ret = NULL;
- xmlAttributeTablePtr table;
-
- if (dtd == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlScanAttributeDecl: dtd == NULL\n");
- return(NULL);
- }
- if (elem == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlScanAttributeDecl: elem == NULL\n");
- return(NULL);
- }
- table = (xmlAttributeTablePtr) dtd->attributes;
- if (table == NULL)
- return(NULL);
-
- /* WRONG !!! */
- xmlHashScan3(table, NULL, NULL, elem,
- (xmlHashScanner) xmlScanAttributeDeclCallback, &ret);
- return(ret);
-}
-
-/**
- * xmlScanIDAttributeDecl:
- * @ctxt: the validation context
- * @elem: the element name
- *
- * Verify that the element don't have too many ID attributes
- * declared.
- *
- * Returns the number of ID attributes found.
- */
-static int
-xmlScanIDAttributeDecl(xmlValidCtxtPtr ctxt, xmlElementPtr elem) {
- xmlAttributePtr cur;
- int ret = 0;
-
- if (elem == NULL) return(0);
- cur = elem->attributes;
- while (cur != NULL) {
- if (cur->atype == XML_ATTRIBUTE_ID) {
- ret ++;
- if (ret > 1)
- VERROR(ctxt->userData,
- "Element %s has too many ID attributes defined : %s\n",
- elem->name, cur->name);
- }
- cur = cur->nexth;
- }
- return(ret);
-}
-
-/**
- * xmlFreeAttribute:
- * @elem: An attribute
- *
- * Deallocate the memory used by an attribute definition
- */
-static void
-xmlFreeAttribute(xmlAttributePtr attr) {
- if (attr == NULL) return;
- xmlUnlinkNode((xmlNodePtr) attr);
- if (attr->tree != NULL)
- xmlFreeEnumeration(attr->tree);
- if (attr->elem != NULL)
- xmlFree((xmlChar *) attr->elem);
- if (attr->name != NULL)
- xmlFree((xmlChar *) attr->name);
- if (attr->defaultValue != NULL)
- xmlFree((xmlChar *) attr->defaultValue);
- if (attr->prefix != NULL)
- xmlFree((xmlChar *) attr->prefix);
- xmlFree(attr);
-}
-
-
-/**
- * xmlAddAttributeDecl:
- * @ctxt: the validation context
- * @dtd: pointer to the DTD
- * @elem: the element name
- * @name: the attribute name
- * @ns: the attribute namespace prefix
- * @type: the attribute type
- * @def: the attribute default type
- * @defaultValue: the attribute default value
- * @tree: if it's an enumeration, the associated list
- *
- * Register a new attribute declaration
- * Note that @tree becomes the ownership of the DTD
- *
- * Returns NULL if not new, otherwise the attribute decl
- */
-xmlAttributePtr
-xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *elem,
- const xmlChar *name, const xmlChar *ns,
- xmlAttributeType type, xmlAttributeDefault def,
- const xmlChar *defaultValue, xmlEnumerationPtr tree) {
- xmlAttributePtr ret;
- xmlAttributeTablePtr table;
- xmlElementPtr elemDef;
-
- if (dtd == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddAttributeDecl: dtd == NULL\n");
- xmlFreeEnumeration(tree);
- return(NULL);
- }
- if (name == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddAttributeDecl: name == NULL\n");
- xmlFreeEnumeration(tree);
- return(NULL);
- }
- if (elem == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddAttributeDecl: elem == NULL\n");
- xmlFreeEnumeration(tree);
- return(NULL);
- }
-
- /*
- * Check the type and possibly the default value.
- */
- switch (type) {
- case XML_ATTRIBUTE_CDATA:
- break;
- case XML_ATTRIBUTE_ID:
- break;
- case XML_ATTRIBUTE_IDREF:
- break;
- case XML_ATTRIBUTE_IDREFS:
- break;
- case XML_ATTRIBUTE_ENTITY:
- break;
- case XML_ATTRIBUTE_ENTITIES:
- break;
- case XML_ATTRIBUTE_NMTOKEN:
- break;
- case XML_ATTRIBUTE_NMTOKENS:
- break;
- case XML_ATTRIBUTE_ENUMERATION:
- break;
- case XML_ATTRIBUTE_NOTATION:
- break;
- default:
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddAttributeDecl: unknown type %d\n", type);
- xmlFreeEnumeration(tree);
- return(NULL);
- }
- if ((defaultValue != NULL) &&
- (!xmlValidateAttributeValue(type, defaultValue))) {
- VERROR(ctxt->userData, "Attribute %s of %s: invalid default value\n",
- elem, name, defaultValue);
- defaultValue = NULL;
- ctxt->valid = 0;
- }
-
- /*
- * Check first that an attribute defined in the external subset wasn't
- * already defined in the internal subset
- */
- if ((dtd->doc != NULL) && (dtd->doc->extSubset == dtd) &&
- (dtd->doc->intSubset != NULL) &&
- (dtd->doc->intSubset->attributes != NULL)) {
- ret = xmlHashLookup3(dtd->doc->intSubset->attributes, name, ns, elem);
- if (ret != NULL)
- return(NULL);
- }
-
- /*
- * Create the Attribute table if needed.
- */
- table = (xmlAttributeTablePtr) dtd->attributes;
- if (table == NULL) {
- table = xmlCreateAttributeTable();
- dtd->attributes = (void *) table;
- }
- if (table == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddAttributeDecl: Table creation failed!\n");
- return(NULL);
- }
-
-
- ret = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddAttributeDecl: out of memory\n");
- return(NULL);
- }
- memset(ret, 0, sizeof(xmlAttribute));
- ret->type = XML_ATTRIBUTE_DECL;
-
- /*
- * fill the structure.
- */
- ret->atype = type;
- ret->name = xmlStrdup(name);
- ret->prefix = xmlStrdup(ns);
- ret->elem = xmlStrdup(elem);
- ret->def = def;
- ret->tree = tree;
- if (defaultValue != NULL)
- ret->defaultValue = xmlStrdup(defaultValue);
-
- /*
- * Validity Check:
- * Search the DTD for previous declarations of the ATTLIST
- */
- if (xmlHashAddEntry3(table, name, ns, elem, ret) < 0) {
- /*
- * The attribute is already defined in this DTD.
- */
- VWARNING(ctxt->userData,
- "Attribute %s of element %s: already defined\n",
- name, elem);
- xmlFreeAttribute(ret);
- return(NULL);
- }
-
- /*
- * Validity Check:
- * Multiple ID per element
- */
- elemDef = xmlGetDtdElementDesc2(dtd, elem, 1);
- if (elemDef != NULL) {
-
- if ((type == XML_ATTRIBUTE_ID) &&
- (xmlScanIDAttributeDecl(NULL, elemDef) != 0)) {
- VERROR(ctxt->userData,
- "Element %s has too may ID attributes defined : %s\n",
- elem, name);
- ctxt->valid = 0;
- }
-
- /*
- * Insert namespace default def first they need to be
- * processed first.
- */
- if ((xmlStrEqual(ret->name, BAD_CAST "xmlns")) ||
- ((ret->prefix != NULL &&
- (xmlStrEqual(ret->prefix, BAD_CAST "xmlns"))))) {
- ret->nexth = elemDef->attributes;
- elemDef->attributes = ret;
- } else {
- xmlAttributePtr tmp = elemDef->attributes;
-
- while ((tmp != NULL) &&
- ((xmlStrEqual(tmp->name, BAD_CAST "xmlns")) ||
- ((ret->prefix != NULL &&
- (xmlStrEqual(ret->prefix, BAD_CAST "xmlns")))))) {
- if (tmp->nexth == NULL)
- break;
- tmp = tmp->nexth;
- }
- if (tmp != NULL) {
- ret->nexth = tmp->nexth;
- tmp->nexth = ret;
- } else {
- ret->nexth = elemDef->attributes;
- elemDef->attributes = ret;
- }
- }
- }
-
- /*
- * Link it to the DTD
- */
- ret->parent = dtd;
- ret->doc = dtd->doc;
- if (dtd->last == NULL) {
- dtd->children = dtd->last = (xmlNodePtr) ret;
- } else {
- dtd->last->next = (xmlNodePtr) ret;
- ret->prev = dtd->last;
- dtd->last = (xmlNodePtr) ret;
- }
- return(ret);
-}
-
-/**
- * xmlFreeAttributeTable:
- * @table: An attribute table
- *
- * Deallocate the memory used by an entities hash table.
- */
-void
-xmlFreeAttributeTable(xmlAttributeTablePtr table) {
- xmlHashFree(table, (xmlHashDeallocator) xmlFreeAttribute);
-}
-
-/**
- * xmlCopyAttribute:
- * @attr: An attribute
- *
- * Build a copy of an attribute.
- *
- * Returns the new xmlAttributePtr or NULL in case of error.
- */
-static xmlAttributePtr
-xmlCopyAttribute(xmlAttributePtr attr) {
- xmlAttributePtr cur;
-
- cur = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlCopyAttribute: out of memory !\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlAttribute));
- cur->type = XML_ATTRIBUTE_DECL;
- cur->atype = attr->atype;
- cur->def = attr->def;
- cur->tree = xmlCopyEnumeration(attr->tree);
- if (attr->elem != NULL)
- cur->elem = xmlStrdup(attr->elem);
- if (attr->name != NULL)
- cur->name = xmlStrdup(attr->name);
- if (attr->prefix != NULL)
- cur->prefix = xmlStrdup(attr->prefix);
- if (attr->defaultValue != NULL)
- cur->defaultValue = xmlStrdup(attr->defaultValue);
- return(cur);
-}
-
-/**
- * xmlCopyAttributeTable:
- * @table: An attribute table
- *
- * Build a copy of an attribute table.
- *
- * Returns the new xmlAttributeTablePtr or NULL in case of error.
- */
-xmlAttributeTablePtr
-xmlCopyAttributeTable(xmlAttributeTablePtr table) {
- return((xmlAttributeTablePtr) xmlHashCopy(table,
- (xmlHashCopier) xmlCopyAttribute));
-}
-
-/**
- * xmlDumpAttributeDecl:
- * @buf: the XML buffer output
- * @attr: An attribute declaration
- *
- * This will dump the content of the attribute declaration as an XML
- * DTD definition
- */
-void
-xmlDumpAttributeDecl(xmlBufferPtr buf, xmlAttributePtr attr) {
- xmlBufferWriteChar(buf, "<!ATTLIST ");
- xmlBufferWriteCHAR(buf, attr->elem);
- xmlBufferWriteChar(buf, " ");
- if (attr->prefix != NULL) {
- xmlBufferWriteCHAR(buf, attr->prefix);
- xmlBufferWriteChar(buf, ":");
- }
- xmlBufferWriteCHAR(buf, attr->name);
- switch (attr->atype) {
- case XML_ATTRIBUTE_CDATA:
- xmlBufferWriteChar(buf, " CDATA");
- break;
- case XML_ATTRIBUTE_ID:
- xmlBufferWriteChar(buf, " ID");
- break;
- case XML_ATTRIBUTE_IDREF:
- xmlBufferWriteChar(buf, " IDREF");
- break;
- case XML_ATTRIBUTE_IDREFS:
- xmlBufferWriteChar(buf, " IDREFS");
- break;
- case XML_ATTRIBUTE_ENTITY:
- xmlBufferWriteChar(buf, " ENTITY");
- break;
- case XML_ATTRIBUTE_ENTITIES:
- xmlBufferWriteChar(buf, " ENTITIES");
- break;
- case XML_ATTRIBUTE_NMTOKEN:
- xmlBufferWriteChar(buf, " NMTOKEN");
- break;
- case XML_ATTRIBUTE_NMTOKENS:
- xmlBufferWriteChar(buf, " NMTOKENS");
- break;
- case XML_ATTRIBUTE_ENUMERATION:
- xmlBufferWriteChar(buf, " (");
- xmlDumpEnumeration(buf, attr->tree);
- break;
- case XML_ATTRIBUTE_NOTATION:
- xmlBufferWriteChar(buf, " NOTATION (");
- xmlDumpEnumeration(buf, attr->tree);
- break;
- default:
- xmlGenericError(xmlGenericErrorContext,
- "xmlDumpAttributeDecl: internal: unknown type %d\n",
- attr->atype);
- }
- switch (attr->def) {
- case XML_ATTRIBUTE_NONE:
- break;
- case XML_ATTRIBUTE_REQUIRED:
- xmlBufferWriteChar(buf, " #REQUIRED");
- break;
- case XML_ATTRIBUTE_IMPLIED:
- xmlBufferWriteChar(buf, " #IMPLIED");
- break;
- case XML_ATTRIBUTE_FIXED:
- xmlBufferWriteChar(buf, " #FIXED");
- break;
- default:
- xmlGenericError(xmlGenericErrorContext,
- "xmlDumpAttributeDecl: internal: unknown default %d\n",
- attr->def);
- }
- if (attr->defaultValue != NULL) {
- xmlBufferWriteChar(buf, " ");
- xmlBufferWriteQuotedString(buf, attr->defaultValue);
- }
- xmlBufferWriteChar(buf, ">\n");
-}
-
-/**
- * xmlDumpAttributeTable:
- * @buf: the XML buffer output
- * @table: An attribute table
- *
- * This will dump the content of the attribute table as an XML DTD definition
- */
-void
-xmlDumpAttributeTable(xmlBufferPtr buf, xmlAttributeTablePtr table) {
- xmlHashScan(table, (xmlHashScanner) xmlDumpAttributeDecl, buf);
-}
-
-/************************************************************************
- * *
- * NOTATIONs *
- * *
- ************************************************************************/
-/**
- * xmlCreateNotationTable:
- *
- * create and initialize an empty notation hash table.
- *
- * Returns the xmlNotationTablePtr just created or NULL in case
- * of error.
- */
-static xmlNotationTablePtr
-xmlCreateNotationTable(void) {
- return(xmlHashCreate(0));
-}
-
-/**
- * xmlFreeNotation:
- * @not: A notation
- *
- * Deallocate the memory used by an notation definition
- */
-static void
-xmlFreeNotation(xmlNotationPtr nota) {
- if (nota == NULL) return;
- if (nota->name != NULL)
- xmlFree((xmlChar *) nota->name);
- if (nota->PublicID != NULL)
- xmlFree((xmlChar *) nota->PublicID);
- if (nota->SystemID != NULL)
- xmlFree((xmlChar *) nota->SystemID);
- xmlFree(nota);
-}
-
-
-/**
- * xmlAddNotationDecl:
- * @dtd: pointer to the DTD
- * @ctxt: the validation context
- * @name: the entity name
- * @PublicID: the public identifier or NULL
- * @SystemID: the system identifier or NULL
- *
- * Register a new notation declaration
- *
- * Returns NULL if not, otherwise the entity
- */
-xmlNotationPtr
-xmlAddNotationDecl(xmlValidCtxtPtr ctxt ATTRIBUTE_UNUSED, xmlDtdPtr dtd,
- const xmlChar *name,
- const xmlChar *PublicID, const xmlChar *SystemID) {
- xmlNotationPtr ret;
- xmlNotationTablePtr table;
-
- if (dtd == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddNotationDecl: dtd == NULL\n");
- return(NULL);
- }
- if (name == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddNotationDecl: name == NULL\n");
- return(NULL);
- }
- if ((PublicID == NULL) && (SystemID == NULL)) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddNotationDecl: no PUBLIC ID nor SYSTEM ID\n");
- return(NULL);
- }
-
- /*
- * Create the Notation table if needed.
- */
- table = (xmlNotationTablePtr) dtd->notations;
- if (table == NULL)
- dtd->notations = table = xmlCreateNotationTable();
- if (table == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddNotationDecl: Table creation failed!\n");
- return(NULL);
- }
-
- ret = (xmlNotationPtr) xmlMalloc(sizeof(xmlNotation));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddNotationDecl: out of memory\n");
- return(NULL);
- }
- memset(ret, 0, sizeof(xmlNotation));
-
- /*
- * fill the structure.
- */
- ret->name = xmlStrdup(name);
- if (SystemID != NULL)
- ret->SystemID = xmlStrdup(SystemID);
- if (PublicID != NULL)
- ret->PublicID = xmlStrdup(PublicID);
-
- /*
- * Validity Check:
- * Check the DTD for previous declarations of the ATTLIST
- */
- if (xmlHashAddEntry(table, name, ret)) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddNotationDecl: %s already defined\n", name);
- xmlFreeNotation(ret);
- return(NULL);
- }
- return(ret);
-}
-
-/**
- * xmlFreeNotationTable:
- * @table: An notation table
- *
- * Deallocate the memory used by an entities hash table.
- */
-void
-xmlFreeNotationTable(xmlNotationTablePtr table) {
- xmlHashFree(table, (xmlHashDeallocator) xmlFreeNotation);
-}
-
-/**
- * xmlCopyNotation:
- * @nota: A notation
- *
- * Build a copy of a notation.
- *
- * Returns the new xmlNotationPtr or NULL in case of error.
- */
-static xmlNotationPtr
-xmlCopyNotation(xmlNotationPtr nota) {
- xmlNotationPtr cur;
-
- cur = (xmlNotationPtr) xmlMalloc(sizeof(xmlNotation));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlCopyNotation: out of memory !\n");
- return(NULL);
- }
- if (nota->name != NULL)
- cur->name = xmlStrdup(nota->name);
- else
- cur->name = NULL;
- if (nota->PublicID != NULL)
- cur->PublicID = xmlStrdup(nota->PublicID);
- else
- cur->PublicID = NULL;
- if (nota->SystemID != NULL)
- cur->SystemID = xmlStrdup(nota->SystemID);
- else
- cur->SystemID = NULL;
- return(cur);
-}
-
-/**
- * xmlCopyNotationTable:
- * @table: A notation table
- *
- * Build a copy of a notation table.
- *
- * Returns the new xmlNotationTablePtr or NULL in case of error.
- */
-xmlNotationTablePtr
-xmlCopyNotationTable(xmlNotationTablePtr table) {
- return((xmlNotationTablePtr) xmlHashCopy(table,
- (xmlHashCopier) xmlCopyNotation));
-}
-
-/**
- * xmlDumpNotationDecl:
- * @buf: the XML buffer output
- * @nota: A notation declaration
- *
- * This will dump the content the notation declaration as an XML DTD definition
- */
-void
-xmlDumpNotationDecl(xmlBufferPtr buf, xmlNotationPtr nota) {
- xmlBufferWriteChar(buf, "<!NOTATION ");
- xmlBufferWriteCHAR(buf, nota->name);
- if (nota->PublicID != NULL) {
- xmlBufferWriteChar(buf, " PUBLIC ");
- xmlBufferWriteQuotedString(buf, nota->PublicID);
- if (nota->SystemID != NULL) {
- xmlBufferWriteChar(buf, " ");
- xmlBufferWriteCHAR(buf, nota->SystemID);
- }
- } else {
- xmlBufferWriteChar(buf, " SYSTEM ");
- xmlBufferWriteCHAR(buf, nota->SystemID);
- }
- xmlBufferWriteChar(buf, " >\n");
-}
-
-/**
- * xmlDumpNotationTable:
- * @buf: the XML buffer output
- * @table: A notation table
- *
- * This will dump the content of the notation table as an XML DTD definition
- */
-void
-xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
- xmlHashScan(table, (xmlHashScanner) xmlDumpNotationDecl, buf);
-}
-
-/************************************************************************
- * *
- * IDs *
- * *
- ************************************************************************/
-/**
- * xmlCreateIDTable:
- *
- * create and initialize an empty id hash table.
- *
- * Returns the xmlIDTablePtr just created or NULL in case
- * of error.
- */
-static xmlIDTablePtr
-xmlCreateIDTable(void) {
- return(xmlHashCreate(0));
-}
-
-/**
- * xmlFreeID:
- * @not: A id
- *
- * Deallocate the memory used by an id definition
- */
-static void
-xmlFreeID(xmlIDPtr id) {
- if (id == NULL) return;
- if (id->value != NULL)
- xmlFree((xmlChar *) id->value);
- xmlFree(id);
-}
-
-/**
- * xmlAddID:
- * @ctxt: the validation context
- * @doc: pointer to the document
- * @value: the value name
- * @attr: the attribute holding the ID
- *
- * Register a new id declaration
- *
- * Returns NULL if not, otherwise the new xmlIDPtr
- */
-xmlIDPtr
-xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
- xmlAttrPtr attr) {
- xmlIDPtr ret;
- xmlIDTablePtr table;
-
- if (doc == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddID: doc == NULL\n");
- return(NULL);
- }
- if (value == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddID: value == NULL\n");
- return(NULL);
- }
- if (attr == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddID: attr == NULL\n");
- return(NULL);
- }
-
- /*
- * Create the ID table if needed.
- */
- table = (xmlIDTablePtr) doc->ids;
- if (table == NULL)
- doc->ids = table = xmlCreateIDTable();
- if (table == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddID: Table creation failed!\n");
- return(NULL);
- }
-
- ret = (xmlIDPtr) xmlMalloc(sizeof(xmlID));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddID: out of memory\n");
- return(NULL);
- }
-
- /*
- * fill the structure.
- */
- ret->value = xmlStrdup(value);
- ret->attr = attr;
-
- if (xmlHashAddEntry(table, value, ret) < 0) {
- /*
- * The id is already defined in this DTD.
- */
- if (ctxt != NULL) {
- VECTXT(ctxt, attr->parent);
- VERROR(ctxt->userData, "ID %s already defined\n", value);
- }
- xmlFreeID(ret);
- return(NULL);
- }
- return(ret);
-}
-
-/**
- * xmlFreeIDTable:
- * @table: An id table
- *
- * Deallocate the memory used by an ID hash table.
- */
-void
-xmlFreeIDTable(xmlIDTablePtr table) {
- xmlHashFree(table, (xmlHashDeallocator) xmlFreeID);
-}
-
-/**
- * xmlIsID:
- * @doc: the document
- * @elem: the element carrying the attribute
- * @attr: the attribute
- *
- * Determine whether an attribute is of type ID. In case we have DTD(s)
- * then this is done if DTD loading has been requested. In the case
- * of HTML documents parsed with the HTML parser, then ID detection is
- * done systematically.
- *
- * Returns 0 or 1 depending on the lookup result
- */
-int
-xmlIsID(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
- if (doc == NULL) return(0);
- if (attr == NULL) return(0);
- if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) {
- return(0);
- } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
- if ((xmlStrEqual(BAD_CAST "id", attr->name)) ||
- (xmlStrEqual(BAD_CAST "name", attr->name)))
- return(1);
- return(0);
- } else {
- xmlAttributePtr attrDecl;
-
- if (elem == NULL) return(0);
- if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
- /*
- * TODO: this sucks ... recomputing this every time is stupid
- */
- int len = xmlStrlen(elem->name) + xmlStrlen(elem->ns->prefix) + 2;
- xmlChar *fullname;
-
- fullname = xmlMalloc(len);
- if (fullname == NULL)
- return(0);
- snprintf((char *) fullname, len, "%s:%s", (char *) elem->ns->prefix,
- (char *) elem->name);
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullname,
- attr->name);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, fullname,
- attr->name);
- xmlFree(fullname);
- } else {
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name,
- attr->name);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name,
- attr->name);
- }
-
- if ((attrDecl != NULL) && (attrDecl->atype == XML_ATTRIBUTE_ID))
- return(1);
- }
- return(0);
-}
-
-/**
- * xmlRemoveID:
- * @doc: the document
- * @attr: the attribute
- *
- * Remove the given attribute from the ID table maintained internally.
- *
- * Returns -1 if the lookup failed and 0 otherwise
- */
-int
-xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
- xmlAttrPtr cur;
- xmlIDTablePtr table;
- xmlChar *ID;
-
- if (doc == NULL) return(-1);
- if (attr == NULL) return(-1);
- table = (xmlIDTablePtr) doc->ids;
- if (table == NULL)
- return(-1);
-
- if (attr == NULL)
- return(-1);
- ID = xmlNodeListGetString(doc, attr->children, 1);
- if (ID == NULL)
- return(-1);
- cur = xmlHashLookup(table, ID);
- if (cur != attr) {
- xmlFree(ID);
- return(-1);
- }
- xmlHashUpdateEntry(table, ID, NULL, (xmlHashDeallocator) xmlFreeID);
- xmlFree(ID);
- return(0);
-}
-
-/**
- * xmlGetID:
- * @doc: pointer to the document
- * @ID: the ID value
- *
- * Search the attribute declaring the given ID
- *
- * Returns NULL if not found, otherwise the xmlAttrPtr defining the ID
- */
-xmlAttrPtr
-xmlGetID(xmlDocPtr doc, const xmlChar *ID) {
- xmlIDTablePtr table;
- xmlIDPtr id;
-
- if (doc == NULL) {
- xmlGenericError(xmlGenericErrorContext, "xmlGetID: doc == NULL\n");
- return(NULL);
- }
-
- if (ID == NULL) {
- xmlGenericError(xmlGenericErrorContext, "xmlGetID: ID == NULL\n");
- return(NULL);
- }
-
- table = (xmlIDTablePtr) doc->ids;
- if (table == NULL)
- return(NULL);
-
- id = xmlHashLookup(table, ID);
- if (id == NULL)
- return(NULL);
- return(id->attr);
-}
-
-/************************************************************************
- * *
- * Refs *
- * *
- ************************************************************************/
-typedef struct xmlRemoveMemo_t
-{
- xmlListPtr l;
- xmlAttrPtr ap;
-} xmlRemoveMemo;
-
-typedef xmlRemoveMemo *xmlRemoveMemoPtr;
-
-typedef struct xmlValidateMemo_t
-{
- xmlValidCtxtPtr ctxt;
- const xmlChar *name;
-} xmlValidateMemo;
-
-typedef xmlValidateMemo *xmlValidateMemoPtr;
-
-/**
- * xmlCreateRefTable:
- *
- * create and initialize an empty ref hash table.
- *
- * Returns the xmlRefTablePtr just created or NULL in case
- * of error.
- */
-static xmlRefTablePtr
-xmlCreateRefTable(void) {
- return(xmlHashCreate(0));
-}
-
-/**
- * xmlFreeRef:
- * @lk: A list link
- *
- * Deallocate the memory used by a ref definition
- */
-static void
-xmlFreeRef(xmlLinkPtr lk) {
- xmlRefPtr ref = (xmlRefPtr)xmlLinkGetData(lk);
- if (ref == NULL) return;
- if (ref->value != NULL)
- xmlFree((xmlChar *)ref->value);
- xmlFree(ref);
-}
-
-/**
- * xmlFreeRefList:
- * @list_ref: A list of references.
- *
- * Deallocate the memory used by a list of references
- */
-static void
-xmlFreeRefList(xmlListPtr list_ref) {
- if (list_ref == NULL) return;
- xmlListDelete(list_ref);
-}
-
-/**
- * xmlWalkRemoveRef:
- * @data: Contents of current link
- * @user: Value supplied by the user
- *
- * Returns 0 to abort the walk or 1 to continue
- */
-static int
-xmlWalkRemoveRef(const void *data, const void *user)
-{
- xmlAttrPtr attr0 = ((xmlRefPtr)data)->attr;
- xmlAttrPtr attr1 = ((xmlRemoveMemoPtr)user)->ap;
- xmlListPtr ref_list = ((xmlRemoveMemoPtr)user)->l;
-
- if (attr0 == attr1) { /* Matched: remove and terminate walk */
- xmlListRemoveFirst(ref_list, (void *)data);
- return 0;
- }
- return 1;
-}
-
-/**
- * xmlAddRef:
- * @ctxt: the validation context
- * @doc: pointer to the document
- * @value: the value name
- * @attr: the attribute holding the Ref
- *
- * Register a new ref declaration
- *
- * Returns NULL if not, otherwise the new xmlRefPtr
- */
-xmlRefPtr
-xmlAddRef(xmlValidCtxtPtr ctxt ATTRIBUTE_UNUSED, xmlDocPtr doc, const xmlChar *value,
- xmlAttrPtr attr) {
- xmlRefPtr ret;
- xmlRefTablePtr table;
- xmlListPtr ref_list;
-
- if (doc == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddRef: doc == NULL\n");
- return(NULL);
- }
- if (value == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddRef: value == NULL\n");
- return(NULL);
- }
- if (attr == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddRef: attr == NULL\n");
- return(NULL);
- }
-
- /*
- * Create the Ref table if needed.
- */
- table = (xmlRefTablePtr) doc->refs;
- if (table == NULL)
- doc->refs = table = xmlCreateRefTable();
- if (table == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddRef: Table creation failed!\n");
- return(NULL);
- }
-
- ret = (xmlRefPtr) xmlMalloc(sizeof(xmlRef));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddRef: out of memory\n");
- return(NULL);
- }
-
- /*
- * fill the structure.
- */
- ret->value = xmlStrdup(value);
- ret->attr = attr;
-
- /* To add a reference :-
- * References are maintained as a list of references,
- * Lookup the entry, if no entry create new nodelist
- * Add the owning node to the NodeList
- * Return the ref
- */
-
- if (NULL == (ref_list = xmlHashLookup(table, value))) {
- if (NULL == (ref_list = xmlListCreate(xmlFreeRef, NULL))) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddRef: Reference list creation failed!\n");
- return(NULL);
- }
- if (xmlHashAddEntry(table, value, ref_list) < 0) {
- xmlListDelete(ref_list);
- xmlGenericError(xmlGenericErrorContext,
- "xmlAddRef: Reference list insertion failed!\n");
- return(NULL);
- }
- }
- xmlListInsert(ref_list, ret);
- return(ret);
-}
-
-/**
- * xmlFreeRefTable:
- * @table: An ref table
- *
- * Deallocate the memory used by an Ref hash table.
- */
-void
-xmlFreeRefTable(xmlRefTablePtr table) {
- xmlHashFree(table, (xmlHashDeallocator) xmlFreeRefList);
-}
-
-/**
- * xmlIsRef:
- * @doc: the document
- * @elem: the element carrying the attribute
- * @attr: the attribute
- *
- * Determine whether an attribute is of type Ref. In case we have DTD(s)
- * then this is simple, otherwise we use an heuristic: name Ref (upper
- * or lowercase).
- *
- * Returns 0 or 1 depending on the lookup result
- */
-int
-xmlIsRef(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
- if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) {
- return(0);
- } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
- /* TODO @@@ */
- return(0);
- } else {
- xmlAttributePtr attrDecl;
-
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, attr->name);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
- elem->name, attr->name);
-
- if ((attrDecl != NULL) &&
- (attrDecl->atype == XML_ATTRIBUTE_IDREF ||
- attrDecl->atype == XML_ATTRIBUTE_IDREFS))
- return(1);
- }
- return(0);
-}
-
-/**
- * xmlRemoveRef:
- * @doc: the document
- * @attr: the attribute
- *
- * Remove the given attribute from the Ref table maintained internally.
- *
- * Returns -1 if the lookup failed and 0 otherwise
- */
-int
-xmlRemoveRef(xmlDocPtr doc, xmlAttrPtr attr) {
- xmlListPtr ref_list;
- xmlRefTablePtr table;
- xmlChar *ID;
- xmlRemoveMemo target;
-
- if (doc == NULL) return(-1);
- if (attr == NULL) return(-1);
- table = (xmlRefTablePtr) doc->refs;
- if (table == NULL)
- return(-1);
-
- if (attr == NULL)
- return(-1);
- ID = xmlNodeListGetString(doc, attr->children, 1);
- if (ID == NULL)
- return(-1);
- ref_list = xmlHashLookup(table, ID);
-
- if(ref_list == NULL) {
- xmlFree(ID);
- return (-1);
- }
- /* At this point, ref_list refers to a list of references which
- * have the same key as the supplied attr. Our list of references
- * is ordered by reference address and we don't have that information
- * here to use when removing. We'll have to walk the list and
- * check for a matching attribute, when we find one stop the walk
- * and remove the entry.
- * The list is ordered by reference, so that means we don't have the
- * key. Passing the list and the reference to the walker means we
- * will have enough data to be able to remove the entry.
- */
- target.l = ref_list;
- target.ap = attr;
-
- /* Remove the supplied attr from our list */
- xmlListWalk(ref_list, xmlWalkRemoveRef, &target);
-
- /*If the list is empty then remove the list entry in the hash */
- if (xmlListEmpty(ref_list))
- xmlHashUpdateEntry(table, ID, NULL, (xmlHashDeallocator)
- xmlFreeRefList);
- xmlFree(ID);
- return(0);
-}
-
-/**
- * xmlGetRefs:
- * @doc: pointer to the document
- * @ID: the ID value
- *
- * Find the set of references for the supplied ID.
- *
- * Returns NULL if not found, otherwise node set for the ID.
- */
-xmlListPtr
-xmlGetRefs(xmlDocPtr doc, const xmlChar *ID) {
- xmlRefTablePtr table;
-
- if (doc == NULL) {
- xmlGenericError(xmlGenericErrorContext, "xmlGetRefs: doc == NULL\n");
- return(NULL);
- }
-
- if (ID == NULL) {
- xmlGenericError(xmlGenericErrorContext, "xmlGetRefs: ID == NULL\n");
- return(NULL);
- }
-
- table = (xmlRefTablePtr) doc->refs;
- if (table == NULL)
- return(NULL);
-
- return (xmlHashLookup(table, ID));
-}
-
-/************************************************************************
- * *
- * Routines for validity checking *
- * *
- ************************************************************************/
-
-/**
- * xmlGetDtdElementDesc:
- * @dtd: a pointer to the DtD to search
- * @name: the element name
- *
- * Search the DTD for the description of this element
- *
- * returns the xmlElementPtr if found or NULL
- */
-
-xmlElementPtr
-xmlGetDtdElementDesc(xmlDtdPtr dtd, const xmlChar *name) {
- xmlElementTablePtr table;
- xmlElementPtr cur;
- xmlChar *uqname = NULL, *prefix = NULL;
-
- if (dtd == NULL) return(NULL);
- if (dtd->elements == NULL)
- return(NULL);
- table = (xmlElementTablePtr) dtd->elements;
-
- uqname = xmlSplitQName2(name, &prefix);
- if (uqname != NULL)
- name = uqname;
- cur = xmlHashLookup2(table, name, prefix);
- if (prefix != NULL) xmlFree(prefix);
- if (uqname != NULL) xmlFree(uqname);
- return(cur);
-}
-/**
- * xmlGetDtdElementDesc2:
- * @dtd: a pointer to the DtD to search
- * @name: the element name
- * @create: create an empty description if not found
- *
- * Search the DTD for the description of this element
- *
- * returns the xmlElementPtr if found or NULL
- */
-
-static xmlElementPtr
-xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name, int create) {
- xmlElementTablePtr table;
- xmlElementPtr cur;
- xmlChar *uqname = NULL, *prefix = NULL;
-
- if (dtd == NULL) return(NULL);
- if (dtd->elements == NULL) {
- if (!create)
- return(NULL);
- /*
- * Create the Element table if needed.
- */
- table = (xmlElementTablePtr) dtd->elements;
- if (table == NULL) {
- table = xmlCreateElementTable();
- dtd->elements = (void *) table;
- }
- if (table == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlGetDtdElementDesc2: Table creation failed!\n");
- return(NULL);
- }
- }
- table = (xmlElementTablePtr) dtd->elements;
-
- uqname = xmlSplitQName2(name, &prefix);
- if (uqname != NULL)
- name = uqname;
- cur = xmlHashLookup2(table, name, prefix);
- if ((cur == NULL) && (create)) {
- cur = (xmlElementPtr) xmlMalloc(sizeof(xmlElement));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlGetDtdElementDesc2: out of memory\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlElement));
- cur->type = XML_ELEMENT_DECL;
-
- /*
- * fill the structure.
- */
- cur->name = xmlStrdup(name);
- cur->prefix = xmlStrdup(prefix);
- cur->etype = XML_ELEMENT_TYPE_UNDEFINED;
-
- xmlHashAddEntry2(table, name, prefix, cur);
- }
- if (prefix != NULL) xmlFree(prefix);
- if (uqname != NULL) xmlFree(uqname);
- return(cur);
-}
-
-/**
- * xmlGetDtdQElementDesc:
- * @dtd: a pointer to the DtD to search
- * @name: the element name
- * @prefix: the element namespace prefix
- *
- * Search the DTD for the description of this element
- *
- * returns the xmlElementPtr if found or NULL
- */
-
-xmlElementPtr
-xmlGetDtdQElementDesc(xmlDtdPtr dtd, const xmlChar *name,
- const xmlChar *prefix) {
- xmlElementTablePtr table;
-
- if (dtd == NULL) return(NULL);
- if (dtd->elements == NULL) return(NULL);
- table = (xmlElementTablePtr) dtd->elements;
-
- return(xmlHashLookup2(table, name, prefix));
-}
-
-/**
- * xmlGetDtdAttrDesc:
- * @dtd: a pointer to the DtD to search
- * @elem: the element name
- * @name: the attribute name
- *
- * Search the DTD for the description of this attribute on
- * this element.
- *
- * returns the xmlAttributePtr if found or NULL
- */
-
-xmlAttributePtr
-xmlGetDtdAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name) {
- xmlAttributeTablePtr table;
- xmlAttributePtr cur;
- xmlChar *uqname = NULL, *prefix = NULL;
-
- if (dtd == NULL) return(NULL);
- if (dtd->attributes == NULL) return(NULL);
-
- table = (xmlAttributeTablePtr) dtd->attributes;
- if (table == NULL)
- return(NULL);
-
- uqname = xmlSplitQName2(name, &prefix);
-
- if (uqname != NULL) {
- cur = xmlHashLookup3(table, uqname, prefix, elem);
- if (prefix != NULL) xmlFree(prefix);
- if (uqname != NULL) xmlFree(uqname);
- } else
- cur = xmlHashLookup3(table, name, NULL, elem);
- return(cur);
-}
-
-/**
- * xmlGetDtdQAttrDesc:
- * @dtd: a pointer to the DtD to search
- * @elem: the element name
- * @name: the attribute name
- * @prefix: the attribute namespace prefix
- *
- * Search the DTD for the description of this qualified attribute on
- * this element.
- *
- * returns the xmlAttributePtr if found or NULL
- */
-
-xmlAttributePtr
-xmlGetDtdQAttrDesc(xmlDtdPtr dtd, const xmlChar *elem, const xmlChar *name,
- const xmlChar *prefix) {
- xmlAttributeTablePtr table;
-
- if (dtd == NULL) return(NULL);
- if (dtd->attributes == NULL) return(NULL);
- table = (xmlAttributeTablePtr) dtd->attributes;
-
- return(xmlHashLookup3(table, name, prefix, elem));
-}
-
-/**
- * xmlGetDtdNotationDesc:
- * @dtd: a pointer to the DtD to search
- * @name: the notation name
- *
- * Search the DTD for the description of this notation
- *
- * returns the xmlNotationPtr if found or NULL
- */
-
-xmlNotationPtr
-xmlGetDtdNotationDesc(xmlDtdPtr dtd, const xmlChar *name) {
- xmlNotationTablePtr table;
-
- if (dtd == NULL) return(NULL);
- if (dtd->notations == NULL) return(NULL);
- table = (xmlNotationTablePtr) dtd->notations;
-
- return(xmlHashLookup(table, name));
-}
-
-/**
- * xmlValidateNotationUse:
- * @ctxt: the validation context
- * @doc: the document
- * @notationName: the notation name to check
- *
- * Validate that the given name match a notation declaration.
- * - [ VC: Notation Declared ]
- *
- * returns 1 if valid or 0 otherwise
- */
-
-int
-xmlValidateNotationUse(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
- const xmlChar *notationName) {
- xmlNotationPtr notaDecl;
- if ((doc == NULL) || (doc->intSubset == NULL)) return(-1);
-
- notaDecl = xmlGetDtdNotationDesc(doc->intSubset, notationName);
- if ((notaDecl == NULL) && (doc->extSubset != NULL))
- notaDecl = xmlGetDtdNotationDesc(doc->extSubset, notationName);
-
- if (notaDecl == NULL) {
- VERROR(ctxt->userData, "NOTATION %s is not declared\n",
- notationName);
- return(0);
- }
- return(1);
-}
-
-/**
- * xmlIsMixedElement:
- * @doc: the document
- * @name: the element name
- *
- * Search in the DtDs whether an element accept Mixed content (or ANY)
- * basically if it is supposed to accept text childs
- *
- * returns 0 if no, 1 if yes, and -1 if no element description is available
- */
-
-int
-xmlIsMixedElement(xmlDocPtr doc, const xmlChar *name) {
- xmlElementPtr elemDecl;
-
- if ((doc == NULL) || (doc->intSubset == NULL)) return(-1);
-
- elemDecl = xmlGetDtdElementDesc(doc->intSubset, name);
- if ((elemDecl == NULL) && (doc->extSubset != NULL))
- elemDecl = xmlGetDtdElementDesc(doc->extSubset, name);
- if (elemDecl == NULL) return(-1);
- switch (elemDecl->etype) {
- case XML_ELEMENT_TYPE_UNDEFINED:
- return(-1);
- case XML_ELEMENT_TYPE_ELEMENT:
- return(0);
- case XML_ELEMENT_TYPE_EMPTY:
- /*
- * return 1 for EMPTY since we want VC error to pop up
- * on <empty> </empty> for example
- */
- case XML_ELEMENT_TYPE_ANY:
- case XML_ELEMENT_TYPE_MIXED:
- return(1);
- }
- return(1);
-}
-
-/**
- * xmlValidateNameValue:
- * @value: an Name value
- *
- * Validate that the given value match Name production
- *
- * returns 1 if valid or 0 otherwise
- */
-
-int
-xmlValidateNameValue(const xmlChar *value) {
- const xmlChar *cur;
- int val, len;
-
- if (value == NULL) return(0);
- cur = value;
- val = xmlStringCurrentChar(NULL, cur, &len);
- cur += len;
- if (!IS_LETTER(val) && (val != '_') &&
- (val != ':')) {
- return(0);
- }
-
- val = xmlStringCurrentChar(NULL, cur, &len);
- cur += len;
- while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
- (val == '.') || (val == '-') ||
- (val == '_') || (val == ':') ||
- (IS_COMBINING(val)) ||
- (IS_EXTENDER(val))) {
- val = xmlStringCurrentChar(NULL, cur, &len);
- cur += len;
- }
-
- if (val != 0) return(0);
-
- return(1);
-}
-
-/**
- * xmlValidateNamesValue:
- * @value: an Names value
- *
- * Validate that the given value match Names production
- *
- * returns 1 if valid or 0 otherwise
- */
-
-int
-xmlValidateNamesValue(const xmlChar *value) {
- const xmlChar *cur;
- int val, len;
-
- if (value == NULL) return(0);
- cur = value;
- val = xmlStringCurrentChar(NULL, cur, &len);
- cur += len;
-
- if (!IS_LETTER(val) && (val != '_') &&
- (val != ':')) {
- return(0);
- }
-
- val = xmlStringCurrentChar(NULL, cur, &len);
- cur += len;
- while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
- (val == '.') || (val == '-') ||
- (val == '_') || (val == ':') ||
- (IS_COMBINING(val)) ||
- (IS_EXTENDER(val))) {
- val = xmlStringCurrentChar(NULL, cur, &len);
- cur += len;
- }
-
- while (IS_BLANK(val)) {
- while (IS_BLANK(val)) {
- val = xmlStringCurrentChar(NULL, cur, &len);
- cur += len;
- }
-
- if (!IS_LETTER(val) && (val != '_') &&
- (val != ':')) {
- return(0);
- }
- val = xmlStringCurrentChar(NULL, cur, &len);
- cur += len;
-
- while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
- (val == '.') || (val == '-') ||
- (val == '_') || (val == ':') ||
- (IS_COMBINING(val)) ||
- (IS_EXTENDER(val))) {
- val = xmlStringCurrentChar(NULL, cur, &len);
- cur += len;
- }
- }
-
- if (val != 0) return(0);
-
- return(1);
-}
-
-/**
- * xmlValidateNmtokenValue:
- * @value: an Nmtoken value
- *
- * Validate that the given value match Nmtoken production
- *
- * [ VC: Name Token ]
- *
- * returns 1 if valid or 0 otherwise
- */
-
-int
-xmlValidateNmtokenValue(const xmlChar *value) {
- const xmlChar *cur;
- int val, len;
-
- if (value == NULL) return(0);
- cur = value;
- val = xmlStringCurrentChar(NULL, cur, &len);
- cur += len;
-
- if (!IS_LETTER(val) && !IS_DIGIT(val) &&
- (val != '.') && (val != '-') &&
- (val != '_') && (val != ':') &&
- (!IS_COMBINING(val)) &&
- (!IS_EXTENDER(val)))
- return(0);
-
- while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
- (val == '.') || (val == '-') ||
- (val == '_') || (val == ':') ||
- (IS_COMBINING(val)) ||
- (IS_EXTENDER(val))) {
- val = xmlStringCurrentChar(NULL, cur, &len);
- cur += len;
- }
-
- if (val != 0) return(0);
-
- return(1);
-}
-
-/**
- * xmlValidateNmtokensValue:
- * @value: an Nmtokens value
- *
- * Validate that the given value match Nmtokens production
- *
- * [ VC: Name Token ]
- *
- * returns 1 if valid or 0 otherwise
- */
-
-int
-xmlValidateNmtokensValue(const xmlChar *value) {
- const xmlChar *cur;
- int val, len;
-
- if (value == NULL) return(0);
- cur = value;
- val = xmlStringCurrentChar(NULL, cur, &len);
- cur += len;
-
- while (IS_BLANK(val)) {
- val = xmlStringCurrentChar(NULL, cur, &len);
- cur += len;
- }
-
- if (!IS_LETTER(val) && !IS_DIGIT(val) &&
- (val != '.') && (val != '-') &&
- (val != '_') && (val != ':') &&
- (!IS_COMBINING(val)) &&
- (!IS_EXTENDER(val)))
- return(0);
-
- while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
- (val == '.') || (val == '-') ||
- (val == '_') || (val == ':') ||
- (IS_COMBINING(val)) ||
- (IS_EXTENDER(val))) {
- val = xmlStringCurrentChar(NULL, cur, &len);
- cur += len;
- }
-
- while (IS_BLANK(val)) {
- while (IS_BLANK(val)) {
- val = xmlStringCurrentChar(NULL, cur, &len);
- cur += len;
- }
- if (val == 0) return(1);
-
- if (!IS_LETTER(val) && !IS_DIGIT(val) &&
- (val != '.') && (val != '-') &&
- (val != '_') && (val != ':') &&
- (!IS_COMBINING(val)) &&
- (!IS_EXTENDER(val)))
- return(0);
-
- while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
- (val == '.') || (val == '-') ||
- (val == '_') || (val == ':') ||
- (IS_COMBINING(val)) ||
- (IS_EXTENDER(val))) {
- val = xmlStringCurrentChar(NULL, cur, &len);
- cur += len;
- }
- }
-
- if (val != 0) return(0);
-
- return(1);
-}
-
-/**
- * xmlValidateNotationDecl:
- * @ctxt: the validation context
- * @doc: a document instance
- * @nota: a notation definition
- *
- * Try to validate a single notation definition
- * basically it does the following checks as described by the
- * XML-1.0 recommendation:
- * - it seems that no validity constraint exists on notation declarations
- * But this function get called anyway ...
- *
- * returns 1 if valid or 0 otherwise
- */
-
-int
-xmlValidateNotationDecl(xmlValidCtxtPtr ctxt ATTRIBUTE_UNUSED, xmlDocPtr doc ATTRIBUTE_UNUSED,
- xmlNotationPtr nota ATTRIBUTE_UNUSED) {
- int ret = 1;
-
- return(ret);
-}
-
-/**
- * xmlValidateAttributeValue:
- * @type: an attribute type
- * @value: an attribute value
- *
- * Validate that the given attribute value match the proper production
- *
- * [ VC: ID ]
- * Values of type ID must match the Name production....
- *
- * [ VC: IDREF ]
- * Values of type IDREF must match the Name production, and values
- * of type IDREFS must match Names ...
- *
- * [ VC: Entity Name ]
- * Values of type ENTITY must match the Name production, values
- * of type ENTITIES must match Names ...
- *
- * [ VC: Name Token ]
- * Values of type NMTOKEN must match the Nmtoken production; values
- * of type NMTOKENS must match Nmtokens.
- *
- * returns 1 if valid or 0 otherwise
- */
-
-int
-xmlValidateAttributeValue(xmlAttributeType type, const xmlChar *value) {
- switch (type) {
- case XML_ATTRIBUTE_ENTITIES:
- case XML_ATTRIBUTE_IDREFS:
- return(xmlValidateNamesValue(value));
- case XML_ATTRIBUTE_ENTITY:
- case XML_ATTRIBUTE_IDREF:
- case XML_ATTRIBUTE_ID:
- case XML_ATTRIBUTE_NOTATION:
- return(xmlValidateNameValue(value));
- case XML_ATTRIBUTE_NMTOKENS:
- case XML_ATTRIBUTE_ENUMERATION:
- return(xmlValidateNmtokensValue(value));
- case XML_ATTRIBUTE_NMTOKEN:
- return(xmlValidateNmtokenValue(value));
- case XML_ATTRIBUTE_CDATA:
- break;
- }
- return(1);
-}
-
-/**
- * xmlValidateAttributeValue2:
- * @ctxt: the validation context
- * @doc: the document
- * @name: the attribute name (used for error reporting only)
- * @type: the attribute type
- * @value: the attribute value
- *
- * Validate that the given attribute value match a given type.
- * This typically cannot be done before having finished parsing
- * the subsets.
- *
- * [ VC: IDREF ]
- * Values of type IDREF must match one of the declared IDs
- * Values of type IDREFS must match a sequence of the declared IDs
- * each Name must match the value of an ID attribute on some element
- * in the XML document; i.e. IDREF values must match the value of
- * some ID attribute
- *
- * [ VC: Entity Name ]
- * Values of type ENTITY must match one declared entity
- * Values of type ENTITIES must match a sequence of declared entities
- *
- * [ VC: Notation Attributes ]
- * all notation names in the declaration must be declared.
- *
- * returns 1 if valid or 0 otherwise
- */
-
-static int
-xmlValidateAttributeValue2(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
- const xmlChar *name, xmlAttributeType type, const xmlChar *value) {
- int ret = 1;
- switch (type) {
- case XML_ATTRIBUTE_IDREFS:
- case XML_ATTRIBUTE_IDREF:
- case XML_ATTRIBUTE_ID:
- case XML_ATTRIBUTE_NMTOKENS:
- case XML_ATTRIBUTE_ENUMERATION:
- case XML_ATTRIBUTE_NMTOKEN:
- case XML_ATTRIBUTE_CDATA:
- break;
- case XML_ATTRIBUTE_ENTITY: {
- xmlEntityPtr ent;
-
- ent = xmlGetDocEntity(doc, value);
- if ((ent == NULL) && (doc->standalone == 1)) {
- doc->standalone = 0;
- ent = xmlGetDocEntity(doc, value);
- if (ent != NULL) {
- VERROR(ctxt->userData,
-"standalone problem: attribute %s reference entity \"%s\" in external subset\n",
- name, value);
- /* WAIT to get answer from the Core WG on this
- ret = 0;
- */
- }
- }
- if (ent == NULL) {
- VERROR(ctxt->userData,
- "ENTITY attribute %s reference an unknown entity \"%s\"\n",
- name, value);
- ret = 0;
- } else if (ent->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
- VERROR(ctxt->userData,
- "ENTITY attribute %s reference an entity \"%s\" of wrong type\n",
- name, value);
- ret = 0;
- }
- break;
- }
- case XML_ATTRIBUTE_ENTITIES: {
- xmlChar *dup, *nam = NULL, *cur, save;
- xmlEntityPtr ent;
-
- dup = xmlStrdup(value);
- if (dup == NULL)
- return(0);
- cur = dup;
- while (*cur != 0) {
- nam = cur;
- while ((*cur != 0) && (!IS_BLANK(*cur))) cur++;
- save = *cur;
- *cur = 0;
- ent = xmlGetDocEntity(doc, nam);
- if (ent == NULL) {
- VERROR(ctxt->userData,
- "ENTITIES attribute %s reference an unknown entity \"%s\"\n",
- name, nam);
- ret = 0;
- } else if (ent->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
- VERROR(ctxt->userData,
- "ENTITIES attribute %s reference an entity \"%s\" of wrong type\n",
- name, nam);
- ret = 0;
- }
- if (save == 0)
- break;
- *cur = save;
- while (IS_BLANK(*cur)) cur++;
- }
- xmlFree(dup);
- break;
- }
- case XML_ATTRIBUTE_NOTATION: {
- xmlNotationPtr nota;
-
- nota = xmlGetDtdNotationDesc(doc->intSubset, value);
- if ((nota == NULL) && (doc->extSubset != NULL))
- nota = xmlGetDtdNotationDesc(doc->extSubset, value);
-
- if (nota == NULL) {
- VERROR(ctxt->userData,
- "NOTATION attribute %s reference an unknown notation \"%s\"\n",
- name, value);
- ret = 0;
- }
- break;
- }
- }
- return(ret);
-}
-
-/**
- * xmlValidCtxtNormalizeAttributeValue:
- * @ctxt: the validation context
- * @doc: the document
- * @elem: the parent
- * @name: the attribute name
- * @value: the attribute value
- * @ctxt: the validation context or NULL
- *
- * Does the validation related extra step of the normalization of attribute
- * values:
- *
- * If the declared value is not CDATA, then the XML processor must further
- * process the normalized attribute value by discarding any leading and
- * trailing space (#x20) characters, and by replacing sequences of space
- * (#x20) characters by single space (#x20) character.
- *
- * Also check VC: Standalone Document Declaration in P32, and update
- * ctxt->valid accordingly
- *
- * returns a new normalized string if normalization is needed, NULL otherwise
- * the caller must free the returned value.
- */
-
-xmlChar *
-xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
- xmlNodePtr elem, const xmlChar *name, const xmlChar *value) {
- xmlChar *ret, *dst;
- const xmlChar *src;
- xmlAttributePtr attrDecl = NULL;
- int extsubset = 0;
-
- if (doc == NULL) return(NULL);
- if (elem == NULL) return(NULL);
- if (name == NULL) return(NULL);
- if (value == NULL) return(NULL);
-
- if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
- xmlChar qname[500];
- snprintf((char *) qname, sizeof(qname), "%s:%s",
- elem->ns->prefix, elem->name);
- qname[sizeof(qname) - 1] = 0;
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, qname, name);
- if ((attrDecl == NULL) && (doc->extSubset != NULL)) {
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, qname, name);
- if (attrDecl != NULL)
- extsubset = 1;
- }
- }
- if ((attrDecl == NULL) && (doc->intSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, name);
- if ((attrDecl == NULL) && (doc->extSubset != NULL)) {
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name, name);
- if (attrDecl != NULL)
- extsubset = 1;
- }
-
- if (attrDecl == NULL)
- return(NULL);
- if (attrDecl->atype == XML_ATTRIBUTE_CDATA)
- return(NULL);
-
- ret = xmlStrdup(value);
- if (ret == NULL)
- return(NULL);
- src = value;
- dst = ret;
- while (*src == 0x20) src++;
- while (*src != 0) {
- if (*src == 0x20) {
- while (*src == 0x20) src++;
- if (*src != 0)
- *dst++ = 0x20;
- } else {
- *dst++ = *src++;
- }
- }
- *dst = 0;
- if ((doc->standalone) && (extsubset == 1) && (!xmlStrEqual(value, ret))) {
- VERROR(ctxt->userData,
-"standalone: %s on %s value had to be normalized based on external subset declaration\n",
- name, elem->name);
- ctxt->valid = 0;
- }
- return(ret);
-}
-
-/**
- * xmlValidNormalizeAttributeValue:
- * @doc: the document
- * @elem: the parent
- * @name: the attribute name
- * @value: the attribute value
- *
- * Does the validation related extra step of the normalization of attribute
- * values:
- *
- * If the declared value is not CDATA, then the XML processor must further
- * process the normalized attribute value by discarding any leading and
- * trailing space (#x20) characters, and by replacing sequences of space
- * (#x20) characters by single space (#x20) character.
- *
- * returns a new normalized string if normalization is needed, NULL otherwise
- * the caller must free the returned value.
- */
-
-xmlChar *
-xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
- const xmlChar *name, const xmlChar *value) {
- xmlChar *ret, *dst;
- const xmlChar *src;
- xmlAttributePtr attrDecl = NULL;
-
- if (doc == NULL) return(NULL);
- if (elem == NULL) return(NULL);
- if (name == NULL) return(NULL);
- if (value == NULL) return(NULL);
-
- if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
- xmlChar qname[500];
- snprintf((char *) qname, sizeof(qname), "%s:%s",
- elem->ns->prefix, elem->name);
- qname[sizeof(qname) - 1] = 0;
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, qname, name);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, qname, name);
- }
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, elem->name, name);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, elem->name, name);
-
- if (attrDecl == NULL)
- return(NULL);
- if (attrDecl->atype == XML_ATTRIBUTE_CDATA)
- return(NULL);
-
- ret = xmlStrdup(value);
- if (ret == NULL)
- return(NULL);
- src = value;
- dst = ret;
- while (*src == 0x20) src++;
- while (*src != 0) {
- if (*src == 0x20) {
- while (*src == 0x20) src++;
- if (*src != 0)
- *dst++ = 0x20;
- } else {
- *dst++ = *src++;
- }
- }
- *dst = 0;
- return(ret);
-}
-
-static void
-xmlValidateAttributeIdCallback(xmlAttributePtr attr, int *count,
- const xmlChar* name ATTRIBUTE_UNUSED) {
- if (attr->atype == XML_ATTRIBUTE_ID) (*count)++;
-}
-
-/**
- * xmlValidateAttributeDecl:
- * @ctxt: the validation context
- * @doc: a document instance
- * @attr: an attribute definition
- *
- * Try to validate a single attribute definition
- * basically it does the following checks as described by the
- * XML-1.0 recommendation:
- * - [ VC: Attribute Default Legal ]
- * - [ VC: Enumeration ]
- * - [ VC: ID Attribute Default ]
- *
- * The ID/IDREF uniqueness and matching are done separately
- *
- * returns 1 if valid or 0 otherwise
- */
-
-int
-xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
- xmlAttributePtr attr) {
- int ret = 1;
- int val;
- CHECK_DTD;
- if(attr == NULL) return(1);
-
- /* Attribute Default Legal */
- /* Enumeration */
- if (attr->defaultValue != NULL) {
- val = xmlValidateAttributeValue(attr->atype, attr->defaultValue);
- if (val == 0) {
- VERROR(ctxt->userData,
- "Syntax of default value for attribute %s of %s is not valid\n",
- attr->name, attr->elem);
- }
- ret &= val;
- }
-
- /* ID Attribute Default */
- if ((attr->atype == XML_ATTRIBUTE_ID)&&
- (attr->def != XML_ATTRIBUTE_IMPLIED) &&
- (attr->def != XML_ATTRIBUTE_REQUIRED)) {
- VERROR(ctxt->userData,
- "ID attribute %s of %s is not valid must be #IMPLIED or #REQUIRED\n",
- attr->name, attr->elem);
- ret = 0;
- }
-
- /* One ID per Element Type */
- if (attr->atype == XML_ATTRIBUTE_ID) {
- int nbId;
-
- /* the trick is that we parse DtD as their own internal subset */
- xmlElementPtr elem = xmlGetDtdElementDesc(doc->intSubset,
- attr->elem);
- if (elem != NULL) {
- nbId = xmlScanIDAttributeDecl(NULL, elem);
- } else {
- xmlAttributeTablePtr table;
-
- /*
- * The attribute may be declared in the internal subset and the
- * element in the external subset.
- */
- nbId = 0;
- table = (xmlAttributeTablePtr) doc->intSubset->attributes;
- xmlHashScan3(table, NULL, NULL, attr->elem, (xmlHashScanner)
- xmlValidateAttributeIdCallback, &nbId);
- }
- if (nbId > 1) {
- VERROR(ctxt->userData,
- "Element %s has %d ID attribute defined in the internal subset : %s\n",
- attr->elem, nbId, attr->name);
- } else if (doc->extSubset != NULL) {
- int extId = 0;
- elem = xmlGetDtdElementDesc(doc->extSubset, attr->elem);
- if (elem != NULL) {
- extId = xmlScanIDAttributeDecl(NULL, elem);
- }
- if (extId > 1) {
- VERROR(ctxt->userData,
- "Element %s has %d ID attribute defined in the external subset : %s\n",
- attr->elem, extId, attr->name);
- } else if (extId + nbId > 1) {
- VERROR(ctxt->userData,
-"Element %s has ID attributes defined in the internal and external subset : %s\n",
- attr->elem, attr->name);
- }
- }
- }
-
- /* Validity Constraint: Enumeration */
- if ((attr->defaultValue != NULL) && (attr->tree != NULL)) {
- xmlEnumerationPtr tree = attr->tree;
- while (tree != NULL) {
- if (xmlStrEqual(tree->name, attr->defaultValue)) break;
- tree = tree->next;
- }
- if (tree == NULL) {
- VERROR(ctxt->userData,
-"Default value \"%s\" for attribute %s of %s is not among the enumerated set\n",
- attr->defaultValue, attr->name, attr->elem);
- ret = 0;
- }
- }
-
- return(ret);
-}
-
-/**
- * xmlValidateElementDecl:
- * @ctxt: the validation context
- * @doc: a document instance
- * @elem: an element definition
- *
- * Try to validate a single element definition
- * basically it does the following checks as described by the
- * XML-1.0 recommendation:
- * - [ VC: One ID per Element Type ]
- * - [ VC: No Duplicate Types ]
- * - [ VC: Unique Element Type Declaration ]
- *
- * returns 1 if valid or 0 otherwise
- */
-
-int
-xmlValidateElementDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
- xmlElementPtr elem) {
- int ret = 1;
- xmlElementPtr tst;
-
- CHECK_DTD;
-
- if (elem == NULL) return(1);
-
-#if 0
-#ifdef LIBXML_REGEXP_ENABLED
- /* Build the regexp associated to the content model */
- ret = xmlValidBuildContentModel(ctxt, elem);
-#endif
-#endif
-
- /* No Duplicate Types */
- if (elem->etype == XML_ELEMENT_TYPE_MIXED) {
- xmlElementContentPtr cur, next;
- const xmlChar *name;
-
- cur = elem->content;
- while (cur != NULL) {
- if (cur->type != XML_ELEMENT_CONTENT_OR) break;
- if (cur->c1 == NULL) break;
- if (cur->c1->type == XML_ELEMENT_CONTENT_ELEMENT) {
- name = cur->c1->name;
- next = cur->c2;
- while (next != NULL) {
- if (next->type == XML_ELEMENT_CONTENT_ELEMENT) {
- if (xmlStrEqual(next->name, name)) {
- VERROR(ctxt->userData,
- "Definition of %s has duplicate references of %s\n",
- elem->name, name);
- ret = 0;
- }
- break;
- }
- if (next->c1 == NULL) break;
- if (next->c1->type != XML_ELEMENT_CONTENT_ELEMENT) break;
- if (xmlStrEqual(next->c1->name, name)) {
- VERROR(ctxt->userData,
- "Definition of %s has duplicate references of %s\n",
- elem->name, name);
- ret = 0;
- }
- next = next->c2;
- }
- }
- cur = cur->c2;
- }
- }
-
- /* VC: Unique Element Type Declaration */
- tst = xmlGetDtdElementDesc(doc->intSubset, elem->name);
- if ((tst != NULL ) && (tst != elem) &&
- ((tst->prefix == elem->prefix) ||
- (xmlStrEqual(tst->prefix, elem->prefix))) &&
- (tst->etype != XML_ELEMENT_TYPE_UNDEFINED)) {
- VERROR(ctxt->userData, "Redefinition of element %s\n",
- elem->name);
- ret = 0;
- }
- tst = xmlGetDtdElementDesc(doc->extSubset, elem->name);
- if ((tst != NULL ) && (tst != elem) &&
- ((tst->prefix == elem->prefix) ||
- (xmlStrEqual(tst->prefix, elem->prefix))) &&
- (tst->etype != XML_ELEMENT_TYPE_UNDEFINED)) {
- VERROR(ctxt->userData, "Redefinition of element %s\n",
- elem->name);
- ret = 0;
- }
- /* One ID per Element Type
- * already done when registering the attribute
- if (xmlScanIDAttributeDecl(ctxt, elem) > 1) {
- ret = 0;
- } */
- return(ret);
-}
-
-/**
- * xmlValidateOneAttribute:
- * @ctxt: the validation context
- * @doc: a document instance
- * @elem: an element instance
- * @attr: an attribute instance
- * @value: the attribute value (without entities processing)
- *
- * Try to validate a single attribute for an element
- * basically it does the following checks as described by the
- * XML-1.0 recommendation:
- * - [ VC: Attribute Value Type ]
- * - [ VC: Fixed Attribute Default ]
- * - [ VC: Entity Name ]
- * - [ VC: Name Token ]
- * - [ VC: ID ]
- * - [ VC: IDREF ]
- * - [ VC: Entity Name ]
- * - [ VC: Notation Attributes ]
- *
- * The ID/IDREF uniqueness and matching are done separately
- *
- * returns 1 if valid or 0 otherwise
- */
-
-int
-xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
- xmlNodePtr elem, xmlAttrPtr attr, const xmlChar *value) {
- /* xmlElementPtr elemDecl; */
- xmlAttributePtr attrDecl = NULL;
- int val;
- int ret = 1;
-
- CHECK_DTD;
- if ((elem == NULL) || (elem->name == NULL)) return(0);
- if ((attr == NULL) || (attr->name == NULL)) return(0);
-
- if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
- xmlChar qname[500];
- snprintf((char *) qname, sizeof(qname), "%s:%s",
- elem->ns->prefix, elem->name);
- qname[sizeof(qname) - 1] = 0;
- if (attr->ns != NULL) {
- attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, qname,
- attr->name, attr->ns->prefix);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, qname,
- attr->name, attr->ns->prefix);
- } else {
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, qname, attr->name);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
- qname, attr->name);
- }
- }
- if (attrDecl == NULL) {
- if (attr->ns != NULL) {
- attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, elem->name,
- attr->name, attr->ns->prefix);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, elem->name,
- attr->name, attr->ns->prefix);
- } else {
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset,
- elem->name, attr->name);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
- elem->name, attr->name);
- }
- }
-
-
- /* Validity Constraint: Attribute Value Type */
- if (attrDecl == NULL) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "No declaration for attribute %s of element %s\n",
- attr->name, elem->name);
- return(0);
- }
- attr->atype = attrDecl->atype;
-
- val = xmlValidateAttributeValue(attrDecl->atype, value);
- if (val == 0) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Syntax of value for attribute %s of %s is not valid\n",
- attr->name, elem->name);
- ret = 0;
- }
-
- /* Validity constraint: Fixed Attribute Default */
- if (attrDecl->def == XML_ATTRIBUTE_FIXED) {
- if (!xmlStrEqual(value, attrDecl->defaultValue)) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Value for attribute %s of %s is different from default \"%s\"\n",
- attr->name, elem->name, attrDecl->defaultValue);
- ret = 0;
- }
- }
-
- /* Validity Constraint: ID uniqueness */
- if (attrDecl->atype == XML_ATTRIBUTE_ID) {
- if (xmlAddID(ctxt, doc, value, attr) == NULL)
- ret = 0;
- }
-
- if ((attrDecl->atype == XML_ATTRIBUTE_IDREF) ||
- (attrDecl->atype == XML_ATTRIBUTE_IDREFS)) {
- if (xmlAddRef(ctxt, doc, value, attr) == NULL)
- ret = 0;
- }
-
- /* Validity Constraint: Notation Attributes */
- if (attrDecl->atype == XML_ATTRIBUTE_NOTATION) {
- xmlEnumerationPtr tree = attrDecl->tree;
- xmlNotationPtr nota;
-
- /* First check that the given NOTATION was declared */
- nota = xmlGetDtdNotationDesc(doc->intSubset, value);
- if (nota == NULL)
- nota = xmlGetDtdNotationDesc(doc->extSubset, value);
-
- if (nota == NULL) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Value \"%s\" for attribute %s of %s is not a declared Notation\n",
- value, attr->name, elem->name);
- ret = 0;
- }
-
- /* Second, verify that it's among the list */
- while (tree != NULL) {
- if (xmlStrEqual(tree->name, value)) break;
- tree = tree->next;
- }
- if (tree == NULL) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
-"Value \"%s\" for attribute %s of %s is not among the enumerated notations\n",
- value, attr->name, elem->name);
- ret = 0;
- }
- }
-
- /* Validity Constraint: Enumeration */
- if (attrDecl->atype == XML_ATTRIBUTE_ENUMERATION) {
- xmlEnumerationPtr tree = attrDecl->tree;
- while (tree != NULL) {
- if (xmlStrEqual(tree->name, value)) break;
- tree = tree->next;
- }
- if (tree == NULL) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Value \"%s\" for attribute %s of %s is not among the enumerated set\n",
- value, attr->name, elem->name);
- ret = 0;
- }
- }
-
- /* Fixed Attribute Default */
- if ((attrDecl->def == XML_ATTRIBUTE_FIXED) &&
- (!xmlStrEqual(attrDecl->defaultValue, value))) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Value for attribute %s of %s must be \"%s\"\n",
- attr->name, elem->name, attrDecl->defaultValue);
- ret = 0;
- }
-
- /* Extra check for the attribute value */
- ret &= xmlValidateAttributeValue2(ctxt, doc, attr->name,
- attrDecl->atype, value);
-
- return(ret);
-}
-
-/**
- * xmlValidateOneNamespace:
- * @ctxt: the validation context
- * @doc: a document instance
- * @elem: an element instance
- * @prefix: the namespace prefix
- * @ns: an namespace declaration instance
- * @value: the attribute value (without entities processing)
- *
- * Try to validate a single namespace declaration for an element
- * basically it does the following checks as described by the
- * XML-1.0 recommendation:
- * - [ VC: Attribute Value Type ]
- * - [ VC: Fixed Attribute Default ]
- * - [ VC: Entity Name ]
- * - [ VC: Name Token ]
- * - [ VC: ID ]
- * - [ VC: IDREF ]
- * - [ VC: Entity Name ]
- * - [ VC: Notation Attributes ]
- *
- * The ID/IDREF uniqueness and matching are done separately
- *
- * returns 1 if valid or 0 otherwise
- */
-
-int
-xmlValidateOneNamespace(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
-xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) {
- /* xmlElementPtr elemDecl; */
- xmlAttributePtr attrDecl = NULL;
- int val;
- int ret = 1;
-
- CHECK_DTD;
- if ((elem == NULL) || (elem->name == NULL)) return(0);
- if ((ns == NULL) || (ns->href == NULL)) return(0);
-
- if (prefix != NULL) {
- xmlChar qname[500];
- snprintf((char *) qname, sizeof(qname), "%s:%s",
- prefix, elem->name);
- qname[sizeof(qname) - 1] = 0;
- if (ns->prefix != NULL) {
- attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, qname,
- ns->prefix, BAD_CAST "xmlns");
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, qname,
- ns->prefix, BAD_CAST "xmlns");
- } else {
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, qname,
- BAD_CAST "xmlns");
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, qname,
- BAD_CAST "xmlns");
- }
- }
- if (attrDecl == NULL) {
- if (ns->prefix != NULL) {
- attrDecl = xmlGetDtdQAttrDesc(doc->intSubset, elem->name,
- ns->prefix, BAD_CAST "xmlns");
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdQAttrDesc(doc->extSubset, elem->name,
- ns->prefix, BAD_CAST "xmlns");
- } else {
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset,
- elem->name, BAD_CAST "xmlns");
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset,
- elem->name, BAD_CAST "xmlns");
- }
- }
-
-
- /* Validity Constraint: Attribute Value Type */
- if (attrDecl == NULL) {
- VECTXT(ctxt, elem);
- if (ns->prefix != NULL) {
- VERROR(ctxt->userData,
- "No declaration for attribute xmlns:%s of element %s\n",
- ns->prefix, elem->name);
- } else {
- VERROR(ctxt->userData,
- "No declaration for attribute xmlns of element %s\n",
- elem->name);
- }
- return(0);
- }
-
- val = xmlValidateAttributeValue(attrDecl->atype, value);
- if (val == 0) {
- VECTXT(ctxt, elem);
- if (ns->prefix != NULL) {
- VERROR(ctxt->userData,
- "Syntax of value for attribute xmlns:%s of %s is not valid\n",
- ns->prefix, elem->name);
- } else {
- VERROR(ctxt->userData,
- "Syntax of value for attribute xmlns of %s is not valid\n",
- elem->name);
- }
- ret = 0;
- }
-
- /* Validity constraint: Fixed Attribute Default */
- if (attrDecl->def == XML_ATTRIBUTE_FIXED) {
- if (!xmlStrEqual(value, attrDecl->defaultValue)) {
- VECTXT(ctxt, elem);
- if (ns->prefix != NULL) {
- VERROR(ctxt->userData,
- "Value for attribute xmlns:%s of %s is different from default \"%s\"\n",
- ns->prefix, elem->name, attrDecl->defaultValue);
- } else {
- VERROR(ctxt->userData,
- "Value for attribute xmlns of %s is different from default \"%s\"\n",
- elem->name, attrDecl->defaultValue);
- }
- ret = 0;
- }
- }
-
- /* Validity Constraint: ID uniqueness */
- if (attrDecl->atype == XML_ATTRIBUTE_ID) {
- if (xmlAddID(ctxt, doc, value, (xmlAttrPtr) ns) == NULL)
- ret = 0;
- }
-
- if ((attrDecl->atype == XML_ATTRIBUTE_IDREF) ||
- (attrDecl->atype == XML_ATTRIBUTE_IDREFS)) {
- if (xmlAddRef(ctxt, doc, value, (xmlAttrPtr) ns) == NULL)
- ret = 0;
- }
-
- /* Validity Constraint: Notation Attributes */
- if (attrDecl->atype == XML_ATTRIBUTE_NOTATION) {
- xmlEnumerationPtr tree = attrDecl->tree;
- xmlNotationPtr nota;
-
- /* First check that the given NOTATION was declared */
- nota = xmlGetDtdNotationDesc(doc->intSubset, value);
- if (nota == NULL)
- nota = xmlGetDtdNotationDesc(doc->extSubset, value);
-
- if (nota == NULL) {
- VECTXT(ctxt, elem);
- if (ns->prefix != NULL) {
- VERROR(ctxt->userData,
- "Value \"%s\" for attribute xmlns:%s of %s is not a declared Notation\n",
- value, ns->prefix, elem->name);
- } else {
- VERROR(ctxt->userData,
- "Value \"%s\" for attribute xmlns of %s is not a declared Notation\n",
- value, elem->name);
- }
- ret = 0;
- }
-
- /* Second, verify that it's among the list */
- while (tree != NULL) {
- if (xmlStrEqual(tree->name, value)) break;
- tree = tree->next;
- }
- if (tree == NULL) {
- VECTXT(ctxt, elem);
- if (ns->prefix != NULL) {
- VERROR(ctxt->userData,
-"Value \"%s\" for attribute xmlns:%s of %s is not among the enumerated notations\n",
- value, ns->prefix, elem->name);
- } else {
- VERROR(ctxt->userData,
-"Value \"%s\" for attribute xmlns of %s is not among the enumerated notations\n",
- value, elem->name);
- }
- ret = 0;
- }
- }
-
- /* Validity Constraint: Enumeration */
- if (attrDecl->atype == XML_ATTRIBUTE_ENUMERATION) {
- xmlEnumerationPtr tree = attrDecl->tree;
- while (tree != NULL) {
- if (xmlStrEqual(tree->name, value)) break;
- tree = tree->next;
- }
- if (tree == NULL) {
- VECTXT(ctxt, elem);
- if (ns->prefix != NULL) {
- VERROR(ctxt->userData,
-"Value \"%s\" for attribute xmlns:%s of %s is not among the enumerated set\n",
- value, ns->prefix, elem->name);
- } else {
- VERROR(ctxt->userData,
-"Value \"%s\" for attribute xmlns of %s is not among the enumerated set\n",
- value, elem->name);
- }
- ret = 0;
- }
- }
-
- /* Fixed Attribute Default */
- if ((attrDecl->def == XML_ATTRIBUTE_FIXED) &&
- (!xmlStrEqual(attrDecl->defaultValue, value))) {
- VECTXT(ctxt, elem);
- if (ns->prefix != NULL) {
- VERROR(ctxt->userData,
- "Value for attribute xmlns:%s of %s must be \"%s\"\n",
- ns->prefix, elem->name, attrDecl->defaultValue);
- } else {
- VERROR(ctxt->userData,
- "Value for attribute xmlns of %s must be \"%s\"\n",
- elem->name, attrDecl->defaultValue);
- }
- ret = 0;
- }
-
- /* Extra check for the attribute value */
- if (ns->prefix != NULL) {
- ret &= xmlValidateAttributeValue2(ctxt, doc, ns->prefix,
- attrDecl->atype, value);
- } else {
- ret &= xmlValidateAttributeValue2(ctxt, doc, BAD_CAST "xmlns",
- attrDecl->atype, value);
- }
-
- return(ret);
-}
-
-#ifndef LIBXML_REGEXP_ENABLED
-/**
- * xmlValidateSkipIgnorable:
- * @ctxt: the validation context
- * @child: the child list
- *
- * Skip ignorable elements w.r.t. the validation process
- *
- * returns the first element to consider for validation of the content model
- */
-
-static xmlNodePtr
-xmlValidateSkipIgnorable(xmlNodePtr child) {
- while (child != NULL) {
- switch (child->type) {
- /* These things are ignored (skipped) during validation. */
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- child = child->next;
- break;
- case XML_TEXT_NODE:
- if (xmlIsBlankNode(child))
- child = child->next;
- else
- return(child);
- break;
- /* keep current node */
- default:
- return(child);
- }
- }
- return(child);
-}
-
-/**
- * xmlValidateElementType:
- * @ctxt: the validation context
- *
- * Try to validate the content model of an element internal function
- *
- * returns 1 if valid or 0 ,-1 in case of error, -2 if an entity
- * reference is found and -3 if the validation succeeded but
- * the content model is not determinist.
- */
-
-static int
-xmlValidateElementType(xmlValidCtxtPtr ctxt) {
- int ret = -1;
- int determinist = 1;
-
- NODE = xmlValidateSkipIgnorable(NODE);
- if ((NODE == NULL) && (CONT == NULL))
- return(1);
- if ((NODE == NULL) &&
- ((CONT->ocur == XML_ELEMENT_CONTENT_MULT) ||
- (CONT->ocur == XML_ELEMENT_CONTENT_OPT))) {
- return(1);
- }
- if (CONT == NULL) return(-1);
- if ((NODE != NULL) && (NODE->type == XML_ENTITY_REF_NODE))
- return(-2);
-
- /*
- * We arrive here when more states need to be examined
- */
-cont:
-
- /*
- * We just recovered from a rollback generated by a possible
- * epsilon transition, go directly to the analysis phase
- */
- if (STATE == ROLLBACK_PARENT) {
- DEBUG_VALID_MSG("restored parent branch");
- DEBUG_VALID_STATE(NODE, CONT)
- ret = 1;
- goto analyze;
- }
-
- DEBUG_VALID_STATE(NODE, CONT)
- /*
- * we may have to save a backup state here. This is the equivalent
- * of handling epsilon transition in NFAs.
- */
- if ((CONT != NULL) &&
- ((CONT->parent == NULL) ||
- (CONT->parent->type != XML_ELEMENT_CONTENT_OR)) &&
- ((CONT->ocur == XML_ELEMENT_CONTENT_MULT) ||
- (CONT->ocur == XML_ELEMENT_CONTENT_OPT) ||
- ((CONT->ocur == XML_ELEMENT_CONTENT_PLUS) && (OCCURRENCE)))) {
- DEBUG_VALID_MSG("saving parent branch");
- if (vstateVPush(ctxt, CONT, NODE, DEPTH, OCCURS, ROLLBACK_PARENT) < 0)
- return(0);
- }
-
-
- /*
- * Check first if the content matches
- */
- switch (CONT->type) {
- case XML_ELEMENT_CONTENT_PCDATA:
- if (NODE == NULL) {
- DEBUG_VALID_MSG("pcdata failed no node");
- ret = 0;
- break;
- }
- if (NODE->type == XML_TEXT_NODE) {
- DEBUG_VALID_MSG("pcdata found, skip to next");
- /*
- * go to next element in the content model
- * skipping ignorable elems
- */
- do {
- NODE = NODE->next;
- NODE = xmlValidateSkipIgnorable(NODE);
- if ((NODE != NULL) &&
- (NODE->type == XML_ENTITY_REF_NODE))
- return(-2);
- } while ((NODE != NULL) &&
- ((NODE->type != XML_ELEMENT_NODE) &&
- (NODE->type != XML_TEXT_NODE) &&
- (NODE->type != XML_CDATA_SECTION_NODE)));
- ret = 1;
- break;
- } else {
- DEBUG_VALID_MSG("pcdata failed");
- ret = 0;
- break;
- }
- break;
- case XML_ELEMENT_CONTENT_ELEMENT:
- if (NODE == NULL) {
- DEBUG_VALID_MSG("element failed no node");
- ret = 0;
- break;
- }
- ret = ((NODE->type == XML_ELEMENT_NODE) &&
- (xmlStrEqual(NODE->name, CONT->name)));
- if (ret == 1) {
- if ((NODE->ns == NULL) || (NODE->ns->prefix == NULL)) {
- ret = (CONT->prefix == NULL);
- } else if (CONT->prefix == NULL) {
- ret = 0;
- } else {
- ret = xmlStrEqual(NODE->ns->prefix, CONT->prefix);
- }
- }
- if (ret == 1) {
- DEBUG_VALID_MSG("element found, skip to next");
- /*
- * go to next element in the content model
- * skipping ignorable elems
- */
- do {
- NODE = NODE->next;
- NODE = xmlValidateSkipIgnorable(NODE);
- if ((NODE != NULL) &&
- (NODE->type == XML_ENTITY_REF_NODE))
- return(-2);
- } while ((NODE != NULL) &&
- ((NODE->type != XML_ELEMENT_NODE) &&
- (NODE->type != XML_TEXT_NODE) &&
- (NODE->type != XML_CDATA_SECTION_NODE)));
- } else {
- DEBUG_VALID_MSG("element failed");
- ret = 0;
- break;
- }
- break;
- case XML_ELEMENT_CONTENT_OR:
- /*
- * Small optimization.
- */
- if (CONT->c1->type == XML_ELEMENT_CONTENT_ELEMENT) {
- if ((NODE == NULL) ||
- (!xmlStrEqual(NODE->name, CONT->c1->name))) {
- DEPTH++;
- CONT = CONT->c2;
- goto cont;
- }
- if ((NODE->ns == NULL) || (NODE->ns->prefix == NULL)) {
- ret = (CONT->c1->prefix == NULL);
- } else if (CONT->c1->prefix == NULL) {
- ret = 0;
- } else {
- ret = xmlStrEqual(NODE->ns->prefix, CONT->c1->prefix);
- }
- if (ret == 0) {
- DEPTH++;
- CONT = CONT->c2;
- goto cont;
- }
- }
-
- /*
- * save the second branch 'or' branch
- */
- DEBUG_VALID_MSG("saving 'or' branch");
- if (vstateVPush(ctxt, CONT->c2, NODE, (unsigned char)(DEPTH + 1),
- OCCURS, ROLLBACK_OR) < 0)
- return(-1);
- DEPTH++;
- CONT = CONT->c1;
- goto cont;
- case XML_ELEMENT_CONTENT_SEQ:
- /*
- * Small optimization.
- */
- if ((CONT->c1->type == XML_ELEMENT_CONTENT_ELEMENT) &&
- ((CONT->c1->ocur == XML_ELEMENT_CONTENT_OPT) ||
- (CONT->c1->ocur == XML_ELEMENT_CONTENT_MULT))) {
- if ((NODE == NULL) ||
- (!xmlStrEqual(NODE->name, CONT->c1->name))) {
- DEPTH++;
- CONT = CONT->c2;
- goto cont;
- }
- if ((NODE->ns == NULL) || (NODE->ns->prefix == NULL)) {
- ret = (CONT->c1->prefix == NULL);
- } else if (CONT->c1->prefix == NULL) {
- ret = 0;
- } else {
- ret = xmlStrEqual(NODE->ns->prefix, CONT->c1->prefix);
- }
- if (ret == 0) {
- DEPTH++;
- CONT = CONT->c2;
- goto cont;
- }
- }
- DEPTH++;
- CONT = CONT->c1;
- goto cont;
- }
-
- /*
- * At this point handle going up in the tree
- */
- if (ret == -1) {
- DEBUG_VALID_MSG("error found returning");
- return(ret);
- }
-analyze:
- while (CONT != NULL) {
- /*
- * First do the analysis depending on the occurrence model at
- * this level.
- */
- if (ret == 0) {
- switch (CONT->ocur) {
- xmlNodePtr cur;
-
- case XML_ELEMENT_CONTENT_ONCE:
- cur = ctxt->vstate->node;
- DEBUG_VALID_MSG("Once branch failed, rollback");
- if (vstateVPop(ctxt) < 0 ) {
- DEBUG_VALID_MSG("exhaustion, failed");
- return(0);
- }
- if (cur != ctxt->vstate->node)
- determinist = -3;
- goto cont;
- case XML_ELEMENT_CONTENT_PLUS:
- if (OCCURRENCE == 0) {
- cur = ctxt->vstate->node;
- DEBUG_VALID_MSG("Plus branch failed, rollback");
- if (vstateVPop(ctxt) < 0 ) {
- DEBUG_VALID_MSG("exhaustion, failed");
- return(0);
- }
- if (cur != ctxt->vstate->node)
- determinist = -3;
- goto cont;
- }
- DEBUG_VALID_MSG("Plus branch found");
- ret = 1;
- break;
- case XML_ELEMENT_CONTENT_MULT:
-#ifdef DEBUG_VALID_ALGO
- if (OCCURRENCE == 0) {
- DEBUG_VALID_MSG("Mult branch failed");
- } else {
- DEBUG_VALID_MSG("Mult branch found");
- }
-#endif
- ret = 1;
- break;
- case XML_ELEMENT_CONTENT_OPT:
- DEBUG_VALID_MSG("Option branch failed");
- ret = 1;
- break;
- }
- } else {
- switch (CONT->ocur) {
- case XML_ELEMENT_CONTENT_OPT:
- DEBUG_VALID_MSG("Option branch succeeded");
- ret = 1;
- break;
- case XML_ELEMENT_CONTENT_ONCE:
- DEBUG_VALID_MSG("Once branch succeeded");
- ret = 1;
- break;
- case XML_ELEMENT_CONTENT_PLUS:
- if (STATE == ROLLBACK_PARENT) {
- DEBUG_VALID_MSG("Plus branch rollback");
- ret = 1;
- break;
- }
- if (NODE == NULL) {
- DEBUG_VALID_MSG("Plus branch exhausted");
- ret = 1;
- break;
- }
- DEBUG_VALID_MSG("Plus branch succeeded, continuing");
- SET_OCCURRENCE;
- goto cont;
- case XML_ELEMENT_CONTENT_MULT:
- if (STATE == ROLLBACK_PARENT) {
- DEBUG_VALID_MSG("Mult branch rollback");
- ret = 1;
- break;
- }
- if (NODE == NULL) {
- DEBUG_VALID_MSG("Mult branch exhausted");
- ret = 1;
- break;
- }
- DEBUG_VALID_MSG("Mult branch succeeded, continuing");
- /* SET_OCCURRENCE; */
- goto cont;
- }
- }
- STATE = 0;
-
- /*
- * Then act accordingly at the parent level
- */
- RESET_OCCURRENCE;
- if (CONT->parent == NULL)
- break;
-
- switch (CONT->parent->type) {
- case XML_ELEMENT_CONTENT_PCDATA:
- DEBUG_VALID_MSG("Error: parent pcdata");
- return(-1);
- case XML_ELEMENT_CONTENT_ELEMENT:
- DEBUG_VALID_MSG("Error: parent element");
- return(-1);
- case XML_ELEMENT_CONTENT_OR:
- if (ret == 1) {
- DEBUG_VALID_MSG("Or succeeded");
- CONT = CONT->parent;
- DEPTH--;
- } else {
- DEBUG_VALID_MSG("Or failed");
- CONT = CONT->parent;
- DEPTH--;
- }
- break;
- case XML_ELEMENT_CONTENT_SEQ:
- if (ret == 0) {
- DEBUG_VALID_MSG("Sequence failed");
- CONT = CONT->parent;
- DEPTH--;
- } else if (CONT == CONT->parent->c1) {
- DEBUG_VALID_MSG("Sequence testing 2nd branch");
- CONT = CONT->parent->c2;
- goto cont;
- } else {
- DEBUG_VALID_MSG("Sequence succeeded");
- CONT = CONT->parent;
- DEPTH--;
- }
- }
- }
- if (NODE != NULL) {
- xmlNodePtr cur;
-
- cur = ctxt->vstate->node;
- DEBUG_VALID_MSG("Failed, remaining input, rollback");
- if (vstateVPop(ctxt) < 0 ) {
- DEBUG_VALID_MSG("exhaustion, failed");
- return(0);
- }
- if (cur != ctxt->vstate->node)
- determinist = -3;
- goto cont;
- }
- if (ret == 0) {
- xmlNodePtr cur;
-
- cur = ctxt->vstate->node;
- DEBUG_VALID_MSG("Failure, rollback");
- if (vstateVPop(ctxt) < 0 ) {
- DEBUG_VALID_MSG("exhaustion, failed");
- return(0);
- }
- if (cur != ctxt->vstate->node)
- determinist = -3;
- goto cont;
- }
- return(determinist);
-}
-#endif
-
-/**
- * xmlSnprintfElements:
- * @buf: an output buffer
- * @size: the size of the buffer
- * @content: An element
- * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
- *
- * This will dump the list of elements to the buffer
- * Intended just for the debug routine
- */
-static void
-xmlSnprintfElements(char *buf, int size, xmlNodePtr node, int glob) {
- xmlNodePtr cur;
- int len;
-
- if (node == NULL) return;
- if (glob) strcat(buf, "(");
- cur = node;
- while (cur != NULL) {
- len = strlen(buf);
- if (size - len < 50) {
- if ((size - len > 4) && (buf[len - 1] != '.'))
- strcat(buf, " ...");
- return;
- }
- switch (cur->type) {
- case XML_ELEMENT_NODE:
- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
- if (size - len < xmlStrlen(cur->ns->prefix) + 10) {
- if ((size - len > 4) && (buf[len - 1] != '.'))
- strcat(buf, " ...");
- return;
- }
- strcat(buf, (char *) cur->ns->prefix);
- strcat(buf, ":");
- }
- if (size - len < xmlStrlen(cur->name) + 10) {
- if ((size - len > 4) && (buf[len - 1] != '.'))
- strcat(buf, " ...");
- return;
- }
- strcat(buf, (char *) cur->name);
- if (cur->next != NULL)
- strcat(buf, " ");
- break;
- case XML_TEXT_NODE:
- if (xmlIsBlankNode(cur))
- break;
- case XML_CDATA_SECTION_NODE:
- case XML_ENTITY_REF_NODE:
- strcat(buf, "CDATA");
- if (cur->next != NULL)
- strcat(buf, " ");
- break;
- case XML_ATTRIBUTE_NODE:
- case XML_DOCUMENT_NODE:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- case XML_HTML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_NOTATION_NODE:
- case XML_NAMESPACE_DECL:
- strcat(buf, "???");
- if (cur->next != NULL)
- strcat(buf, " ");
- break;
- case XML_ENTITY_NODE:
- case XML_PI_NODE:
- case XML_DTD_NODE:
- case XML_COMMENT_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- break;
- }
- cur = cur->next;
- }
- if (glob) strcat(buf, ")");
-}
-
-/**
- * xmlValidateElementContent:
- * @ctxt: the validation context
- * @child: the child list
- * @elemDecl: pointer to the element declaration
- * @warn: emit the error message
- * @parent: the parent element (for error reporting)
- *
- * Try to validate the content model of an element
- *
- * returns 1 if valid or 0 if not and -1 in case of error
- */
-
-static int
-xmlValidateElementContent(xmlValidCtxtPtr ctxt, xmlNodePtr child,
- xmlElementPtr elemDecl, int warn, xmlNodePtr parent) {
- int ret = 1;
-#ifndef LIBXML_REGEXP_ENABLED
- xmlNodePtr repl = NULL, last = NULL, tmp;
-#endif
- xmlNodePtr cur;
- xmlElementContentPtr cont;
- const xmlChar *name;
-
- if (elemDecl == NULL)
- return(-1);
- cont = elemDecl->content;
- name = elemDecl->name;
-
-#ifdef LIBXML_REGEXP_ENABLED
- /* Build the regexp associated to the content model */
- if (elemDecl->contModel == NULL)
- ret = xmlValidBuildContentModel(ctxt, elemDecl);
- if (elemDecl->contModel == NULL) {
- ret = -1;
- } else {
- xmlRegExecCtxtPtr exec;
-
- ctxt->nodeMax = 0;
- ctxt->nodeNr = 0;
- ctxt->nodeTab = NULL;
- exec = xmlRegNewExecCtxt(elemDecl->contModel, NULL, NULL);
- if (exec != NULL) {
- cur = child;
- while (cur != NULL) {
- switch (cur->type) {
- case XML_ENTITY_REF_NODE:
- /*
- * Push the current node to be able to roll back
- * and process within the entity
- */
- if ((cur->children != NULL) &&
- (cur->children->children != NULL)) {
- nodeVPush(ctxt, cur);
- cur = cur->children->children;
- continue;
- }
- break;
- case XML_TEXT_NODE:
- if (xmlIsBlankNode(cur))
- break;
- ret = 0;
- goto fail;
- case XML_CDATA_SECTION_NODE:
- TODO
- ret = 0;
- goto fail;
- case XML_ELEMENT_NODE:
- if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
- xmlChar *QName;
- int len;
-
- len = xmlStrlen(cur->name) +
- xmlStrlen(cur->ns->prefix) + 2;
- QName = xmlMalloc(len);
- if (QName == NULL) {
- ret = -1;
- goto fail;
- }
- snprintf((char *) QName, len, "%s:%s",
- (char *)cur->ns->prefix,
- (char *)cur->name);
- ret = xmlRegExecPushString(exec, QName, NULL);
- xmlFree(QName);
- } else {
- ret = xmlRegExecPushString(exec, cur->name, NULL);
- }
- break;
- default:
- break;
- }
- /*
- * Switch to next element
- */
- cur = cur->next;
- while (cur == NULL) {
- cur = nodeVPop(ctxt);
- if (cur == NULL)
- break;
- cur = cur->next;
- }
- }
- ret = xmlRegExecPushString(exec, NULL, NULL);
-fail:
- xmlRegFreeExecCtxt(exec);
- }
- }
-#else /* LIBXML_REGEXP_ENABLED */
- /*
- * Allocate the stack
- */
- ctxt->vstateMax = 8;
- ctxt->vstateTab = (xmlValidState *) xmlMalloc(
- ctxt->vstateMax * sizeof(ctxt->vstateTab[0]));
- if (ctxt->vstateTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc failed !n");
- return(-1);
- }
- /*
- * The first entry in the stack is reserved to the current state
- */
- ctxt->nodeMax = 0;
- ctxt->nodeNr = 0;
- ctxt->nodeTab = NULL;
- ctxt->vstate = &ctxt->vstateTab[0];
- ctxt->vstateNr = 1;
- CONT = cont;
- NODE = child;
- DEPTH = 0;
- OCCURS = 0;
- STATE = 0;
- ret = xmlValidateElementType(ctxt);
- if ((ret == -3) && (warn)) {
- VWARNING(ctxt->userData,
- "Content model for Element %s is ambiguous\n", name);
- } else if (ret == -2) {
- /*
- * An entities reference appeared at this level.
- * Buid a minimal representation of this node content
- * sufficient to run the validation process on it
- */
- DEBUG_VALID_MSG("Found an entity reference, linearizing");
- cur = child;
- while (cur != NULL) {
- switch (cur->type) {
- case XML_ENTITY_REF_NODE:
- /*
- * Push the current node to be able to roll back
- * and process within the entity
- */
- if ((cur->children != NULL) &&
- (cur->children->children != NULL)) {
- nodeVPush(ctxt, cur);
- cur = cur->children->children;
- continue;
- }
- break;
- case XML_TEXT_NODE:
- if (xmlIsBlankNode(cur))
- break;
- /* no break on purpose */
- case XML_CDATA_SECTION_NODE:
- /* no break on purpose */
- case XML_ELEMENT_NODE:
- /*
- * Allocate a new node and minimally fills in
- * what's required
- */
- tmp = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
- if (tmp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlValidateElementContent : malloc failed\n");
- xmlFreeNodeList(repl);
- ret = -1;
- goto done;
- }
- tmp->type = cur->type;
- tmp->name = cur->name;
- tmp->ns = cur->ns;
- tmp->next = NULL;
- tmp->content = NULL;
- if (repl == NULL)
- repl = last = tmp;
- else {
- last->next = tmp;
- last = tmp;
- }
- if (cur->type == XML_CDATA_SECTION_NODE) {
- /*
- * E59 spaces in CDATA does not match the
- * nonterminal S
- */
- tmp->content = xmlStrdup(BAD_CAST "CDATA");
- }
- break;
- default:
- break;
- }
- /*
- * Switch to next element
- */
- cur = cur->next;
- while (cur == NULL) {
- cur = nodeVPop(ctxt);
- if (cur == NULL)
- break;
- cur = cur->next;
- }
- }
-
- /*
- * Relaunch the validation
- */
- ctxt->vstate = &ctxt->vstateTab[0];
- ctxt->vstateNr = 1;
- CONT = cont;
- NODE = repl;
- DEPTH = 0;
- OCCURS = 0;
- STATE = 0;
- ret = xmlValidateElementType(ctxt);
- }
-#endif /* LIBXML_REGEXP_ENABLED */
- if ((warn) && ((ret != 1) && (ret != -3))) {
- if ((ctxt != NULL) && (ctxt->warning != NULL)) {
- char expr[5000];
- char list[5000];
-
- expr[0] = 0;
- xmlSnprintfElementContent(expr, 5000, cont, 1);
- list[0] = 0;
-#ifndef LIBXML_REGEXP_ENABLED
- if (repl != NULL)
- xmlSnprintfElements(list, 5000, repl, 1);
- else
-#endif /* LIBXML_REGEXP_ENABLED */
- xmlSnprintfElements(list, 5000, child, 1);
-
- if (name != NULL) {
- if (parent != NULL) VECTXT(ctxt, parent);
- VERROR(ctxt->userData,
- "Element %s content does not follow the DTD\nExpecting %s, got %s\n",
- name, expr, list);
- } else {
- if (parent != NULL) VECTXT(ctxt, parent);
- VERROR(ctxt->userData,
- "Element content does not follow the DTD\nExpecting %s, got %s\n",
- expr, list);
- }
- } else {
- if (name != NULL) {
- if (parent != NULL) VECTXT(ctxt, parent);
- VERROR(ctxt->userData,
- "Element %s content does not follow the DTD\n",
- name);
- } else {
- if (parent != NULL) VECTXT(ctxt, parent);
- VERROR(ctxt->userData,
- "Element content does not follow the DTD\n");
- }
- }
- ret = 0;
- }
- if (ret == -3)
- ret = 1;
-
-#ifndef LIBXML_REGEXP_ENABLED
-done:
- /*
- * Deallocate the copy if done, and free up the validation stack
- */
- while (repl != NULL) {
- tmp = repl->next;
- xmlFree(repl);
- repl = tmp;
- }
- ctxt->vstateMax = 0;
- if (ctxt->vstateTab != NULL) {
- xmlFree(ctxt->vstateTab);
- ctxt->vstateTab = NULL;
- }
-#endif
- ctxt->nodeMax = 0;
- ctxt->nodeNr = 0;
- if (ctxt->nodeTab != NULL) {
- xmlFree(ctxt->nodeTab);
- ctxt->nodeTab = NULL;
- }
- return(ret);
-
-}
-
-/**
- * xmlValidateCdataElement:
- * @ctxt: the validation context
- * @doc: a document instance
- * @elem: an element instance
- *
- * Check that an element follows #CDATA
- *
- * returns 1 if valid or 0 otherwise
- */
-static int
-xmlValidateOneCdataElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
- xmlNodePtr elem) {
- int ret = 1;
- xmlNodePtr cur, child;
-
- if ((ctxt == NULL) || (doc == NULL) || (elem == NULL))
- return(0);
-
- child = elem->children;
-
- cur = child;
- while (cur != NULL) {
- switch (cur->type) {
- case XML_ENTITY_REF_NODE:
- /*
- * Push the current node to be able to roll back
- * and process within the entity
- */
- if ((cur->children != NULL) &&
- (cur->children->children != NULL)) {
- nodeVPush(ctxt, cur);
- cur = cur->children->children;
- continue;
- }
- break;
- case XML_COMMENT_NODE:
- case XML_PI_NODE:
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- break;
- default:
- ret = 0;
- goto done;
- }
- /*
- * Switch to next element
- */
- cur = cur->next;
- while (cur == NULL) {
- cur = nodeVPop(ctxt);
- if (cur == NULL)
- break;
- cur = cur->next;
- }
- }
-done:
- ctxt->nodeMax = 0;
- ctxt->nodeNr = 0;
- if (ctxt->nodeTab != NULL) {
- xmlFree(ctxt->nodeTab);
- ctxt->nodeTab = NULL;
- }
- return(ret);
-}
-
-/**
- * xmlValidateOneElement:
- * @ctxt: the validation context
- * @doc: a document instance
- * @elem: an element instance
- *
- * Try to validate a single element and it's attributes,
- * basically it does the following checks as described by the
- * XML-1.0 recommendation:
- * - [ VC: Element Valid ]
- * - [ VC: Required Attribute ]
- * Then call xmlValidateOneAttribute() for each attribute present.
- *
- * The ID/IDREF checkings are done separately
- *
- * returns 1 if valid or 0 otherwise
- */
-
-int
-xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
- xmlNodePtr elem) {
- xmlElementPtr elemDecl = NULL;
- xmlElementContentPtr cont;
- xmlAttributePtr attr;
- xmlNodePtr child;
- int ret = 1, tmp;
- const xmlChar *name;
- const xmlChar *prefix = NULL;
- int extsubset = 0;
-
- CHECK_DTD;
-
- if (elem == NULL) return(0);
- switch (elem->type) {
- case XML_ATTRIBUTE_NODE:
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Attribute element not expected here\n");
- return(0);
- case XML_TEXT_NODE:
- if (elem->children != NULL) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData, "Text element has childs !\n");
- return(0);
- }
- if (elem->properties != NULL) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData, "Text element has attributes !\n");
- return(0);
- }
- if (elem->ns != NULL) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData, "Text element has namespace !\n");
- return(0);
- }
- if (elem->nsDef != NULL) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Text element carries namespace definitions !\n");
- return(0);
- }
- if (elem->content == NULL) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Text element has no content !\n");
- return(0);
- }
- return(1);
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- return(1);
- case XML_CDATA_SECTION_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- return(1);
- case XML_ENTITY_NODE:
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Entity element not expected here\n");
- return(0);
- case XML_NOTATION_NODE:
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Notation element not expected here\n");
- return(0);
- case XML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Document element not expected here\n");
- return(0);
- case XML_HTML_DOCUMENT_NODE:
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "\n");
- return(0);
- case XML_ELEMENT_NODE:
- break;
- default:
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "unknown element type %d\n", elem->type);
- return(0);
- }
- if (elem->name == NULL) return(0);
-
- /*
- * Fetch the declaration for the qualified name
- */
- if ((elem->ns != NULL) && (elem->ns->prefix != NULL))
- prefix = elem->ns->prefix;
-
- if (prefix != NULL) {
- elemDecl = xmlGetDtdQElementDesc(doc->intSubset,
- elem->name, prefix);
- if ((elemDecl == NULL) && (doc->extSubset != NULL)) {
- elemDecl = xmlGetDtdQElementDesc(doc->extSubset,
- elem->name, prefix);
- if (elemDecl != NULL)
- extsubset = 1;
- }
- }
-
- /*
- * Fetch the declaration for the non qualified name
- * This is "non-strict" validation should be done on the
- * full QName but in that case being flexible makes sense.
- */
- if (elemDecl == NULL) {
- elemDecl = xmlGetDtdElementDesc(doc->intSubset, elem->name);
- if ((elemDecl == NULL) && (doc->extSubset != NULL)) {
- elemDecl = xmlGetDtdElementDesc(doc->extSubset, elem->name);
- if (elemDecl != NULL)
- extsubset = 1;
- }
- }
- if (elemDecl == NULL) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData, "No declaration for element %s\n",
- elem->name);
- return(0);
- }
-
- /* Check that the element content matches the definition */
- switch (elemDecl->etype) {
- case XML_ELEMENT_TYPE_UNDEFINED:
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData, "No declaration for element %s\n",
- elem->name);
- return(0);
- case XML_ELEMENT_TYPE_EMPTY:
- if (elem->children != NULL) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Element %s was declared EMPTY this one has content\n",
- elem->name);
- ret = 0;
- }
- break;
- case XML_ELEMENT_TYPE_ANY:
- /* I don't think anything is required then */
- break;
- case XML_ELEMENT_TYPE_MIXED:
-
- /* simple case of declared as #PCDATA */
- if ((elemDecl->content != NULL) &&
- (elemDecl->content->type == XML_ELEMENT_CONTENT_PCDATA)) {
- ret = xmlValidateOneCdataElement(ctxt, doc, elem);
- if (!ret) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Element %s was declared #PCDATA but contains non text nodes\n",
- elem->name);
- }
- break;
- }
- child = elem->children;
- /* Hum, this start to get messy */
- while (child != NULL) {
- if (child->type == XML_ELEMENT_NODE) {
- name = child->name;
- if ((child->ns != NULL) && (child->ns->prefix != NULL)) {
- xmlChar qname[500];
- snprintf((char *) qname, sizeof(qname), "%s:%s",
- child->ns->prefix, child->name);
- qname[sizeof(qname) - 1] = 0;
- cont = elemDecl->content;
- while (cont != NULL) {
- if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) {
- if (xmlStrEqual(cont->name, qname)) break;
- } else if ((cont->type == XML_ELEMENT_CONTENT_OR) &&
- (cont->c1 != NULL) &&
- (cont->c1->type == XML_ELEMENT_CONTENT_ELEMENT)){
- if (xmlStrEqual(cont->c1->name, qname)) break;
- } else if ((cont->type != XML_ELEMENT_CONTENT_OR) ||
- (cont->c1 == NULL) ||
- (cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)){
- /* Internal error !!! */
- xmlGenericError(xmlGenericErrorContext,
- "Internal: MIXED struct bad\n");
- break;
- }
- cont = cont->c2;
- }
- if (cont != NULL)
- goto child_ok;
- }
- cont = elemDecl->content;
- while (cont != NULL) {
- if (cont->type == XML_ELEMENT_CONTENT_ELEMENT) {
- if (xmlStrEqual(cont->name, name)) break;
- } else if ((cont->type == XML_ELEMENT_CONTENT_OR) &&
- (cont->c1 != NULL) &&
- (cont->c1->type == XML_ELEMENT_CONTENT_ELEMENT)) {
- if (xmlStrEqual(cont->c1->name, name)) break;
- } else if ((cont->type != XML_ELEMENT_CONTENT_OR) ||
- (cont->c1 == NULL) ||
- (cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)) {
- /* Internal error !!! */
- xmlGenericError(xmlGenericErrorContext,
- "Internal: MIXED struct bad\n");
- break;
- }
- cont = cont->c2;
- }
- if (cont == NULL) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Element %s is not declared in %s list of possible children\n",
- name, elem->name);
- ret = 0;
- }
- }
-child_ok:
- child = child->next;
- }
- break;
- case XML_ELEMENT_TYPE_ELEMENT:
- if ((doc->standalone == 1) && (extsubset == 1)) {
- /*
- * VC: Standalone Document Declaration
- * - element types with element content, if white space
- * occurs directly within any instance of those types.
- */
- child = elem->children;
- while (child != NULL) {
- if (child->type == XML_TEXT_NODE) {
- const xmlChar *content = child->content;
-
- while (IS_BLANK(*content))
- content++;
- if (*content == 0) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
-"standalone: %s declared in the external subset contains white spaces nodes\n",
- elem->name);
- ret = 0;
- break;
- }
- }
- child =child->next;
- }
- }
- child = elem->children;
- cont = elemDecl->content;
- tmp = xmlValidateElementContent(ctxt, child, elemDecl, 1, elem);
- if (tmp <= 0)
- ret = tmp;
- break;
- }
-
- /* [ VC: Required Attribute ] */
- attr = elemDecl->attributes;
- while (attr != NULL) {
- if (attr->def == XML_ATTRIBUTE_REQUIRED) {
- int qualified = -1;
-
- if ((attr->prefix == NULL) &&
- (xmlStrEqual(attr->name, BAD_CAST "xmlns"))) {
- xmlNsPtr ns;
-
- ns = elem->nsDef;
- while (ns != NULL) {
- if (ns->prefix == NULL)
- goto found;
- ns = ns->next;
- }
- } else if (xmlStrEqual(attr->prefix, BAD_CAST "xmlns")) {
- xmlNsPtr ns;
-
- ns = elem->nsDef;
- while (ns != NULL) {
- if (xmlStrEqual(attr->name, ns->prefix))
- goto found;
- ns = ns->next;
- }
- } else {
- xmlAttrPtr attrib;
-
- attrib = elem->properties;
- while (attrib != NULL) {
- if (xmlStrEqual(attrib->name, attr->name)) {
- if (attr->prefix != NULL) {
- xmlNsPtr nameSpace = attrib->ns;
-
- if (nameSpace == NULL)
- nameSpace = elem->ns;
- /*
- * qualified names handling is problematic, having a
- * different prefix should be possible but DTDs don't
- * allow to define the URI instead of the prefix :-(
- */
- if (nameSpace == NULL) {
- if (qualified < 0)
- qualified = 0;
- } else if (!xmlStrEqual(nameSpace->prefix,
- attr->prefix)) {
- if (qualified < 1)
- qualified = 1;
- } else
- goto found;
- } else {
- /*
- * We should allow applications to define namespaces
- * for their application even if the DTD doesn't
- * carry one, otherwise, basically we would always
- * break.
- */
- goto found;
- }
- }
- attrib = attrib->next;
- }
- }
- if (qualified == -1) {
- if (attr->prefix == NULL) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Element %s does not carry attribute %s\n",
- elem->name, attr->name);
- ret = 0;
- } else {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Element %s does not carry attribute %s:%s\n",
- elem->name, attr->prefix,attr->name);
- ret = 0;
- }
- } else if (qualified == 0) {
- VWARNING(ctxt->userData,
- "Element %s required attribute %s:%s has no prefix\n",
- elem->name, attr->prefix,attr->name);
- } else if (qualified == 1) {
- VWARNING(ctxt->userData,
- "Element %s required attribute %s:%s has different prefix\n",
- elem->name, attr->prefix,attr->name);
- }
- } else if (attr->def == XML_ATTRIBUTE_FIXED) {
- /*
- * Special tests checking #FIXED namespace declarations
- * have the right value since this is not done as an
- * attribute checking
- */
- if ((attr->prefix == NULL) &&
- (xmlStrEqual(attr->name, BAD_CAST "xmlns"))) {
- xmlNsPtr ns;
-
- ns = elem->nsDef;
- while (ns != NULL) {
- if (ns->prefix == NULL) {
- if (!xmlStrEqual(attr->defaultValue, ns->href)) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Element %s namespace name for default namespace does not match the DTD\n",
- elem->name);
- ret = 0;
- }
- goto found;
- }
- ns = ns->next;
- }
- } else if (xmlStrEqual(attr->prefix, BAD_CAST "xmlns")) {
- xmlNsPtr ns;
-
- ns = elem->nsDef;
- while (ns != NULL) {
- if (xmlStrEqual(attr->name, ns->prefix)) {
- if (!xmlStrEqual(attr->defaultValue, ns->href)) {
- VECTXT(ctxt, elem);
- VERROR(ctxt->userData,
- "Element %s namespace name for %s does not match the DTD\n",
- elem->name, ns->prefix);
- ret = 0;
- }
- goto found;
- }
- ns = ns->next;
- }
- }
- }
-found:
- attr = attr->nexth;
- }
- return(ret);
-}
-
-/**
- * xmlValidateRoot:
- * @ctxt: the validation context
- * @doc: a document instance
- *
- * Try to validate a the root element
- * basically it does the following check as described by the
- * XML-1.0 recommendation:
- * - [ VC: Root Element Type ]
- * it doesn't try to recurse or apply other check to the element
- *
- * returns 1 if valid or 0 otherwise
- */
-
-int
-xmlValidateRoot(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
- xmlNodePtr root;
- if (doc == NULL) return(0);
-
- root = xmlDocGetRootElement(doc);
- if ((root == NULL) || (root->name == NULL)) {
- VERROR(ctxt->userData, "Not valid: no root element\n");
- return(0);
- }
-
- /*
- * When doing post validation against a separate DTD, those may
- * no internal subset has been generated
- */
- if ((doc->intSubset != NULL) &&
- (doc->intSubset->name != NULL)) {
- /*
- * Check first the document root against the NQName
- */
- if (!xmlStrEqual(doc->intSubset->name, root->name)) {
- if ((root->ns != NULL) && (root->ns->prefix != NULL)) {
- xmlChar qname[500];
- snprintf((char *) qname, sizeof(qname), "%s:%s",
- root->ns->prefix, root->name);
- qname[sizeof(qname) - 1] = 0;
- if (xmlStrEqual(doc->intSubset->name, qname))
- goto name_ok;
- }
- if ((xmlStrEqual(doc->intSubset->name, BAD_CAST "HTML")) &&
- (xmlStrEqual(root->name, BAD_CAST "html")))
- goto name_ok;
- VECTXT(ctxt, root);
- VERROR(ctxt->userData,
- "Not valid: root and DTD name do not match '%s' and '%s'\n",
- root->name, doc->intSubset->name);
- return(0);
-
- }
- }
-name_ok:
- return(1);
-}
-
-
-/**
- * xmlValidateElement:
- * @ctxt: the validation context
- * @doc: a document instance
- * @elem: an element instance
- *
- * Try to validate the subtree under an element
- *
- * returns 1 if valid or 0 otherwise
- */
-
-int
-xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr elem) {
- xmlNodePtr child;
- xmlAttrPtr attr;
- xmlChar *value;
- int ret = 1;
-
- if (elem == NULL) return(0);
-
- /*
- * XInclude elements were added after parsing in the infoset,
- * they don't really mean anything validation wise.
- */
- if ((elem->type == XML_XINCLUDE_START) ||
- (elem->type == XML_XINCLUDE_END))
- return(1);
-
- CHECK_DTD;
-
- /*
- * Entities references have to be handled separately
- */
- if (elem->type == XML_ENTITY_REF_NODE) {
- return(1);
- }
-
- ret &= xmlValidateOneElement(ctxt, doc, elem);
- attr = elem->properties;
- while(attr != NULL) {
- value = xmlNodeListGetString(doc, attr->children, 0);
- ret &= xmlValidateOneAttribute(ctxt, doc, elem, attr, value);
- if (value != NULL)
- xmlFree(value);
- attr= attr->next;
- }
- child = elem->children;
- while (child != NULL) {
- ret &= xmlValidateElement(ctxt, doc, child);
- child = child->next;
- }
-
- return(ret);
-}
-
-/**
- * xmlValidateRef:
- * @ref: A reference to be validated
- * @ctxt: Validation context
- * @name: Name of ID we are searching for
- *
- */
-static void
-xmlValidateRef(xmlRefPtr ref, xmlValidCtxtPtr ctxt,
- const xmlChar *name) {
- xmlAttrPtr id;
- xmlAttrPtr attr;
-
- if (ref == NULL)
- return;
- attr = ref->attr;
- if (attr == NULL)
- return;
- if (attr->atype == XML_ATTRIBUTE_IDREF) {
- id = xmlGetID(ctxt->doc, name);
- if (id == NULL) {
- VECTXT(ctxt, attr->parent);
- VERROR(ctxt->userData,
- "IDREF attribute %s references an unknown ID \"%s\"\n",
- attr->name, name);
- ctxt->valid = 0;
- }
- } else if (attr->atype == XML_ATTRIBUTE_IDREFS) {
- xmlChar *dup, *str = NULL, *cur, save;
-
- dup = xmlStrdup(name);
- if (dup == NULL) {
- ctxt->valid = 0;
- return;
- }
- cur = dup;
- while (*cur != 0) {
- str = cur;
- while ((*cur != 0) && (!IS_BLANK(*cur))) cur++;
- save = *cur;
- *cur = 0;
- id = xmlGetID(ctxt->doc, str);
- if (id == NULL) {
- VECTXT(ctxt, attr->parent);
- VERROR(ctxt->userData,
- "IDREFS attribute %s references an unknown ID \"%s\"\n",
- attr->name, str);
- ctxt->valid = 0;
- }
- if (save == 0)
- break;
- *cur = save;
- while (IS_BLANK(*cur)) cur++;
- }
- xmlFree(dup);
- }
-}
-
-/**
- * xmlWalkValidateList:
- * @data: Contents of current link
- * @user: Value supplied by the user
- *
- * Returns 0 to abort the walk or 1 to continue
- */
-static int
-xmlWalkValidateList(const void *data, const void *user)
-{
- xmlValidateMemoPtr memo = (xmlValidateMemoPtr)user;
- xmlValidateRef((xmlRefPtr)data, memo->ctxt, memo->name);
- return 1;
-}
-
-/**
- * xmlValidateCheckRefCallback:
- * @ref_list: List of references
- * @ctxt: Validation context
- * @name: Name of ID we are searching for
- *
- */
-static void
-xmlValidateCheckRefCallback(xmlListPtr ref_list, xmlValidCtxtPtr ctxt,
- const xmlChar *name) {
- xmlValidateMemo memo;
-
- if (ref_list == NULL)
- return;
- memo.ctxt = ctxt;
- memo.name = name;
-
- xmlListWalk(ref_list, xmlWalkValidateList, &memo);
-
-}
-
-/**
- * xmlValidateDocumentFinal:
- * @ctxt: the validation context
- * @doc: a document instance
- *
- * Does the final step for the document validation once all the
- * incremental validation steps have been completed
- *
- * basically it does the following checks described by the XML Rec
- *
- *
- * returns 1 if valid or 0 otherwise
- */
-
-int
-xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
- xmlRefTablePtr table;
-
- if (doc == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlValidateDocumentFinal: doc == NULL\n");
- return(0);
- }
-
- /*
- * Check all the NOTATION/NOTATIONS attributes
- */
- /*
- * Check all the ENTITY/ENTITIES attributes definition for validity
- */
- /*
- * Check all the IDREF/IDREFS attributes definition for validity
- */
- table = (xmlRefTablePtr) doc->refs;
- ctxt->doc = doc;
- ctxt->valid = 1;
- xmlHashScan(table, (xmlHashScanner) xmlValidateCheckRefCallback, ctxt);
- return(ctxt->valid);
-}
-
-/**
- * xmlValidateDtd:
- * @ctxt: the validation context
- * @doc: a document instance
- * @dtd: a dtd instance
- *
- * Try to validate the document against the dtd instance
- *
- * basically it does check all the definitions in the DtD.
- *
- * returns 1 if valid or 0 otherwise
- */
-
-int
-xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) {
- int ret;
- xmlDtdPtr oldExt;
- xmlNodePtr root;
-
- if (dtd == NULL) return(0);
- if (doc == NULL) return(0);
- oldExt = doc->extSubset;
- doc->extSubset = dtd;
- ret = xmlValidateRoot(ctxt, doc);
- if (ret == 0) {
- doc->extSubset = oldExt;
- return(ret);
- }
- if (doc->ids != NULL) {
- xmlFreeIDTable(doc->ids);
- doc->ids = NULL;
- }
- if (doc->refs != NULL) {
- xmlFreeRefTable(doc->refs);
- doc->refs = NULL;
- }
- root = xmlDocGetRootElement(doc);
- ret = xmlValidateElement(ctxt, doc, root);
- ret &= xmlValidateDocumentFinal(ctxt, doc);
- doc->extSubset = oldExt;
- return(ret);
-}
-
-static void
-xmlValidateNotationCallback(xmlEntityPtr cur, xmlValidCtxtPtr ctxt,
- const xmlChar *name ATTRIBUTE_UNUSED) {
- if (cur == NULL)
- return;
- if (cur->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
- xmlChar *notation = cur->content;
-
- if (notation != NULL) {
- int ret;
-
- ret = xmlValidateNotationUse(ctxt, cur->doc, notation);
- if (ret != 1) {
- ctxt->valid = 0;
- }
- }
- }
-}
-
-static void
-xmlValidateAttributeCallback(xmlAttributePtr cur, xmlValidCtxtPtr ctxt,
- const xmlChar *name ATTRIBUTE_UNUSED) {
- int ret;
- xmlDocPtr doc;
- xmlElementPtr elem;
-
- if (cur == NULL)
- return;
- switch (cur->atype) {
- case XML_ATTRIBUTE_CDATA:
- case XML_ATTRIBUTE_ID:
- case XML_ATTRIBUTE_IDREF :
- case XML_ATTRIBUTE_IDREFS:
- case XML_ATTRIBUTE_NMTOKEN:
- case XML_ATTRIBUTE_NMTOKENS:
- case XML_ATTRIBUTE_ENUMERATION:
- break;
- case XML_ATTRIBUTE_ENTITY:
- case XML_ATTRIBUTE_ENTITIES:
- case XML_ATTRIBUTE_NOTATION:
- if (cur->defaultValue != NULL) {
-
- ret = xmlValidateAttributeValue2(ctxt, ctxt->doc, cur->name,
- cur->atype, cur->defaultValue);
- if ((ret == 0) && (ctxt->valid == 1))
- ctxt->valid = 0;
- }
- if (cur->tree != NULL) {
- xmlEnumerationPtr tree = cur->tree;
- while (tree != NULL) {
- ret = xmlValidateAttributeValue2(ctxt, ctxt->doc,
- cur->name, cur->atype, tree->name);
- if ((ret == 0) && (ctxt->valid == 1))
- ctxt->valid = 0;
- tree = tree->next;
- }
- }
- }
- if (cur->atype == XML_ATTRIBUTE_NOTATION) {
- doc = cur->doc;
- if ((doc == NULL) || (cur->elem == NULL)) {
- VERROR(ctxt->userData,
- "xmlValidateAttributeCallback(%s): internal error\n",
- cur->name);
- return;
- }
- elem = xmlGetDtdElementDesc(doc->intSubset, cur->elem);
- if (elem == NULL)
- elem = xmlGetDtdElementDesc(doc->extSubset, cur->elem);
- if (elem == NULL) {
- VERROR(ctxt->userData,
- "attribute %s: could not find decl for element %s\n",
- cur->name, cur->elem);
- return;
- }
- if (elem->etype == XML_ELEMENT_TYPE_EMPTY) {
- VERROR(ctxt->userData,
- "NOTATION attribute %s declared for EMPTY element %s\n",
- cur->name, cur->elem);
- ctxt->valid = 0;
- }
- }
-}
-
-/**
- * xmlValidateDtdFinal:
- * @ctxt: the validation context
- * @doc: a document instance
- *
- * Does the final step for the dtds validation once all the
- * subsets have been parsed
- *
- * basically it does the following checks described by the XML Rec
- * - check that ENTITY and ENTITIES type attributes default or
- * possible values matches one of the defined entities.
- * - check that NOTATION type attributes default or
- * possible values matches one of the defined notations.
- *
- * returns 1 if valid or 0 if invalid and -1 if not well-formed
- */
-
-int
-xmlValidateDtdFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
- xmlDtdPtr dtd;
- xmlAttributeTablePtr table;
- xmlEntitiesTablePtr entities;
-
- if (doc == NULL) return(0);
- if ((doc->intSubset == NULL) && (doc->extSubset == NULL))
- return(0);
- ctxt->doc = doc;
- ctxt->valid = 1;
- dtd = doc->intSubset;
- if ((dtd != NULL) && (dtd->attributes != NULL)) {
- table = (xmlAttributeTablePtr) dtd->attributes;
- xmlHashScan(table, (xmlHashScanner) xmlValidateAttributeCallback, ctxt);
- }
- if ((dtd != NULL) && (dtd->entities != NULL)) {
- entities = (xmlEntitiesTablePtr) dtd->entities;
- xmlHashScan(entities, (xmlHashScanner) xmlValidateNotationCallback,
- ctxt);
- }
- dtd = doc->extSubset;
- if ((dtd != NULL) && (dtd->attributes != NULL)) {
- table = (xmlAttributeTablePtr) dtd->attributes;
- xmlHashScan(table, (xmlHashScanner) xmlValidateAttributeCallback, ctxt);
- }
- if ((dtd != NULL) && (dtd->entities != NULL)) {
- entities = (xmlEntitiesTablePtr) dtd->entities;
- xmlHashScan(entities, (xmlHashScanner) xmlValidateNotationCallback,
- ctxt);
- }
- return(ctxt->valid);
-}
-
-/**
- * xmlValidateDocument:
- * @ctxt: the validation context
- * @doc: a document instance
- *
- * Try to validate the document instance
- *
- * basically it does the all the checks described by the XML Rec
- * i.e. validates the internal and external subset (if present)
- * and validate the document tree.
- *
- * returns 1 if valid or 0 otherwise
- */
-
-int
-xmlValidateDocument(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
- int ret;
- xmlNodePtr root;
-
- if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) {
- VERROR(ctxt->userData, "no DTD found!\n" );
- return(0);
- }
- if ((doc->intSubset != NULL) && ((doc->intSubset->SystemID != NULL) ||
- (doc->intSubset->ExternalID != NULL)) && (doc->extSubset == NULL)) {
- doc->extSubset = xmlParseDTD(doc->intSubset->ExternalID,
- doc->intSubset->SystemID);
- if (doc->extSubset == NULL) {
- if (doc->intSubset->SystemID != NULL) {
- VERROR(ctxt->userData,
- "Could not load the external subset \"%s\"\n",
- doc->intSubset->SystemID);
- } else {
- VERROR(ctxt->userData,
- "Could not load the external subset \"%s\"\n",
- doc->intSubset->ExternalID);
- }
- return(0);
- }
- }
-
- if (doc->ids != NULL) {
- xmlFreeIDTable(doc->ids);
- doc->ids = NULL;
- }
- if (doc->refs != NULL) {
- xmlFreeRefTable(doc->refs);
- doc->refs = NULL;
- }
- ret = xmlValidateDtdFinal(ctxt, doc);
- if (!xmlValidateRoot(ctxt, doc)) return(0);
-
- root = xmlDocGetRootElement(doc);
- ret &= xmlValidateElement(ctxt, doc, root);
- ret &= xmlValidateDocumentFinal(ctxt, doc);
- return(ret);
-}
-
-
-/************************************************************************
- * *
- * Routines for dynamic validation editing *
- * *
- ************************************************************************/
-
-/**
- * xmlValidGetPotentialChildren:
- * @ctree: an element content tree
- * @list: an array to store the list of child names
- * @len: a pointer to the number of element in the list
- * @max: the size of the array
- *
- * Build/extend a list of potential children allowed by the content tree
- *
- * returns the number of element in the list, or -1 in case of error.
- */
-
-int
-xmlValidGetPotentialChildren(xmlElementContent *ctree, const xmlChar **list,
- int *len, int max) {
- int i;
-
- if ((ctree == NULL) || (list == NULL) || (len == NULL))
- return(-1);
- if (*len >= max) return(*len);
-
- switch (ctree->type) {
- case XML_ELEMENT_CONTENT_PCDATA:
- for (i = 0; i < *len;i++)
- if (xmlStrEqual(BAD_CAST "#PCDATA", list[i])) return(*len);
- list[(*len)++] = BAD_CAST "#PCDATA";
- break;
- case XML_ELEMENT_CONTENT_ELEMENT:
- for (i = 0; i < *len;i++)
- if (xmlStrEqual(ctree->name, list[i])) return(*len);
- list[(*len)++] = ctree->name;
- break;
- case XML_ELEMENT_CONTENT_SEQ:
- xmlValidGetPotentialChildren(ctree->c1, list, len, max);
- xmlValidGetPotentialChildren(ctree->c2, list, len, max);
- break;
- case XML_ELEMENT_CONTENT_OR:
- xmlValidGetPotentialChildren(ctree->c1, list, len, max);
- xmlValidGetPotentialChildren(ctree->c2, list, len, max);
- break;
- }
-
- return(*len);
-}
-
-/**
- * xmlValidGetValidElements:
- * @prev: an element to insert after
- * @next: an element to insert next
- * @list: an array to store the list of child names
- * @max: the size of the array
- *
- * This function returns the list of authorized children to insert
- * within an existing tree while respecting the validity constraints
- * forced by the Dtd. The insertion point is defined using @prev and
- * @next in the following ways:
- * to insert before 'node': xmlValidGetValidElements(node->prev, node, ...
- * to insert next 'node': xmlValidGetValidElements(node, node->next, ...
- * to replace 'node': xmlValidGetValidElements(node->prev, node->next, ...
- * to prepend a child to 'node': xmlValidGetValidElements(NULL, node->childs,
- * to append a child to 'node': xmlValidGetValidElements(node->last, NULL, ...
- *
- * pointers to the element names are inserted at the beginning of the array
- * and do not need to be freed.
- *
- * returns the number of element in the list, or -1 in case of error. If
- * the function returns the value @max the caller is invited to grow the
- * receiving array and retry.
- */
-
-int
-xmlValidGetValidElements(xmlNode *prev, xmlNode *next, const xmlChar **list,
- int max) {
- xmlValidCtxt vctxt;
- int nb_valid_elements = 0;
- const xmlChar *elements[256];
- int nb_elements = 0, i;
- const xmlChar *name;
-
- xmlNode *ref_node;
- xmlNode *parent;
- xmlNode *test_node;
-
- xmlNode *prev_next;
- xmlNode *next_prev;
- xmlNode *parent_childs;
- xmlNode *parent_last;
-
- xmlElement *element_desc;
-
- memset(&vctxt, 0, sizeof (xmlValidCtxt));
-
- if (prev == NULL && next == NULL)
- return(-1);
-
- if (list == NULL) return(-1);
- if (max <= 0) return(-1);
-
- nb_valid_elements = 0;
- ref_node = prev ? prev : next;
- parent = ref_node->parent;
-
- /*
- * Retrieves the parent element declaration
- */
- element_desc = xmlGetDtdElementDesc(parent->doc->intSubset,
- parent->name);
- if ((element_desc == NULL) && (parent->doc->extSubset != NULL))
- element_desc = xmlGetDtdElementDesc(parent->doc->extSubset,
- parent->name);
- if (element_desc == NULL) return(-1);
-
- /*
- * Do a backup of the current tree structure
- */
- prev_next = prev ? prev->next : NULL;
- next_prev = next ? next->prev : NULL;
- parent_childs = parent->children;
- parent_last = parent->last;
-
- /*
- * Creates a dummy node and insert it into the tree
- */
- test_node = xmlNewNode (NULL, BAD_CAST "<!dummy?>");
- test_node->doc = ref_node->doc;
- test_node->parent = parent;
- test_node->prev = prev;
- test_node->next = next;
- name = test_node->name;
-
- if (prev) prev->next = test_node;
- else parent->children = test_node;
-
- if (next) next->prev = test_node;
- else parent->last = test_node;
-
- /*
- * Insert each potential child node and check if the parent is
- * still valid
- */
- nb_elements = xmlValidGetPotentialChildren(element_desc->content,
- elements, &nb_elements, 256);
-
- for (i = 0;i < nb_elements;i++) {
- test_node->name = elements[i];
- if (xmlValidateOneElement(&vctxt, parent->doc, parent)) {
- int j;
-
- for (j = 0; j < nb_valid_elements;j++)
- if (xmlStrEqual(elements[i], list[j])) break;
- list[nb_valid_elements++] = elements[i];
- if (nb_valid_elements >= max) break;
- }
- }
-
- /*
- * Restore the tree structure
- */
- if (prev) prev->next = prev_next;
- if (next) next->prev = next_prev;
- parent->children = parent_childs;
- parent->last = parent_last;
-
- /*
- * Free up the dummy node
- */
- test_node->name = name;
- xmlFreeNode(test_node);
-
- return(nb_valid_elements);
-}
diff --git a/bundle/libxml/xinclude.c b/bundle/libxml/xinclude.c
deleted file mode 100644
index 78ee0427b2..0000000000
--- a/bundle/libxml/xinclude.c
+++ /dev/null
@@ -1,1729 +0,0 @@
-/*
- * xinclude.c : Code to implement XInclude processing
- *
- * World Wide Web Consortium W3C Last Call Working Draft 16 May 2001
- * http://www.w3.org/TR/2001/WD-xinclude-20010516/
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-/*
- * TODO: compute XPointers nodesets
- * TODO: add an node intermediate API and handle recursion at this level
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#include <string.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/uri.h>
-#include <libxml/xpointer.h>
-#include <libxml/parserInternals.h>
-#include <libxml/xmlerror.h>
-#include <libxml/encoding.h>
-#include <libxml/globals.h>
-
-#ifdef LIBXML_XINCLUDE_ENABLED
-#include <libxml/xinclude.h>
-
-#define XINCLUDE_NS (const xmlChar *) "http://www.w3.org/2001/XInclude"
-#define XINCLUDE_NODE (const xmlChar *) "include"
-#define XINCLUDE_FALLBACK (const xmlChar *) "fallback"
-#define XINCLUDE_HREF (const xmlChar *) "href"
-#define XINCLUDE_PARSE (const xmlChar *) "parse"
-#define XINCLUDE_PARSE_XML (const xmlChar *) "xml"
-#define XINCLUDE_PARSE_TEXT (const xmlChar *) "text"
-#define XINCLUDE_PARSE_ENCODING (const xmlChar *) "encoding"
-
-/* #define DEBUG_XINCLUDE */
-#ifdef DEBUG_XINCLUDE
-#ifdef LIBXML_DEBUG_ENABLED
-#include <libxml/debugXML.h>
-#endif
-#endif
-
-/************************************************************************
- * *
- * XInclude contexts handling *
- * *
- ************************************************************************/
-
-/*
- * An XInclude context
- */
-typedef xmlChar *xmlURL;
-
-typedef struct _xmlXIncludeRef xmlXIncludeRef;
-typedef xmlXIncludeRef *xmlXIncludeRefPtr;
-struct _xmlXIncludeRef {
- xmlChar *URI; /* the rully resolved resource URL */
- xmlChar *fragment; /* the fragment in the URI */
- xmlDocPtr doc; /* the parsed document */
- xmlNodePtr ref; /* the node making the reference in the source */
- xmlNodePtr inc; /* the included copy */
- int xml; /* xml or txt */
- int count; /* how many refs use that specific doc */
-};
-
-typedef struct _xmlXIncludeCtxt xmlXIncludeCtxt;
-typedef xmlXIncludeCtxt *xmlXIncludeCtxtPtr;
-struct _xmlXIncludeCtxt {
- xmlDocPtr doc; /* the source document */
- int incBase; /* the first include for this document */
- int incNr; /* number of includes */
- int incMax; /* size of includes tab */
- xmlXIncludeRefPtr *incTab; /* array of included references */
-
- int txtNr; /* number of unparsed documents */
- int txtMax; /* size of unparsed documents tab */
- xmlNodePtr *txtTab; /* array of unparsed text nodes */
- xmlURL *txturlTab; /* array of unparsed txtuments URLs */
-};
-
-static int
-xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc);
-
-/**
- * xmlXIncludeFreeRef:
- * @ref: the XInclude reference
- *
- * Free an XInclude reference
- */
-static void
-xmlXIncludeFreeRef(xmlXIncludeRefPtr ref) {
- if (ref == NULL)
- return;
-#ifdef DEBUG_XINCLUDE
- xmlGenericError(xmlGenericErrorContext, "Freeing ref\n");
-#endif
- if (ref->doc != NULL) {
-#ifdef DEBUG_XINCLUDE
- xmlGenericError(xmlGenericErrorContext, "Freeing doc %s\n", ref->URI);
-#endif
- xmlFreeDoc(ref->doc);
- }
- if (ref->URI != NULL)
- xmlFree(ref->URI);
- if (ref->fragment != NULL)
- xmlFree(ref->fragment);
- xmlFree(ref);
-}
-
-/**
- * xmlXIncludeNewRef:
- * @ctxt: the XInclude context
- * @URI: the resource URI
- *
- * Creates a new reference within an XInclude context
- *
- * Returns the new set
- */
-static xmlXIncludeRefPtr
-xmlXIncludeNewRef(xmlXIncludeCtxtPtr ctxt, const xmlChar *URI,
- xmlNodePtr ref) {
- xmlXIncludeRefPtr ret;
-
-#ifdef DEBUG_XINCLUDE
- xmlGenericError(xmlGenericErrorContext, "New ref %s\n", URI);
-#endif
- ret = (xmlXIncludeRefPtr) xmlMalloc(sizeof(xmlXIncludeRef));
- if (ret == NULL)
- return(NULL);
- memset(ret, 0, sizeof(xmlXIncludeRef));
- if (URI == NULL)
- ret->URI = NULL;
- else
- ret->URI = xmlStrdup(URI);
- ret->fragment = NULL;
- ret->ref = ref;
- ret->doc = 0;
- ret->count = 0;
- ret->xml = 0;
- ret->inc = NULL;
- if (ctxt->incMax == 0) {
- ctxt->incMax = 4;
- ctxt->incTab = (xmlXIncludeRefPtr *) xmlMalloc(ctxt->incMax *
- sizeof(ctxt->incTab[0]));
- if (ctxt->incTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc failed !\n");
- xmlXIncludeFreeRef(ret);
- return(NULL);
- }
- }
- if (ctxt->incNr >= ctxt->incMax) {
- ctxt->incMax *= 2;
- ctxt->incTab = (xmlXIncludeRefPtr *) xmlRealloc(ctxt->incTab,
- ctxt->incMax * sizeof(ctxt->incTab[0]));
- if (ctxt->incTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc failed !\n");
- xmlXIncludeFreeRef(ret);
- return(NULL);
- }
- }
- ctxt->incTab[ctxt->incNr++] = ret;
- return(ret);
-}
-
-/**
- * xmlXIncludeNewContext:
- * @doc: an XML Document
- *
- * Creates a new XInclude context
- *
- * Returns the new set
- */
-static xmlXIncludeCtxtPtr
-xmlXIncludeNewContext(xmlDocPtr doc) {
- xmlXIncludeCtxtPtr ret;
-
-#ifdef DEBUG_XINCLUDE
- xmlGenericError(xmlGenericErrorContext, "New context\n");
-#endif
- if (doc == NULL)
- return(NULL);
- ret = (xmlXIncludeCtxtPtr) xmlMalloc(sizeof(xmlXIncludeCtxt));
- if (ret == NULL)
- return(NULL);
- memset(ret, 0, sizeof(xmlXIncludeCtxt));
- ret->doc = doc;
- ret->incNr = 0;
- ret->incBase = 0;
- ret->incMax = 0;
- ret->incTab = NULL;
- return(ret);
-}
-
-/**
- * xmlXIncludeFreeContext:
- * @ctxt: the XInclude context
- *
- * Free an XInclude context
- */
-static void
-xmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) {
- int i;
-
-#ifdef DEBUG_XINCLUDE
- xmlGenericError(xmlGenericErrorContext, "Freeing context\n");
-#endif
- if (ctxt == NULL)
- return;
- for (i = 0;i < ctxt->incNr;i++) {
- if (ctxt->incTab[i] != NULL)
- xmlXIncludeFreeRef(ctxt->incTab[i]);
- }
- for (i = 0;i < ctxt->txtNr;i++) {
- if (ctxt->txturlTab[i] != NULL)
- xmlFree(ctxt->txturlTab[i]);
- }
- if (ctxt->incTab != NULL)
- xmlFree(ctxt->incTab);
- if (ctxt->txtTab != NULL)
- xmlFree(ctxt->txtTab);
- if (ctxt->txturlTab != NULL)
- xmlFree(ctxt->txturlTab);
- xmlFree(ctxt);
-}
-
-/**
- * xmlXIncludeAddNode:
- * @ctxt: the XInclude context
- * @cur: the new node
- *
- * Add a new node to process to an XInclude context
- */
-static int
-xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
- xmlXIncludeRefPtr ref;
- xmlURIPtr uri;
- xmlChar *URL;
- xmlChar *fragment = NULL;
- xmlChar *href;
- xmlChar *parse;
- xmlChar *base;
- xmlChar *URI;
- int xml = 1; /* default Issue 64 */
-
-
- if (ctxt == NULL)
- return(-1);
- if (cur == NULL)
- return(-1);
-
-#ifdef DEBUG_XINCLUDE
- xmlGenericError(xmlGenericErrorContext, "Add node\n");
-#endif
- /*
- * read the attributes
- */
- href = xmlGetNsProp(cur, XINCLUDE_NS, XINCLUDE_HREF);
- if (href == NULL) {
- href = xmlGetProp(cur, XINCLUDE_HREF);
- if (href == NULL) {
- xmlGenericError(xmlGenericErrorContext, "XInclude: no href\n");
- return(-1);
- }
- }
- parse = xmlGetNsProp(cur, XINCLUDE_NS, XINCLUDE_PARSE);
- if (parse == NULL) {
- parse = xmlGetProp(cur, XINCLUDE_PARSE);
- }
- if (parse != NULL) {
- if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
- xml = 1;
- else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
- xml = 0;
- else {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: invalid value %s for %s\n",
- parse, XINCLUDE_PARSE);
- if (href != NULL)
- xmlFree(href);
- if (parse != NULL)
- xmlFree(parse);
- return(-1);
- }
- }
-
- /*
- * compute the URI
- */
- base = xmlNodeGetBase(ctxt->doc, cur);
- if (base == NULL) {
- URI = xmlBuildURI(href, ctxt->doc->URL);
- } else {
- URI = xmlBuildURI(href, base);
- }
- if (URI == NULL) {
- xmlChar *escbase;
- xmlChar *eschref;
- /*
- * Some escaping may be needed
- */
- escbase = xmlURIEscape(base);
- eschref = xmlURIEscape(href);
- URI = xmlBuildURI(eschref, escbase);
- if (escbase != NULL)
- xmlFree(escbase);
- if (eschref != NULL)
- xmlFree(eschref);
- }
- if (parse != NULL)
- xmlFree(parse);
- if (href != NULL)
- xmlFree(href);
- if (base != NULL)
- xmlFree(base);
- if (URI == NULL) {
- xmlGenericError(xmlGenericErrorContext, "XInclude: failed build URL\n");
- return(-1);
- }
-
- /*
- * Check the URL and remove any fragment identifier
- */
- uri = xmlParseURI((const char *)URI);
- if (uri == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: invalid value URI %s\n", URI);
- return(-1);
- }
- if (uri->fragment != NULL) {
- fragment = (xmlChar *) uri->fragment;
- uri->fragment = NULL;
- }
- URL = xmlSaveUri(uri);
- xmlFreeURI(uri);
- xmlFree(URI);
- if (URL == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: invalid value URI %s\n", URI);
- if (fragment != NULL)
- xmlFree(fragment);
- return(-1);
- }
-
- ref = xmlXIncludeNewRef(ctxt, URL, cur);
- if (ref == NULL) {
- return(-1);
- }
- ref->fragment = fragment;
- ref->doc = NULL;
- ref->xml = xml;
- ref->count = 1;
- xmlFree(URL);
- return(0);
-}
-
-/**
- * xmlXIncludeRecurseDoc:
- * @ctxt: the XInclude context
- * @doc: the new document
- * @url: the associated URL
- *
- * The XInclude recursive nature is handled at this point.
- */
-static void
-xmlXIncludeRecurseDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc,
- const xmlURL url ATTRIBUTE_UNUSED) {
- xmlXIncludeCtxtPtr newctxt;
- int i;
-
-#ifdef DEBUG_XINCLUDE
- xmlGenericError(xmlGenericErrorContext, "Recursing in doc %s\n", doc->URL);
-#endif
- /*
- * Handle recursion here.
- */
-
- newctxt = xmlXIncludeNewContext(doc);
- if (newctxt != NULL) {
- /*
- * Copy the existing document set
- */
- newctxt->incMax = ctxt->incMax;
- newctxt->incNr = ctxt->incNr;
- newctxt->incTab = (xmlXIncludeRefPtr *) xmlMalloc(newctxt->incMax *
- sizeof(newctxt->incTab[0]));
- if (newctxt->incTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc failed !\n");
- xmlFree(newctxt);
- return;
- }
-
- /*
- * Inherit the documents already in use by others includes
- */
- newctxt->incBase = ctxt->incNr;
- for (i = 0;i < ctxt->incNr;i++) {
- newctxt->incTab[i] = ctxt->incTab[i];
- newctxt->incTab[i]->count++; /* prevent the recursion from
- freeing it */
- }
- xmlXIncludeDoProcess(newctxt, doc);
- for (i = 0;i < ctxt->incNr;i++) {
- newctxt->incTab[i]->count--;
- newctxt->incTab[i] = NULL;
- }
- xmlXIncludeFreeContext(newctxt);
- }
-#ifdef DEBUG_XINCLUDE
- xmlGenericError(xmlGenericErrorContext, "Done recursing in doc %s\n", url);
-#endif
-}
-
-/**
- * xmlXIncludeAddTxt:
- * @ctxt: the XInclude context
- * @txt: the new text node
- * @url: the associated URL
- *
- * Add a new txtument to the list
- */
-static void
-xmlXIncludeAddTxt(xmlXIncludeCtxtPtr ctxt, xmlNodePtr txt, const xmlURL url) {
-#ifdef DEBUG_XINCLUDE
- xmlGenericError(xmlGenericErrorContext, "Adding text %s\n", url);
-#endif
- if (ctxt->txtMax == 0) {
- ctxt->txtMax = 4;
- ctxt->txtTab = (xmlNodePtr *) xmlMalloc(ctxt->txtMax *
- sizeof(ctxt->txtTab[0]));
- if (ctxt->txtTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc failed !\n");
- return;
- }
- ctxt->txturlTab = (xmlURL *) xmlMalloc(ctxt->txtMax *
- sizeof(ctxt->txturlTab[0]));
- if (ctxt->txturlTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "malloc failed !\n");
- return;
- }
- }
- if (ctxt->txtNr >= ctxt->txtMax) {
- ctxt->txtMax *= 2;
- ctxt->txtTab = (xmlNodePtr *) xmlRealloc(ctxt->txtTab,
- ctxt->txtMax * sizeof(ctxt->txtTab[0]));
- if (ctxt->txtTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc failed !\n");
- return;
- }
- ctxt->txturlTab = (xmlURL *) xmlRealloc(ctxt->txturlTab,
- ctxt->txtMax * sizeof(ctxt->txturlTab[0]));
- if (ctxt->txturlTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "realloc failed !\n");
- return;
- }
- }
- ctxt->txtTab[ctxt->txtNr] = txt;
- ctxt->txturlTab[ctxt->txtNr] = xmlStrdup(url);
- ctxt->txtNr++;
-}
-
-/************************************************************************
- * *
- * Node copy with specific semantic *
- * *
- ************************************************************************/
-
-/**
- * xmlXIncludeCopyNode:
- * @ctxt: the XInclude context
- * @target: the document target
- * @source: the document source
- * @elem: the element
- *
- * Make a copy of the node while preserving the XInclude semantic
- * of the Infoset copy
- */
-static xmlNodePtr
-xmlXIncludeCopyNode(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
- xmlDocPtr source, xmlNodePtr elem) {
- xmlNodePtr result = NULL;
-
- if ((ctxt == NULL) || (target == NULL) || (source == NULL) ||
- (elem == NULL))
- return(NULL);
- if (elem->type == XML_DTD_NODE)
- return(NULL);
- result = xmlDocCopyNode(elem, target, 1);
- return(result);
-}
-
-/**
- * xmlXIncludeCopyNodeList:
- * @ctxt: the XInclude context
- * @target: the document target
- * @source: the document source
- * @elem: the element list
- *
- * Make a copy of the node list while preserving the XInclude semantic
- * of the Infoset copy
- */
-static xmlNodePtr
-xmlXIncludeCopyNodeList(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
- xmlDocPtr source, xmlNodePtr elem) {
- xmlNodePtr cur, res, result = NULL, last = NULL;
-
- if ((ctxt == NULL) || (target == NULL) || (source == NULL) ||
- (elem == NULL))
- return(NULL);
- cur = elem;
- while (cur != NULL) {
- res = xmlXIncludeCopyNode(ctxt, target, source, cur);
- if (res != NULL) {
- if (result == NULL) {
- result = last = res;
- } else {
- last->next = res;
- res->prev = last;
- last = res;
- }
- }
- cur = cur->next;
- }
- return(result);
-}
-
-/**
- * xmlXInclueGetNthChild:
- * @cur: the node
- * @no: the child number
- *
- * Returns the @no'th element child of @cur or NULL
- */
-static xmlNodePtr
-xmlXIncludeGetNthChild(xmlNodePtr cur, int no) {
- int i;
- if (cur == NULL)
- return(cur);
- cur = cur->children;
- for (i = 0;i <= no;cur = cur->next) {
- if (cur == NULL)
- return(cur);
- if ((cur->type == XML_ELEMENT_NODE) ||
- (cur->type == XML_DOCUMENT_NODE) ||
- (cur->type == XML_HTML_DOCUMENT_NODE)) {
- i++;
- if (i == no)
- break;
- }
- }
- return(cur);
-}
-
-xmlNodePtr xmlXPtrAdvanceNode(xmlNodePtr cur);
-
-/**
- * xmlXIncludeCopyRange:
- * @ctxt: the XInclude context
- * @target: the document target
- * @source: the document source
- * @obj: the XPointer result from the evaluation.
- *
- * Build a node list tree copy of the XPointer result.
- *
- * Returns an xmlNodePtr list or NULL.
- * the caller has to free the node tree.
- */
-static xmlNodePtr
-xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
- xmlDocPtr source, xmlXPathObjectPtr range) {
- /* pointers to generated nodes */
- xmlNodePtr list = NULL, last = NULL, parent = NULL, tmp;
- /* pointers to traversal nodes */
- xmlNodePtr start, cur, end;
- int index1, index2;
-
- if ((ctxt == NULL) || (target == NULL) || (source == NULL) ||
- (range == NULL))
- return(NULL);
- if (range->type != XPATH_RANGE)
- return(NULL);
- start = (xmlNodePtr) range->user;
-
- if (start == NULL)
- return(NULL);
- end = range->user2;
- if (end == NULL)
- return(xmlDocCopyNode(start, target, 1));
-
- cur = start;
- index1 = range->index;
- index2 = range->index2;
- while (cur != NULL) {
- if (cur == end) {
- if (cur->type == XML_TEXT_NODE) {
- const xmlChar *content = cur->content;
- int len;
-
- if (content == NULL) {
- tmp = xmlNewTextLen(NULL, 0);
- } else {
- len = index2;
- if ((cur == start) && (index1 > 1)) {
- content += (index1 - 1);
- len -= (index1 - 1);
- index1 = 0;
- } else {
- len = index2;
- }
- tmp = xmlNewTextLen(content, len);
- }
- /* single sub text node selection */
- if (list == NULL)
- return(tmp);
- /* prune and return full set */
- if (last != NULL)
- xmlAddNextSibling(last, tmp);
- else
- xmlAddChild(parent, tmp);
- return(list);
- } else {
- tmp = xmlDocCopyNode(cur, target, 0);
- if (list == NULL)
- list = tmp;
- else {
- if (last != NULL)
- xmlAddNextSibling(last, tmp);
- else
- xmlAddChild(parent, tmp);
- }
- last = NULL;
- parent = tmp;
-
- if (index2 > 1) {
- end = xmlXIncludeGetNthChild(cur, index2 - 1);
- index2 = 0;
- }
- if ((cur == start) && (index1 > 1)) {
- cur = xmlXIncludeGetNthChild(cur, index1 - 1);
- index1 = 0;
- } else {
- cur = cur->children;
- }
- /*
- * Now gather the remaining nodes from cur to end
- */
- continue; /* while */
- }
- } else if ((cur == start) &&
- (list == NULL) /* looks superfluous but ... */ ) {
- if ((cur->type == XML_TEXT_NODE) ||
- (cur->type == XML_CDATA_SECTION_NODE)) {
- const xmlChar *content = cur->content;
-
- if (content == NULL) {
- tmp = xmlNewTextLen(NULL, 0);
- } else {
- if (index1 > 1) {
- content += (index1 - 1);
- }
- tmp = xmlNewText(content);
- }
- last = list = tmp;
- } else {
- if ((cur == start) && (index1 > 1)) {
- tmp = xmlDocCopyNode(cur, target, 0);
- list = tmp;
- parent = tmp;
- last = NULL;
- cur = xmlXIncludeGetNthChild(cur, index1 - 1);
- index1 = 0;
- /*
- * Now gather the remaining nodes from cur to end
- */
- continue; /* while */
- }
- tmp = xmlDocCopyNode(cur, target, 1);
- list = tmp;
- parent = NULL;
- last = tmp;
- }
- } else {
- tmp = NULL;
- switch (cur->type) {
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_NODE:
- /* Do not copy DTD informations */
- break;
- case XML_ENTITY_DECL:
- /* handle crossing entities -> stack needed */
- break;
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- /* don't consider it part of the tree content */
- break;
- case XML_ATTRIBUTE_NODE:
- /* Humm, should not happen ! */
- break;
- default:
- tmp = xmlDocCopyNode(cur, target, 1);
- break;
- }
- if (tmp != NULL) {
- if ((list == NULL) || ((last == NULL) && (parent == NULL))) {
- return(NULL);
- }
- if (last != NULL)
- xmlAddNextSibling(last, tmp);
- else {
- xmlAddChild(parent, tmp);
- last = tmp;
- }
- }
- }
- /*
- * Skip to next node in document order
- */
- if ((list == NULL) || ((last == NULL) && (parent == NULL))) {
- return(NULL);
- }
- cur = xmlXPtrAdvanceNode(cur);
- }
- return(list);
-}
-
-/**
- * xmlXIncludeBuildNodeList:
- * @ctxt: the XInclude context
- * @target: the document target
- * @source: the document source
- * @obj: the XPointer result from the evaluation.
- *
- * Build a node list tree copy of the XPointer result.
- * This will drop Attributes and Namespace declarations.
- *
- * Returns an xmlNodePtr list or NULL.
- * the caller has to free the node tree.
- */
-static xmlNodePtr
-xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
- xmlDocPtr source, xmlXPathObjectPtr obj) {
- xmlNodePtr list = NULL, last = NULL;
- int i;
-
- if ((ctxt == NULL) || (target == NULL) || (source == NULL) ||
- (obj == NULL))
- return(NULL);
- switch (obj->type) {
- case XPATH_NODESET: {
- xmlNodeSetPtr set = obj->nodesetval;
- if (set == NULL)
- return(NULL);
- for (i = 0;i < set->nodeNr;i++) {
- if (set->nodeTab[i] == NULL)
- continue;
- switch (set->nodeTab[i]->type) {
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- 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:
- case XML_HTML_DOCUMENT_NODE:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- break;
- case XML_ATTRIBUTE_NODE:
- case XML_NAMESPACE_DECL:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_NOTATION_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- continue; /* for */
- }
- if (last == NULL)
- list = last = xmlXIncludeCopyNode(ctxt, target, source,
- set->nodeTab[i]);
- else {
- xmlAddNextSibling(last,
- xmlXIncludeCopyNode(ctxt, target, source,
- set->nodeTab[i]));
- if (last->next != NULL)
- last = last->next;
- }
- }
- break;
- }
- case XPATH_LOCATIONSET: {
- xmlLocationSetPtr set = (xmlLocationSetPtr) obj->user;
- if (set == NULL)
- return(NULL);
- for (i = 0;i < set->locNr;i++) {
- if (last == NULL)
- list = last = xmlXIncludeCopyXPointer(ctxt, target, source,
- set->locTab[i]);
- else
- xmlAddNextSibling(last,
- xmlXIncludeCopyXPointer(ctxt, target, source,
- set->locTab[i]));
- if (last != NULL) {
- while (last->next != NULL)
- last = last->next;
- }
- }
- break;
- }
- case XPATH_RANGE:
- return(xmlXIncludeCopyRange(ctxt, target, source, obj));
- case XPATH_POINT:
- /* points are ignored in XInclude */
- break;
- default:
- break;
- }
- return(list);
-}
-/************************************************************************
- * *
- * XInclude I/O handling *
- * *
- ************************************************************************/
-
-/**
- * xmlXIncludeLoadDoc:
- * @ctxt: the XInclude context
- * @url: the associated URL
- * @nr: the xinclude node number
- *
- * Load the document, and store the result in the XInclude context
- *
- * Returns 0 in case of success, -1 in case of failure
- */
-static int
-xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
- xmlDocPtr doc;
- xmlURIPtr uri;
- xmlChar *URL;
- xmlChar *fragment = NULL;
- int i = 0;
-
-#ifdef DEBUG_XINCLUDE
- xmlGenericError(xmlGenericErrorContext, "Loading doc %s:%d\n", url, nr);
-#endif
- /*
- * Check the URL and remove any fragment identifier
- */
- uri = xmlParseURI((const char *)url);
- if (uri == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: invalid value URI %s\n", url);
- return(-1);
- }
- if (uri->fragment != NULL) {
- fragment = (xmlChar *) uri->fragment;
- uri->fragment = NULL;
- }
- URL = xmlSaveUri(uri);
- xmlFreeURI(uri);
- if (URL == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: invalid value URI %s\n", url);
- if (fragment != NULL)
- xmlFree(fragment);
- return(-1);
- }
-
- /*
- * Handling of references to the local document are done
- * directly through ctxt->doc.
- */
- if ((URL[0] == 0) || (URL[0] == '#')) {
- doc = NULL;
- goto loaded;
- }
-
- /*
- * Prevent reloading twice the document.
- */
- for (i = 0; i < ctxt->incNr; i++) {
- if ((xmlStrEqual(URL, ctxt->incTab[i]->URI)) &&
- (ctxt->incTab[i]->doc != NULL)) {
- doc = ctxt->incTab[i]->doc;
-#ifdef DEBUG_XINCLUDE
- printf("Already loaded %s\n", URL);
-#endif
- goto loaded;
- }
- }
-
- /*
- * Load it.
- */
-#ifdef DEBUG_XINCLUDE
- printf("loading %s\n", URL);
-#endif
- doc = xmlParseFile((const char *)URL);
- if (doc == NULL) {
- xmlFree(URL);
- if (fragment != NULL)
- xmlFree(fragment);
- return(-1);
- }
- ctxt->incTab[nr]->doc = doc;
-
- /*
- * TODO: Make sure we have all entities fixed up
- */
-
- /*
- * We don't need the DTD anymore, free up space
- if (doc->intSubset != NULL) {
- xmlUnlinkNode((xmlNodePtr) doc->intSubset);
- xmlFreeNode((xmlNodePtr) doc->intSubset);
- doc->intSubset = NULL;
- }
- if (doc->extSubset != NULL) {
- xmlUnlinkNode((xmlNodePtr) doc->extSubset);
- xmlFreeNode((xmlNodePtr) doc->extSubset);
- doc->extSubset = NULL;
- }
- */
- xmlXIncludeRecurseDoc(ctxt, doc, URL);
-
-loaded:
- if (fragment == NULL) {
- /*
- * Add the top children list as the replacement copy.
- */
- if (doc == NULL)
- {
- /* Hopefully a DTD declaration won't be copied from
- * the same document */
- ctxt->incTab[nr]->inc = xmlCopyNodeList(ctxt->doc->children);
- } else {
- ctxt->incTab[nr]->inc = xmlXIncludeCopyNodeList(ctxt, ctxt->doc,
- doc, doc->children);
- }
- } else {
- /*
- * Computes the XPointer expression and make a copy used
- * as the replacement copy.
- */
- xmlXPathObjectPtr xptr;
- xmlXPathContextPtr xptrctxt;
- xmlNodeSetPtr set;
-
- if (doc == NULL) {
- xptrctxt = xmlXPtrNewContext(ctxt->doc, ctxt->incTab[nr]->ref,
- NULL);
- } else {
- xptrctxt = xmlXPtrNewContext(doc, NULL, NULL);
- }
- if (xptrctxt == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: could create XPointer context\n");
- xmlFree(URL);
- xmlFree(fragment);
- return(-1);
- }
- xptr = xmlXPtrEval(fragment, xptrctxt);
- if (xptr == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: XPointer evaluation failed: #%s\n",
- fragment);
- xmlXPathFreeContext(xptrctxt);
- xmlFree(URL);
- xmlFree(fragment);
- return(-1);
- }
- switch (xptr->type) {
- case XPATH_UNDEFINED:
- case XPATH_BOOLEAN:
- case XPATH_NUMBER:
- case XPATH_STRING:
- case XPATH_POINT:
- case XPATH_USERS:
- case XPATH_XSLT_TREE:
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: XPointer is not a range: #%s\n",
- fragment);
- xmlXPathFreeContext(xptrctxt);
- xmlFree(URL);
- xmlFree(fragment);
- return(-1);
- case XPATH_NODESET:
- case XPATH_RANGE:
- case XPATH_LOCATIONSET:
- break;
- }
- set = xptr->nodesetval;
- if (set != NULL) {
- for (i = 0;i < set->nodeNr;i++) {
- if (set->nodeTab[i] == NULL)
- continue;
- switch (set->nodeTab[i]->type) {
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- 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:
- case XML_HTML_DOCUMENT_NODE:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- continue;
- case XML_ATTRIBUTE_NODE:
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: XPointer selects an attribute: #%s\n",
- fragment);
- set->nodeTab[i] = NULL;
- continue;
- case XML_NAMESPACE_DECL:
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: XPointer selects a namespace: #%s\n",
- fragment);
- set->nodeTab[i] = NULL;
- continue;
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_NOTATION_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: XPointer selects unexpected nodes: #%s\n",
- fragment);
- set->nodeTab[i] = NULL;
- set->nodeTab[i] = NULL;
- continue; /* for */
- }
- }
- }
- ctxt->incTab[nr]->inc =
- xmlXIncludeCopyXPointer(ctxt, ctxt->doc, doc, xptr);
- xmlXPathFreeObject(xptr);
- xmlXPathFreeContext(xptrctxt);
- xmlFree(fragment);
- }
-
- /*
- * Do the xml:base fixup if needed
- */
- if ((doc != NULL) && (URL != NULL) && (xmlStrchr(URL, (xmlChar) '/'))) {
- xmlNodePtr node;
-
- node = ctxt->incTab[nr]->inc;
- while (node != NULL) {
- if (node->type == XML_ELEMENT_NODE)
- xmlNodeSetBase(node, URL);
- node = node->next;
- }
- }
- if ((nr < ctxt->incNr) && (ctxt->incTab[nr]->doc != NULL) &&
- (ctxt->incTab[nr]->count <= 1)) {
-#ifdef DEBUG_XINCLUDE
- printf("freeing %s\n", ctxt->incTab[nr]->doc->URL);
-#endif
- xmlFreeDoc(ctxt->incTab[nr]->doc);
- ctxt->incTab[nr]->doc = NULL;
- }
- xmlFree(URL);
- return(0);
-}
-
-/**
- * xmlXIncludeLoadTxt:
- * @ctxt: the XInclude context
- * @url: the associated URL
- * @nr: the xinclude node number
- *
- * Load the content, and store the result in the XInclude context
- *
- * Returns 0 in case of success, -1 in case of failure
- */
-static int
-xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
- xmlParserInputBufferPtr buf;
- xmlNodePtr node;
- xmlURIPtr uri;
- xmlChar *URL;
- int i;
- xmlChar *encoding = NULL;
- xmlCharEncoding enc = 0;
-
- /*
- * Check the URL and remove any fragment identifier
- */
- uri = xmlParseURI((const char *)url);
- if (uri == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: invalid value URI %s\n", url);
- return(-1);
- }
- if (uri->fragment != NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: fragment identifier forbidden for text: %s\n",
- uri->fragment);
- xmlFreeURI(uri);
- return(-1);
- }
- URL = xmlSaveUri(uri);
- xmlFreeURI(uri);
- if (URL == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: invalid value URI %s\n", url);
- return(-1);
- }
-
- /*
- * Handling of references to the local document are done
- * directly through ctxt->doc.
- */
- if (URL[0] == 0) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: text serialization of document not available\n");
- xmlFree(URL);
- return(-1);
- }
-
- /*
- * Prevent reloading twice the document.
- */
- for (i = 0; i < ctxt->txtNr; i++) {
- if (xmlStrEqual(URL, ctxt->txturlTab[i])) {
- node = xmlCopyNode(ctxt->txtTab[i], 1);
- goto loaded;
- }
- }
- /*
- * Try to get the encoding if available
- */
- if ((ctxt->incTab[nr] != NULL) && (ctxt->incTab[nr]->ref != NULL)) {
- encoding = xmlGetProp(ctxt->incTab[nr]->ref, XINCLUDE_PARSE_ENCODING);
- }
- if (encoding != NULL) {
- /*
- * TODO: we should not have to remap to the xmlCharEncoding
- * predefined set, a better interface than
- * xmlParserInputBufferCreateFilename should allow any
- * encoding supported by iconv
- */
- enc = xmlParseCharEncoding((const char *) encoding);
- if (enc == XML_CHAR_ENCODING_ERROR) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: encoding %s not supported\n", encoding);
- xmlFree(encoding);
- xmlFree(URL);
- return(-1);
- }
- xmlFree(encoding);
- }
-
- /*
- * Load it.
- */
- buf = xmlParserInputBufferCreateFilename((const char *)URL, enc);
- if (buf == NULL) {
- xmlFree(URL);
- return(-1);
- }
- node = xmlNewText(NULL);
-
- /*
- * Scan all chars from the resource and add the to the node
- */
- while (xmlParserInputBufferRead(buf, 128) > 0) {
- int len;
- const xmlChar *content;
-
- content = xmlBufferContent(buf->buffer);
- len = xmlBufferLength(buf->buffer);
- for (i = 0;i < len;) {
- int cur;
- int l;
-
- cur = xmlStringCurrentChar(NULL, &content[i], &l);
- if (!IS_CHAR(cur)) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: %s contains invalid char %d\n", URL, cur);
- } else {
- xmlNodeAddContentLen(node, &content[i], l);
- }
- i += l;
- }
- xmlBufferShrink(buf->buffer, len);
- }
- xmlFreeParserInputBuffer(buf);
- xmlXIncludeAddTxt(ctxt, node, URL);
-
-loaded:
- /*
- * Add the element as the replacement copy.
- */
- ctxt->incTab[nr]->inc = node;
- xmlFree(URL);
- return(0);
-}
-
-/**
- * xmlXIncludeLoadFallback:
- * @ctxt: the XInclude context
- * @fallback: the fallback node
- * @nr: the xinclude node number
- *
- * Load the content of the fallback node, and store the result
- * in the XInclude context
- *
- * Returns 0 in case of success, -1 in case of failure
- */
-static int
-xmlXIncludeLoadFallback(xmlXIncludeCtxtPtr ctxt, xmlNodePtr fallback, int nr) {
- if ((fallback == NULL) || (ctxt == NULL))
- return(-1);
-
- ctxt->incTab[nr]->inc = xmlCopyNode(fallback->children, 1);
- return(0);
-}
-
-/************************************************************************
- * *
- * XInclude Processing *
- * *
- ************************************************************************/
-
-/**
- * xmlXIncludePreProcessNode:
- * @ctxt: an XInclude context
- * @node: an XInclude node
- *
- * Implement the XInclude preprocessing, currently just adding the element
- * for further processing.
- *
- * Returns the result list or NULL in case of error
- */
-static xmlNodePtr
-xmlXIncludePreProcessNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
- xmlXIncludeAddNode(ctxt, node);
- return(0);
-}
-
-#if 0
-/**
- * xmlXIncludePreloadNode:
- * @ctxt: an XInclude context
- * @nr: the node number
- *
- * Do some precomputations and preload shared documents
- *
- * Returns 0 if substitution succeeded, -1 if some processing failed
- */
-static int
-xmlXIncludePreloadNode(xmlXIncludeCtxtPtr ctxt, int nr) {
- xmlNodePtr cur;
- xmlChar *href;
- xmlChar *parse;
- xmlChar *base;
- xmlChar *URI;
- int xml = 1; /* default Issue 64 */
- xmlURIPtr uri;
- xmlChar *URL;
- xmlChar *fragment = NULL;
- int i;
-
-
- if (ctxt == NULL)
- return(-1);
- if ((nr < 0) || (nr >= ctxt->incNr))
- return(-1);
- cur = ctxt->incTab[nr]->ref;
- if (cur == NULL)
- return(-1);
-
- /*
- * read the attributes
- */
- href = xmlGetNsProp(cur, XINCLUDE_NS, XINCLUDE_HREF);
- if (href == NULL) {
- href = xmlGetProp(cur, XINCLUDE_HREF);
- if (href == NULL) {
- xmlGenericError(xmlGenericErrorContext, "XInclude: no href\n");
- return(-1);
- }
- }
- parse = xmlGetNsProp(cur, XINCLUDE_NS, XINCLUDE_PARSE);
- if (parse == NULL) {
- parse = xmlGetProp(cur, XINCLUDE_PARSE);
- }
- if (parse != NULL) {
- if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
- xml = 1;
- else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
- xml = 0;
- else {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: invalid value %s for %s\n",
- parse, XINCLUDE_PARSE);
- if (href != NULL)
- xmlFree(href);
- if (parse != NULL)
- xmlFree(parse);
- return(-1);
- }
- }
-
- /*
- * compute the URI
- */
- base = xmlNodeGetBase(ctxt->doc, cur);
- if (base == NULL) {
- URI = xmlBuildURI(href, ctxt->doc->URL);
- } else {
- URI = xmlBuildURI(href, base);
- }
- if (URI == NULL) {
- xmlChar *escbase;
- xmlChar *eschref;
- /*
- * Some escaping may be needed
- */
- escbase = xmlURIEscape(base);
- eschref = xmlURIEscape(href);
- URI = xmlBuildURI(eschref, escbase);
- if (escbase != NULL)
- xmlFree(escbase);
- if (eschref != NULL)
- xmlFree(eschref);
- }
- if (parse != NULL)
- xmlFree(parse);
- if (href != NULL)
- xmlFree(href);
- if (base != NULL)
- xmlFree(base);
- if (URI == NULL) {
- xmlGenericError(xmlGenericErrorContext, "XInclude: failed build URL\n");
- return(-1);
- }
-
- /*
- * Check the URL and remove any fragment identifier
- */
- uri = xmlParseURI((const char *)URI);
- if (uri == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: invalid value URI %s\n", URI);
- xmlFree(URI);
- return(-1);
- }
- if (uri->fragment != NULL) {
- fragment = (xmlChar *) uri->fragment;
- uri->fragment = NULL;
- }
- URL = xmlSaveUri(uri);
- xmlFreeURI(uri);
- if (URL == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: invalid value URI %s\n", URI);
- if (fragment != NULL)
- xmlFree(fragment);
- xmlFree(URI);
- return(-1);
- }
- xmlFree(URI);
- if (fragment != NULL)
- xmlFree(fragment);
-
- for (i = 0; i < nr; i++) {
- if (xmlStrEqual(URL, ctxt->incTab[i]->URI)) {
-#ifdef DEBUG_XINCLUDE
- printf("Incrementing count for %d : %s\n", i, ctxt->incTab[i]->URI);
-#endif
- ctxt->incTab[i]->count++;
- break;
- }
- }
- xmlFree(URL);
- return(0);
-}
-#endif
-
-/**
- * xmlXIncludeLoadNode:
- * @ctxt: an XInclude context
- * @nr: the node number
- *
- * Find and load the infoset replacement for the given node.
- *
- * Returns 0 if substitution succeeded, -1 if some processing failed
- */
-static int
-xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, int nr) {
- xmlNodePtr cur;
- xmlChar *href;
- xmlChar *parse;
- xmlChar *base;
- xmlChar *URI;
- int xml = 1; /* default Issue 64 */
- int ret;
-
- if (ctxt == NULL)
- return(-1);
- if ((nr < 0) || (nr >= ctxt->incNr))
- return(-1);
- cur = ctxt->incTab[nr]->ref;
- if (cur == NULL)
- return(-1);
-
- /*
- * read the attributes
- */
- href = xmlGetNsProp(cur, XINCLUDE_NS, XINCLUDE_HREF);
- if (href == NULL) {
- href = xmlGetProp(cur, XINCLUDE_HREF);
- if (href == NULL) {
- xmlGenericError(xmlGenericErrorContext, "XInclude: no href\n");
- return(-1);
- }
- }
- parse = xmlGetNsProp(cur, XINCLUDE_NS, XINCLUDE_PARSE);
- if (parse == NULL) {
- parse = xmlGetProp(cur, XINCLUDE_PARSE);
- }
- if (parse != NULL) {
- if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
- xml = 1;
- else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
- xml = 0;
- else {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: invalid value %s for %s\n",
- parse, XINCLUDE_PARSE);
- if (href != NULL)
- xmlFree(href);
- if (parse != NULL)
- xmlFree(parse);
- return(-1);
- }
- }
-
- /*
- * compute the URI
- */
- base = xmlNodeGetBase(ctxt->doc, cur);
- if (base == NULL) {
- URI = xmlBuildURI(href, ctxt->doc->URL);
- } else {
- URI = xmlBuildURI(href, base);
- }
- if (URI == NULL) {
- xmlChar *escbase;
- xmlChar *eschref;
- /*
- * Some escaping may be needed
- */
- escbase = xmlURIEscape(base);
- eschref = xmlURIEscape(href);
- URI = xmlBuildURI(eschref, escbase);
- if (escbase != NULL)
- xmlFree(escbase);
- if (eschref != NULL)
- xmlFree(eschref);
- }
- if (URI == NULL) {
- xmlGenericError(xmlGenericErrorContext, "XInclude: failed build URL\n");
- if (parse != NULL)
- xmlFree(parse);
- if (href != NULL)
- xmlFree(href);
- if (base != NULL)
- xmlFree(base);
- return(-1);
- }
-#ifdef DEBUG_XINCLUDE
- xmlGenericError(xmlGenericErrorContext, "parse: %s\n",
- xml ? "xml": "text");
- xmlGenericError(xmlGenericErrorContext, "URI: %s\n", URI);
-#endif
-
- /*
- * Cleanup
- */
- if (xml) {
- ret = xmlXIncludeLoadDoc(ctxt, URI, nr);
- /* xmlXIncludeGetFragment(ctxt, cur, URI); */
- } else {
- ret = xmlXIncludeLoadTxt(ctxt, URI, nr);
- }
- if (ret < 0) {
- xmlNodePtr children;
-
- /*
- * Time to try a fallback if availble
- */
-#ifdef DEBUG_XINCLUDE
- xmlGenericError(xmlGenericErrorContext, "error looking for fallback\n");
-#endif
- children = cur->children;
- while (children != NULL) {
- if ((children->type == XML_ELEMENT_NODE) &&
- (children->ns != NULL) &&
- (xmlStrEqual(children->name, XINCLUDE_FALLBACK)) &&
- (xmlStrEqual(children->ns->href, XINCLUDE_NS))) {
- ret = xmlXIncludeLoadFallback(ctxt, children, nr);
- if (ret == 0)
- break;
- }
- children = children->next;
- }
- }
- if (ret < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: could not load %s, and no fallback was found\n",
- URI);
- }
-
- /*
- * Cleanup
- */
- if (URI != NULL)
- xmlFree(URI);
- if (parse != NULL)
- xmlFree(parse);
- if (href != NULL)
- xmlFree(href);
- if (base != NULL)
- xmlFree(base);
- return(0);
-}
-
-/**
- * xmlXIncludeIncludeNode:
- * @ctxt: an XInclude context
- * @nr: the node number
- *
- * Inplement the infoset replacement for the given node
- *
- * Returns 0 if substitution succeeded, -1 if some processing failed
- */
-static int
-xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) {
- xmlNodePtr cur, end, list;
-
- if (ctxt == NULL)
- return(-1);
- if ((nr < 0) || (nr >= ctxt->incNr))
- return(-1);
- cur = ctxt->incTab[nr]->ref;
- if (cur == NULL)
- return(-1);
-
- /*
- * Change the current node as an XInclude start one, and add an
- * entity end one
- */
- cur->type = XML_XINCLUDE_START;
- end = xmlNewNode(cur->ns, cur->name);
- if (end == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "XInclude: failed to build node\n");
- return(-1);
- }
- end->type = XML_XINCLUDE_END;
- xmlAddNextSibling(cur, end);
-
- /*
- * Add the list of nodes
- */
- list = ctxt->incTab[nr]->inc;
- ctxt->incTab[nr]->inc = NULL;
- while (list != NULL) {
- cur = list;
- list = list->next;
-
- xmlAddPrevSibling(end, cur);
- }
-
-
- return(0);
-}
-
-/**
- * xmlXIncludeTestNode:
- * @node: an XInclude node
- *
- * test if the node is an XInclude node
- *
- * Returns 1 true, 0 otherwise
- */
-static int
-xmlXIncludeTestNode(xmlNodePtr node) {
- if (node == NULL)
- return(0);
- if (node->ns == NULL)
- return(0);
- if ((xmlStrEqual(node->name, XINCLUDE_NODE)) &&
- (xmlStrEqual(node->ns->href, XINCLUDE_NS))) return(1);
- return(0);
-}
-
-/**
- * xmlXIncludeDoProcess:
- * @ctxt:
- * @doc: an XML document
- *
- * Implement the XInclude substitution on the XML document @doc
- *
- * Returns 0 if no substitution were done, -1 if some processing failed
- * or the number of substitutions done.
- */
-static int
-xmlXIncludeDoProcess(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc) {
- xmlNodePtr cur;
- int ret = 0;
- int i;
-
- if (doc == NULL)
- return(-1);
- if (ctxt == NULL)
- return(-1);
-
- /*
- * First phase: lookup the elements in the document
- */
- cur = xmlDocGetRootElement(doc);
- if (xmlXIncludeTestNode(cur))
- xmlXIncludePreProcessNode(ctxt, cur);
- while (cur != NULL) {
- /* TODO: need to work on entities -> stack */
- if ((cur->children != NULL) &&
- (cur->children->type != XML_ENTITY_DECL)) {
- cur = cur->children;
- if (xmlXIncludeTestNode(cur))
- xmlXIncludePreProcessNode(ctxt, cur);
- } else if (cur->next != NULL) {
- cur = cur->next;
- if (xmlXIncludeTestNode(cur))
- xmlXIncludePreProcessNode(ctxt, cur);
- } else {
- do {
- cur = cur->parent;
- if (cur == NULL) break; /* do */
- if (cur->next != NULL) {
- cur = cur->next;
- if (xmlXIncludeTestNode(cur))
- xmlXIncludePreProcessNode(ctxt, cur);
- break; /* do */
- }
- } while (cur != NULL);
- }
- }
-
- /*
- * Second Phase : collect the infosets fragments
- */
- /*
- for (i = ctxt->incBase;i < ctxt->incNr; i++) {
- xmlXIncludePreloadNode(ctxt, i);
- }
- */
- for (i = ctxt->incBase;i < ctxt->incNr; i++) {
- xmlXIncludeLoadNode(ctxt, i);
- }
-
- /*
- * Third phase: extend the original document infoset.
- */
- for (i = ctxt->incBase;i < ctxt->incNr; i++) {
- xmlXIncludeIncludeNode(ctxt, i);
- }
-
- return(ret);
-}
-
-/**
- * xmlXIncludeProcess:
- * @doc: an XML document
- *
- * Implement the XInclude substitution on the XML document @doc
- *
- * Returns 0 if no substitution were done, -1 if some processing failed
- * or the number of substitutions done.
- */
-int
-xmlXIncludeProcess(xmlDocPtr doc) {
- xmlXIncludeCtxtPtr ctxt;
- int ret = 0;
-
- if (doc == NULL)
- return(-1);
- ctxt = xmlXIncludeNewContext(doc);
- if (ctxt == NULL)
- return(-1);
- ret = xmlXIncludeDoProcess(ctxt, doc);
-
- xmlXIncludeFreeContext(ctxt);
- return(ret);
-}
-
-#else /* !LIBXML_XINCLUDE_ENABLED */
-#endif
diff --git a/bundle/libxml/xlink.c b/bundle/libxml/xlink.c
deleted file mode 100644
index 17ec77f66f..0000000000
--- a/bundle/libxml/xlink.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * xlink.c : implementation of the hyperlinks detection module
- * This version supports both XML XLinks and HTML simple links
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#include <string.h> /* for memset() only */
-#ifdef HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-#include <libxml/xmlmemory.h>
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/valid.h>
-#include <libxml/xlink.h>
-#include <libxml/globals.h>
-
-#define XLINK_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xlink/namespace/")
-#define XHTML_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xhtml/")
-
-/****************************************************************
- * *
- * Default setting and related functions *
- * *
- ****************************************************************/
-
-static xlinkHandlerPtr xlinkDefaultHandler = NULL;
-static xlinkNodeDetectFunc xlinkDefaultDetect = NULL;
-
-/**
- * xlinkGetDefaultHandler:
- *
- * Get the default xlink handler.
- *
- * Returns the current xlinkHandlerPtr value.
- */
-xlinkHandlerPtr
-xlinkGetDefaultHandler(void) {
- return(xlinkDefaultHandler);
-}
-
-
-/**
- * xlinkSetDefaultHandler:
- * @handler: the new value for the xlink handler block
- *
- * Set the default xlink handlers
- */
-void
-xlinkSetDefaultHandler(xlinkHandlerPtr handler) {
- xlinkDefaultHandler = handler;
-}
-
-/**
- * xlinkGetDefaultDetect:
- *
- * Get the default xlink detection routine
- *
- * Returns the current function or NULL;
- */
-xlinkNodeDetectFunc
-xlinkGetDefaultDetect (void) {
- return(xlinkDefaultDetect);
-}
-
-/**
- * xlinkSetDefaultDetect:
- * @func: pointer to the new detection routine.
- *
- * Set the default xlink detection routine
- */
-void
-xlinkSetDefaultDetect (xlinkNodeDetectFunc func) {
- xlinkDefaultDetect = func;
-}
-
-/****************************************************************
- * *
- * The detection routines *
- * *
- ****************************************************************/
-
-
-/**
- * xlinkIsLink:
- * @doc: the document containing the node
- * @node: the node pointer itself
- *
- * Check whether the given node carries the attributes needed
- * to be a link element (or is one of the linking elements issued
- * from the (X)HTML DtDs).
- * This routine don't try to do full checking of the link validity
- * but tries to detect and return the appropriate link type.
- *
- * Returns the xlinkType of the node (XLINK_TYPE_NONE if there is no
- * link detected.
- */
-xlinkType
-xlinkIsLink (xmlDocPtr doc, xmlNodePtr node) {
- xmlChar *type = NULL, *role = NULL;
- xlinkType ret = XLINK_TYPE_NONE;
-
- if (node == NULL) return(XLINK_TYPE_NONE);
- if (doc == NULL) doc = node->doc;
- if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
- /*
- * This is an HTML document.
- */
- } else if ((node->ns != NULL) &&
- (xmlStrEqual(node->ns->href, XHTML_NAMESPACE))) {
- /*
- * !!!! We really need an IS_XHTML_ELEMENT function from HTMLtree.h @@@
- */
- /*
- * This is an XHTML element within an XML document
- * Check whether it's one of the element able to carry links
- * and in that case if it holds the attributes.
- */
- }
-
- /*
- * We don't prevent a-priori having XML Linking constructs on
- * XHTML elements
- */
- type = xmlGetNsProp(node, BAD_CAST"type", XLINK_NAMESPACE);
- if (type != NULL) {
- if (!xmlStrEqual(type, BAD_CAST "simple")) {
- ret = XLINK_TYPE_SIMPLE;
- } if (!xmlStrEqual(type, BAD_CAST "extended")) {
- role = xmlGetNsProp(node, BAD_CAST "role", XLINK_NAMESPACE);
- if (role != NULL) {
- xmlNsPtr xlink;
- xlink = xmlSearchNs(doc, node, XLINK_NAMESPACE);
- if (xlink == NULL) {
- /* Humm, fallback method */
- if (xmlStrEqual(role, BAD_CAST"xlink:external-linkset"))
- ret = XLINK_TYPE_EXTENDED_SET;
- } else {
- xmlChar buf[200];
- snprintf((char *) buf, sizeof(buf), "%s:external-linkset",
- (char *) xlink->prefix);
- buf[sizeof(buf) - 1] = 0;
- if (xmlStrEqual(role, buf))
- ret = XLINK_TYPE_EXTENDED_SET;
-
- }
-
- }
- ret = XLINK_TYPE_EXTENDED;
- }
- }
-
- if (type != NULL) xmlFree(type);
- if (role != NULL) xmlFree(role);
- return(ret);
-}
diff --git a/bundle/libxml/xmlIO.c b/bundle/libxml/xmlIO.c
deleted file mode 100644
index 8bd9f9ca18..0000000000
--- a/bundle/libxml/xmlIO.c
+++ /dev/null
@@ -1,2839 +0,0 @@
-/*
- * xmlIO.c : implementation of the I/O interfaces used by the parser
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- *
- * 14 Nov 2000 ht - for VMS, truncated name of long functions to under 32 char
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#include <string.h>
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-
-/* Figure a portable way to know if a file is a directory. */
-#ifndef HAVE_STAT
-# ifdef HAVE__STAT
- /* MS C library seems to define stat and _stat. The definition
- is identical. Still, mapping them to each other causes a warning. */
-# ifndef _MSC_VER
-# define stat(x,y) _stat(x,y)
-# endif
-# define HAVE_STAT
-# endif
-#endif
-#ifdef HAVE_STAT
-# ifndef S_ISDIR
-# ifdef _S_ISDIR
-# define S_ISDIR(x) _S_ISDIR(x)
-# else
-# ifdef S_IFDIR
-# ifndef S_IFMT
-# ifdef _S_IFMT
-# define S_IFMT _S_IFMT
-# endif
-# endif
-# ifdef S_IFMT
-# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-# endif
-# endif
-# endif
-# endif
-#endif
-
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include <libxml/parserInternals.h>
-#include <libxml/xmlIO.h>
-#include <libxml/uri.h>
-#include <libxml/nanohttp.h>
-#include <libxml/nanoftp.h>
-#include <libxml/xmlerror.h>
-#ifdef LIBXML_CATALOG_ENABLED
-#include <libxml/catalog.h>
-#endif
-#include <libxml/globals.h>
-
-/* #define VERBOSE_FAILURE */
-/* #define DEBUG_EXTERNAL_ENTITIES */
-/* #define DEBUG_INPUT */
-
-#ifdef DEBUG_INPUT
-#define MINLEN 40
-#else
-#define MINLEN 4000
-#endif
-
-/*
- * Input I/O callback sets
- */
-typedef struct _xmlInputCallback {
- xmlInputMatchCallback matchcallback;
- xmlInputOpenCallback opencallback;
- xmlInputReadCallback readcallback;
- xmlInputCloseCallback closecallback;
-} xmlInputCallback;
-
-#define MAX_INPUT_CALLBACK 15
-
-static xmlInputCallback xmlInputCallbackTable[MAX_INPUT_CALLBACK];
-static int xmlInputCallbackNr = 0;
-static int xmlInputCallbackInitialized = 0;
-
-/*
- * Output I/O callback sets
- */
-typedef struct _xmlOutputCallback {
- xmlOutputMatchCallback matchcallback;
- xmlOutputOpenCallback opencallback;
- xmlOutputWriteCallback writecallback;
- xmlOutputCloseCallback closecallback;
-} xmlOutputCallback;
-
-#define MAX_OUTPUT_CALLBACK 15
-
-static xmlOutputCallback xmlOutputCallbackTable[MAX_OUTPUT_CALLBACK];
-static int xmlOutputCallbackNr = 0;
-static int xmlOutputCallbackInitialized = 0;
-
-/************************************************************************
- * *
- * Handling of Windows file paths *
- * *
- ************************************************************************/
-
-#define IS_WINDOWS_PATH(p) \
- ((p != NULL) && \
- (((p[0] >= 'a') && (p[0] <= 'z')) || \
- ((p[0] >= 'A') && (p[0] <= 'Z'))) && \
- (p[1] == ':') && ((p[2] == '/') || (p[2] == '\\')))
-
-
-/**
- * xmlNormalizeWindowsPath:
- * @path: a windows path like "C:/foo/bar"
- *
- * Normalize a Windows path to make an URL from it
- *
- * Returns a new URI which must be freed by the caller or NULL
- * in case of error
- */
-xmlChar *
-xmlNormalizeWindowsPath(const xmlChar *path)
-{
- int len, i = 0, j;
- xmlChar *ret;
-
- if (path == NULL)
- return(NULL);
-
- len = xmlStrlen(path);
- if (!IS_WINDOWS_PATH(path)) {
- ret = xmlStrdup(path);
- if (ret == NULL)
- return(NULL);
- j = 0;
- } else {
- ret = xmlMalloc(len + 10);
- if (ret == NULL)
- return(NULL);
- ret[0] = 'f';
- ret[1] = 'i';
- ret[2] = 'l';
- ret[3] = 'e';
- ret[4] = ':';
- ret[5] = '/';
- ret[6] = '/';
- ret[7] = '/';
- j = 8;
- }
-
- while (i < len) {
- /* TODO: UTF8 conversion + URI escaping ??? */
- if (path[i] == '\\')
- ret[j] = '/';
- else
- ret[j] = path[i];
- i++;
- j++;
- }
- ret[j] = 0;
-
- return(ret);
-}
-
-/**
- * xmlCleanupInputCallbacks:
- *
- * clears the entire input callback table. this includes the
- * compiled-in I/O.
- */
-void
-xmlCleanupInputCallbacks(void)
-{
- int i;
-
- if (!xmlInputCallbackInitialized)
- return;
-
- for (i = xmlInputCallbackNr - 1; i >= 0; i--) {
- xmlInputCallbackTable[i].matchcallback = NULL;
- xmlInputCallbackTable[i].opencallback = NULL;
- xmlInputCallbackTable[i].readcallback = NULL;
- xmlInputCallbackTable[i].closecallback = NULL;
- }
- xmlInputCallbackInitialized = 0;
-
- xmlInputCallbackNr = 0;
- xmlInputCallbackInitialized = 0;
-}
-
-/**
- * xmlCleanupOutputCallbacks:
- *
- * clears the entire output callback table. this includes the
- * compiled-in I/O callbacks.
- */
-void
-xmlCleanupOutputCallbacks(void)
-{
- int i;
-
- if (!xmlOutputCallbackInitialized)
- return;
-
- for (i = xmlOutputCallbackNr - 1; i >= 0; i--) {
- xmlOutputCallbackTable[i].matchcallback = NULL;
- xmlOutputCallbackTable[i].opencallback = NULL;
- xmlOutputCallbackTable[i].writecallback = NULL;
- xmlOutputCallbackTable[i].closecallback = NULL;
- }
- xmlOutputCallbackInitialized = 0;
-
- xmlOutputCallbackNr = 0;
- xmlOutputCallbackInitialized = 0;
-}
-
-/************************************************************************
- * *
- * Standard I/O for file accesses *
- * *
- ************************************************************************/
-
-/**
- * xmlCheckFilename:
- * @path: the path to check
- *
- * function checks to see if @path is a valid source
- * (file, socket...) for XML.
- *
- * if stat is not available on the target machine,
- * returns 1. if stat fails, returns 0 (if calling
- * stat on the filename fails, it can't be right).
- * if stat succeeds and the file is a directory,
- * returns 2. otherwise returns 1.
- */
-
-int
-xmlCheckFilename (const char *path)
-{
-#ifdef HAVE_STAT
- struct stat stat_buffer;
-
- if (stat(path, &stat_buffer) == -1)
- return 0;
-
-#ifdef S_ISDIR
- if (S_ISDIR(stat_buffer.st_mode)) {
- return 2;
- }
-#endif
-#endif
- return 1;
-}
-
-static int
-xmlNop(void) {
- return(0);
-}
-
-/**
- * xmlFdRead:
- * @context: the I/O context
- * @buffer: where to drop data
- * @len: number of bytes to read
- *
- * Read @len bytes to @buffer from the I/O channel.
- *
- * Returns the number of bytes written
- */
-static int
-xmlFdRead (void * context, char * buffer, int len) {
- return(read((int) (long) context, &buffer[0], len));
-}
-
-/**
- * xmlFdWrite:
- * @context: the I/O context
- * @buffer: where to get data
- * @len: number of bytes to write
- *
- * Write @len bytes from @buffer to the I/O channel.
- *
- * Returns the number of bytes written
- */
-static int
-xmlFdWrite (void * context, const char * buffer, int len) {
- return(write((int) (long) context, &buffer[0], len));
-}
-
-/**
- * xmlFdClose:
- * @context: the I/O context
- *
- * Close an I/O channel
- *
- * Returns 0 in case of success and error code otherwise
- */
-static int
-xmlFdClose (void * context) {
- return ( close((int) (long) context) );
-}
-
-/**
- * xmlFileMatch:
- * @filename: the URI for matching
- *
- * input from FILE *
- *
- * Returns 1 if matches, 0 otherwise
- */
-int
-xmlFileMatch (const char *filename ATTRIBUTE_UNUSED) {
- return(1);
-}
-
-/**
- * xmlFileOpen:
- * @filename: the URI for matching
- *
- * input from FILE *, supports compressed input
- * if @filename is " " then the standard input is used
- *
- * Returns an I/O context or NULL in case of error
- */
-void *
-xmlFileOpen (const char *filename) {
- const char *path = NULL;
- FILE *fd;
-
- if (!strcmp(filename, "-")) {
- fd = stdin;
- return((void *) fd);
- }
-
- if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
-#if defined (_WIN32) && !defined(__CYGWIN__)
- path = &filename[17];
-#else
- path = &filename[16];
-#endif
- else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
-#if defined (_WIN32) && !defined(__CYGWIN__)
- path = &filename[8];
-#else
- path = &filename[7];
-#endif
- } else
- path = filename;
-
- if (path == NULL)
- return(NULL);
- if (!xmlCheckFilename(path))
- return(NULL);
-
-#if defined(WIN32) || defined (__CYGWIN__)
- fd = fopen(path, "rb");
-#else
- fd = fopen(path, "r");
-#endif /* WIN32 */
- return((void *) fd);
-}
-
-/**
- * xmlFileOpenW:
- * @filename: the URI for matching
- *
- * output to from FILE *,
- * if @filename is "-" then the standard output is used
- *
- * Returns an I/O context or NULL in case of error
- */
-static void *
-xmlFileOpenW (const char *filename) {
- const char *path = NULL;
- FILE *fd;
-
- if (!strcmp(filename, "-")) {
- fd = stdout;
- return((void *) fd);
- }
-
- if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
-#if defined (_WIN32) && !defined(__CYGWIN__)
- path = &filename[17];
-#else
- path = &filename[16];
-#endif
- else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
-#if defined (_WIN32) && !defined(__CYGWIN__)
- path = &filename[8];
-#else
- path = &filename[7];
-#endif
- } else
- path = filename;
-
- if (path == NULL)
- return(NULL);
-
- fd = fopen(path, "w");
- return((void *) fd);
-}
-
-/**
- * xmlFileRead:
- * @context: the I/O context
- * @buffer: where to drop data
- * @len: number of bytes to write
- *
- * Read @len bytes to @buffer from the I/O channel.
- *
- * Returns the number of bytes written
- */
-int
-xmlFileRead (void * context, char * buffer, int len) {
- return(fread(&buffer[0], 1, len, (FILE *) context));
-}
-
-/**
- * xmlFileWrite:
- * @context: the I/O context
- * @buffer: where to drop data
- * @len: number of bytes to write
- *
- * Write @len bytes from @buffer to the I/O channel.
- *
- * Returns the number of bytes written
- */
-static int
-xmlFileWrite (void * context, const char * buffer, int len) {
- return(fwrite(&buffer[0], 1, len, (FILE *) context));
-}
-
-/**
- * xmlFileClose:
- * @context: the I/O context
- *
- * Close an I/O channel
- *
- * Returns 0 or -1 in case of error
- */
-int
-xmlFileClose (void * context) {
- FILE *fil;
-
- fil = (FILE *) context;
- if (fil == stdin)
- return(0);
- if (fil == stdout)
- return(0);
- if (fil == stderr)
- return(0);
- return ( ( fclose((FILE *) context) == EOF ) ? -1 : 0 );
-}
-
-/**
- * xmlFileFlush:
- * @context: the I/O context
- *
- * Flush an I/O channel
- */
-static int
-xmlFileFlush (void * context) {
- return ( ( fflush((FILE *) context) == EOF ) ? -1 : 0 );
-}
-
-#ifdef HAVE_ZLIB_H
-/************************************************************************
- * *
- * I/O for compressed file accesses *
- * *
- ************************************************************************/
-/**
- * xmlGzfileMatch:
- * @filename: the URI for matching
- *
- * input from compressed file test
- *
- * Returns 1 if matches, 0 otherwise
- */
-static int
-xmlGzfileMatch (const char *filename ATTRIBUTE_UNUSED) {
- return(1);
-}
-
-/**
- * xmlGzfileOpen:
- * @filename: the URI for matching
- *
- * input from compressed file open
- * if @filename is " " then the standard input is used
- *
- * Returns an I/O context or NULL in case of error
- */
-static void *
-xmlGzfileOpen (const char *filename) {
- const char *path = NULL;
- gzFile fd;
-
- if (!strcmp(filename, "-")) {
- fd = gzdopen(dup(0), "rb");
- return((void *) fd);
- }
-
- if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
-#if defined (_WIN32) && !defined(__CYGWIN__)
- path = &filename[17];
-#else
- path = &filename[16];
-#endif
- else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
-#if defined (_WIN32) && !defined(__CYGWIN__)
- path = &filename[8];
-#else
- path = &filename[7];
-#endif
- } else
- path = filename;
-
- if (path == NULL)
- return(NULL);
- if (!xmlCheckFilename(path))
- return(NULL);
-
- fd = gzopen(path, "rb");
- return((void *) fd);
-}
-
-/**
- * xmlGzfileOpenW:
- * @filename: the URI for matching
- * @compression: the compression factor (0 - 9 included)
- *
- * input from compressed file open
- * if @filename is " " then the standard input is used
- *
- * Returns an I/O context or NULL in case of error
- */
-static void *
-xmlGzfileOpenW (const char *filename, int compression) {
- const char *path = NULL;
- char mode[15];
- gzFile fd;
-
- snprintf(mode, sizeof(mode), "wb%d", compression);
- if (!strcmp(filename, "-")) {
- fd = gzdopen(dup(1), mode);
- return((void *) fd);
- }
-
- if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
-#if defined (_WIN32) && !defined(__CYGWIN__)
- path = &filename[17];
-#else
- path = &filename[16];
-#endif
- else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
-#if defined (_WIN32) && !defined(__CYGWIN__)
- path = &filename[8];
-#else
- path = &filename[7];
-#endif
- } else
- path = filename;
-
- if (path == NULL)
- return(NULL);
-
- fd = gzopen(path, mode);
- return((void *) fd);
-}
-
-/**
- * xmlGzfileRead:
- * @context: the I/O context
- * @buffer: where to drop data
- * @len: number of bytes to write
- *
- * Read @len bytes to @buffer from the compressed I/O channel.
- *
- * Returns the number of bytes written
- */
-static int
-xmlGzfileRead (void * context, char * buffer, int len) {
- return(gzread((gzFile) context, &buffer[0], len));
-}
-
-/**
- * xmlGzfileWrite:
- * @context: the I/O context
- * @buffer: where to drop data
- * @len: number of bytes to write
- *
- * Write @len bytes from @buffer to the compressed I/O channel.
- *
- * Returns the number of bytes written
- */
-static int
-xmlGzfileWrite (void * context, const char * buffer, int len) {
- return(gzwrite((gzFile) context, (char *) &buffer[0], len));
-}
-
-/**
- * xmlGzfileClose:
- * @context: the I/O context
- *
- * Close a compressed I/O channel
- */
-static int
-xmlGzfileClose (void * context) {
- return ( ( gzclose((gzFile) context) == Z_OK ) ? 0 : -1 );
-}
-#endif /* HAVE_ZLIB_H */
-
-#ifdef LIBXML_HTTP_ENABLED
-/************************************************************************
- * *
- * I/O for HTTP file accesses *
- * *
- ************************************************************************/
-
-typedef struct xmlIOHTTPWriteCtxt_
-{
- int compression;
-
- char * uri;
-
- void * doc_buff;
-
-} xmlIOHTTPWriteCtxt, *xmlIOHTTPWriteCtxtPtr;
-
-#ifdef HAVE_ZLIB_H
-
-#define DFLT_WBITS ( -15 )
-#define DFLT_MEM_LVL ( 8 )
-#define GZ_MAGIC1 ( 0x1f )
-#define GZ_MAGIC2 ( 0x8b )
-#define LXML_ZLIB_OS_CODE ( 0x03 )
-#define INIT_HTTP_BUFF_SIZE ( 32768 )
-#define DFLT_ZLIB_RATIO ( 5 )
-
-/*
-** Data structure and functions to work with sending compressed data
-** via HTTP.
-*/
-
-typedef struct xmlZMemBuff_
-{
- unsigned long size;
- unsigned long crc;
-
- unsigned char * zbuff;
- z_stream zctrl;
-
-} xmlZMemBuff, *xmlZMemBuffPtr;
-
-/**
- * append_reverse_ulong
- * @buff: Compressed memory buffer
- * @data: Unsigned long to append
- *
- * Append a unsigned long in reverse byte order to the end of the
- * memory buffer.
- */
-static void
-append_reverse_ulong( xmlZMemBuff * buff, unsigned long data ) {
-
- int idx;
-
- if ( buff == NULL )
- return;
-
- /*
- ** This is plagiarized from putLong in gzio.c (zlib source) where
- ** the number "4" is hardcoded. If zlib is ever patched to
- ** support 64 bit file sizes, this code would need to be patched
- ** as well.
- */
-
- for ( idx = 0; idx < 4; idx++ ) {
- *buff->zctrl.next_out = ( data & 0xff );
- data >>= 8;
- buff->zctrl.next_out++;
- }
-
- return;
-}
-
-/**
- *
- * xmlFreeZMemBuff
- * @buff: The memory buffer context to clear
- *
- * Release all the resources associated with the compressed memory buffer.
- */
-static void
-xmlFreeZMemBuff( xmlZMemBuffPtr buff ) {
-
- int z_err;
-
- if ( buff == NULL )
- return;
-
- xmlFree( buff->zbuff );
- z_err = deflateEnd( &buff->zctrl );
-#ifdef DEBUG_HTTP
- if ( z_err != Z_OK )
- xmlGenericError( xmlGenericErrorContext,
- "xmlFreeZMemBuff: Error releasing zlib context: %d\n",
- z_err );
-#endif
-
- xmlFree( buff );
- return;
-}
-
-/**
- * xmlCreateZMemBuff
- *@compression: Compression value to use
- *
- * Create a memory buffer to hold the compressed XML document. The
- * compressed document in memory will end up being identical to what
- * would be created if gzopen/gzwrite/gzclose were being used to
- * write the document to disk. The code for the header/trailer data to
- * the compression is plagiarized from the zlib source files.
- */
-static void *
-xmlCreateZMemBuff( int compression ) {
-
- int z_err;
- int hdr_lgth;
- xmlZMemBuffPtr buff = NULL;
-
- if ( ( compression < 1 ) || ( compression > 9 ) )
- return ( NULL );
-
- /* Create the control and data areas */
-
- buff = xmlMalloc( sizeof( xmlZMemBuff ) );
- if ( buff == NULL ) {
- xmlGenericError( xmlGenericErrorContext,
- "xmlCreateZMemBuff: %s\n",
- "Failure allocating buffer context." );
- return ( NULL );
- }
-
- (void)memset( buff, 0, sizeof( xmlZMemBuff ) );
- buff->size = INIT_HTTP_BUFF_SIZE;
- buff->zbuff = xmlMalloc( buff->size );
- if ( buff->zbuff == NULL ) {
- xmlFreeZMemBuff( buff );
- xmlGenericError( xmlGenericErrorContext,
- "xmlCreateZMemBuff: %s\n",
- "Failure allocating data buffer." );
- return ( NULL );
- }
-
- z_err = deflateInit2( &buff->zctrl, compression, Z_DEFLATED,
- DFLT_WBITS, DFLT_MEM_LVL, Z_DEFAULT_STRATEGY );
- if ( z_err != Z_OK ) {
- xmlFreeZMemBuff( buff );
- buff = NULL;
- xmlGenericError( xmlGenericErrorContext,
- "xmlCreateZMemBuff: %s %d\n",
- "Error initializing compression context. ZLIB error:",
- z_err );
- return ( NULL );
- }
-
- /* Set the header data. The CRC will be needed for the trailer */
- buff->crc = crc32( 0L, Z_NULL, 0 );
- hdr_lgth = snprintf( (char *)buff->zbuff, buff->size,
- "%c%c%c%c%c%c%c%c%c%c",
- GZ_MAGIC1, GZ_MAGIC2, Z_DEFLATED,
- 0, 0, 0, 0, 0, 0, LXML_ZLIB_OS_CODE );
- buff->zctrl.next_out = buff->zbuff + hdr_lgth;
- buff->zctrl.avail_out = buff->size - hdr_lgth;
-
- return ( buff );
-}
-
-/**
- * xmlZMemBuffExtend
- * @buff: Buffer used to compress and consolidate data.
- * @ext_amt: Number of bytes to extend the buffer.
- *
- * Extend the internal buffer used to store the compressed data by the
- * specified amount.
- *
- * Returns 0 on success or -1 on failure to extend the buffer. On failure
- * the original buffer still exists at the original size.
- */
-static int
-xmlZMemBuffExtend( xmlZMemBuffPtr buff, size_t ext_amt ) {
-
- int rc = -1;
- size_t new_size;
- size_t cur_used;
-
- unsigned char * tmp_ptr = NULL;
-
- if ( buff == NULL )
- return ( -1 );
-
- else if ( ext_amt == 0 )
- return ( 0 );
-
- cur_used = buff->zctrl.next_out - buff->zbuff;
- new_size = buff->size + ext_amt;
-
-#ifdef DEBUG_HTTP
- if ( cur_used > new_size )
- xmlGenericError( xmlGenericErrorContext,
- "xmlZMemBuffExtend: %s\n%s %d bytes.\n",
- "Buffer overwrite detected during compressed memory",
- "buffer extension. Overflowed by",
- (cur_used - new_size ) );
-#endif
-
- tmp_ptr = xmlRealloc( buff->zbuff, new_size );
- if ( tmp_ptr != NULL ) {
- rc = 0;
- buff->size = new_size;
- buff->zbuff = tmp_ptr;
- buff->zctrl.next_out = tmp_ptr + cur_used;
- buff->zctrl.avail_out = new_size - cur_used;
- }
- else {
- xmlGenericError( xmlGenericErrorContext,
- "xmlZMemBuffExtend: %s %lu bytes.\n",
- "Allocation failure extending output buffer to",
- new_size );
- }
-
- return ( rc );
-}
-
-/**
- * xmlZMemBuffAppend
- * @buff: Buffer used to compress and consolidate data
- * @src: Uncompressed source content to append to buffer
- * @len: Length of source data to append to buffer
- *
- * Compress and append data to the internal buffer. The data buffer
- * will be expanded if needed to store the additional data.
- *
- * Returns the number of bytes appended to the buffer or -1 on error.
- */
-static int
-xmlZMemBuffAppend( xmlZMemBuffPtr buff, const char * src, int len ) {
-
- int z_err;
- size_t min_accept;
-
- if ( ( buff == NULL ) || ( src == NULL ) )
- return ( -1 );
-
- buff->zctrl.avail_in = len;
- buff->zctrl.next_in = (unsigned char *)src;
- while ( buff->zctrl.avail_in > 0 ) {
- /*
- ** Extend the buffer prior to deflate call if a reasonable amount
- ** of output buffer space is not available.
- */
- min_accept = buff->zctrl.avail_in / DFLT_ZLIB_RATIO;
- if ( buff->zctrl.avail_out <= min_accept ) {
- if ( xmlZMemBuffExtend( buff, buff->size ) == -1 )
- return ( -1 );
- }
-
- z_err = deflate( &buff->zctrl, Z_NO_FLUSH );
- if ( z_err != Z_OK ) {
- xmlGenericError( xmlGenericErrorContext,
- "xmlZMemBuffAppend: %s %d %s - %d",
- "Compression error while appending",
- len, "bytes to buffer. ZLIB error", z_err );
- return ( -1 );
- }
- }
-
- buff->crc = crc32( buff->crc, (unsigned char *)src, len );
-
- return ( len );
-}
-
-/**
- * xmlZMemBuffGetContent
- * @buff: Compressed memory content buffer
- * @data_ref: Pointer reference to point to compressed content
- *
- * Flushes the compression buffers, appends gzip file trailers and
- * returns the compressed content and length of the compressed data.
- * NOTE: The gzip trailer code here is plagiarized from zlib source.
- *
- * Returns the length of the compressed data or -1 on error.
- */
-static int
-xmlZMemBuffGetContent( xmlZMemBuffPtr buff, char ** data_ref ) {
-
- int zlgth = -1;
- int z_err;
-
- if ( ( buff == NULL ) || ( data_ref == NULL ) )
- return ( -1 );
-
- /* Need to loop until compression output buffers are flushed */
-
- do
- {
- z_err = deflate( &buff->zctrl, Z_FINISH );
- if ( z_err == Z_OK ) {
- /* In this case Z_OK means more buffer space needed */
-
- if ( xmlZMemBuffExtend( buff, buff->size ) == -1 )
- return ( -1 );
- }
- }
- while ( z_err == Z_OK );
-
- /* If the compression state is not Z_STREAM_END, some error occurred */
-
- if ( z_err == Z_STREAM_END ) {
-
- /* Need to append the gzip data trailer */
-
- if ( buff->zctrl.avail_out < ( 2 * sizeof( unsigned long ) ) ) {
- if ( xmlZMemBuffExtend(buff, (2 * sizeof(unsigned long))) == -1 )
- return ( -1 );
- }
-
- /*
- ** For whatever reason, the CRC and length data are pushed out
- ** in reverse byte order. So a memcpy can't be used here.
- */
-
- append_reverse_ulong( buff, buff->crc );
- append_reverse_ulong( buff, buff->zctrl.total_in );
-
- zlgth = buff->zctrl.next_out - buff->zbuff;
- *data_ref = (char *)buff->zbuff;
- }
-
- else
- xmlGenericError( xmlGenericErrorContext,
- "xmlZMemBuffGetContent: %s - %d\n",
- "Error flushing zlib buffers. Error code", z_err );
-
- return ( zlgth );
-}
-#endif /* HAVE_ZLIB_H */
-
-/**
- * xmlFreeHTTPWriteCtxt
- * @ctxt: Context to cleanup
- *
- * Free allocated memory and reclaim system resources.
- *
- * No return value.
- */
-static void
-xmlFreeHTTPWriteCtxt( xmlIOHTTPWriteCtxtPtr ctxt )
-{
- if ( ctxt->uri != NULL )
- xmlFree( ctxt->uri );
-
- if ( ctxt->doc_buff != NULL ) {
-
-#ifdef HAVE_ZLIB_H
- if ( ctxt->compression > 0 ) {
- xmlFreeZMemBuff( ctxt->doc_buff );
- }
- else
-#endif
- {
- xmlOutputBufferClose( ctxt->doc_buff );
- }
- }
-
- xmlFree( ctxt );
- return;
-}
-
-
-/**
- * xmlIOHTTPMatch:
- * @filename: the URI for matching
- *
- * check if the URI matches an HTTP one
- *
- * Returns 1 if matches, 0 otherwise
- */
-int
-xmlIOHTTPMatch (const char *filename) {
- if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "http://", 7))
- return(1);
- return(0);
-}
-
-/**
- * xmlIOHTTPOpen:
- * @filename: the URI for matching
- *
- * open an HTTP I/O channel
- *
- * Returns an I/O context or NULL in case of error
- */
-void *
-xmlIOHTTPOpen (const char *filename) {
- return(xmlNanoHTTPOpen(filename, NULL));
-}
-
-/**
- * xmlIOHTTPOpenW:
- * @post_uri: The destination URI for the document
- * @compression: The compression desired for the document.
- *
- * Open a temporary buffer to collect the document for a subsequent HTTP POST
- * request. Non-static as is called from the output buffer creation routine.
- *
- * Returns an I/O context or NULL in case of error.
- */
-
-void *
-xmlIOHTTPOpenW(const char *post_uri, int compression)
-{
-
- xmlIOHTTPWriteCtxtPtr ctxt = NULL;
-
- if (post_uri == NULL)
- return (NULL);
-
- ctxt = xmlMalloc(sizeof(xmlIOHTTPWriteCtxt));
- if (ctxt == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlIOHTTPOpenW: Failed to create output HTTP context.\n");
- return (NULL);
- }
-
- (void) memset(ctxt, 0, sizeof(xmlIOHTTPWriteCtxt));
-
- ctxt->uri = (char *) xmlStrdup((const xmlChar *)post_uri);
- if (ctxt->uri == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlIOHTTPOpenW: Failed to duplicate destination URI.\n");
- xmlFreeHTTPWriteCtxt(ctxt);
- return (NULL);
- }
-
- /*
- * ** Since the document length is required for an HTTP post,
- * ** need to put the document into a buffer. A memory buffer
- * ** is being used to avoid pushing the data to disk and back.
- */
-
-#ifdef HAVE_ZLIB_H
- if ((compression > 0) && (compression <= 9)) {
-
- ctxt->compression = compression;
- ctxt->doc_buff = xmlCreateZMemBuff(compression);
- } else
-#endif
- {
- /* Any character conversions should have been done before this */
-
- ctxt->doc_buff = xmlAllocOutputBuffer(NULL);
- }
-
- if (ctxt->doc_buff == NULL) {
- xmlFreeHTTPWriteCtxt(ctxt);
- ctxt = NULL;
- }
-
- return (ctxt);
-}
-
-/**
- * xmlIOHTTPDfltOpenW
- * @post_uri: The destination URI for this document.
- *
- * Calls xmlIOHTTPOpenW with no compression to set up for a subsequent
- * HTTP post command. This function should generally not be used as
- * the open callback is short circuited in xmlOutputBufferCreateFile.
- *
- * Returns a pointer to the new IO context.
- */
-static void *
-xmlIOHTTPDfltOpenW( const char * post_uri ) {
- return ( xmlIOHTTPOpenW( post_uri, 0 ) );
-}
-
-/**
- * xmlIOHTTPRead:
- * @context: the I/O context
- * @buffer: where to drop data
- * @len: number of bytes to write
- *
- * Read @len bytes to @buffer from the I/O channel.
- *
- * Returns the number of bytes written
- */
-int
-xmlIOHTTPRead(void * context, char * buffer, int len) {
- return(xmlNanoHTTPRead(context, &buffer[0], len));
-}
-
-/**
- * xmlIOHTTPWrite
- * @context: previously opened writing context
- * @buffer: data to output to temporary buffer
- * @len: bytes to output
- *
- * Collect data from memory buffer into a temporary file for later
- * processing.
- *
- * Returns number of bytes written.
- */
-
-static int
-xmlIOHTTPWrite( void * context, const char * buffer, int len ) {
-
- xmlIOHTTPWriteCtxtPtr ctxt = context;
-
- if ( ( ctxt == NULL ) || ( ctxt->doc_buff == NULL ) || ( buffer == NULL ) )
- return ( -1 );
-
- if ( len > 0 ) {
-
- /* Use gzwrite or fwrite as previously setup in the open call */
-
-#ifdef HAVE_ZLIB_H
- if ( ctxt->compression > 0 )
- len = xmlZMemBuffAppend( ctxt->doc_buff, buffer, len );
-
- else
-#endif
- len = xmlOutputBufferWrite( ctxt->doc_buff, len, buffer );
-
- if ( len < 0 ) {
- xmlGenericError( xmlGenericErrorContext,
- "xmlIOHTTPWrite: %s\n%s '%s'.\n",
- "Error appending to internal buffer.",
- "Error sending document to URI",
- ctxt->uri );
- }
- }
-
- return ( len );
-}
-
-
-/**
- * xmlIOHTTPClose:
- * @context: the I/O context
- *
- * Close an HTTP I/O channel
- *
- * Returns 0
- */
-int
-xmlIOHTTPClose (void * context) {
- xmlNanoHTTPClose(context);
- return 0;
-}
-
-/**
- * xmlIOHTTCloseWrite
- * @context: The I/O context
- * @http_mthd: The HTTP method to be used when sending the data
- *
- * Close the transmit HTTP I/O channel and actually send the data.
- */
-static int
-xmlIOHTTPCloseWrite( void * context, const char * http_mthd ) {
-
- int close_rc = -1;
- int http_rtn = 0;
- int content_lgth = 0;
- xmlIOHTTPWriteCtxtPtr ctxt = context;
-
- char * http_content = NULL;
- char * content_encoding = NULL;
- char * content_type = (char *) "text/xml";
- void * http_ctxt = NULL;
-
- if ( ( ctxt == NULL ) || ( http_mthd == NULL ) )
- return ( -1 );
-
- /* Retrieve the content from the appropriate buffer */
-
-#ifdef HAVE_ZLIB_H
-
- if ( ctxt->compression > 0 ) {
- content_lgth = xmlZMemBuffGetContent( ctxt->doc_buff, &http_content );
- content_encoding = (char *) "Content-Encoding: gzip";
- }
- else
-#endif
- {
- /* Pull the data out of the memory output buffer */
-
- xmlOutputBufferPtr dctxt = ctxt->doc_buff;
- http_content = (char *)dctxt->buffer->content;
- content_lgth = dctxt->buffer->use;
- }
-
- if ( http_content == NULL ) {
- xmlGenericError( xmlGenericErrorContext,
- "xmlIOHTTPCloseWrite: %s '%s' %s '%s'.\n",
- "Error retrieving content.\nUnable to",
- http_mthd, "data to URI", ctxt->uri );
- }
-
- else {
-
- http_ctxt = xmlNanoHTTPMethod( ctxt->uri, http_mthd, http_content,
- &content_type, content_encoding,
- content_lgth );
-
- if ( http_ctxt != NULL ) {
-#ifdef DEBUG_HTTP
- /* If testing/debugging - dump reply with request content */
-
- FILE * tst_file = NULL;
- char buffer[ 4096 ];
- char * dump_name = NULL;
- int avail;
-
- xmlGenericError( xmlGenericErrorContext,
- "xmlNanoHTTPCloseWrite: HTTP %s to\n%s returned %d.\n",
- http_mthd, ctxt->uri,
- xmlNanoHTTPReturnCode( http_ctxt ) );
-
- /*
- ** Since either content or reply may be gzipped,
- ** dump them to separate files instead of the
- ** standard error context.
- */
-
- dump_name = tempnam( NULL, "lxml" );
- if ( dump_name != NULL ) {
- (void)snprintf( buffer, sizeof(buffer), "%s.content", dump_name );
-
- tst_file = fopen( buffer, "w" );
- if ( tst_file != NULL ) {
- xmlGenericError( xmlGenericErrorContext,
- "Transmitted content saved in file: %s\n", buffer );
-
- fwrite( http_content, sizeof( char ),
- content_lgth, tst_file );
- fclose( tst_file );
- }
-
- (void)snprintf( buffer, sizeof(buffer), "%s.reply", dump_name );
- tst_file = fopen( buffer, "w" );
- if ( tst_file != NULL ) {
- xmlGenericError( xmlGenericErrorContext,
- "Reply content saved in file: %s\n", buffer );
-
-
- while ( (avail = xmlNanoHTTPRead( http_ctxt,
- buffer, sizeof( buffer ) )) > 0 ) {
-
- fwrite( buffer, sizeof( char ), avail, tst_file );
- }
-
- fclose( tst_file );
- }
-
- free( dump_name );
- }
-#endif /* DEBUG_HTTP */
-
- http_rtn = xmlNanoHTTPReturnCode( http_ctxt );
- if ( ( http_rtn >= 200 ) && ( http_rtn < 300 ) )
- close_rc = 0;
- else
- xmlGenericError( xmlGenericErrorContext,
- "xmlIOHTTPCloseWrite: HTTP '%s' of %d %s\n'%s' %s %d\n",
- http_mthd, content_lgth,
- "bytes to URI", ctxt->uri,
- "failed. HTTP return code:", http_rtn );
-
- xmlNanoHTTPClose( http_ctxt );
- xmlFree( content_type );
- }
- }
-
- /* Final cleanups */
-
- xmlFreeHTTPWriteCtxt( ctxt );
-
- return ( close_rc );
-}
-
-/**
- * xmlIOHTTPClosePut
- *
- * @context: The I/O context
- *
- * Close the transmit HTTP I/O channel and actually send data using a PUT
- * HTTP method.
- */
-static int
-xmlIOHTTPClosePut( void * ctxt ) {
- return ( xmlIOHTTPCloseWrite( ctxt, "PUT" ) );
-}
-
-
-/**
- * xmlIOHTTPClosePost
- *
- * @context: The I/O context
- *
- * Close the transmit HTTP I/O channel and actually send data using a POST
- * HTTP method.
- */
-static int
-xmlIOHTTPClosePost( void * ctxt ) {
- return ( xmlIOHTTPCloseWrite( ctxt, "POST" ) );
-}
-
-#endif /* LIBXML_HTTP_ENABLED */
-
-#ifdef LIBXML_FTP_ENABLED
-/************************************************************************
- * *
- * I/O for FTP file accesses *
- * *
- ************************************************************************/
-/**
- * xmlIOFTPMatch:
- * @filename: the URI for matching
- *
- * check if the URI matches an FTP one
- *
- * Returns 1 if matches, 0 otherwise
- */
-int
-xmlIOFTPMatch (const char *filename) {
- if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "ftp://", 6))
- return(1);
- return(0);
-}
-
-/**
- * xmlIOFTPOpen:
- * @filename: the URI for matching
- *
- * open an FTP I/O channel
- *
- * Returns an I/O context or NULL in case of error
- */
-void *
-xmlIOFTPOpen (const char *filename) {
- return(xmlNanoFTPOpen(filename));
-}
-
-/**
- * xmlIOFTPRead:
- * @context: the I/O context
- * @buffer: where to drop data
- * @len: number of bytes to write
- *
- * Read @len bytes to @buffer from the I/O channel.
- *
- * Returns the number of bytes written
- */
-int
-xmlIOFTPRead(void * context, char * buffer, int len) {
- return(xmlNanoFTPRead(context, &buffer[0], len));
-}
-
-/**
- * xmlIOFTPClose:
- * @context: the I/O context
- *
- * Close an FTP I/O channel
- *
- * Returns 0
- */
-int
-xmlIOFTPClose (void * context) {
- return ( xmlNanoFTPClose(context) );
-}
-#endif /* LIBXML_FTP_ENABLED */
-
-
-/**
- * xmlRegisterInputCallbacks:
- * @matchFunc: the xmlInputMatchCallback
- * @openFunc: the xmlInputOpenCallback
- * @readFunc: the xmlInputReadCallback
- * @closeFunc: the xmlInputCloseCallback
- *
- * Register a new set of I/O callback for handling parser input.
- *
- * Returns the registered handler number or -1 in case of error
- */
-int
-xmlRegisterInputCallbacks(xmlInputMatchCallback matchFunc,
- xmlInputOpenCallback openFunc, xmlInputReadCallback readFunc,
- xmlInputCloseCallback closeFunc) {
- if (xmlInputCallbackNr >= MAX_INPUT_CALLBACK) {
- return(-1);
- }
- xmlInputCallbackTable[xmlInputCallbackNr].matchcallback = matchFunc;
- xmlInputCallbackTable[xmlInputCallbackNr].opencallback = openFunc;
- xmlInputCallbackTable[xmlInputCallbackNr].readcallback = readFunc;
- xmlInputCallbackTable[xmlInputCallbackNr].closecallback = closeFunc;
- return(xmlInputCallbackNr++);
-}
-
-/**
- * xmlRegisterOutputCallbacks:
- * @matchFunc: the xmlOutputMatchCallback
- * @openFunc: the xmlOutputOpenCallback
- * @writeFunc: the xmlOutputWriteCallback
- * @closeFunc: the xmlOutputCloseCallback
- *
- * Register a new set of I/O callback for handling output.
- *
- * Returns the registered handler number or -1 in case of error
- */
-int
-xmlRegisterOutputCallbacks(xmlOutputMatchCallback matchFunc,
- xmlOutputOpenCallback openFunc, xmlOutputWriteCallback writeFunc,
- xmlOutputCloseCallback closeFunc) {
- if (xmlOutputCallbackNr >= MAX_INPUT_CALLBACK) {
- return(-1);
- }
- xmlOutputCallbackTable[xmlOutputCallbackNr].matchcallback = matchFunc;
- xmlOutputCallbackTable[xmlOutputCallbackNr].opencallback = openFunc;
- xmlOutputCallbackTable[xmlOutputCallbackNr].writecallback = writeFunc;
- xmlOutputCallbackTable[xmlOutputCallbackNr].closecallback = closeFunc;
- return(xmlOutputCallbackNr++);
-}
-
-/**
- * xmlRegisterDefaultInputCallbacks:
- *
- * Registers the default compiled-in I/O handlers.
- */
-void
-xmlRegisterDefaultInputCallbacks
-(void) {
- if (xmlInputCallbackInitialized)
- return;
-
- xmlRegisterInputCallbacks(xmlFileMatch, xmlFileOpen,
- xmlFileRead, xmlFileClose);
-#ifdef HAVE_ZLIB_H
- xmlRegisterInputCallbacks(xmlGzfileMatch, xmlGzfileOpen,
- xmlGzfileRead, xmlGzfileClose);
-#endif /* HAVE_ZLIB_H */
-
-#ifdef LIBXML_HTTP_ENABLED
- xmlRegisterInputCallbacks(xmlIOHTTPMatch, xmlIOHTTPOpen,
- xmlIOHTTPRead, xmlIOHTTPClose);
-#endif /* LIBXML_HTTP_ENABLED */
-
-#ifdef LIBXML_FTP_ENABLED
- xmlRegisterInputCallbacks(xmlIOFTPMatch, xmlIOFTPOpen,
- xmlIOFTPRead, xmlIOFTPClose);
-#endif /* LIBXML_FTP_ENABLED */
- xmlInputCallbackInitialized = 1;
-}
-
-/**
- * xmlRegisterDefaultOutputCallbacks:
- *
- * Registers the default compiled-in I/O handlers.
- */
-void
-xmlRegisterDefaultOutputCallbacks
-(void) {
- if (xmlOutputCallbackInitialized)
- return;
-
- xmlRegisterOutputCallbacks(xmlFileMatch, xmlFileOpenW,
- xmlFileWrite, xmlFileClose);
-
-#ifdef LIBXML_HTTP_ENABLED
- xmlRegisterOutputCallbacks(xmlIOHTTPMatch, xmlIOHTTPDfltOpenW,
- xmlIOHTTPWrite, xmlIOHTTPClosePut);
-#endif
-
-/*********************************
- No way a-priori to distinguish between gzipped files from
- uncompressed ones except opening if existing then closing
- and saving with same compression ratio ... a pain.
-
-#ifdef HAVE_ZLIB_H
- xmlRegisterOutputCallbacks(xmlGzfileMatch, xmlGzfileOpen,
- xmlGzfileWrite, xmlGzfileClose);
-#endif
-
- Nor FTP PUT ....
-#ifdef LIBXML_FTP_ENABLED
- xmlRegisterOutputCallbacks(xmlIOFTPMatch, xmlIOFTPOpen,
- xmlIOFTPWrite, xmlIOFTPClose);
-#endif
- **********************************/
- xmlOutputCallbackInitialized = 1;
-}
-
-#ifdef LIBXML_HTTP_ENABLED
-/**
- * xmlRegisterHTTPPostCallbacks:
- *
- * By default, libxml submits HTTP output requests using the "PUT" method.
- * Calling this method changes the HTTP output method to use the "POST"
- * method instead.
- *
- */
-void
-xmlRegisterHTTPPostCallbacks( void ) {
-
- /* Register defaults if not done previously */
-
- if ( xmlOutputCallbackInitialized == 0 )
- xmlRegisterDefaultOutputCallbacks( );
-
- xmlRegisterOutputCallbacks(xmlIOHTTPMatch, xmlIOHTTPDfltOpenW,
- xmlIOHTTPWrite, xmlIOHTTPClosePost);
- return;
-}
-#endif
-
-/**
- * xmlAllocParserInputBuffer:
- * @enc: the charset encoding if known
- *
- * Create a buffered parser input for progressive parsing
- *
- * Returns the new parser input or NULL
- */
-xmlParserInputBufferPtr
-xmlAllocParserInputBuffer(xmlCharEncoding enc) {
- xmlParserInputBufferPtr ret;
-
- ret = (xmlParserInputBufferPtr) xmlMalloc(sizeof(xmlParserInputBuffer));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAllocParserInputBuffer : out of memory!\n");
- return(NULL);
- }
- memset(ret, 0, (size_t) sizeof(xmlParserInputBuffer));
- ret->buffer = xmlBufferCreate();
- if (ret->buffer == NULL) {
- xmlFree(ret);
- return(NULL);
- }
- ret->buffer->alloc = XML_BUFFER_ALLOC_DOUBLEIT;
- ret->encoder = xmlGetCharEncodingHandler(enc);
- if (ret->encoder != NULL)
- ret->raw = xmlBufferCreate();
- else
- ret->raw = NULL;
- ret->readcallback = NULL;
- ret->closecallback = NULL;
- ret->context = NULL;
-
- return(ret);
-}
-
-/**
- * xmlAllocOutputBuffer:
- * @encoder: the encoding converter or NULL
- *
- * Create a buffered parser output
- *
- * Returns the new parser output or NULL
- */
-xmlOutputBufferPtr
-xmlAllocOutputBuffer(xmlCharEncodingHandlerPtr encoder) {
- xmlOutputBufferPtr ret;
-
- ret = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlAllocOutputBuffer : out of memory!\n");
- return(NULL);
- }
- memset(ret, 0, (size_t) sizeof(xmlOutputBuffer));
- ret->buffer = xmlBufferCreate();
- if (ret->buffer == NULL) {
- xmlFree(ret);
- return(NULL);
- }
- ret->buffer->alloc = XML_BUFFER_ALLOC_DOUBLEIT;
- ret->encoder = encoder;
- if (encoder != NULL) {
- ret->conv = xmlBufferCreateSize(4000);
- /*
- * This call is designed to initiate the encoder state
- */
- xmlCharEncOutFunc(encoder, ret->conv, NULL);
- } else
- ret->conv = NULL;
- ret->writecallback = NULL;
- ret->closecallback = NULL;
- ret->context = NULL;
- ret->written = 0;
-
- return(ret);
-}
-
-/**
- * xmlFreeParserInputBuffer:
- * @in: a buffered parser input
- *
- * Free up the memory used by a buffered parser input
- */
-void
-xmlFreeParserInputBuffer(xmlParserInputBufferPtr in) {
- if (in->raw) {
- xmlBufferFree(in->raw);
- in->raw = NULL;
- }
- if (in->encoder != NULL) {
- xmlCharEncCloseFunc(in->encoder);
- }
- if (in->closecallback != NULL) {
- in->closecallback(in->context);
- }
- if (in->buffer != NULL) {
- xmlBufferFree(in->buffer);
- in->buffer = NULL;
- }
-
- xmlFree(in);
-}
-
-/**
- * xmlOutputBufferClose:
- * @out: a buffered output
- *
- * flushes and close the output I/O channel
- * and free up all the associated resources
- *
- * Returns the number of byte written or -1 in case of error.
- */
-int
-xmlOutputBufferClose(xmlOutputBufferPtr out) {
- int written;
- int err_rc = 0;
-
- if (out == NULL)
- return(-1);
- if (out->writecallback != NULL)
- xmlOutputBufferFlush(out);
- if (out->closecallback != NULL) {
- err_rc = out->closecallback(out->context);
- }
- written = out->written;
- if (out->conv) {
- xmlBufferFree(out->conv);
- out->conv = NULL;
- }
- if (out->encoder != NULL) {
- xmlCharEncCloseFunc(out->encoder);
- }
- if (out->buffer != NULL) {
- xmlBufferFree(out->buffer);
- out->buffer = NULL;
- }
-
- xmlFree(out);
- return( ( err_rc == 0 ) ? written : err_rc );
-}
-
-/**
- * xmlParserInputBufferCreateFname:
- * @URI: a C string containing the URI or filename
- * @enc: the charset encoding if known
- *
- * Returns the new parser input or NULL
- */
-/**
- * xmlParserInputBufferCreateFilename:
- * @URI: a C string containing the URI or filename
- * @enc: the charset encoding if known
- *
- * Create a buffered parser input for the progressive parsing of a file
- * If filename is "-' then we use stdin as the input.
- * Automatic support for ZLIB/Compress compressed document is provided
- * by default if found at compile-time.
- * Do an encoding check if enc == XML_CHAR_ENCODING_NONE
- *
- * Returns the new parser input or NULL
- */
-xmlParserInputBufferPtr
-xmlParserInputBufferCreateFilename
-(const char *URI, xmlCharEncoding enc) {
- xmlParserInputBufferPtr ret;
- int i = 0;
- void *context = NULL;
- char *unescaped;
- char *normalized;
-
- if (xmlInputCallbackInitialized == 0)
- xmlRegisterDefaultInputCallbacks();
-
- if (URI == NULL) return(NULL);
- normalized = (char *) xmlNormalizeWindowsPath((const xmlChar *)URI);
- if (normalized == NULL) return(NULL);
-
-#ifdef LIBXML_CATALOG_ENABLED
-#endif
-
- /*
- * Try to find one of the input accept method accepting that scheme
- * Go in reverse to give precedence to user defined handlers.
- * try with an unescaped version of the URI
- */
- unescaped = xmlURIUnescapeString((char *) normalized, 0, NULL);
- if (unescaped != NULL) {
- for (i = xmlInputCallbackNr - 1;i >= 0;i--) {
- if ((xmlInputCallbackTable[i].matchcallback != NULL) &&
- (xmlInputCallbackTable[i].matchcallback(unescaped) != 0)) {
- context = xmlInputCallbackTable[i].opencallback(unescaped);
- if (context != NULL)
- break;
- }
- }
- xmlFree(unescaped);
- }
-
- /*
- * If this failed try with a non-escaped URI this may be a strange
- * filename
- */
- if (context == NULL) {
- for (i = xmlInputCallbackNr - 1;i >= 0;i--) {
- if ((xmlInputCallbackTable[i].matchcallback != NULL) &&
- (xmlInputCallbackTable[i].matchcallback(URI) != 0)) {
- context = xmlInputCallbackTable[i].opencallback(normalized);
- if (context != NULL)
- break;
- }
- }
- }
- xmlFree(normalized);
- if (context == NULL) {
- return(NULL);
- }
-
- /*
- * Allocate the Input buffer front-end.
- */
- ret = xmlAllocParserInputBuffer(enc);
- if (ret != NULL) {
- ret->context = context;
- ret->readcallback = xmlInputCallbackTable[i].readcallback;
- ret->closecallback = xmlInputCallbackTable[i].closecallback;
- }
- return(ret);
-}
-
-/**
- * xmlOutputBufferCreateFilename:
- * @URI: a C string containing the URI or filename
- * @encoder: the encoding converter or NULL
- * @compression: the compression ration (0 none, 9 max).
- *
- * Create a buffered output for the progressive saving of a file
- * If filename is "-' then we use stdout as the output.
- * Automatic support for ZLIB/Compress compressed document is provided
- * by default if found at compile-time.
- * TODO: currently if compression is set, the library only support
- * writing to a local file.
- *
- * Returns the new output or NULL
- */
-xmlOutputBufferPtr
-xmlOutputBufferCreateFilename(const char *URI,
- xmlCharEncodingHandlerPtr encoder,
- int compression) {
- xmlOutputBufferPtr ret;
- int i = 0;
- void *context = NULL;
- char *unescaped;
- char *normalized;
-
- int is_http_uri = 0; /* Can't change if HTTP disabled */
-
- if (xmlOutputCallbackInitialized == 0)
- xmlRegisterDefaultOutputCallbacks();
-
- if (URI == NULL) return(NULL);
- normalized = (char *) xmlNormalizeWindowsPath((const xmlChar *)URI);
- if (normalized == NULL) return(NULL);
-
-#ifdef LIBXML_HTTP_ENABLED
- /* Need to prevent HTTP URI's from falling into zlib short circuit */
-
- is_http_uri = xmlIOHTTPMatch( normalized );
-#endif
-
-
- /*
- * Try to find one of the output accept method accepting that scheme
- * Go in reverse to give precedence to user defined handlers.
- * try with an unescaped version of the URI
- */
- unescaped = xmlURIUnescapeString(normalized, 0, NULL);
- if (unescaped != NULL) {
-#ifdef HAVE_ZLIB_H
- if ((compression > 0) && (compression <= 9) && (is_http_uri == 0)) {
- context = xmlGzfileOpenW(unescaped, compression);
- if (context != NULL) {
- ret = xmlAllocOutputBuffer(encoder);
- if (ret != NULL) {
- ret->context = context;
- ret->writecallback = xmlGzfileWrite;
- ret->closecallback = xmlGzfileClose;
- }
- xmlFree(unescaped);
- xmlFree(normalized);
- return(ret);
- }
- }
-#endif
- for (i = xmlOutputCallbackNr - 1;i >= 0;i--) {
- if ((xmlOutputCallbackTable[i].matchcallback != NULL) &&
- (xmlOutputCallbackTable[i].matchcallback(unescaped) != 0)) {
-#if defined(LIBXML_HTTP_ENABLED) && defined(HAVE_ZLIB_H)
- /* Need to pass compression parameter into HTTP open calls */
- if (xmlOutputCallbackTable[i].matchcallback == xmlIOHTTPMatch)
- context = xmlIOHTTPOpenW(unescaped, compression);
- else
-#endif
- context = xmlOutputCallbackTable[i].opencallback(unescaped);
- if (context != NULL)
- break;
- }
- }
- xmlFree(unescaped);
- }
-
- /*
- * If this failed try with a non-escaped URI this may be a strange
- * filename
- */
- if (context == NULL) {
-#ifdef HAVE_ZLIB_H
- if ((compression > 0) && (compression <= 9) && (is_http_uri == 0)) {
- context = xmlGzfileOpenW(normalized, compression);
- if (context != NULL) {
- ret = xmlAllocOutputBuffer(encoder);
- if (ret != NULL) {
- ret->context = context;
- ret->writecallback = xmlGzfileWrite;
- ret->closecallback = xmlGzfileClose;
- }
- xmlFree(normalized);
- return(ret);
- }
- }
-#endif
- for (i = xmlOutputCallbackNr - 1;i >= 0;i--) {
- if ((xmlOutputCallbackTable[i].matchcallback != NULL) &&
- (xmlOutputCallbackTable[i].matchcallback(normalized) != 0)) {
-#if defined(LIBXML_HTTP_ENABLED) && defined(HAVE_ZLIB_H)
- /* Need to pass compression parameter into HTTP open calls */
- if (xmlOutputCallbackTable[i].matchcallback == xmlIOHTTPMatch)
- context = xmlIOHTTPOpenW(URI, compression);
- else
-#endif
- context = xmlOutputCallbackTable[i].opencallback(URI);
- if (context != NULL)
- break;
- }
- }
- }
- xmlFree(normalized);
-
- if (context == NULL) {
- return(NULL);
- }
-
- /*
- * Allocate the Output buffer front-end.
- */
- ret = xmlAllocOutputBuffer(encoder);
- if (ret != NULL) {
- ret->context = context;
- ret->writecallback = xmlOutputCallbackTable[i].writecallback;
- ret->closecallback = xmlOutputCallbackTable[i].closecallback;
- }
- return(ret);
-}
-
-/**
- * xmlParserInputBufferCreateFile:
- * @file: a FILE*
- * @enc: the charset encoding if known
- *
- * Create a buffered parser input for the progressive parsing of a FILE *
- * buffered C I/O
- *
- * Returns the new parser input or NULL
- */
-xmlParserInputBufferPtr
-xmlParserInputBufferCreateFile(FILE *file, xmlCharEncoding enc) {
- xmlParserInputBufferPtr ret;
-
- if (xmlInputCallbackInitialized == 0)
- xmlRegisterDefaultInputCallbacks();
-
- if (file == NULL) return(NULL);
-
- ret = xmlAllocParserInputBuffer(enc);
- if (ret != NULL) {
- ret->context = file;
- ret->readcallback = xmlFileRead;
- ret->closecallback = xmlFileFlush;
- }
-
- return(ret);
-}
-
-/**
- * xmlOutputBufferCreateFile:
- * @file: a FILE*
- * @encoder: the encoding converter or NULL
- *
- * Create a buffered output for the progressive saving to a FILE *
- * buffered C I/O
- *
- * Returns the new parser output or NULL
- */
-xmlOutputBufferPtr
-xmlOutputBufferCreateFile(FILE *file, xmlCharEncodingHandlerPtr encoder) {
- xmlOutputBufferPtr ret;
-
- if (xmlOutputCallbackInitialized == 0)
- xmlRegisterDefaultOutputCallbacks();
-
- if (file == NULL) return(NULL);
-
- ret = xmlAllocOutputBuffer(encoder);
- if (ret != NULL) {
- ret->context = file;
- ret->writecallback = xmlFileWrite;
- ret->closecallback = xmlFileFlush;
- }
-
- return(ret);
-}
-
-/**
- * xmlParserInputBufferCreateFd:
- * @fd: a file descriptor number
- * @enc: the charset encoding if known
- *
- * Create a buffered parser input for the progressive parsing for the input
- * from a file descriptor
- *
- * Returns the new parser input or NULL
- */
-xmlParserInputBufferPtr
-xmlParserInputBufferCreateFd(int fd, xmlCharEncoding enc) {
- xmlParserInputBufferPtr ret;
-
- if (fd < 0) return(NULL);
-
- ret = xmlAllocParserInputBuffer(enc);
- if (ret != NULL) {
- ret->context = (void *) (long) fd;
- ret->readcallback = xmlFdRead;
- ret->closecallback = xmlFdClose;
- }
-
- return(ret);
-}
-
-/**
- * xmlParserInputBufferCreateMem:
- * @mem: the memory input
- * @size: the length of the memory block
- * @enc: the charset encoding if known
- *
- * Create a buffered parser input for the progressive parsing for the input
- * from a memory area.
- *
- * Returns the new parser input or NULL
- */
-xmlParserInputBufferPtr
-xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
- xmlParserInputBufferPtr ret;
-
- if (size <= 0) return(NULL);
- if (mem == NULL) return(NULL);
-
- ret = xmlAllocParserInputBuffer(enc);
- if (ret != NULL) {
- ret->context = (void *) mem;
- ret->readcallback = (xmlInputReadCallback) xmlNop;
- ret->closecallback = NULL;
- xmlBufferAdd(ret->buffer, (const xmlChar *) mem, size);
- }
-
- return(ret);
-}
-
-/**
- * xmlOutputBufferCreateFd:
- * @fd: a file descriptor number
- * @encoder: the encoding converter or NULL
- *
- * Create a buffered output for the progressive saving
- * to a file descriptor
- *
- * Returns the new parser output or NULL
- */
-xmlOutputBufferPtr
-xmlOutputBufferCreateFd(int fd, xmlCharEncodingHandlerPtr encoder) {
- xmlOutputBufferPtr ret;
-
- if (fd < 0) return(NULL);
-
- ret = xmlAllocOutputBuffer(encoder);
- if (ret != NULL) {
- ret->context = (void *) (long) fd;
- ret->writecallback = xmlFdWrite;
- ret->closecallback = NULL;
- }
-
- return(ret);
-}
-
-/**
- * xmlParserInputBufferCreateIO:
- * @ioread: an I/O read function
- * @ioclose: an I/O close function
- * @ioctx: an I/O handler
- * @enc: the charset encoding if known
- *
- * Create a buffered parser input for the progressive parsing for the input
- * from an I/O handler
- *
- * Returns the new parser input or NULL
- */
-xmlParserInputBufferPtr
-xmlParserInputBufferCreateIO(xmlInputReadCallback ioread,
- xmlInputCloseCallback ioclose, void *ioctx, xmlCharEncoding enc) {
- xmlParserInputBufferPtr ret;
-
- if (ioread == NULL) return(NULL);
-
- ret = xmlAllocParserInputBuffer(enc);
- if (ret != NULL) {
- ret->context = (void *) ioctx;
- ret->readcallback = ioread;
- ret->closecallback = ioclose;
- }
-
- return(ret);
-}
-
-/**
- * xmlOutputBufferCreateIO:
- * @iowrite: an I/O write function
- * @ioclose: an I/O close function
- * @ioctx: an I/O handler
- * @encoder: the charset encoding if known
- *
- * Create a buffered output for the progressive saving
- * to an I/O handler
- *
- * Returns the new parser output or NULL
- */
-xmlOutputBufferPtr
-xmlOutputBufferCreateIO(xmlOutputWriteCallback iowrite,
- xmlOutputCloseCallback ioclose, void *ioctx,
- xmlCharEncodingHandlerPtr encoder) {
- xmlOutputBufferPtr ret;
-
- if (iowrite == NULL) return(NULL);
-
- ret = xmlAllocOutputBuffer(encoder);
- if (ret != NULL) {
- ret->context = (void *) ioctx;
- ret->writecallback = iowrite;
- ret->closecallback = ioclose;
- }
-
- return(ret);
-}
-
-/**
- * xmlParserInputBufferPush:
- * @in: a buffered parser input
- * @len: the size in bytes of the array.
- * @buf: an char array
- *
- * Push the content of the arry in the input buffer
- * This routine handle the I18N transcoding to internal UTF-8
- * This is used when operating the parser in progressive (push) mode.
- *
- * Returns the number of chars read and stored in the buffer, or -1
- * in case of error.
- */
-int
-xmlParserInputBufferPush(xmlParserInputBufferPtr in,
- int len, const char *buf) {
- int nbchars = 0;
-
- if (len < 0) return(0);
- if (in->encoder != NULL) {
- /*
- * Store the data in the incoming raw buffer
- */
- if (in->raw == NULL) {
- in->raw = xmlBufferCreate();
- }
- xmlBufferAdd(in->raw, (const xmlChar *) buf, len);
-
- /*
- * convert as much as possible to the parser reading buffer.
- */
- nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
- if (nbchars < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlParserInputBufferPush: encoder error\n");
- return(-1);
- }
- } else {
- nbchars = len;
- xmlBufferAdd(in->buffer, (xmlChar *) buf, nbchars);
- }
-#ifdef DEBUG_INPUT
- xmlGenericError(xmlGenericErrorContext,
- "I/O: pushed %d chars, buffer %d/%d\n",
- nbchars, in->buffer->use, in->buffer->size);
-#endif
- return(nbchars);
-}
-
-/**
- * endOfInput:
- *
- * When reading from an Input channel indicated end of file or error
- * don't reread from it again.
- */
-static int
-endOfInput (void * context ATTRIBUTE_UNUSED,
- char * buffer ATTRIBUTE_UNUSED,
- int len ATTRIBUTE_UNUSED) {
- return(0);
-}
-
-/**
- * xmlParserInputBufferGrow:
- * @in: a buffered parser input
- * @len: indicative value of the amount of chars to read
- *
- * Grow up the content of the input buffer, the old data are preserved
- * This routine handle the I18N transcoding to internal UTF-8
- * This routine is used when operating the parser in normal (pull) mode
- *
- * TODO: one should be able to remove one extra copy by copying directly
- * onto in->buffer or in->raw
- *
- * Returns the number of chars read and stored in the buffer, or -1
- * in case of error.
- */
-int
-xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) {
- char *buffer = NULL;
- int res = 0;
- int nbchars = 0;
- int buffree;
- unsigned int needSize;
-
- if ((len <= MINLEN) && (len != 4))
- len = MINLEN;
- buffree = in->buffer->size - in->buffer->use;
- if (buffree <= 0) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlParserInputBufferGrow : buffer full !\n");
- return(0);
- }
- if (len > buffree)
- len = buffree;
-
- needSize = in->buffer->use + len + 1;
- if (needSize > in->buffer->size){
- if (!xmlBufferResize(in->buffer, needSize)){
- xmlGenericError(xmlGenericErrorContext,
- "xmlBufferAdd : out of memory!\n");
- return(0);
- }
- }
- buffer = (char *)&in->buffer->content[in->buffer->use];
-
- /*
- * Call the read method for this I/O type.
- */
- if (in->readcallback != NULL) {
- res = in->readcallback(in->context, &buffer[0], len);
- if (res <= 0)
- in->readcallback = endOfInput;
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "xmlParserInputBufferGrow : no input !\n");
- return(-1);
- }
- if (res < 0) {
- return(-1);
- }
- len = res;
- if (in->encoder != NULL) {
- /*
- * Store the data in the incoming raw buffer
- */
- if (in->raw == NULL) {
- in->raw = xmlBufferCreate();
- }
- xmlBufferAdd(in->raw, (const xmlChar *) buffer, len);
-
- /*
- * convert as much as possible to the parser reading buffer.
- */
- nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
- if (nbchars < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlParserInputBufferGrow: encoder error\n");
- return(-1);
- }
- } else {
- nbchars = len;
- in->buffer->use += nbchars;
- buffer[nbchars] = 0;
- }
-#ifdef DEBUG_INPUT
- xmlGenericError(xmlGenericErrorContext,
- "I/O: read %d chars, buffer %d/%d\n",
- nbchars, in->buffer->use, in->buffer->size);
-#endif
- return(nbchars);
-}
-
-/**
- * xmlParserInputBufferRead:
- * @in: a buffered parser input
- * @len: indicative value of the amount of chars to read
- *
- * Refresh the content of the input buffer, the old data are considered
- * consumed
- * This routine handle the I18N transcoding to internal UTF-8
- *
- * Returns the number of chars read and stored in the buffer, or -1
- * in case of error.
- */
-int
-xmlParserInputBufferRead(xmlParserInputBufferPtr in, int len) {
- /* xmlBufferEmpty(in->buffer); */
- if (in->readcallback != NULL)
- return(xmlParserInputBufferGrow(in, len));
- else
- return(-1);
-}
-
-/**
- * xmlOutputBufferWrite:
- * @out: a buffered parser output
- * @len: the size in bytes of the array.
- * @buf: an char array
- *
- * Write the content of the array in the output I/O buffer
- * This routine handle the I18N transcoding from internal UTF-8
- * The buffer is lossless, i.e. will store in case of partial
- * or delayed writes.
- *
- * Returns the number of chars immediately written, or -1
- * in case of error.
- */
-int
-xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) {
- int nbchars = 0; /* number of chars to output to I/O */
- int ret; /* return from function call */
- int written = 0; /* number of char written to I/O so far */
- int chunk; /* number of byte curreent processed from buf */
-
- if (len < 0) return(0);
-
- do {
- chunk = len;
- if (chunk > 4 * MINLEN)
- chunk = 4 * MINLEN;
-
- /*
- * first handle encoding stuff.
- */
- if (out->encoder != NULL) {
- /*
- * Store the data in the incoming raw buffer
- */
- if (out->conv == NULL) {
- out->conv = xmlBufferCreate();
- }
- xmlBufferAdd(out->buffer, (const xmlChar *) buf, chunk);
-
- if ((out->buffer->use < MINLEN) && (chunk == len))
- goto done;
-
- /*
- * convert as much as possible to the parser reading buffer.
- */
- ret = xmlCharEncOutFunc(out->encoder, out->conv, out->buffer);
- if (ret < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlOutputBufferWrite: encoder error\n");
- return(-1);
- }
- nbchars = out->conv->use;
- } else {
- xmlBufferAdd(out->buffer, (const xmlChar *) buf, chunk);
- nbchars = out->buffer->use;
- }
- buf += chunk;
- len -= chunk;
-
- if ((nbchars < MINLEN) && (len <= 0))
- goto done;
-
- if (out->writecallback) {
- /*
- * second write the stuff to the I/O channel
- */
- if (out->encoder != NULL) {
- ret = out->writecallback(out->context,
- (const char *)out->conv->content, nbchars);
- if (ret >= 0)
- xmlBufferShrink(out->conv, ret);
- } else {
- ret = out->writecallback(out->context,
- (const char *)out->buffer->content, nbchars);
- if (ret >= 0)
- xmlBufferShrink(out->buffer, ret);
- }
- if (ret < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "I/O: error %d writing %d bytes\n", ret, nbchars);
- return(ret);
- }
- out->written += ret;
- }
- written += nbchars;
- } while (len > 0);
-
-done:
-#ifdef DEBUG_INPUT
- xmlGenericError(xmlGenericErrorContext,
- "I/O: wrote %d chars\n", written);
-#endif
- return(written);
-}
-
-/**
- * xmlOutputBufferWriteString:
- * @out: a buffered parser output
- * @str: a zero terminated C string
- *
- * Write the content of the string in the output I/O buffer
- * This routine handle the I18N transcoding from internal UTF-8
- * The buffer is lossless, i.e. will store in case of partial
- * or delayed writes.
- *
- * Returns the number of chars immediately written, or -1
- * in case of error.
- */
-int
-xmlOutputBufferWriteString(xmlOutputBufferPtr out, const char *str) {
- int len;
-
- if (str == NULL)
- return(-1);
- len = strlen(str);
-
- if (len > 0)
- return(xmlOutputBufferWrite(out, len, str));
- return(len);
-}
-
-/**
- * xmlOutputBufferFlush:
- * @out: a buffered output
- *
- * flushes the output I/O channel
- *
- * Returns the number of byte written or -1 in case of error.
- */
-int
-xmlOutputBufferFlush(xmlOutputBufferPtr out) {
- int nbchars = 0, ret = 0;
-
- /*
- * first handle encoding stuff.
- */
- if ((out->conv != NULL) && (out->encoder != NULL)) {
- /*
- * convert as much as possible to the parser reading buffer.
- */
- nbchars = xmlCharEncOutFunc(out->encoder, out->conv, out->buffer);
- if (nbchars < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlOutputBufferFlush: encoder error\n");
- return(-1);
- }
- }
-
- /*
- * second flush the stuff to the I/O channel
- */
- if ((out->conv != NULL) && (out->encoder != NULL) &&
- (out->writecallback != NULL)) {
- ret = out->writecallback(out->context,
- (const char *)out->conv->content, out->conv->use);
- if (ret >= 0)
- xmlBufferShrink(out->conv, ret);
- } else if (out->writecallback != NULL) {
- ret = out->writecallback(out->context,
- (const char *)out->buffer->content, out->buffer->use);
- if (ret >= 0)
- xmlBufferShrink(out->buffer, ret);
- }
- if (ret < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "I/O: error %d flushing %d bytes\n", ret, nbchars);
- return(ret);
- }
- out->written += ret;
-
-#ifdef DEBUG_INPUT
- xmlGenericError(xmlGenericErrorContext,
- "I/O: flushed %d chars\n", ret);
-#endif
- return(ret);
-}
-
-/**
- * xmlParserGetDirectory:
- * @filename: the path to a file
- *
- * lookup the directory for that file
- *
- * Returns a new allocated string containing the directory, or NULL.
- */
-char *
-xmlParserGetDirectory(const char *filename) {
- char *ret = NULL;
- char dir[1024];
- char *cur;
- char sep = '/';
-
-#ifdef _WIN32_WCE /* easy way by now ... wince does not have dirs! */
- return NULL;
-#endif
-
- if (xmlInputCallbackInitialized == 0)
- xmlRegisterDefaultInputCallbacks();
-
- if (filename == NULL) return(NULL);
-#if defined(WIN32) && !defined(__CYGWIN__)
- sep = '\\';
-#endif
-
- strncpy(dir, filename, 1023);
- dir[1023] = 0;
- cur = &dir[strlen(dir)];
- while (cur > dir) {
- if (*cur == sep) break;
- cur --;
- }
- if (*cur == sep) {
- if (cur == dir) dir[1] = 0;
- else *cur = 0;
- ret = xmlMemStrdup(dir);
- } else {
- if (getcwd(dir, 1024) != NULL) {
- dir[1023] = 0;
- ret = xmlMemStrdup(dir);
- }
- }
- return(ret);
-}
-
-/****************************************************************
- * *
- * External entities loading *
- * *
- ****************************************************************/
-
-#ifdef LIBXML_CATALOG_ENABLED
-static int xmlSysIDExists(const char *URL) {
-#ifdef HAVE_STAT
- int ret;
- struct stat info;
- const char *path;
-
- if (URL == NULL)
- return(0);
-
- if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file://localhost/", 17))
-#if defined (_WIN32) && !defined(__CYGWIN__)
- path = &URL[17];
-#else
- path = &URL[16];
-#endif
- else if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file:///", 8)) {
-#if defined (_WIN32) && !defined(__CYGWIN__)
- path = &URL[8];
-#else
- path = &URL[7];
-#endif
- } else
- path = URL;
- ret = stat(path, &info);
- if (ret == 0)
- return(1);
-#endif
- return(0);
-}
-#endif
-
-/**
- * xmlDefaultExternalEntityLoader:
- * @URL: the URL for the entity to load
- * @ID: the System ID for the entity to load
- * @ctxt: the context in which the entity is called or NULL
- *
- * By default we don't load external entitites, yet.
- *
- * Returns a new allocated xmlParserInputPtr, or NULL.
- */
-static
-xmlParserInputPtr
-xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
- xmlParserCtxtPtr ctxt) {
- xmlParserInputPtr ret = NULL;
- xmlChar *resource = NULL;
-#ifdef LIBXML_CATALOG_ENABLED
- xmlCatalogAllow pref;
-#endif
-
-#ifdef DEBUG_EXTERNAL_ENTITIES
- xmlGenericError(xmlGenericErrorContext,
- "xmlDefaultExternalEntityLoader(%s, xxx)\n", URL);
-#endif
-#ifdef LIBXML_CATALOG_ENABLED
- /*
- * If the resource doesn't exists as a file,
- * try to load it from the resource pointed in the catalogs
- */
- pref = xmlCatalogGetDefaults();
-
- if ((pref != XML_CATA_ALLOW_NONE) && (!xmlSysIDExists(URL))) {
- /*
- * Do a local lookup
- */
- if ((ctxt->catalogs != NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_DOCUMENT))) {
- resource = xmlCatalogLocalResolve(ctxt->catalogs,
- (const xmlChar *)ID,
- (const xmlChar *)URL);
- }
- /*
- * Try a global lookup
- */
- if ((resource == NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_GLOBAL))) {
- resource = xmlCatalogResolve((const xmlChar *)ID,
- (const xmlChar *)URL);
- }
- if ((resource == NULL) && (URL != NULL))
- resource = xmlStrdup((const xmlChar *) URL);
-
- /*
- * TODO: do an URI lookup on the reference
- */
- if ((resource != NULL) && (!xmlSysIDExists((const char *)resource))) {
- xmlChar *tmp = NULL;
-
- if ((ctxt->catalogs != NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_DOCUMENT))) {
- tmp = xmlCatalogLocalResolveURI(ctxt->catalogs, resource);
- }
- if ((tmp == NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_GLOBAL))) {
- tmp = xmlCatalogResolveURI(resource);
- }
-
- if (tmp != NULL) {
- xmlFree(resource);
- resource = tmp;
- }
- }
- }
-#endif
-
- if (resource == NULL)
- resource = (xmlChar *) URL;
-
- if (resource == NULL) {
- if (ID == NULL)
- ID = "NULL";
- if ((ctxt->validate) && (ctxt->sax != NULL) &&
- (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt,
- "failed to load external entity \"%s\"\n", ID);
- else if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt,
- "failed to load external entity \"%s\"\n", ID);
- return(NULL);
- }
- ret = xmlNewInputFromFile(ctxt, (const char *)resource);
- if (ret == NULL) {
- if ((ctxt->validate) && (ctxt->sax != NULL) &&
- (ctxt->sax->error != NULL))
- ctxt->sax->error(ctxt,
- "failed to load external entity \"%s\"\n", resource);
- else if ((ctxt->sax != NULL) && (ctxt->sax->warning != NULL))
- ctxt->sax->warning(ctxt,
- "failed to load external entity \"%s\"\n", resource);
- }
- if ((resource != NULL) && (resource != (xmlChar *) URL))
- xmlFree(resource);
- return(ret);
-}
-
-static xmlExternalEntityLoader xmlCurrentExternalEntityLoader =
- xmlDefaultExternalEntityLoader;
-
-/**
- * xmlSetExternalEntityLoader:
- * @f: the new entity resolver function
- *
- * Changes the defaultexternal entity resolver function for the application
- */
-void
-xmlSetExternalEntityLoader(xmlExternalEntityLoader f) {
- xmlCurrentExternalEntityLoader = f;
-}
-
-/**
- * xmlGetExternalEntityLoader:
- *
- * Get the default external entity resolver function for the application
- *
- * Returns the xmlExternalEntityLoader function pointer
- */
-xmlExternalEntityLoader
-xmlGetExternalEntityLoader(void) {
- return(xmlCurrentExternalEntityLoader);
-}
-
-/**
- * xmlLoadExternalEntity:
- * @URL: the URL for the entity to load
- * @ID: the Public ID for the entity to load
- * @ctxt: the context in which the entity is called or NULL
- *
- * Load an external entity, note that the use of this function for
- * unparsed entities may generate problems
- * TODO: a more generic External entity API must be designed
- *
- * Returns the xmlParserInputPtr or NULL
- */
-xmlParserInputPtr
-xmlLoadExternalEntity(const char *URL, const char *ID,
- xmlParserCtxtPtr ctxt) {
- return(xmlCurrentExternalEntityLoader(URL, ID, ctxt));
-}
-
-/************************************************************************
- * *
- * Disabling Network access *
- * *
- ************************************************************************/
-
-#ifdef LIBXML_CATALOG_ENABLED
-static int
-xmlNoNetExists(const char *URL)
-{
-#ifdef HAVE_STAT
- int ret;
- struct stat info;
- const char *path;
-
- if (URL == NULL)
- return (0);
-
- if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file://localhost/", 17))
-#if defined (_WIN32) && !defined(__CYGWIN__)
- path = &URL[17];
-#else
- path = &URL[16];
-#endif
- else if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file:///", 8)) {
-#if defined (_WIN32) && !defined(__CYGWIN__)
- path = &URL[8];
-#else
- path = &URL[7];
-#endif
- } else
- path = URL;
- ret = stat(path, &info);
- if (ret == 0)
- return (1);
-#endif
- return (0);
-}
-#endif
-
-/**
- * xmlNoNetExternalEntityLoader:
- * @URL: the URL for the entity to load
- * @ID: the System ID for the entity to load
- * @ctxt: the context in which the entity is called or NULL
- *
- * A specific entity loader disabling network accesses, though still
- * allowing local catalog accesses for resolution.
- *
- * Returns a new allocated xmlParserInputPtr, or NULL.
- */
-xmlParserInputPtr
-xmlNoNetExternalEntityLoader(const char *URL, const char *ID,
- xmlParserCtxtPtr ctxt) {
- xmlParserInputPtr input = NULL;
- xmlChar *resource = NULL;
-
-#ifdef LIBXML_CATALOG_ENABLED
- xmlCatalogAllow pref;
-
- /*
- * If the resource doesn't exists as a file,
- * try to load it from the resource pointed in the catalogs
- */
- pref = xmlCatalogGetDefaults();
-
- if ((pref != XML_CATA_ALLOW_NONE) && (!xmlNoNetExists(URL))) {
- /*
- * Do a local lookup
- */
- if ((ctxt->catalogs != NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_DOCUMENT))) {
- resource = xmlCatalogLocalResolve(ctxt->catalogs,
- (const xmlChar *)ID,
- (const xmlChar *)URL);
- }
- /*
- * Try a global lookup
- */
- if ((resource == NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_GLOBAL))) {
- resource = xmlCatalogResolve((const xmlChar *)ID,
- (const xmlChar *)URL);
- }
- if ((resource == NULL) && (URL != NULL))
- resource = xmlStrdup((const xmlChar *) URL);
-
- /*
- * TODO: do an URI lookup on the reference
- */
- if ((resource != NULL) && (!xmlNoNetExists((const char *)resource))) {
- xmlChar *tmp = NULL;
-
- if ((ctxt->catalogs != NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_DOCUMENT))) {
- tmp = xmlCatalogLocalResolveURI(ctxt->catalogs, resource);
- }
- if ((tmp == NULL) &&
- ((pref == XML_CATA_ALLOW_ALL) ||
- (pref == XML_CATA_ALLOW_GLOBAL))) {
- tmp = xmlCatalogResolveURI(resource);
- }
-
- if (tmp != NULL) {
- xmlFree(resource);
- resource = tmp;
- }
- }
- }
-#endif
- if (resource == NULL)
- resource = (xmlChar *) URL;
-
- if (resource != NULL) {
- if ((!xmlStrncasecmp(BAD_CAST resource, BAD_CAST "ftp://", 6)) ||
- (!xmlStrncasecmp(BAD_CAST resource, BAD_CAST "http://", 7))) {
- xmlGenericError(xmlGenericErrorContext,
- "Attempt to load network entity %s \n", resource);
-
- if (resource != (xmlChar *) URL)
- xmlFree(resource);
- return(NULL);
- }
- }
- input = xmlDefaultExternalEntityLoader((const char *) resource, ID, ctxt);
- if (resource != (xmlChar *) URL)
- xmlFree(resource);
- return(input);
-}
-
diff --git a/bundle/libxml/xmlmemory.c b/bundle/libxml/xmlmemory.c
deleted file mode 100644
index 2add3a321d..0000000000
--- a/bundle/libxml/xmlmemory.c
+++ /dev/null
@@ -1,777 +0,0 @@
-/*
- * xmlmemory.c: libxml memory allocator wrapper.
- *
- * daniel@veillard.com
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#include <string.h>
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#else
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-#endif
-
-#ifdef HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-
-/**
- * MEM_LIST:
- *
- * keep track of all allocated blocks for error reporting
- * Always build the memory list !
- */
-#if DEBUG && !defined(MEMLIST)
-#define MEM_LIST /* keep a list of all the allocated memory blocks */
-#else
-#undef MEM_LIST
-#endif
-
-#include <libxml/xmlmemory.h>
-#include <libxml/globals.h>
-#include <libxml/xmlerror.h>
-
-void xmlMallocBreakpoint(void);
-void * xmlMemMalloc(size_t size);
-void * xmlMemRealloc(void *ptr,size_t size);
-void xmlMemFree(void *ptr);
-char * xmlMemoryStrdup(const char *str);
-
-/************************************************************************
- * *
- * Macros, variables and associated types *
- * *
- ************************************************************************/
-
-
-#ifdef xmlMalloc
-#undef xmlMalloc
-#endif
-#ifdef xmlRealloc
-#undef xmlRealloc
-#endif
-#ifdef xmlMemStrdup
-#undef xmlMemStrdup
-#endif
-
-
-/*
- * Each of the blocks allocated begin with a header containing informations
- */
-
-#define MEMTAG 0x5aa5
-
-#define MALLOC_TYPE 1
-#define REALLOC_TYPE 2
-#define STRDUP_TYPE 3
-
-typedef struct memnod {
- unsigned int mh_tag;
- unsigned int mh_type;
- unsigned long mh_number;
- size_t mh_size;
-#ifdef MEM_LIST
- struct memnod *mh_next;
- struct memnod *mh_prev;
-#endif
- const char *mh_file;
- unsigned int mh_line;
-} MEMHDR;
-
-
-#ifdef SUN4
-#define ALIGN_SIZE 16
-#else
-#define ALIGN_SIZE sizeof(double)
-#endif
-#define HDR_SIZE sizeof(MEMHDR)
-#define RESERVE_SIZE (((HDR_SIZE + (ALIGN_SIZE-1)) \
- / ALIGN_SIZE ) * ALIGN_SIZE)
-
-
-#define CLIENT_2_HDR(a) ((MEMHDR *) (((char *) (a)) - RESERVE_SIZE))
-#define HDR_2_CLIENT(a) ((void *) (((char *) (a)) + RESERVE_SIZE))
-
-
-static unsigned long debugMemSize = 0;
-static unsigned long debugMaxMemSize = 0;
-static int block=0;
-static int xmlMemStopAtBlock = 0;
-static void *xmlMemTraceBlockAt = NULL;
-static int xmlMemInitialized = 0;
-#ifdef MEM_LIST
-static MEMHDR *memlist = NULL;
-#endif
-
-static void debugmem_tag_error(void *addr);
-#ifdef MEM_LIST
-static void debugmem_list_add(MEMHDR *);
-static void debugmem_list_delete(MEMHDR *);
-#endif
-#define Mem_Tag_Err(a) debugmem_tag_error(a);
-
-#ifndef TEST_POINT
-#define TEST_POINT
-#endif
-
-/**
- * xmlMallocBreakpoint:
- *
- * Breakpoint to use in conjunction with xmlMemStopAtBlock. When the block
- * number reaches the specified value this function is called. One need to add a breakpoint
- * to it to get the context in which the given block is allocated.
- */
-
-void
-xmlMallocBreakpoint(void) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlMallocBreakpoint reached on block %d\n", xmlMemStopAtBlock);
-}
-
-/**
- * xmlMallocLoc:
- * @size: an int specifying the size in byte to allocate.
- * @file: the file name or NULL
- * @line: the line number
- *
- * a malloc() equivalent, with logging of the allocation info.
- *
- * Returns a pointer to the allocated area or NULL in case of lack of memory.
- */
-
-void *
-xmlMallocLoc(size_t size, const char * file, int line)
-{
- MEMHDR *p;
- void *ret;
-
- if (!xmlMemInitialized) xmlInitMemory();
-#ifdef DEBUG_MEMORY
- xmlGenericError(xmlGenericErrorContext,
- "Malloc(%d)\n",size);
-#endif
-
- TEST_POINT
-
- p = (MEMHDR *) malloc(RESERVE_SIZE+size);
-
- if (!p) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlMallocLoc : Out of free space\n");
- xmlMemoryDump();
- return(NULL);
- }
- p->mh_tag = MEMTAG;
- p->mh_number = ++block;
- p->mh_size = size;
- p->mh_type = MALLOC_TYPE;
- p->mh_file = file;
- p->mh_line = line;
- debugMemSize += size;
- if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
-#ifdef MEM_LIST
- debugmem_list_add(p);
-#endif
-
-#ifdef DEBUG_MEMORY
- xmlGenericError(xmlGenericErrorContext,
- "Malloc(%d) Ok\n",size);
-#endif
-
- if (xmlMemStopAtBlock == block) xmlMallocBreakpoint();
-
- ret = HDR_2_CLIENT(p);
-
- if (xmlMemTraceBlockAt == ret) {
- xmlGenericError(xmlGenericErrorContext,
- "%p : Malloc(%d) Ok\n", xmlMemTraceBlockAt, size);
- xmlMallocBreakpoint();
- }
-
- TEST_POINT
-
- return(ret);
-}
-
-/**
- * xmlMemMalloc:
- * @size: an int specifying the size in byte to allocate.
- *
- * a malloc() equivalent, with logging of the allocation info.
- *
- * Returns a pointer to the allocated area or NULL in case of lack of memory.
- */
-
-void *
-xmlMemMalloc(size_t size)
-{
- return(xmlMallocLoc(size, "none", 0));
-}
-
-/**
- * xmlReallocLoc:
- * @ptr: the initial memory block pointer
- * @size: an int specifying the size in byte to allocate.
- * @file: the file name or NULL
- * @line: the line number
- *
- * a realloc() equivalent, with logging of the allocation info.
- *
- * Returns a pointer to the allocated area or NULL in case of lack of memory.
- */
-
-void *
-xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
-{
- MEMHDR *p;
- unsigned long number;
-
- if (!xmlMemInitialized) xmlInitMemory();
- TEST_POINT
-
- p = CLIENT_2_HDR(ptr);
- number = p->mh_number;
- if (p->mh_tag != MEMTAG) {
- Mem_Tag_Err(p);
- goto error;
- }
- p->mh_tag = ~MEMTAG;
- debugMemSize -= p->mh_size;
-#ifdef MEM_LIST
- debugmem_list_delete(p);
-#endif
-
- p = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
- if (!p) {
- goto error;
- }
- if (xmlMemTraceBlockAt == ptr) {
- xmlGenericError(xmlGenericErrorContext,
- "%p : Realloced(%d -> %d) Ok\n",
- xmlMemTraceBlockAt, p->mh_size, size);
- xmlMallocBreakpoint();
- }
- p->mh_tag = MEMTAG;
- p->mh_number = number;
- p->mh_type = REALLOC_TYPE;
- p->mh_size = size;
- p->mh_file = file;
- p->mh_line = line;
- debugMemSize += size;
- if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
-#ifdef MEM_LIST
- debugmem_list_add(p);
-#endif
-
- TEST_POINT
-
- return(HDR_2_CLIENT(p));
-
-error:
- return(NULL);
-}
-
-/**
- * xmlMemRealloc:
- * @ptr: the initial memory block pointer
- * @size: an int specifying the size in byte to allocate.
- *
- * a realloc() equivalent, with logging of the allocation info.
- *
- * Returns a pointer to the allocated area or NULL in case of lack of memory.
- */
-
-void *
-xmlMemRealloc(void *ptr,size_t size) {
- return(xmlReallocLoc(ptr, size, "none", 0));
-}
-
-/**
- * xmlMemFree:
- * @ptr: the memory block pointer
- *
- * a free() equivalent, with error checking.
- */
-void
-xmlMemFree(void *ptr)
-{
- MEMHDR *p;
- char *target;
-
- if (ptr == (void *) -1) {
- xmlGenericError(xmlGenericErrorContext,
- "trying to free pointer from freed area\n");
- goto error;
- }
-
- if (xmlMemTraceBlockAt == ptr) {
- xmlGenericError(xmlGenericErrorContext,
- "%p : Freed()\n", xmlMemTraceBlockAt);
- xmlMallocBreakpoint();
- }
-
- TEST_POINT
-
- target = (char *) ptr;
-
- p = CLIENT_2_HDR(ptr);
- if (p->mh_tag != MEMTAG) {
- Mem_Tag_Err(p);
- goto error;
- }
- p->mh_tag = ~MEMTAG;
- debugMemSize -= p->mh_size;
- memset(target, -1, p->mh_size);
-
-#ifdef MEM_LIST
- debugmem_list_delete(p);
-#endif
- free(p);
-
- TEST_POINT
-
- return;
-
-error:
- xmlGenericError(xmlGenericErrorContext,
- "xmlMemFree(%lX) error\n", (unsigned long) ptr);
- xmlMallocBreakpoint();
- return;
-}
-
-/**
- * xmlMemStrdupLoc:
- * @str: the initial string pointer
- * @file: the file name or NULL
- * @line: the line number
- *
- * a strdup() equivalent, with logging of the allocation info.
- *
- * Returns a pointer to the new string or NULL if allocation error occurred.
- */
-
-char *
-xmlMemStrdupLoc(const char *str, const char *file, int line)
-{
- char *s;
- size_t size = strlen(str) + 1;
- MEMHDR *p;
-
- if (!xmlMemInitialized) xmlInitMemory();
- TEST_POINT
-
- p = (MEMHDR *) malloc(RESERVE_SIZE+size);
- if (!p) {
- goto error;
- }
- p->mh_tag = MEMTAG;
- p->mh_number = ++block;
- p->mh_size = size;
- p->mh_type = STRDUP_TYPE;
- p->mh_file = file;
- p->mh_line = line;
- debugMemSize += size;
- if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;
-#ifdef MEM_LIST
- debugmem_list_add(p);
-#endif
- s = (char *) HDR_2_CLIENT(p);
-
- if (xmlMemStopAtBlock == block) xmlMallocBreakpoint();
-
- if (s != NULL)
- strcpy(s,str);
- else
- goto error;
-
- TEST_POINT
-
- if (xmlMemTraceBlockAt == s) {
- xmlGenericError(xmlGenericErrorContext,
- "%p : Strdup() Ok\n", xmlMemTraceBlockAt);
- xmlMallocBreakpoint();
- }
-
- return(s);
-
-error:
- return(NULL);
-}
-
-/**
- * xmlMemoryStrdup:
- * @str: the initial string pointer
- *
- * a strdup() equivalent, with logging of the allocation info.
- *
- * Returns a pointer to the new string or NULL if allocation error occurred.
- */
-
-char *
-xmlMemoryStrdup(const char *str) {
- return(xmlMemStrdupLoc(str, "none", 0));
-}
-
-/**
- * xmlMemUsed:
- *
- * Provides the amount of memory currently allocated
- *
- * Returns an int representing the amount of memory allocated.
- */
-
-int
-xmlMemUsed(void) {
- return(debugMemSize);
-}
-
-#ifdef MEM_LIST
-/**
- * xmlMemContentShow:
- * @fp: a FILE descriptor used as the output file
- * @p: a memory block header
- *
- * tries to show some content from the memory block
- */
-
-static void
-xmlMemContentShow(FILE *fp, MEMHDR *p)
-{
- int i,j,len = p->mh_size;
- const char *buf = (const char *) HDR_2_CLIENT(p);
-
- if (p == NULL) {
- fprintf(fp, " NULL");
- return;
- }
-
- for (i = 0;i < len;i++) {
- if (buf[i] == 0) break;
- if (!isprint((unsigned char) buf[i])) break;
- }
- if ((i < 4) && ((buf[i] != 0) || (i == 0))) {
- if (len >= 4) {
- MEMHDR *q;
- void *cur;
-
- for (j = 0;j < len -3;j += 4) {
- cur = *((void **) &buf[j]);
- q = CLIENT_2_HDR(cur);
- p = memlist;
- while (p != NULL) {
- if (p == q) break;
- p = p->mh_next;
- }
- if ((p != NULL) && (p == q)) {
- fprintf(fp, " pointer to #%lu at index %d",
- p->mh_number, j);
- return;
- }
- }
- }
- } else if ((i == 0) && (buf[i] == 0)) {
- fprintf(fp," null");
- } else {
- if (buf[i] == 0) fprintf(fp," \"%.25s\"", buf);
- else {
- fprintf(fp," [");
- for (j = 0;j < i;j++)
- fprintf(fp,"%c", buf[j]);
- fprintf(fp,"]");
- }
- }
-}
-#endif
-
-/**
- * xmlMemShow:
- * @fp: a FILE descriptor used as the output file
- * @nr: number of entries to dump
- *
- * show a show display of the memory allocated, and dump
- * the @nr last allocated areas which were not freed
- */
-
-void
-xmlMemShow(FILE *fp, int nr)
-{
-#ifdef MEM_LIST
- MEMHDR *p;
-#endif
-
- if (fp != NULL)
- fprintf(fp," MEMORY ALLOCATED : %lu, MAX was %lu\n",
- debugMemSize, debugMaxMemSize);
-#ifdef MEM_LIST
- if (nr > 0) {
- fprintf(fp,"NUMBER SIZE TYPE WHERE\n");
- p = memlist;
- while ((p) && nr > 0) {
- fprintf(fp,"%6lu %6lu ",p->mh_number,(unsigned long)p->mh_size);
- switch (p->mh_type) {
- case STRDUP_TYPE:fprintf(fp,"strdup() in ");break;
- case MALLOC_TYPE:fprintf(fp,"malloc() in ");break;
- case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
- default:fprintf(fp," ??? in ");break;
- }
- if (p->mh_file != NULL)
- fprintf(fp,"%s(%d)", p->mh_file, p->mh_line);
- if (p->mh_tag != MEMTAG)
- fprintf(fp," INVALID");
- xmlMemContentShow(fp, p);
- fprintf(fp,"\n");
- nr--;
- p = p->mh_next;
- }
- }
-#endif /* MEM_LIST */
-}
-
-/**
- * xmlMemDisplay:
- * @fp: a FILE descriptor used as the output file, if NULL, the result is
- * written to the file .memorylist
- *
- * show in-extenso the memory blocks allocated
- */
-
-void
-xmlMemDisplay(FILE *fp)
-{
-#ifdef MEM_LIST
- MEMHDR *p;
- unsigned idx;
- int nb = 0;
-#if defined(HAVE_LOCALTIME) && defined(HAVE_STRFTIME)
- time_t currentTime;
- char buf[500];
- struct tm * tstruct;
-
- currentTime = time(NULL);
- tstruct = localtime(&currentTime);
- strftime(buf, sizeof(buf) - 1, "%I:%M:%S %p", tstruct);
- fprintf(fp," %s\n\n", buf);
-#endif
-
-
- fprintf(fp," MEMORY ALLOCATED : %lu, MAX was %lu\n",
- debugMemSize, debugMaxMemSize);
- fprintf(fp,"BLOCK NUMBER SIZE TYPE\n");
- idx = 0;
- p = memlist;
- while (p) {
- fprintf(fp,"%-5u %6lu %6lu ",idx++,p->mh_number,
- (unsigned long)p->mh_size);
- switch (p->mh_type) {
- case STRDUP_TYPE:fprintf(fp,"strdup() in ");break;
- case MALLOC_TYPE:fprintf(fp,"malloc() in ");break;
- case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
- default:fprintf(fp," ??? in ");break;
- }
- if (p->mh_file != NULL) fprintf(fp,"%s(%d)", p->mh_file, p->mh_line);
- if (p->mh_tag != MEMTAG)
- fprintf(fp," INVALID");
- nb++;
- if (nb < 100)
- xmlMemContentShow(fp, p);
- else
- fprintf(fp," skip");
-
- fprintf(fp,"\n");
- p = p->mh_next;
- }
-#else
- fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n");
-#endif
-}
-
-#ifdef MEM_LIST
-
-static void debugmem_list_add(MEMHDR *p)
-{
- p->mh_next = memlist;
- p->mh_prev = NULL;
- if (memlist) memlist->mh_prev = p;
- memlist = p;
-#ifdef MEM_LIST_DEBUG
- if (stderr)
- Mem_Display(stderr);
-#endif
-}
-
-static void debugmem_list_delete(MEMHDR *p)
-{
- if (p->mh_next)
- p->mh_next->mh_prev = p->mh_prev;
- if (p->mh_prev)
- p->mh_prev->mh_next = p->mh_next;
- else memlist = p->mh_next;
-#ifdef MEM_LIST_DEBUG
- if (stderr)
- Mem_Display(stderr);
-#endif
-}
-
-#endif
-
-/*
- * debugmem_tag_error:
- *
- * internal error function.
- */
-
-static void debugmem_tag_error(void *p)
-{
- xmlGenericError(xmlGenericErrorContext,
- "Memory tag error occurs :%p \n\t bye\n", p);
-#ifdef MEM_LIST
- if (stderr)
- xmlMemDisplay(stderr);
-#endif
-}
-
-static FILE *xmlMemoryDumpFile = NULL;
-
-
-/**
- * xmlMemoryDump:
- *
- * Dump in-extenso the memory blocks allocated to the file .memorylist
- */
-
-void
-xmlMemoryDump(void)
-{
- FILE *dump;
-
- if (debugMaxMemSize == 0)
- return;
- dump = fopen(".memdump", "w");
- if (dump == NULL)
- xmlMemoryDumpFile = stderr;
- else xmlMemoryDumpFile = dump;
-
- xmlMemDisplay(xmlMemoryDumpFile);
-
- if (dump != NULL) fclose(dump);
-}
-
-
-/****************************************************************
- * *
- * Initialization Routines *
- * *
- ****************************************************************/
-
-static int xmlInitMemoryDone = 0;
-
-/**
- * xmlInitMemory:
- *
- * Initialize the memory layer.
- *
- * Returns 0 on success
- */
-int
-xmlInitMemory(void)
-{
- int ret;
-
-#ifdef HAVE_STDLIB_H
- char *breakpoint;
-#endif
-
- if (xmlInitMemoryDone) return(-1);
-
-#ifdef HAVE_STDLIB_H
- breakpoint = getenv("XML_MEM_BREAKPOINT");
- if (breakpoint != NULL) {
- sscanf(breakpoint, "%d", &xmlMemStopAtBlock);
- }
-#endif
-#ifdef HAVE_STDLIB_H
- breakpoint = getenv("XML_MEM_TRACE");
- if (breakpoint != NULL) {
- sscanf(breakpoint, "%p", &xmlMemTraceBlockAt);
- }
-#endif
-
-#ifdef DEBUG_MEMORY
- xmlGenericError(xmlGenericErrorContext,
- "xmlInitMemory() Ok\n");
-#endif
- xmlMemInitialized = 1;
- xmlInitMemoryDone = 1;
-
- ret = 0;
- return(ret);
-}
-
-/**
- * xmlMemSetup:
- * @freeFunc: the free() function to use
- * @mallocFunc: the malloc() function to use
- * @reallocFunc: the realloc() function to use
- * @strdupFunc: the strdup() function to use
- *
- * Override the default memory access functions with a new set
- * This has to be called before any other libxml routines !
- *
- * Should this be blocked if there was already some allocations
- * done ?
- *
- * Returns 0 on success
- */
-int
-xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
- xmlReallocFunc reallocFunc, xmlStrdupFunc strdupFunc) {
- if (freeFunc == NULL)
- return(-1);
- if (mallocFunc == NULL)
- return(-1);
- if (reallocFunc == NULL)
- return(-1);
- if (strdupFunc == NULL)
- return(-1);
- xmlFree = freeFunc;
- xmlMalloc = mallocFunc;
- xmlRealloc = reallocFunc;
- xmlMemStrdup = strdupFunc;
- return(0);
-}
-
-/**
- * xmlMemGet:
- * @freeFunc: place to save the free() function in use
- * @mallocFunc: place to save the malloc() function in use
- * @reallocFunc: place to save the realloc() function in use
- * @strdupFunc: place to save the strdup() function in use
- *
- * Provides the memory access functions set currently in use
- *
- * Returns 0 on success
- */
-int
-xmlMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc,
- xmlReallocFunc *reallocFunc, xmlStrdupFunc *strdupFunc) {
- if (freeFunc != NULL) *freeFunc = xmlFree;
- if (mallocFunc != NULL) *mallocFunc = xmlMalloc;
- if (reallocFunc != NULL) *reallocFunc = xmlRealloc;
- if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup;
- return(0);
-}
-
diff --git a/bundle/libxml/xmlreader.c b/bundle/libxml/xmlreader.c
deleted file mode 100644
index 65ca8e8ae1..0000000000
--- a/bundle/libxml/xmlreader.c
+++ /dev/null
@@ -1,882 +0,0 @@
-/*
- * xmlreader.c: implements the xmlTextReader streaming node API
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#include <string.h> /* for memset() only ! */
-
-#ifdef HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#include <libxml/xmlmemory.h>
-#include <libxml/xmlIO.h>
-#include <libxml/xmlreader.h>
-
-/* #define DEBUG_CALLBACKS */
-/* #define DEBUG_READER */
-
-/**
- * TODO:
- *
- * macro to flag unimplemented blocks
- */
-#define TODO \
- xmlGenericError(xmlGenericErrorContext, \
- "Unimplemented block at %s:%d\n", \
- __FILE__, __LINE__);
-
-#ifdef DEBUG_READER
-#define DUMP_READER xmlTextReaderDebug(reader);
-#else
-#define DUMP_READER
-#endif
-
-/************************************************************************
- * *
- * The parser: maps the Text Reader API on top of the existing *
- * parsing routines building a tree *
- * *
- ************************************************************************/
-
-#define XML_TEXTREADER_INPUT 1
-#define XML_TEXTREADER_CTXT 2
-
-typedef enum {
- XML_TEXTREADER_MODE_NORMAL = 0,
- XML_TEXTREADER_MODE_EOF = 1
-} xmlTextReaderMode;
-
-typedef enum {
- XML_TEXTREADER_NONE = -1,
- XML_TEXTREADER_START= 0,
- XML_TEXTREADER_ELEMENT= 1,
- XML_TEXTREADER_END= 2,
- XML_TEXTREADER_EMPTY= 3,
- XML_TEXTREADER_BACKTRACK= 4
-} xmlTextReaderState;
-
-struct _xmlTextReader {
- int mode; /* the parsing mode */
- int allocs; /* what structure were deallocated */
- xmlTextReaderState state;
- xmlParserCtxtPtr ctxt; /* the parser context */
- xmlSAXHandlerPtr sax; /* the parser SAX callbacks */
- xmlParserInputBufferPtr input; /* the input */
- startElementSAXFunc startElement;/* initial SAX callbacks */
- endElementSAXFunc endElement; /* idem */
- unsigned int base; /* base of the segment in the input */
- unsigned int cur; /* current position in the input */
- xmlNodePtr node; /* current node */
- int depth; /* depth of the current node */
-};
-
-#ifdef DEBUG_READER
-static void
-xmlTextReaderDebug(xmlTextReaderPtr reader) {
- if ((reader == NULL) || (reader->ctxt == NULL)) {
- fprintf(stderr, "xmlTextReader NULL\n");
- return;
- }
- fprintf(stderr, "xmlTextReader: state %d depth %d ",
- reader->state, reader->depth);
- if (reader->node == NULL) {
- fprintf(stderr, "node = NULL\n");
- } else {
- fprintf(stderr, "node %s\n", reader->node->name);
- }
- fprintf(stderr, " input: base %d, cur %d, depth %d: ",
- reader->base, reader->cur, reader->ctxt->nodeNr);
- if (reader->input->buffer == NULL) {
- fprintf(stderr, "buffer is NULL\n");
- } else {
-#ifdef LIBXML_DEBUG_ENABLED
- xmlDebugDumpString(stderr,
- &reader->input->buffer->content[reader->cur]);
-#endif
- fprintf(stderr, "\n");
- }
-}
-#endif
-
-/**
- * xmlTextReaderStartElement:
- * @ctx: the user data (XML parser context)
- * @fullname: The element name, including namespace prefix
- * @atts: An array of name/value attributes pairs, NULL terminated
- *
- * called when an opening tag has been processed.
- */
-static void
-xmlTextReaderStartElement(void *ctx, const xmlChar *fullname,
- const xmlChar **atts) {
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlTextReaderPtr reader = ctxt->_private;
-
-#ifdef DEBUG_CALLBACKS
- printf("xmlTextReaderStartElement(%s)\n", fullname);
-#endif
- if ((reader != NULL) && (reader->startElement != NULL))
- reader->startElement(ctx, fullname, atts);
- reader->state = XML_TEXTREADER_ELEMENT;
-}
-
-/**
- * xmlTextReaderEndElement:
- * @ctx: the user data (XML parser context)
- * @fullname: The element name, including namespace prefix
- *
- * called when an ending tag has been processed.
- */
-static void
-xmlTextReaderEndElement(void *ctx, const xmlChar *fullname) {
- xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
- xmlTextReaderPtr reader = ctxt->_private;
-
-#ifdef DEBUG_CALLBACKS
- printf("xmlTextReaderEndElement(%s)\n", fullname);
-#endif
- if ((reader != NULL) && (reader->endElement != NULL))
- reader->endElement(ctx, fullname);
- if (reader->state == XML_TEXTREADER_ELEMENT)
- reader->state = XML_TEXTREADER_EMPTY;
- else
- reader->state = XML_TEXTREADER_END;
-}
-
-/**
- * xmlTextReaderPushData:
- * @reader: the xmlTextReaderPtr used
- *
- * Push data down the progressive parser until a significant callback
- * got raised.
- *
- * Returns -1 in case of failure, 0 otherwise
- */
-static int
-xmlTextReaderPushData(xmlTextReaderPtr reader) {
- unsigned int cur = reader->cur;
- xmlBufferPtr inbuf;
- int val;
-
- if ((reader->input == NULL) || (reader->input->buffer == NULL))
- return(-1);
-
- reader->state = XML_TEXTREADER_NONE;
- inbuf = reader->input->buffer;
- while (reader->state == XML_TEXTREADER_NONE) {
- if (cur >= inbuf->use) {
- /*
- * Refill the buffer unless we are at the end of the stream
- */
- if (reader->mode != XML_TEXTREADER_MODE_EOF) {
- val = xmlParserInputBufferRead(reader->input, 4096);
- if (val <= 0) {
- reader->mode = XML_TEXTREADER_MODE_EOF;
- return(val);
- }
- } else
- break;
- }
- if ((inbuf->content[cur] == '>') || (inbuf->content[cur] == '&')) {
- cur = cur + 1;
- val = xmlParseChunk(reader->ctxt,
- (const char *) &inbuf->content[reader->cur],
- cur - reader->cur, 0);
- if (val != 0)
- return(-1);
- reader->cur = cur;
- break;
- } else {
- cur = cur + 1;
-
- /*
- * One may have to force a flush at some point when parsing really
- * large CDATA sections
- */
- if ((cur - reader->cur > 4096) && (reader->base == 0) &&
- (reader->mode == XML_TEXTREADER_MODE_NORMAL)) {
- cur = cur + 1;
- val = xmlParseChunk(reader->ctxt,
- (const char *) &inbuf->content[reader->cur],
- cur - reader->cur, 0);
- if (val != 0)
- return(-1);
- reader->cur = cur;
- }
- }
- }
- /*
- * Discard the consumed input when needed and possible
- */
- if (reader->mode == XML_TEXTREADER_MODE_NORMAL) {
- if ((reader->cur >= 4096) && (reader->base == 0)) {
- val = xmlBufferShrink(inbuf, cur);
- if (val >= 0) {
- reader->cur -= val;
- }
- }
- }
-
- /*
- * At the end of the stream signal that the work is done to the Push
- * parser.
- */
- if ((reader->mode == XML_TEXTREADER_MODE_EOF) && (cur >= inbuf->use)) {
- val = xmlParseChunk(reader->ctxt,
- (const char *) &inbuf->content[reader->cur], 0, 1);
- }
- return(0);
-}
-
-/**
- * xmlTextReaderRead:
- * @reader: the xmlTextReaderPtr used
- *
- * Moves the position of the current instance to the next node in
- * the stream, exposing its properties.
- *
- * Returns 1 if the node was read successfully, 0 if there is no more
- * nodes to read, or -1 in case of error
- */
-int
-xmlTextReaderRead(xmlTextReaderPtr reader) {
- int val, olddepth;
- xmlTextReaderState oldstate;
- xmlNodePtr oldnode;
-
- if ((reader == NULL) || (reader->ctxt == NULL))
- return(-1);
- if (reader->ctxt->wellFormed != 1)
- return(-1);
-
-#ifdef DEBUG_READER
- fprintf(stderr, "\nREAD ");
- DUMP_READER
-#endif
- if (reader->node == NULL) {
- /*
- * Initial state
- */
- do {
- val = xmlTextReaderPushData(reader);
- if (val < 0)
- return(-1);
- } while ((reader->ctxt->node == NULL) &&
- (reader->mode != XML_TEXTREADER_MODE_EOF));
- if (reader->ctxt->node == NULL) {
- if (reader->ctxt->myDoc != NULL)
- reader->node = reader->ctxt->myDoc->children;
- if (reader->node == NULL)
- return(-1);
- } else {
- reader->node = reader->ctxt->node;
- }
- reader->depth = 1;
- return(1);
- }
- oldstate = reader->state;
- olddepth = reader->ctxt->nodeNr;
- oldnode = reader->node;
- /*
- * If we are not backtracking on ancestors or examined nodes,
- * that the parser didn't finished or that we arent at the end
- * of stream, continue processing.
- */
- if (oldstate != XML_TEXTREADER_BACKTRACK) {
- while (((reader->node->children == NULL) ||
- (reader->node->type == XML_ENTITY_REF_NODE) ||
- (reader->node->type == XML_DTD_NODE)) &&
- (reader->node->next == NULL) &&
- (reader->ctxt->nodeNr == olddepth) &&
- (reader->ctxt->instate != XML_PARSER_EOF)) {
- val = xmlTextReaderPushData(reader);
- if (val < 0)
- return(-1);
- if (reader->node == NULL)
- return(0);
- }
- if ((reader->node->children != NULL) &&
- (reader->node->type != XML_ENTITY_REF_NODE) &&
- (reader->node->type != XML_DTD_NODE)) {
- reader->node = reader->node->children;
- reader->depth++;
- if ((reader->state != XML_TEXTREADER_ELEMENT) &&
- (reader->state != XML_TEXTREADER_EMPTY))
- reader->state = XML_TEXTREADER_ELEMENT;
- DUMP_READER
- return(1);
- }
- }
- if (reader->node->next != NULL) {
- if ((oldstate == XML_TEXTREADER_ELEMENT) &&
- (reader->node->type == XML_ELEMENT_NODE)) {
- reader->state = XML_TEXTREADER_END;
- DUMP_READER
- return(1);
- }
- reader->node = reader->node->next;
- reader->state = XML_TEXTREADER_ELEMENT;
- DUMP_READER
- /*
- * Cleanup of the old node
- */
- if (oldnode->type != XML_DTD_NODE) {
- xmlUnlinkNode(oldnode);
- xmlFreeNode(oldnode);
- }
-
- return(1);
- }
- reader->node = reader->node->parent;
- if ((reader->node == NULL) ||
- (reader->node->type == XML_DOCUMENT_NODE) ||
-#ifdef LIBXML_DOCB_ENABLED
- (reader->node->type == XML_DOCB_DOCUMENT_NODE) ||
-#endif
- (reader->node->type == XML_HTML_DOCUMENT_NODE)) {
- reader->node = NULL;
- reader->depth = 0;
-
- /*
- * Cleanup of the old node
- */
- if (oldnode->type != XML_DTD_NODE) {
- xmlUnlinkNode(oldnode);
- xmlFreeNode(oldnode);
- }
-
- return(0);
- }
- reader->depth--;
- reader->state = XML_TEXTREADER_BACKTRACK;
- DUMP_READER
- return(1);
-}
-
-/************************************************************************
- * *
- * Constructor and destructors *
- * *
- ************************************************************************/
-/**
- * xmlNewTextReader:
- * @input: the xmlParserInputBufferPtr used to read data
- *
- * Create an xmlTextReader structure fed with @input
- *
- * Returns the new xmlTextReaderPtr or NULL in case of error
- */
-xmlTextReaderPtr
-xmlNewTextReader(xmlParserInputBufferPtr input) {
- xmlTextReaderPtr ret;
- int val;
-
- if (input == NULL)
- return(NULL);
- ret = xmlMalloc(sizeof(xmlTextReader));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewTextReader : malloc failed\n");
- return(NULL);
- }
- memset(ret, 0, sizeof(xmlTextReader));
- ret->input = input;
- ret->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
- if (ret->sax == NULL) {
- xmlFree(ret);
- xmlGenericError(xmlGenericErrorContext,
- "xmlNewTextReader : malloc failed\n");
- return(NULL);
- }
- memcpy(ret->sax, &xmlDefaultSAXHandler, sizeof(xmlSAXHandler));
- ret->startElement = ret->sax->startElement;
- ret->sax->startElement = xmlTextReaderStartElement;
- ret->endElement = ret->sax->endElement;
- ret->sax->endElement = xmlTextReaderEndElement;
-
- ret->mode = XML_TEXTREADER_MODE_NORMAL;
- ret->node = NULL;
- val = xmlParserInputBufferRead(input, 4);
- if (val >= 4) {
- ret->ctxt = xmlCreatePushParserCtxt(ret->sax, NULL,
- (const char *) ret->input->buffer->content, 4, NULL);
- ret->base = 0;
- ret->cur = 4;
- } else {
- ret->ctxt = xmlCreatePushParserCtxt(ret->sax, NULL, NULL, 0, NULL);
- ret->base = 0;
- ret->cur = 0;
- }
- ret->ctxt->_private = ret;
- ret->allocs = XML_TEXTREADER_CTXT;
- return(ret);
-
-}
-
-/**
- * xmlNewTextReaderFilename:
- * @URI: the URI of the resource to process
- *
- * Create an xmlTextReader structure fed with the resource at @URI
- *
- * Returns the new xmlTextReaderPtr or NULL in case of error
- */
-xmlTextReaderPtr
-xmlNewTextReaderFilename(const char *URI) {
- xmlParserInputBufferPtr input;
- xmlTextReaderPtr ret;
-
- input = xmlParserInputBufferCreateFilename(URI, XML_CHAR_ENCODING_NONE);
- if (input == NULL)
- return(NULL);
- ret = xmlNewTextReader(input);
- if (ret == NULL) {
- xmlFreeParserInputBuffer(input);
- return(NULL);
- }
- ret->allocs |= XML_TEXTREADER_INPUT;
- return(ret);
-}
-
-/**
- * xmlFreeTextReader:
- * @reader: the xmlTextReaderPtr
- *
- * Deallocate all the resources associated to the reader
- */
-void
-xmlFreeTextReader(xmlTextReaderPtr reader) {
- if (reader == NULL)
- return;
- if (reader->ctxt != NULL) {
- if (reader->ctxt->myDoc != NULL) {
- xmlFreeDoc(reader->ctxt->myDoc);
- reader->ctxt->myDoc = NULL;
- }
- if (reader->allocs & XML_TEXTREADER_CTXT)
- xmlFreeParserCtxt(reader->ctxt);
- }
- if (reader->sax != NULL)
- xmlFree(reader->sax);
- if ((reader->input != NULL) && (reader->allocs & XML_TEXTREADER_INPUT))
- xmlFreeParserInputBuffer(reader->input);
- xmlFree(reader);
-}
-
-/************************************************************************
- * *
- * Acces API to the current node *
- * *
- ************************************************************************/
-/**
- * xmlTextReaderAttributeCount:
- * @reader: the xmlTextReaderPtr used
- *
- * Provides the number of attributes of the current node
- *
- * Returns 0 i no attributes, -1 in case of error or the attribute count
- */
-int
-xmlTextReaderAttributeCount(xmlTextReaderPtr reader) {
- int ret;
- xmlAttrPtr attr;
-
- if (reader == NULL)
- return(-1);
- if (reader->node == NULL)
- return(0);
- if (reader->node->type != XML_ELEMENT_NODE)
- return(0);
- if ((reader->state == XML_TEXTREADER_END) ||
- (reader->state == XML_TEXTREADER_BACKTRACK))
- return(0);
- ret = 0;
- attr = reader->node->properties;
- while (attr != NULL) {
- ret++;
- attr = attr->next;
- }
- return(ret);
-}
-
-/**
- * xmlTextReaderNodeType:
- * @reader: the xmlTextReaderPtr used
- *
- * Get the node type of the current node
- * Reference:
- * http://dotgnu.org/pnetlib-doc/System/Xml/XmlNodeType.html
- *
- * Returns the xmlNodeType of the current node or -1 in case of error
- */
-int
-xmlTextReaderNodeType(xmlTextReaderPtr reader) {
- if (reader == NULL)
- return(-1);
- if (reader->node == NULL)
- return(0);
- switch (reader->node->type) {
- case XML_ELEMENT_NODE:
- if ((reader->state == XML_TEXTREADER_END) ||
- (reader->state == XML_TEXTREADER_BACKTRACK))
- return(15);
- return(1);
- case XML_ATTRIBUTE_NODE:
- return(2);
- case XML_TEXT_NODE:
- return(3); /* TODO: SignificantWhitespace == 14 Whitespace == 13 */
- case XML_CDATA_SECTION_NODE:
- return(4);
- case XML_ENTITY_REF_NODE:
- return(5);
- case XML_ENTITY_NODE:
- return(6);
- case XML_PI_NODE:
- return(7);
- case XML_COMMENT_NODE:
- return(8);
- case XML_DOCUMENT_NODE:
- case XML_HTML_DOCUMENT_NODE:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- return(9);
- case XML_DOCUMENT_FRAG_NODE:
- return(11);
- case XML_NOTATION_NODE:
- return(12);
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DTD_NODE:
- return(10);
-
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_NAMESPACE_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- return(0);
- }
- return(-1);
-}
-
-/**
- * xmlTextReaderIsEmptyElement:
- * @reader: the xmlTextReaderPtr used
- *
- * Check if the current node is empty
- *
- * Returns 1 if empty, 0 if not and -1 in case of error
- */
-int
-xmlTextReaderIsEmptyElement(xmlTextReaderPtr reader) {
- if ((reader == NULL) || (reader->node == NULL))
- return(-1);
- if (reader->node->children != NULL)
- return(0);
- if ((reader->state == XML_TEXTREADER_EMPTY) ||
- (reader->state == XML_TEXTREADER_BACKTRACK))
- return(1);
- return(0);
-}
-
-/**
- * xmlTextReaderLocalName:
- * @reader: the xmlTextReaderPtr used
- *
- * The local name of the node.
- *
- * Returns the local name or NULL if not available
- */
-xmlChar *
-xmlTextReaderLocalName(xmlTextReaderPtr reader) {
- if ((reader == NULL) || (reader->node == NULL))
- return(NULL);
- if ((reader->node->type != XML_ELEMENT_NODE) &&
- (reader->node->type != XML_ATTRIBUTE_NODE))
- return(xmlTextReaderName(reader));
- return(xmlStrdup(reader->node->name));
-}
-
-/**
- * xmlTextReaderName:
- * @reader: the xmlTextReaderPtr used
- *
- * The qualified name of the node, equal to Prefix :LocalName.
- *
- * Returns the local name or NULL if not available
- */
-xmlChar *
-xmlTextReaderName(xmlTextReaderPtr reader) {
- xmlChar *ret;
-
- if ((reader == NULL) || (reader->node == NULL))
- return(NULL);
- switch (reader->node->type) {
- case XML_ELEMENT_NODE:
- case XML_ATTRIBUTE_NODE:
- if ((reader->node->ns == NULL) ||
- (reader->node->ns->prefix == NULL))
- return(xmlStrdup(reader->node->name));
-
- ret = xmlStrdup(reader->node->ns->prefix);
- ret = xmlStrcat(ret, BAD_CAST ":");
- ret = xmlStrcat(ret, reader->node->name);
- return(ret);
- case XML_TEXT_NODE:
- return(xmlStrdup(BAD_CAST "#text"));
- case XML_CDATA_SECTION_NODE:
- return(xmlStrdup(BAD_CAST "#cdata-section"));
- case XML_ENTITY_NODE:
- case XML_ENTITY_REF_NODE:
- return(xmlStrdup(reader->node->name));
- case XML_PI_NODE:
- return(xmlStrdup(reader->node->name));
- case XML_COMMENT_NODE:
- return(xmlStrdup(BAD_CAST "#comment"));
- case XML_DOCUMENT_NODE:
- case XML_HTML_DOCUMENT_NODE:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- return(xmlStrdup(BAD_CAST "#document"));
- case XML_DOCUMENT_FRAG_NODE:
- return(xmlStrdup(BAD_CAST "#document-fragment"));
- case XML_NOTATION_NODE:
- return(xmlStrdup(reader->node->name));
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DTD_NODE:
- return(xmlStrdup(reader->node->name));
-
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_NAMESPACE_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- return(NULL);
- }
- return(NULL);
-}
-
-/**
- * xmlTextReaderPrefix:
- * @reader: the xmlTextReaderPtr used
- *
- * A shorthand reference to the namespace associated with the node.
- *
- * Returns the prefix or NULL if not available
- */
-xmlChar *
-xmlTextReaderPrefix(xmlTextReaderPtr reader) {
- if ((reader == NULL) || (reader->node == NULL))
- return(NULL);
- if ((reader->node->type != XML_ELEMENT_NODE) &&
- (reader->node->type != XML_ATTRIBUTE_NODE))
- return(NULL);
- if ((reader->node->ns != NULL) || (reader->node->ns->prefix != NULL))
- return(xmlStrdup(reader->node->ns->prefix));
- return(NULL);
-}
-
-/**
- * xmlTextReaderNamespaceUri:
- * @reader: the xmlTextReaderPtr used
- *
- * The URI defining the namespace associated with the node.
- *
- * Returns the namespace URI or NULL if not available
- */
-xmlChar *
-xmlTextReaderNamespaceUri(xmlTextReaderPtr reader) {
- if ((reader == NULL) || (reader->node == NULL))
- return(NULL);
- if ((reader->node->type != XML_ELEMENT_NODE) &&
- (reader->node->type != XML_ATTRIBUTE_NODE))
- return(NULL);
- if (reader->node->ns != NULL)
- return(xmlStrdup(reader->node->ns->href));
- return(NULL);
-}
-
-/**
- * xmlTextReaderBaseUri:
- * @reader: the xmlTextReaderPtr used
- *
- * The base URI of the node.
- *
- * Returns the base URI or NULL if not available
- */
-xmlChar *
-xmlTextReaderBaseUri(xmlTextReaderPtr reader) {
- if ((reader == NULL) || (reader->node == NULL))
- return(NULL);
- return(xmlNodeGetBase(NULL, reader->node));
-}
-
-/**
- * xmlTextReaderDepth:
- * @reader: the xmlTextReaderPtr used
- *
- * The depth of the node in the tree.
- *
- * Returns the depth or -1 in case of error
- */
-int
-xmlTextReaderDepth(xmlTextReaderPtr reader) {
- if (reader == NULL)
- return(-1);
- if (reader->node == NULL)
- return(0);
-
- return(reader->depth);
-}
-
-/**
- * xmlTextReaderHasAttributes:
- * @reader: the xmlTextReaderPtr used
- *
- * Whether the node has attributes.
- *
- * Returns 1 if true, 0 if false, and -1 in case or error
- */
-int
-xmlTextReaderHasAttributes(xmlTextReaderPtr reader) {
- if (reader == NULL)
- return(-1);
- if (reader->node == NULL)
- return(0);
-
- if ((reader->node->type == XML_ELEMENT_NODE) &&
- (reader->node->properties != NULL))
- return(1);
- /* TODO: handle the xmlDecl */
- return(0);
-}
-
-/**
- * xmlTextReaderHasValue:
- * @reader: the xmlTextReaderPtr used
- *
- * Whether the node can have a text value.
- *
- * Returns 1 if true, 0 if false, and -1 in case or error
- */
-int
-xmlTextReaderHasValue(xmlTextReaderPtr reader) {
- if (reader == NULL)
- return(-1);
- if (reader->node == NULL)
- return(0);
-
- switch (reader->node->type) {
- case XML_ATTRIBUTE_NODE:
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- return(1);
- default:
- return(0);
- }
- return(0);
-}
-
-/**
- * xmlTextReaderValue:
- * @reader: the xmlTextReaderPtr used
- *
- * Provides the text value of the node if present
- *
- * Returns the string or NULL if not available. The retsult must be deallocated
- * with xmlFree()
- */
-xmlChar *
-xmlTextReaderValue(xmlTextReaderPtr reader) {
- if (reader == NULL)
- return(NULL);
- if (reader->node == NULL)
- return(NULL);
-
- switch (reader->node->type) {
- case XML_ATTRIBUTE_NODE:{
- xmlAttrPtr attr = (xmlAttrPtr) reader->node;
-
- if (attr->parent != NULL)
- return (xmlNodeListGetString
- (attr->parent->doc, attr->children, 1));
- else
- return (xmlNodeListGetString(NULL, attr->children, 1));
- break;
- }
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- if (reader->node->content != NULL)
- return (xmlStrdup(reader->node->content));
- default:
- return(NULL);
- }
- return(NULL);
-}
-
-/**
- * xmlTextReaderIsDefault:
- * @reader: the xmlTextReaderPtr used
- *
- * Whether an Attribute node was generated from the default value
- * defined in the DTD or schema.
- *
- * Returns 0 if not defaulted, 1 if defaulted, and -1 in case of error
- */
-int
-xmlTextReaderIsDefault(xmlTextReaderPtr reader) {
- if (reader == NULL)
- return(-1);
- return(0);
-}
-
-/**
- * xmlTextReaderQuoteChar:
- * @reader: the xmlTextReaderPtr used
- *
- * The quotation mark character used to enclose the value of an attribute.
- *
- * Returns " or ' and -1 in case of error
- */
-int
-xmlTextReaderQuoteChar(xmlTextReaderPtr reader) {
- if (reader == NULL)
- return(-1);
- /* TODO maybe lookup the attribute value for " first */
- return((int) '"');
-}
-
-/**
- * xmlTextReaderXmlLang:
- * @reader: the xmlTextReaderPtr used
- *
- * The xml:lang scope within which the node resides.
- *
- * Returns the xml:lang value or NULL if none exists.
- */
-xmlChar *
-xmlTextReaderXmlLang(xmlTextReaderPtr reader) {
- if (reader == NULL)
- return(NULL);
- if (reader->node == NULL)
- return(NULL);
- return(xmlNodeGetLang(reader->node));
-}
-
diff --git a/bundle/libxml/xmlregexp.c b/bundle/libxml/xmlregexp.c
deleted file mode 100644
index 129c1269ec..0000000000
--- a/bundle/libxml/xmlregexp.c
+++ /dev/null
@@ -1,4319 +0,0 @@
-/*
- * regexp.c: generic and extensible Regular Expression engine
- *
- * Basically designed with the purpose of compiling regexps for
- * the variety of validation/shemas mechanisms now available in
- * XML related specifications thise includes:
- * - XML-1.0 DTD validation
- * - XML Schemas structure part 1
- * - XML Schemas Datatypes part 2 especially Appendix F
- * - RELAX-NG/TREX i.e. the counter proposal
- *
- * See Copyright for the status of this software.
- *
- * Daniel Veillard <veillard@redhat.com>
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#ifdef LIBXML_REGEXP_ENABLED
-
-#include <stdio.h>
-#include <string.h>
-#include <libxml/tree.h>
-#include <libxml/parserInternals.h>
-#include <libxml/xmlregexp.h>
-#include <libxml/xmlautomata.h>
-#include <libxml/xmlunicode.h>
-
-/* #define DEBUG_REGEXP_GRAPH */
-/* #define DEBUG_REGEXP_EXEC */
-/* #define DEBUG_PUSH */
-/* #define DEBUG_COMPACTION */
-
-#define ERROR(str) ctxt->error = 1; \
- xmlGenericError(xmlGenericErrorContext, "Regexp: %s: %s\n", str, ctxt->cur)
-#define NEXT ctxt->cur++
-#define CUR (*(ctxt->cur))
-#define NXT(index) (ctxt->cur[index])
-
-#define CUR_SCHAR(s, l) xmlStringCurrentChar(NULL, s, &l)
-#define NEXTL(l) ctxt->cur += l;
-
-/**
- * TODO:
- *
- * macro to flag unimplemented blocks
- */
-#define TODO \
- xmlGenericError(xmlGenericErrorContext, \
- "Unimplemented block at %s:%d\n", \
- __FILE__, __LINE__);
-
-
-/************************************************************************
- * *
- * Datatypes and structures *
- * *
- ************************************************************************/
-
-typedef enum {
- XML_REGEXP_EPSILON = 1,
- XML_REGEXP_CHARVAL,
- XML_REGEXP_RANGES,
- XML_REGEXP_SUBREG,
- XML_REGEXP_STRING,
- XML_REGEXP_ANYCHAR, /* . */
- XML_REGEXP_ANYSPACE, /* \s */
- XML_REGEXP_NOTSPACE, /* \S */
- XML_REGEXP_INITNAME, /* \l */
- XML_REGEXP_NOTINITNAME, /* \l */
- XML_REGEXP_NAMECHAR, /* \c */
- XML_REGEXP_NOTNAMECHAR, /* \C */
- XML_REGEXP_DECIMAL, /* \d */
- XML_REGEXP_NOTDECIMAL, /* \d */
- XML_REGEXP_REALCHAR, /* \w */
- XML_REGEXP_NOTREALCHAR, /* \w */
- XML_REGEXP_LETTER,
- XML_REGEXP_LETTER_UPPERCASE,
- XML_REGEXP_LETTER_LOWERCASE,
- XML_REGEXP_LETTER_TITLECASE,
- XML_REGEXP_LETTER_MODIFIER,
- XML_REGEXP_LETTER_OTHERS,
- XML_REGEXP_MARK,
- XML_REGEXP_MARK_NONSPACING,
- XML_REGEXP_MARK_SPACECOMBINING,
- XML_REGEXP_MARK_ENCLOSING,
- XML_REGEXP_NUMBER,
- XML_REGEXP_NUMBER_DECIMAL,
- XML_REGEXP_NUMBER_LETTER,
- XML_REGEXP_NUMBER_OTHERS,
- XML_REGEXP_PUNCT,
- XML_REGEXP_PUNCT_CONNECTOR,
- XML_REGEXP_PUNCT_DASH,
- XML_REGEXP_PUNCT_OPEN,
- XML_REGEXP_PUNCT_CLOSE,
- XML_REGEXP_PUNCT_INITQUOTE,
- XML_REGEXP_PUNCT_FINQUOTE,
- XML_REGEXP_PUNCT_OTHERS,
- XML_REGEXP_SEPAR,
- XML_REGEXP_SEPAR_SPACE,
- XML_REGEXP_SEPAR_LINE,
- XML_REGEXP_SEPAR_PARA,
- XML_REGEXP_SYMBOL,
- XML_REGEXP_SYMBOL_MATH,
- XML_REGEXP_SYMBOL_CURRENCY,
- XML_REGEXP_SYMBOL_MODIFIER,
- XML_REGEXP_SYMBOL_OTHERS,
- XML_REGEXP_OTHER,
- XML_REGEXP_OTHER_CONTROL,
- XML_REGEXP_OTHER_FORMAT,
- XML_REGEXP_OTHER_PRIVATE,
- XML_REGEXP_OTHER_NA,
- XML_REGEXP_BLOCK_NAME
-} xmlRegAtomType;
-
-typedef enum {
- XML_REGEXP_QUANT_EPSILON = 1,
- XML_REGEXP_QUANT_ONCE,
- XML_REGEXP_QUANT_OPT,
- XML_REGEXP_QUANT_MULT,
- XML_REGEXP_QUANT_PLUS,
- XML_REGEXP_QUANT_ONCEONLY,
- XML_REGEXP_QUANT_ALL,
- XML_REGEXP_QUANT_RANGE
-} xmlRegQuantType;
-
-typedef enum {
- XML_REGEXP_START_STATE = 1,
- XML_REGEXP_FINAL_STATE,
- XML_REGEXP_TRANS_STATE
-} xmlRegStateType;
-
-typedef enum {
- XML_REGEXP_MARK_NORMAL = 0,
- XML_REGEXP_MARK_START,
- XML_REGEXP_MARK_VISITED
-} xmlRegMarkedType;
-
-typedef struct _xmlRegRange xmlRegRange;
-typedef xmlRegRange *xmlRegRangePtr;
-
-struct _xmlRegRange {
- int neg;
- xmlRegAtomType type;
- int start;
- int end;
- xmlChar *blockName;
-};
-
-typedef struct _xmlRegAtom xmlRegAtom;
-typedef xmlRegAtom *xmlRegAtomPtr;
-
-typedef struct _xmlAutomataState xmlRegState;
-typedef xmlRegState *xmlRegStatePtr;
-
-struct _xmlRegAtom {
- int no;
- xmlRegAtomType type;
- xmlRegQuantType quant;
- int min;
- int max;
-
- void *valuep;
- void *valuep2;
- int neg;
- int codepoint;
- xmlRegStatePtr start;
- xmlRegStatePtr stop;
- int maxRanges;
- int nbRanges;
- xmlRegRangePtr *ranges;
- void *data;
-};
-
-typedef struct _xmlRegCounter xmlRegCounter;
-typedef xmlRegCounter *xmlRegCounterPtr;
-
-struct _xmlRegCounter {
- int min;
- int max;
-};
-
-typedef struct _xmlRegTrans xmlRegTrans;
-typedef xmlRegTrans *xmlRegTransPtr;
-
-struct _xmlRegTrans {
- xmlRegAtomPtr atom;
- int to;
- int counter;
- int count;
-};
-
-struct _xmlAutomataState {
- xmlRegStateType type;
- xmlRegMarkedType mark;
- xmlRegMarkedType reached;
- int no;
-
- int maxTrans;
- int nbTrans;
- xmlRegTrans *trans;
-};
-
-typedef struct _xmlAutomata xmlRegParserCtxt;
-typedef xmlRegParserCtxt *xmlRegParserCtxtPtr;
-
-struct _xmlAutomata {
- xmlChar *string;
- xmlChar *cur;
-
- int error;
- int neg;
-
- xmlRegStatePtr start;
- xmlRegStatePtr end;
- xmlRegStatePtr state;
-
- xmlRegAtomPtr atom;
-
- int maxAtoms;
- int nbAtoms;
- xmlRegAtomPtr *atoms;
-
- int maxStates;
- int nbStates;
- xmlRegStatePtr *states;
-
- int maxCounters;
- int nbCounters;
- xmlRegCounter *counters;
-
- int determinist;
-};
-
-struct _xmlRegexp {
- xmlChar *string;
- int nbStates;
- xmlRegStatePtr *states;
- int nbAtoms;
- xmlRegAtomPtr *atoms;
- int nbCounters;
- xmlRegCounter *counters;
- int determinist;
- /*
- * That's the compact form for determinists automatas
- */
- int nbstates;
- int *compact;
- void **transdata;
- int nbstrings;
- xmlChar **stringMap;
-};
-
-typedef struct _xmlRegExecRollback xmlRegExecRollback;
-typedef xmlRegExecRollback *xmlRegExecRollbackPtr;
-
-struct _xmlRegExecRollback {
- xmlRegStatePtr state;/* the current state */
- int index; /* the index in the input stack */
- int nextbranch; /* the next transition to explore in that state */
- int *counts; /* save the automate state if it has some */
-};
-
-typedef struct _xmlRegInputToken xmlRegInputToken;
-typedef xmlRegInputToken *xmlRegInputTokenPtr;
-
-struct _xmlRegInputToken {
- xmlChar *value;
- void *data;
-};
-
-struct _xmlRegExecCtxt {
- int status; /* execution status != 0 indicate an error */
- int determinist; /* did we found an inderterministic behaviour */
- xmlRegexpPtr comp; /* the compiled regexp */
- xmlRegExecCallbacks callback;
- void *data;
-
- xmlRegStatePtr state;/* the current state */
- int transno; /* the current transition on that state */
- int transcount; /* the number of char in char counted transitions */
-
- /*
- * A stack of rollback states
- */
- int maxRollbacks;
- int nbRollbacks;
- xmlRegExecRollback *rollbacks;
-
- /*
- * The state of the automata if any
- */
- int *counts;
-
- /*
- * The input stack
- */
- int inputStackMax;
- int inputStackNr;
- int index;
- int *charStack;
- const xmlChar *inputString; /* when operating on characters */
- xmlRegInputTokenPtr inputStack;/* when operating on strings */
-
-};
-
-#define REGEXP_ALL_COUNTER 0x123456
-#define REGEXP_ALL_LAX_COUNTER 0x123457
-
-static void xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top);
-static void xmlRegFreeState(xmlRegStatePtr state);
-static void xmlRegFreeAtom(xmlRegAtomPtr atom);
-
-/************************************************************************
- * *
- * Allocation/Deallocation *
- * *
- ************************************************************************/
-
-static int xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt);
-/**
- * xmlRegEpxFromParse:
- * @ctxt: the parser context used to build it
- *
- * Allocate a new regexp and fill it with the reult from the parser
- *
- * Returns the new regexp or NULL in case of error
- */
-static xmlRegexpPtr
-xmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) {
- xmlRegexpPtr ret;
-
- ret = (xmlRegexpPtr) xmlMalloc(sizeof(xmlRegexp));
- if (ret == NULL)
- return(NULL);
- memset(ret, 0, sizeof(xmlRegexp));
- ret->string = ctxt->string;
- ctxt->string = NULL;
- ret->nbStates = ctxt->nbStates;
- ctxt->nbStates = 0;
- ret->states = ctxt->states;
- ctxt->states = NULL;
- ret->nbAtoms = ctxt->nbAtoms;
- ctxt->nbAtoms = 0;
- ret->atoms = ctxt->atoms;
- ctxt->atoms = NULL;
- ret->nbCounters = ctxt->nbCounters;
- ctxt->nbCounters = 0;
- ret->counters = ctxt->counters;
- ctxt->counters = NULL;
- ret->determinist = ctxt->determinist;
-
- if ((ret->determinist != 0) &&
- (ret->nbCounters == 0) &&
- (ret->atoms != NULL) &&
- (ret->atoms[0] != NULL) &&
- (ret->atoms[0]->type == XML_REGEXP_STRING)) {
- int i, j, nbstates = 0, nbatoms = 0;
- int *stateRemap;
- int *stringRemap;
- int *transitions;
- void **transdata;
- xmlChar **stringMap;
- xmlChar *value;
-
- /*
- * Switch to a compact representation
- * 1/ counting the effective number of states left
- * 2/ conting the unique number of atoms, and check that
- * they are all of the string type
- * 3/ build a table state x atom for the transitions
- */
-
- stateRemap = xmlMalloc(ret->nbStates * sizeof(int));
- for (i = 0;i < ret->nbStates;i++) {
- if (ret->states[i] != NULL) {
- stateRemap[i] = nbstates;
- nbstates++;
- } else {
- stateRemap[i] = -1;
- }
- }
-#ifdef DEBUG_COMPACTION
- printf("Final: %d states\n", nbstates);
-#endif
- stringMap = xmlMalloc(ret->nbAtoms * sizeof(char *));
- stringRemap = xmlMalloc(ret->nbAtoms * sizeof(int));
- for (i = 0;i < ret->nbAtoms;i++) {
- if ((ret->atoms[i]->type == XML_REGEXP_STRING) &&
- (ret->atoms[i]->quant == XML_REGEXP_QUANT_ONCE)) {
- value = ret->atoms[i]->valuep;
- for (j = 0;j < nbatoms;j++) {
- if (xmlStrEqual(stringMap[j], value)) {
- stringRemap[i] = j;
- break;
- }
- }
- if (j >= nbatoms) {
- stringRemap[i] = nbatoms;
- stringMap[nbatoms] = xmlStrdup(value);
- nbatoms++;
- }
- } else {
- xmlFree(stateRemap);
- xmlFree(stringRemap);
- for (i = 0;i < nbatoms;i++)
- xmlFree(stringMap[i]);
- xmlFree(stringMap);
- goto fail_compact;
- }
- }
-#ifdef DEBUG_COMPACTION
- printf("Final: %d atoms\n", nbatoms);
-#endif
-
- /*
- * Allocate the transition table. The first entry for each
- * state correspond to the state type.
- */
- transitions = (int *) xmlMalloc(nbstates * (nbatoms + 1) * sizeof(int));
- transdata = NULL;
- memset(transitions, 0, nbstates * (nbatoms + 1) * sizeof(int));
-
- for (i = 0;i < ret->nbStates;i++) {
- int stateno, atomno, targetno, prev;
- xmlRegStatePtr state;
- xmlRegTransPtr trans;
-
- stateno = stateRemap[i];
- if (stateno == -1)
- continue;
- state = ret->states[i];
-
- transitions[stateno * (nbatoms + 1)] = state->type;
-
- for (j = 0;j < state->nbTrans;j++) {
- trans = &(state->trans[j]);
- if ((trans->to == -1) || (trans->atom == NULL))
- continue;
- atomno = stringRemap[trans->atom->no];
- if ((trans->atom->data != NULL) && (transdata == NULL)) {
- transdata = (void **) xmlMalloc(nbstates * nbatoms *
- sizeof(void *));
- if (transdata != NULL)
- memset(transdata, 0,
- nbstates * nbatoms * sizeof(void *));
- }
- targetno = stateRemap[trans->to];
- /*
- * if the same atome can generate transition to 2 different
- * states then it means the automata is not determinist and
- * the compact form can't be used !
- */
- prev = transitions[stateno * (nbatoms + 1) + atomno + 1];
- if (prev != 0) {
- if (prev != targetno + 1) {
- printf("not determinist\n");
- ret->determinist = 0;
-#ifdef DEBUG_COMPACTION
- printf("Indet: state %d trans %d, atom %d to %d : %d to %d\n",
- i, j, trans->atom->no, trans->to, atomno, targetno);
- printf(" previous to is %d\n", prev);
-#endif
- ret->determinist = 0;
- if (transdata != NULL)
- xmlFree(transdata);
- xmlFree(transitions);
- xmlFree(stateRemap);
- xmlFree(stringRemap);
- for (i = 0;i < nbatoms;i++)
- xmlFree(stringMap[i]);
- xmlFree(stringMap);
- goto fail_compact;
- }
- } else {
-#if 0
- printf("State %d trans %d: atom %d to %d : %d to %d\n",
- i, j, trans->atom->no, trans->to, atomno, targetno);
-#endif
- transitions[stateno * (nbatoms + 1) + atomno + 1] =
- targetno + 1; /* to avoid 0 */
- if (transdata != NULL)
- transdata[stateno * nbatoms + atomno] =
- trans->atom->data;
- }
- }
- }
- ret->determinist = 1;
-#ifdef DEBUG_COMPACTION
- /*
- * Debug
- */
- for (i = 0;i < nbstates;i++) {
- for (j = 0;j < nbatoms + 1;j++) {
- printf("%02d ", transitions[i * (nbatoms + 1) + j]);
- }
- printf("\n");
- }
- printf("\n");
-#endif
- /*
- * Cleanup of the old data
- */
- if (ret->states != NULL) {
- for (i = 0;i < ret->nbStates;i++)
- xmlRegFreeState(ret->states[i]);
- xmlFree(ret->states);
- }
- ret->states = NULL;
- ret->nbStates = 0;
- if (ret->atoms != NULL) {
- for (i = 0;i < ret->nbAtoms;i++)
- xmlRegFreeAtom(ret->atoms[i]);
- xmlFree(ret->atoms);
- }
- ret->atoms = NULL;
- ret->nbAtoms = 0;
-
- ret->compact = transitions;
- ret->transdata = transdata;
- ret->stringMap = stringMap;
- ret->nbstrings = nbatoms;
- ret->nbstates = nbstates;
- xmlFree(stateRemap);
- xmlFree(stringRemap);
- }
-fail_compact:
- return(ret);
-}
-
-/**
- * xmlRegNewParserCtxt:
- * @string: the string to parse
- *
- * Allocate a new regexp parser context
- *
- * Returns the new context or NULL in case of error
- */
-static xmlRegParserCtxtPtr
-xmlRegNewParserCtxt(const xmlChar *string) {
- xmlRegParserCtxtPtr ret;
-
- ret = (xmlRegParserCtxtPtr) xmlMalloc(sizeof(xmlRegParserCtxt));
- if (ret == NULL)
- return(NULL);
- memset(ret, 0, sizeof(xmlRegParserCtxt));
- if (string != NULL)
- ret->string = xmlStrdup(string);
- ret->cur = ret->string;
- ret->neg = 0;
- ret->error = 0;
- ret->determinist = -1;
- return(ret);
-}
-
-/**
- * xmlRegNewRange:
- * @ctxt: the regexp parser context
- * @neg: is that negative
- * @type: the type of range
- * @start: the start codepoint
- * @end: the end codepoint
- *
- * Allocate a new regexp range
- *
- * Returns the new range or NULL in case of error
- */
-static xmlRegRangePtr
-xmlRegNewRange(xmlRegParserCtxtPtr ctxt,
- int neg, xmlRegAtomType type, int start, int end) {
- xmlRegRangePtr ret;
-
- ret = (xmlRegRangePtr) xmlMalloc(sizeof(xmlRegRange));
- if (ret == NULL) {
- ERROR("failed to allocate regexp range");
- return(NULL);
- }
- ret->neg = neg;
- ret->type = type;
- ret->start = start;
- ret->end = end;
- return(ret);
-}
-
-/**
- * xmlRegFreeRange:
- * @range: the regexp range
- *
- * Free a regexp range
- */
-static void
-xmlRegFreeRange(xmlRegRangePtr range) {
- if (range == NULL)
- return;
-
- if (range->blockName != NULL)
- xmlFree(range->blockName);
- xmlFree(range);
-}
-
-/**
- * xmlRegNewAtom:
- * @ctxt: the regexp parser context
- * @type: the type of atom
- *
- * Allocate a new regexp range
- *
- * Returns the new atom or NULL in case of error
- */
-static xmlRegAtomPtr
-xmlRegNewAtom(xmlRegParserCtxtPtr ctxt, xmlRegAtomType type) {
- xmlRegAtomPtr ret;
-
- ret = (xmlRegAtomPtr) xmlMalloc(sizeof(xmlRegAtom));
- if (ret == NULL) {
- ERROR("failed to allocate regexp atom");
- return(NULL);
- }
- memset(ret, 0, sizeof(xmlRegAtom));
- ret->type = type;
- ret->quant = XML_REGEXP_QUANT_ONCE;
- ret->min = 0;
- ret->max = 0;
- return(ret);
-}
-
-/**
- * xmlRegFreeAtom:
- * @atom: the regexp atom
- *
- * Free a regexp atom
- */
-static void
-xmlRegFreeAtom(xmlRegAtomPtr atom) {
- int i;
-
- if (atom == NULL)
- return;
-
- for (i = 0;i < atom->nbRanges;i++)
- xmlRegFreeRange(atom->ranges[i]);
- if (atom->ranges != NULL)
- xmlFree(atom->ranges);
- if (atom->type == XML_REGEXP_STRING)
- xmlFree(atom->valuep);
- xmlFree(atom);
-}
-
-static xmlRegStatePtr
-xmlRegNewState(xmlRegParserCtxtPtr ctxt) {
- xmlRegStatePtr ret;
-
- ret = (xmlRegStatePtr) xmlMalloc(sizeof(xmlRegState));
- if (ret == NULL) {
- ERROR("failed to allocate regexp state");
- return(NULL);
- }
- memset(ret, 0, sizeof(xmlRegState));
- ret->type = XML_REGEXP_TRANS_STATE;
- ret->mark = XML_REGEXP_MARK_NORMAL;
- return(ret);
-}
-
-/**
- * xmlRegFreeState:
- * @state: the regexp state
- *
- * Free a regexp state
- */
-static void
-xmlRegFreeState(xmlRegStatePtr state) {
- if (state == NULL)
- return;
-
- if (state->trans != NULL)
- xmlFree(state->trans);
- xmlFree(state);
-}
-
-/**
- * xmlRegFreeParserCtxt:
- * @ctxt: the regexp parser context
- *
- * Free a regexp parser context
- */
-static void
-xmlRegFreeParserCtxt(xmlRegParserCtxtPtr ctxt) {
- int i;
- if (ctxt == NULL)
- return;
-
- if (ctxt->string != NULL)
- xmlFree(ctxt->string);
- if (ctxt->states != NULL) {
- for (i = 0;i < ctxt->nbStates;i++)
- xmlRegFreeState(ctxt->states[i]);
- xmlFree(ctxt->states);
- }
- if (ctxt->atoms != NULL) {
- for (i = 0;i < ctxt->nbAtoms;i++)
- xmlRegFreeAtom(ctxt->atoms[i]);
- xmlFree(ctxt->atoms);
- }
- if (ctxt->counters != NULL)
- xmlFree(ctxt->counters);
- xmlFree(ctxt);
-}
-
-/************************************************************************
- * *
- * Display of Data structures *
- * *
- ************************************************************************/
-
-static void
-xmlRegPrintAtomType(FILE *output, xmlRegAtomType type) {
- switch (type) {
- case XML_REGEXP_EPSILON:
- fprintf(output, "epsilon "); break;
- case XML_REGEXP_CHARVAL:
- fprintf(output, "charval "); break;
- case XML_REGEXP_RANGES:
- fprintf(output, "ranges "); break;
- case XML_REGEXP_SUBREG:
- fprintf(output, "subexpr "); break;
- case XML_REGEXP_STRING:
- fprintf(output, "string "); break;
- case XML_REGEXP_ANYCHAR:
- fprintf(output, "anychar "); break;
- case XML_REGEXP_ANYSPACE:
- fprintf(output, "anyspace "); break;
- case XML_REGEXP_NOTSPACE:
- fprintf(output, "notspace "); break;
- case XML_REGEXP_INITNAME:
- fprintf(output, "initname "); break;
- case XML_REGEXP_NOTINITNAME:
- fprintf(output, "notinitname "); break;
- case XML_REGEXP_NAMECHAR:
- fprintf(output, "namechar "); break;
- case XML_REGEXP_NOTNAMECHAR:
- fprintf(output, "notnamechar "); break;
- case XML_REGEXP_DECIMAL:
- fprintf(output, "decimal "); break;
- case XML_REGEXP_NOTDECIMAL:
- fprintf(output, "notdecimal "); break;
- case XML_REGEXP_REALCHAR:
- fprintf(output, "realchar "); break;
- case XML_REGEXP_NOTREALCHAR:
- fprintf(output, "notrealchar "); break;
- case XML_REGEXP_LETTER:
- fprintf(output, "LETTER "); break;
- case XML_REGEXP_LETTER_UPPERCASE:
- fprintf(output, "LETTER_UPPERCASE "); break;
- case XML_REGEXP_LETTER_LOWERCASE:
- fprintf(output, "LETTER_LOWERCASE "); break;
- case XML_REGEXP_LETTER_TITLECASE:
- fprintf(output, "LETTER_TITLECASE "); break;
- case XML_REGEXP_LETTER_MODIFIER:
- fprintf(output, "LETTER_MODIFIER "); break;
- case XML_REGEXP_LETTER_OTHERS:
- fprintf(output, "LETTER_OTHERS "); break;
- case XML_REGEXP_MARK:
- fprintf(output, "MARK "); break;
- case XML_REGEXP_MARK_NONSPACING:
- fprintf(output, "MARK_NONSPACING "); break;
- case XML_REGEXP_MARK_SPACECOMBINING:
- fprintf(output, "MARK_SPACECOMBINING "); break;
- case XML_REGEXP_MARK_ENCLOSING:
- fprintf(output, "MARK_ENCLOSING "); break;
- case XML_REGEXP_NUMBER:
- fprintf(output, "NUMBER "); break;
- case XML_REGEXP_NUMBER_DECIMAL:
- fprintf(output, "NUMBER_DECIMAL "); break;
- case XML_REGEXP_NUMBER_LETTER:
- fprintf(output, "NUMBER_LETTER "); break;
- case XML_REGEXP_NUMBER_OTHERS:
- fprintf(output, "NUMBER_OTHERS "); break;
- case XML_REGEXP_PUNCT:
- fprintf(output, "PUNCT "); break;
- case XML_REGEXP_PUNCT_CONNECTOR:
- fprintf(output, "PUNCT_CONNECTOR "); break;
- case XML_REGEXP_PUNCT_DASH:
- fprintf(output, "PUNCT_DASH "); break;
- case XML_REGEXP_PUNCT_OPEN:
- fprintf(output, "PUNCT_OPEN "); break;
- case XML_REGEXP_PUNCT_CLOSE:
- fprintf(output, "PUNCT_CLOSE "); break;
- case XML_REGEXP_PUNCT_INITQUOTE:
- fprintf(output, "PUNCT_INITQUOTE "); break;
- case XML_REGEXP_PUNCT_FINQUOTE:
- fprintf(output, "PUNCT_FINQUOTE "); break;
- case XML_REGEXP_PUNCT_OTHERS:
- fprintf(output, "PUNCT_OTHERS "); break;
- case XML_REGEXP_SEPAR:
- fprintf(output, "SEPAR "); break;
- case XML_REGEXP_SEPAR_SPACE:
- fprintf(output, "SEPAR_SPACE "); break;
- case XML_REGEXP_SEPAR_LINE:
- fprintf(output, "SEPAR_LINE "); break;
- case XML_REGEXP_SEPAR_PARA:
- fprintf(output, "SEPAR_PARA "); break;
- case XML_REGEXP_SYMBOL:
- fprintf(output, "SYMBOL "); break;
- case XML_REGEXP_SYMBOL_MATH:
- fprintf(output, "SYMBOL_MATH "); break;
- case XML_REGEXP_SYMBOL_CURRENCY:
- fprintf(output, "SYMBOL_CURRENCY "); break;
- case XML_REGEXP_SYMBOL_MODIFIER:
- fprintf(output, "SYMBOL_MODIFIER "); break;
- case XML_REGEXP_SYMBOL_OTHERS:
- fprintf(output, "SYMBOL_OTHERS "); break;
- case XML_REGEXP_OTHER:
- fprintf(output, "OTHER "); break;
- case XML_REGEXP_OTHER_CONTROL:
- fprintf(output, "OTHER_CONTROL "); break;
- case XML_REGEXP_OTHER_FORMAT:
- fprintf(output, "OTHER_FORMAT "); break;
- case XML_REGEXP_OTHER_PRIVATE:
- fprintf(output, "OTHER_PRIVATE "); break;
- case XML_REGEXP_OTHER_NA:
- fprintf(output, "OTHER_NA "); break;
- case XML_REGEXP_BLOCK_NAME:
- fprintf(output, "BLOCK "); break;
- }
-}
-
-static void
-xmlRegPrintQuantType(FILE *output, xmlRegQuantType type) {
- switch (type) {
- case XML_REGEXP_QUANT_EPSILON:
- fprintf(output, "epsilon "); break;
- case XML_REGEXP_QUANT_ONCE:
- fprintf(output, "once "); break;
- case XML_REGEXP_QUANT_OPT:
- fprintf(output, "? "); break;
- case XML_REGEXP_QUANT_MULT:
- fprintf(output, "* "); break;
- case XML_REGEXP_QUANT_PLUS:
- fprintf(output, "+ "); break;
- case XML_REGEXP_QUANT_RANGE:
- fprintf(output, "range "); break;
- case XML_REGEXP_QUANT_ONCEONLY:
- fprintf(output, "onceonly "); break;
- case XML_REGEXP_QUANT_ALL:
- fprintf(output, "all "); break;
- }
-}
-static void
-xmlRegPrintRange(FILE *output, xmlRegRangePtr range) {
- fprintf(output, " range: ");
- if (range->neg)
- fprintf(output, "negative ");
- xmlRegPrintAtomType(output, range->type);
- fprintf(output, "%c - %c\n", range->start, range->end);
-}
-
-static void
-xmlRegPrintAtom(FILE *output, xmlRegAtomPtr atom) {
- fprintf(output, " atom: ");
- if (atom == NULL) {
- fprintf(output, "NULL\n");
- return;
- }
- xmlRegPrintAtomType(output, atom->type);
- xmlRegPrintQuantType(output, atom->quant);
- if (atom->quant == XML_REGEXP_QUANT_RANGE)
- fprintf(output, "%d-%d ", atom->min, atom->max);
- if (atom->type == XML_REGEXP_STRING)
- fprintf(output, "'%s' ", (char *) atom->valuep);
- if (atom->type == XML_REGEXP_CHARVAL)
- fprintf(output, "char %c\n", atom->codepoint);
- else if (atom->type == XML_REGEXP_RANGES) {
- int i;
- fprintf(output, "%d entries\n", atom->nbRanges);
- for (i = 0; i < atom->nbRanges;i++)
- xmlRegPrintRange(output, atom->ranges[i]);
- } else if (atom->type == XML_REGEXP_SUBREG) {
- fprintf(output, "start %d end %d\n", atom->start->no, atom->stop->no);
- } else {
- fprintf(output, "\n");
- }
-}
-
-static void
-xmlRegPrintTrans(FILE *output, xmlRegTransPtr trans) {
- fprintf(output, " trans: ");
- if (trans == NULL) {
- fprintf(output, "NULL\n");
- return;
- }
- if (trans->to < 0) {
- fprintf(output, "removed\n");
- return;
- }
- if (trans->counter >= 0) {
- fprintf(output, "counted %d, ", trans->counter);
- }
- if (trans->count == REGEXP_ALL_COUNTER) {
- fprintf(output, "all transition, ");
- } else if (trans->count >= 0) {
- fprintf(output, "count based %d, ", trans->count);
- }
- if (trans->atom == NULL) {
- fprintf(output, "epsilon to %d\n", trans->to);
- return;
- }
- if (trans->atom->type == XML_REGEXP_CHARVAL)
- fprintf(output, "char %c ", trans->atom->codepoint);
- fprintf(output, "atom %d, to %d\n", trans->atom->no, trans->to);
-}
-
-static void
-xmlRegPrintState(FILE *output, xmlRegStatePtr state) {
- int i;
-
- fprintf(output, " state: ");
- if (state == NULL) {
- fprintf(output, "NULL\n");
- return;
- }
- if (state->type == XML_REGEXP_START_STATE)
- fprintf(output, "START ");
- if (state->type == XML_REGEXP_FINAL_STATE)
- fprintf(output, "FINAL ");
-
- fprintf(output, "%d, %d transitions:\n", state->no, state->nbTrans);
- for (i = 0;i < state->nbTrans; i++) {
- xmlRegPrintTrans(output, &(state->trans[i]));
- }
-}
-
-#ifdef DEBUG_REGEXP_GRAPH
-static void
-xmlRegPrintCtxt(FILE *output, xmlRegParserCtxtPtr ctxt) {
- int i;
-
- fprintf(output, " ctxt: ");
- if (ctxt == NULL) {
- fprintf(output, "NULL\n");
- return;
- }
- fprintf(output, "'%s' ", ctxt->string);
- if (ctxt->error)
- fprintf(output, "error ");
- if (ctxt->neg)
- fprintf(output, "neg ");
- fprintf(output, "\n");
- fprintf(output, "%d atoms:\n", ctxt->nbAtoms);
- for (i = 0;i < ctxt->nbAtoms; i++) {
- fprintf(output, " %02d ", i);
- xmlRegPrintAtom(output, ctxt->atoms[i]);
- }
- if (ctxt->atom != NULL) {
- fprintf(output, "current atom:\n");
- xmlRegPrintAtom(output, ctxt->atom);
- }
- fprintf(output, "%d states:", ctxt->nbStates);
- if (ctxt->start != NULL)
- fprintf(output, " start: %d", ctxt->start->no);
- if (ctxt->end != NULL)
- fprintf(output, " end: %d", ctxt->end->no);
- fprintf(output, "\n");
- for (i = 0;i < ctxt->nbStates; i++) {
- xmlRegPrintState(output, ctxt->states[i]);
- }
- fprintf(output, "%d counters:\n", ctxt->nbCounters);
- for (i = 0;i < ctxt->nbCounters; i++) {
- fprintf(output, " %d: min %d max %d\n", i, ctxt->counters[i].min,
- ctxt->counters[i].max);
- }
-}
-#endif
-
-/************************************************************************
- * *
- * Finite Automata structures manipulations *
- * *
- ************************************************************************/
-
-static void
-xmlRegAtomAddRange(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom,
- int neg, xmlRegAtomType type, int start, int end,
- xmlChar *blockName) {
- xmlRegRangePtr range;
-
- if (atom == NULL) {
- ERROR("add range: atom is NULL");
- return;
- }
- if (atom->type != XML_REGEXP_RANGES) {
- ERROR("add range: atom is not ranges");
- return;
- }
- if (atom->maxRanges == 0) {
- atom->maxRanges = 4;
- atom->ranges = (xmlRegRangePtr *) xmlMalloc(atom->maxRanges *
- sizeof(xmlRegRangePtr));
- if (atom->ranges == NULL) {
- ERROR("add range: allocation failed");
- atom->maxRanges = 0;
- return;
- }
- } else if (atom->nbRanges >= atom->maxRanges) {
- xmlRegRangePtr *tmp;
- atom->maxRanges *= 2;
- tmp = (xmlRegRangePtr *) xmlRealloc(atom->ranges, atom->maxRanges *
- sizeof(xmlRegRangePtr));
- if (tmp == NULL) {
- ERROR("add range: allocation failed");
- atom->maxRanges /= 2;
- return;
- }
- atom->ranges = tmp;
- }
- range = xmlRegNewRange(ctxt, neg, type, start, end);
- if (range == NULL)
- return;
- range->blockName = blockName;
- atom->ranges[atom->nbRanges++] = range;
-
-}
-
-static int
-xmlRegGetCounter(xmlRegParserCtxtPtr ctxt) {
- if (ctxt->maxCounters == 0) {
- ctxt->maxCounters = 4;
- ctxt->counters = (xmlRegCounter *) xmlMalloc(ctxt->maxCounters *
- sizeof(xmlRegCounter));
- if (ctxt->counters == NULL) {
- ERROR("reg counter: allocation failed");
- ctxt->maxCounters = 0;
- return(-1);
- }
- } else if (ctxt->nbCounters >= ctxt->maxCounters) {
- xmlRegCounter *tmp;
- ctxt->maxCounters *= 2;
- tmp = (xmlRegCounter *) xmlRealloc(ctxt->counters, ctxt->maxCounters *
- sizeof(xmlRegCounter));
- if (tmp == NULL) {
- ERROR("reg counter: allocation failed");
- ctxt->maxCounters /= 2;
- return(-1);
- }
- ctxt->counters = tmp;
- }
- ctxt->counters[ctxt->nbCounters].min = -1;
- ctxt->counters[ctxt->nbCounters].max = -1;
- return(ctxt->nbCounters++);
-}
-
-static void
-xmlRegAtomPush(xmlRegParserCtxtPtr ctxt, xmlRegAtomPtr atom) {
- if (atom == NULL) {
- ERROR("atom push: atom is NULL");
- return;
- }
- if (ctxt->maxAtoms == 0) {
- ctxt->maxAtoms = 4;
- ctxt->atoms = (xmlRegAtomPtr *) xmlMalloc(ctxt->maxAtoms *
- sizeof(xmlRegAtomPtr));
- if (ctxt->atoms == NULL) {
- ERROR("atom push: allocation failed");
- ctxt->maxAtoms = 0;
- return;
- }
- } else if (ctxt->nbAtoms >= ctxt->maxAtoms) {
- xmlRegAtomPtr *tmp;
- ctxt->maxAtoms *= 2;
- tmp = (xmlRegAtomPtr *) xmlRealloc(ctxt->atoms, ctxt->maxAtoms *
- sizeof(xmlRegAtomPtr));
- if (tmp == NULL) {
- ERROR("atom push: allocation failed");
- ctxt->maxAtoms /= 2;
- return;
- }
- ctxt->atoms = tmp;
- }
- atom->no = ctxt->nbAtoms;
- ctxt->atoms[ctxt->nbAtoms++] = atom;
-}
-
-static void
-xmlRegStateAddTrans(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
- xmlRegAtomPtr atom, xmlRegStatePtr target,
- int counter, int count) {
- if (state == NULL) {
- ERROR("add state: state is NULL");
- return;
- }
- if (target == NULL) {
- ERROR("add state: target is NULL");
- return;
- }
- if (state->maxTrans == 0) {
- state->maxTrans = 4;
- state->trans = (xmlRegTrans *) xmlMalloc(state->maxTrans *
- sizeof(xmlRegTrans));
- if (state->trans == NULL) {
- ERROR("add range: allocation failed");
- state->maxTrans = 0;
- return;
- }
- } else if (state->nbTrans >= state->maxTrans) {
- xmlRegTrans *tmp;
- state->maxTrans *= 2;
- tmp = (xmlRegTrans *) xmlRealloc(state->trans, state->maxTrans *
- sizeof(xmlRegTrans));
- if (tmp == NULL) {
- ERROR("add range: allocation failed");
- state->maxTrans /= 2;
- return;
- }
- state->trans = tmp;
- }
-#ifdef DEBUG_REGEXP_GRAPH
- printf("Add trans from %d to %d ", state->no, target->no);
- if (count == REGEXP_ALL_COUNTER)
- printf("all transition");
- else if (count >= 0)
- printf("count based %d", count);
- else if (counter >= 0)
- printf("counted %d", counter);
- else if (atom == NULL)
- printf("epsilon transition");
- printf("\n");
-#endif
-
- state->trans[state->nbTrans].atom = atom;
- state->trans[state->nbTrans].to = target->no;
- state->trans[state->nbTrans].counter = counter;
- state->trans[state->nbTrans].count = count;
- state->nbTrans++;
-}
-
-static void
-xmlRegStatePush(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state) {
- if (ctxt->maxStates == 0) {
- ctxt->maxStates = 4;
- ctxt->states = (xmlRegStatePtr *) xmlMalloc(ctxt->maxStates *
- sizeof(xmlRegStatePtr));
- if (ctxt->states == NULL) {
- ERROR("add range: allocation failed");
- ctxt->maxStates = 0;
- return;
- }
- } else if (ctxt->nbStates >= ctxt->maxStates) {
- xmlRegStatePtr *tmp;
- ctxt->maxStates *= 2;
- tmp = (xmlRegStatePtr *) xmlRealloc(ctxt->states, ctxt->maxStates *
- sizeof(xmlRegStatePtr));
- if (tmp == NULL) {
- ERROR("add range: allocation failed");
- ctxt->maxStates /= 2;
- return;
- }
- ctxt->states = tmp;
- }
- state->no = ctxt->nbStates;
- ctxt->states[ctxt->nbStates++] = state;
-}
-
-/**
- * xmlFAGenerateAllTransition:
- * @ctxt: a regexp parser context
- * @from: the from state
- * @to: the target state or NULL for building a new one
- * @lax:
- *
- */
-static void
-xmlFAGenerateAllTransition(xmlRegParserCtxtPtr ctxt,
- xmlRegStatePtr from, xmlRegStatePtr to,
- int lax) {
- if (to == NULL) {
- to = xmlRegNewState(ctxt);
- xmlRegStatePush(ctxt, to);
- ctxt->state = to;
- }
- if (lax)
- xmlRegStateAddTrans(ctxt, from, NULL, to, -1, REGEXP_ALL_LAX_COUNTER);
- else
- xmlRegStateAddTrans(ctxt, from, NULL, to, -1, REGEXP_ALL_COUNTER);
-}
-
-/**
- * xmlFAGenerateEpsilonTransition:
- * @ctxt: a regexp parser context
- * @from: the from state
- * @to: the target state or NULL for building a new one
- *
- */
-static void
-xmlFAGenerateEpsilonTransition(xmlRegParserCtxtPtr ctxt,
- xmlRegStatePtr from, xmlRegStatePtr to) {
- if (to == NULL) {
- to = xmlRegNewState(ctxt);
- xmlRegStatePush(ctxt, to);
- ctxt->state = to;
- }
- xmlRegStateAddTrans(ctxt, from, NULL, to, -1, -1);
-}
-
-/**
- * xmlFAGenerateCountedEpsilonTransition:
- * @ctxt: a regexp parser context
- * @from: the from state
- * @to: the target state or NULL for building a new one
- * counter: the counter for that transition
- *
- */
-static void
-xmlFAGenerateCountedEpsilonTransition(xmlRegParserCtxtPtr ctxt,
- xmlRegStatePtr from, xmlRegStatePtr to, int counter) {
- if (to == NULL) {
- to = xmlRegNewState(ctxt);
- xmlRegStatePush(ctxt, to);
- ctxt->state = to;
- }
- xmlRegStateAddTrans(ctxt, from, NULL, to, counter, -1);
-}
-
-/**
- * xmlFAGenerateCountedTransition:
- * @ctxt: a regexp parser context
- * @from: the from state
- * @to: the target state or NULL for building a new one
- * counter: the counter for that transition
- *
- */
-static void
-xmlFAGenerateCountedTransition(xmlRegParserCtxtPtr ctxt,
- xmlRegStatePtr from, xmlRegStatePtr to, int counter) {
- if (to == NULL) {
- to = xmlRegNewState(ctxt);
- xmlRegStatePush(ctxt, to);
- ctxt->state = to;
- }
- xmlRegStateAddTrans(ctxt, from, NULL, to, -1, counter);
-}
-
-/**
- * xmlFAGenerateTransitions:
- * @ctxt: a regexp parser context
- * @from: the from state
- * @to: the target state or NULL for building a new one
- * @atom: the atom generating the transition
- *
- */
-static void
-xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
- xmlRegStatePtr to, xmlRegAtomPtr atom) {
- if (atom == NULL) {
- ERROR("genrate transition: atom == NULL");
- return;
- }
- if (atom->type == XML_REGEXP_SUBREG) {
- /*
- * this is a subexpression handling one should not need to
- * create a new node excep for XML_REGEXP_QUANT_RANGE.
- */
- xmlRegAtomPush(ctxt, atom);
- if ((to != NULL) && (atom->stop != to) &&
- (atom->quant != XML_REGEXP_QUANT_RANGE)) {
- /*
- * Generate an epsilon transition to link to the target
- */
- xmlFAGenerateEpsilonTransition(ctxt, atom->stop, to);
- }
- switch (atom->quant) {
- case XML_REGEXP_QUANT_OPT:
- atom->quant = XML_REGEXP_QUANT_ONCE;
- xmlFAGenerateEpsilonTransition(ctxt, atom->start, atom->stop);
- break;
- case XML_REGEXP_QUANT_MULT:
- atom->quant = XML_REGEXP_QUANT_ONCE;
- xmlFAGenerateEpsilonTransition(ctxt, atom->start, atom->stop);
- xmlFAGenerateEpsilonTransition(ctxt, atom->stop, atom->start);
- break;
- case XML_REGEXP_QUANT_PLUS:
- atom->quant = XML_REGEXP_QUANT_ONCE;
- xmlFAGenerateEpsilonTransition(ctxt, atom->stop, atom->start);
- break;
- case XML_REGEXP_QUANT_RANGE: {
- int counter;
- xmlRegStatePtr newstate;
-
- /*
- * This one is nasty:
- * 1/ register a new counter
- * 2/ register an epsilon transition associated to
- * this counter going from atom->stop to atom->start
- * 3/ create a new state
- * 4/ generate a counted transition from atom->stop to
- * that state
- */
- counter = xmlRegGetCounter(ctxt);
- ctxt->counters[counter].min = atom->min - 1;
- ctxt->counters[counter].max = atom->max - 1;
- atom->min = 0;
- atom->max = 0;
- atom->quant = XML_REGEXP_QUANT_ONCE;
- xmlFAGenerateCountedEpsilonTransition(ctxt, atom->stop,
- atom->start, counter);
- if (to != NULL) {
- newstate = to;
- } else {
- newstate = xmlRegNewState(ctxt);
- xmlRegStatePush(ctxt, newstate);
- ctxt->state = newstate;
- }
- xmlFAGenerateCountedTransition(ctxt, atom->stop,
- newstate, counter);
- }
- default:
- break;
- }
- return;
- } else {
- if (to == NULL) {
- to = xmlRegNewState(ctxt);
- xmlRegStatePush(ctxt, to);
- }
- xmlRegStateAddTrans(ctxt, from, atom, to, -1, -1);
- xmlRegAtomPush(ctxt, atom);
- ctxt->state = to;
- }
- switch (atom->quant) {
- case XML_REGEXP_QUANT_OPT:
- atom->quant = XML_REGEXP_QUANT_ONCE;
- xmlFAGenerateEpsilonTransition(ctxt, from, to);
- break;
- case XML_REGEXP_QUANT_MULT:
- atom->quant = XML_REGEXP_QUANT_ONCE;
- xmlFAGenerateEpsilonTransition(ctxt, from, to);
- xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1);
- break;
- case XML_REGEXP_QUANT_PLUS:
- atom->quant = XML_REGEXP_QUANT_ONCE;
- xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1);
- break;
- default:
- break;
- }
-}
-
-/**
- * xmlFAReduceEpsilonTransitions:
- * @ctxt: a regexp parser context
- * @fromnr: the from state
- * @tonr: the to state
- * @cpunter: should that transition be associted to a counted
- *
- */
-static void
-xmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt, int fromnr,
- int tonr, int counter) {
- int transnr;
- xmlRegStatePtr from;
- xmlRegStatePtr to;
-
-#ifdef DEBUG_REGEXP_GRAPH
- printf("xmlFAReduceEpsilonTransitions(%d, %d)\n", fromnr, tonr);
-#endif
- from = ctxt->states[fromnr];
- if (from == NULL)
- return;
- to = ctxt->states[tonr];
- if (to == NULL)
- return;
- if ((to->mark == XML_REGEXP_MARK_START) ||
- (to->mark == XML_REGEXP_MARK_VISITED))
- return;
-
- to->mark = XML_REGEXP_MARK_VISITED;
- if (to->type == XML_REGEXP_FINAL_STATE) {
-#ifdef DEBUG_REGEXP_GRAPH
- printf("State %d is final, so %d becomes final\n", tonr, fromnr);
-#endif
- from->type = XML_REGEXP_FINAL_STATE;
- }
- for (transnr = 0;transnr < to->nbTrans;transnr++) {
- if (to->trans[transnr].atom == NULL) {
- /*
- * Don't remove counted transitions
- * Don't loop either
- */
- if (to->trans[transnr].to != fromnr) {
- if (to->trans[transnr].count >= 0) {
- int newto = to->trans[transnr].to;
-
- xmlRegStateAddTrans(ctxt, from, NULL,
- ctxt->states[newto],
- -1, to->trans[transnr].count);
- } else {
-#ifdef DEBUG_REGEXP_GRAPH
- printf("Found epsilon trans %d from %d to %d\n",
- transnr, tonr, to->trans[transnr].to);
-#endif
- if (to->trans[transnr].counter >= 0) {
- xmlFAReduceEpsilonTransitions(ctxt, fromnr,
- to->trans[transnr].to,
- to->trans[transnr].counter);
- } else {
- xmlFAReduceEpsilonTransitions(ctxt, fromnr,
- to->trans[transnr].to,
- counter);
- }
- }
- }
- } else {
- int newto = to->trans[transnr].to;
-
- if (to->trans[transnr].counter >= 0) {
- xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom,
- ctxt->states[newto],
- to->trans[transnr].counter, -1);
- } else {
- xmlRegStateAddTrans(ctxt, from, to->trans[transnr].atom,
- ctxt->states[newto], counter, -1);
- }
- }
- }
- to->mark = XML_REGEXP_MARK_NORMAL;
-}
-
-/**
- * xmlFAEliminateEpsilonTransitions:
- * @ctxt: a regexp parser context
- *
- */
-static void
-xmlFAEliminateEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
- int statenr, transnr;
- xmlRegStatePtr state;
-
- /*
- * build the completed transitions bypassing the epsilons
- * Use a marking algorithm to avoid loops
- */
- for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
- state = ctxt->states[statenr];
- if (state == NULL)
- continue;
- for (transnr = 0;transnr < state->nbTrans;transnr++) {
- if ((state->trans[transnr].atom == NULL) &&
- (state->trans[transnr].to >= 0)) {
- if (state->trans[transnr].to == statenr) {
- state->trans[transnr].to = -1;
-#ifdef DEBUG_REGEXP_GRAPH
- printf("Removed loopback epsilon trans %d on %d\n",
- transnr, statenr);
-#endif
- } else if (state->trans[transnr].count < 0) {
- int newto = state->trans[transnr].to;
-
-#ifdef DEBUG_REGEXP_GRAPH
- printf("Found epsilon trans %d from %d to %d\n",
- transnr, statenr, newto);
-#endif
- state->mark = XML_REGEXP_MARK_START;
- xmlFAReduceEpsilonTransitions(ctxt, statenr,
- newto, state->trans[transnr].counter);
- state->mark = XML_REGEXP_MARK_NORMAL;
-#ifdef DEBUG_REGEXP_GRAPH
- } else {
- printf("Found counted transition %d on %d\n",
- transnr, statenr);
-#endif
- }
- }
- }
- }
- /*
- * Eliminate the epsilon transitions
- */
- for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
- state = ctxt->states[statenr];
- if (state == NULL)
- continue;
- for (transnr = 0;transnr < state->nbTrans;transnr++) {
- if ((state->trans[transnr].atom == NULL) &&
- (state->trans[transnr].count < 0) &&
- (state->trans[transnr].to >= 0)) {
- state->trans[transnr].to = -1;
- }
- }
- }
-
- /*
- * Use this pass to detect unreachable states too
- */
- for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
- state = ctxt->states[statenr];
- if (state != NULL)
- state->reached = 0;
- }
- state = ctxt->states[0];
- if (state != NULL)
- state->reached = 1;
- while (state != NULL) {
- xmlRegStatePtr target = NULL;
- state->reached = 2;
- /*
- * Mark all state reachable from the current reachable state
- */
- for (transnr = 0;transnr < state->nbTrans;transnr++) {
- if ((state->trans[transnr].to >= 0) &&
- ((state->trans[transnr].atom != NULL) ||
- (state->trans[transnr].count >= 0))) {
- int newto = state->trans[transnr].to;
-
- if (ctxt->states[newto] == NULL)
- continue;
- if (ctxt->states[newto]->reached == 0) {
- ctxt->states[newto]->reached = 1;
- target = ctxt->states[newto];
- }
- }
- }
- /*
- * find the next accessible state not explored
- */
- if (target == NULL) {
- for (statenr = 1;statenr < ctxt->nbStates;statenr++) {
- state = ctxt->states[statenr];
- if ((state != NULL) && (state->reached == 1)) {
- target = state;
- break;
- }
- }
- }
- state = target;
- }
- for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
- state = ctxt->states[statenr];
- if ((state != NULL) && (state->reached == 0)) {
-#ifdef DEBUG_REGEXP_GRAPH
- printf("Removed unreachable state %d\n", statenr);
-#endif
- xmlRegFreeState(state);
- ctxt->states[statenr] = NULL;
- }
- }
-
-}
-
-/**
- * xmlFACompareAtoms:
- * @atom1: an atom
- * @atom2: an atom
- *
- * Compares two atoms to check whether they are equivatents
- *
- * Returns 1 if yes and 0 otherwise
- */
-static int
-xmlFACompareAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2) {
- if (atom1 == atom2)
- return(1);
- if ((atom1 == NULL) || (atom2 == NULL))
- return(0);
-
- if (atom1->type != atom2->type)
- return(0);
- switch (atom1->type) {
- case XML_REGEXP_STRING:
- return(xmlStrEqual((xmlChar *)atom1->valuep,
- (xmlChar *)atom2->valuep));
- case XML_REGEXP_EPSILON:
- return(1);
- case XML_REGEXP_CHARVAL:
- return(atom1->codepoint == atom2->codepoint);
- case XML_REGEXP_RANGES:
- TODO;
- return(0);
- default:
- break;
- }
- return(1);
-}
-
-/**
- * xmlFARecurseDeterminism:
- * @ctxt: a regexp parser context
- *
- * Check whether the associated regexp is determinist,
- * should be called after xmlFAEliminateEpsilonTransitions()
- *
- */
-static int
-xmlFARecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
- int to, xmlRegAtomPtr atom) {
- int ret = 1;
- int transnr;
- xmlRegTransPtr t1;
-
- if (state == NULL)
- return(ret);
- for (transnr = 0;transnr < state->nbTrans;transnr++) {
- t1 = &(state->trans[transnr]);
- /*
- * check transitions conflicting with the one looked at
- */
- if (t1->atom == NULL) {
- if (t1->to == -1)
- continue;
- ret = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to],
- to, atom);
- if (ret == 0)
- return(0);
- continue;
- }
- if (t1->to != to)
- continue;
- if (xmlFACompareAtoms(t1->atom, atom))
- return(0);
- }
- return(ret);
-}
-
-/**
- * xmlFAComputesDeterminism:
- * @ctxt: a regexp parser context
- *
- * Check whether the associated regexp is determinist,
- * should be called after xmlFAEliminateEpsilonTransitions()
- *
- */
-static int
-xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt) {
- int statenr, transnr;
- xmlRegStatePtr state;
- xmlRegTransPtr t1, t2;
- int i;
- int ret = 1;
-
-#ifdef DEBUG_REGEXP_GRAPH
- printf("xmlFAComputesDeterminism\n");
- xmlRegPrintCtxt(stdout, ctxt);
-#endif
- if (ctxt->determinist != -1)
- return(ctxt->determinist);
-
- /*
- * Check for all states that there isn't 2 transitions
- * with the same atom and a different target.
- */
- for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
- state = ctxt->states[statenr];
- if (state == NULL)
- continue;
- for (transnr = 0;transnr < state->nbTrans;transnr++) {
- t1 = &(state->trans[transnr]);
- /*
- * Determinism checks in case of counted or all transitions
- * will have to be handled separately
- */
- if (t1->atom == NULL)
- continue;
- if (t1->to == -1) /* eliminated */
- continue;
- for (i = 0;i < transnr;i++) {
- t2 = &(state->trans[i]);
- if (t2->to == -1) /* eliminated */
- continue;
- if (t2->atom != NULL) {
- if (t1->to == t2->to) {
- if (xmlFACompareAtoms(t1->atom, t2->atom))
- t2->to = -1; /* eliminate */
- } else {
- /* not determinist ! */
- if (xmlFACompareAtoms(t1->atom, t2->atom))
- ret = 0;
- }
- } else if (t1->to != -1) {
- /*
- * do the closure in case of remaining specific
- * epsilon transitions like choices or all
- */
- ret = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to],
- t2->to, t2->atom);
- if (ret == 0)
- return(0);
- }
- }
- if (ret == 0)
- break;
- }
- if (ret == 0)
- break;
- }
- ctxt->determinist = ret;
- return(ret);
-}
-
-/************************************************************************
- * *
- * Routines to check input against transition atoms *
- * *
- ************************************************************************/
-
-static int
-xmlRegCheckCharacterRange(xmlRegAtomType type, int codepoint, int neg,
- int start, int end, const xmlChar *blockName) {
- int ret = 0;
-
- switch (type) {
- case XML_REGEXP_STRING:
- case XML_REGEXP_SUBREG:
- case XML_REGEXP_RANGES:
- case XML_REGEXP_EPSILON:
- return(-1);
- case XML_REGEXP_ANYCHAR:
- ret = ((codepoint != '\n') && (codepoint != '\r'));
- break;
- case XML_REGEXP_CHARVAL:
- ret = ((codepoint >= start) && (codepoint <= end));
- break;
- case XML_REGEXP_NOTSPACE:
- neg = !neg;
- case XML_REGEXP_ANYSPACE:
- ret = ((codepoint == '\n') || (codepoint == '\r') ||
- (codepoint == '\t') || (codepoint == ' '));
- break;
- case XML_REGEXP_NOTINITNAME:
- neg = !neg;
- case XML_REGEXP_INITNAME:
- ret = (xmlIsLetter(codepoint) ||
- (codepoint == '_') || (codepoint == ':'));
- break;
- case XML_REGEXP_NOTNAMECHAR:
- neg = !neg;
- case XML_REGEXP_NAMECHAR:
- ret = (xmlIsLetter(codepoint) || xmlIsDigit(codepoint) ||
- (codepoint == '.') || (codepoint == '-') ||
- (codepoint == '_') || (codepoint == ':') ||
- xmlIsCombining(codepoint) || xmlIsExtender(codepoint));
- break;
- case XML_REGEXP_NOTDECIMAL:
- neg = !neg;
- case XML_REGEXP_DECIMAL:
- ret = xmlUCSIsCatNd(codepoint);
- break;
- case XML_REGEXP_REALCHAR:
- neg = !neg;
- case XML_REGEXP_NOTREALCHAR:
- ret = xmlUCSIsCatP(codepoint);
- if (ret == 0)
- ret = xmlUCSIsCatZ(codepoint);
- if (ret == 0)
- ret = xmlUCSIsCatC(codepoint);
- break;
- case XML_REGEXP_LETTER:
- ret = xmlUCSIsCatL(codepoint);
- break;
- case XML_REGEXP_LETTER_UPPERCASE:
- ret = xmlUCSIsCatLu(codepoint);
- break;
- case XML_REGEXP_LETTER_LOWERCASE:
- ret = xmlUCSIsCatLl(codepoint);
- break;
- case XML_REGEXP_LETTER_TITLECASE:
- ret = xmlUCSIsCatLt(codepoint);
- break;
- case XML_REGEXP_LETTER_MODIFIER:
- ret = xmlUCSIsCatLm(codepoint);
- break;
- case XML_REGEXP_LETTER_OTHERS:
- ret = xmlUCSIsCatLo(codepoint);
- break;
- case XML_REGEXP_MARK:
- ret = xmlUCSIsCatM(codepoint);
- break;
- case XML_REGEXP_MARK_NONSPACING:
- ret = xmlUCSIsCatMn(codepoint);
- break;
- case XML_REGEXP_MARK_SPACECOMBINING:
- ret = xmlUCSIsCatMc(codepoint);
- break;
- case XML_REGEXP_MARK_ENCLOSING:
- ret = xmlUCSIsCatMe(codepoint);
- break;
- case XML_REGEXP_NUMBER:
- ret = xmlUCSIsCatN(codepoint);
- break;
- case XML_REGEXP_NUMBER_DECIMAL:
- ret = xmlUCSIsCatNd(codepoint);
- break;
- case XML_REGEXP_NUMBER_LETTER:
- ret = xmlUCSIsCatNl(codepoint);
- break;
- case XML_REGEXP_NUMBER_OTHERS:
- ret = xmlUCSIsCatNo(codepoint);
- break;
- case XML_REGEXP_PUNCT:
- ret = xmlUCSIsCatP(codepoint);
- break;
- case XML_REGEXP_PUNCT_CONNECTOR:
- ret = xmlUCSIsCatPc(codepoint);
- break;
- case XML_REGEXP_PUNCT_DASH:
- ret = xmlUCSIsCatPd(codepoint);
- break;
- case XML_REGEXP_PUNCT_OPEN:
- ret = xmlUCSIsCatPs(codepoint);
- break;
- case XML_REGEXP_PUNCT_CLOSE:
- ret = xmlUCSIsCatPe(codepoint);
- break;
- case XML_REGEXP_PUNCT_INITQUOTE:
- ret = xmlUCSIsCatPi(codepoint);
- break;
- case XML_REGEXP_PUNCT_FINQUOTE:
- ret = xmlUCSIsCatPf(codepoint);
- break;
- case XML_REGEXP_PUNCT_OTHERS:
- ret = xmlUCSIsCatPo(codepoint);
- break;
- case XML_REGEXP_SEPAR:
- ret = xmlUCSIsCatZ(codepoint);
- break;
- case XML_REGEXP_SEPAR_SPACE:
- ret = xmlUCSIsCatZs(codepoint);
- break;
- case XML_REGEXP_SEPAR_LINE:
- ret = xmlUCSIsCatZl(codepoint);
- break;
- case XML_REGEXP_SEPAR_PARA:
- ret = xmlUCSIsCatZp(codepoint);
- break;
- case XML_REGEXP_SYMBOL:
- ret = xmlUCSIsCatS(codepoint);
- break;
- case XML_REGEXP_SYMBOL_MATH:
- ret = xmlUCSIsCatSm(codepoint);
- break;
- case XML_REGEXP_SYMBOL_CURRENCY:
- ret = xmlUCSIsCatSc(codepoint);
- break;
- case XML_REGEXP_SYMBOL_MODIFIER:
- ret = xmlUCSIsCatSk(codepoint);
- break;
- case XML_REGEXP_SYMBOL_OTHERS:
- ret = xmlUCSIsCatSo(codepoint);
- break;
- case XML_REGEXP_OTHER:
- ret = xmlUCSIsCatC(codepoint);
- break;
- case XML_REGEXP_OTHER_CONTROL:
- ret = xmlUCSIsCatCc(codepoint);
- break;
- case XML_REGEXP_OTHER_FORMAT:
- ret = xmlUCSIsCatCf(codepoint);
- break;
- case XML_REGEXP_OTHER_PRIVATE:
- ret = xmlUCSIsCatCo(codepoint);
- break;
- case XML_REGEXP_OTHER_NA:
- /* ret = xmlUCSIsCatCn(codepoint); */
- /* Seems it doesn't exist anymore in recent Unicode releases */
- ret = 0;
- break;
- case XML_REGEXP_BLOCK_NAME:
- ret = xmlUCSIsBlock(codepoint, (const char *) blockName);
- break;
- }
- if (neg)
- return(!ret);
- return(ret);
-}
-
-static int
-xmlRegCheckCharacter(xmlRegAtomPtr atom, int codepoint) {
- int i, ret = 0;
- xmlRegRangePtr range;
-
- if ((atom == NULL) || (!xmlIsChar(codepoint)))
- return(-1);
-
- switch (atom->type) {
- case XML_REGEXP_SUBREG:
- case XML_REGEXP_EPSILON:
- return(-1);
- case XML_REGEXP_CHARVAL:
- return(codepoint == atom->codepoint);
- case XML_REGEXP_RANGES: {
- int accept = 0;
- for (i = 0;i < atom->nbRanges;i++) {
- range = atom->ranges[i];
- if (range->neg) {
- ret = xmlRegCheckCharacterRange(range->type, codepoint,
- 0, range->start, range->end,
- range->blockName);
- if (ret != 0)
- return(0); /* excluded char */
- } else {
- ret = xmlRegCheckCharacterRange(range->type, codepoint,
- 0, range->start, range->end,
- range->blockName);
- if (ret != 0)
- accept = 1; /* might still be excluded */
- }
- }
- return(accept);
- }
- case XML_REGEXP_STRING:
- printf("TODO: XML_REGEXP_STRING\n");
- return(-1);
- case XML_REGEXP_ANYCHAR:
- case XML_REGEXP_ANYSPACE:
- case XML_REGEXP_NOTSPACE:
- case XML_REGEXP_INITNAME:
- case XML_REGEXP_NOTINITNAME:
- case XML_REGEXP_NAMECHAR:
- case XML_REGEXP_NOTNAMECHAR:
- case XML_REGEXP_DECIMAL:
- case XML_REGEXP_NOTDECIMAL:
- case XML_REGEXP_REALCHAR:
- case XML_REGEXP_NOTREALCHAR:
- case XML_REGEXP_LETTER:
- case XML_REGEXP_LETTER_UPPERCASE:
- case XML_REGEXP_LETTER_LOWERCASE:
- case XML_REGEXP_LETTER_TITLECASE:
- case XML_REGEXP_LETTER_MODIFIER:
- case XML_REGEXP_LETTER_OTHERS:
- case XML_REGEXP_MARK:
- case XML_REGEXP_MARK_NONSPACING:
- case XML_REGEXP_MARK_SPACECOMBINING:
- case XML_REGEXP_MARK_ENCLOSING:
- case XML_REGEXP_NUMBER:
- case XML_REGEXP_NUMBER_DECIMAL:
- case XML_REGEXP_NUMBER_LETTER:
- case XML_REGEXP_NUMBER_OTHERS:
- case XML_REGEXP_PUNCT:
- case XML_REGEXP_PUNCT_CONNECTOR:
- case XML_REGEXP_PUNCT_DASH:
- case XML_REGEXP_PUNCT_OPEN:
- case XML_REGEXP_PUNCT_CLOSE:
- case XML_REGEXP_PUNCT_INITQUOTE:
- case XML_REGEXP_PUNCT_FINQUOTE:
- case XML_REGEXP_PUNCT_OTHERS:
- case XML_REGEXP_SEPAR:
- case XML_REGEXP_SEPAR_SPACE:
- case XML_REGEXP_SEPAR_LINE:
- case XML_REGEXP_SEPAR_PARA:
- case XML_REGEXP_SYMBOL:
- case XML_REGEXP_SYMBOL_MATH:
- case XML_REGEXP_SYMBOL_CURRENCY:
- case XML_REGEXP_SYMBOL_MODIFIER:
- case XML_REGEXP_SYMBOL_OTHERS:
- case XML_REGEXP_OTHER:
- case XML_REGEXP_OTHER_CONTROL:
- case XML_REGEXP_OTHER_FORMAT:
- case XML_REGEXP_OTHER_PRIVATE:
- case XML_REGEXP_OTHER_NA:
- case XML_REGEXP_BLOCK_NAME:
- ret = xmlRegCheckCharacterRange(atom->type, codepoint, 0, 0, 0,
- (const xmlChar *)atom->valuep);
- if (atom->neg)
- ret = !ret;
- break;
- }
- return(ret);
-}
-
-/************************************************************************
- * *
- * Saving an restoring state of an execution context *
- * *
- ************************************************************************/
-
-#ifdef DEBUG_REGEXP_EXEC
-static void
-xmlFARegDebugExec(xmlRegExecCtxtPtr exec) {
- printf("state: %d:%d:idx %d", exec->state->no, exec->transno, exec->index);
- if (exec->inputStack != NULL) {
- int i;
- printf(": ");
- for (i = 0;(i < 3) && (i < exec->inputStackNr);i++)
- printf("%s ", exec->inputStack[exec->inputStackNr - (i + 1)]);
- } else {
- printf(": %s", &(exec->inputString[exec->index]));
- }
- printf("\n");
-}
-#endif
-
-static void
-xmlFARegExecSave(xmlRegExecCtxtPtr exec) {
-#ifdef DEBUG_REGEXP_EXEC
- printf("saving ");
- exec->transno++;
- xmlFARegDebugExec(exec);
- exec->transno--;
-#endif
-
- if (exec->maxRollbacks == 0) {
- exec->maxRollbacks = 4;
- exec->rollbacks = (xmlRegExecRollback *) xmlMalloc(exec->maxRollbacks *
- sizeof(xmlRegExecRollback));
- if (exec->rollbacks == NULL) {
- fprintf(stderr, "exec save: allocation failed");
- exec->maxRollbacks = 0;
- return;
- }
- memset(exec->rollbacks, 0,
- exec->maxRollbacks * sizeof(xmlRegExecRollback));
- } else if (exec->nbRollbacks >= exec->maxRollbacks) {
- xmlRegExecRollback *tmp;
- int len = exec->maxRollbacks;
-
- exec->maxRollbacks *= 2;
- tmp = (xmlRegExecRollback *) xmlRealloc(exec->rollbacks,
- exec->maxRollbacks * sizeof(xmlRegExecRollback));
- if (tmp == NULL) {
- fprintf(stderr, "exec save: allocation failed");
- exec->maxRollbacks /= 2;
- return;
- }
- exec->rollbacks = tmp;
- tmp = &exec->rollbacks[len];
- memset(tmp, 0, (exec->maxRollbacks - len) * sizeof(xmlRegExecRollback));
- }
- exec->rollbacks[exec->nbRollbacks].state = exec->state;
- exec->rollbacks[exec->nbRollbacks].index = exec->index;
- exec->rollbacks[exec->nbRollbacks].nextbranch = exec->transno + 1;
- if (exec->comp->nbCounters > 0) {
- if (exec->rollbacks[exec->nbRollbacks].counts == NULL) {
- exec->rollbacks[exec->nbRollbacks].counts = (int *)
- xmlMalloc(exec->comp->nbCounters * sizeof(int));
- if (exec->rollbacks[exec->nbRollbacks].counts == NULL) {
- fprintf(stderr, "exec save: allocation failed");
- exec->status = -5;
- return;
- }
- }
- memcpy(exec->rollbacks[exec->nbRollbacks].counts, exec->counts,
- exec->comp->nbCounters * sizeof(int));
- }
- exec->nbRollbacks++;
-}
-
-static void
-xmlFARegExecRollBack(xmlRegExecCtxtPtr exec) {
- if (exec->nbRollbacks <= 0) {
- exec->status = -1;
-#ifdef DEBUG_REGEXP_EXEC
- printf("rollback failed on empty stack\n");
-#endif
- return;
- }
- exec->nbRollbacks--;
- exec->state = exec->rollbacks[exec->nbRollbacks].state;
- exec->index = exec->rollbacks[exec->nbRollbacks].index;
- exec->transno = exec->rollbacks[exec->nbRollbacks].nextbranch;
- if (exec->comp->nbCounters > 0) {
- if (exec->rollbacks[exec->nbRollbacks].counts == NULL) {
- fprintf(stderr, "exec save: allocation failed");
- exec->status = -6;
- return;
- }
- memcpy(exec->counts, exec->rollbacks[exec->nbRollbacks].counts,
- exec->comp->nbCounters * sizeof(int));
- }
-
-#ifdef DEBUG_REGEXP_EXEC
- printf("restored ");
- xmlFARegDebugExec(exec);
-#endif
-}
-
-/************************************************************************
- * *
- * Verifyer, running an input against a compiled regexp *
- * *
- ************************************************************************/
-
-static int
-xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
- xmlRegExecCtxt execval;
- xmlRegExecCtxtPtr exec = &execval;
- int ret, codepoint, len;
-
- exec->inputString = content;
- exec->index = 0;
- exec->determinist = 1;
- exec->maxRollbacks = 0;
- exec->nbRollbacks = 0;
- exec->rollbacks = NULL;
- exec->status = 0;
- exec->comp = comp;
- exec->state = comp->states[0];
- exec->transno = 0;
- exec->transcount = 0;
- if (comp->nbCounters > 0) {
- exec->counts = (int *) xmlMalloc(comp->nbCounters * sizeof(int));
- if (exec->counts == NULL)
- return(-1);
- memset(exec->counts, 0, comp->nbCounters * sizeof(int));
- } else
- exec->counts = NULL;
- while ((exec->status == 0) &&
- ((exec->inputString[exec->index] != 0) ||
- (exec->state->type != XML_REGEXP_FINAL_STATE))) {
- xmlRegTransPtr trans;
- xmlRegAtomPtr atom;
-
- /*
- * End of input on non-terminal state, rollback, however we may
- * still have epsilon like transition for counted transitions
- * on counters, in that case don't break too early.
- */
- if ((exec->inputString[exec->index] == 0) && (exec->counts == NULL))
- goto rollback;
-
- exec->transcount = 0;
- for (;exec->transno < exec->state->nbTrans;exec->transno++) {
- trans = &exec->state->trans[exec->transno];
- if (trans->to < 0)
- continue;
- atom = trans->atom;
- ret = 0;
- if (trans->count >= 0) {
- int count;
- xmlRegCounterPtr counter;
-
- /*
- * A counted transition.
- */
-
- count = exec->counts[trans->count];
- counter = &exec->comp->counters[trans->count];
-#ifdef DEBUG_REGEXP_EXEC
- printf("testing count %d: val %d, min %d, max %d\n",
- trans->count, count, counter->min, counter->max);
-#endif
- ret = ((count >= counter->min) && (count <= counter->max));
- } else if (atom == NULL) {
- fprintf(stderr, "epsilon transition left at runtime\n");
- exec->status = -2;
- break;
- } else if (exec->inputString[exec->index] != 0) {
- codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), len);
- ret = xmlRegCheckCharacter(atom, codepoint);
- if ((ret == 1) && (atom->min > 0) && (atom->max > 0)) {
- xmlRegStatePtr to = comp->states[trans->to];
-
- /*
- * this is a multiple input sequence
- */
- if (exec->state->nbTrans > exec->transno + 1) {
- xmlFARegExecSave(exec);
- }
- exec->transcount = 1;
- do {
- /*
- * Try to progress as much as possible on the input
- */
- if (exec->transcount == atom->max) {
- break;
- }
- exec->index += len;
- /*
- * End of input: stop here
- */
- if (exec->inputString[exec->index] == 0) {
- exec->index -= len;
- break;
- }
- if (exec->transcount >= atom->min) {
- int transno = exec->transno;
- xmlRegStatePtr state = exec->state;
-
- /*
- * The transition is acceptable save it
- */
- exec->transno = -1; /* trick */
- exec->state = to;
- xmlFARegExecSave(exec);
- exec->transno = transno;
- exec->state = state;
- }
- codepoint = CUR_SCHAR(&(exec->inputString[exec->index]),
- len);
- ret = xmlRegCheckCharacter(atom, codepoint);
- exec->transcount++;
- } while (ret == 1);
- if (exec->transcount < atom->min)
- ret = 0;
-
- /*
- * If the last check failed but one transition was found
- * possible, rollback
- */
- if (ret < 0)
- ret = 0;
- if (ret == 0) {
- goto rollback;
- }
- }
- }
- if (ret == 1) {
- if (exec->state->nbTrans > exec->transno + 1) {
- xmlFARegExecSave(exec);
- }
- if (trans->counter >= 0) {
-#ifdef DEBUG_REGEXP_EXEC
- printf("Increasing count %d\n", trans->counter);
-#endif
- exec->counts[trans->counter]++;
- }
-#ifdef DEBUG_REGEXP_EXEC
- printf("entering state %d\n", trans->to);
-#endif
- exec->state = comp->states[trans->to];
- exec->transno = 0;
- if (trans->atom != NULL) {
- exec->index += len;
- }
- goto progress;
- } else if (ret < 0) {
- exec->status = -4;
- break;
- }
- }
- if ((exec->transno != 0) || (exec->state->nbTrans == 0)) {
-rollback:
- /*
- * Failed to find a way out
- */
- exec->determinist = 0;
- xmlFARegExecRollBack(exec);
- }
-progress:
- continue;
- }
- if (exec->rollbacks != NULL) {
- if (exec->counts != NULL) {
- int i;
-
- for (i = 0;i < exec->maxRollbacks;i++)
- if (exec->rollbacks[i].counts != NULL)
- xmlFree(exec->rollbacks[i].counts);
- }
- xmlFree(exec->rollbacks);
- }
- if (exec->counts != NULL)
- xmlFree(exec->counts);
- if (exec->status == 0)
- return(1);
- if (exec->status == -1)
- return(0);
- return(exec->status);
-}
-
-/************************************************************************
- * *
- * Progressive interface to the verifyer one atom at a time *
- * *
- ************************************************************************/
-
-/**
- * xmlRegNewExecCtxt:
- * @comp: a precompiled regular expression
- * @callback: a callback function used for handling progresses in the
- * automata matching phase
- * @data: the context data associated to the callback in this context
- *
- * Build a context used for progressive evaluation of a regexp.
- *
- * Returns the new context
- */
-xmlRegExecCtxtPtr
-xmlRegNewExecCtxt(xmlRegexpPtr comp, xmlRegExecCallbacks callback, void *data) {
- xmlRegExecCtxtPtr exec;
-
- if (comp == NULL)
- return(NULL);
- exec = (xmlRegExecCtxtPtr) xmlMalloc(sizeof(xmlRegExecCtxt));
- if (exec == NULL) {
- return(NULL);
- }
- memset(exec, 0, sizeof(xmlRegExecCtxt));
- exec->inputString = NULL;
- exec->index = 0;
- exec->determinist = 1;
- exec->maxRollbacks = 0;
- exec->nbRollbacks = 0;
- exec->rollbacks = NULL;
- exec->status = 0;
- exec->comp = comp;
- if (comp->compact == NULL)
- exec->state = comp->states[0];
- exec->transno = 0;
- exec->transcount = 0;
- exec->callback = callback;
- exec->data = data;
- if (comp->nbCounters > 0) {
- exec->counts = (int *) xmlMalloc(comp->nbCounters * sizeof(int));
- if (exec->counts == NULL) {
- xmlFree(exec);
- return(NULL);
- }
- memset(exec->counts, 0, comp->nbCounters * sizeof(int));
- } else
- exec->counts = NULL;
- exec->inputStackMax = 0;
- exec->inputStackNr = 0;
- exec->inputStack = NULL;
- return(exec);
-}
-
-/**
- * xmlRegFreeExecCtxt:
- * @exec: a regular expression evaulation context
- *
- * Free the structures associated to a regular expression evaulation context.
- */
-void
-xmlRegFreeExecCtxt(xmlRegExecCtxtPtr exec) {
- if (exec == NULL)
- return;
-
- if (exec->rollbacks != NULL) {
- if (exec->counts != NULL) {
- int i;
-
- for (i = 0;i < exec->maxRollbacks;i++)
- if (exec->rollbacks[i].counts != NULL)
- xmlFree(exec->rollbacks[i].counts);
- }
- xmlFree(exec->rollbacks);
- }
- if (exec->counts != NULL)
- xmlFree(exec->counts);
- if (exec->inputStack != NULL) {
- int i;
-
- for (i = 0;i < exec->inputStackNr;i++) {
- if (exec->inputStack[i].value != NULL)
- xmlFree(exec->inputStack[i].value);
- }
- xmlFree(exec->inputStack);
- }
- xmlFree(exec);
-}
-
-static void
-xmlFARegExecSaveInputString(xmlRegExecCtxtPtr exec, const xmlChar *value,
- void *data) {
-#ifdef DEBUG_PUSH
- printf("saving value: %d:%s\n", exec->inputStackNr, value);
-#endif
- if (exec->inputStackMax == 0) {
- exec->inputStackMax = 4;
- exec->inputStack = (xmlRegInputTokenPtr)
- xmlMalloc(exec->inputStackMax * sizeof(xmlRegInputToken));
- if (exec->inputStack == NULL) {
- fprintf(stderr, "push input: allocation failed");
- exec->inputStackMax = 0;
- return;
- }
- } else if (exec->inputStackNr + 1 >= exec->inputStackMax) {
- xmlRegInputTokenPtr tmp;
-
- exec->inputStackMax *= 2;
- tmp = (xmlRegInputTokenPtr) xmlRealloc(exec->inputStack,
- exec->inputStackMax * sizeof(xmlRegInputToken));
- if (tmp == NULL) {
- fprintf(stderr, "push input: allocation failed");
- exec->inputStackMax /= 2;
- return;
- }
- exec->inputStack = tmp;
- }
- exec->inputStack[exec->inputStackNr].value = xmlStrdup(value);
- exec->inputStack[exec->inputStackNr].data = data;
- exec->inputStackNr++;
- exec->inputStack[exec->inputStackNr].value = NULL;
- exec->inputStack[exec->inputStackNr].data = NULL;
-}
-
-
-/**
- * xmlRegCompactPushString:
- * @exec: a regexp execution context
- * @comp: the precompiled exec with a compact table
- * @value: a string token input
- * @data: data associated to the token to reuse in callbacks
- *
- * Push one input token in the execution context
- *
- * Returns: 1 if the regexp reached a final state, 0 if non-final, and
- * a negative value in case of error.
- */
-static int
-xmlRegCompactPushString(xmlRegExecCtxtPtr exec,
- xmlRegexpPtr comp,
- const xmlChar *value,
- void *data) {
- int state = exec->index;
- int i, target;
-
- if ((comp == NULL) || (comp->compact == NULL) || (comp->stringMap == NULL))
- return(-1);
-
- if (value == NULL) {
- /*
- * are we at a final state ?
- */
- if (comp->compact[state * (comp->nbstrings + 1)] ==
- XML_REGEXP_FINAL_STATE)
- return(1);
- return(0);
- }
-
-#ifdef DEBUG_PUSH
- printf("value pushed: %s\n", value);
-#endif
-
- /*
- * Examine all outside transition from current state
- */
- for (i = 0;i < comp->nbstrings;i++) {
- target = comp->compact[state * (comp->nbstrings + 1) + i + 1];
- if ((target > 0) && (target <= comp->nbstates)) {
- target--; /* to avoid 0 */
- if (xmlStrEqual(comp->stringMap[i], value)) {
- exec->index = target;
- if ((exec->callback != NULL) && (comp->transdata != NULL)) {
- exec->callback(exec->data, value,
- comp->transdata[state * comp->nbstrings + i], data);
- }
-#ifdef DEBUG_PUSH
- printf("entering state %d\n", target);
-#endif
- if (comp->compact[target * (comp->nbstrings + 1)] ==
- XML_REGEXP_FINAL_STATE)
- return(1);
- return(0);
- }
- }
- }
- /*
- * Failed to find an exit transition out from current state for the
- * current token
- */
-#ifdef DEBUG_PUSH
- printf("failed to find a transition for %s on state %d\n", value, state);
-#endif
- exec->status = -1;
- return(-1);
-}
-
-/**
- * xmlRegExecPushString:
- * @exec: a regexp execution context
- * @value: a string token input
- * @data: data associated to the token to reuse in callbacks
- *
- * Push one input token in the execution context
- *
- * Returns: 1 if the regexp reached a final state, 0 if non-final, and
- * a negative value in case of error.
- */
-int
-xmlRegExecPushString(xmlRegExecCtxtPtr exec, const xmlChar *value,
- void *data) {
- xmlRegTransPtr trans;
- xmlRegAtomPtr atom;
- int ret;
- int final = 0;
-
- if (exec == NULL)
- return(-1);
- if (exec->comp == NULL)
- return(-1);
- if (exec->status != 0)
- return(exec->status);
-
- if (exec->comp->compact != NULL)
- return(xmlRegCompactPushString(exec, exec->comp, value, data));
-
- if (value == NULL) {
- if (exec->state->type == XML_REGEXP_FINAL_STATE)
- return(1);
- final = 1;
- }
-
-#ifdef DEBUG_PUSH
- printf("value pushed: %s\n", value);
-#endif
- /*
- * If we have an active rollback stack push the new value there
- * and get back to where we were left
- */
- if ((value != NULL) && (exec->inputStackNr > 0)) {
- xmlFARegExecSaveInputString(exec, value, data);
- value = exec->inputStack[exec->index].value;
- data = exec->inputStack[exec->index].data;
-#ifdef DEBUG_PUSH
- printf("value loaded: %s\n", value);
-#endif
- }
-
- while ((exec->status == 0) &&
- ((value != NULL) ||
- ((final == 1) &&
- (exec->state->type != XML_REGEXP_FINAL_STATE)))) {
-
- /*
- * End of input on non-terminal state, rollback, however we may
- * still have epsilon like transition for counted transitions
- * on counters, in that case don't break too early.
- */
- if ((value == NULL) && (exec->counts == NULL))
- goto rollback;
-
- exec->transcount = 0;
- for (;exec->transno < exec->state->nbTrans;exec->transno++) {
- trans = &exec->state->trans[exec->transno];
- if (trans->to < 0)
- continue;
- atom = trans->atom;
- ret = 0;
- if (trans->count == REGEXP_ALL_LAX_COUNTER) {
- int i;
- int count;
- xmlRegTransPtr t;
- xmlRegCounterPtr counter;
-
- ret = 0;
-
-#ifdef DEBUG_PUSH
- printf("testing all lax %d\n", trans->count);
-#endif
- /*
- * Check all counted transitions from the current state
- */
- if ((value == NULL) && (final)) {
- ret = 1;
- } else if (value != NULL) {
- for (i = 0;i < exec->state->nbTrans;i++) {
- t = &exec->state->trans[i];
- if ((t->counter < 0) || (t == trans))
- continue;
- counter = &exec->comp->counters[t->counter];
- count = exec->counts[t->counter];
- if ((count < counter->max) &&
- (t->atom != NULL) &&
- (xmlStrEqual(value, t->atom->valuep))) {
- ret = 0;
- break;
- }
- if ((count >= counter->min) &&
- (count < counter->max) &&
- (xmlStrEqual(value, t->atom->valuep))) {
- ret = 1;
- break;
- }
- }
- }
- } else if (trans->count == REGEXP_ALL_COUNTER) {
- int i;
- int count;
- xmlRegTransPtr t;
- xmlRegCounterPtr counter;
-
- ret = 1;
-
-#ifdef DEBUG_PUSH
- printf("testing all %d\n", trans->count);
-#endif
- /*
- * Check all counted transitions from the current state
- */
- for (i = 0;i < exec->state->nbTrans;i++) {
- t = &exec->state->trans[i];
- if ((t->counter < 0) || (t == trans))
- continue;
- counter = &exec->comp->counters[t->counter];
- count = exec->counts[t->counter];
- if ((count < counter->min) || (count > counter->max)) {
- ret = 0;
- break;
- }
- }
- } else if (trans->count >= 0) {
- int count;
- xmlRegCounterPtr counter;
-
- /*
- * A counted transition.
- */
-
- count = exec->counts[trans->count];
- counter = &exec->comp->counters[trans->count];
-#ifdef DEBUG_PUSH
- printf("testing count %d: val %d, min %d, max %d\n",
- trans->count, count, counter->min, counter->max);
-#endif
- ret = ((count >= counter->min) && (count <= counter->max));
- } else if (atom == NULL) {
- fprintf(stderr, "epsilon transition left at runtime\n");
- exec->status = -2;
- break;
- } else if (value != NULL) {
- ret = xmlStrEqual(value, atom->valuep);
- if ((ret == 1) && (trans->counter >= 0)) {
- xmlRegCounterPtr counter;
- int count;
-
- count = exec->counts[trans->counter];
- counter = &exec->comp->counters[trans->counter];
- if (count >= counter->max)
- ret = 0;
- }
-
- if ((ret == 1) && (atom->min > 0) && (atom->max > 0)) {
- xmlRegStatePtr to = exec->comp->states[trans->to];
-
- /*
- * this is a multiple input sequence
- */
- if (exec->state->nbTrans > exec->transno + 1) {
- if (exec->inputStackNr <= 0) {
- xmlFARegExecSaveInputString(exec, value, data);
- }
- xmlFARegExecSave(exec);
- }
- exec->transcount = 1;
- do {
- /*
- * Try to progress as much as possible on the input
- */
- if (exec->transcount == atom->max) {
- break;
- }
- exec->index++;
- value = exec->inputStack[exec->index].value;
- data = exec->inputStack[exec->index].data;
-#ifdef DEBUG_PUSH
- printf("value loaded: %s\n", value);
-#endif
-
- /*
- * End of input: stop here
- */
- if (value == NULL) {
- exec->index --;
- break;
- }
- if (exec->transcount >= atom->min) {
- int transno = exec->transno;
- xmlRegStatePtr state = exec->state;
-
- /*
- * The transition is acceptable save it
- */
- exec->transno = -1; /* trick */
- exec->state = to;
- if (exec->inputStackNr <= 0) {
- xmlFARegExecSaveInputString(exec, value, data);
- }
- xmlFARegExecSave(exec);
- exec->transno = transno;
- exec->state = state;
- }
- ret = xmlStrEqual(value, atom->valuep);
- exec->transcount++;
- } while (ret == 1);
- if (exec->transcount < atom->min)
- ret = 0;
-
- /*
- * If the last check failed but one transition was found
- * possible, rollback
- */
- if (ret < 0)
- ret = 0;
- if (ret == 0) {
- goto rollback;
- }
- }
- }
- if (ret == 1) {
- if ((exec->callback != NULL) && (atom != NULL)) {
- exec->callback(exec->data, atom->valuep,
- atom->data, data);
- }
- if (exec->state->nbTrans > exec->transno + 1) {
- if (exec->inputStackNr <= 0) {
- xmlFARegExecSaveInputString(exec, value, data);
- }
- xmlFARegExecSave(exec);
- }
- if (trans->counter >= 0) {
-#ifdef DEBUG_PUSH
- printf("Increasing count %d\n", trans->counter);
-#endif
- exec->counts[trans->counter]++;
- }
-#ifdef DEBUG_PUSH
- printf("entering state %d\n", trans->to);
-#endif
- exec->state = exec->comp->states[trans->to];
- exec->transno = 0;
- if (trans->atom != NULL) {
- if (exec->inputStack != NULL) {
- exec->index++;
- if (exec->index < exec->inputStackNr) {
- value = exec->inputStack[exec->index].value;
- data = exec->inputStack[exec->index].data;
-#ifdef DEBUG_PUSH
- printf("value loaded: %s\n", value);
-#endif
- } else {
- value = NULL;
- data = NULL;
-#ifdef DEBUG_PUSH
- printf("end of input\n");
-#endif
- }
- } else {
- value = NULL;
- data = NULL;
-#ifdef DEBUG_PUSH
- printf("end of input\n");
-#endif
- }
- }
- goto progress;
- } else if (ret < 0) {
- exec->status = -4;
- break;
- }
- }
- if ((exec->transno != 0) || (exec->state->nbTrans == 0)) {
-rollback:
- /*
- * Failed to find a way out
- */
- exec->determinist = 0;
- xmlFARegExecRollBack(exec);
- if (exec->status == 0) {
- value = exec->inputStack[exec->index].value;
- data = exec->inputStack[exec->index].data;
-#ifdef DEBUG_PUSH
- printf("value loaded: %s\n", value);
-#endif
- }
- }
-progress:
- continue;
- }
- if (exec->status == 0) {
- return(exec->state->type == XML_REGEXP_FINAL_STATE);
- }
- return(exec->status);
-}
-
-#if 0
-static int
-xmlRegExecPushChar(xmlRegExecCtxtPtr exec, int UCS) {
- xmlRegTransPtr trans;
- xmlRegAtomPtr atom;
- int ret;
- int codepoint, len;
-
- if (exec == NULL)
- return(-1);
- if (exec->status != 0)
- return(exec->status);
-
- while ((exec->status == 0) &&
- ((exec->inputString[exec->index] != 0) ||
- (exec->state->type != XML_REGEXP_FINAL_STATE))) {
-
- /*
- * End of input on non-terminal state, rollback, however we may
- * still have epsilon like transition for counted transitions
- * on counters, in that case don't break too early.
- */
- if ((exec->inputString[exec->index] == 0) && (exec->counts == NULL))
- goto rollback;
-
- exec->transcount = 0;
- for (;exec->transno < exec->state->nbTrans;exec->transno++) {
- trans = &exec->state->trans[exec->transno];
- if (trans->to < 0)
- continue;
- atom = trans->atom;
- ret = 0;
- if (trans->count >= 0) {
- int count;
- xmlRegCounterPtr counter;
-
- /*
- * A counted transition.
- */
-
- count = exec->counts[trans->count];
- counter = &exec->comp->counters[trans->count];
-#ifdef DEBUG_REGEXP_EXEC
- printf("testing count %d: val %d, min %d, max %d\n",
- trans->count, count, counter->min, counter->max);
-#endif
- ret = ((count >= counter->min) && (count <= counter->max));
- } else if (atom == NULL) {
- fprintf(stderr, "epsilon transition left at runtime\n");
- exec->status = -2;
- break;
- } else if (exec->inputString[exec->index] != 0) {
- codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), len);
- ret = xmlRegCheckCharacter(atom, codepoint);
- if ((ret == 1) && (atom->min > 0) && (atom->max > 0)) {
- xmlRegStatePtr to = exec->comp->states[trans->to];
-
- /*
- * this is a multiple input sequence
- */
- if (exec->state->nbTrans > exec->transno + 1) {
- xmlFARegExecSave(exec);
- }
- exec->transcount = 1;
- do {
- /*
- * Try to progress as much as possible on the input
- */
- if (exec->transcount == atom->max) {
- break;
- }
- exec->index += len;
- /*
- * End of input: stop here
- */
- if (exec->inputString[exec->index] == 0) {
- exec->index -= len;
- break;
- }
- if (exec->transcount >= atom->min) {
- int transno = exec->transno;
- xmlRegStatePtr state = exec->state;
-
- /*
- * The transition is acceptable save it
- */
- exec->transno = -1; /* trick */
- exec->state = to;
- xmlFARegExecSave(exec);
- exec->transno = transno;
- exec->state = state;
- }
- codepoint = CUR_SCHAR(&(exec->inputString[exec->index]),
- len);
- ret = xmlRegCheckCharacter(atom, codepoint);
- exec->transcount++;
- } while (ret == 1);
- if (exec->transcount < atom->min)
- ret = 0;
-
- /*
- * If the last check failed but one transition was found
- * possible, rollback
- */
- if (ret < 0)
- ret = 0;
- if (ret == 0) {
- goto rollback;
- }
- }
- }
- if (ret == 1) {
- if (exec->state->nbTrans > exec->transno + 1) {
- xmlFARegExecSave(exec);
- }
- if (trans->counter >= 0) {
-#ifdef DEBUG_REGEXP_EXEC
- printf("Increasing count %d\n", trans->counter);
-#endif
- exec->counts[trans->counter]++;
- }
-#ifdef DEBUG_REGEXP_EXEC
- printf("entering state %d\n", trans->to);
-#endif
- exec->state = exec->comp->states[trans->to];
- exec->transno = 0;
- if (trans->atom != NULL) {
- exec->index += len;
- }
- goto progress;
- } else if (ret < 0) {
- exec->status = -4;
- break;
- }
- }
- if ((exec->transno != 0) || (exec->state->nbTrans == 0)) {
-rollback:
- /*
- * Failed to find a way out
- */
- exec->determinist = 0;
- xmlFARegExecRollBack(exec);
- }
-progress:
- continue;
- }
-}
-#endif
-/************************************************************************
- * *
- * Parser for the Shemas Datatype Regular Expressions *
- * http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/#regexs *
- * *
- ************************************************************************/
-
-/**
- * xmlFAIsChar:
- * @ctxt: a regexp parser context
- *
- * [10] Char ::= [^.\?*+()|#x5B#x5D]
- */
-static int
-xmlFAIsChar(xmlRegParserCtxtPtr ctxt) {
- int cur;
- int len;
-
- cur = CUR_SCHAR(ctxt->cur, len);
- if ((cur == '.') || (cur == '\\') || (cur == '?') ||
- (cur == '*') || (cur == '+') || (cur == '(') ||
- (cur == ')') || (cur == '|') || (cur == 0x5B) ||
- (cur == 0x5D) || (cur == 0))
- return(-1);
- return(cur);
-}
-
-/**
- * xmlFAParseCharProp:
- * @ctxt: a regexp parser context
- *
- * [27] charProp ::= IsCategory | IsBlock
- * [28] IsCategory ::= Letters | Marks | Numbers | Punctuation |
- * Separators | Symbols | Others
- * [29] Letters ::= 'L' [ultmo]?
- * [30] Marks ::= 'M' [nce]?
- * [31] Numbers ::= 'N' [dlo]?
- * [32] Punctuation ::= 'P' [cdseifo]?
- * [33] Separators ::= 'Z' [slp]?
- * [34] Symbols ::= 'S' [mcko]?
- * [35] Others ::= 'C' [cfon]?
- * [36] IsBlock ::= 'Is' [a-zA-Z0-9#x2D]+
- */
-static void
-xmlFAParseCharProp(xmlRegParserCtxtPtr ctxt) {
- int cur;
- xmlRegAtomType type = 0;
- xmlChar *blockName = NULL;
-
- cur = CUR;
- if (cur == 'L') {
- NEXT;
- cur = CUR;
- if (cur == 'u') {
- NEXT;
- type = XML_REGEXP_LETTER_UPPERCASE;
- } else if (cur == 'l') {
- NEXT;
- type = XML_REGEXP_LETTER_LOWERCASE;
- } else if (cur == 't') {
- NEXT;
- type = XML_REGEXP_LETTER_TITLECASE;
- } else if (cur == 'm') {
- NEXT;
- type = XML_REGEXP_LETTER_MODIFIER;
- } else if (cur == 'o') {
- NEXT;
- type = XML_REGEXP_LETTER_OTHERS;
- } else {
- type = XML_REGEXP_LETTER;
- }
- } else if (cur == 'M') {
- NEXT;
- cur = CUR;
- if (cur == 'n') {
- NEXT;
- /* nonspacing */
- type = XML_REGEXP_MARK_NONSPACING;
- } else if (cur == 'c') {
- NEXT;
- /* spacing combining */
- type = XML_REGEXP_MARK_SPACECOMBINING;
- } else if (cur == 'e') {
- NEXT;
- /* enclosing */
- type = XML_REGEXP_MARK_ENCLOSING;
- } else {
- /* all marks */
- type = XML_REGEXP_MARK;
- }
- } else if (cur == 'N') {
- NEXT;
- cur = CUR;
- if (cur == 'd') {
- NEXT;
- /* digital */
- type = XML_REGEXP_NUMBER_DECIMAL;
- } else if (cur == 'l') {
- NEXT;
- /* letter */
- type = XML_REGEXP_NUMBER_LETTER;
- } else if (cur == 'o') {
- NEXT;
- /* other */
- type = XML_REGEXP_NUMBER_OTHERS;
- } else {
- /* all numbers */
- type = XML_REGEXP_NUMBER;
- }
- } else if (cur == 'P') {
- NEXT;
- cur = CUR;
- if (cur == 'c') {
- NEXT;
- /* connector */
- type = XML_REGEXP_PUNCT_CONNECTOR;
- } else if (cur == 'd') {
- NEXT;
- /* dash */
- type = XML_REGEXP_PUNCT_DASH;
- } else if (cur == 's') {
- NEXT;
- /* open */
- type = XML_REGEXP_PUNCT_OPEN;
- } else if (cur == 'e') {
- NEXT;
- /* close */
- type = XML_REGEXP_PUNCT_CLOSE;
- } else if (cur == 'i') {
- NEXT;
- /* initial quote */
- type = XML_REGEXP_PUNCT_INITQUOTE;
- } else if (cur == 'f') {
- NEXT;
- /* final quote */
- type = XML_REGEXP_PUNCT_FINQUOTE;
- } else if (cur == 'o') {
- NEXT;
- /* other */
- type = XML_REGEXP_PUNCT_OTHERS;
- } else {
- /* all punctuation */
- type = XML_REGEXP_PUNCT;
- }
- } else if (cur == 'Z') {
- NEXT;
- cur = CUR;
- if (cur == 's') {
- NEXT;
- /* space */
- type = XML_REGEXP_SEPAR_SPACE;
- } else if (cur == 'l') {
- NEXT;
- /* line */
- type = XML_REGEXP_SEPAR_LINE;
- } else if (cur == 'p') {
- NEXT;
- /* paragraph */
- type = XML_REGEXP_SEPAR_PARA;
- } else {
- /* all separators */
- type = XML_REGEXP_SEPAR;
- }
- } else if (cur == 'S') {
- NEXT;
- cur = CUR;
- if (cur == 'm') {
- NEXT;
- type = XML_REGEXP_SYMBOL_MATH;
- /* math */
- } else if (cur == 'c') {
- NEXT;
- type = XML_REGEXP_SYMBOL_CURRENCY;
- /* currency */
- } else if (cur == 'k') {
- NEXT;
- type = XML_REGEXP_SYMBOL_MODIFIER;
- /* modifiers */
- } else if (cur == 'o') {
- NEXT;
- type = XML_REGEXP_SYMBOL_OTHERS;
- /* other */
- } else {
- /* all symbols */
- type = XML_REGEXP_SYMBOL;
- }
- } else if (cur == 'C') {
- NEXT;
- cur = CUR;
- if (cur == 'c') {
- NEXT;
- /* control */
- type = XML_REGEXP_OTHER_CONTROL;
- } else if (cur == 'f') {
- NEXT;
- /* format */
- type = XML_REGEXP_OTHER_FORMAT;
- } else if (cur == 'o') {
- NEXT;
- /* private use */
- type = XML_REGEXP_OTHER_PRIVATE;
- } else if (cur == 'n') {
- NEXT;
- /* not assigned */
- type = XML_REGEXP_OTHER_NA;
- } else {
- /* all others */
- type = XML_REGEXP_OTHER;
- }
- } else if (cur == 'I') {
- const xmlChar *start;
- NEXT;
- cur = CUR;
- if (cur != 's') {
- ERROR("IsXXXX expected");
- return;
- }
- NEXT;
- start = ctxt->cur;
- cur = CUR;
- if (((cur >= 'a') && (cur <= 'z')) ||
- ((cur >= 'A') && (cur <= 'Z')) ||
- ((cur >= '0') && (cur <= '9')) ||
- (cur == 0x2D)) {
- NEXT;
- cur = CUR;
- while (((cur >= 'a') && (cur <= 'z')) ||
- ((cur >= 'A') && (cur <= 'Z')) ||
- ((cur >= '0') && (cur <= '9')) ||
- (cur == 0x2D)) {
- NEXT;
- cur = CUR;
- }
- }
- type = XML_REGEXP_BLOCK_NAME;
- blockName = xmlStrndup(start, ctxt->cur - start);
- } else {
- ERROR("Unknown char property");
- return;
- }
- if (ctxt->atom == NULL) {
- ctxt->atom = xmlRegNewAtom(ctxt, type);
- if (ctxt->atom != NULL)
- ctxt->atom->valuep = blockName;
- } else if (ctxt->atom->type == XML_REGEXP_RANGES) {
- xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
- type, 0, 0, blockName);
- }
-}
-
-/**
- * xmlFAParseCharClassEsc:
- * @ctxt: a regexp parser context
- *
- * [23] charClassEsc ::= ( SingleCharEsc | MultiCharEsc | catEsc | complEsc )
- * [24] SingleCharEsc ::= '\' [nrt\|.?*+(){}#x2D#x5B#x5D#x5E]
- * [25] catEsc ::= '\p{' charProp '}'
- * [26] complEsc ::= '\P{' charProp '}'
- * [37] MultiCharEsc ::= '.' | ('\' [sSiIcCdDwW])
- */
-static void
-xmlFAParseCharClassEsc(xmlRegParserCtxtPtr ctxt) {
- int cur;
-
- if (CUR == '.') {
- if (ctxt->atom == NULL) {
- ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_ANYCHAR);
- } else if (ctxt->atom->type == XML_REGEXP_RANGES) {
- xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
- XML_REGEXP_ANYCHAR, 0, 0, NULL);
- }
- NEXT;
- return;
- }
- if (CUR != '\\') {
- ERROR("Escaped sequence: expecting \\");
- return;
- }
- NEXT;
- cur = CUR;
- if (cur == 'p') {
- NEXT;
- if (CUR != '{') {
- ERROR("Expecting '{'");
- return;
- }
- NEXT;
- xmlFAParseCharProp(ctxt);
- if (CUR != '}') {
- ERROR("Expecting '}'");
- return;
- }
- NEXT;
- } else if (cur == 'P') {
- NEXT;
- if (CUR != '{') {
- ERROR("Expecting '{'");
- return;
- }
- NEXT;
- xmlFAParseCharProp(ctxt);
- ctxt->atom->neg = 1;
- if (CUR != '}') {
- ERROR("Expecting '}'");
- return;
- }
- NEXT;
- } else if ((cur == 'n') || (cur == 'r') || (cur == 't') || (cur == '\\') ||
- (cur == '|') || (cur == '.') || (cur == '?') || (cur == '*') ||
- (cur == '+') || (cur == '(') || (cur == ')') || (cur == '{') ||
- (cur == '}') || (cur == 0x2D) || (cur == 0x5B) || (cur == 0x5D) ||
- (cur == 0x5E)) {
- if (ctxt->atom == NULL) {
- ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_CHARVAL);
- if (ctxt->atom != NULL)
- ctxt->atom->codepoint = cur;
- } else if (ctxt->atom->type == XML_REGEXP_RANGES) {
- xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
- XML_REGEXP_CHARVAL, cur, cur, NULL);
- }
- NEXT;
- } else if ((cur == 's') || (cur == 'S') || (cur == 'i') || (cur == 'I') ||
- (cur == 'c') || (cur == 'C') || (cur == 'd') || (cur == 'D') ||
- (cur == 'w') || (cur == 'W')) {
- xmlRegAtomType type = XML_REGEXP_ANYSPACE;
-
- switch (cur) {
- case 's':
- type = XML_REGEXP_ANYSPACE;
- break;
- case 'S':
- type = XML_REGEXP_NOTSPACE;
- break;
- case 'i':
- type = XML_REGEXP_INITNAME;
- break;
- case 'I':
- type = XML_REGEXP_NOTINITNAME;
- break;
- case 'c':
- type = XML_REGEXP_NAMECHAR;
- break;
- case 'C':
- type = XML_REGEXP_NOTNAMECHAR;
- break;
- case 'd':
- type = XML_REGEXP_DECIMAL;
- break;
- case 'D':
- type = XML_REGEXP_NOTDECIMAL;
- break;
- case 'w':
- type = XML_REGEXP_REALCHAR;
- break;
- case 'W':
- type = XML_REGEXP_NOTREALCHAR;
- break;
- }
- NEXT;
- if (ctxt->atom == NULL) {
- ctxt->atom = xmlRegNewAtom(ctxt, type);
- } else if (ctxt->atom->type == XML_REGEXP_RANGES) {
- xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
- type, 0, 0, NULL);
- }
- }
-}
-
-/**
- * xmlFAParseCharRef:
- * @ctxt: a regexp parser context
- *
- * [19] XmlCharRef ::= ( '&#' [0-9]+ ';' ) | (' &#x' [0-9a-fA-F]+ ';' )
- */
-static int
-xmlFAParseCharRef(xmlRegParserCtxtPtr ctxt) {
- int ret = 0, cur;
-
- if ((CUR != '&') || (NXT(1) != '#'))
- return(-1);
- NEXT;
- NEXT;
- cur = CUR;
- if (cur == 'x') {
- NEXT;
- cur = CUR;
- if (((cur >= '0') && (cur <= '9')) ||
- ((cur >= 'a') && (cur <= 'f')) ||
- ((cur >= 'A') && (cur <= 'F'))) {
- while (((cur >= '0') && (cur <= '9')) ||
- ((cur >= 'A') && (cur <= 'F'))) {
- if ((cur >= '0') && (cur <= '9'))
- ret = ret * 16 + cur - '0';
- else if ((cur >= 'a') && (cur <= 'f'))
- ret = ret * 16 + 10 + (cur - 'a');
- else
- ret = ret * 16 + 10 + (cur - 'A');
- NEXT;
- cur = CUR;
- }
- } else {
- ERROR("Char ref: expecting [0-9A-F]");
- return(-1);
- }
- } else {
- if ((cur >= '0') && (cur <= '9')) {
- while ((cur >= '0') && (cur <= '9')) {
- ret = ret * 10 + cur - '0';
- NEXT;
- cur = CUR;
- }
- } else {
- ERROR("Char ref: expecting [0-9]");
- return(-1);
- }
- }
- if (cur != ';') {
- ERROR("Char ref: expecting ';'");
- return(-1);
- } else {
- NEXT;
- }
- return(ret);
-}
-
-/**
- * xmlFAParseCharRange:
- * @ctxt: a regexp parser context
- *
- * [17] charRange ::= seRange | XmlCharRef | XmlCharIncDash
- * [18] seRange ::= charOrEsc '-' charOrEsc
- * [20] charOrEsc ::= XmlChar | SingleCharEsc
- * [21] XmlChar ::= [^\#x2D#x5B#x5D]
- * [22] XmlCharIncDash ::= [^\#x5B#x5D]
- */
-static void
-xmlFAParseCharRange(xmlRegParserCtxtPtr ctxt) {
- int cur;
- int start = -1;
- int end = -1;
-
- if ((CUR == '&') && (NXT(1) == '#')) {
- end = start = xmlFAParseCharRef(ctxt);
- xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
- XML_REGEXP_CHARVAL, start, end, NULL);
- return;
- }
- cur = CUR;
- if (cur == '\\') {
- NEXT;
- cur = CUR;
- switch (cur) {
- case 'n': start = 0xA; break;
- case 'r': start = 0xD; break;
- case 't': start = 0x9; break;
- case '\\': case '|': case '.': case '-': case '^': case '?':
- case '*': case '+': case '{': case '}': case '(': case ')':
- case '[': case ']':
- start = cur; break;
- default:
- ERROR("Invalid escape value");
- return;
- }
- end = start;
- } else if ((cur != 0x5B) && (cur != 0x5D)) {
- end = start = cur;
- } else {
- ERROR("Expecting a char range");
- return;
- }
- NEXT;
- if (start == '-') {
- return;
- }
- cur = CUR;
- if (cur != '-') {
- xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
- XML_REGEXP_CHARVAL, start, end, NULL);
- return;
- }
- NEXT;
- cur = CUR;
- if (cur == '\\') {
- NEXT;
- cur = CUR;
- switch (cur) {
- case 'n': end = 0xA; break;
- case 'r': end = 0xD; break;
- case 't': end = 0x9; break;
- case '\\': case '|': case '.': case '-': case '^': case '?':
- case '*': case '+': case '{': case '}': case '(': case ')':
- case '[': case ']':
- end = cur; break;
- default:
- ERROR("Invalid escape value");
- return;
- }
- } else if ((cur != 0x5B) && (cur != 0x5D)) {
- end = cur;
- } else {
- ERROR("Expecting the end of a char range");
- return;
- }
- NEXT;
- /* TODO check that the values are acceptable character ranges for XML */
- if (end < start) {
- ERROR("End of range is before start of range");
- } else {
- xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
- XML_REGEXP_CHARVAL, start, end, NULL);
- }
- return;
-}
-
-/**
- * xmlFAParsePosCharGroup:
- * @ctxt: a regexp parser context
- *
- * [14] posCharGroup ::= ( charRange | charClassEsc )+
- */
-static void
-xmlFAParsePosCharGroup(xmlRegParserCtxtPtr ctxt) {
- do {
- if ((CUR == '\\') || (CUR == '.')) {
- xmlFAParseCharClassEsc(ctxt);
- } else {
- xmlFAParseCharRange(ctxt);
- }
- } while ((CUR != ']') && (CUR != '^') && (CUR != '-') &&
- (ctxt->error == 0));
-}
-
-/**
- * xmlFAParseCharGroup:
- * @ctxt: a regexp parser context
- *
- * [13] charGroup ::= posCharGroup | negCharGroup | charClassSub
- * [15] negCharGroup ::= '^' posCharGroup
- * [16] charClassSub ::= ( posCharGroup | negCharGroup ) '-' charClassExpr
- * [12] charClassExpr ::= '[' charGroup ']'
- */
-static void
-xmlFAParseCharGroup(xmlRegParserCtxtPtr ctxt) {
- int n = ctxt->neg;
- while ((CUR != ']') && (ctxt->error == 0)) {
- if (CUR == '^') {
- int neg = ctxt->neg;
-
- NEXT;
- ctxt->neg = !ctxt->neg;
- xmlFAParsePosCharGroup(ctxt);
- ctxt->neg = neg;
- } else if (CUR == '-') {
- NEXT;
- ctxt->neg = !ctxt->neg;
- if (CUR != '[') {
- ERROR("charClassExpr: '[' expected");
- break;
- }
- NEXT;
- xmlFAParseCharGroup(ctxt);
- if (CUR == ']') {
- NEXT;
- } else {
- ERROR("charClassExpr: ']' expected");
- break;
- }
- break;
- } else if (CUR != ']') {
- xmlFAParsePosCharGroup(ctxt);
- }
- }
- ctxt->neg = n;
-}
-
-/**
- * xmlFAParseCharClass:
- * @ctxt: a regexp parser context
- *
- * [11] charClass ::= charClassEsc | charClassExpr
- * [12] charClassExpr ::= '[' charGroup ']'
- */
-static void
-xmlFAParseCharClass(xmlRegParserCtxtPtr ctxt) {
- if (CUR == '[') {
- NEXT;
- ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_RANGES);
- if (ctxt->atom == NULL)
- return;
- xmlFAParseCharGroup(ctxt);
- if (CUR == ']') {
- NEXT;
- } else {
- ERROR("xmlFAParseCharClass: ']' expected");
- }
- } else {
- xmlFAParseCharClassEsc(ctxt);
- }
-}
-
-/**
- * xmlFAParseQuantExact:
- * @ctxt: a regexp parser context
- *
- * [8] QuantExact ::= [0-9]+
- */
-static int
-xmlFAParseQuantExact(xmlRegParserCtxtPtr ctxt) {
- int ret = 0;
- int ok = 0;
-
- while ((CUR >= '0') && (CUR <= '9')) {
- ret = ret * 10 + (CUR - '0');
- ok = 1;
- NEXT;
- }
- if (ok != 1) {
- return(-1);
- }
- return(ret);
-}
-
-/**
- * xmlFAParseQuantifier:
- * @ctxt: a regexp parser context
- *
- * [4] quantifier ::= [?*+] | ( '{' quantity '}' )
- * [5] quantity ::= quantRange | quantMin | QuantExact
- * [6] quantRange ::= QuantExact ',' QuantExact
- * [7] quantMin ::= QuantExact ','
- * [8] QuantExact ::= [0-9]+
- */
-static int
-xmlFAParseQuantifier(xmlRegParserCtxtPtr ctxt) {
- int cur;
-
- cur = CUR;
- if ((cur == '?') || (cur == '*') || (cur == '+')) {
- if (ctxt->atom != NULL) {
- if (cur == '?')
- ctxt->atom->quant = XML_REGEXP_QUANT_OPT;
- else if (cur == '*')
- ctxt->atom->quant = XML_REGEXP_QUANT_MULT;
- else if (cur == '+')
- ctxt->atom->quant = XML_REGEXP_QUANT_PLUS;
- }
- NEXT;
- return(1);
- }
- if (cur == '{') {
- int min = 0, max = 0;
-
- NEXT;
- cur = xmlFAParseQuantExact(ctxt);
- if (cur >= 0)
- min = cur;
- if (CUR == ',') {
- NEXT;
- cur = xmlFAParseQuantExact(ctxt);
- if (cur >= 0)
- max = cur;
- }
- if (CUR == '}') {
- NEXT;
- } else {
- ERROR("Unterminated quantifier");
- }
- if (max == 0)
- max = min;
- if (ctxt->atom != NULL) {
- ctxt->atom->quant = XML_REGEXP_QUANT_RANGE;
- ctxt->atom->min = min;
- ctxt->atom->max = max;
- }
- return(1);
- }
- return(0);
-}
-
-/**
- * xmlFAParseAtom:
- * @ctxt: a regexp parser context
- *
- * [9] atom ::= Char | charClass | ( '(' regExp ')' )
- */
-static int
-xmlFAParseAtom(xmlRegParserCtxtPtr ctxt) {
- int codepoint, len;
-
- codepoint = xmlFAIsChar(ctxt);
- if (codepoint > 0) {
- ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_CHARVAL);
- if (ctxt->atom == NULL)
- return(-1);
- codepoint = CUR_SCHAR(ctxt->cur, len);
- ctxt->atom->codepoint = codepoint;
- NEXTL(len);
- return(1);
- } else if (CUR == '|') {
- return(0);
- } else if (CUR == 0) {
- return(0);
- } else if (CUR == ')') {
- return(0);
- } else if (CUR == '(') {
- xmlRegStatePtr start, oldend;
-
- NEXT;
- xmlFAGenerateEpsilonTransition(ctxt, ctxt->state, NULL);
- start = ctxt->state;
- oldend = ctxt->end;
- ctxt->end = NULL;
- ctxt->atom = NULL;
- xmlFAParseRegExp(ctxt, 0);
- if (CUR == ')') {
- NEXT;
- } else {
- ERROR("xmlFAParseAtom: expecting ')'");
- }
- ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_SUBREG);
- if (ctxt->atom == NULL)
- return(-1);
- ctxt->atom->start = start;
- ctxt->atom->stop = ctxt->state;
- ctxt->end = oldend;
- return(1);
- } else if ((CUR == '[') || (CUR == '\\') || (CUR == '.')) {
- xmlFAParseCharClass(ctxt);
- return(1);
- }
- return(0);
-}
-
-/**
- * xmlFAParsePiece:
- * @ctxt: a regexp parser context
- *
- * [3] piece ::= atom quantifier?
- */
-static int
-xmlFAParsePiece(xmlRegParserCtxtPtr ctxt) {
- int ret;
-
- ctxt->atom = NULL;
- ret = xmlFAParseAtom(ctxt);
- if (ret == 0)
- return(0);
- if (ctxt->atom == NULL) {
- ERROR("internal: no atom generated");
- }
- xmlFAParseQuantifier(ctxt);
- return(1);
-}
-
-/**
- * xmlFAParseBranch:
- * @ctxt: a regexp parser context
- * @first: is taht the first
- *
- * [2] branch ::= piece*
- */
-static void
-xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, int first) {
- xmlRegStatePtr previous;
- xmlRegAtomPtr prevatom = NULL;
- int ret;
-
- previous = ctxt->state;
- ret = xmlFAParsePiece(ctxt);
- if (ret != 0) {
- if (first) {
- xmlFAGenerateTransitions(ctxt, previous, NULL, ctxt->atom);
- previous = ctxt->state;
- } else {
- prevatom = ctxt->atom;
- }
- ctxt->atom = NULL;
- }
- while ((ret != 0) && (ctxt->error == 0)) {
- ret = xmlFAParsePiece(ctxt);
- if (ret != 0) {
- if (first) {
- xmlFAGenerateTransitions(ctxt, previous, NULL, ctxt->atom);
- } else {
- xmlFAGenerateTransitions(ctxt, previous, NULL, prevatom);
- prevatom = ctxt->atom;
- }
- previous = ctxt->state;
- ctxt->atom = NULL;
- }
- }
- if (!first) {
- xmlFAGenerateTransitions(ctxt, previous, ctxt->end, prevatom);
- }
-}
-
-/**
- * xmlFAParseRegExp:
- * @ctxt: a regexp parser context
- * @top: is that the top-level expressions ?
- *
- * [1] regExp ::= branch ( '|' branch )*
- */
-static void
-xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top) {
- xmlRegStatePtr start, end, oldend;
-
- oldend = ctxt->end;
-
- start = ctxt->state;
- xmlFAParseBranch(ctxt, (ctxt->end == NULL));
- if (CUR != '|') {
- ctxt->end = ctxt->state;
- return;
- }
- end = ctxt->state;
- while ((CUR == '|') && (ctxt->error == 0)) {
- NEXT;
- ctxt->state = start;
- ctxt->end = end;
- xmlFAParseBranch(ctxt, 0);
- }
- if (!top)
- ctxt->end = oldend;
-}
-
-/************************************************************************
- * *
- * The basic API *
- * *
- ************************************************************************/
-
-/**
- * xmlRegexpPrint:
- * @output: the file for the output debug
- * @regexp: the compiled regexp
- *
- * Print the content of the compiled regular expression
- */
-void
-xmlRegexpPrint(FILE *output, xmlRegexpPtr regexp) {
- int i;
-
- fprintf(output, " regexp: ");
- if (regexp == NULL) {
- fprintf(output, "NULL\n");
- return;
- }
- fprintf(output, "'%s' ", regexp->string);
- fprintf(output, "\n");
- fprintf(output, "%d atoms:\n", regexp->nbAtoms);
- for (i = 0;i < regexp->nbAtoms; i++) {
- fprintf(output, " %02d ", i);
- xmlRegPrintAtom(output, regexp->atoms[i]);
- }
- fprintf(output, "%d states:", regexp->nbStates);
- fprintf(output, "\n");
- for (i = 0;i < regexp->nbStates; i++) {
- xmlRegPrintState(output, regexp->states[i]);
- }
- fprintf(output, "%d counters:\n", regexp->nbCounters);
- for (i = 0;i < regexp->nbCounters; i++) {
- fprintf(output, " %d: min %d max %d\n", i, regexp->counters[i].min,
- regexp->counters[i].max);
- }
-}
-
-/**
- * xmlRegexpCompile:
- * @regexp: a regular expression string
- *
- * Parses a regular expression conforming to XML Schemas Part 2 Datatype
- * Appendix F and build an automata suitable for testing strings against
- * that regular expression
- *
- * Returns the compiled expression or NULL in case of error
- */
-xmlRegexpPtr
-xmlRegexpCompile(const xmlChar *regexp) {
- xmlRegexpPtr ret;
- xmlRegParserCtxtPtr ctxt;
-
- ctxt = xmlRegNewParserCtxt(regexp);
- if (ctxt == NULL)
- return(NULL);
-
- /* initialize the parser */
- ctxt->end = NULL;
- ctxt->start = ctxt->state = xmlRegNewState(ctxt);
- xmlRegStatePush(ctxt, ctxt->start);
-
- /* parse the expression building an automata */
- xmlFAParseRegExp(ctxt, 1);
- if (CUR != 0) {
- ERROR("xmlFAParseRegExp: extra characters");
- }
- ctxt->end = ctxt->state;
- ctxt->start->type = XML_REGEXP_START_STATE;
- ctxt->end->type = XML_REGEXP_FINAL_STATE;
-
- /* remove the Epsilon except for counted transitions */
- xmlFAEliminateEpsilonTransitions(ctxt);
-
-
- if (ctxt->error != 0) {
- xmlRegFreeParserCtxt(ctxt);
- return(NULL);
- }
- ret = xmlRegEpxFromParse(ctxt);
- xmlRegFreeParserCtxt(ctxt);
- return(ret);
-}
-
-/**
- * xmlRegexpExec:
- * @comp: the compiled regular expression
- * @content: the value to check against the regular expression
- *
- * Check if the regular expression generate the value
- *
- * Returns 1 if it matches, 0 if not and a negativa value in case of error
- */
-int
-xmlRegexpExec(xmlRegexpPtr comp, const xmlChar *content) {
- if ((comp == NULL) || (content == NULL))
- return(-1);
- return(xmlFARegExec(comp, content));
-}
-
-/**
- * xmlRegexpIsDeterminist:
- * @comp: the compiled regular expression
- *
- * Check if the regular expression is determinist
- *
- * Returns 1 if it yes, 0 if not and a negativa value in case of error
- */
-int
-xmlRegexpIsDeterminist(xmlRegexpPtr comp) {
- xmlAutomataPtr am;
- int ret;
-
- if (comp == NULL)
- return(-1);
- if (comp->determinist != -1)
- return(comp->determinist);
-
- am = xmlNewAutomata();
- if (am->states != NULL) {
- int i;
-
- for (i = 0;i < am->nbStates;i++)
- xmlRegFreeState(am->states[i]);
- xmlFree(am->states);
- }
- am->nbAtoms = comp->nbAtoms;
- am->atoms = comp->atoms;
- am->nbStates = comp->nbStates;
- am->states = comp->states;
- am->determinist = -1;
- ret = xmlFAComputesDeterminism(am);
- am->atoms = NULL;
- am->states = NULL;
- xmlFreeAutomata(am);
- return(ret);
-}
-
-/**
- * xmlRegFreeRegexp:
- * @regexp: the regexp
- *
- * Free a regexp
- */
-void
-xmlRegFreeRegexp(xmlRegexpPtr regexp) {
- int i;
- if (regexp == NULL)
- return;
-
- if (regexp->string != NULL)
- xmlFree(regexp->string);
- if (regexp->states != NULL) {
- for (i = 0;i < regexp->nbStates;i++)
- xmlRegFreeState(regexp->states[i]);
- xmlFree(regexp->states);
- }
- if (regexp->atoms != NULL) {
- for (i = 0;i < regexp->nbAtoms;i++)
- xmlRegFreeAtom(regexp->atoms[i]);
- xmlFree(regexp->atoms);
- }
- if (regexp->counters != NULL)
- xmlFree(regexp->counters);
- if (regexp->compact != NULL)
- xmlFree(regexp->compact);
- if (regexp->transdata != NULL)
- xmlFree(regexp->transdata);
- if (regexp->stringMap != NULL) {
- for (i = 0; i < regexp->nbstrings;i++)
- xmlFree(regexp->stringMap[i]);
- xmlFree(regexp->stringMap);
- }
-
- xmlFree(regexp);
-}
-
-#ifdef LIBXML_AUTOMATA_ENABLED
-/************************************************************************
- * *
- * The Automata interface *
- * *
- ************************************************************************/
-
-/**
- * xmlNewAutomata:
- *
- * Create a new automata
- *
- * Returns the new object or NULL in case of failure
- */
-xmlAutomataPtr
-xmlNewAutomata(void) {
- xmlAutomataPtr ctxt;
-
- ctxt = xmlRegNewParserCtxt(NULL);
- if (ctxt == NULL)
- return(NULL);
-
- /* initialize the parser */
- ctxt->end = NULL;
- ctxt->start = ctxt->state = xmlRegNewState(ctxt);
- xmlRegStatePush(ctxt, ctxt->start);
-
- return(ctxt);
-}
-
-/**
- * xmlFreeAutomata:
- * @am: an automata
- *
- * Free an automata
- */
-void
-xmlFreeAutomata(xmlAutomataPtr am) {
- if (am == NULL)
- return;
- xmlRegFreeParserCtxt(am);
-}
-
-/**
- * xmlAutomataGetInitState:
- * @am: an automata
- *
- * Initial state lookup
- *
- * Returns the initial state of the automata
- */
-xmlAutomataStatePtr
-xmlAutomataGetInitState(xmlAutomataPtr am) {
- if (am == NULL)
- return(NULL);
- return(am->start);
-}
-
-/**
- * xmlAutomataSetFinalState:
- * @am: an automata
- * @state: a state in this automata
- *
- * Makes that state a final state
- *
- * Returns 0 or -1 in case of error
- */
-int
-xmlAutomataSetFinalState(xmlAutomataPtr am, xmlAutomataStatePtr state) {
- if ((am == NULL) || (state == NULL))
- return(-1);
- state->type = XML_REGEXP_FINAL_STATE;
- return(0);
-}
-
-/**
- * xmlAutomataNewTransition:
- * @am: an automata
- * @from: the starting point of the transition
- * @to: the target point of the transition or NULL
- * @token: the input string associated to that transition
- * @data: data passed to the callback function if the transition is activated
- *
- * If @to is NULL, this create first a new target state in the automata
- * and then adds a transition from the @from state to the target state
- * activated by the value of @token
- *
- * Returns the target state or NULL in case of error
- */
-xmlAutomataStatePtr
-xmlAutomataNewTransition(xmlAutomataPtr am, xmlAutomataStatePtr from,
- xmlAutomataStatePtr to, const xmlChar *token,
- void *data) {
- xmlRegAtomPtr atom;
-
- if ((am == NULL) || (from == NULL) || (token == NULL))
- return(NULL);
- atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
- atom->data = data;
- if (atom == NULL)
- return(NULL);
- atom->valuep = xmlStrdup(token);
-
- xmlFAGenerateTransitions(am, from, to, atom);
- if (to == NULL)
- return(am->state);
- return(to);
-}
-
-/**
- * xmlAutomataNewCountTrans:
- * @am: an automata
- * @from: the starting point of the transition
- * @to: the target point of the transition or NULL
- * @token: the input string associated to that transition
- * @min: the minimum successive occurences of token
- * @max: the maximum successive occurences of token
- * @data: data associated to the transition
- *
- * If @to is NULL, this create first a new target state in the automata
- * and then adds a transition from the @from state to the target state
- * activated by a succession of input of value @token and whose number
- * is between @min and @max
- *
- * Returns the target state or NULL in case of error
- */
-xmlAutomataStatePtr
-xmlAutomataNewCountTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
- xmlAutomataStatePtr to, const xmlChar *token,
- int min, int max, void *data) {
- xmlRegAtomPtr atom;
-
- if ((am == NULL) || (from == NULL) || (token == NULL))
- return(NULL);
- if (min < 0)
- return(NULL);
- if ((max < min) || (max < 1))
- return(NULL);
- atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
- if (atom == NULL)
- return(NULL);
- atom->valuep = xmlStrdup(token);
- atom->data = data;
- if (min == 0)
- atom->min = 1;
- else
- atom->min = min;
- atom->max = max;
-
- xmlFAGenerateTransitions(am, from, to, atom);
- if (to == NULL)
- to = am->state;
- if (to == NULL)
- return(NULL);
- if (min == 0)
- xmlFAGenerateEpsilonTransition(am, from, to);
- return(to);
-}
-
-/**
- * xmlAutomataNewOnceTrans:
- * @am: an automata
- * @from: the starting point of the transition
- * @to: the target point of the transition or NULL
- * @token: the input string associated to that transition
- * @min: the minimum successive occurences of token
- * @max: the maximum successive occurences of token
- * @data: data associated to the transition
- *
- * If @to is NULL, this create first a new target state in the automata
- * and then adds a transition from the @from state to the target state
- * activated by a succession of input of value @token and whose number
- * is between @min and @max, moreover that transistion can only be crossed
- * once.
- *
- * Returns the target state or NULL in case of error
- */
-xmlAutomataStatePtr
-xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
- xmlAutomataStatePtr to, const xmlChar *token,
- int min, int max, void *data) {
- xmlRegAtomPtr atom;
- int counter;
-
- if ((am == NULL) || (from == NULL) || (token == NULL))
- return(NULL);
- if (min < 1)
- return(NULL);
- if ((max < min) || (max < 1))
- return(NULL);
- atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
- if (atom == NULL)
- return(NULL);
- atom->valuep = xmlStrdup(token);
- atom->data = data;
- atom->quant = XML_REGEXP_QUANT_ONCEONLY;
- if (min == 0)
- atom->min = 1;
- else
- atom->min = min;
- atom->max = max;
- /*
- * associate a counter to the transition.
- */
- counter = xmlRegGetCounter(am);
- am->counters[counter].min = 1;
- am->counters[counter].max = 1;
-
- /* xmlFAGenerateTransitions(am, from, to, atom); */
- if (to == NULL) {
- to = xmlRegNewState(am);
- xmlRegStatePush(am, to);
- }
- xmlRegStateAddTrans(am, from, atom, to, counter, -1);
- xmlRegAtomPush(am, atom);
- am->state = to;
- if (to == NULL)
- to = am->state;
- if (to == NULL)
- return(NULL);
- return(to);
-}
-
-/**
- * xmlAutomataNewState:
- * @am: an automata
- *
- * Create a new disconnected state in the automata
- *
- * Returns the new state or NULL in case of error
- */
-xmlAutomataStatePtr
-xmlAutomataNewState(xmlAutomataPtr am) {
- xmlAutomataStatePtr to;
-
- if (am == NULL)
- return(NULL);
- to = xmlRegNewState(am);
- xmlRegStatePush(am, to);
- return(to);
-}
-
-/**
- * xmlAutomataNewEpsilon:
- * @am: an automata
- * @from: the starting point of the transition
- * @to: the target point of the transition or NULL
- *
- * If @to is NULL, this create first a new target state in the automata
- * and then adds a an epsilon transition from the @from state to the
- * target state
- *
- * Returns the target state or NULL in case of error
- */
-xmlAutomataStatePtr
-xmlAutomataNewEpsilon(xmlAutomataPtr am, xmlAutomataStatePtr from,
- xmlAutomataStatePtr to) {
- if ((am == NULL) || (from == NULL))
- return(NULL);
- xmlFAGenerateEpsilonTransition(am, from, to);
- if (to == NULL)
- return(am->state);
- return(to);
-}
-
-/**
- * xmlAutomataNewAllTrans:
- * @am: an automata
- * @from: the starting point of the transition
- * @to: the target point of the transition or NULL
- * @lax: allow to transition if not all all transitions have been activated
- *
- * If @to is NULL, this create first a new target state in the automata
- * and then adds a an ALL transition from the @from state to the
- * target state. That transition is an epsilon transition allowed only when
- * all transitions from the @from node have been activated.
- *
- * Returns the target state or NULL in case of error
- */
-xmlAutomataStatePtr
-xmlAutomataNewAllTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
- xmlAutomataStatePtr to, int lax) {
- if ((am == NULL) || (from == NULL))
- return(NULL);
- xmlFAGenerateAllTransition(am, from, to, lax);
- if (to == NULL)
- return(am->state);
- return(to);
-}
-
-/**
- * xmlAutomataNewCounter:
- * @am: an automata
- * @min: the minimal value on the counter
- * @max: the maximal value on the counter
- *
- * Create a new counter
- *
- * Returns the counter number or -1 in case of error
- */
-int
-xmlAutomataNewCounter(xmlAutomataPtr am, int min, int max) {
- int ret;
-
- if (am == NULL)
- return(-1);
-
- ret = xmlRegGetCounter(am);
- if (ret < 0)
- return(-1);
- am->counters[ret].min = min;
- am->counters[ret].max = max;
- return(ret);
-}
-
-/**
- * xmlAutomataNewCountedTrans:
- * @am: an automata
- * @from: the starting point of the transition
- * @to: the target point of the transition or NULL
- * @counter: the counter associated to that transition
- *
- * If @to is NULL, this create first a new target state in the automata
- * and then adds an epsilon transition from the @from state to the target state
- * which will increment the counter provided
- *
- * Returns the target state or NULL in case of error
- */
-xmlAutomataStatePtr
-xmlAutomataNewCountedTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
- xmlAutomataStatePtr to, int counter) {
- if ((am == NULL) || (from == NULL) || (counter < 0))
- return(NULL);
- xmlFAGenerateCountedEpsilonTransition(am, from, to, counter);
- if (to == NULL)
- return(am->state);
- return(to);
-}
-
-/**
- * xmlAutomataNewCounterTrans:
- * @am: an automata
- * @from: the starting point of the transition
- * @to: the target point of the transition or NULL
- * @counter: the counter associated to that transition
- *
- * If @to is NULL, this create first a new target state in the automata
- * and then adds an epsilon transition from the @from state to the target state
- * which will be allowed only if the counter is within the right range.
- *
- * Returns the target state or NULL in case of error
- */
-xmlAutomataStatePtr
-xmlAutomataNewCounterTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
- xmlAutomataStatePtr to, int counter) {
- if ((am == NULL) || (from == NULL) || (counter < 0))
- return(NULL);
- xmlFAGenerateCountedTransition(am, from, to, counter);
- if (to == NULL)
- return(am->state);
- return(to);
-}
-
-/**
- * xmlAutomataCompile:
- * @am: an automata
- *
- * Compile the automata into a Reg Exp ready for being executed.
- * The automata should be free after this point.
- *
- * Returns the compiled regexp or NULL in case of error
- */
-xmlRegexpPtr
-xmlAutomataCompile(xmlAutomataPtr am) {
- xmlRegexpPtr ret;
-
- xmlFAEliminateEpsilonTransitions(am);
- /* xmlFAComputesDeterminism(am); */
- ret = xmlRegEpxFromParse(am);
-
- return(ret);
-}
-
-/**
- * xmlAutomataIsDeterminist:
- * @am: an automata
- *
- * Checks if an automata is determinist.
- *
- * Returns 1 if true, 0 if not, and -1 in case of error
- */
-int
-xmlAutomataIsDeterminist(xmlAutomataPtr am) {
- int ret;
-
- if (am == NULL)
- return(-1);
-
- ret = xmlFAComputesDeterminism(am);
- return(ret);
-}
-#endif /* LIBXML_AUTOMATA_ENABLED */
-#endif /* LIBXML_REGEXP_ENABLED */
diff --git a/bundle/libxml/xmlschemas.c b/bundle/libxml/xmlschemas.c
deleted file mode 100644
index 9bafb2dcf9..0000000000
--- a/bundle/libxml/xmlschemas.c
+++ /dev/null
@@ -1,5468 +0,0 @@
-/*
- * schemas.c : implementation of the XML Schema handling and
- * schema validity checking
- *
- * See Copyright for the status of this software.
- *
- * Daniel Veillard <veillard@redhat.com>
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#ifdef LIBXML_SCHEMAS_ENABLED
-
-#include <string.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include <libxml/parserInternals.h>
-#include <libxml/hash.h>
-#include <libxml/uri.h>
-
-#include <libxml/xmlschemas.h>
-#include <libxml/schemasInternals.h>
-#include <libxml/xmlschemastypes.h>
-#include <libxml/xmlautomata.h>
-#include <libxml/xmlregexp.h>
-
-#define DEBUG 1 /* very verbose output */
-#define DEBUG_CONTENT 1
-#define DEBUG_TYPE 1
-/* #define DEBUG_CONTENT_REGEXP 1 */
-/* #define DEBUG_AUTOMATA 1 */
-
-#define UNBOUNDED (1 << 30)
-#define TODO \
- xmlGenericError(xmlGenericErrorContext, \
- "Unimplemented block at %s:%d\n", \
- __FILE__, __LINE__);
-
-#define XML_SCHEMAS_DEFAULT_NAMESPACE (const xmlChar *)"the default namespace"
-
-/*
- * The XML Schemas namespaces
- */
-static const xmlChar *xmlSchemaNs = (const xmlChar *)
- "http://www.w3.org/2001/XMLSchema";
-
-static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
- "http://www.w3.org/2001/XMLSchema-instance";
-
-#define IS_SCHEMA(node, type) \
- ((node != NULL) && (node->ns != NULL) && \
- (xmlStrEqual(node->name, (const xmlChar *) type)) && \
- (xmlStrEqual(node->ns->href, xmlSchemaNs)))
-
-#define XML_SCHEMAS_PARSE_ERROR 1
-
-struct _xmlSchemaParserCtxt {
- void *userData; /* user specific data block */
- xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
- xmlSchemaValidityWarningFunc warning;/* the callback in case of warning */
- xmlSchemaValidError err;
-
- xmlSchemaPtr schema; /* The schema in use */
- xmlChar *container; /* the current element, group, ... */
- int counter;
-
- xmlChar *URL;
- xmlDocPtr doc;
-
- const char *buffer;
- int size;
-
- /*
- * Used to build complex element content models
- */
- xmlAutomataPtr am;
- xmlAutomataStatePtr start;
- xmlAutomataStatePtr end;
- xmlAutomataStatePtr state;
-};
-
-
-#define XML_SCHEMAS_ATTR_UNKNOWN 1
-#define XML_SCHEMAS_ATTR_CHECKED 2
-
-typedef struct _xmlSchemaAttrState xmlSchemaAttrState;
-typedef xmlSchemaAttrState *xmlSchemaAttrStatePtr;
-struct _xmlSchemaAttrState {
- xmlAttrPtr attr;
- int state;
-};
-
-/**
- * xmlSchemaValidCtxt:
- *
- * A Schemas validation context
- */
-
-struct _xmlSchemaValidCtxt {
- void *userData; /* user specific data block */
- xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
- xmlSchemaValidityWarningFunc warning;/* the callback in case of warning */
-
- xmlSchemaPtr schema; /* The schema in use */
- xmlDocPtr doc;
- xmlParserInputBufferPtr input;
- xmlCharEncoding enc;
- xmlSAXHandlerPtr sax;
- void *user_data;
-
- xmlDocPtr myDoc;
- int err;
-
- xmlNodePtr node;
- xmlSchemaTypePtr type;
-
- xmlRegExecCtxtPtr regexp;
- xmlSchemaValPtr value;
-
- int attrNr;
- int attrBase;
- int attrMax;
- xmlSchemaAttrStatePtr attr;
-};
-
-
-/************************************************************************
- * *
- * Some predeclarations *
- * *
- ************************************************************************/
-static int xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
- xmlSchemaTypePtr type,
- xmlChar *value);
-
-/************************************************************************
- * *
- * Allocation functions *
- * *
- ************************************************************************/
-
-/**
- * xmlSchemaNewSchema:
- * @ctxt: a schema validation context (optional)
- *
- * Allocate a new Schema structure.
- *
- * Returns the newly allocated structure or NULL in case or error
- */
-static xmlSchemaPtr
-xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
-{
- xmlSchemaPtr ret;
-
- ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
- if (ret == NULL) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Out of memory\n");
- return (NULL);
- }
- memset(ret, 0, sizeof(xmlSchema));
-
- return (ret);
-}
-
-/**
- * xmlSchemaNewFacet:
- * @ctxt: a schema validation context (optional)
- *
- * Allocate a new Facet structure.
- *
- * Returns the newly allocated structure or NULL in case or error
- */
-static xmlSchemaFacetPtr
-xmlSchemaNewFacet(xmlSchemaParserCtxtPtr ctxt)
-{
- xmlSchemaFacetPtr ret;
-
- ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
- if (ret == NULL) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Out of memory\n");
- return (NULL);
- }
- memset(ret, 0, sizeof(xmlSchemaFacet));
-
- return (ret);
-}
-
-/**
- * xmlSchemaNewAnnot:
- * @ctxt: a schema validation context (optional)
- * @node: a node
- *
- * Allocate a new annotation structure.
- *
- * Returns the newly allocated structure or NULL in case or error
- */
-static xmlSchemaAnnotPtr
-xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
-{
- xmlSchemaAnnotPtr ret;
-
- ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
- if (ret == NULL) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Out of memory\n");
- return (NULL);
- }
- memset(ret, 0, sizeof(xmlSchemaAnnot));
- ret->content = node;
- return (ret);
-}
-
-/**
- * xmlSchemaFreeAnnot:
- * @annot: a schema type structure
- *
- * Deallocate a annotation structure
- */
-static void
-xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
-{
- if (annot == NULL)
- return;
- xmlFree(annot);
-}
-
-/**
- * xmlSchemaFreeNotation:
- * @schema: a schema notation structure
- *
- * Deallocate a Schema Notation structure.
- */
-static void
-xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
-{
- if (nota == NULL)
- return;
- if (nota->name != NULL)
- xmlFree((xmlChar *) nota->name);
- xmlFree(nota);
-}
-
-/**
- * xmlSchemaFreeAttribute:
- * @schema: a schema attribute structure
- *
- * Deallocate a Schema Attribute structure.
- */
-static void
-xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
-{
- if (attr == NULL)
- return;
- if (attr->name != NULL)
- xmlFree((xmlChar *) attr->name);
- if (attr->ref != NULL)
- xmlFree((xmlChar *) attr->ref);
- if (attr->refNs != NULL)
- xmlFree((xmlChar *) attr->refNs);
- if (attr->typeName != NULL)
- xmlFree((xmlChar *) attr->typeName);
- if (attr->typeNs != NULL)
- xmlFree((xmlChar *) attr->typeNs);
- xmlFree(attr);
-}
-
-/**
- * xmlSchemaFreeAttributeGroup:
- * @schema: a schema attribute group structure
- *
- * Deallocate a Schema Attribute Group structure.
- */
-static void
-xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attr)
-{
- if (attr == NULL)
- return;
- if (attr->name != NULL)
- xmlFree((xmlChar *) attr->name);
- xmlFree(attr);
-}
-
-/**
- * xmlSchemaFreeElement:
- * @schema: a schema element structure
- *
- * Deallocate a Schema Element structure.
- */
-static void
-xmlSchemaFreeElement(xmlSchemaElementPtr elem)
-{
- if (elem == NULL)
- return;
- if (elem->name != NULL)
- xmlFree((xmlChar *) elem->name);
- if (elem->namedType != NULL)
- xmlFree((xmlChar *) elem->namedType);
- if (elem->namedTypeNs != NULL)
- xmlFree((xmlChar *) elem->namedTypeNs);
- if (elem->ref != NULL)
- xmlFree((xmlChar *) elem->ref);
- if (elem->refNs != NULL)
- xmlFree((xmlChar *) elem->refNs);
- if (elem->annot != NULL)
- xmlSchemaFreeAnnot(elem->annot);
- if (elem->contModel != NULL)
- xmlRegFreeRegexp(elem->contModel);
- xmlFree(elem);
-}
-
-/**
- * xmlSchemaFreeFacet:
- * @facet: a schema facet structure
- *
- * Deallocate a Schema Facet structure.
- */
-static void
-xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
-{
- if (facet == NULL)
- return;
- if (facet->value != NULL)
- xmlFree((xmlChar *) facet->value);
- if (facet->id != NULL)
- xmlFree((xmlChar *) facet->id);
- if (facet->val != NULL)
- xmlSchemaFreeValue(facet->val);
- if (facet->regexp != NULL)
- xmlRegFreeRegexp(facet->regexp);
- if (facet->annot != NULL)
- xmlSchemaFreeAnnot(facet->annot);
- xmlFree(facet);
-}
-
-/**
- * xmlSchemaFreeType:
- * @type: a schema type structure
- *
- * Deallocate a Schema Type structure.
- */
-void
-xmlSchemaFreeType(xmlSchemaTypePtr type)
-{
- if (type == NULL)
- return;
- if (type->name != NULL)
- xmlFree((xmlChar *) type->name);
- if (type->base != NULL)
- xmlFree((xmlChar *) type->base);
- if (type->baseNs != NULL)
- xmlFree((xmlChar *) type->baseNs);
- if (type->annot != NULL)
- xmlSchemaFreeAnnot(type->annot);
- if (type->facets != NULL) {
- xmlSchemaFacetPtr facet, next;
-
- facet = type->facets;
- while (facet != NULL) {
- next = facet->next;
- xmlSchemaFreeFacet(facet);
- facet = next;
- }
- }
- xmlFree(type);
-}
-
-/**
- * xmlSchemaFree:
- * @schema: a schema structure
- *
- * Deallocate a Schema structure.
- */
-void
-xmlSchemaFree(xmlSchemaPtr schema)
-{
- if (schema == NULL)
- return;
-
- if (schema->name != NULL)
- xmlFree((xmlChar *) schema->name);
- if (schema->notaDecl != NULL)
- xmlHashFree(schema->notaDecl,
- (xmlHashDeallocator) xmlSchemaFreeNotation);
- if (schema->attrDecl != NULL)
- xmlHashFree(schema->attrDecl,
- (xmlHashDeallocator) xmlSchemaFreeAttribute);
- if (schema->attrgrpDecl != NULL)
- xmlHashFree(schema->attrgrpDecl,
- (xmlHashDeallocator) xmlSchemaFreeAttributeGroup);
- if (schema->elemDecl != NULL)
- xmlHashFree(schema->elemDecl,
- (xmlHashDeallocator) xmlSchemaFreeElement);
- if (schema->typeDecl != NULL)
- xmlHashFree(schema->typeDecl,
- (xmlHashDeallocator) xmlSchemaFreeType);
- if (schema->annot != NULL)
- xmlSchemaFreeAnnot(schema->annot);
- if (schema->doc != NULL)
- xmlFreeDoc(schema->doc);
-
- xmlFree(schema);
-}
-
-/************************************************************************
- * *
- * Error functions *
- * *
- ************************************************************************/
-
-/**
- * xmlSchemaErrorContext:
- * @ctxt: the parsing context
- * @schema: the schema being built
- * @node: the node being processed
- * @child: the child being processed
- *
- * Dump a SchemaType structure
- */
-static void
-xmlSchemaErrorContext(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node, xmlNodePtr child)
-{
- int line = 0;
- const xmlChar *file = NULL;
- const xmlChar *name = NULL;
- const char *type = "error";
-
- if ((ctxt == NULL) || (ctxt->error == NULL))
- return;
-
- if (child != NULL)
- node = child;
-
- if (node != NULL) {
- if ((node->type == XML_DOCUMENT_NODE) ||
- (node->type == XML_HTML_DOCUMENT_NODE)) {
- xmlDocPtr doc = (xmlDocPtr) node;
-
- file = doc->URL;
- } else {
- /*
- * Try to find contextual informations to report
- */
- if (node->type == XML_ELEMENT_NODE) {
- line = (int) node->content;
- } else if ((node->prev != NULL) &&
- (node->prev->type == XML_ELEMENT_NODE)) {
- line = (int) node->prev->content;
- } else if ((node->parent != NULL) &&
- (node->parent->type == XML_ELEMENT_NODE)) {
- line = (int) node->parent->content;
- }
- if ((node->doc != NULL) && (node->doc->URL != NULL))
- file = node->doc->URL;
- if (node->name != NULL)
- name = node->name;
- }
- }
-
- if (ctxt != NULL)
- type = "compilation error";
- else if (schema != NULL)
- type = "runtime error";
-
- if ((file != NULL) && (line != 0) && (name != NULL))
- ctxt->error(ctxt->userData, "%s: file %s line %d element %s\n",
- type, file, line, name);
- else if ((file != NULL) && (name != NULL))
- ctxt->error(ctxt->userData, "%s: file %s element %s\n",
- type, file, name);
- else if ((file != NULL) && (line != 0))
- ctxt->error(ctxt->userData, "%s: file %s line %d\n", type, file, line);
- else if (file != NULL)
- ctxt->error(ctxt->userData, "%s: file %s\n", type, file);
- else if (name != NULL)
- ctxt->error(ctxt->userData, "%s: element %s\n", type, name);
- else
- ctxt->error(ctxt->userData, "%s\n", type);
-}
-
-/************************************************************************
- * *
- * Debug functions *
- * *
- ************************************************************************/
-
-/**
- * xmlSchemaElementDump:
- * @elem: an element
- * @output: the file output
- *
- * Dump the element
- */
-static void
-xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output,
- const xmlChar *name ATTRIBUTE_UNUSED,
- const xmlChar *context ATTRIBUTE_UNUSED,
- const xmlChar *namespace ATTRIBUTE_UNUSED)
-{
- if (elem == NULL)
- return;
-
- fprintf(output, "Element ");
- if (elem->flags & XML_SCHEMAS_ELEM_TOPLEVEL)
- fprintf(output, "toplevel ");
- fprintf(output, ": %s ", elem->name);
- if (namespace != NULL)
- fprintf(output, "namespace '%s' ", namespace);
-
- if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
- fprintf(output, "nillable ");
- if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
- fprintf(output, "global ");
- if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
- fprintf(output, "default ");
- if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
- fprintf(output, "fixed ");
- if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
- fprintf(output, "abstract ");
- if (elem->flags & XML_SCHEMAS_ELEM_REF)
- fprintf(output, "ref '%s' ", elem->ref);
- if (elem->id != NULL)
- fprintf(output, "id '%s' ", elem->id);
- fprintf(output, "\n");
- if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
- fprintf(output, " ");
- if (elem->minOccurs != 1)
- fprintf(output, "min: %d ", elem->minOccurs);
- if (elem->maxOccurs >= UNBOUNDED)
- fprintf(output, "max: unbounded\n");
- else if (elem->maxOccurs != 1)
- fprintf(output, "max: %d\n", elem->maxOccurs);
- else
- fprintf(output, "\n");
- }
- if (elem->namedType != NULL) {
- fprintf(output, " type: %s", elem->namedType);
- if (elem->namedTypeNs != NULL)
- fprintf(output, " ns %s\n", elem->namedTypeNs);
- else
- fprintf(output, "\n");
- }
- if (elem->substGroup != NULL) {
- fprintf(output, " substitutionGroup: %s", elem->substGroup);
- if (elem->substGroupNs != NULL)
- fprintf(output, " ns %s\n", elem->substGroupNs);
- else
- fprintf(output, "\n");
- }
- if (elem->value != NULL)
- fprintf(output, " default: %s", elem->value);
-}
-
-/**
- * xmlSchemaAnnotDump:
- * @output: the file output
- * @annot: a annotation
- *
- * Dump the annotation
- */
-static void
-xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
-{
- xmlChar *content;
-
- if (annot == NULL)
- return;
-
- content = xmlNodeGetContent(annot->content);
- if (content != NULL) {
- fprintf(output, " Annot: %s\n", content);
- xmlFree(content);
- } else
- fprintf(output, " Annot: empty\n");
-}
-
-/**
- * xmlSchemaTypeDump:
- * @output: the file output
- * @type: a type structure
- *
- * Dump a SchemaType structure
- */
-static void
-xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
-{
- if (type == NULL) {
- fprintf(output, "Type: NULL\n");
- return;
- }
- fprintf(output, "Type: ");
- if (type->name != NULL)
- fprintf(output, "%s, ", type->name);
- else
- fprintf(output, "no name");
- switch (type->type) {
- case XML_SCHEMA_TYPE_BASIC:
- fprintf(output, "basic ");
- break;
- case XML_SCHEMA_TYPE_SIMPLE:
- fprintf(output, "simple ");
- break;
- case XML_SCHEMA_TYPE_COMPLEX:
- fprintf(output, "complex ");
- break;
- case XML_SCHEMA_TYPE_SEQUENCE:
- fprintf(output, "sequence ");
- break;
- case XML_SCHEMA_TYPE_CHOICE:
- fprintf(output, "choice ");
- break;
- case XML_SCHEMA_TYPE_ALL:
- fprintf(output, "all ");
- break;
- case XML_SCHEMA_TYPE_UR:
- fprintf(output, "ur ");
- break;
- case XML_SCHEMA_TYPE_RESTRICTION:
- fprintf(output, "restriction ");
- break;
- case XML_SCHEMA_TYPE_EXTENSION:
- fprintf(output, "extension ");
- break;
- default:
- fprintf(output, "unknowntype%d ", type->type);
- break;
- }
- if (type->base != NULL) {
- fprintf(output, "base %s, ", type->base);
- }
- switch (type->contentType) {
- case XML_SCHEMA_CONTENT_UNKNOWN:
- fprintf(output, "unknown ");
- break;
- case XML_SCHEMA_CONTENT_EMPTY:
- fprintf(output, "empty ");
- break;
- case XML_SCHEMA_CONTENT_ELEMENTS:
- fprintf(output, "element ");
- break;
- case XML_SCHEMA_CONTENT_MIXED:
- fprintf(output, "mixed ");
- break;
- case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
- fprintf(output, "mixed_or_elems ");
- break;
- case XML_SCHEMA_CONTENT_BASIC:
- fprintf(output, "basic ");
- break;
- case XML_SCHEMA_CONTENT_SIMPLE:
- fprintf(output, "simple ");
- break;
- case XML_SCHEMA_CONTENT_ANY:
- fprintf(output, "any ");
- break;
- }
- fprintf(output, "\n");
- if ((type->minOccurs != 1) || (type->maxOccurs != 1)) {
- fprintf(output, " ");
- if (type->minOccurs != 1)
- fprintf(output, "min: %d ", type->minOccurs);
- if (type->maxOccurs >= UNBOUNDED)
- fprintf(output, "max: unbounded\n");
- else if (type->maxOccurs != 1)
- fprintf(output, "max: %d\n", type->maxOccurs);
- else
- fprintf(output, "\n");
- }
- if (type->annot != NULL)
- xmlSchemaAnnotDump(output, type->annot);
- if (type->subtypes != NULL) {
- xmlSchemaTypePtr sub = type->subtypes;
-
- fprintf(output, " subtypes: ");
- while (sub != NULL) {
- fprintf(output, "%s ", sub->name);
- sub = sub->next;
- }
- fprintf(output, "\n");
- }
-
-}
-
-/**
- * xmlSchemaDump:
- * @output: the file output
- * @schema: a schema structure
- *
- * Dump a Schema structure.
- */
-void
-xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
-{
- if (schema == NULL) {
- fprintf(output, "Schemas: NULL\n");
- return;
- }
- fprintf(output, "Schemas: ");
- if (schema->name != NULL)
- fprintf(output, "%s, ", schema->name);
- else
- fprintf(output, "no name, ");
- if (schema->targetNamespace != NULL)
- fprintf(output, "%s", schema->targetNamespace);
- else
- fprintf(output, "no target namespace");
- fprintf(output, "\n");
- if (schema->annot != NULL)
- xmlSchemaAnnotDump(output, schema->annot);
-
- xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump,
- output);
- xmlHashScanFull(schema->elemDecl,
- (xmlHashScannerFull) xmlSchemaElementDump, output);
-}
-
-/************************************************************************
- * *
- * Parsing functions *
- * *
- ************************************************************************/
-
-/**
- * xmlSchemaGetType:
- * @schema: the schemas context
- * @name: the type name
- * @ns: the type namespace
- *
- * Lookup a type in the schemas or the predefined types
- *
- * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
- */
-static xmlSchemaTypePtr
-xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
- const xmlChar * namespace) {
- xmlSchemaTypePtr ret;
-
- if (name == NULL)
- return(NULL);
- if (schema != NULL) {
- ret = xmlHashLookup2(schema->typeDecl, name, namespace);
- if (ret != NULL)
- return(ret);
- }
- ret = xmlSchemaGetPredefinedType(name, namespace);
-#ifdef DEBUG
- if (ret == NULL) {
- if (namespace == NULL)
- fprintf(stderr, "Unable to lookup type %s", name);
- else
- fprintf(stderr, "Unable to lookup type %s:%s", name, namespace);
- }
-#endif
- return(ret);
-}
-
-/************************************************************************
- * *
- * Parsing functions *
- * *
- ************************************************************************/
-
-#define IS_BLANK_NODE(n) \
- (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content)))
-
-/**
- * xmlSchemaIsBlank:
- * @str: a string
- *
- * Check if a string is ignorable
- *
- * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
- */
-static int
-xmlSchemaIsBlank(xmlChar *str) {
- if (str == NULL)
- return(1);
- while (*str != 0) {
- if (!(IS_BLANK(*str))) return(0);
- str++;
- }
- return(1);
-}
-
-/**
- * xmlSchemaAddNotation:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @name: the item name
- *
- * Add an XML schema Attrribute declaration
- * *WARNING* this interface is highly subject to change
- *
- * Returns the new struture or NULL in case of error
- */
-static xmlSchemaNotationPtr
-xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- const xmlChar * name)
-{
- xmlSchemaNotationPtr ret = NULL;
- int val;
-
- if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
- return (NULL);
-
- if (schema->notaDecl == NULL)
- schema->notaDecl = xmlHashCreate(10);
- if (schema->notaDecl == NULL)
- return (NULL);
-
- ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
- if (ret == NULL) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Out of memory\n");
- return (NULL);
- }
- memset(ret, 0, sizeof(xmlSchemaNotation));
- ret->name = xmlStrdup(name);
- val = xmlHashAddEntry2(schema->notaDecl, name, schema->targetNamespace,
- ret);
- if (val != 0) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Could not add notation %s\n",
- name);
- xmlFree((char *) ret->name);
- xmlFree(ret);
- return (NULL);
- }
- return (ret);
-}
-
-
-/**
- * xmlSchemaAddAttribute:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @name: the item name
- * @container: the container's name
- *
- * Add an XML schema Attrribute declaration
- * *WARNING* this interface is highly subject to change
- *
- * Returns the new struture or NULL in case of error
- */
-static xmlSchemaAttributePtr
-xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- const xmlChar * name)
-{
- xmlSchemaAttributePtr ret = NULL;
- int val;
-
- if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
- return (NULL);
-
- if (schema->attrDecl == NULL)
- schema->attrDecl = xmlHashCreate(10);
- if (schema->attrDecl == NULL)
- return (NULL);
-
- ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
- if (ret == NULL) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Out of memory\n");
- return (NULL);
- }
- memset(ret, 0, sizeof(xmlSchemaAttribute));
- ret->name = xmlStrdup(name);
- val = xmlHashAddEntry3(schema->attrDecl, name,
- schema->targetNamespace, ctxt->container, ret);
- if (val != 0) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Could not add attribute %s\n",
- name);
- xmlFree((char *) ret->name);
- xmlFree(ret);
- return (NULL);
- }
- return (ret);
-}
-
-/**
- * xmlSchemaAddAttributeGroup:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @name: the item name
- *
- * Add an XML schema Attrribute Group declaration
- *
- * Returns the new struture or NULL in case of error
- */
-static xmlSchemaAttributeGroupPtr
-xmlSchemaAddAttributeGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- const xmlChar * name)
-{
- xmlSchemaAttributeGroupPtr ret = NULL;
- int val;
-
- if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
- return (NULL);
-
- if (schema->attrgrpDecl == NULL)
- schema->attrgrpDecl = xmlHashCreate(10);
- if (schema->attrgrpDecl == NULL)
- return (NULL);
-
- ret = (xmlSchemaAttributeGroupPtr) xmlMalloc(sizeof(xmlSchemaAttributeGroup));
- if (ret == NULL) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Out of memory\n");
- return (NULL);
- }
- memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
- ret->name = xmlStrdup(name);
- val = xmlHashAddEntry3(schema->attrgrpDecl, name,
- schema->targetNamespace, ctxt->container, ret);
- if (val != 0) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Could not add attribute group %s\n",
- name);
- xmlFree((char *) ret->name);
- xmlFree(ret);
- return (NULL);
- }
- return (ret);
-}
-
-/**
- * xmlSchemaAddElement:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @name: the type name
- * @namespace: the type namespace
- *
- * Add an XML schema Element declaration
- * *WARNING* this interface is highly subject to change
- *
- * Returns the new struture or NULL in case of error
- */
-static xmlSchemaElementPtr
-xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- const xmlChar * name, const xmlChar * namespace)
-{
- xmlSchemaElementPtr ret = NULL;
- int val;
-
- if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
- return (NULL);
-
- if (schema->elemDecl == NULL)
- schema->elemDecl = xmlHashCreate(10);
- if (schema->elemDecl == NULL)
- return (NULL);
-
- ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
- if (ret == NULL) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Out of memory\n");
- return (NULL);
- }
- memset(ret, 0, sizeof(xmlSchemaElement));
- ret->name = xmlStrdup(name);
- val = xmlHashAddEntry3(schema->elemDecl, name,
- namespace, ctxt->container, ret);
- if (val != 0) {
- char buf[100];
-
- snprintf(buf, 99, "privatieelem%d", ctxt->counter++ + 1);
- val = xmlHashAddEntry3(schema->elemDecl, name, (xmlChar *) buf,
- namespace, ret);
- if (val != 0) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Could not add element %s\n",
- name);
- xmlFree((char *) ret->name);
- xmlFree(ret);
- return (NULL);
- }
- }
- return (ret);
-}
-
-/**
- * xmlSchemaAddType:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @name: the item name
- *
- * Add an XML schema Simple Type definition
- * *WARNING* this interface is highly subject to change
- *
- * Returns the new struture or NULL in case of error
- */
-static xmlSchemaTypePtr
-xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- const xmlChar * name)
-{
- xmlSchemaTypePtr ret = NULL;
- int val;
-
- if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
- return (NULL);
-
- if (schema->typeDecl == NULL)
- schema->typeDecl = xmlHashCreate(10);
- if (schema->typeDecl == NULL)
- return (NULL);
-
- ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
- if (ret == NULL) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Out of memory\n");
- return (NULL);
- }
- memset(ret, 0, sizeof(xmlSchemaType));
- ret->name = xmlStrdup(name);
- val = xmlHashAddEntry2(schema->typeDecl, name, schema->targetNamespace,
- ret);
- if (val != 0) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Could not add type %s\n", name);
- xmlFree((char *) ret->name);
- xmlFree(ret);
- return (NULL);
- }
- ret->minOccurs = 1;
- ret->maxOccurs = 1;
-
- return (ret);
-}
-
-/************************************************************************
- * *
- * Utilities for parsing *
- * *
- ************************************************************************/
-
-/**
- * xmlGetQNameProp:
- * @ctxt: a schema validation context
- * @node: a subtree containing XML Schema informations
- * @name: the attribute name
- * @namespace: the result namespace if any
- *
- * Extract a QName Attribute value
- *
- * Returns the NCName or NULL if not found, and also update @namespace
- * with the namespace URI
- */
-static xmlChar *
-xmlGetQNameProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
- const char *name,
- xmlChar **namespace) {
- xmlChar *val, *ret, *prefix;
- xmlNsPtr ns;
-
-
- if (namespace != NULL)
- *namespace = NULL;
- val = xmlGetProp(node, (const xmlChar *) name);
- if (val == NULL)
- return(NULL);
-
- ret = xmlSplitQName2(val, &prefix);
- if (ret == NULL)
- return(val);
- xmlFree(val);
-
- ns = xmlSearchNs(node->doc, node, prefix);
- if (ns == NULL) {
- xmlSchemaErrorContext(ctxt, NULL, node, NULL);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Attribute %s: the QName prefix %s is undefined\n",
- name, prefix);
- } else {
- *namespace = xmlStrdup(ns->href);
- }
- xmlFree(prefix);
- return(ret);
-}
-
-/**
- * xmlGetMaxOccurs:
- * @ctxt: a schema validation context
- * @node: a subtree containing XML Schema informations
- *
- * Get the maxOccurs property
- *
- * Returns the default if not found, or the value
- */
-static int
-xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) {
- xmlChar *val, *cur;
- int ret = 0;
-
- val = xmlGetProp(node, (const xmlChar *) "maxOccurs");
- if (val == NULL)
- return(1);
-
- if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
- xmlFree(val);
- return(UNBOUNDED); /* encoding it with -1 might be another option */
- }
-
- cur = val;
- while (IS_BLANK(*cur)) cur++;
- while ((*cur >= '0') && (*cur <= '9')) {
- ret = ret * 10 + (*cur - '0');
- cur++;
- }
- while (IS_BLANK(*cur)) cur++;
- if (*cur != 0) {
- xmlSchemaErrorContext(ctxt, NULL, node, NULL);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "invalid value for minOccurs: %s\n",
- val);
- xmlFree(val);
- return(1);
- }
- xmlFree(val);
- return(ret);
-}
-
-/**
- * xmlGetMinOccurs:
- * @ctxt: a schema validation context
- * @node: a subtree containing XML Schema informations
- *
- * Get the minOccurs property
- *
- * Returns the default if not found, or the value
- */
-static int
-xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node) {
- xmlChar *val, *cur;
- int ret = 0;
-
- val = xmlGetProp(node, (const xmlChar *) "minOccurs");
- if (val == NULL)
- return(1);
-
- cur = val;
- while (IS_BLANK(*cur)) cur++;
- while ((*cur >= '0') && (*cur <= '9')) {
- ret = ret * 10 + (*cur - '0');
- cur++;
- }
- while (IS_BLANK(*cur)) cur++;
- if (*cur != 0) {
- xmlSchemaErrorContext(ctxt, NULL, node, NULL);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "invalid value for minOccurs: %s\n",
- val);
- xmlFree(val);
- return(1);
- }
- xmlFree(val);
- return(ret);
-}
-
-/**
- * xmlGetBooleanProp:
- * @ctxt: a schema validation context
- * @node: a subtree containing XML Schema informations
- * @name: the attribute name
- * @def: the default value
- *
- * Get is a bolean property is set
- *
- * Returns the default if not found, 0 if found to be false,
- * 1 if found to be true
- */
-static int
-xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
- const char *name, int def) {
- xmlChar *val;
-
- val = xmlGetProp(node, (const xmlChar *) name);
- if (val == NULL)
- return(def);
-
- if (xmlStrEqual(val, BAD_CAST"true"))
- def = 1;
- else if (xmlStrEqual(val, BAD_CAST"false"))
- def = 0;
- else {
- xmlSchemaErrorContext(ctxt, NULL, node, NULL);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Attribute %s: the value %s is not boolean\n",
- name, val);
- }
- xmlFree(val);
- return(def);
-}
-
-/************************************************************************
- * *
- * Shema extraction from an Infoset *
- * *
- ************************************************************************/
-static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
- ctxt, xmlSchemaPtr schema,
- xmlNodePtr node);
-static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaPtr schema,
- xmlNodePtr node);
-static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaPtr schema,
- xmlNodePtr node,
- int simple);
-static xmlSchemaTypePtr xmlSchemaParseSequence(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaPtr schema,
- xmlNodePtr node);
-static xmlSchemaTypePtr xmlSchemaParseAll(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaPtr schema,
- xmlNodePtr node);
-static xmlSchemaAttributePtr xmlSchemaParseAttribute(xmlSchemaParserCtxtPtr
- ctxt,
- xmlSchemaPtr schema,
- xmlNodePtr node);
-static xmlSchemaAttributeGroupPtr
-xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaPtr schema, xmlNodePtr node);
-static xmlSchemaTypePtr xmlSchemaParseChoice(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaPtr schema,
- xmlNodePtr node);
-static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaPtr schema,
- xmlNodePtr node);
-static xmlSchemaAttributePtr
-xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node);
-
-/**
- * xmlSchemaParseAttrDecls:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- * @type: the hosting type
- *
- * parse a XML schema attrDecls declaration corresponding to
- * <!ENTITY % attrDecls
- * '((%attribute;| %attributeGroup;)*,(%anyAttribute;)?)'>
- */
-static xmlNodePtr
-xmlSchemaParseAttrDecls(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr child, xmlSchemaTypePtr type)
-{
- xmlSchemaAttributePtr lastattr, attr;
-
- lastattr = NULL;
- while ((IS_SCHEMA(child, "attribute")) ||
- (IS_SCHEMA(child, "attributeGroup"))) {
- attr = NULL;
- if (IS_SCHEMA(child, "attribute")) {
- attr = xmlSchemaParseAttribute(ctxt, schema, child);
- } else if (IS_SCHEMA(child, "attributeGroup")) {
- attr = (xmlSchemaAttributePtr)
- xmlSchemaParseAttributeGroup(ctxt, schema, child);
- }
- if (attr != NULL) {
- if (lastattr == NULL) {
- type->attributes = attr;
- lastattr = attr
- ;
- } else {
- lastattr->next = attr;
- lastattr = attr;
- }
- }
- child = child->next;
- }
- if (IS_SCHEMA(child, "anyAttribute")) {
- attr = xmlSchemaParseAnyAttribute(ctxt, schema, child);
- if (attr != NULL) {
- if (lastattr == NULL) {
- type->attributes = attr;
- lastattr = attr
- ;
- } else {
- lastattr->next = attr;
- lastattr = attr;
- }
- }
- child = child->next;
- }
- return(child);
-}
-
-/**
- * xmlSchemaParseAnnotation:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema Attrribute declaration
- * *WARNING* this interface is highly subject to change
- *
- * Returns -1 in case of error, 0 if the declaration is inproper and
- * 1 in case of success.
- */
-static xmlSchemaAnnotPtr
-xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlSchemaAnnotPtr ret;
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
- ret = xmlSchemaNewAnnot(ctxt, node);
-
- return (ret);
-}
-
-/**
- * xmlSchemaParseFacet:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema Facet declaration
- * *WARNING* this interface is highly subject to change
- *
- * Returns the new type structure or NULL in case of error
- */
-static xmlSchemaFacetPtr
-xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlSchemaFacetPtr facet;
- xmlNodePtr child = NULL;
- xmlChar *value;
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
- facet = xmlSchemaNewFacet(ctxt);
- if (facet == NULL)
- return (NULL);
- facet->node = node;
- value = xmlGetProp(node, (const xmlChar *) "value");
- if (value == NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Facet %s has no value\n", node->name);
- xmlSchemaFreeFacet(facet);
- return (NULL);
- }
- if (IS_SCHEMA(node, "minInclusive")) {
- facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
- } else if (IS_SCHEMA(node, "minExclusive")) {
- facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
- } else if (IS_SCHEMA(node, "maxInclusive")) {
- facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
- } else if (IS_SCHEMA(node, "maxExclusive")) {
- facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
- } else if (IS_SCHEMA(node, "totalDigits")) {
- facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
- } else if (IS_SCHEMA(node, "fractionDigits")) {
- facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
- } else if (IS_SCHEMA(node, "pattern")) {
- facet->type = XML_SCHEMA_FACET_PATTERN;
- } else if (IS_SCHEMA(node, "enumeration")) {
- facet->type = XML_SCHEMA_FACET_ENUMERATION;
- } else if (IS_SCHEMA(node, "whiteSpace")) {
- facet->type = XML_SCHEMA_FACET_WHITESPACE;
- } else if (IS_SCHEMA(node, "length")) {
- facet->type = XML_SCHEMA_FACET_LENGTH;
- } else if (IS_SCHEMA(node, "maxLength")) {
- facet->type = XML_SCHEMA_FACET_MAXLENGTH;
- } else if (IS_SCHEMA(node, "minLength")) {
- facet->type = XML_SCHEMA_FACET_MINLENGTH;
- } else {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Unknown facet type %s\n", node->name);
- xmlSchemaFreeFacet(facet);
- return(NULL);
- }
- facet->id = xmlGetProp(node, (const xmlChar *) "id");
- facet->value = value;
- child = node->children;
-
- if (IS_SCHEMA(child, "annotation")) {
- facet->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Facet %s has unexpected child content\n",
- node->name);
- }
- return (facet);
-}
-
-/**
- * xmlSchemaParseAny:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema Any declaration
- * *WARNING* this interface is highly subject to change
- *
- * Returns the new type structure or NULL in case of error
- */
-static xmlSchemaTypePtr
-xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlSchemaTypePtr type;
- xmlNodePtr child = NULL;
- xmlChar name[30];
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
- snprintf((char *)name, 30, "any %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_ANY;
- child = node->children;
- type->minOccurs = xmlGetMinOccurs(ctxt, node);
- type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
-
- if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Sequence %s has unexpected content\n",
- type->name);
- }
-
- return (type);
-}
-
-/**
- * xmlSchemaParseNotation:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema Notation declaration
- *
- * Returns the new structure or NULL in case of error
- */
-static xmlSchemaNotationPtr
-xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlChar *name;
- xmlSchemaNotationPtr ret;
- xmlNodePtr child = NULL;
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
- name = xmlGetProp(node, (const xmlChar *) "name");
- if (name == NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Notation has no name\n");
- return (NULL);
- }
- ret = xmlSchemaAddNotation(ctxt, schema, name);
- if (ret == NULL) {
- xmlFree(name);
- return (NULL);
- }
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "notation %s has unexpected content\n",
- name);
- }
-
- return (ret);
-}
-
-/**
- * xmlSchemaParseAnyAttribute:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema AnyAttrribute declaration
- * *WARNING* this interface is highly subject to change
- *
- * Returns an attribute def structure or NULL
- */
-static xmlSchemaAttributePtr
-xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlChar *processContents;
- xmlSchemaAttributePtr ret;
- xmlNodePtr child = NULL;
- char name[100];
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
- snprintf(name, 99, "anyattr %d", ctxt->counter++ + 1);
- ret = xmlSchemaAddAttribute(ctxt, schema, (xmlChar *)name);
- if (ret == NULL) {
- return (NULL);
- }
- ret->id = xmlGetProp(node, (const xmlChar *) "id");
- processContents = xmlGetProp(node, (const xmlChar *) "processContents");
- if ((processContents == NULL) ||
- (xmlStrEqual(processContents, (const xmlChar *)"strict"))) {
- ret->occurs = XML_SCHEMAS_ANYATTR_STRICT;
- } else if (xmlStrEqual(processContents, (const xmlChar *)"skip")) {
- ret->occurs = XML_SCHEMAS_ANYATTR_SKIP;
- } else if (xmlStrEqual(processContents, (const xmlChar *)"lax")) {
- ret->occurs = XML_SCHEMAS_ANYATTR_LAX;
- } else {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "anyAttribute has unexpected content for processContents: %s\n",
- processContents);
- ret->occurs = XML_SCHEMAS_ANYATTR_STRICT;
- }
- if (processContents != NULL)
- xmlFree(processContents);
-
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "anyAttribute %s has unexpected content\n",
- name);
- }
-
- return (ret);
-}
-
-
-/**
- * xmlSchemaParseAttribute:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema Attrribute declaration
- * *WARNING* this interface is highly subject to change
- *
- * Returns -1 in case of error, 0 if the declaration is inproper and
- * 1 in case of success.
- */
-static xmlSchemaAttributePtr
-xmlSchemaParseAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlChar *name, *refNs = NULL, *ref = NULL;
- xmlSchemaAttributePtr ret;
- xmlNodePtr child = NULL;
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
- name = xmlGetProp(node, (const xmlChar *) "name");
- if (name == NULL) {
- char buf[100];
-
- ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
- if (ref == NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Attribute has no name nor ref\n");
- return (NULL);
- }
- snprintf(buf, 99, "anonattr%d", ctxt->counter++ + 1);
- name = xmlStrdup((xmlChar *) buf);
- }
- ret = xmlSchemaAddAttribute(ctxt, schema, name);
- if (ret == NULL) {
- xmlFree(name);
- if (ref != NULL)
- xmlFree(ref);
- return (NULL);
- }
- xmlFree(name);
- ret->ref = ref;
- ret->refNs = refNs;
- ret->typeName = xmlGetQNameProp(ctxt, node, "type", &(ret->typeNs));
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- if (IS_SCHEMA(child, "simpleType")) {
- ret->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child);
- child = child->next;
- }
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "attribute %s has unexpected content\n",
- name);
- }
-
- return (ret);
-}
-
-/**
- * xmlSchemaParseAttributeGroup:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema Attribute Group declaration
- * *WARNING* this interface is highly subject to change
- *
- * Returns the attribute group or NULL in case of error.
- */
-static xmlSchemaAttributeGroupPtr
-xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlChar *name, *refNs = NULL, *ref = NULL;
- xmlSchemaAttributeGroupPtr ret;
- xmlSchemaAttributePtr last = NULL, attr;
- xmlNodePtr child = NULL;
- xmlChar *oldcontainer;
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
- oldcontainer = ctxt->container;
- name = xmlGetProp(node, (const xmlChar *) "name");
- if (name == NULL) {
- char buf[100];
-
- ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
- if (ref == NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "AttributeGroup has no name nor ref\n");
- return (NULL);
- }
- snprintf(buf, 99, "anonattrgroup%d", ctxt->counter++ + 1);
- name = xmlStrdup((xmlChar *) buf);
- }
- ret = xmlSchemaAddAttributeGroup(ctxt, schema, name);
- if (ret == NULL) {
- xmlFree(name);
- if (ref != NULL)
- xmlFree(ref);
- return (NULL);
- }
- ret->ref = ref;
- ret->refNs = refNs;
- ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
- child = node->children;
- ctxt->container = name;
- if (IS_SCHEMA(child, "annotation")) {
- ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- while ((IS_SCHEMA(child, "attribute")) ||
- (IS_SCHEMA(child, "attributeGroup"))) {
- attr = NULL;
- if (IS_SCHEMA(child, "attribute")) {
- attr = xmlSchemaParseAttribute(ctxt, schema, child);
- } else if (IS_SCHEMA(child, "attributeGroup")) {
- attr = (xmlSchemaAttributePtr)
- xmlSchemaParseAttributeGroup(ctxt, schema, child);
- }
- if (attr != NULL) {
- if (last == NULL) {
- ret->attributes = attr;
- last = attr;
- } else {
- last->next = attr;
- last = attr;
- }
- }
- child = child->next;
- }
- if (IS_SCHEMA(child, "anyAttribute")) {
- TODO
- child = child->next;
- }
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "attribute group %s has unexpected content\n",
- name);
- }
-
- ctxt->container = oldcontainer;
- return (ret);
-}
-
-/**
- * xmlSchemaParseElement:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema Element declaration
- * *WARNING* this interface is highly subject to change
- *
- * Returns -1 in case of error, 0 if the declaration is inproper and
- * 1 in case of success.
- */
-static xmlSchemaElementPtr
-xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node, int toplevel)
-{
- xmlChar *name, *refNs = NULL, *ref = NULL, *namespace, *fixed;
- xmlSchemaElementPtr ret;
- xmlNodePtr child = NULL;
- xmlChar *oldcontainer;
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
- oldcontainer = ctxt->container;
- name = xmlGetProp(node, (const xmlChar *) "name");
- if (name == NULL) {
- char buf[100];
-
- ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
- if (ref == NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Element has no name nor ref\n");
- return (NULL);
- }
- snprintf(buf, 99, "anonelem%d", ctxt->counter++ + 1);
- name = xmlStrdup((xmlChar *) buf);
- }
- namespace = xmlGetProp(node, (const xmlChar *) "targetNamespace");
- if (namespace == NULL)
- ret =
- xmlSchemaAddElement(ctxt, schema, name,
- schema->targetNamespace);
- else
- ret = xmlSchemaAddElement(ctxt, schema, name, namespace);
- if (namespace != NULL)
- xmlFree(namespace);
- if (ret == NULL) {
- xmlFree(name);
- if (ref != NULL)
- xmlFree(ref);
- return (NULL);
- }
- ret->type = XML_SCHEMA_TYPE_ELEMENT;
- ret->ref = ref;
- ret->refNs = refNs;
- if (ref != NULL)
- ret->flags |= XML_SCHEMAS_ELEM_REF;
- if (toplevel)
- ret->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
- if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
- ret->flags |= XML_SCHEMAS_ELEM_NILLABLE;
- if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
- ret->flags |= XML_SCHEMAS_ELEM_NILLABLE;
- ctxt->container = name;
-
- ret->id = xmlGetProp(node, BAD_CAST "id");
- ret->namedType = xmlGetQNameProp(ctxt, node, "type", &(ret->namedTypeNs));
- ret->substGroup = xmlGetQNameProp(ctxt, node, "substitutionGroup",
- &(ret->substGroupNs));
- fixed = xmlGetProp(node, BAD_CAST "fixed");
- ret->minOccurs = xmlGetMinOccurs(ctxt, node);
- ret->maxOccurs = xmlGetMaxOccurs(ctxt, node);
-
- ret->value = xmlGetProp(node, BAD_CAST "default");
- if ((ret->value != NULL) && (fixed != NULL)) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- ctxt->error(ctxt->userData,
- "Element %s has both default and fixed\n",
- ret->name);
- xmlFree(fixed);
- } else if (fixed != NULL) {
- ret->flags |= XML_SCHEMAS_ELEM_FIXED;
- ret->value = fixed;
- }
-
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- ret->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- if (IS_SCHEMA(child, "complexType")) {
- ret->subtypes = xmlSchemaParseComplexType(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "simpleType")) {
- ret->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child);
- child = child->next;
- }
- while ((IS_SCHEMA(child, "unique")) ||
- (IS_SCHEMA(child, "key")) ||
- (IS_SCHEMA(child, "keyref"))) {
- TODO
- child = child->next;
- }
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "element %s has unexpected content\n",
- name);
- }
-
- ctxt->container = oldcontainer;
- xmlFree(name);
- return (ret);
-}
-
-/**
- * xmlSchemaParseUnion:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema Union definition
- * *WARNING* this interface is highly subject to change
- *
- * Returns -1 in case of error, 0 if the declaration is inproper and
- * 1 in case of success.
- */
-static xmlSchemaTypePtr
-xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlSchemaTypePtr type, subtype, last = NULL;
- xmlNodePtr child = NULL;
- xmlChar name[30];
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
-
- snprintf((char *)name, 30, "union %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_LIST;
- type->id = xmlGetProp(node, BAD_CAST "id");
- type->ref = xmlGetProp(node, BAD_CAST "memberTypes");
-
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- while (IS_SCHEMA(child, "simpleType")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseSimpleType(ctxt, schema, child);
- if (subtype != NULL) {
- if (last == NULL) {
- type->subtypes = subtype;
- last = subtype;
- } else {
- last->next = subtype;
- last = subtype;
- }
- last->next = NULL;
- }
- child = child->next;
- }
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Union %s has unexpected content\n",
- type->name);
- }
- return (type);
-}
-
-/**
- * xmlSchemaParseList:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema List definition
- * *WARNING* this interface is highly subject to change
- *
- * Returns -1 in case of error, 0 if the declaration is inproper and
- * 1 in case of success.
- */
-static xmlSchemaTypePtr
-xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlSchemaTypePtr type, subtype;
- xmlNodePtr child = NULL;
- xmlChar name[30];
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
- snprintf((char *)name, 30, "list %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_LIST;
- type->id = xmlGetProp(node, BAD_CAST "id");
- type->ref = xmlGetQNameProp(ctxt, node, "ref", &(type->refNs));
-
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- subtype = NULL;
- if (IS_SCHEMA(child, "simpleType")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseSimpleType(ctxt, schema, child);
- child = child->next;
- type->subtypes = subtype;
- }
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "List %s has unexpected content\n",
- type->name);
- }
- return (type);
-}
-/**
- * xmlSchemaParseSimpleType:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema Simple Type definition
- * *WARNING* this interface is highly subject to change
- *
- * Returns -1 in case of error, 0 if the declaration is inproper and
- * 1 in case of success.
- */
-static xmlSchemaTypePtr
-xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlSchemaTypePtr type, subtype;
- xmlNodePtr child = NULL;
- xmlChar *name;
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
-
- name = xmlGetProp(node, (const xmlChar *) "name");
- if (name == NULL) {
- char buf[100];
-
- snprintf(buf, 99, "simpletype%d", ctxt->counter++ + 1);
- name = xmlStrdup((xmlChar *) buf);
- }
- if (name == NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "simpleType has no name\n");
- return (NULL);
- }
- type = xmlSchemaAddType(ctxt, schema, name);
- xmlFree(name);
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_SIMPLE;
- type->id = xmlGetProp(node, BAD_CAST "id");
-
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- subtype = NULL;
- if (IS_SCHEMA(child, "restriction")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseRestriction(ctxt, schema, child, 1);
- child = child->next;
- } else if (IS_SCHEMA(child, "list")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseList(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "union")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseUnion(ctxt, schema, child);
- child = child->next;
- }
- type->subtypes = subtype;
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "SimpleType %s has unexpected content\n",
- type->name);
- }
-
- return (type);
-}
-
-
-/**
- * xmlSchemaParseGroup:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema Group definition
- * *WARNING* this interface is highly subject to change
- *
- * Returns -1 in case of error, 0 if the declaration is inproper and
- * 1 in case of success.
- */
-static xmlSchemaTypePtr
-xmlSchemaParseGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlSchemaTypePtr type, subtype;
- xmlNodePtr child = NULL;
- xmlChar *name, *ref = NULL, *refNs = NULL;
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
-
- name = xmlGetProp(node, (const xmlChar *) "name");
- if (name == NULL) {
- char buf[100];
-
- ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
- if (ref == NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "Group has no name nor ref\n");
- return (NULL);
- }
- snprintf(buf, 99, "anongroup%d", ctxt->counter++ + 1);
- name = xmlStrdup((xmlChar *) buf);
- }
- type = xmlSchemaAddType(ctxt, schema, name);
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_GROUP;
- type->id = xmlGetProp(node, BAD_CAST "id");
- type->ref = ref;
- type->refNs = refNs;
- type->minOccurs = xmlGetMinOccurs(ctxt, node);
- type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
-
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- subtype = NULL;
- if (IS_SCHEMA(child, "all")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseAll(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "choice")) {
- subtype = xmlSchemaParseChoice(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "sequence")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseSequence(ctxt, schema, child);
- child = child->next;
- }
- if (subtype != NULL)
- type->subtypes = subtype;
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Group %s has unexpected content\n",
- type->name);
- }
-
- return (type);
-}
-
-/**
- * xmlSchemaParseAll:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema All definition
- * *WARNING* this interface is highly subject to change
- *
- * Returns -1 in case of error, 0 if the declaration is inproper and
- * 1 in case of success.
- */
-static xmlSchemaTypePtr
-xmlSchemaParseAll(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlSchemaTypePtr type, subtype, last = NULL;
- xmlNodePtr child = NULL;
- xmlChar name[30];
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
-
- snprintf((char *)name, 30, "all%d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_ALL;
- type->id = xmlGetProp(node, BAD_CAST "id");
- type->minOccurs = xmlGetMinOccurs(ctxt, node);
- type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
-
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- while (IS_SCHEMA(child, "element")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseElement(ctxt, schema, child, 0);
- if (subtype != NULL) {
- if (last == NULL) {
- type->subtypes = subtype;
- last = subtype;
- } else {
- last->next = subtype;
- last = subtype;
- }
- last->next = NULL;
- }
- child = child->next;
- }
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "All %s has unexpected content\n",
- type->name);
- }
-
- return (type);
-}
-
-/**
- * xmlSchemaParseImport:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema Import definition
- * *WARNING* this interface is highly subject to change
- *
- * Returns -1 in case of error, 0 if the declaration is inproper and
- * 1 in case of success.
- */
-static int
-xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlNodePtr child = NULL;
- xmlChar *namespace;
- xmlChar *schemaLocation;
- xmlChar *previous;
- xmlURIPtr check;
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (-1);
-
- namespace = xmlGetProp(node, BAD_CAST "namespace");
- if (namespace != NULL) {
- check = xmlParseURI((const char *) namespace);
- if (check == NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Import namespace attribute is not an URI: %s\n",
- namespace);
- xmlFree(namespace);
- return(-1);
- } else {
- xmlFreeURI(check);
- }
- }
- schemaLocation = xmlGetProp(node, BAD_CAST "schemaLocation");
- if (schemaLocation != NULL) {
- check = xmlParseURI((const char *) schemaLocation);
- if (check == NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Import schemaLocation attribute is not an URI: %s\n",
- schemaLocation);
- if (namespace != NULL)
- xmlFree(namespace);
- xmlFree(schemaLocation);
- return(-1);
- } else {
- xmlFreeURI(check);
- }
- }
- if (schema->schemasImports == NULL) {
- schema->schemasImports = xmlHashCreate(10);
- if (schema->schemasImports == NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Internal: failed to build import table\n");
- if (namespace != NULL)
- xmlFree(namespace);
- if (schemaLocation != NULL)
- xmlFree(schemaLocation);
- return(-1);
- }
- }
- if (namespace == NULL) {
- previous = xmlHashLookup(schema->schemasImports,
- XML_SCHEMAS_DEFAULT_NAMESPACE);
- if (schemaLocation != NULL) {
- if (previous != NULL) {
- if (!xmlStrEqual(schemaLocation, previous)) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Redefining import for default namespace with a different URI: %s\n",
- schemaLocation);
- }
- } else {
- xmlHashAddEntry(schema->schemasImports,
- XML_SCHEMAS_DEFAULT_NAMESPACE, schemaLocation);
- }
- }
- } else {
- previous = xmlHashLookup(schema->schemasImports, namespace);
- if (schemaLocation != NULL) {
- if (previous != NULL) {
- if (!xmlStrEqual(schemaLocation, previous)) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Redefining import for namespace %s with a different URI: %s\n",
- namespace, schemaLocation);
- }
- } else {
- xmlHashAddEntry(schema->schemasImports,
- namespace, schemaLocation);
- }
- }
- }
-
- child = node->children;
- while (IS_SCHEMA(child, "annotation")) {
- /*
- * the annotations here are simply discarded ...
- */
- child = child->next;
- }
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Import has unexpected content\n");
- return(-1);
- }
- return(1);
-}
-
-/**
- * xmlSchemaParseChoice:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema Choice definition
- * *WARNING* this interface is highly subject to change
- *
- * Returns -1 in case of error, 0 if the declaration is inproper and
- * 1 in case of success.
- */
-static xmlSchemaTypePtr
-xmlSchemaParseChoice(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlSchemaTypePtr type, subtype, last = NULL;
- xmlNodePtr child = NULL;
- xmlChar name[30];
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
-
- snprintf((char *)name, 30, "choice %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_CHOICE;
- type->id = xmlGetProp(node, BAD_CAST "id");
- type->minOccurs = xmlGetMinOccurs(ctxt, node);
- type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
-
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- while ((IS_SCHEMA(child, "element")) ||
- (IS_SCHEMA(child, "group")) ||
- (IS_SCHEMA(child, "any")) ||
- (IS_SCHEMA(child, "choice")) ||
- (IS_SCHEMA(child, "sequence"))) {
- subtype = NULL;
- if (IS_SCHEMA(child, "element")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseElement(ctxt, schema, child, 0);
- } else if (IS_SCHEMA(child, "group")) {
- subtype = xmlSchemaParseGroup(ctxt, schema, child);
- } else if (IS_SCHEMA(child, "any")) {
- subtype = xmlSchemaParseAny(ctxt, schema, child);
- } else if (IS_SCHEMA(child, "sequence")) {
- subtype = xmlSchemaParseSequence(ctxt, schema, child);
- } else if (IS_SCHEMA(child, "choice")) {
- subtype = xmlSchemaParseChoice(ctxt, schema, child);
- }
- if (subtype != NULL) {
- if (last == NULL) {
- type->subtypes = subtype;
- last = subtype;
- } else {
- last->next = subtype;
- last = subtype;
- }
- last->next = NULL;
- }
- child = child->next;
- }
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Choice %s has unexpected content\n",
- type->name);
- }
-
- return (type);
-}
-
-/**
- * xmlSchemaParseSequence:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema Sequence definition
- * *WARNING* this interface is highly subject to change
- *
- * Returns -1 in case of error, 0 if the declaration is inproper and
- * 1 in case of success.
- */
-static xmlSchemaTypePtr
-xmlSchemaParseSequence(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlSchemaTypePtr type, subtype, last = NULL;
- xmlNodePtr child = NULL;
- xmlChar name[30];
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
-
- snprintf((char *)name, 30, "sequence %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_SEQUENCE;
- type->id = xmlGetProp(node, BAD_CAST "id");
- type->minOccurs = xmlGetMinOccurs(ctxt, node);
- type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
-
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- while ((IS_SCHEMA(child, "element")) ||
- (IS_SCHEMA(child, "group")) ||
- (IS_SCHEMA(child, "any")) ||
- (IS_SCHEMA(child, "choice")) ||
- (IS_SCHEMA(child, "sequence"))) {
- subtype = NULL;
- if (IS_SCHEMA(child, "element")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseElement(ctxt, schema, child, 0);
- } else if (IS_SCHEMA(child, "group")) {
- subtype = xmlSchemaParseGroup(ctxt, schema, child);
- } else if (IS_SCHEMA(child, "any")) {
- subtype = xmlSchemaParseAny(ctxt, schema, child);
- } else if (IS_SCHEMA(child, "choice")) {
- subtype = xmlSchemaParseChoice(ctxt, schema, child);
- } else if (IS_SCHEMA(child, "sequence")) {
- subtype = xmlSchemaParseSequence(ctxt, schema, child);
- }
- if (subtype != NULL) {
- if (last == NULL) {
- type->subtypes = subtype;
- last = subtype;
- } else {
- last->next = subtype;
- last = subtype;
- }
- last->next = NULL;
- }
- child = child->next;
- }
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Sequence %s has unexpected content\n",
- type->name);
- }
-
- return (type);
-}
-
-/**
- * xmlSchemaParseRestriction:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- * @simple: is that part of a simple type.
- *
- * parse a XML schema Restriction definition
- * *WARNING* this interface is highly subject to change
- *
- * Returns the type definition or NULL in case of error
- */
-static xmlSchemaTypePtr
-xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node, int simple)
-{
- xmlSchemaTypePtr type, subtype;
- xmlSchemaFacetPtr facet, lastfacet = NULL;
- xmlNodePtr child = NULL;
- xmlChar name[30];
- xmlChar *oldcontainer;
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
- oldcontainer = ctxt->container;
-
- snprintf((char *)name, 30, "restriction %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_RESTRICTION;
- type->id = xmlGetProp(node, BAD_CAST "id");
- type->base = xmlGetQNameProp(ctxt, node, "base", &(type->baseNs));
- if ((!simple) && (type->base == NULL)) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Restriction %s has no base\n",
- type->name);
- }
- ctxt->container = name;
-
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- subtype = NULL;
-
- if (IS_SCHEMA(child, "all")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseAll(ctxt, schema, child);
- child = child->next;
- type->subtypes = subtype;
- } else if (IS_SCHEMA(child, "choice")) {
- subtype = xmlSchemaParseChoice(ctxt, schema, child);
- child = child->next;
- type->subtypes = subtype;
- } else if (IS_SCHEMA(child, "sequence")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseSequence(ctxt, schema, child);
- child = child->next;
- type->subtypes = subtype;
- } else if (IS_SCHEMA(child, "group")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseGroup(ctxt, schema, child);
- child = child->next;
- type->subtypes = subtype;
- } else {
- if (IS_SCHEMA(child, "simpleType")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseSimpleType(ctxt, schema, child);
- child = child->next;
- type->baseType = subtype;
- }
- /*
- * Facets
- */
- while ((IS_SCHEMA(child, "minInclusive")) ||
- (IS_SCHEMA(child, "minExclusive")) ||
- (IS_SCHEMA(child, "maxInclusive")) ||
- (IS_SCHEMA(child, "maxExclusive")) ||
- (IS_SCHEMA(child, "totalDigits")) ||
- (IS_SCHEMA(child, "fractionDigits")) ||
- (IS_SCHEMA(child, "pattern")) ||
- (IS_SCHEMA(child, "enumeration")) ||
- (IS_SCHEMA(child, "whiteSpace")) ||
- (IS_SCHEMA(child, "length")) ||
- (IS_SCHEMA(child, "maxLength")) ||
- (IS_SCHEMA(child, "minLength"))) {
- facet = xmlSchemaParseFacet(ctxt, schema, child);
- if (facet != NULL) {
- if (lastfacet == NULL) {
- type->facets = facet;
- lastfacet = facet;
- } else {
- lastfacet->next = facet;
- lastfacet = facet;
- }
- lastfacet->next = NULL;
- }
- child = child->next;
- }
- }
- child = xmlSchemaParseAttrDecls(ctxt, schema, child, type);
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Restriction %s has unexpected content\n",
- type->name);
- }
- ctxt->container = oldcontainer;
- return (type);
-}
-
-/**
- * xmlSchemaParseExtension:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema Extension definition
- * *WARNING* this interface is highly subject to change
- *
- * Returns the type definition or NULL in case of error
- */
-static xmlSchemaTypePtr
-xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlSchemaTypePtr type, subtype;
- xmlNodePtr child = NULL;
- xmlChar name[30];
- xmlChar *oldcontainer;
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
- oldcontainer = ctxt->container;
-
- snprintf((char *)name, 30, "extension %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_EXTENSION;
- type->id = xmlGetProp(node, BAD_CAST "id");
- ctxt->container = name;
-
- type->base = xmlGetQNameProp(ctxt, node, "base", &(type->baseNs));
- if (type->base == NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Extension %s has no base\n",
- type->name);
- }
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- subtype = NULL;
-
- if (IS_SCHEMA(child, "all")) {
- subtype = xmlSchemaParseAll(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "choice")) {
- subtype = xmlSchemaParseChoice(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "sequence")) {
- subtype = xmlSchemaParseSequence(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "group")) {
- subtype = xmlSchemaParseGroup(ctxt, schema, child);
- child = child->next;
- }
- if (subtype != NULL)
- type->subtypes = subtype;
- child = xmlSchemaParseAttrDecls(ctxt, schema, child, type);
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Extension %s has unexpected content\n",
- type->name);
- }
- ctxt->container = oldcontainer;
- return (type);
-}
-
-/**
- * xmlSchemaParseSimpleContent:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema SimpleContent definition
- * *WARNING* this interface is highly subject to change
- *
- * Returns the type definition or NULL in case of error
- */
-static xmlSchemaTypePtr
-xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlSchemaTypePtr type, subtype;
- xmlNodePtr child = NULL;
- xmlChar name[30];
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
-
- snprintf((char *)name, 30, "complexContent %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_SIMPLE_CONTENT;
- type->id = xmlGetProp(node, BAD_CAST "id");
-
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- subtype = NULL;
- if (IS_SCHEMA(child, "restriction")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseRestriction(ctxt, schema, child, 0);
- child = child->next;
- } else if (IS_SCHEMA(child, "extension")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseExtension(ctxt, schema, child);
- child = child->next;
- }
- type->subtypes = subtype;
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "SimpleContent %s has unexpected content\n",
- type->name);
- }
- return (type);
-}
-
-/**
- * xmlSchemaParseComplexContent:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema ComplexContent definition
- * *WARNING* this interface is highly subject to change
- *
- * Returns the type definition or NULL in case of error
- */
-static xmlSchemaTypePtr
-xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlSchemaTypePtr type, subtype;
- xmlNodePtr child = NULL;
- xmlChar name[30];
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
-
- snprintf((char *)name, 30, "complexContent %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
- if (type == NULL)
- return (NULL);
- type->node = node;
- type->type = XML_SCHEMA_TYPE_COMPLEX_CONTENT;
- type->id = xmlGetProp(node, BAD_CAST "id");
-
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- subtype = NULL;
- if (IS_SCHEMA(child, "restriction")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseRestriction(ctxt, schema, child, 0);
- child = child->next;
- } else if (IS_SCHEMA(child, "extension")) {
- subtype = (xmlSchemaTypePtr)
- xmlSchemaParseExtension(ctxt, schema, child);
- child = child->next;
- }
- type->subtypes = subtype;
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "ComplexContent %s has unexpected content\n",
- type->name);
- }
- return (type);
-}
-
-/**
- * xmlSchemaParseComplexType:
- * @ctxt: a schema validation context
- * @schema: the schema being built
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema Complex Type definition
- * *WARNING* this interface is highly subject to change
- *
- * Returns the type definition or NULL in case of error
- */
-static xmlSchemaTypePtr
-xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
-{
- xmlSchemaTypePtr type, subtype;
- xmlNodePtr child = NULL;
- xmlChar *name;
- xmlChar *oldcontainer;
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (NULL);
-
- oldcontainer = ctxt->container;
- name = xmlGetProp(node, (const xmlChar *) "name");
- if (name == NULL) {
- char buf[100];
-
- snprintf(buf, 99, "anontype%d", ctxt->counter++ + 1);
- name = xmlStrdup((xmlChar *) buf);
- }
- if (name == NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData, "complexType has no name\n");
- return (NULL);
- }
- type = xmlSchemaAddType(ctxt, schema, name);
- if (type == NULL) {
- xmlFree(name);
- return (NULL);
- }
- type->node = node;
- type->type = XML_SCHEMA_TYPE_COMPLEX;
- type->id = xmlGetProp(node, BAD_CAST "id");
- ctxt->container = name;
-
- child = node->children;
- if (IS_SCHEMA(child, "annotation")) {
- type->annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- child = child->next;
- }
- if (IS_SCHEMA(child, "simpleContent")) {
- type->subtypes = xmlSchemaParseSimpleContent(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "complexContent")) {
- type->subtypes = xmlSchemaParseComplexContent(ctxt, schema, child);
- child = child->next;
- } else {
- subtype = NULL;
-
- if (IS_SCHEMA(child, "all")) {
- subtype = xmlSchemaParseAll(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "choice")) {
- subtype = xmlSchemaParseChoice(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "sequence")) {
- subtype = xmlSchemaParseSequence(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "group")) {
- subtype = xmlSchemaParseGroup(ctxt, schema, child);
- child = child->next;
- }
- if (subtype != NULL)
- type->subtypes = subtype;
- child = xmlSchemaParseAttrDecls(ctxt, schema, child, type);
- }
- if (child != NULL) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "ComplexType %s has unexpected content\n",
- type->name);
- }
- ctxt->container = oldcontainer;
- xmlFree(name);
- return (type);
-}
-
-
-/**
- * xmlSchemaParseSchema:
- * @ctxt: a schema validation context
- * @node: a subtree containing XML Schema informations
- *
- * parse a XML schema definition from a node set
- * *WARNING* this interface is highly subject to change
- *
- * Returns the internal XML Schema structure built from the resource or
- * NULL in case of error
- */
-static xmlSchemaPtr
-xmlSchemaParseSchema(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
-{
- xmlSchemaPtr schema = NULL;
- xmlSchemaAnnotPtr annot;
- xmlNodePtr child = NULL;
- xmlChar *val;
-
- if ((ctxt == NULL) || (node == NULL))
- return (NULL);
-
- if (IS_SCHEMA(node, "schema")) {
- schema = xmlSchemaNewSchema(ctxt);
- if (schema == NULL)
- return(NULL);
- schema->targetNamespace = xmlGetProp(node, BAD_CAST "targetNamespace");
- schema->id = xmlGetProp(node, BAD_CAST "id");
- schema->version = xmlGetProp(node, BAD_CAST "version");
- val = xmlGetProp(node, BAD_CAST "elementFormDefault");
- if (val != NULL) {
- if (xmlStrEqual(val, BAD_CAST "qualified"))
- schema->flags |= XML_SCHEMAS_QUALIF_ELEM;
- else if (!xmlStrEqual(val, BAD_CAST "unqualified")) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL)) {
- ctxt->error(ctxt->userData,
- "Invalid value %s for elementFormDefault\n",
- val);
- }
- }
- xmlFree(val);
- }
- val = xmlGetProp(node, BAD_CAST "attributeFormDefault");
- if (val != NULL) {
- if (xmlStrEqual(val, BAD_CAST "qualified"))
- schema->flags |= XML_SCHEMAS_QUALIF_ATTR;
- else if (!xmlStrEqual(val, BAD_CAST "unqualified")) {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL)) {
- ctxt->error(ctxt->userData,
- "Invalid value %s for elementFormDefault\n",
- val);
- }
- }
- xmlFree(val);
- }
-
- child = node->children;
- while ((IS_SCHEMA(child, "include")) ||
- (IS_SCHEMA(child, "import")) ||
- (IS_SCHEMA(child, "redefine")) ||
- (IS_SCHEMA(child, "annotation"))) {
- if (IS_SCHEMA(child, "annotation")) {
- annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- if (schema->annot == NULL)
- schema->annot = annot;
- else
- xmlSchemaFreeAnnot(annot);
- } else if (IS_SCHEMA(child, "include")) {
- TODO
- } else if (IS_SCHEMA(child, "import")) {
- xmlSchemaParseImport(ctxt, schema, child);
- } else if (IS_SCHEMA(child, "redefine")) {
- TODO
- }
- child = child->next;
- }
- while (child != NULL) {
- if (IS_SCHEMA(child, "complexType")) {
- xmlSchemaParseComplexType(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "simpleType")) {
- xmlSchemaParseSimpleType(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "element")) {
- xmlSchemaParseElement(ctxt, schema, child, 1);
- child = child->next;
- } else if (IS_SCHEMA(child, "attribute")) {
- xmlSchemaParseAttribute(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "attributeGroup")) {
- xmlSchemaParseAttributeGroup(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "group")) {
- xmlSchemaParseGroup(ctxt, schema, child);
- child = child->next;
- } else if (IS_SCHEMA(child, "notation")) {
- xmlSchemaParseNotation(ctxt, schema, child);
- child = child->next;
- } else {
- xmlSchemaErrorContext(ctxt, schema, node, child);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Schemas: unexpected element %s here \n",
- child->name);
- child = child->next;
- }
- while (IS_SCHEMA(child, "annotation")) {
- annot = xmlSchemaParseAnnotation(ctxt, schema, child);
- if (schema->annot == NULL)
- schema->annot = annot;
- else
- xmlSchemaFreeAnnot(annot);
- child = child->next;
- }
- }
- }
-#ifdef DEBUG
- if (schema == NULL)
- xmlGenericError(xmlGenericErrorContext,
- "xmlSchemaParse() failed\n");
-#endif
-
- return (schema);
-}
-
-/************************************************************************
- * *
- * Validating using Schemas *
- * *
- ************************************************************************/
-
-/************************************************************************
- * *
- * Reading/Writing Schemas *
- * *
- ************************************************************************/
-
-/**
- * xmlSchemaNewParserCtxt:
- * @URL: the location of the schema
- *
- * Create an XML Schemas parse context for that file/resource expected
- * to contain an XML Schemas file.
- *
- * Returns the parser context or NULL in case of error
- */
-xmlSchemaParserCtxtPtr
-xmlSchemaNewParserCtxt(const char *URL) {
- xmlSchemaParserCtxtPtr ret;
-
- if (URL == NULL)
- return(NULL);
-
- ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Failed to allocate new schama parser context for %s\n", URL);
- return (NULL);
- }
- memset(ret, 0, sizeof(xmlSchemaParserCtxt));
- ret->URL = xmlStrdup((const xmlChar *)URL);
- return (ret);
-}
-
-/**
- * xmlSchemaNewMemParserCtxt:
- * @buffer: a pointer to a char array containing the schemas
- * @size: the size of the array
- *
- * Create an XML Schemas parse context for that memory buffer expected
- * to contain an XML Schemas file.
- *
- * Returns the parser context or NULL in case of error
- */
-xmlSchemaParserCtxtPtr
-xmlSchemaNewMemParserCtxt(const char *buffer, int size) {
- xmlSchemaParserCtxtPtr ret;
-
- if ((buffer == NULL) || (size <= 0))
- return(NULL);
-
- ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Failed to allocate new schama parser context\n");
- return (NULL);
- }
- memset(ret, 0, sizeof(xmlSchemaParserCtxt));
- ret->buffer = buffer;
- ret->size = size;
- return (ret);
-}
-
-/**
- * xmlSchemaFreeParserCtxt:
- * @ctxt: the schema parser context
- *
- * Free the resources associated to the schema parser context
- */
-void
-xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt) {
- if (ctxt == NULL)
- return;
- if (ctxt->URL != NULL)
- xmlFree(ctxt->URL);
- if (ctxt->doc != NULL)
- xmlFreeDoc(ctxt->doc);
- xmlFree(ctxt);
-}
-
-/************************************************************************
- * *
- * Building the content models *
- * *
- ************************************************************************/
-/**
- * xmlSchemaBuildAContentModel:
- * @type: the schema type definition
- * @ctxt: the schema parser context
- * @name: the element name whose content is being built
- *
- * Generate the automata sequence needed for that type
- */
-static void
-xmlSchemaBuildAContentModel(xmlSchemaTypePtr type,
- xmlSchemaParserCtxtPtr ctxt,
- const xmlChar *name) {
- if (type == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Found unexpected type = NULL in %s content model\n",
- name);
- return;
- }
- switch (type->type) {
- case XML_SCHEMA_TYPE_ANY:
- /* TODO : handle the namespace too */
- /* TODO : make that a specific transition type */
- TODO
- ctxt->state = xmlAutomataNewTransition(ctxt->am, ctxt->state,
- NULL, BAD_CAST "*", NULL);
- break;
- case XML_SCHEMA_TYPE_ELEMENT: {
- xmlSchemaElementPtr elem = (xmlSchemaElementPtr) type;
- /* TODO : handle the namespace too */
- xmlAutomataStatePtr oldstate = ctxt->state;
- if (elem->maxOccurs >= UNBOUNDED) {
- if (elem->minOccurs > 1) {
- xmlAutomataStatePtr tmp;
- int counter;
-
- ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
- oldstate, NULL);
- oldstate = ctxt->state;
-
- counter = xmlAutomataNewCounter(ctxt->am,
- elem->minOccurs - 1, UNBOUNDED);
-
- if (elem->refDecl != NULL) {
- xmlSchemaBuildAContentModel(
- (xmlSchemaTypePtr) elem->refDecl,
- ctxt, elem->refDecl->name);
- } else {
- ctxt->state = xmlAutomataNewTransition(ctxt->am,
- ctxt->state, NULL, elem->name, type);
- }
- tmp = ctxt->state;
- xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
- counter);
- ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, tmp,
- NULL, counter);
-
- } else {
- if (elem->refDecl != NULL) {
- xmlSchemaBuildAContentModel(
- (xmlSchemaTypePtr) elem->refDecl,
- ctxt, elem->refDecl->name);
- } else {
- ctxt->state = xmlAutomataNewTransition(ctxt->am,
- ctxt->state, NULL, elem->name, type);
- }
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldstate);
- if (elem->minOccurs == 0) {
- /* basically an elem* */
- xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
- }
- }
- } else if ((elem->maxOccurs > 1) || (elem->minOccurs > 1)) {
- xmlAutomataStatePtr tmp;
- int counter;
-
- ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
- oldstate, NULL);
- oldstate = ctxt->state;
-
- counter = xmlAutomataNewCounter(ctxt->am,
- elem->minOccurs - 1, elem->maxOccurs - 1);
-
- if (elem->refDecl != NULL) {
- xmlSchemaBuildAContentModel(
- (xmlSchemaTypePtr) elem->refDecl,
- ctxt, elem->refDecl->name);
- } else {
- ctxt->state = xmlAutomataNewTransition(ctxt->am,
- ctxt->state, NULL, elem->name, type);
- }
- tmp = ctxt->state;
- xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
- counter);
- ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, tmp,
- NULL, counter);
- if (elem->minOccurs == 0) {
- /* basically an elem? */
- xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
- }
-
- } else {
- if (elem->refDecl != NULL) {
- xmlSchemaBuildAContentModel(
- (xmlSchemaTypePtr) elem->refDecl,
- ctxt, elem->refDecl->name);
- } else {
- ctxt->state = xmlAutomataNewTransition(ctxt->am,
- ctxt->state, NULL, elem->name, type);
- }
- if (elem->minOccurs == 0) {
- /* basically an elem? */
- xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
- }
- }
- break;
- }
- case XML_SCHEMA_TYPE_SEQUENCE: {
- xmlSchemaTypePtr subtypes;
-
- /*
- * If max and min occurances are default (1) then
- * simply iterate over the subtypes
- */
- if ((type->minOccurs == 1 ) && (type->maxOccurs == 1)) {
- subtypes = type->subtypes;
- while (subtypes != NULL) {
- xmlSchemaBuildAContentModel(subtypes, ctxt, name);
- subtypes = subtypes->next;
- }
- } else {
- xmlAutomataStatePtr oldstate = ctxt->state;
- if (type->maxOccurs >= UNBOUNDED) {
- if (type->minOccurs > 1) {
- xmlAutomataStatePtr tmp;
- int counter;
-
- ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
- oldstate, NULL);
- oldstate = ctxt->state;
-
- counter = xmlAutomataNewCounter(ctxt->am,
- type->minOccurs - 1, UNBOUNDED);
-
- subtypes = type->subtypes;
- while (subtypes != NULL) {
- xmlSchemaBuildAContentModel(subtypes, ctxt, name);
- subtypes = subtypes->next;
- }
- tmp = ctxt->state;
- xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
- counter);
- ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, tmp,
- NULL, counter);
-
- } else {
- subtypes = type->subtypes;
- while (subtypes != NULL) {
- xmlSchemaBuildAContentModel(subtypes, ctxt, name);
- subtypes = subtypes->next;
- }
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldstate);
- if (type->minOccurs == 0) {
- xmlAutomataNewEpsilon(ctxt->am, oldstate,
- ctxt->state);
- }
- }
- } else if ((type->maxOccurs > 1) || (type->minOccurs > 1)) {
- xmlAutomataStatePtr tmp;
- int counter;
-
- ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
- oldstate, NULL);
- oldstate = ctxt->state;
-
- counter = xmlAutomataNewCounter(ctxt->am,
- type->minOccurs - 1, type->maxOccurs - 1);
-
- subtypes = type->subtypes;
- while (subtypes != NULL) {
- xmlSchemaBuildAContentModel(subtypes, ctxt, name);
- subtypes = subtypes->next;
- }
- tmp = ctxt->state;
- xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
- counter);
- ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, tmp,
- NULL, counter);
- if (type->minOccurs == 0) {
- xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
- }
-
- } else {
- subtypes = type->subtypes;
- while (subtypes != NULL) {
- xmlSchemaBuildAContentModel(subtypes, ctxt, name);
- subtypes = subtypes->next;
- }
- if (type->minOccurs == 0) {
- xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
- }
- }
- }
- break;
- }
- case XML_SCHEMA_TYPE_CHOICE: {
- xmlSchemaTypePtr subtypes;
- xmlAutomataStatePtr start, end;
-
- start = ctxt->state;
- end = xmlAutomataNewState(ctxt->am);
-
- /*
- * iterate over the subtypes and remerge the end with an
- * epsilon transition
- */
- if (type->maxOccurs == 1) {
- subtypes = type->subtypes;
- while (subtypes != NULL) {
- ctxt->state = start;
- xmlSchemaBuildAContentModel(subtypes, ctxt, name);
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
- subtypes = subtypes->next;
- }
- } else {
- int counter;
- xmlAutomataStatePtr hop;
- int maxOccurs = type->maxOccurs == UNBOUNDED ?
- UNBOUNDED : type->maxOccurs - 1;
- int minOccurs = type->minOccurs < 1 ? 0 : type->minOccurs - 1;
-
- /*
- * use a counter to keep track of the number of transtions
- * which went through the choice.
- */
- counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
- hop = xmlAutomataNewState(ctxt->am);
-
- subtypes = type->subtypes;
- while (subtypes != NULL) {
- ctxt->state = start;
- xmlSchemaBuildAContentModel(subtypes, ctxt, name);
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
- subtypes = subtypes->next;
- }
- xmlAutomataNewCountedTrans(ctxt->am, hop, start, counter);
- xmlAutomataNewCounterTrans(ctxt->am, hop, end, counter);
- }
- if (type->minOccurs == 0) {
- xmlAutomataNewEpsilon(ctxt->am, start, end);
- }
- ctxt->state = end;
- break;
- }
- case XML_SCHEMA_TYPE_ALL: {
- xmlAutomataStatePtr start;
- xmlSchemaTypePtr subtypes;
- xmlSchemaElementPtr elem = (xmlSchemaElementPtr) type;
- int lax;
-
- subtypes = type->subtypes;
- if (subtypes == NULL)
- break;
- start = ctxt->state;
- while (subtypes != NULL) {
- ctxt->state = start;
- elem = (xmlSchemaElementPtr) subtypes;
-
- /* TODO : handle the namespace too */
- xmlAutomataNewOnceTrans(ctxt->am, ctxt->state, ctxt->state,
- elem->name, elem->minOccurs, elem->maxOccurs,
- subtypes);
- subtypes = subtypes->next;
- }
- lax = type->minOccurs == 0;
- ctxt->state = xmlAutomataNewAllTrans(ctxt->am, ctxt->state, NULL,
- lax);
- break;
- }
- case XML_SCHEMA_TYPE_RESTRICTION:
- if (type->subtypes != NULL)
- xmlSchemaBuildAContentModel(type->subtypes, ctxt, name);
- break;
- case XML_SCHEMA_TYPE_EXTENSION:
- if (type->baseType != NULL) {
- xmlSchemaTypePtr subtypes;
-
- xmlSchemaBuildAContentModel(type->baseType, ctxt, name);
- subtypes = type->subtypes;
- while (subtypes != NULL) {
- xmlSchemaBuildAContentModel(subtypes, ctxt, name);
- subtypes = subtypes->next;
- }
- } else if (type->subtypes != NULL)
- xmlSchemaBuildAContentModel(type->subtypes, ctxt, name);
- break;
- case XML_SCHEMA_TYPE_GROUP:
- case XML_SCHEMA_TYPE_COMPLEX:
- case XML_SCHEMA_TYPE_COMPLEX_CONTENT:
- if (type->subtypes != NULL)
- xmlSchemaBuildAContentModel(type->subtypes, ctxt, name);
- break;
- default:
- xmlGenericError(xmlGenericErrorContext,
- "Found unexpected type %d in %s content model\n",
- type->type, name);
- return;
- }
-}
-/**
- * xmlSchemaBuildContentModel:
- * @typeDecl: the schema type definition
- * @ctxt: the schema parser context
- *
- * Fixes the content model of the element.
- */
-static void
-xmlSchemaBuildContentModel(xmlSchemaElementPtr elem,
- xmlSchemaParserCtxtPtr ctxt,
- const xmlChar *name) {
- xmlAutomataStatePtr start;
-
- if (elem->contModel != NULL)
- return;
- if (elem->subtypes == NULL) {
- elem->contentType = XML_SCHEMA_CONTENT_ANY;
- return;
- }
- if (elem->subtypes->type != XML_SCHEMA_TYPE_COMPLEX)
- return;
- if (elem->subtypes->contentType == XML_SCHEMA_CONTENT_BASIC)
- return;
-
-#ifdef DEBUG_CONTENT
- xmlGenericError(xmlGenericErrorContext,
- "Building content model for %s\n", name);
-#endif
-
- ctxt->am = xmlNewAutomata();
- if (ctxt->am == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Cannot create automata for elem %s\n", name);
- return;
- }
- start = ctxt->state = xmlAutomataGetInitState(ctxt->am);
- xmlSchemaBuildAContentModel(elem->subtypes, ctxt, name);
- xmlAutomataSetFinalState(ctxt->am, ctxt->state);
- elem->contModel = xmlAutomataCompile(ctxt->am);
- if (!xmlAutomataIsDeterminist(ctxt->am)) {
- xmlGenericError(xmlGenericErrorContext,
- "Content model of %s is not determinist:\n", name);
- ctxt->err = XML_SCHEMAS_ERR_NOTDETERMINIST;
- ctxt->state = NULL;
- } else {
-#ifdef DEBUG_CONTENT_REGEXP
- xmlGenericError(xmlGenericErrorContext,
- "Content model of %s:\n", name);
- xmlRegexpPrint(stderr, elem->contModel);
-#endif
- ctxt->state = NULL;
- }
- xmlFreeAutomata(ctxt->am);
- ctxt->am = NULL;
-}
-
-/**
- * xmlSchemaRefFixupCallback:
- * @elem: the schema element context
- * @ctxt: the schema parser context
- *
- * Free the resources associated to the schema parser context
- */
-static void
-xmlSchemaRefFixupCallback(xmlSchemaElementPtr elem,
- xmlSchemaParserCtxtPtr ctxt,
- const xmlChar *name,
- const xmlChar *context ATTRIBUTE_UNUSED,
- const xmlChar *namespace ATTRIBUTE_UNUSED)
-{
- if ((ctxt == NULL) || (elem == NULL))
- return;
- if (elem->ref != NULL) {
- xmlSchemaElementPtr elemDecl;
-
- if (elem->subtypes != NULL) {
- xmlSchemaErrorContext(ctxt, NULL, elem->node, NULL);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Schemas: element %s have both ref and subtype\n",
- name);
- return;
- }
- elemDecl = xmlHashLookup2(ctxt->schema->elemDecl,
- elem->ref, elem->refNs);
-
- if (elemDecl == NULL) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Schemas: element %s ref to %s not found\n",
- name, elem->ref);
- return;
- }
- elem->refDecl = elemDecl;
- } else if (elem->namedType != NULL) {
- xmlSchemaTypePtr typeDecl;
-
- if (elem->subtypes != NULL) {
- xmlSchemaErrorContext(ctxt, NULL, elem->node, NULL);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Schemas: element %s have both type and subtype\n",
- name);
- return;
- }
- typeDecl = xmlSchemaGetType(ctxt->schema, elem->namedType,
- elem->namedTypeNs);
-
- if (typeDecl == NULL) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Schemas: element %s type %s not found\n",
- name, elem->namedType);
- return;
- }
- elem->subtypes = typeDecl;
- }
-}
-
-/**
- * xmlSchemaTypeFixup:
- * @typeDecl: the schema type definition
- * @ctxt: the schema parser context
- *
- * Fixes the content model of the type.
- */
-static void
-xmlSchemaTypeFixup(xmlSchemaTypePtr typeDecl,
- xmlSchemaParserCtxtPtr ctxt,
- const xmlChar *name)
-{
- if (name == NULL)
- name = typeDecl->name;
- if (typeDecl->contentType == XML_SCHEMA_CONTENT_UNKNOWN) {
- switch (typeDecl->type) {
- case XML_SCHEMA_TYPE_SIMPLE_CONTENT: {
- xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
- typeDecl->contentType = typeDecl->subtypes->contentType;
- break;
- }
- case XML_SCHEMA_TYPE_RESTRICTION: {
- if (typeDecl->subtypes != NULL)
- xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
-
- if (typeDecl->base != NULL) {
- xmlSchemaTypePtr baseType;
-
- baseType = xmlSchemaGetType(ctxt->schema, typeDecl->base,
- typeDecl->baseNs);
- if (baseType == NULL) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Schemas: type %s base type %s not found\n",
- name, typeDecl->base);
- }
- typeDecl->baseType = baseType;
- }
- if (typeDecl->subtypes == NULL)
- /* 1.1.1 */
- typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
- else if ((typeDecl->subtypes->subtypes == NULL) &&
- ((typeDecl->subtypes->type == XML_SCHEMA_TYPE_ALL) ||
- (typeDecl->subtypes->type == XML_SCHEMA_TYPE_SEQUENCE)))
- /* 1.1.2 */
- typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
- else if ((typeDecl->subtypes->type == XML_SCHEMA_TYPE_CHOICE) &&
- (typeDecl->subtypes->subtypes == NULL))
- /* 1.1.3 */
- typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
- else {
- /* 1.2 and 2.X are applied at the other layer */
- typeDecl->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
- }
- break;
- }
- case XML_SCHEMA_TYPE_EXTENSION: {
- xmlSchemaContentType explicitContentType;
- xmlSchemaTypePtr base;
-
- if (typeDecl->base != NULL) {
- xmlSchemaTypePtr baseType;
-
- baseType = xmlSchemaGetType(ctxt->schema, typeDecl->base,
- typeDecl->baseNs);
- if (baseType == NULL) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Schemas: type %s base type %s not found\n",
- name, typeDecl->base);
- }
- typeDecl->baseType = baseType;
- }
- if (typeDecl->subtypes != NULL)
- xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
-
- explicitContentType = XML_SCHEMA_CONTENT_ELEMENTS;
- if (typeDecl->subtypes == NULL)
- /* 1.1.1 */
- explicitContentType = XML_SCHEMA_CONTENT_EMPTY;
- else if ((typeDecl->subtypes->subtypes == NULL) &&
- ((typeDecl->subtypes->type == XML_SCHEMA_TYPE_ALL) ||
- (typeDecl->subtypes->type == XML_SCHEMA_TYPE_SEQUENCE)))
- /* 1.1.2 */
- explicitContentType = XML_SCHEMA_CONTENT_EMPTY;
- else if ((typeDecl->subtypes->type == XML_SCHEMA_TYPE_CHOICE) &&
- (typeDecl->subtypes->subtypes == NULL))
- /* 1.1.3 */
- explicitContentType = XML_SCHEMA_CONTENT_EMPTY;
-
- base = xmlSchemaGetType(ctxt->schema, typeDecl->base,
- typeDecl->baseNs);
- if (base == NULL) {
- xmlSchemaErrorContext(ctxt, NULL, typeDecl->node, NULL);
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Schemas: base type %s of type %s not found\n",
- typeDecl->base, name);
- return;
- }
- xmlSchemaTypeFixup(base, ctxt, NULL);
- if (explicitContentType == XML_SCHEMA_CONTENT_EMPTY) {
- /* 2.1 */
- typeDecl->contentType = base->contentType;
- } else if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
- /* 2.2 imbitable ! */
- typeDecl->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
- } else {
- /* 2.3 imbitable pareil ! */
- typeDecl->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
- }
- break;
- }
- case XML_SCHEMA_TYPE_COMPLEX: {
- if (typeDecl->subtypes == NULL) {
- typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
- } else {
- if (typeDecl->flags & XML_SCHEMAS_TYPE_MIXED)
- typeDecl->contentType = XML_SCHEMA_CONTENT_MIXED;
- else {
- xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
- typeDecl->contentType = typeDecl->subtypes->contentType;
- }
- }
- break;
- }
- case XML_SCHEMA_TYPE_COMPLEX_CONTENT: {
- if (typeDecl->subtypes == NULL) {
- typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
- } else {
- if (typeDecl->flags & XML_SCHEMAS_TYPE_MIXED)
- typeDecl->contentType = XML_SCHEMA_CONTENT_MIXED;
- else {
- xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
- typeDecl->contentType = typeDecl->subtypes->contentType;
- }
- }
- break;
- }
- case XML_SCHEMA_TYPE_SEQUENCE:
- case XML_SCHEMA_TYPE_GROUP:
- case XML_SCHEMA_TYPE_ALL:
- case XML_SCHEMA_TYPE_CHOICE:
- typeDecl->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
- break;
- case XML_SCHEMA_TYPE_BASIC:
- case XML_SCHEMA_TYPE_ANY:
- case XML_SCHEMA_TYPE_FACET:
- case XML_SCHEMA_TYPE_SIMPLE:
- case XML_SCHEMA_TYPE_UR:
- case XML_SCHEMA_TYPE_ELEMENT:
- case XML_SCHEMA_TYPE_ATTRIBUTE:
- case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
- case XML_SCHEMA_TYPE_NOTATION:
- case XML_SCHEMA_TYPE_LIST:
- case XML_SCHEMA_TYPE_UNION:
- case XML_SCHEMA_FACET_MININCLUSIVE:
- case XML_SCHEMA_FACET_MINEXCLUSIVE:
- case XML_SCHEMA_FACET_MAXINCLUSIVE:
- case XML_SCHEMA_FACET_MAXEXCLUSIVE:
- case XML_SCHEMA_FACET_TOTALDIGITS:
- case XML_SCHEMA_FACET_FRACTIONDIGITS:
- case XML_SCHEMA_FACET_PATTERN:
- case XML_SCHEMA_FACET_ENUMERATION:
- case XML_SCHEMA_FACET_WHITESPACE:
- case XML_SCHEMA_FACET_LENGTH:
- case XML_SCHEMA_FACET_MAXLENGTH:
- case XML_SCHEMA_FACET_MINLENGTH:
- typeDecl->contentType = XML_SCHEMA_CONTENT_SIMPLE;
- break;
- }
- }
-#ifdef DEBUG_TYPE
- if (typeDecl->node != NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Type of %s : %s:%d :", name, typeDecl->node->doc->URL,
- xmlGetLineNo(typeDecl->node));
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "Type of %s :", name);
- }
- switch (typeDecl->contentType) {
- case XML_SCHEMA_CONTENT_SIMPLE:
- xmlGenericError(xmlGenericErrorContext,
- "simple\n"); break;
- case XML_SCHEMA_CONTENT_ELEMENTS:
- xmlGenericError(xmlGenericErrorContext,
- "elements\n"); break;
- case XML_SCHEMA_CONTENT_UNKNOWN:
- xmlGenericError(xmlGenericErrorContext,
- "unknown !!!\n"); break;
- case XML_SCHEMA_CONTENT_EMPTY:
- xmlGenericError(xmlGenericErrorContext,
- "empty\n"); break;
- case XML_SCHEMA_CONTENT_MIXED:
- xmlGenericError(xmlGenericErrorContext,
- "mixed\n"); break;
- case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
- xmlGenericError(xmlGenericErrorContext,
- "mixed or elems\n"); break;
- case XML_SCHEMA_CONTENT_BASIC:
- xmlGenericError(xmlGenericErrorContext,
- "basic\n"); break;
- default:
- xmlGenericError(xmlGenericErrorContext,
- "not registered !!!\n"); break;
- }
-#endif
-}
-
-/**
- * xmlSchemaCheckDefaults:
- * @typeDecl: the schema type definition
- * @ctxt: the schema parser context
- *
- * Checks the default values types, especially for facets
- */
-static void
-xmlSchemaCheckDefaults(xmlSchemaTypePtr typeDecl,
- xmlSchemaParserCtxtPtr ctxt,
- const xmlChar *name)
-{
- static xmlSchemaTypePtr nonNegativeIntegerType = NULL;
- if (name == NULL)
- name = typeDecl->name;
- if (nonNegativeIntegerType == NULL) {
- nonNegativeIntegerType = xmlSchemaGetPredefinedType(
- BAD_CAST "nonNegativeInteger", xmlSchemaNs);
- }
- if (typeDecl->type == XML_SCHEMA_TYPE_RESTRICTION) {
- if (typeDecl->facets != NULL) {
- xmlSchemaFacetPtr facet = typeDecl->facets;
- while (facet != NULL) {
- switch (facet->type) {
- case XML_SCHEMA_FACET_MININCLUSIVE:
- case XML_SCHEMA_FACET_MINEXCLUSIVE:
- case XML_SCHEMA_FACET_MAXINCLUSIVE:
- case XML_SCHEMA_FACET_MAXEXCLUSIVE: {
- /*
- * Okay we need to validate the value
- * at that point.
- */
- xmlSchemaValidCtxtPtr vctxt;
-
- vctxt = xmlSchemaNewValidCtxt(NULL);
- if (vctxt == NULL)
- break;
- xmlSchemaValidateSimpleValue(vctxt, typeDecl,
- facet->value);
- facet->val = vctxt->value;
- vctxt->value = NULL;
- if (facet->val == NULL) {
- /* error code */
- xmlSchemaErrorContext(ctxt, NULL,
- facet->node, NULL);
- ctxt->error(ctxt->userData,
- "Schemas: type %s facet value %s invalid\n",
- name, facet->value);
- }
- xmlSchemaFreeValidCtxt(vctxt);
- break;
- }
- case XML_SCHEMA_FACET_ENUMERATION: {
- /*
- * Okay we need to validate the value
- * at that point.
- */
- xmlSchemaValidCtxtPtr vctxt;
- int ret;
-
- vctxt = xmlSchemaNewValidCtxt(NULL);
- if (vctxt == NULL)
- break;
- ret = xmlSchemaValidateSimpleValue(vctxt, typeDecl,
- facet->value);
- if (ret != 0) {
- xmlSchemaErrorContext(ctxt, NULL,
- facet->node, NULL);
- ctxt->error(ctxt->userData,
- "Schemas: type %s enumeration value %s invalid\n",
- name, facet->value);
- }
- xmlSchemaFreeValidCtxt(vctxt);
- break;
- }
- case XML_SCHEMA_FACET_PATTERN:
- facet->regexp = xmlRegexpCompile(facet->value);
- if (facet->regexp == NULL) {
- /* error code */
- ctxt->error(ctxt->userData,
- "Schemas: type %s facet regexp %s invalid\n",
- name, facet->value);
- }
- break;
- case XML_SCHEMA_FACET_TOTALDIGITS:
- case XML_SCHEMA_FACET_FRACTIONDIGITS:
- case XML_SCHEMA_FACET_LENGTH:
- case XML_SCHEMA_FACET_MAXLENGTH:
- case XML_SCHEMA_FACET_MINLENGTH: {
- int ret;
-
- ret = xmlSchemaValidatePredefinedType(
- nonNegativeIntegerType, facet->value,
- &facet->val);
- if (ret != 0) {
- /* error code */
- xmlSchemaErrorContext(ctxt, NULL,
- facet->node, NULL);
- ctxt->error(ctxt->userData,
- "Schemas: type %s facet value %s invalid\n",
- name, facet->value);
- }
- break;
- }
- case XML_SCHEMA_FACET_WHITESPACE: {
- if (xmlStrEqual(facet->value, BAD_CAST"preserve")) {
- facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
- } else if (xmlStrEqual(facet->value,
- BAD_CAST"replace")) {
- facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
- } else if (xmlStrEqual(facet->value,
- BAD_CAST"collapse")) {
- facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
- } else {
- xmlSchemaErrorContext(ctxt, NULL,
- facet->node, NULL);
- ctxt->error(ctxt->userData,
- "Schemas: type %s whiteSpace value %s invalid\n",
- name, facet->value);
- }
- }
- default:
- break;
- }
- facet = facet->next;
- }
- }
- }
-}
-
-/**
- * xmlSchemaAttrGrpFixup:
- * @attrgrpDecl: the schema attribute definition
- * @ctxt: the schema parser context
- * @name: the attribute name
- *
- * Fixes finish doing the computations on the attributes definitions
- */
-static void
-xmlSchemaAttrGrpFixup(xmlSchemaAttributeGroupPtr attrgrpDecl,
- xmlSchemaParserCtxtPtr ctxt,
- const xmlChar *name)
-{
- if (name == NULL)
- name = attrgrpDecl->name;
- if (attrgrpDecl->attributes != NULL)
- return;
- if (attrgrpDecl->ref != NULL) {
- xmlSchemaAttributeGroupPtr ref;
-
- ref = xmlHashLookup2(ctxt->schema->attrgrpDecl, attrgrpDecl->ref,
- attrgrpDecl->refNs);
- if (ref == NULL) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Schemas: attribute group %s reference %s not found\n",
- name, attrgrpDecl->ref);
- return;
- }
- xmlSchemaAttrGrpFixup(ref, ctxt, NULL);
- attrgrpDecl->attributes = ref->attributes;
- } else {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Schemas: attribute %s has no attributes nor reference\n",
- name);
- }
-}
-
-/**
- * xmlSchemaAttrFixup:
- * @attrDecl: the schema attribute definition
- * @ctxt: the schema parser context
- * @name: the attribute name
- *
- * Fixes finish doing the computations on the attributes definitions
- */
-static void
-xmlSchemaAttrFixup(xmlSchemaAttributePtr attrDecl,
- xmlSchemaParserCtxtPtr ctxt,
- const xmlChar *name)
-{
- if (name == NULL)
- name = attrDecl->name;
- if (attrDecl->subtypes != NULL)
- return;
- if (attrDecl->typeName != NULL) {
- xmlSchemaTypePtr type;
-
- type = xmlSchemaGetType(ctxt->schema, attrDecl->typeName,
- attrDecl->typeNs);
- if (type == NULL) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Schemas: attribute %s type %s not found\n",
- name, attrDecl->typeName);
- }
- attrDecl->subtypes = type;
- } else if (attrDecl->ref != NULL) {
- xmlSchemaAttributePtr ref;
-
- ref = xmlHashLookup2(ctxt->schema->attrDecl, attrDecl->ref,
- attrDecl->refNs);
- if (ref == NULL) {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Schemas: attribute %s reference %s not found\n",
- name, attrDecl->ref);
- return;
- }
- xmlSchemaAttrFixup(ref, ctxt, NULL);
- attrDecl->subtypes = ref->subtypes;
- } else {
- if ((ctxt != NULL) && (ctxt->error != NULL))
- ctxt->error(ctxt->userData,
- "Schemas: attribute %s has no type nor reference\n",
- name);
- }
-}
-
-/**
- * xmlSchemaParse:
- * @ctxt: a schema validation context
- *
- * parse a schema definition resource and build an internal
- * XML Shema struture which can be used to validate instances.
- * *WARNING* this interface is highly subject to change
- *
- * Returns the internal XML Schema structure built from the resource or
- * NULL in case of error
- */
-xmlSchemaPtr
-xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
-{
- xmlSchemaPtr ret = NULL;
- xmlDocPtr doc;
- xmlNodePtr root, cur, delete;
-
- xmlSchemaInitTypes();
-
- if (ctxt == NULL)
- return (NULL);
-
- ctxt->counter = 0;
- ctxt->container = NULL;
-
- /*
- * First step is to parse the input document into an DOM/Infoset
- */
- if (ctxt->URL != NULL) {
- doc = xmlParseFile((const char *) ctxt->URL);
- if (doc == NULL) {
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "xmlSchemaParse: could not load %s\n", ctxt->URL);
- return (NULL);
- }
- } else if (ctxt->buffer != NULL) {
- doc = xmlParseMemory(ctxt->buffer, ctxt->size);
- if (doc == NULL) {
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "xmlSchemaParse: could not parse schemas\n");
- return (NULL);
- }
- doc->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
- ctxt->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
- } else {
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "xmlSchemaParse: nothing to parse\n");
- return (NULL);
- }
-
- /*
- * Then extract the root and Schema parse it
- */
- root = xmlDocGetRootElement(doc);
- if (root == NULL) {
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData, "xmlSchemaParse: %s is empty\n",
- ctxt->URL);
- return (NULL);
- }
-
- /*
- * Remove all the blank text nodes
- */
- delete = NULL;
- cur = root;
- while (cur != NULL) {
- if (delete != NULL) {
- xmlUnlinkNode(delete);
- xmlFreeNode(delete);
- delete = NULL;
- }
- if (cur->type == XML_TEXT_NODE) {
- if (IS_BLANK_NODE(cur)) {
- if (xmlNodeGetSpacePreserve(cur) != 1) {
- delete = cur;
- }
- }
- } else if ((cur->type != XML_ELEMENT_NODE) &&
- (cur->type != XML_CDATA_SECTION_NODE)) {
- delete = cur;
- goto skip_children;
- }
-
- /*
- * Skip to next node
- */
- if (cur->children != NULL) {
- if ((cur->children->type != XML_ENTITY_DECL) &&
- (cur->children->type != XML_ENTITY_REF_NODE) &&
- (cur->children->type != XML_ENTITY_NODE)) {
- cur = cur->children;
- continue;
- }
- }
-skip_children:
- if (cur->next != NULL) {
- cur = cur->next;
- continue;
- }
-
- do {
- cur = cur->parent;
- if (cur == NULL)
- break;
- if (cur == root) {
- cur = NULL;
- break;
- }
- if (cur->next != NULL) {
- cur = cur->next;
- break;
- }
- } while (cur != NULL);
- }
- if (delete != NULL) {
- xmlUnlinkNode(delete);
- xmlFreeNode(delete);
- delete = NULL;
- }
-
- /*
- * Then do the parsing for good
- */
- ret = xmlSchemaParseSchema(ctxt, root);
- if (ret == NULL)
- return(NULL);
- ret->doc = doc;
-
- /*
- * Then fix all the references.
- */
- ctxt->schema = ret;
- xmlHashScanFull(ret->elemDecl,
- (xmlHashScannerFull) xmlSchemaRefFixupCallback, ctxt);
-
- /*
- * Then fixup all types properties
- */
- xmlHashScan(ret->typeDecl, (xmlHashScanner) xmlSchemaTypeFixup, ctxt);
-
- /*
- * Then build the content model for all elements
- */
- xmlHashScan(ret->elemDecl,
- (xmlHashScanner) xmlSchemaBuildContentModel, ctxt);
-
- /*
- * Then check the defaults part of the type like facets values
- */
- xmlHashScan(ret->typeDecl, (xmlHashScanner) xmlSchemaCheckDefaults, ctxt);
-
- /*
- * Then fixup all attributes declarations
- */
- xmlHashScan(ret->attrDecl, (xmlHashScanner) xmlSchemaAttrFixup, ctxt);
-
- /*
- * Then fixup all attributes group declarations
- */
- xmlHashScan(ret->attrgrpDecl, (xmlHashScanner) xmlSchemaAttrGrpFixup, ctxt);
-
- return (ret);
-}
-
-/**
- * xmlSchemaSetParserErrors:
- * @ctxt: a schema validation context
- * @err: the error callback
- * @warn: the warning callback
- * @ctx: contextual data for the callbacks
- *
- * Set the callback functions used to handle errors for a validation context
- */
-void
-xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaValidityErrorFunc err,
- xmlSchemaValidityWarningFunc warn, void *ctx) {
- if (ctxt == NULL)
- return;
- ctxt->error = err;
- ctxt->warning = warn;
- ctxt->userData = ctx;
-}
-
-/************************************************************************
- * *
- * Simple type validation *
- * *
- ************************************************************************/
-
-/**
- * xmlSchemaValidateSimpleValue:
- * @ctxt: a schema validation context
- * @type: the type declaration
- * @value: the value to validate
- *
- * Validate a value against a simple type
- *
- * Returns 0 if the value is valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
- xmlSchemaTypePtr type,
- xmlChar *value) {
- int ret = 0;
- /*
- * First normalize the value accordingly to Schema Datatype
- * 4.3.6 whiteSpace definition of the whiteSpace facet of type
- */
- /*
- * Then check the normalized value against the lexical space of the
- * type.
- */
- if (type->type == XML_SCHEMA_TYPE_BASIC) {
- if (ctxt->value != NULL) {
- xmlSchemaFreeValue(ctxt->value);
- ctxt->value = NULL;
- }
- ret = xmlSchemaValidatePredefinedType(type, value, &(ctxt->value));
- } else if (type->type == XML_SCHEMA_TYPE_RESTRICTION) {
- xmlSchemaTypePtr base;
- xmlSchemaFacetPtr facet;
- int tmp;
-
- base = type->baseType;
- if (base != NULL) {
- ret = xmlSchemaValidateSimpleValue(ctxt, base, value);
- } else if (type->subtypes != NULL) {
-
- }
- /*
- * Do not validate facets when working on building the Schemas
- */
- if (ctxt->schema != NULL) {
- if (ret == 0) {
- facet = type->facets;
- if ((type->type == XML_SCHEMA_TYPE_RESTRICTION) &&
- (facet != NULL) &&
- (facet->type == XML_SCHEMA_FACET_ENUMERATION)) {
- while (facet != NULL) {
- ret = 1;
-
- tmp = xmlSchemaValidateFacet(base, facet, value,
- ctxt->value);
- if (tmp == 0) {
- ret = 0;
- break;
- }
- facet = facet->next;
- }
- } else {
- while (facet != NULL) {
- tmp = xmlSchemaValidateFacet(base, facet, value,
- ctxt->value);
- if (tmp != 0)
- ret = tmp;
- facet = facet->next;
- }
- }
- }
- }
- } else if (type->type == XML_SCHEMA_TYPE_SIMPLE) {
- xmlSchemaTypePtr base;
-
- base = type->subtypes;
- if (base != NULL) {
- ret = xmlSchemaValidateSimpleValue(ctxt, base, value);
- } else {
- TODO
- }
- } else if (type->type == XML_SCHEMA_TYPE_LIST) {
- xmlSchemaTypePtr base;
- xmlChar *cur, *end, tmp;
- int ret2;
-
- base = type->subtypes;
- if (base == NULL) {
- ctxt->err = XML_SCHEMAS_ERR_INTERNAL;
- if (ctxt->error != NULL) {
- xmlSchemaErrorContext(NULL, ctxt->schema, type->node, NULL);
- ctxt->error(ctxt->userData,
- "Internal: List type %s has no base type\n",
- type->name);
- }
- return(-1);
- }
- cur = value;
- do {
- while (IS_BLANK(*cur)) cur++;
- end = cur;
- while ((*end != 0) && (!(IS_BLANK(*end)))) end++;
- if (end == cur)
- break;
- tmp = *end;
- *end = 0;
- ret2 = xmlSchemaValidateSimpleValue(ctxt, base, cur);
- if (ret2 != 0)
- ret = 1;
- *end = tmp;
- cur = end;
- } while (*cur != 0);
- } else {
- TODO
- }
- return(ret);
-}
-
-/************************************************************************
- * *
- * DOM Validation code *
- * *
- ************************************************************************/
-
-static int xmlSchemaValidateContent(xmlSchemaValidCtxtPtr ctxt,
- xmlNodePtr node);
-static int xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt,
- xmlNodePtr elem, xmlSchemaAttributePtr attributes);
-static int xmlSchemaValidateType(xmlSchemaValidCtxtPtr ctxt,
- xmlNodePtr elem, xmlSchemaElementPtr elemDecl, xmlSchemaTypePtr type);
-
-/**
- * xmlSchemaRegisterAttributes:
- * @ctxt: a schema validation context
- * @attrs: a list of attributes
- *
- * Register the list of attributes as the set to be validated on that element
- *
- * Returns -1 in case of error, 0 otherwise
- */
-static int
-xmlSchemaRegisterAttributes(xmlSchemaValidCtxtPtr ctxt,
- xmlAttrPtr attrs) {
- while (attrs != NULL) {
- if ((attrs->ns != NULL) &&
- (xmlStrEqual(attrs->ns->href, xmlSchemaInstanceNs))) {
- attrs = attrs->next;
- continue;
- }
- if (ctxt->attrNr >= ctxt->attrMax) {
- xmlSchemaAttrStatePtr tmp;
-
- ctxt->attrMax *= 2;
- tmp = (xmlSchemaAttrStatePtr)
- xmlRealloc(ctxt->attr, ctxt->attrMax *
- sizeof(xmlSchemaAttrState));
- if (tmp == NULL) {
- ctxt->attrMax /= 2;
- return(-1);
- }
- ctxt->attr = tmp;
- }
- ctxt->attr[ctxt->attrNr].attr = attrs;
- ctxt->attr[ctxt->attrNr].state = XML_SCHEMAS_ATTR_UNKNOWN;
- ctxt->attrNr++;
- attrs = attrs->next;
- }
- return(0);
-}
-
-/**
- * xmlSchemaCheckAttributes:
- * @ctxt: a schema validation context
- * @node: the node carrying it.
- *
- * Check that the registered set of attributes on the current node
- * has been properly validated.
- *
- * Returns 0 if validity constraints are met, 1 otherwise.
- */
-static int
-xmlSchemaCheckAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node) {
- int ret = 0;
- int i;
-
- for (i = ctxt->attrBase;i < ctxt->attrNr;i++) {
- if (ctxt->attr[i].attr == NULL)
- break;
- if (ctxt->attr[i].state == XML_SCHEMAS_ATTR_UNKNOWN) {
- ret = 1;
- ctxt->err = XML_SCHEMAS_ERR_ATTRUNKNOWN;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Attribute %s on %s is unknown\n",
- ctxt->attr[i].attr->name,
- node->name);
- }
- }
- return(ret);
-}
-
-/**
- * xmlSchemaValidateSimpleContent:
- * @ctxt: a schema validation context
- * @elem: an element
- * @type: the type declaration
- *
- * Validate the content of an element expected to be a simple type
- *
- * Returns 0 if the element is schemas valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateSimpleContent(xmlSchemaValidCtxtPtr ctxt,
- xmlNodePtr node ATTRIBUTE_UNUSED) {
- xmlNodePtr child;
- xmlSchemaTypePtr type, base;
- xmlChar *value;
- int ret = 0, tmp;
-
- child = ctxt->node;
- type = ctxt->type;
-
- /*
- * Validation Rule: Element Locally Valid (Type): 3.1.3
- */
- value = xmlNodeGetContent(child);
- /* xmlSchemaValidateSimpleValue(ctxt, type, value); */
- switch (type->type) {
- case XML_SCHEMA_TYPE_RESTRICTION: {
- xmlSchemaFacetPtr facet;
-
- base = type->baseType;
- if (base != NULL) {
- ret = xmlSchemaValidateSimpleValue(ctxt, base, value);
- } else {
- TODO
- }
- if (ret == 0) {
- facet = type->facets;
- while (facet != NULL) {
- tmp = xmlSchemaValidateFacet(base, facet, value,
- ctxt->value);
- if (tmp != 0)
- ret = tmp;
- facet = facet->next;
- }
- }
- break;
- }
- default:
- TODO
- }
- if (value != NULL)
- xmlFree(value);
-
- return(ret);
-}
-
-/**
- * xmlSchemaValidateCheckNodeList
- * @nodelist: the list of nodes
- *
- * Check the node list is only made of text nodes and entities pointing
- * to text nodes
- *
- * Returns 1 if true, 0 if false and -1 in case of error
- */
-static int
-xmlSchemaValidateCheckNodeList(xmlNodePtr nodelist) {
- while (nodelist != NULL) {
- if (nodelist->type == XML_ENTITY_REF_NODE) {
- TODO /* implement recursion in the entity content */
- }
- if ((nodelist->type != XML_TEXT_NODE) &&
- (nodelist->type != XML_COMMENT_NODE) &&
- (nodelist->type != XML_PI_NODE) &&
- (nodelist->type != XML_PI_NODE)) {
- return(0);
- }
- nodelist = nodelist->next;
- }
- return(1);
-}
-
-/**
- * xmlSchemaSkipIgnored:
- * @ctxt: a schema validation context
- * @type: the current type context
- * @node: the top node.
- *
- * Skip ignorable nodes in that context
- *
- * Returns the new sibling
- * number otherwise and -1 in case of internal or API error.
- */
-static xmlNodePtr
-xmlSchemaSkipIgnored(xmlSchemaValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
- xmlSchemaTypePtr type,
- xmlNodePtr node) {
- int mixed = 0;
- /*
- * TODO complete and handle entities
- */
- mixed = ((type->contentType == XML_SCHEMA_CONTENT_MIXED) ||
- (type->contentType == XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS));
- while ((node != NULL) &&
- ((node->type == XML_COMMENT_NODE) ||
- ((mixed == 1) && (node->type == XML_TEXT_NODE)) ||
- (((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) &&
- (node->type == XML_TEXT_NODE) &&
- (IS_BLANK_NODE(node)))))) {
- node = node->next;
- }
- return(node);
-}
-
-/**
- * xmlSchemaValidateCallback:
- * @ctxt: a schema validation context
- * @name: the name of the element detected (might be NULL)
- * @type: the type
- *
- * A transition has been made in the automata associated to an element
- * content model
- */
-static void
-xmlSchemaValidateCallback(xmlSchemaValidCtxtPtr ctxt,
- const xmlChar *name ATTRIBUTE_UNUSED,
- xmlSchemaTypePtr type,
- xmlNodePtr node) {
- xmlSchemaTypePtr oldtype = ctxt->type;
- xmlNodePtr oldnode = ctxt->node;
-#ifdef DEBUG_CONTENT
- xmlGenericError(xmlGenericErrorContext,
- "xmlSchemaValidateCallback: %s, %s, %s\n",
- name, type->name, node->name);
-#endif
- ctxt->type = type;
- ctxt->node = node;
- xmlSchemaValidateContent(ctxt, node);
- ctxt->type = oldtype;
- ctxt->node = oldnode;
-}
-
-
-#if 0
-/**
- * xmlSchemaValidateSimpleRestrictionType:
- * @ctxt: a schema validation context
- * @node: the top node.
- *
- * Validate the content of a restriction type.
- *
- * Returns 0 if the element is schemas valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateSimpleRestrictionType(xmlSchemaValidCtxtPtr ctxt,
- xmlNodePtr node)
-{
- xmlNodePtr child;
- xmlSchemaTypePtr type;
- int ret;
-
- child = ctxt->node;
- type = ctxt->type;
-
- if ((ctxt == NULL) || (type == NULL)) {
- ctxt->err = XML_SCHEMAS_ERR_INTERNAL;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Internal error: xmlSchemaValidateSimpleRestrictionType %s\n",
- node->name);
- return (-1);
- }
- /*
- * Only text and text based entities references shall be found there
- */
- ret = xmlSchemaValidateCheckNodeList(child);
- if (ret < 0) {
- ctxt->err = XML_SCHEMAS_ERR_INTERNAL;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Internal error: xmlSchemaValidateSimpleType %s content\n",
- node->name);
- return (-1);
- } else if (ret == 0) {
- ctxt->err = XML_SCHEMAS_ERR_NOTSIMPLE;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Element %s content is not a simple type\n",
- node->name);
- return (-1);
- }
- ctxt->type = type->subtypes;
- xmlSchemaValidateContent(ctxt, node);
- ctxt->type = type;
- return (ret);
-}
-#endif
-
-/**
- * xmlSchemaValidateSimpleType:
- * @ctxt: a schema validation context
- * @node: the top node.
- *
- * Validate the content of an simple type.
- *
- * Returns 0 if the element is schemas valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateSimpleType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node) {
- xmlNodePtr child;
- xmlSchemaTypePtr type;
- xmlAttrPtr attr;
- int ret;
-
- child = ctxt->node;
- type = ctxt->type;
-
- if ((ctxt == NULL) || (type == NULL)) {
- ctxt->err = XML_SCHEMAS_ERR_INTERNAL;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Internal error: xmlSchemaValidateSimpleType %s\n",
- node->name);
- return(-1);
- }
- /*
- * Only text and text based entities references shall be found there
- */
- ret = xmlSchemaValidateCheckNodeList(child);
- if (ret < 0) {
- ctxt->err = XML_SCHEMAS_ERR_INTERNAL;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Internal error: xmlSchemaValidateSimpleType %s content\n",
- node->name);
- return(-1);
- } else if (ret == 0) {
- ctxt->err = XML_SCHEMAS_ERR_NOTSIMPLE;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Element %s content is not a simple type\n",
- node->name);
- return(-1);
- }
- /*
- * Validation Rule: Element Locally Valid (Type): 3.1.1
- */
- attr = node->properties;
- while (attr != NULL) {
- if ((attr->ns == NULL) ||
- (!xmlStrEqual(attr->ns->href, xmlSchemaInstanceNs)) ||
- ((!xmlStrEqual(attr->name, BAD_CAST"type")) &&
- (!xmlStrEqual(attr->name, BAD_CAST"nil")) &&
- (!xmlStrEqual(attr->name, BAD_CAST"schemasLocation")) &&
- (!xmlStrEqual(attr->name, BAD_CAST"noNamespaceSchemaLocation")))) {
- ctxt->err = XML_SCHEMAS_ERR_INVALIDATTR;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Element %s: attribute %s should not be present\n",
- child->name, attr->name);
- return(ctxt->err);
- }
- }
-
- ctxt->type = type->subtypes;
- ret = xmlSchemaValidateSimpleContent(ctxt, node);
- ctxt->type = type;
- return(ret);
-}
-
-/**
- * xmlSchemaValidateElementType:
- * @ctxt: a schema validation context
- * @node: the top node.
- *
- * Validate the content of an element type.
- * Validation Rule: Element Locally Valid (Complex Type)
- *
- * Returns 0 if the element is schemas valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateElementType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node) {
- xmlNodePtr child;
- xmlSchemaTypePtr type;
- xmlRegExecCtxtPtr oldregexp; /* cont model of the parent */
- xmlSchemaElementPtr decl;
- int ret, attrBase;
-
- oldregexp = ctxt->regexp;
-
- child = ctxt->node;
- type = ctxt->type;
-
- if ((ctxt == NULL) || (type == NULL)) {
- ctxt->err = XML_SCHEMAS_ERR_INTERNAL;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Internal error: xmlSchemaValidateElementType\n",
- node->name);
- return(-1);
- }
- if (child == NULL) {
- if (type->minOccurs > 0) {
- ctxt->err = XML_SCHEMAS_ERR_MISSING;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Element %s: missing child %s\n",
- node->name, type->name);
- }
- return(ctxt->err);
- }
-
- /*
- * Verify the element matches
- */
- if (!xmlStrEqual(child->name, type->name)) {
- ctxt->err = XML_SCHEMAS_ERR_WRONGELEM;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Element %s: missing child %s found %s\n",
- node->name, type->name, child->name);
- return(ctxt->err);
- }
- /*
- * Verify the attributes
- */
- attrBase = ctxt->attrBase;
- ctxt->attrBase = ctxt->attrNr;
- xmlSchemaRegisterAttributes(ctxt, child->properties);
- xmlSchemaValidateAttributes(ctxt, child, type->attributes);
- /*
- * Verify the element content recursively
- */
- decl = (xmlSchemaElementPtr) type;
- oldregexp = ctxt->regexp;
- if (decl->contModel != NULL) {
- ctxt->regexp = xmlRegNewExecCtxt(decl->contModel,
- (xmlRegExecCallbacks) xmlSchemaValidateCallback,
- ctxt);
-#ifdef DEBUG_AUTOMATA
- xmlGenericError(xmlGenericErrorContext,
- "====> %s\n", node->name);
-#endif
- }
- xmlSchemaValidateType(ctxt, child, (xmlSchemaElementPtr)type,
- type->subtypes);
-
- if (decl->contModel != NULL) {
- ret = xmlRegExecPushString(ctxt->regexp, NULL, NULL);
-#ifdef DEBUG_AUTOMATA
- xmlGenericError(xmlGenericErrorContext,
- "====> %s : %d\n", node->name, ret);
-#endif
- if (ret == 0) {
- ctxt->err = XML_SCHEMAS_ERR_ELEMCONT;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData, "Element %s content check failed\n",
- node->name);
- } else if (ret < 0) {
- ctxt->err = XML_SCHEMAS_ERR_ELEMCONT;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData, "Element %s content check failure\n",
- node->name);
-#ifdef DEBUG_CONTENT
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "Element %s content check succeeded\n", node->name);
-
-#endif
- }
- xmlRegFreeExecCtxt(ctxt->regexp);
- }
- /*
- * Verify that all attributes were Schemas-validated
- */
- xmlSchemaCheckAttributes(ctxt, node);
- ctxt->attrNr = ctxt->attrBase;
- ctxt->attrBase = attrBase;
-
- ctxt->regexp = oldregexp;
-
- ctxt->node = child;
- ctxt->type = type;
- return(ctxt->err);
-}
-
-/**
- * xmlSchemaValidateBasicType:
- * @ctxt: a schema validation context
- * @node: the top node.
- *
- * Validate the content of an element expected to be a basic type type
- *
- * Returns 0 if the element is schemas valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateBasicType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node) {
- int ret;
- xmlNodePtr child, cur;
- xmlSchemaTypePtr type;
- xmlChar *value; /* lexical representation */
-
- child = ctxt->node;
- type = ctxt->type;
-
- if ((ctxt == NULL) || (type == NULL)) {
- ctxt->err = XML_SCHEMAS_ERR_INTERNAL;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Internal error: xmlSchemaValidateBasicType\n",
- node->name);
- return(-1);
- }
- /*
- * First check the content model of the node.
- */
- cur = child;
- while (cur != NULL) {
- switch (cur->type) {
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- break;
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- TODO
- break;
- case XML_ELEMENT_NODE:
- ctxt->err = XML_SCHEMAS_ERR_INVALIDELEM;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Element %s: child %s should not be present\n",
- node->name, cur->name);
- return(ctxt->err);
- case XML_ATTRIBUTE_NODE:
- case XML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_NOTATION_NODE:
- case XML_HTML_DOCUMENT_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_NAMESPACE_DECL:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- ctxt->err = XML_SCHEMAS_ERR_INVALIDELEM;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Element %s: node type %d unexpected here\n",
- node->name, cur->type);
- return(ctxt->err);
- }
- cur = cur->next;
- }
- if (child == NULL)
- value = NULL;
- else
- value = xmlNodeGetContent(child->parent);
-
- if (ctxt->value != NULL) {
- xmlSchemaFreeValue(ctxt->value);
- ctxt->value = NULL;
- }
- ret = xmlSchemaValidatePredefinedType(type, value, &(ctxt->value));
- if (value != NULL)
- xmlFree(value);
- if (ret != 0) {
- ctxt->error(ctxt->userData,
- "Element %s: failed to validate basic type %s\n",
- node->name, type->name);
- }
- return(ret);
-}
-
-/**
- * xmlSchemaValidateComplexType:
- * @ctxt: a schema validation context
- * @node: the top node.
- *
- * Validate the content of an element expected to be a complex type type
- * xmlschema-1.html#cvc-complex-type
- * Validation Rule: Element Locally Valid (Complex Type)
- *
- * Returns 0 if the element is schemas valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateComplexType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node) {
- xmlNodePtr child;
- xmlSchemaTypePtr type, subtype;
- int ret;
-
- child = ctxt->node;
- type = ctxt->type;
-
- switch (type->contentType) {
- case XML_SCHEMA_CONTENT_EMPTY:
- if (child != NULL) {
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Element %s is supposed to be empty\n",
- node->name);
- }
- if (type->attributes != NULL) {
- xmlSchemaValidateAttributes(ctxt, node, type->attributes);
- }
- subtype = type->subtypes;
- while (subtype != NULL) {
- ctxt->type = subtype;
- xmlSchemaValidateComplexType(ctxt, node);
- subtype = subtype->next;
- }
- break;
- case XML_SCHEMA_CONTENT_ELEMENTS:
- case XML_SCHEMA_CONTENT_MIXED:
- case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
- /*
- * Skip ignorable nodes in that context
- */
- child = xmlSchemaSkipIgnored(ctxt, type, child);
- while (child != NULL) {
- if (child->type == XML_ELEMENT_NODE) {
- ret = xmlRegExecPushString(ctxt->regexp,
- child->name, child);
-#ifdef DEBUG_AUTOMATA
- if (ret < 0)
- xmlGenericError(xmlGenericErrorContext,
- " --> %s Error\n", child->name);
- else
- xmlGenericError(xmlGenericErrorContext,
- " --> %s\n", child->name);
-#endif
- }
- child = child->next;
- /*
- * Skip ignorable nodes in that context
- */
- child = xmlSchemaSkipIgnored(ctxt, type, child);
- }
- break;
- case XML_SCHEMA_CONTENT_BASIC: {
- if (type->subtypes != NULL) {
- ctxt->type = type->subtypes;
- xmlSchemaValidateComplexType(ctxt, node);
- }
- if (type->baseType != NULL) {
- ctxt->type = type->baseType;
- xmlSchemaValidateBasicType(ctxt, node);
- }
- if (type->attributes != NULL) {
- xmlSchemaValidateAttributes(ctxt, node, type->attributes);
- }
- ctxt->type = type;
- break;
- }
- default:
- TODO
- xmlGenericError(xmlGenericErrorContext,
- "unimplemented content type %d\n",
- type->contentType);
- }
- return(ctxt->err);
-}
-
-/**
- * xmlSchemaValidateContent:
- * @ctxt: a schema validation context
- * @elem: an element
- * @type: the type declaration
- *
- * Validate the content of an element against the type.
- *
- * Returns 0 if the element is schemas valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateContent(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node) {
- xmlNodePtr child;
- xmlSchemaTypePtr type;
-
- child = ctxt->node;
- type = ctxt->type;
-
- xmlSchemaValidateAttributes(ctxt, node, type->attributes);
-
- switch (type->type) {
- case XML_SCHEMA_TYPE_ANY:
- /* Any type will do it, fine */
- TODO /* handle recursivity */
- break;
- case XML_SCHEMA_TYPE_COMPLEX:
- xmlSchemaValidateComplexType(ctxt, node);
- break;
- case XML_SCHEMA_TYPE_ELEMENT: {
- xmlSchemaElementPtr decl = (xmlSchemaElementPtr) type;
- /*
- * Handle element reference here
- */
- if (decl->ref != NULL) {
- if (decl->refDecl == NULL) {
- ctxt->err = XML_SCHEMAS_ERR_INTERNAL;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Internal error: element reference %s not resolved\n",
- decl->ref);
- return(-1);
- }
- ctxt->type = (xmlSchemaTypePtr) decl->refDecl;
- decl = decl->refDecl;
- }
- xmlSchemaValidateElementType(ctxt, node);
- ctxt->type = type;
- break;
- }
- case XML_SCHEMA_TYPE_BASIC:
- xmlSchemaValidateBasicType(ctxt, node);
- break;
- case XML_SCHEMA_TYPE_FACET:
- TODO
- break;
- case XML_SCHEMA_TYPE_SIMPLE:
- xmlSchemaValidateSimpleType(ctxt, node);
- break;
- case XML_SCHEMA_TYPE_SEQUENCE:
- TODO
- break;
- case XML_SCHEMA_TYPE_CHOICE:
- TODO
- break;
- case XML_SCHEMA_TYPE_ALL:
- TODO
- break;
- case XML_SCHEMA_TYPE_SIMPLE_CONTENT:
- TODO
- break;
- case XML_SCHEMA_TYPE_COMPLEX_CONTENT:
- TODO
- break;
- case XML_SCHEMA_TYPE_UR:
- TODO
- break;
- case XML_SCHEMA_TYPE_RESTRICTION:
- /*xmlSchemaValidateRestrictionType(ctxt, node); */
- TODO
- break;
- case XML_SCHEMA_TYPE_EXTENSION:
- TODO
- break;
- case XML_SCHEMA_TYPE_ATTRIBUTE:
- TODO
- break;
- case XML_SCHEMA_TYPE_GROUP:
- TODO
- break;
- case XML_SCHEMA_TYPE_NOTATION:
- TODO
- break;
- case XML_SCHEMA_TYPE_LIST:
- TODO
- break;
- case XML_SCHEMA_TYPE_UNION:
- TODO
- break;
- case XML_SCHEMA_FACET_MININCLUSIVE:
- TODO
- break;
- case XML_SCHEMA_FACET_MINEXCLUSIVE:
- TODO
- break;
- case XML_SCHEMA_FACET_MAXINCLUSIVE:
- TODO
- break;
- case XML_SCHEMA_FACET_MAXEXCLUSIVE:
- TODO
- break;
- case XML_SCHEMA_FACET_TOTALDIGITS:
- TODO
- break;
- case XML_SCHEMA_FACET_FRACTIONDIGITS:
- TODO
- break;
- case XML_SCHEMA_FACET_PATTERN:
- TODO
- break;
- case XML_SCHEMA_FACET_ENUMERATION:
- TODO
- break;
- case XML_SCHEMA_FACET_WHITESPACE:
- TODO
- break;
- case XML_SCHEMA_FACET_LENGTH:
- TODO
- break;
- case XML_SCHEMA_FACET_MAXLENGTH:
- TODO
- break;
- case XML_SCHEMA_FACET_MINLENGTH:
- TODO
- break;
- case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
- TODO
- break;
- }
- xmlSchemaValidateAttributes(ctxt, node, type->attributes);
-
- if (ctxt->node == NULL)
- return(ctxt->err);
- ctxt->node = ctxt->node->next;
- ctxt->type = type->next;
- return(ctxt->err);
-}
-
-/**
- * xmlSchemaValidateType:
- * @ctxt: a schema validation context
- * @elem: an element
- * @type: the list of type declarations
- *
- * Validate the content of an element against the types.
- *
- * Returns 0 if the element is schemas valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem,
- xmlSchemaElementPtr elemDecl,
- xmlSchemaTypePtr type) {
- xmlChar *nil;
-
- if ((elem->content == NULL) || (type == NULL) || (elemDecl == NULL))
- return(0);
- /*
- * 3.3.4 : 2
- */
- if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
- ctxt->err = XML_SCHEMAS_ERR_ISABSTRACT;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData, "Element %s is abstract\n", elem->name);
- return(ctxt->err);
- }
- /*
- * 3.3.4: 3
- */
- nil = xmlGetNsProp(elem, BAD_CAST "nil", xmlSchemaInstanceNs);
- if (elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) {
- /* 3.3.4: 3.2 */
- if (xmlStrEqual(nil, BAD_CAST "true")) {
- if (elem->children != NULL) {
- ctxt->err = XML_SCHEMAS_ERR_NOTEMPTY;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData, "Element %s is not empty\n",
- elem->name);
- return(ctxt->err);
- }
- if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
- (elemDecl->value != NULL)) {
- ctxt->err = XML_SCHEMAS_ERR_HAVEDEFAULT;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Empty element %s cannot get a fixed value\n",
- elem->name);
- return(ctxt->err);
- }
- }
- } else {
- /* 3.3.4: 3.1 */
- if (nil != NULL) {
- ctxt->err = XML_SCHEMAS_ERR_NOTNILLABLE;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Element %s with xs:nil but not nillable\n",
- elem->name);
- xmlFree(nil);
- return(ctxt->err);
- }
- }
-
- /* TODO 3.3.4: 4 if the element carries xs:type*/
-
- ctxt->type = elemDecl->subtypes;
- ctxt->node = elem->children;
- xmlSchemaValidateContent(ctxt, elem);
- xmlSchemaValidateAttributes(ctxt, elem, elemDecl->attributes);
-
- return(ctxt->err);
-}
-
-
-/**
- * xmlSchemaValidateAttributes:
- * @ctxt: a schema validation context
- * @elem: an element
- * @attributes: the list of attribute declarations
- *
- * Validate the attributes of an element.
- *
- * Returns 0 if the element is schemas valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem,
- xmlSchemaAttributePtr attributes) {
- int i, ret;
- xmlAttrPtr attr;
- xmlChar *value;
- xmlSchemaAttributeGroupPtr group = NULL;
-
- if (attributes == NULL)
- return(0);
- while (attributes != NULL) {
- /*
- * Handle attribute groups
- */
- if (attributes->type == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
- group = (xmlSchemaAttributeGroupPtr) attributes;
- xmlSchemaValidateAttributes(ctxt, elem, group->attributes);
- attributes = group->next;
- continue;
- }
- for (i = ctxt->attrBase;i < ctxt->attrNr;i++) {
- attr = ctxt->attr[i].attr;
- if (attr == NULL)
- continue;
- if (!xmlStrEqual(attr->name, attributes->name))
- continue;
- /*
- * TODO: handle the mess about namespaces here.
- */
- if ((attr->ns != NULL) /* || (attributes->ns != NULL) */) {
- TODO
- }
- if (attributes->subtypes == NULL) {
- ctxt->err = XML_SCHEMAS_ERR_INTERNAL;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "Internal error: attribute %s type not resolved\n",
- attr->name);
- continue;
- }
- value = xmlNodeListGetString(elem->doc, attr->children, 1);
- ret = xmlSchemaValidateSimpleValue(ctxt, attributes->subtypes,
- value);
- if (ret != 0) {
- ctxt->err = XML_SCHEMAS_ERR_ATTRINVALID;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData,
- "attribute %s on %s does not match type\n",
- attr->name, elem->name);
- } else {
- ctxt->attr[i].state = XML_SCHEMAS_ATTR_CHECKED;
- }
- if (value != NULL) {
- xmlFree(value);
- }
- }
- attributes = attributes->next;
- }
- return(ctxt->err);
-}
-
-/**
- * xmlSchemaValidateElement:
- * @ctxt: a schema validation context
- * @elem: an element
- *
- * Validate an element in a tree
- *
- * Returns 0 if the element is schemas valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem) {
- xmlSchemaElementPtr elemDecl;
- int ret, attrBase;
-
- if (elem->ns != NULL)
- elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
- elem->name, elem->ns->href, NULL);
- else
- elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
- elem->name, NULL, NULL);
- /*
- * 3.3.4 : 1
- */
- if (elemDecl == NULL) {
- ctxt->err = XML_SCHEMAS_ERR_UNDECLAREDELEM;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData, "Element %s not declared\n",
- elem->name);
- return(ctxt->err);
- }
- if (elemDecl->subtypes == NULL) {
- ctxt->err = XML_SCHEMAS_ERR_NOTYPE;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData, "Element %s has no type\n",
- elem->name);
- return(ctxt->err);
- }
- /*
- * Verify the attributes
- */
- attrBase = ctxt->attrBase;
- ctxt->attrBase = ctxt->attrNr;
- xmlSchemaRegisterAttributes(ctxt, elem->properties);
- xmlSchemaValidateAttributes(ctxt, elem, elemDecl->attributes);
- /*
- * Verify the element content recursively
- */
- if (elemDecl->contModel != NULL) {
- ctxt->regexp = xmlRegNewExecCtxt(elemDecl->contModel,
- (xmlRegExecCallbacks) xmlSchemaValidateCallback,
- ctxt);
-#ifdef DEBUG_AUTOMATA
- xmlGenericError(xmlGenericErrorContext,
- "====> %s\n", elem->name);
-#endif
- }
- xmlSchemaValidateType(ctxt, elem, elemDecl, elemDecl->subtypes);
- if (elemDecl->contModel != NULL) {
- ret = xmlRegExecPushString(ctxt->regexp, NULL, NULL);
-#ifdef DEBUG_AUTOMATA
- xmlGenericError(xmlGenericErrorContext,
- "====> %s : %d\n", elem->name, ret);
-#endif
- if (ret == 0) {
- ctxt->err = XML_SCHEMAS_ERR_ELEMCONT;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData, "Element %s content check failed\n",
- elem->name);
- } else if (ret < 0) {
- ctxt->err = XML_SCHEMAS_ERR_ELEMCONT;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData, "Element %s content check failed\n",
- elem->name);
-#ifdef DEBUG_CONTENT
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "Element %s content check succeeded\n", elem->name);
-
-#endif
- }
- xmlRegFreeExecCtxt(ctxt->regexp);
- }
- /*
- * Verify that all attributes were Schemas-validated
- */
- xmlSchemaCheckAttributes(ctxt, elem);
- ctxt->attrNr = ctxt->attrBase;
- ctxt->attrBase = attrBase;
-
- return(ctxt->err);
-}
-
-/**
- * xmlSchemaValidateDocument:
- * @ctxt: a schema validation context
- * @doc: a parsed document tree
- *
- * Validate a document tree in memory.
- *
- * Returns 0 if the document is schemas valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateDocument(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc) {
- xmlNodePtr root;
- xmlSchemaElementPtr elemDecl;
-
- root = xmlDocGetRootElement(doc);
- if (root == NULL) {
- ctxt->err = XML_SCHEMAS_ERR_NOROOT;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData, "document has no root\n");
- return(ctxt->err);
- }
- if (root->ns != NULL)
- elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
- root->name, root->ns->href, NULL);
- else
- elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
- root->name, NULL, NULL);
- if (elemDecl == NULL) {
- ctxt->err = XML_SCHEMAS_ERR_UNDECLAREDELEM;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData, "Element %s not declared\n",
- root->name);
- } else if ((elemDecl->flags & XML_SCHEMAS_ELEM_TOPLEVEL) == 0) {
- ctxt->err = XML_SCHEMAS_ERR_NOTTOPLEVEL;
- if (ctxt->error != NULL)
- ctxt->error(ctxt->userData, "Root element %s not toplevel\n",
- root->name);
- }
- /*
- * Okay, start the recursive validation
- */
- xmlSchemaValidateElement(ctxt, root);
-
- return(ctxt->err);
-}
-
-/************************************************************************
- * *
- * SAX Validation code *
- * *
- ************************************************************************/
-
-/************************************************************************
- * *
- * Validation interfaces *
- * *
- ************************************************************************/
-
-/**
- * xmlSchemaNewValidCtxt:
- * @schema: a precompiled XML Schemas
- *
- * Create an XML Schemas validation context based on the given schema
- *
- * Returns the validation context or NULL in case of error
- */
-xmlSchemaValidCtxtPtr
-xmlSchemaNewValidCtxt(xmlSchemaPtr schema) {
- xmlSchemaValidCtxtPtr ret;
-
- ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Failed to allocate new schama validation context\n");
- return (NULL);
- }
- memset(ret, 0, sizeof(xmlSchemaValidCtxt));
- ret->schema = schema;
- ret->attrNr = 0;
- ret->attrMax = 10;
- ret->attr = (xmlSchemaAttrStatePtr) xmlMalloc(ret->attrMax *
- sizeof(xmlSchemaAttrState));
- if (ret->attr == NULL) {
- free(ret);
- return(NULL);
- }
- memset(ret->attr, 0, ret->attrMax * sizeof(xmlSchemaAttrState));
- return (ret);
-}
-
-/**
- * xmlSchemaFreeValidCtxt:
- * @ctxt: the schema validation context
- *
- * Free the resources associated to the schema validation context
- */
-void
-xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt) {
- if (ctxt == NULL)
- return;
- if (ctxt->attr != NULL)
- xmlFree(ctxt->attr);
- if (ctxt->value != NULL)
- xmlSchemaFreeValue(ctxt->value);
- xmlFree(ctxt);
-}
-
-/**
- * xmlSchemaSetValidErrors:
- * @ctxt: a schema validation context
- * @err: the error function
- * @warn: the warning function
- * @ctx: the functions context
- *
- * Set the error and warning callback informations
- */
-void
-xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
- xmlSchemaValidityErrorFunc err,
- xmlSchemaValidityWarningFunc warn, void *ctx) {
- if (ctxt == NULL)
- return;
- ctxt->error = err;
- ctxt->warning = warn;
- ctxt->userData = ctx;
-}
-
-/**
- * xmlSchemaValidateDoc:
- * @ctxt: a schema validation context
- * @doc: a parsed document tree
- *
- * Validate a document tree in memory.
- *
- * Returns 0 if the document is schemas valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-int
-xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc) {
- int ret;
-
- if ((ctxt == NULL) || (doc == NULL))
- return(-1);
-
- ctxt->doc = doc;
- ret = xmlSchemaValidateDocument(ctxt, doc);
- return(ret);
-}
-
-/**
- * xmlSchemaValidateStream:
- * @ctxt: a schema validation context
- * @input: the input to use for reading the data
- * @enc: an optional encoding information
- * @sax: a SAX handler for the resulting events
- * @user_data: the context to provide to the SAX handler.
- *
- * Validate a document tree in memory.
- *
- * Returns 0 if the document is schemas valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-int
-xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
- xmlParserInputBufferPtr input, xmlCharEncoding enc,
- xmlSAXHandlerPtr sax, void *user_data) {
- if ((ctxt == NULL) || (input == NULL))
- return(-1);
- ctxt->input = input;
- ctxt->enc = enc;
- ctxt->sax = sax;
- ctxt->user_data = user_data;
- TODO
- return(0);
-}
-
-#endif /* LIBXML_SCHEMAS_ENABLED */
diff --git a/bundle/libxml/xmlschemastypes.c b/bundle/libxml/xmlschemastypes.c
deleted file mode 100644
index 1be67c8622..0000000000
--- a/bundle/libxml/xmlschemastypes.c
+++ /dev/null
@@ -1,1880 +0,0 @@
-/*
- * schemastypes.c : implementation of the XML Schema Datatypes
- * definition and validity checking
- *
- * See Copyright for the status of this software.
- *
- * Daniel Veillard <veillard@redhat.com>
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#ifdef LIBXML_SCHEMAS_ENABLED
-
-#include <string.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-#include <libxml/parserInternals.h>
-#include <libxml/hash.h>
-#include <libxml/valid.h>
-
-#include <libxml/xmlschemas.h>
-#include <libxml/schemasInternals.h>
-#include <libxml/xmlschemastypes.h>
-
-#ifdef HAVE_MATH_H
-#include <math.h>
-#endif
-
-#define DEBUG
-
-#define TODO \
- xmlGenericError(xmlGenericErrorContext, \
- "Unimplemented block at %s:%d\n", \
- __FILE__, __LINE__);
-
-#define XML_SCHEMAS_NAMESPACE_NAME \
- (const xmlChar *)"http://www.w3.org/2001/XMLSchema"
-
-typedef enum {
- XML_SCHEMAS_UNKNOWN = 0,
- XML_SCHEMAS_STRING,
- XML_SCHEMAS_NMTOKEN,
- XML_SCHEMAS_DECIMAL,
- XML_SCHEMAS_TIME,
- XML_SCHEMAS_GDAY,
- XML_SCHEMAS_GMONTH,
- XML_SCHEMAS_GMONTHDAY,
- XML_SCHEMAS_GYEAR,
- XML_SCHEMAS_GYEARMONTH,
- XML_SCHEMAS_DATE,
- XML_SCHEMAS_DATETIME,
- XML_SCHEMAS_DURATION,
- XML_SCHEMAS_FLOAT,
- XML_SCHEMAS_DOUBLE,
- XML_SCHEMAS_,
- XML_SCHEMAS_XXX
-} xmlSchemaValType;
-
-unsigned long powten[10] = {
- 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000L,
- 100000000L, 1000000000L
-};
-
-/* Date value */
-typedef struct _xmlSchemaValDate xmlSchemaValDate;
-typedef xmlSchemaValDate *xmlSchemaValDatePtr;
-struct _xmlSchemaValDate {
- long year;
- unsigned int mon :4; /* 1 <= mon <= 12 */
- unsigned int day :5; /* 1 <= day <= 31 */
- unsigned int hour :5; /* 0 <= hour <= 23 */
- unsigned int min :6; /* 0 <= min <= 59 */
- double sec;
- int tz_flag :1; /* is tzo explicitely set? */
- int tzo :11; /* -1440 <= tzo <= 1440 */
-};
-
-/* Duration value */
-typedef struct _xmlSchemaValDuration xmlSchemaValDuration;
-typedef xmlSchemaValDuration *xmlSchemaValDurationPtr;
-struct _xmlSchemaValDuration {
- long mon; /* mon stores years also */
- long day;
- double sec; /* sec stores min and hour also */
-};
-
-typedef struct _xmlSchemaValDecimal xmlSchemaValDecimal;
-typedef xmlSchemaValDecimal *xmlSchemaValDecimalPtr;
-struct _xmlSchemaValDecimal {
- /* would use long long but not portable */
- unsigned long base;
- unsigned int extra;
- unsigned int sign:1;
- int frac:7;
- int total:8;
-};
-
-struct _xmlSchemaVal {
- xmlSchemaValType type;
- union {
- xmlSchemaValDecimal decimal;
- xmlSchemaValDate date;
- xmlSchemaValDuration dur;
- float f;
- double d;
- } value;
-};
-
-static int xmlSchemaTypesInitialized = 0;
-static xmlHashTablePtr xmlSchemaTypesBank = NULL;
-
-static xmlSchemaTypePtr xmlSchemaTypeStringDef = NULL;
-static xmlSchemaTypePtr xmlSchemaTypeAnyTypeDef = NULL;
-static xmlSchemaTypePtr xmlSchemaTypeAnySimpleTypeDef = NULL;
-static xmlSchemaTypePtr xmlSchemaTypeDecimalDef = NULL;
-static xmlSchemaTypePtr xmlSchemaTypeDatetimeDef = NULL;
-static xmlSchemaTypePtr xmlSchemaTypeDateDef = NULL;
-static xmlSchemaTypePtr xmlSchemaTypeTimeDef = NULL;
-static xmlSchemaTypePtr xmlSchemaTypeGYearDef = NULL;
-static xmlSchemaTypePtr xmlSchemaTypeGYearMonthDef = NULL;
-static xmlSchemaTypePtr xmlSchemaTypeGDayDef = NULL;
-static xmlSchemaTypePtr xmlSchemaTypeGMonthDayDef = NULL;
-static xmlSchemaTypePtr xmlSchemaTypeGMonthDef = NULL;
-static xmlSchemaTypePtr xmlSchemaTypeDurationDef = NULL;
-static xmlSchemaTypePtr xmlSchemaTypePositiveIntegerDef = NULL;
-static xmlSchemaTypePtr xmlSchemaTypeNonNegativeIntegerDef = NULL;
-static xmlSchemaTypePtr xmlSchemaTypeNmtoken = NULL;
-static xmlSchemaTypePtr xmlSchemaTypeFloatDef = NULL;
-static xmlSchemaTypePtr xmlSchemaTypeDoubleDef = NULL;
-
-/*
- * xmlSchemaInitBasicType:
- * @name: the type name
- *
- * Initialize one default type
- */
-static xmlSchemaTypePtr
-xmlSchemaInitBasicType(const char *name) {
- xmlSchemaTypePtr ret;
-
- ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "Could not initilize type %s: out of memory\n", name);
- return(NULL);
- }
- memset(ret, 0, sizeof(xmlSchemaType));
- ret->name = xmlStrdup((const xmlChar *)name);
- ret->type = XML_SCHEMA_TYPE_BASIC;
- ret->contentType = XML_SCHEMA_CONTENT_BASIC;
- xmlHashAddEntry2(xmlSchemaTypesBank, ret->name,
- XML_SCHEMAS_NAMESPACE_NAME, ret);
- return(ret);
-}
-
-/*
- * xmlSchemaInitTypes:
- *
- * Initialize the default XML Schemas type library
- */
-void
-xmlSchemaInitTypes(void) {
- if (xmlSchemaTypesInitialized != 0)
- return;
- xmlSchemaTypesBank = xmlHashCreate(40);
-
- xmlSchemaTypeStringDef = xmlSchemaInitBasicType("string");
- xmlSchemaTypeAnyTypeDef = xmlSchemaInitBasicType("anyType");
- xmlSchemaTypeAnySimpleTypeDef = xmlSchemaInitBasicType("anySimpleType");
- xmlSchemaTypeDecimalDef = xmlSchemaInitBasicType("decimal");
- xmlSchemaTypeDateDef = xmlSchemaInitBasicType("date");
- xmlSchemaTypeDatetimeDef = xmlSchemaInitBasicType("dateTime");
- xmlSchemaTypeTimeDef = xmlSchemaInitBasicType("time");
- xmlSchemaTypeGYearDef = xmlSchemaInitBasicType("gYear");
- xmlSchemaTypeGYearMonthDef = xmlSchemaInitBasicType("gYearMonth");
- xmlSchemaTypeGMonthDef = xmlSchemaInitBasicType("gMonth");
- xmlSchemaTypeGMonthDayDef = xmlSchemaInitBasicType("gMonthDay");
- xmlSchemaTypeGDayDef = xmlSchemaInitBasicType("gDay");
- xmlSchemaTypeDurationDef = xmlSchemaInitBasicType("duration");
- xmlSchemaTypePositiveIntegerDef = xmlSchemaInitBasicType("positiveInteger");
- xmlSchemaTypeNonNegativeIntegerDef =
- xmlSchemaInitBasicType("nonNegativeInteger");
- xmlSchemaTypeNmtoken = xmlSchemaInitBasicType("NMTOKEN");
- xmlSchemaTypeFloatDef = xmlSchemaInitBasicType("float");
- xmlSchemaTypeDoubleDef = xmlSchemaInitBasicType("double");
-
- xmlSchemaTypesInitialized = 1;
-}
-
-/**
- * xmlSchemaCleanupTypes:
- *
- * Cleanup the default XML Schemas type library
- */
-void
-xmlSchemaCleanupTypes(void) {
- if (xmlSchemaTypesInitialized == 0)
- return;
- xmlHashFree(xmlSchemaTypesBank, (xmlHashDeallocator) xmlSchemaFreeType);
- xmlSchemaTypesInitialized = 0;
-}
-
-/**
- * xmlSchemaNewValue:
- * @type: the value type
- *
- * Allocate a new simple type value
- *
- * Returns a pointer to the new value or NULL in case of error
- */
-static xmlSchemaValPtr
-xmlSchemaNewValue(xmlSchemaValType type) {
- xmlSchemaValPtr value;
-
- value = (xmlSchemaValPtr) xmlMalloc(sizeof(xmlSchemaVal));
- if (value == NULL) {
- return(NULL);
- }
- memset(value, 0, sizeof(xmlSchemaVal));
- value->type = type;
- return(value);
-}
-
-/**
- * xmlSchemaFreeValue:
- * @value: the value to free
- *
- * Cleanup the default XML Schemas type library
- */
-void
-xmlSchemaFreeValue(xmlSchemaValPtr value) {
- if (value == NULL)
- return;
- xmlFree(value);
-}
-
-/**
- * xmlSchemaGetPredefinedType:
- * @name: the type name
- * @ns: the URI of the namespace usually "http://www.w3.org/2001/XMLSchema"
- *
- * Lookup a type in the default XML Schemas type library
- *
- * Returns the type if found, NULL otherwise
- */
-xmlSchemaTypePtr
-xmlSchemaGetPredefinedType(const xmlChar *name, const xmlChar *ns) {
- if (xmlSchemaTypesInitialized == 0)
- xmlSchemaInitTypes();
- if (name == NULL)
- return(NULL);
- return((xmlSchemaTypePtr) xmlHashLookup2(xmlSchemaTypesBank, name, ns));
-}
-
-/****************************************************************
- * *
- * Convenience macros and functions *
- * *
- ****************************************************************/
-
-#define IS_TZO_CHAR(c) \
- ((c == 0) || (c == 'Z') || (c == '+') || (c == '-'))
-
-#define VALID_YEAR(yr) (yr != 0)
-#define VALID_MONTH(mon) ((mon >= 1) && (mon <= 12))
-/* VALID_DAY should only be used when month is unknown */
-#define VALID_DAY(day) ((day >= 1) && (day <= 31))
-#define VALID_HOUR(hr) ((hr >= 0) && (hr <= 23))
-#define VALID_MIN(min) ((min >= 0) && (min <= 59))
-#define VALID_SEC(sec) ((sec >= 0) && (sec < 60))
-#define VALID_TZO(tzo) ((tzo > -1440) && (tzo < 1440))
-#define IS_LEAP(y) \
- (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0))
-
-static const long daysInMonth[12] =
- { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-static const long daysInMonthLeap[12] =
- { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-
-#define MAX_DAYINMONTH(yr,mon) \
- (IS_LEAP(yr) ? daysInMonthLeap[mon - 1] : daysInMonth[mon - 1])
-
-#define VALID_MDAY(dt) \
- (IS_LEAP(dt->year) ? \
- (dt->day <= daysInMonthLeap[dt->mon - 1]) : \
- (dt->day <= daysInMonth[dt->mon - 1]))
-
-#define VALID_DATE(dt) \
- (VALID_YEAR(dt->year) && VALID_MONTH(dt->mon) && VALID_MDAY(dt))
-
-#define VALID_TIME(dt) \
- (VALID_HOUR(dt->hour) && VALID_MIN(dt->min) && \
- VALID_SEC(dt->sec) && VALID_TZO(dt->tzo))
-
-#define VALID_DATETIME(dt) \
- (VALID_DATE(dt) && VALID_TIME(dt))
-
-#define SECS_PER_MIN (60)
-#define SECS_PER_HOUR (60 * SECS_PER_MIN)
-#define SECS_PER_DAY (24 * SECS_PER_HOUR)
-
-static const long dayInYearByMonth[12] =
- { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
-static const long dayInLeapYearByMonth[12] =
- { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
-
-#define DAY_IN_YEAR(day, month, year) \
- ((IS_LEAP(year) ? \
- dayInLeapYearByMonth[month - 1] : \
- dayInYearByMonth[month - 1]) + day)
-
-#ifdef DEBUG
-#define DEBUG_DATE(dt) \
- xmlGenericError(xmlGenericErrorContext, \
- "type=%o %04ld-%02u-%02uT%02u:%02u:%03f", \
- dt->type,dt->value.date.year,dt->value.date.mon, \
- dt->value.date.day,dt->value.date.hour,dt->value.date.min, \
- dt->value.date.sec); \
- if (dt->value.date.tz_flag) \
- if (dt->value.date.tzo != 0) \
- xmlGenericError(xmlGenericErrorContext, \
- "%+05d\n",dt->value.date.tzo); \
- else \
- xmlGenericError(xmlGenericErrorContext, "Z\n"); \
- else \
- xmlGenericError(xmlGenericErrorContext,"\n")
-#else
-#define DEBUG_DATE(dt)
-#endif
-
-/**
- * _xmlSchemaParseGYear:
- * @dt: pointer to a date structure
- * @str: pointer to the string to analyze
- *
- * Parses a xs:gYear without time zone and fills in the appropriate
- * field of the @dt structure. @str is updated to point just after the
- * xs:gYear. It is supposed that @dt->year is big enough to contain
- * the year.
- *
- * Returns 0 or the error code
- */
-static int
-_xmlSchemaParseGYear (xmlSchemaValDatePtr dt, const xmlChar **str) {
- const xmlChar *cur = *str, *firstChar;
- int isneg = 0, digcnt = 0;
-
- if (((*cur < '0') || (*cur > '9')) &&
- (*cur != '-') && (*cur != '+'))
- return -1;
-
- if (*cur == '-') {
- isneg = 1;
- cur++;
- }
-
- firstChar = cur;
-
- while ((*cur >= '0') && (*cur <= '9')) {
- dt->year = dt->year * 10 + (*cur - '0');
- cur++;
- digcnt++;
- }
-
- /* year must be at least 4 digits (CCYY); over 4
- * digits cannot have a leading zero. */
- if ((digcnt < 4) || ((digcnt > 4) && (*firstChar == '0')))
- return 1;
-
- if (isneg)
- dt->year = - dt->year;
-
- if (!VALID_YEAR(dt->year))
- return 2;
-
- *str = cur;
- return 0;
-}
-
-/**
- * PARSE_2_DIGITS:
- * @num: the integer to fill in
- * @cur: an #xmlChar *
- * @invalid: an integer
- *
- * Parses a 2-digits integer and updates @num with the value. @cur is
- * updated to point just after the integer.
- * In case of error, @invalid is set to %TRUE, values of @num and
- * @cur are undefined.
- */
-#define PARSE_2_DIGITS(num, cur, invalid) \
- if ((cur[0] < '0') || (cur[0] > '9') || \
- (cur[1] < '0') || (cur[1] > '9')) \
- invalid = 1; \
- else \
- num = (cur[0] - '0') * 10 + (cur[1] - '0'); \
- cur += 2;
-
-/**
- * PARSE_FLOAT:
- * @num: the double to fill in
- * @cur: an #xmlChar *
- * @invalid: an integer
- *
- * Parses a float and updates @num with the value. @cur is
- * updated to point just after the float. The float must have a
- * 2-digits integer part and may or may not have a decimal part.
- * In case of error, @invalid is set to %TRUE, values of @num and
- * @cur are undefined.
- */
-#define PARSE_FLOAT(num, cur, invalid) \
- PARSE_2_DIGITS(num, cur, invalid); \
- if (!invalid && (*cur == '.')) { \
- double mult = 1; \
- cur++; \
- if ((*cur < '0') || (*cur > '9')) \
- invalid = 1; \
- while ((*cur >= '0') && (*cur <= '9')) { \
- mult /= 10; \
- num += (*cur - '0') * mult; \
- cur++; \
- } \
- }
-
-/**
- * _xmlSchemaParseGMonth:
- * @dt: pointer to a date structure
- * @str: pointer to the string to analyze
- *
- * Parses a xs:gMonth without time zone and fills in the appropriate
- * field of the @dt structure. @str is updated to point just after the
- * xs:gMonth.
- *
- * Returns 0 or the error code
- */
-static int
-_xmlSchemaParseGMonth (xmlSchemaValDatePtr dt, const xmlChar **str) {
- const xmlChar *cur = *str;
- int ret = 0;
-
- PARSE_2_DIGITS(dt->mon, cur, ret);
- if (ret != 0)
- return ret;
-
- if (!VALID_MONTH(dt->mon))
- return 2;
-
- *str = cur;
- return 0;
-}
-
-/**
- * _xmlSchemaParseGDay:
- * @dt: pointer to a date structure
- * @str: pointer to the string to analyze
- *
- * Parses a xs:gDay without time zone and fills in the appropriate
- * field of the @dt structure. @str is updated to point just after the
- * xs:gDay.
- *
- * Returns 0 or the error code
- */
-static int
-_xmlSchemaParseGDay (xmlSchemaValDatePtr dt, const xmlChar **str) {
- const xmlChar *cur = *str;
- int ret = 0;
-
- PARSE_2_DIGITS(dt->day, cur, ret);
- if (ret != 0)
- return ret;
-
- if (!VALID_DAY(dt->day))
- return 2;
-
- *str = cur;
- return 0;
-}
-
-/**
- * _xmlSchemaParseTime:
- * @dt: pointer to a date structure
- * @str: pointer to the string to analyze
- *
- * Parses a xs:time without time zone and fills in the appropriate
- * fields of the @dt structure. @str is updated to point just after the
- * xs:time.
- * In case of error, values of @dt fields are undefined.
- *
- * Returns 0 or the error code
- */
-static int
-_xmlSchemaParseTime (xmlSchemaValDatePtr dt, const xmlChar **str) {
- const xmlChar *cur = *str;
- unsigned int hour = 0; /* use temp var in case str is not xs:time */
- int ret = 0;
-
- PARSE_2_DIGITS(hour, cur, ret);
- if (ret != 0)
- return ret;
-
- if (*cur != ':')
- return 1;
- cur++;
-
- /* the ':' insures this string is xs:time */
- dt->hour = hour;
-
- PARSE_2_DIGITS(dt->min, cur, ret);
- if (ret != 0)
- return ret;
-
- if (*cur != ':')
- return 1;
- cur++;
-
- PARSE_FLOAT(dt->sec, cur, ret);
- if (ret != 0)
- return ret;
-
- if (!VALID_TIME(dt))
- return 2;
-
- *str = cur;
- return 0;
-}
-
-/**
- * _xmlSchemaParseTimeZone:
- * @dt: pointer to a date structure
- * @str: pointer to the string to analyze
- *
- * Parses a time zone without time zone and fills in the appropriate
- * field of the @dt structure. @str is updated to point just after the
- * time zone.
- *
- * Returns 0 or the error code
- */
-static int
-_xmlSchemaParseTimeZone (xmlSchemaValDatePtr dt, const xmlChar **str) {
- const xmlChar *cur = *str;
- int ret = 0;
-
- if (str == NULL)
- return -1;
-
- switch (*cur) {
- case 0:
- dt->tz_flag = 0;
- dt->tzo = 0;
- break;
-
- case 'Z':
- dt->tz_flag = 1;
- dt->tzo = 0;
- cur++;
- break;
-
- case '+':
- case '-': {
- int isneg = 0, tmp = 0;
- isneg = (*cur == '-');
-
- cur++;
-
- PARSE_2_DIGITS(tmp, cur, ret);
- if (ret != 0)
- return ret;
- if (!VALID_HOUR(tmp))
- return 2;
-
- if (*cur != ':')
- return 1;
- cur++;
-
- dt->tzo = tmp * 60;
-
- PARSE_2_DIGITS(tmp, cur, ret);
- if (ret != 0)
- return ret;
- if (!VALID_MIN(tmp))
- return 2;
-
- dt->tzo += tmp;
- if (isneg)
- dt->tzo = - dt->tzo;
-
- if (!VALID_TZO(dt->tzo))
- return 2;
-
- dt->tz_flag = 1;
- break;
- }
- default:
- return 1;
- }
-
- *str = cur;
- return 0;
-}
-
-/****************************************************************
- * *
- * XML Schema Dates/Times Datatypes Handling *
- * *
- ****************************************************************/
-
-/**
- * PARSE_DIGITS:
- * @num: the integer to fill in
- * @cur: an #xmlChar *
- * @num_type: an integer flag
- *
- * Parses a digits integer and updates @num with the value. @cur is
- * updated to point just after the integer.
- * In case of error, @num_type is set to -1, values of @num and
- * @cur are undefined.
- */
-#define PARSE_DIGITS(num, cur, num_type) \
- if ((*cur < '0') || (*cur > '9')) \
- num_type = -1; \
- else \
- while ((*cur >= '0') && (*cur <= '9')) { \
- num = num * 10 + (*cur - '0'); \
- cur++; \
- }
-
-/**
- * PARSE_NUM:
- * @num: the double to fill in
- * @cur: an #xmlChar *
- * @num_type: an integer flag
- *
- * Parses a float or integer and updates @num with the value. @cur is
- * updated to point just after the number. If the number is a float,
- * then it must have an integer part and a decimal part; @num_type will
- * be set to 1. If there is no decimal part, @num_type is set to zero.
- * In case of error, @num_type is set to -1, values of @num and
- * @cur are undefined.
- */
-#define PARSE_NUM(num, cur, num_type) \
- num = 0; \
- PARSE_DIGITS(num, cur, num_type); \
- if (!num_type && (*cur == '.')) { \
- double mult = 1; \
- cur++; \
- if ((*cur < '0') || (*cur > '9')) \
- num_type = -1; \
- else \
- num_type = 1; \
- while ((*cur >= '0') && (*cur <= '9')) { \
- mult /= 10; \
- num += (*cur - '0') * mult; \
- cur++; \
- } \
- }
-
-/**
- * xmlSchemaValidateDates:
- * @type: the predefined type
- * @dateTime: string to analyze
- * @val: the return computed value
- *
- * Check that @dateTime conforms to the lexical space of one of the date types.
- * if true a value is computed and returned in @val.
- *
- * Returns 0 if this validates, a positive error code number otherwise
- * and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateDates (xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
- const xmlChar *dateTime, xmlSchemaValPtr *val) {
- xmlSchemaValPtr dt;
- int ret;
- const xmlChar *cur = dateTime;
-
-#define RETURN_TYPE_IF_VALID(t) \
- if (IS_TZO_CHAR(*cur)) { \
- ret = _xmlSchemaParseTimeZone(&(dt->value.date), &cur); \
- if (ret == 0) { \
- if (*cur != 0) \
- goto error; \
- dt->type = t; \
- if (val != NULL) \
- *val = dt; \
- return 0; \
- } \
- }
-
- if (dateTime == NULL)
- return -1;
-
- if ((*cur != '-') && (*cur < '0') && (*cur > '9'))
- return 1;
-
- dt = xmlSchemaNewValue(XML_SCHEMAS_UNKNOWN);
- if (dt == NULL)
- return -1;
-
- if ((cur[0] == '-') && (cur[1] == '-')) {
- /*
- * It's an incomplete date (xs:gMonthDay, xs:gMonth or
- * xs:gDay)
- */
- cur += 2;
-
- /* is it an xs:gDay? */
- if (*cur == '-') {
- ++cur;
- ret = _xmlSchemaParseGDay(&(dt->value.date), &cur);
- if (ret != 0)
- goto error;
-
- RETURN_TYPE_IF_VALID(XML_SCHEMAS_GDAY);
-
- goto error;
- }
-
- /*
- * it should be an xs:gMonthDay or xs:gMonth
- */
- ret = _xmlSchemaParseGMonth(&(dt->value.date), &cur);
- if (ret != 0)
- goto error;
-
- if (*cur != '-')
- goto error;
- cur++;
-
- /* is it an xs:gMonth? */
- if (*cur == '-') {
- cur++;
- RETURN_TYPE_IF_VALID(XML_SCHEMAS_GMONTH);
- goto error;
- }
-
- /* it should be an xs:gMonthDay */
- ret = _xmlSchemaParseGDay(&(dt->value.date), &cur);
- if (ret != 0)
- goto error;
-
- RETURN_TYPE_IF_VALID(XML_SCHEMAS_GMONTHDAY);
-
- goto error;
- }
-
- /*
- * It's a right-truncated date or an xs:time.
- * Try to parse an xs:time then fallback on right-truncated dates.
- */
- if ((*cur >= '0') && (*cur <= '9')) {
- ret = _xmlSchemaParseTime(&(dt->value.date), &cur);
- if (ret == 0) {
- /* it's an xs:time */
- RETURN_TYPE_IF_VALID(XML_SCHEMAS_TIME);
- }
- }
-
- /* fallback on date parsing */
- cur = dateTime;
-
- ret = _xmlSchemaParseGYear(&(dt->value.date), &cur);
- if (ret != 0)
- goto error;
-
- /* is it an xs:gYear? */
- RETURN_TYPE_IF_VALID(XML_SCHEMAS_GYEAR);
-
- if (*cur != '-')
- goto error;
- cur++;
-
- ret = _xmlSchemaParseGMonth(&(dt->value.date), &cur);
- if (ret != 0)
- goto error;
-
- /* is it an xs:gYearMonth? */
- RETURN_TYPE_IF_VALID(XML_SCHEMAS_GYEARMONTH);
-
- if (*cur != '-')
- goto error;
- cur++;
-
- ret = _xmlSchemaParseGDay(&(dt->value.date), &cur);
- if ((ret != 0) || !VALID_DATE((&(dt->value.date))))
- goto error;
-
- /* is it an xs:date? */
- RETURN_TYPE_IF_VALID(XML_SCHEMAS_DATE);
-
- if (*cur != 'T')
- goto error;
- cur++;
-
- /* it should be an xs:dateTime */
- ret = _xmlSchemaParseTime(&(dt->value.date), &cur);
- if (ret != 0)
- goto error;
-
- ret = _xmlSchemaParseTimeZone(&(dt->value.date), &cur);
- if ((ret != 0) || (*cur != 0) || !VALID_DATETIME((&(dt->value.date))))
- goto error;
-
- dt->type = XML_SCHEMAS_DATETIME;
-
- if (val != NULL)
- *val = dt;
-
- return 0;
-
-error:
- if (dt != NULL)
- xmlSchemaFreeValue(dt);
- return 1;
-}
-
-/**
- * xmlSchemaValidateDuration:
- * @type: the predefined type
- * @duration: string to analyze
- * @val: the return computed value
- *
- * Check that @duration conforms to the lexical space of the duration type.
- * if true a value is computed and returned in @val.
- *
- * Returns 0 if this validates, a positive error code number otherwise
- * and -1 in case of internal or API error.
- */
-static int
-xmlSchemaValidateDuration (xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
- const xmlChar *duration, xmlSchemaValPtr *val) {
- const xmlChar *cur = duration;
- xmlSchemaValPtr dur;
- int isneg = 0;
- unsigned int seq = 0;
-
- if (duration == NULL)
- return -1;
-
- if (*cur == '-') {
- isneg = 1;
- cur++;
- }
-
- /* duration must start with 'P' (after sign) */
- if (*cur++ != 'P')
- return 1;
-
- dur = xmlSchemaNewValue(XML_SCHEMAS_DURATION);
- if (dur == NULL)
- return -1;
-
- while (*cur != 0) {
- double num;
- int num_type = 0; /* -1 = invalid, 0 = int, 1 = floating */
- const xmlChar desig[] = {'Y', 'M', 'D', 'H', 'M', 'S'};
- const double multi[] = { 0.0, 0.0, 86400.0, 3600.0, 60.0, 1.0, 0.0};
-
- /* input string should be empty or invalid date/time item */
- if (seq >= sizeof(desig))
- goto error;
-
- /* T designator must be present for time items */
- if (*cur == 'T') {
- if (seq <= 3) {
- seq = 3;
- cur++;
- } else
- return 1;
- } else if (seq == 3)
- goto error;
-
- /* parse the number portion of the item */
- PARSE_NUM(num, cur, num_type);
-
- if ((num_type == -1) || (*cur == 0))
- goto error;
-
- /* update duration based on item type */
- while (seq < sizeof(desig)) {
- if (*cur == desig[seq]) {
-
- /* verify numeric type; only seconds can be float */
- if ((num_type != 0) && (seq < (sizeof(desig)-1)))
- goto error;
-
- switch (seq) {
- case 0:
- dur->value.dur.mon = (long)num * 12;
- break;
- case 1:
- dur->value.dur.mon += (long)num;
- break;
- default:
- /* convert to seconds using multiplier */
- dur->value.dur.sec += num * multi[seq];
- seq++;
- break;
- }
-
- break; /* exit loop */
- }
- /* no date designators found? */
- if (++seq == 3)
- goto error;
- }
- cur++;
- }
-
- if (isneg) {
- dur->value.dur.mon = -dur->value.dur.mon;
- dur->value.dur.day = -dur->value.dur.day;
- dur->value.dur.sec = -dur->value.dur.sec;
- }
-
- if (val != NULL)
- *val = dur;
-
- return 0;
-
-error:
- if (dur != NULL)
- xmlSchemaFreeValue(dur);
- return 1;
-}
-
-/**
- * xmlSchemaValidatePredefinedType:
- * @type: the predefined type
- * @value: the value to check
- * @val: the return computed value
- *
- * Check that a value conforms to the lexical space of the predefined type.
- * if true a value is computed and returned in @val.
- *
- * Returns 0 if this validates, a positive error code number otherwise
- * and -1 in case of internal or API error.
- */
-int
-xmlSchemaValidatePredefinedType(xmlSchemaTypePtr type, const xmlChar *value,
- xmlSchemaValPtr *val) {
- xmlSchemaValPtr v;
-
- if (xmlSchemaTypesInitialized == 0)
- return(-1);
- if (type == NULL)
- return(-1);
-
- if (val != NULL)
- *val = NULL;
- if (type == xmlSchemaTypeStringDef) {
- return(0);
- } else if (type == xmlSchemaTypeAnyTypeDef) {
- return(0);
- } else if (type == xmlSchemaTypeAnySimpleTypeDef) {
- return(0);
- } else if (type == xmlSchemaTypeNmtoken) {
- if (xmlValidateNmtokenValue(value))
- return(0);
- return(1);
- } else if (type == xmlSchemaTypeDecimalDef) {
- const xmlChar *cur = value, *tmp;
- int frac = 0, len, neg = 0;
- unsigned long base = 0;
- if (cur == NULL)
- return(1);
- if (*cur == '+')
- cur++;
- else if (*cur == '-') {
- neg = 1;
- cur++;
- }
- tmp = cur;
- while ((*cur >= '0') && (*cur <= '9')) {
- base = base * 10 + (*cur - '0');
- cur++;
- }
- len = cur - tmp;
- if (*cur == '.') {
- cur++;
- tmp = cur;
- while ((*cur >= '0') && (*cur <= '9')) {
- base = base * 10 + (*cur - '0');
- cur++;
- }
- frac = cur - tmp;
- }
- if (*cur != 0)
- return(1);
- if (val != NULL) {
- v = xmlSchemaNewValue(XML_SCHEMAS_DECIMAL);
- if (v != NULL) {
- v->value.decimal.base = base;
- v->value.decimal.sign = neg;
- v->value.decimal.frac = frac;
- v->value.decimal.total = frac + len;
- *val = v;
- }
- }
- return(0);
- } else if (type == xmlSchemaTypeDurationDef) {
- return xmlSchemaValidateDuration(type, value, val);
- } else if ((type == xmlSchemaTypeDatetimeDef) ||
- (type == xmlSchemaTypeTimeDef) ||
- (type == xmlSchemaTypeDateDef) ||
- (type == xmlSchemaTypeGYearDef) ||
- (type == xmlSchemaTypeGYearMonthDef) ||
- (type == xmlSchemaTypeGMonthDef) ||
- (type == xmlSchemaTypeGMonthDayDef) ||
- (type == xmlSchemaTypeGDayDef)) {
- return xmlSchemaValidateDates(type, value, val);
- } else if (type == xmlSchemaTypePositiveIntegerDef) {
- const xmlChar *cur = value;
- unsigned long base = 0;
- int total = 0;
- if (cur == NULL)
- return(1);
- if (*cur == '+')
- cur++;
- while ((*cur >= '0') && (*cur <= '9')) {
- base = base * 10 + (*cur - '0');
- total++;
- cur++;
- }
- if (*cur != 0)
- return(1);
- if (val != NULL) {
- v = xmlSchemaNewValue(XML_SCHEMAS_DECIMAL);
- if (v != NULL) {
- v->value.decimal.base = base;
- v->value.decimal.sign = 0;
- v->value.decimal.frac = 0;
- v->value.decimal.total = total;
- *val = v;
- }
- }
- return(0);
- } else if (type == xmlSchemaTypeNonNegativeIntegerDef) {
- const xmlChar *cur = value;
- unsigned long base = 0;
- int total = 0;
- int sign = 0;
- if (cur == NULL)
- return(1);
- if (*cur == '-') {
- sign = 1;
- cur++;
- } else if (*cur == '+')
- cur++;
- while ((*cur >= '0') && (*cur <= '9')) {
- base = base * 10 + (*cur - '0');
- total++;
- cur++;
- }
- if (*cur != 0)
- return(1);
- if ((sign == 1) && (base != 0))
- return(1);
- if (val != NULL) {
- v = xmlSchemaNewValue(XML_SCHEMAS_DECIMAL);
- if (v != NULL) {
- v->value.decimal.base = base;
- v->value.decimal.sign = 0;
- v->value.decimal.frac = 0;
- v->value.decimal.total = total;
- *val = v;
- }
- }
- return(0);
- } else if (type == xmlSchemaTypeFloatDef) {
- const xmlChar *cur = value, *tmp;
- int frac = 0, len, neg = 0;
- unsigned long base = 0;
- if (cur == NULL)
- return(1);
- if (*cur == '+')
- cur++;
- else if (*cur == '-') {
- neg = 1;
- cur++;
- }
- tmp = cur;
- while ((*cur >= '0') && (*cur <= '9')) {
- base = base * 10 + (*cur - '0');
- cur++;
- }
- len = cur - tmp;
- if (*cur == '.') {
- cur++;
- tmp = cur;
- while ((*cur >= '0') && (*cur <= '9')) {
- base = base * 10 + (*cur - '0');
- cur++;
- }
- frac = cur - tmp;
- }
- TODO
- return(0);
- } else if (type == xmlSchemaTypeDoubleDef) {
- TODO
- return(0);
- } else {
- TODO
- return(0);
- }
-}
-
-/**
- * xmlSchemaCompareDecimals:
- * @x: a first decimal value
- * @y: a second decimal value
- *
- * Compare 2 decimals
- *
- * Returns -1 if x < y, 0 if x == y, 1 if x > y and -2 in case of error
- */
-static int
-xmlSchemaCompareDecimals(xmlSchemaValPtr x, xmlSchemaValPtr y)
-{
- xmlSchemaValPtr swp;
- int order = 1;
- unsigned long tmp;
-
- if ((x->value.decimal.sign) && (x->value.decimal.sign))
- order = -1;
- else if (x->value.decimal.sign)
- return (-1);
- else if (y->value.decimal.sign)
- return (1);
- if (x->value.decimal.frac == y->value.decimal.frac) {
- if (x->value.decimal.base < y->value.decimal.base)
- return (-1);
- return (x->value.decimal.base > y->value.decimal.base);
- }
- if (y->value.decimal.frac > x->value.decimal.frac) {
- swp = y;
- y = x;
- x = swp;
- order = -order;
- }
- tmp =
- x->value.decimal.base / powten[x->value.decimal.frac -
- y->value.decimal.frac];
- if (tmp > y->value.decimal.base)
- return (order);
- if (tmp < y->value.decimal.base)
- return (-order);
- tmp =
- y->value.decimal.base * powten[x->value.decimal.frac -
- y->value.decimal.frac];
- if (x->value.decimal.base < tmp)
- return (-order);
- if (x->value.decimal.base == tmp)
- return (0);
- return (order);
-}
-
-/**
- * xmlSchemaCompareDurations:
- * @x: a first duration value
- * @y: a second duration value
- *
- * Compare 2 durations
- *
- * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
- * case of error
- */
-static int
-xmlSchemaCompareDurations(xmlSchemaValPtr x, xmlSchemaValPtr y)
-{
- long carry, mon, day;
- double sec;
- long xmon, xday, myear, lyear, minday, maxday;
- static const long dayRange [2][12] = {
- { 0, 28, 59, 89, 120, 150, 181, 212, 242, 273, 303, 334, },
- { 0, 31, 62, 92, 123, 153, 184, 215, 245, 276, 306, 337} };
-
- if ((x == NULL) || (y == NULL))
- return -2;
-
- /* months */
- mon = x->value.dur.mon - y->value.dur.mon;
-
- /* seconds */
- sec = x->value.dur.sec - y->value.dur.sec;
- carry = (long)sec / SECS_PER_DAY;
- sec -= (double)(carry * SECS_PER_DAY);
-
- /* days */
- day = x->value.dur.day - y->value.dur.day + carry;
-
- /* easy test */
- if (mon == 0) {
- if (day == 0)
- if (sec == 0.0)
- return 0;
- else if (sec < 0.0)
- return -1;
- else
- return 1;
- else if (day < 0)
- return -1;
- else
- return 1;
- }
-
- if (mon > 0) {
- if ((day >= 0) && (sec >= 0.0))
- return 1;
- else {
- xmon = mon;
- xday = -day;
- }
- } else if ((day <= 0) && (sec <= 0.0)) {
- return -1;
- } else {
- xmon = -mon;
- xday = day;
- }
-
- myear = xmon / 12;
- lyear = myear / 4;
- minday = (myear * 365) + (lyear != 0 ? lyear - 1 : 0);
- maxday = (myear * 365) + (lyear != 0 ? lyear + 1 : 0);
-
- xmon = xmon % 12;
- minday += dayRange[0][xmon];
- maxday += dayRange[1][xmon];
-
- if (maxday < xday)
- return 1;
- else if (minday > xday)
- return -1;
-
- /* indeterminate */
- return 2;
-}
-
-/*
- * macros for adding date/times and durations
- */
-#define FQUOTIENT(a,b) (floor(((double)a/(double)b)))
-#define MODULO(a,b) (a - FQUOTIENT(a,b) * b)
-#define FQUOTIENT_RANGE(a,low,high) (FQUOTIENT((a-low),(high-low)))
-#define MODULO_RANGE(a,low,high) ((MODULO((a-low),(high-low)))+low)
-
-/**
- * _xmlSchemaDateAdd:
- * @dt: an #xmlSchemaValPtr
- * @dur: an #xmlSchemaValPtr of type #XS_DURATION
- *
- * Compute a new date/time from @dt and @dur. This function assumes @dt
- * is either #XML_SCHEMAS_DATETIME, #XML_SCHEMAS_DATE, #XML_SCHEMAS_GYEARMONTH,
- * or #XML_SCHEMAS_GYEAR.
- *
- * Returns date/time pointer or NULL.
- */
-static xmlSchemaValPtr
-_xmlSchemaDateAdd (xmlSchemaValPtr dt, xmlSchemaValPtr dur)
-{
- xmlSchemaValPtr ret;
- long carry, tempdays, temp;
- xmlSchemaValDatePtr r, d;
- xmlSchemaValDurationPtr u;
-
- if ((dt == NULL) || (dur == NULL))
- return NULL;
-
- ret = xmlSchemaNewValue(dt->type);
- if (ret == NULL)
- return NULL;
-
- r = &(ret->value.date);
- d = &(dt->value.date);
- u = &(dur->value.dur);
-
- /* normalization */
- if (d->mon == 0)
- d->mon = 1;
-
- /* normalize for time zone offset */
- u->sec -= (d->tzo * 60);
- d->tzo = 0;
-
- /* normalization */
- if (d->day == 0)
- d->day = 1;
-
- /* month */
- carry = d->mon + u->mon;
- r->mon = MODULO_RANGE(carry, 1, 13);
- carry = FQUOTIENT_RANGE(carry, 1, 13);
-
- /* year (may be modified later) */
- r->year = d->year + carry;
- if (r->year == 0) {
- if (d->year > 0)
- r->year--;
- else
- r->year++;
- }
-
- /* time zone */
- r->tzo = d->tzo;
- r->tz_flag = d->tz_flag;
-
- /* seconds */
- r->sec = d->sec + u->sec;
- carry = FQUOTIENT((long)r->sec, 60);
- if (r->sec != 0.0) {
- r->sec = MODULO(r->sec, 60.0);
- }
-
- /* minute */
- carry += d->min;
- r->min = MODULO(carry, 60);
- carry = FQUOTIENT(carry, 60);
-
- /* hours */
- carry += d->hour;
- r->hour = MODULO(carry, 24);
- carry = FQUOTIENT(carry, 24);
-
- /*
- * days
- * Note we use tempdays because the temporary values may need more
- * than 5 bits
- */
- if ((VALID_YEAR(r->year)) && (VALID_MONTH(r->mon)) &&
- (d->day > MAX_DAYINMONTH(r->year, r->mon)))
- tempdays = MAX_DAYINMONTH(r->year, r->mon);
- else if (d->day < 1)
- tempdays = 1;
- else
- tempdays = d->day;
-
- tempdays += u->day + carry;
-
- while (1) {
- if (tempdays < 1) {
- long tmon = MODULO_RANGE(r->mon-1, 1, 13);
- long tyr = r->year + FQUOTIENT_RANGE(r->mon-1, 1, 13);
- if (tyr == 0)
- tyr--;
- tempdays += MAX_DAYINMONTH(tyr, tmon);
- carry = -1;
- } else if (tempdays > MAX_DAYINMONTH(r->year, r->mon)) {
- tempdays = tempdays - MAX_DAYINMONTH(r->year, r->mon);
- carry = 1;
- } else
- break;
-
- temp = r->mon + carry;
- r->mon = MODULO_RANGE(temp, 1, 13);
- r->year = r->year + FQUOTIENT_RANGE(temp, 1, 13);
- if (r->year == 0) {
- if (temp < 1)
- r->year--;
- else
- r->year++;
- }
- }
-
- r->day = tempdays;
-
- /*
- * adjust the date/time type to the date values
- */
- if (ret->type != XML_SCHEMAS_DATETIME) {
- if ((r->hour) || (r->min) || (r->sec))
- ret->type = XML_SCHEMAS_DATETIME;
- else if (ret->type != XML_SCHEMAS_DATE) {
- if ((r->mon != 1) && (r->day != 1))
- ret->type = XML_SCHEMAS_DATE;
- else if ((ret->type != XML_SCHEMAS_GYEARMONTH) && (r->mon != 1))
- ret->type = XML_SCHEMAS_GYEARMONTH;
- }
- }
-
- return ret;
-}
-
-/**
- * xmlSchemaDupVal:
- * @v: value to duplicate
- *
- * returns a duplicated value.
- */
-static xmlSchemaValPtr
-xmlSchemaDupVal (xmlSchemaValPtr v)
-{
- xmlSchemaValPtr ret = xmlSchemaNewValue(v->type);
- if (ret == NULL)
- return ret;
-
- memcpy(ret, v, sizeof(xmlSchemaVal));
- return ret;
-}
-
-/**
- * xmlSchemaDateNormalize:
- * @dt: an #xmlSchemaValPtr
- *
- * Normalize @dt to GMT time.
- *
- */
-static xmlSchemaValPtr
-xmlSchemaDateNormalize (xmlSchemaValPtr dt, double offset)
-{
- xmlSchemaValPtr dur, ret;
-
- if (dt == NULL)
- return NULL;
-
- if (((dt->type != XML_SCHEMAS_TIME) &&
- (dt->type != XML_SCHEMAS_DATETIME)) || (dt->value.date.tzo == 0))
- return xmlSchemaDupVal(dt);
-
- dur = xmlSchemaNewValue(XML_SCHEMAS_DURATION);
- if (dur == NULL)
- return NULL;
-
- dur->value.date.sec -= offset;
-
- ret = _xmlSchemaDateAdd(dt, dur);
- if (ret == NULL)
- return NULL;
-
- xmlSchemaFreeValue(dur);
-
- /* ret->value.date.tzo = 0; */
- return ret;
-}
-
-/**
- * _xmlSchemaDateCastYMToDays:
- * @dt: an #xmlSchemaValPtr
- *
- * Convert mon and year of @dt to total number of days. Take the
- * number of years since (or before) 1 AD and add the number of leap
- * years. This is a function because negative
- * years must be handled a little differently and there is no zero year.
- *
- * Returns number of days.
- */
-static long
-_xmlSchemaDateCastYMToDays (const xmlSchemaValPtr dt)
-{
- long ret;
-
- if (dt->value.date.year < 0)
- ret = (dt->value.date.year * 365) +
- (((dt->value.date.year+1)/4)-((dt->value.date.year+1)/100)+
- ((dt->value.date.year+1)/400)) +
- DAY_IN_YEAR(0, dt->value.date.mon, dt->value.date.year);
- else
- ret = ((dt->value.date.year-1) * 365) +
- (((dt->value.date.year-1)/4)-((dt->value.date.year-1)/100)+
- ((dt->value.date.year-1)/400)) +
- DAY_IN_YEAR(0, dt->value.date.mon, dt->value.date.year);
-
- return ret;
-}
-
-/**
- * TIME_TO_NUMBER:
- * @dt: an #xmlSchemaValPtr
- *
- * Calculates the number of seconds in the time portion of @dt.
- *
- * Returns seconds.
- */
-#define TIME_TO_NUMBER(dt) \
- ((double)((dt->value.date.hour * SECS_PER_HOUR) + \
- (dt->value.date.min * SECS_PER_MIN)) + dt->value.date.sec)
-
-/**
- * xmlSchemaCompareDates:
- * @x: a first date/time value
- * @y: a second date/time value
- *
- * Compare 2 date/times
- *
- * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
- * case of error
- */
-static int
-xmlSchemaCompareDates (xmlSchemaValPtr x, xmlSchemaValPtr y)
-{
- unsigned char xmask, ymask, xor_mask, and_mask;
- xmlSchemaValPtr p1, p2, q1, q2;
- long p1d, p2d, q1d, q2d;
-
- if ((x == NULL) || (y == NULL))
- return -2;
-
- if (x->value.date.tz_flag) {
-
- if (!y->value.date.tz_flag) {
- p1 = xmlSchemaDateNormalize(x, 0);
- p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day;
- /* normalize y + 14:00 */
- q1 = xmlSchemaDateNormalize(y, (14 * SECS_PER_HOUR));
-
- q1d = _xmlSchemaDateCastYMToDays(q1) + q1->value.date.day;
- if (p1d < q1d) {
- xmlSchemaFreeValue(p1);
- xmlSchemaFreeValue(q1);
- return -1;
- } else if (p1d == q1d) {
- double sec;
-
- sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
- if (sec < 0.0) {
- xmlSchemaFreeValue(p1);
- xmlSchemaFreeValue(q1);
- return -1;
- } else {
- /* normalize y - 14:00 */
- q2 = xmlSchemaDateNormalize(y, -(14 * SECS_PER_HOUR));
- q2d = _xmlSchemaDateCastYMToDays(q2) + q2->value.date.day;
- xmlSchemaFreeValue(p1);
- xmlSchemaFreeValue(q1);
- xmlSchemaFreeValue(q2);
- if (p1d > q2d)
- return 1;
- else if (p1d == q2d) {
- sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q2);
- if (sec > 0.0)
- return 1;
- else
- return 2; /* indeterminate */
- }
- }
- } else {
- xmlSchemaFreeValue(p1);
- xmlSchemaFreeValue(q1);
- }
- }
- } else if (y->value.date.tz_flag) {
- q1 = xmlSchemaDateNormalize(y, 0);
- q1d = _xmlSchemaDateCastYMToDays(q1) + q1->value.date.day;
-
- /* normalize x - 14:00 */
- p1 = xmlSchemaDateNormalize(x, -(14 * SECS_PER_HOUR));
- p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day;
-
- if (p1d < q1d) {
- xmlSchemaFreeValue(p1);
- xmlSchemaFreeValue(q1);
- return -1;
- } else if (p1d == q1d) {
- double sec;
-
- sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
- if (sec < 0.0) {
- xmlSchemaFreeValue(p1);
- xmlSchemaFreeValue(q1);
- return -1;
- } else {
- /* normalize x + 14:00 */
- p2 = xmlSchemaDateNormalize(x, (14 * SECS_PER_HOUR));
- p2d = _xmlSchemaDateCastYMToDays(p2) + p2->value.date.day;
-
- xmlSchemaFreeValue(p1);
- xmlSchemaFreeValue(q1);
- xmlSchemaFreeValue(p2);
- if (p2d > q1d)
- return 1;
- else if (p2d == q1d) {
- sec = TIME_TO_NUMBER(p2) - TIME_TO_NUMBER(q1);
- if (sec > 0.0)
- return 1;
- else
- return 2; /* indeterminate */
- }
- }
- } else {
- xmlSchemaFreeValue(p1);
- xmlSchemaFreeValue(q1);
- }
- }
-
- /*
- * if the same type then calculate the difference
- */
- if (x->type == y->type) {
- q1 = xmlSchemaDateNormalize(y, 0);
- q1d = _xmlSchemaDateCastYMToDays(q1) + q1->value.date.day;
-
- p1 = xmlSchemaDateNormalize(x, 0);
- p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day;
-
- if (p1d < q1d) {
- xmlSchemaFreeValue(p1);
- xmlSchemaFreeValue(q1);
- return -1;
- } else if (p1d > q1d) {
- xmlSchemaFreeValue(p1);
- xmlSchemaFreeValue(q1);
- return 1;
- } else {
- double sec;
-
- sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
- xmlSchemaFreeValue(p1);
- xmlSchemaFreeValue(q1);
- if (sec < 0.0)
- return -1;
- else if (sec > 0.0)
- return 1;
-
- }
- return 0;
- }
-
- switch (x->type) {
- case XML_SCHEMAS_DATETIME:
- xmask = 0xf;
- break;
- case XML_SCHEMAS_DATE:
- xmask = 0x7;
- break;
- case XML_SCHEMAS_GYEAR:
- xmask = 0x1;
- break;
- case XML_SCHEMAS_GMONTH:
- xmask = 0x2;
- break;
- case XML_SCHEMAS_GDAY:
- xmask = 0x3;
- break;
- case XML_SCHEMAS_GYEARMONTH:
- xmask = 0x3;
- break;
- case XML_SCHEMAS_GMONTHDAY:
- xmask = 0x6;
- break;
- case XML_SCHEMAS_TIME:
- xmask = 0x8;
- break;
- default:
- xmask = 0;
- break;
- }
-
- switch (y->type) {
- case XML_SCHEMAS_DATETIME:
- ymask = 0xf;
- break;
- case XML_SCHEMAS_DATE:
- ymask = 0x7;
- break;
- case XML_SCHEMAS_GYEAR:
- ymask = 0x1;
- break;
- case XML_SCHEMAS_GMONTH:
- ymask = 0x2;
- break;
- case XML_SCHEMAS_GDAY:
- ymask = 0x3;
- break;
- case XML_SCHEMAS_GYEARMONTH:
- ymask = 0x3;
- break;
- case XML_SCHEMAS_GMONTHDAY:
- ymask = 0x6;
- break;
- case XML_SCHEMAS_TIME:
- ymask = 0x8;
- break;
- default:
- ymask = 0;
- break;
- }
-
- xor_mask = xmask ^ ymask; /* mark type differences */
- and_mask = xmask & ymask; /* mark field specification */
-
- /* year */
- if (xor_mask & 1)
- return 2; /* indeterminate */
- else if (and_mask & 1) {
- if (x->value.date.year < y->value.date.year)
- return -1;
- else if (x->value.date.year > y->value.date.year)
- return 1;
- }
-
- /* month */
- if (xor_mask & 2)
- return 2; /* indeterminate */
- else if (and_mask & 2) {
- if (x->value.date.mon < y->value.date.mon)
- return -1;
- else if (x->value.date.mon > y->value.date.mon)
- return 1;
- }
-
- /* day */
- if (xor_mask & 4)
- return 2; /* indeterminate */
- else if (and_mask & 4) {
- if (x->value.date.day < y->value.date.day)
- return -1;
- else if (x->value.date.day > y->value.date.day)
- return 1;
- }
-
- /* time */
- if (xor_mask & 8)
- return 2; /* indeterminate */
- else if (and_mask & 8) {
- if (x->value.date.hour < y->value.date.hour)
- return -1;
- else if (x->value.date.hour > y->value.date.hour)
- return 1;
- else if (x->value.date.min < y->value.date.min)
- return -1;
- else if (x->value.date.min > y->value.date.min)
- return 1;
- else if (x->value.date.sec < y->value.date.sec)
- return -1;
- else if (x->value.date.sec > y->value.date.sec)
- return 1;
- }
-
- return 0;
-}
-
-/**
- * xmlSchemaCompareValues:
- * @x: a first value
- * @y: a second value
- *
- * Compare 2 values
- *
- * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
- * case of error
- */
-static int
-xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) {
- if ((x == NULL) || (y == NULL))
- return(-2);
-
- switch (x->type) {
- case XML_SCHEMAS_STRING:
- TODO
- case XML_SCHEMAS_DECIMAL:
- if (y->type == XML_SCHEMAS_DECIMAL)
- return(xmlSchemaCompareDecimals(x, y));
- return(-2);
- case XML_SCHEMAS_DURATION:
- if (y->type == XML_SCHEMAS_DURATION)
- return(xmlSchemaCompareDurations(x, y));
- return(-2);
- case XML_SCHEMAS_TIME:
- case XML_SCHEMAS_GDAY:
- case XML_SCHEMAS_GMONTH:
- case XML_SCHEMAS_GMONTHDAY:
- case XML_SCHEMAS_GYEAR:
- case XML_SCHEMAS_GYEARMONTH:
- case XML_SCHEMAS_DATE:
- case XML_SCHEMAS_DATETIME:
- if ((y->type == XML_SCHEMAS_DATETIME) ||
- (y->type == XML_SCHEMAS_TIME) ||
- (y->type == XML_SCHEMAS_GDAY) ||
- (y->type == XML_SCHEMAS_GMONTH) ||
- (y->type == XML_SCHEMAS_GMONTHDAY) ||
- (y->type == XML_SCHEMAS_GYEAR) ||
- (y->type == XML_SCHEMAS_DATE) ||
- (y->type == XML_SCHEMAS_GYEARMONTH))
- return (xmlSchemaCompareDates(x, y));
-
- return (-2);
- default:
- TODO
- }
- return -2;
-}
-
-/**
- * xmlSchemaValidateFacet:
- * @base: the base type
- * @facet: the facet to check
- * @value: the lexical repr of the value to validate
- * @val: the precomputed value
- *
- * Check a value against a facet condition
- *
- * Returns 0 if the element is schemas valid, a positive error code
- * number otherwise and -1 in case of internal or API error.
- */
-int
-xmlSchemaValidateFacet(xmlSchemaTypePtr base ATTRIBUTE_UNUSED,
- xmlSchemaFacetPtr facet,
- const xmlChar *value, xmlSchemaValPtr val)
-{
- int ret;
-
- switch (facet->type) {
- case XML_SCHEMA_FACET_PATTERN:
- ret = xmlRegexpExec(facet->regexp, value);
- if (ret == 1)
- return(0);
- if (ret == 0) {
- TODO /* error code */
- return(1);
- }
- return(ret);
- case XML_SCHEMA_FACET_MAXEXCLUSIVE:
- ret = xmlSchemaCompareValues(val, facet->val);
- if (ret == -2) {
- TODO /* error code */
- return(-1);
- }
- if (ret == -1)
- return(0);
- /* error code */
- return(1);
- case XML_SCHEMA_FACET_MAXINCLUSIVE:
- ret = xmlSchemaCompareValues(val, facet->val);
- if (ret == -2) {
- TODO /* error code */
- return(-1);
- }
- if ((ret == -1) || (ret == 0))
- return(0);
- /* error code */
- return(1);
- case XML_SCHEMA_FACET_MINEXCLUSIVE:
- ret = xmlSchemaCompareValues(val, facet->val);
- if (ret == -2) {
- TODO /* error code */
- return(-1);
- }
- if (ret == 1)
- return(0);
- /* error code */
- return(1);
- case XML_SCHEMA_FACET_MININCLUSIVE:
- ret = xmlSchemaCompareValues(val, facet->val);
- if (ret == -2) {
- TODO /* error code */
- return(-1);
- }
- if ((ret == 1) || (ret == 0))
- return(0);
- /* error code */
- return(1);
- case XML_SCHEMA_FACET_WHITESPACE:
- TODO /* whitespaces */
- return(0);
- case XML_SCHEMA_FACET_MAXLENGTH:
- if ((facet->val != NULL) &&
- (facet->val->type == XML_SCHEMAS_DECIMAL) &&
- (facet->val->value.decimal.frac == 0)) {
- unsigned int len;
-
- if (facet->val->value.decimal.sign == 1)
- return(1);
- len = xmlUTF8Strlen(value);
- if (len > facet->val->value.decimal.base)
- return(1);
- return(0);
- }
- TODO /* error code */
- return(1);
- case XML_SCHEMA_FACET_ENUMERATION:
- if ((facet->value != NULL) &&
- (xmlStrEqual(facet->value, value)))
- return(0);
- return(1);
- default:
- TODO
- }
- return(0);
-}
-
-#endif /* LIBXML_SCHEMAS_ENABLED */
diff --git a/bundle/libxml/xmlunicode.c b/bundle/libxml/xmlunicode.c
deleted file mode 100644
index 8baf8d18c7..0000000000
--- a/bundle/libxml/xmlunicode.c
+++ /dev/null
@@ -1,4290 +0,0 @@
-/*
- * xmlunicode.c: this module implements the Unicode character APIs
- *
- * This file is automatically generated from the
- * UCS description files of the Unicode Character Database
- * http://www.unicode.org/Public/3.1-Update/UnicodeCharacterDatabase-3.1.0.html
- * using the genUnicode.py Python script.
- *
- * Generation date: Tue Apr 16 17:28:05 2002
- * Sources: Blocks-4.txt UnicodeData-3.1.0.txt
- * Daniel Veillard <veillard@redhat.com>
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-#ifdef LIBXML_UNICODE_ENABLED
-
-#include <string.h>
-#include <libxml/xmlversion.h>
-#include <libxml/xmlunicode.h>
-
-/**
- * xmlUCSIsAlphabeticPresentationForms:
- * @code: UCS code point
- *
- * Check whether the character is part of AlphabeticPresentationForms UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsAlphabeticPresentationForms(int code) {
- return((code >= 0xFB00) && (code <= 0xFB4F));
-}
-
-/**
- * xmlUCSIsArabic:
- * @code: UCS code point
- *
- * Check whether the character is part of Arabic UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsArabic(int code) {
- return((code >= 0x0600) && (code <= 0x06FF));
-}
-
-/**
- * xmlUCSIsArabicPresentationFormsA:
- * @code: UCS code point
- *
- * Check whether the character is part of ArabicPresentationForms-A UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsArabicPresentationFormsA(int code) {
- return((code >= 0xFB50) && (code <= 0xFDFF));
-}
-
-/**
- * xmlUCSIsArabicPresentationFormsB:
- * @code: UCS code point
- *
- * Check whether the character is part of ArabicPresentationForms-B UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsArabicPresentationFormsB(int code) {
- return((code >= 0xFE70) && (code <= 0xFEFE));
-}
-
-/**
- * xmlUCSIsArmenian:
- * @code: UCS code point
- *
- * Check whether the character is part of Armenian UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsArmenian(int code) {
- return((code >= 0x0530) && (code <= 0x058F));
-}
-
-/**
- * xmlUCSIsArrows:
- * @code: UCS code point
- *
- * Check whether the character is part of Arrows UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsArrows(int code) {
- return((code >= 0x2190) && (code <= 0x21FF));
-}
-
-/**
- * xmlUCSIsBasicLatin:
- * @code: UCS code point
- *
- * Check whether the character is part of BasicLatin UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsBasicLatin(int code) {
- return((code >= 0x0000) && (code <= 0x007F));
-}
-
-/**
- * xmlUCSIsBengali:
- * @code: UCS code point
- *
- * Check whether the character is part of Bengali UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsBengali(int code) {
- return((code >= 0x0980) && (code <= 0x09FF));
-}
-
-/**
- * xmlUCSIsBlockElements:
- * @code: UCS code point
- *
- * Check whether the character is part of BlockElements UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsBlockElements(int code) {
- return((code >= 0x2580) && (code <= 0x259F));
-}
-
-/**
- * xmlUCSIsBopomofo:
- * @code: UCS code point
- *
- * Check whether the character is part of Bopomofo UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsBopomofo(int code) {
- return((code >= 0x3100) && (code <= 0x312F));
-}
-
-/**
- * xmlUCSIsBopomofoExtended:
- * @code: UCS code point
- *
- * Check whether the character is part of BopomofoExtended UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsBopomofoExtended(int code) {
- return((code >= 0x31A0) && (code <= 0x31BF));
-}
-
-/**
- * xmlUCSIsBoxDrawing:
- * @code: UCS code point
- *
- * Check whether the character is part of BoxDrawing UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsBoxDrawing(int code) {
- return((code >= 0x2500) && (code <= 0x257F));
-}
-
-/**
- * xmlUCSIsBraillePatterns:
- * @code: UCS code point
- *
- * Check whether the character is part of BraillePatterns UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsBraillePatterns(int code) {
- return((code >= 0x2800) && (code <= 0x28FF));
-}
-
-/**
- * xmlUCSIsByzantineMusicalSymbols:
- * @code: UCS code point
- *
- * Check whether the character is part of ByzantineMusicalSymbols UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsByzantineMusicalSymbols(int code) {
- return((code >= 0x1D000) && (code <= 0x1D0FF));
-}
-
-/**
- * xmlUCSIsCJKCompatibility:
- * @code: UCS code point
- *
- * Check whether the character is part of CJKCompatibility UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCJKCompatibility(int code) {
- return((code >= 0x3300) && (code <= 0x33FF));
-}
-
-/**
- * xmlUCSIsCJKCompatibilityForms:
- * @code: UCS code point
- *
- * Check whether the character is part of CJKCompatibilityForms UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCJKCompatibilityForms(int code) {
- return((code >= 0xFE30) && (code <= 0xFE4F));
-}
-
-/**
- * xmlUCSIsCJKCompatibilityIdeographs:
- * @code: UCS code point
- *
- * Check whether the character is part of CJKCompatibilityIdeographs UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCJKCompatibilityIdeographs(int code) {
- return((code >= 0xF900) && (code <= 0xFAFF));
-}
-
-/**
- * xmlUCSIsCJKCompatibilityIdeographsSupplement:
- * @code: UCS code point
- *
- * Check whether the character is part of CJKCompatibilityIdeographsSupplement UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCJKCompatibilityIdeographsSupplement(int code) {
- return((code >= 0x2F800) && (code <= 0x2FA1F));
-}
-
-/**
- * xmlUCSIsCJKRadicalsSupplement:
- * @code: UCS code point
- *
- * Check whether the character is part of CJKRadicalsSupplement UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCJKRadicalsSupplement(int code) {
- return((code >= 0x2E80) && (code <= 0x2EFF));
-}
-
-/**
- * xmlUCSIsCJKSymbolsandPunctuation:
- * @code: UCS code point
- *
- * Check whether the character is part of CJKSymbolsandPunctuation UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCJKSymbolsandPunctuation(int code) {
- return((code >= 0x3000) && (code <= 0x303F));
-}
-
-/**
- * xmlUCSIsCJKUnifiedIdeographs:
- * @code: UCS code point
- *
- * Check whether the character is part of CJKUnifiedIdeographs UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCJKUnifiedIdeographs(int code) {
- return((code >= 0x4E00) && (code <= 0x9FFF));
-}
-
-/**
- * xmlUCSIsCJKUnifiedIdeographsExtensionA:
- * @code: UCS code point
- *
- * Check whether the character is part of CJKUnifiedIdeographsExtensionA UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCJKUnifiedIdeographsExtensionA(int code) {
- return((code >= 0x3400) && (code <= 0x4DB5));
-}
-
-/**
- * xmlUCSIsCJKUnifiedIdeographsExtensionB:
- * @code: UCS code point
- *
- * Check whether the character is part of CJKUnifiedIdeographsExtensionB UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCJKUnifiedIdeographsExtensionB(int code) {
- return((code >= 0x20000) && (code <= 0x2A6D6));
-}
-
-/**
- * xmlUCSIsCherokee:
- * @code: UCS code point
- *
- * Check whether the character is part of Cherokee UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCherokee(int code) {
- return((code >= 0x13A0) && (code <= 0x13FF));
-}
-
-/**
- * xmlUCSIsCombiningDiacriticalMarks:
- * @code: UCS code point
- *
- * Check whether the character is part of CombiningDiacriticalMarks UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCombiningDiacriticalMarks(int code) {
- return((code >= 0x0300) && (code <= 0x036F));
-}
-
-/**
- * xmlUCSIsCombiningHalfMarks:
- * @code: UCS code point
- *
- * Check whether the character is part of CombiningHalfMarks UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCombiningHalfMarks(int code) {
- return((code >= 0xFE20) && (code <= 0xFE2F));
-}
-
-/**
- * xmlUCSIsCombiningMarksforSymbols:
- * @code: UCS code point
- *
- * Check whether the character is part of CombiningMarksforSymbols UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCombiningMarksforSymbols(int code) {
- return((code >= 0x20D0) && (code <= 0x20FF));
-}
-
-/**
- * xmlUCSIsControlPictures:
- * @code: UCS code point
- *
- * Check whether the character is part of ControlPictures UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsControlPictures(int code) {
- return((code >= 0x2400) && (code <= 0x243F));
-}
-
-/**
- * xmlUCSIsCurrencySymbols:
- * @code: UCS code point
- *
- * Check whether the character is part of CurrencySymbols UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCurrencySymbols(int code) {
- return((code >= 0x20A0) && (code <= 0x20CF));
-}
-
-/**
- * xmlUCSIsCyrillic:
- * @code: UCS code point
- *
- * Check whether the character is part of Cyrillic UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCyrillic(int code) {
- return((code >= 0x0400) && (code <= 0x04FF));
-}
-
-/**
- * xmlUCSIsDeseret:
- * @code: UCS code point
- *
- * Check whether the character is part of Deseret UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsDeseret(int code) {
- return((code >= 0x10400) && (code <= 0x1044F));
-}
-
-/**
- * xmlUCSIsDevanagari:
- * @code: UCS code point
- *
- * Check whether the character is part of Devanagari UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsDevanagari(int code) {
- return((code >= 0x0900) && (code <= 0x097F));
-}
-
-/**
- * xmlUCSIsDingbats:
- * @code: UCS code point
- *
- * Check whether the character is part of Dingbats UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsDingbats(int code) {
- return((code >= 0x2700) && (code <= 0x27BF));
-}
-
-/**
- * xmlUCSIsEnclosedAlphanumerics:
- * @code: UCS code point
- *
- * Check whether the character is part of EnclosedAlphanumerics UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsEnclosedAlphanumerics(int code) {
- return((code >= 0x2460) && (code <= 0x24FF));
-}
-
-/**
- * xmlUCSIsEnclosedCJKLettersandMonths:
- * @code: UCS code point
- *
- * Check whether the character is part of EnclosedCJKLettersandMonths UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsEnclosedCJKLettersandMonths(int code) {
- return((code >= 0x3200) && (code <= 0x32FF));
-}
-
-/**
- * xmlUCSIsEthiopic:
- * @code: UCS code point
- *
- * Check whether the character is part of Ethiopic UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsEthiopic(int code) {
- return((code >= 0x1200) && (code <= 0x137F));
-}
-
-/**
- * xmlUCSIsGeneralPunctuation:
- * @code: UCS code point
- *
- * Check whether the character is part of GeneralPunctuation UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsGeneralPunctuation(int code) {
- return((code >= 0x2000) && (code <= 0x206F));
-}
-
-/**
- * xmlUCSIsGeometricShapes:
- * @code: UCS code point
- *
- * Check whether the character is part of GeometricShapes UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsGeometricShapes(int code) {
- return((code >= 0x25A0) && (code <= 0x25FF));
-}
-
-/**
- * xmlUCSIsGeorgian:
- * @code: UCS code point
- *
- * Check whether the character is part of Georgian UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsGeorgian(int code) {
- return((code >= 0x10A0) && (code <= 0x10FF));
-}
-
-/**
- * xmlUCSIsGothic:
- * @code: UCS code point
- *
- * Check whether the character is part of Gothic UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsGothic(int code) {
- return((code >= 0x10330) && (code <= 0x1034F));
-}
-
-/**
- * xmlUCSIsGreek:
- * @code: UCS code point
- *
- * Check whether the character is part of Greek UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsGreek(int code) {
- return((code >= 0x0370) && (code <= 0x03FF));
-}
-
-/**
- * xmlUCSIsGreekExtended:
- * @code: UCS code point
- *
- * Check whether the character is part of GreekExtended UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsGreekExtended(int code) {
- return((code >= 0x1F00) && (code <= 0x1FFF));
-}
-
-/**
- * xmlUCSIsGujarati:
- * @code: UCS code point
- *
- * Check whether the character is part of Gujarati UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsGujarati(int code) {
- return((code >= 0x0A80) && (code <= 0x0AFF));
-}
-
-/**
- * xmlUCSIsGurmukhi:
- * @code: UCS code point
- *
- * Check whether the character is part of Gurmukhi UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsGurmukhi(int code) {
- return((code >= 0x0A00) && (code <= 0x0A7F));
-}
-
-/**
- * xmlUCSIsHalfwidthandFullwidthForms:
- * @code: UCS code point
- *
- * Check whether the character is part of HalfwidthandFullwidthForms UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsHalfwidthandFullwidthForms(int code) {
- return((code >= 0xFF00) && (code <= 0xFFEF));
-}
-
-/**
- * xmlUCSIsHangulCompatibilityJamo:
- * @code: UCS code point
- *
- * Check whether the character is part of HangulCompatibilityJamo UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsHangulCompatibilityJamo(int code) {
- return((code >= 0x3130) && (code <= 0x318F));
-}
-
-/**
- * xmlUCSIsHangulJamo:
- * @code: UCS code point
- *
- * Check whether the character is part of HangulJamo UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsHangulJamo(int code) {
- return((code >= 0x1100) && (code <= 0x11FF));
-}
-
-/**
- * xmlUCSIsHangulSyllables:
- * @code: UCS code point
- *
- * Check whether the character is part of HangulSyllables UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsHangulSyllables(int code) {
- return((code >= 0xAC00) && (code <= 0xD7A3));
-}
-
-/**
- * xmlUCSIsHebrew:
- * @code: UCS code point
- *
- * Check whether the character is part of Hebrew UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsHebrew(int code) {
- return((code >= 0x0590) && (code <= 0x05FF));
-}
-
-/**
- * xmlUCSIsHighPrivateUseSurrogates:
- * @code: UCS code point
- *
- * Check whether the character is part of HighPrivateUseSurrogates UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsHighPrivateUseSurrogates(int code) {
- return((code >= 0xDB80) && (code <= 0xDBFF));
-}
-
-/**
- * xmlUCSIsHighSurrogates:
- * @code: UCS code point
- *
- * Check whether the character is part of HighSurrogates UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsHighSurrogates(int code) {
- return((code >= 0xD800) && (code <= 0xDB7F));
-}
-
-/**
- * xmlUCSIsHiragana:
- * @code: UCS code point
- *
- * Check whether the character is part of Hiragana UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsHiragana(int code) {
- return((code >= 0x3040) && (code <= 0x309F));
-}
-
-/**
- * xmlUCSIsIPAExtensions:
- * @code: UCS code point
- *
- * Check whether the character is part of IPAExtensions UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsIPAExtensions(int code) {
- return((code >= 0x0250) && (code <= 0x02AF));
-}
-
-/**
- * xmlUCSIsIdeographicDescriptionCharacters:
- * @code: UCS code point
- *
- * Check whether the character is part of IdeographicDescriptionCharacters UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsIdeographicDescriptionCharacters(int code) {
- return((code >= 0x2FF0) && (code <= 0x2FFF));
-}
-
-/**
- * xmlUCSIsKanbun:
- * @code: UCS code point
- *
- * Check whether the character is part of Kanbun UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsKanbun(int code) {
- return((code >= 0x3190) && (code <= 0x319F));
-}
-
-/**
- * xmlUCSIsKangxiRadicals:
- * @code: UCS code point
- *
- * Check whether the character is part of KangxiRadicals UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsKangxiRadicals(int code) {
- return((code >= 0x2F00) && (code <= 0x2FDF));
-}
-
-/**
- * xmlUCSIsKannada:
- * @code: UCS code point
- *
- * Check whether the character is part of Kannada UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsKannada(int code) {
- return((code >= 0x0C80) && (code <= 0x0CFF));
-}
-
-/**
- * xmlUCSIsKatakana:
- * @code: UCS code point
- *
- * Check whether the character is part of Katakana UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsKatakana(int code) {
- return((code >= 0x30A0) && (code <= 0x30FF));
-}
-
-/**
- * xmlUCSIsKhmer:
- * @code: UCS code point
- *
- * Check whether the character is part of Khmer UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsKhmer(int code) {
- return((code >= 0x1780) && (code <= 0x17FF));
-}
-
-/**
- * xmlUCSIsLao:
- * @code: UCS code point
- *
- * Check whether the character is part of Lao UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsLao(int code) {
- return((code >= 0x0E80) && (code <= 0x0EFF));
-}
-
-/**
- * xmlUCSIsLatin1Supplement:
- * @code: UCS code point
- *
- * Check whether the character is part of Latin-1Supplement UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsLatin1Supplement(int code) {
- return((code >= 0x0080) && (code <= 0x00FF));
-}
-
-/**
- * xmlUCSIsLatinExtendedA:
- * @code: UCS code point
- *
- * Check whether the character is part of LatinExtended-A UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsLatinExtendedA(int code) {
- return((code >= 0x0100) && (code <= 0x017F));
-}
-
-/**
- * xmlUCSIsLatinExtendedB:
- * @code: UCS code point
- *
- * Check whether the character is part of LatinExtended-B UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsLatinExtendedB(int code) {
- return((code >= 0x0180) && (code <= 0x024F));
-}
-
-/**
- * xmlUCSIsLatinExtendedAdditional:
- * @code: UCS code point
- *
- * Check whether the character is part of LatinExtendedAdditional UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsLatinExtendedAdditional(int code) {
- return((code >= 0x1E00) && (code <= 0x1EFF));
-}
-
-/**
- * xmlUCSIsLetterlikeSymbols:
- * @code: UCS code point
- *
- * Check whether the character is part of LetterlikeSymbols UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsLetterlikeSymbols(int code) {
- return((code >= 0x2100) && (code <= 0x214F));
-}
-
-/**
- * xmlUCSIsLowSurrogates:
- * @code: UCS code point
- *
- * Check whether the character is part of LowSurrogates UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsLowSurrogates(int code) {
- return((code >= 0xDC00) && (code <= 0xDFFF));
-}
-
-/**
- * xmlUCSIsMalayalam:
- * @code: UCS code point
- *
- * Check whether the character is part of Malayalam UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsMalayalam(int code) {
- return((code >= 0x0D00) && (code <= 0x0D7F));
-}
-
-/**
- * xmlUCSIsMathematicalAlphanumericSymbols:
- * @code: UCS code point
- *
- * Check whether the character is part of MathematicalAlphanumericSymbols UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsMathematicalAlphanumericSymbols(int code) {
- return((code >= 0x1D400) && (code <= 0x1D7FF));
-}
-
-/**
- * xmlUCSIsMathematicalOperators:
- * @code: UCS code point
- *
- * Check whether the character is part of MathematicalOperators UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsMathematicalOperators(int code) {
- return((code >= 0x2200) && (code <= 0x22FF));
-}
-
-/**
- * xmlUCSIsMiscellaneousSymbols:
- * @code: UCS code point
- *
- * Check whether the character is part of MiscellaneousSymbols UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsMiscellaneousSymbols(int code) {
- return((code >= 0x2600) && (code <= 0x26FF));
-}
-
-/**
- * xmlUCSIsMiscellaneousTechnical:
- * @code: UCS code point
- *
- * Check whether the character is part of MiscellaneousTechnical UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsMiscellaneousTechnical(int code) {
- return((code >= 0x2300) && (code <= 0x23FF));
-}
-
-/**
- * xmlUCSIsMongolian:
- * @code: UCS code point
- *
- * Check whether the character is part of Mongolian UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsMongolian(int code) {
- return((code >= 0x1800) && (code <= 0x18AF));
-}
-
-/**
- * xmlUCSIsMusicalSymbols:
- * @code: UCS code point
- *
- * Check whether the character is part of MusicalSymbols UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsMusicalSymbols(int code) {
- return((code >= 0x1D100) && (code <= 0x1D1FF));
-}
-
-/**
- * xmlUCSIsMyanmar:
- * @code: UCS code point
- *
- * Check whether the character is part of Myanmar UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsMyanmar(int code) {
- return((code >= 0x1000) && (code <= 0x109F));
-}
-
-/**
- * xmlUCSIsNumberForms:
- * @code: UCS code point
- *
- * Check whether the character is part of NumberForms UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsNumberForms(int code) {
- return((code >= 0x2150) && (code <= 0x218F));
-}
-
-/**
- * xmlUCSIsOgham:
- * @code: UCS code point
- *
- * Check whether the character is part of Ogham UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsOgham(int code) {
- return((code >= 0x1680) && (code <= 0x169F));
-}
-
-/**
- * xmlUCSIsOldItalic:
- * @code: UCS code point
- *
- * Check whether the character is part of OldItalic UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsOldItalic(int code) {
- return((code >= 0x10300) && (code <= 0x1032F));
-}
-
-/**
- * xmlUCSIsOpticalCharacterRecognition:
- * @code: UCS code point
- *
- * Check whether the character is part of OpticalCharacterRecognition UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsOpticalCharacterRecognition(int code) {
- return((code >= 0x2440) && (code <= 0x245F));
-}
-
-/**
- * xmlUCSIsOriya:
- * @code: UCS code point
- *
- * Check whether the character is part of Oriya UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsOriya(int code) {
- return((code >= 0x0B00) && (code <= 0x0B7F));
-}
-
-/**
- * xmlUCSIsPrivateUse:
- * @code: UCS code point
- *
- * Check whether the character is part of PrivateUse UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsPrivateUse(int code) {
- return((code >= 0x100000) && (code <= 0x10FFFD));
-}
-
-/**
- * xmlUCSIsRunic:
- * @code: UCS code point
- *
- * Check whether the character is part of Runic UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsRunic(int code) {
- return((code >= 0x16A0) && (code <= 0x16FF));
-}
-
-/**
- * xmlUCSIsSinhala:
- * @code: UCS code point
- *
- * Check whether the character is part of Sinhala UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsSinhala(int code) {
- return((code >= 0x0D80) && (code <= 0x0DFF));
-}
-
-/**
- * xmlUCSIsSmallFormVariants:
- * @code: UCS code point
- *
- * Check whether the character is part of SmallFormVariants UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsSmallFormVariants(int code) {
- return((code >= 0xFE50) && (code <= 0xFE6F));
-}
-
-/**
- * xmlUCSIsSpacingModifierLetters:
- * @code: UCS code point
- *
- * Check whether the character is part of SpacingModifierLetters UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsSpacingModifierLetters(int code) {
- return((code >= 0x02B0) && (code <= 0x02FF));
-}
-
-/**
- * xmlUCSIsSpecials:
- * @code: UCS code point
- *
- * Check whether the character is part of Specials UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsSpecials(int code) {
- return((code >= 0xFFF0) && (code <= 0xFFFD));
-}
-
-/**
- * xmlUCSIsSuperscriptsandSubscripts:
- * @code: UCS code point
- *
- * Check whether the character is part of SuperscriptsandSubscripts UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsSuperscriptsandSubscripts(int code) {
- return((code >= 0x2070) && (code <= 0x209F));
-}
-
-/**
- * xmlUCSIsSyriac:
- * @code: UCS code point
- *
- * Check whether the character is part of Syriac UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsSyriac(int code) {
- return((code >= 0x0700) && (code <= 0x074F));
-}
-
-/**
- * xmlUCSIsTags:
- * @code: UCS code point
- *
- * Check whether the character is part of Tags UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsTags(int code) {
- return((code >= 0xE0000) && (code <= 0xE007F));
-}
-
-/**
- * xmlUCSIsTamil:
- * @code: UCS code point
- *
- * Check whether the character is part of Tamil UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsTamil(int code) {
- return((code >= 0x0B80) && (code <= 0x0BFF));
-}
-
-/**
- * xmlUCSIsTelugu:
- * @code: UCS code point
- *
- * Check whether the character is part of Telugu UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsTelugu(int code) {
- return((code >= 0x0C00) && (code <= 0x0C7F));
-}
-
-/**
- * xmlUCSIsThaana:
- * @code: UCS code point
- *
- * Check whether the character is part of Thaana UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsThaana(int code) {
- return((code >= 0x0780) && (code <= 0x07BF));
-}
-
-/**
- * xmlUCSIsThai:
- * @code: UCS code point
- *
- * Check whether the character is part of Thai UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsThai(int code) {
- return((code >= 0x0E00) && (code <= 0x0E7F));
-}
-
-/**
- * xmlUCSIsTibetan:
- * @code: UCS code point
- *
- * Check whether the character is part of Tibetan UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsTibetan(int code) {
- return((code >= 0x0F00) && (code <= 0x0FFF));
-}
-
-/**
- * xmlUCSIsUnifiedCanadianAboriginalSyllabics:
- * @code: UCS code point
- *
- * Check whether the character is part of UnifiedCanadianAboriginalSyllabics UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsUnifiedCanadianAboriginalSyllabics(int code) {
- return((code >= 0x1400) && (code <= 0x167F));
-}
-
-/**
- * xmlUCSIsYiRadicals:
- * @code: UCS code point
- *
- * Check whether the character is part of YiRadicals UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsYiRadicals(int code) {
- return((code >= 0xA490) && (code <= 0xA4CF));
-}
-
-/**
- * xmlUCSIsYiSyllables:
- * @code: UCS code point
- *
- * Check whether the character is part of YiSyllables UCS Block
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsYiSyllables(int code) {
- return((code >= 0xA000) && (code <= 0xA48F));
-}
-
-/**
- * xmlUCSIsBlock:
- * @code: UCS code point
- * @block: UCS block name
- *
- * Check whether the caracter is part of the UCS Block
- *
- * Returns 1 if true, 0 if false and -1 on unknown block
- */
-int
-xmlUCSIsBlock(int code, const char *block) {
- if (!strcmp(block, "AlphabeticPresentationForms"))
- return(xmlUCSIsAlphabeticPresentationForms(code));
- if (!strcmp(block, "Arabic"))
- return(xmlUCSIsArabic(code));
- if (!strcmp(block, "ArabicPresentationForms-A"))
- return(xmlUCSIsArabicPresentationFormsA(code));
- if (!strcmp(block, "ArabicPresentationForms-B"))
- return(xmlUCSIsArabicPresentationFormsB(code));
- if (!strcmp(block, "Armenian"))
- return(xmlUCSIsArmenian(code));
- if (!strcmp(block, "Arrows"))
- return(xmlUCSIsArrows(code));
- if (!strcmp(block, "BasicLatin"))
- return(xmlUCSIsBasicLatin(code));
- if (!strcmp(block, "Bengali"))
- return(xmlUCSIsBengali(code));
- if (!strcmp(block, "BlockElements"))
- return(xmlUCSIsBlockElements(code));
- if (!strcmp(block, "Bopomofo"))
- return(xmlUCSIsBopomofo(code));
- if (!strcmp(block, "BopomofoExtended"))
- return(xmlUCSIsBopomofoExtended(code));
- if (!strcmp(block, "BoxDrawing"))
- return(xmlUCSIsBoxDrawing(code));
- if (!strcmp(block, "BraillePatterns"))
- return(xmlUCSIsBraillePatterns(code));
- if (!strcmp(block, "ByzantineMusicalSymbols"))
- return(xmlUCSIsByzantineMusicalSymbols(code));
- if (!strcmp(block, "CJKCompatibility"))
- return(xmlUCSIsCJKCompatibility(code));
- if (!strcmp(block, "CJKCompatibilityForms"))
- return(xmlUCSIsCJKCompatibilityForms(code));
- if (!strcmp(block, "CJKCompatibilityIdeographs"))
- return(xmlUCSIsCJKCompatibilityIdeographs(code));
- if (!strcmp(block, "CJKCompatibilityIdeographsSupplement"))
- return(xmlUCSIsCJKCompatibilityIdeographsSupplement(code));
- if (!strcmp(block, "CJKRadicalsSupplement"))
- return(xmlUCSIsCJKRadicalsSupplement(code));
- if (!strcmp(block, "CJKSymbolsandPunctuation"))
- return(xmlUCSIsCJKSymbolsandPunctuation(code));
- if (!strcmp(block, "CJKUnifiedIdeographs"))
- return(xmlUCSIsCJKUnifiedIdeographs(code));
- if (!strcmp(block, "CJKUnifiedIdeographsExtensionA"))
- return(xmlUCSIsCJKUnifiedIdeographsExtensionA(code));
- if (!strcmp(block, "CJKUnifiedIdeographsExtensionB"))
- return(xmlUCSIsCJKUnifiedIdeographsExtensionB(code));
- if (!strcmp(block, "Cherokee"))
- return(xmlUCSIsCherokee(code));
- if (!strcmp(block, "CombiningDiacriticalMarks"))
- return(xmlUCSIsCombiningDiacriticalMarks(code));
- if (!strcmp(block, "CombiningHalfMarks"))
- return(xmlUCSIsCombiningHalfMarks(code));
- if (!strcmp(block, "CombiningMarksforSymbols"))
- return(xmlUCSIsCombiningMarksforSymbols(code));
- if (!strcmp(block, "ControlPictures"))
- return(xmlUCSIsControlPictures(code));
- if (!strcmp(block, "CurrencySymbols"))
- return(xmlUCSIsCurrencySymbols(code));
- if (!strcmp(block, "Cyrillic"))
- return(xmlUCSIsCyrillic(code));
- if (!strcmp(block, "Deseret"))
- return(xmlUCSIsDeseret(code));
- if (!strcmp(block, "Devanagari"))
- return(xmlUCSIsDevanagari(code));
- if (!strcmp(block, "Dingbats"))
- return(xmlUCSIsDingbats(code));
- if (!strcmp(block, "EnclosedAlphanumerics"))
- return(xmlUCSIsEnclosedAlphanumerics(code));
- if (!strcmp(block, "EnclosedCJKLettersandMonths"))
- return(xmlUCSIsEnclosedCJKLettersandMonths(code));
- if (!strcmp(block, "Ethiopic"))
- return(xmlUCSIsEthiopic(code));
- if (!strcmp(block, "GeneralPunctuation"))
- return(xmlUCSIsGeneralPunctuation(code));
- if (!strcmp(block, "GeometricShapes"))
- return(xmlUCSIsGeometricShapes(code));
- if (!strcmp(block, "Georgian"))
- return(xmlUCSIsGeorgian(code));
- if (!strcmp(block, "Gothic"))
- return(xmlUCSIsGothic(code));
- if (!strcmp(block, "Greek"))
- return(xmlUCSIsGreek(code));
- if (!strcmp(block, "GreekExtended"))
- return(xmlUCSIsGreekExtended(code));
- if (!strcmp(block, "Gujarati"))
- return(xmlUCSIsGujarati(code));
- if (!strcmp(block, "Gurmukhi"))
- return(xmlUCSIsGurmukhi(code));
- if (!strcmp(block, "HalfwidthandFullwidthForms"))
- return(xmlUCSIsHalfwidthandFullwidthForms(code));
- if (!strcmp(block, "HangulCompatibilityJamo"))
- return(xmlUCSIsHangulCompatibilityJamo(code));
- if (!strcmp(block, "HangulJamo"))
- return(xmlUCSIsHangulJamo(code));
- if (!strcmp(block, "HangulSyllables"))
- return(xmlUCSIsHangulSyllables(code));
- if (!strcmp(block, "Hebrew"))
- return(xmlUCSIsHebrew(code));
- if (!strcmp(block, "HighPrivateUseSurrogates"))
- return(xmlUCSIsHighPrivateUseSurrogates(code));
- if (!strcmp(block, "HighSurrogates"))
- return(xmlUCSIsHighSurrogates(code));
- if (!strcmp(block, "Hiragana"))
- return(xmlUCSIsHiragana(code));
- if (!strcmp(block, "IPAExtensions"))
- return(xmlUCSIsIPAExtensions(code));
- if (!strcmp(block, "IdeographicDescriptionCharacters"))
- return(xmlUCSIsIdeographicDescriptionCharacters(code));
- if (!strcmp(block, "Kanbun"))
- return(xmlUCSIsKanbun(code));
- if (!strcmp(block, "KangxiRadicals"))
- return(xmlUCSIsKangxiRadicals(code));
- if (!strcmp(block, "Kannada"))
- return(xmlUCSIsKannada(code));
- if (!strcmp(block, "Katakana"))
- return(xmlUCSIsKatakana(code));
- if (!strcmp(block, "Khmer"))
- return(xmlUCSIsKhmer(code));
- if (!strcmp(block, "Lao"))
- return(xmlUCSIsLao(code));
- if (!strcmp(block, "Latin-1Supplement"))
- return(xmlUCSIsLatin1Supplement(code));
- if (!strcmp(block, "LatinExtended-A"))
- return(xmlUCSIsLatinExtendedA(code));
- if (!strcmp(block, "LatinExtended-B"))
- return(xmlUCSIsLatinExtendedB(code));
- if (!strcmp(block, "LatinExtendedAdditional"))
- return(xmlUCSIsLatinExtendedAdditional(code));
- if (!strcmp(block, "LetterlikeSymbols"))
- return(xmlUCSIsLetterlikeSymbols(code));
- if (!strcmp(block, "LowSurrogates"))
- return(xmlUCSIsLowSurrogates(code));
- if (!strcmp(block, "Malayalam"))
- return(xmlUCSIsMalayalam(code));
- if (!strcmp(block, "MathematicalAlphanumericSymbols"))
- return(xmlUCSIsMathematicalAlphanumericSymbols(code));
- if (!strcmp(block, "MathematicalOperators"))
- return(xmlUCSIsMathematicalOperators(code));
- if (!strcmp(block, "MiscellaneousSymbols"))
- return(xmlUCSIsMiscellaneousSymbols(code));
- if (!strcmp(block, "MiscellaneousTechnical"))
- return(xmlUCSIsMiscellaneousTechnical(code));
- if (!strcmp(block, "Mongolian"))
- return(xmlUCSIsMongolian(code));
- if (!strcmp(block, "MusicalSymbols"))
- return(xmlUCSIsMusicalSymbols(code));
- if (!strcmp(block, "Myanmar"))
- return(xmlUCSIsMyanmar(code));
- if (!strcmp(block, "NumberForms"))
- return(xmlUCSIsNumberForms(code));
- if (!strcmp(block, "Ogham"))
- return(xmlUCSIsOgham(code));
- if (!strcmp(block, "OldItalic"))
- return(xmlUCSIsOldItalic(code));
- if (!strcmp(block, "OpticalCharacterRecognition"))
- return(xmlUCSIsOpticalCharacterRecognition(code));
- if (!strcmp(block, "Oriya"))
- return(xmlUCSIsOriya(code));
- if (!strcmp(block, "PrivateUse"))
- return(xmlUCSIsPrivateUse(code));
- if (!strcmp(block, "Runic"))
- return(xmlUCSIsRunic(code));
- if (!strcmp(block, "Sinhala"))
- return(xmlUCSIsSinhala(code));
- if (!strcmp(block, "SmallFormVariants"))
- return(xmlUCSIsSmallFormVariants(code));
- if (!strcmp(block, "SpacingModifierLetters"))
- return(xmlUCSIsSpacingModifierLetters(code));
- if (!strcmp(block, "Specials"))
- return(xmlUCSIsSpecials(code));
- if (!strcmp(block, "SuperscriptsandSubscripts"))
- return(xmlUCSIsSuperscriptsandSubscripts(code));
- if (!strcmp(block, "Syriac"))
- return(xmlUCSIsSyriac(code));
- if (!strcmp(block, "Tags"))
- return(xmlUCSIsTags(code));
- if (!strcmp(block, "Tamil"))
- return(xmlUCSIsTamil(code));
- if (!strcmp(block, "Telugu"))
- return(xmlUCSIsTelugu(code));
- if (!strcmp(block, "Thaana"))
- return(xmlUCSIsThaana(code));
- if (!strcmp(block, "Thai"))
- return(xmlUCSIsThai(code));
- if (!strcmp(block, "Tibetan"))
- return(xmlUCSIsTibetan(code));
- if (!strcmp(block, "UnifiedCanadianAboriginalSyllabics"))
- return(xmlUCSIsUnifiedCanadianAboriginalSyllabics(code));
- if (!strcmp(block, "YiRadicals"))
- return(xmlUCSIsYiRadicals(code));
- if (!strcmp(block, "YiSyllables"))
- return(xmlUCSIsYiSyllables(code));
- return(-1);
-}
-
-/**
- * xmlUCSIsCatC:
- * @code: UCS code point
- *
- * Check whether the character is part of C UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatC(int code) {
- return(((code >= 0x0) && (code <= 0x1f)) ||
- ((code >= 0x7f) && (code <= 0x9f)) ||
- (code == 0x70f) ||
- ((code >= 0x180b) && (code <= 0x180e)) ||
- ((code >= 0x200c) && (code <= 0x200f)) ||
- ((code >= 0x202a) && (code <= 0x202e)) ||
- ((code >= 0x206a) && (code <= 0x206f)) ||
- (code == 0xd800) ||
- ((code >= 0xdb7f) && (code <= 0xdb80)) ||
- ((code >= 0xdbff) && (code <= 0xdc00)) ||
- ((code >= 0xdfff) && (code <= 0xe000)) ||
- (code == 0xf8ff) ||
- (code == 0xfeff) ||
- ((code >= 0xfff9) && (code <= 0xfffb)) ||
- ((code >= 0x1d173) && (code <= 0x1d17a)) ||
- (code == 0xe0001) ||
- ((code >= 0xe0020) && (code <= 0xe007f)) ||
- (code == 0xf0000) ||
- (code == 0xffffd) ||
- (code == 0x100000) ||
- (code == 0x10fffd));
-}
-
-/**
- * xmlUCSIsCatCc:
- * @code: UCS code point
- *
- * Check whether the character is part of Cc UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatCc(int code) {
- return(((code >= 0x0) && (code <= 0x1f)) ||
- ((code >= 0x7f) && (code <= 0x9f)));
-}
-
-/**
- * xmlUCSIsCatCf:
- * @code: UCS code point
- *
- * Check whether the character is part of Cf UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatCf(int code) {
- return((code == 0x70f) ||
- ((code >= 0x180b) && (code <= 0x180e)) ||
- ((code >= 0x200c) && (code <= 0x200f)) ||
- ((code >= 0x202a) && (code <= 0x202e)) ||
- ((code >= 0x206a) && (code <= 0x206f)) ||
- (code == 0xfeff) ||
- ((code >= 0xfff9) && (code <= 0xfffb)) ||
- ((code >= 0x1d173) && (code <= 0x1d17a)) ||
- (code == 0xe0001) ||
- ((code >= 0xe0020) && (code <= 0xe007f)));
-}
-
-/**
- * xmlUCSIsCatCo:
- * @code: UCS code point
- *
- * Check whether the character is part of Co UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatCo(int code) {
- return((code == 0xe000) ||
- (code == 0xf8ff) ||
- (code == 0xf0000) ||
- (code == 0xffffd) ||
- (code == 0x100000) ||
- (code == 0x10fffd));
-}
-
-/**
- * xmlUCSIsCatCs:
- * @code: UCS code point
- *
- * Check whether the character is part of Cs UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatCs(int code) {
- return((code == 0xd800) ||
- ((code >= 0xdb7f) && (code <= 0xdb80)) ||
- ((code >= 0xdbff) && (code <= 0xdc00)) ||
- (code == 0xdfff));
-}
-
-/**
- * xmlUCSIsCatL:
- * @code: UCS code point
- *
- * Check whether the character is part of L UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatL(int code) {
- return(((code >= 0x41) && (code <= 0x5a)) ||
- ((code >= 0x61) && (code <= 0x7a)) ||
- (code == 0xaa) ||
- (code == 0xb5) ||
- (code == 0xba) ||
- ((code >= 0xc0) && (code <= 0xd6)) ||
- ((code >= 0xd8) && (code <= 0xf6)) ||
- ((code >= 0xf8) && (code <= 0x21f)) ||
- ((code >= 0x222) && (code <= 0x233)) ||
- ((code >= 0x250) && (code <= 0x2ad)) ||
- ((code >= 0x2b0) && (code <= 0x2b8)) ||
- ((code >= 0x2bb) && (code <= 0x2c1)) ||
- ((code >= 0x2d0) && (code <= 0x2d1)) ||
- ((code >= 0x2e0) && (code <= 0x2e4)) ||
- (code == 0x2ee) ||
- (code == 0x37a) ||
- (code == 0x386) ||
- ((code >= 0x388) && (code <= 0x38a)) ||
- (code == 0x38c) ||
- ((code >= 0x38e) && (code <= 0x3a1)) ||
- ((code >= 0x3a3) && (code <= 0x3ce)) ||
- ((code >= 0x3d0) && (code <= 0x3d7)) ||
- ((code >= 0x3da) && (code <= 0x3f5)) ||
- ((code >= 0x400) && (code <= 0x481)) ||
- ((code >= 0x48c) && (code <= 0x4c4)) ||
- ((code >= 0x4c7) && (code <= 0x4c8)) ||
- ((code >= 0x4cb) && (code <= 0x4cc)) ||
- ((code >= 0x4d0) && (code <= 0x4f5)) ||
- ((code >= 0x4f8) && (code <= 0x4f9)) ||
- ((code >= 0x531) && (code <= 0x556)) ||
- (code == 0x559) ||
- ((code >= 0x561) && (code <= 0x587)) ||
- ((code >= 0x5d0) && (code <= 0x5ea)) ||
- ((code >= 0x5f0) && (code <= 0x5f2)) ||
- ((code >= 0x621) && (code <= 0x63a)) ||
- ((code >= 0x640) && (code <= 0x64a)) ||
- ((code >= 0x671) && (code <= 0x6d3)) ||
- (code == 0x6d5) ||
- ((code >= 0x6e5) && (code <= 0x6e6)) ||
- ((code >= 0x6fa) && (code <= 0x6fc)) ||
- (code == 0x710) ||
- ((code >= 0x712) && (code <= 0x72c)) ||
- ((code >= 0x780) && (code <= 0x7a5)) ||
- ((code >= 0x905) && (code <= 0x939)) ||
- (code == 0x93d) ||
- (code == 0x950) ||
- ((code >= 0x958) && (code <= 0x961)) ||
- ((code >= 0x985) && (code <= 0x98c)) ||
- ((code >= 0x98f) && (code <= 0x990)) ||
- ((code >= 0x993) && (code <= 0x9a8)) ||
- ((code >= 0x9aa) && (code <= 0x9b0)) ||
- (code == 0x9b2) ||
- ((code >= 0x9b6) && (code <= 0x9b9)) ||
- ((code >= 0x9dc) && (code <= 0x9dd)) ||
- ((code >= 0x9df) && (code <= 0x9e1)) ||
- ((code >= 0x9f0) && (code <= 0x9f1)) ||
- ((code >= 0xa05) && (code <= 0xa0a)) ||
- ((code >= 0xa0f) && (code <= 0xa10)) ||
- ((code >= 0xa13) && (code <= 0xa28)) ||
- ((code >= 0xa2a) && (code <= 0xa30)) ||
- ((code >= 0xa32) && (code <= 0xa33)) ||
- ((code >= 0xa35) && (code <= 0xa36)) ||
- ((code >= 0xa38) && (code <= 0xa39)) ||
- ((code >= 0xa59) && (code <= 0xa5c)) ||
- (code == 0xa5e) ||
- ((code >= 0xa72) && (code <= 0xa74)) ||
- ((code >= 0xa85) && (code <= 0xa8b)) ||
- (code == 0xa8d) ||
- ((code >= 0xa8f) && (code <= 0xa91)) ||
- ((code >= 0xa93) && (code <= 0xaa8)) ||
- ((code >= 0xaaa) && (code <= 0xab0)) ||
- ((code >= 0xab2) && (code <= 0xab3)) ||
- ((code >= 0xab5) && (code <= 0xab9)) ||
- (code == 0xabd) ||
- (code == 0xad0) ||
- (code == 0xae0) ||
- ((code >= 0xb05) && (code <= 0xb0c)) ||
- ((code >= 0xb0f) && (code <= 0xb10)) ||
- ((code >= 0xb13) && (code <= 0xb28)) ||
- ((code >= 0xb2a) && (code <= 0xb30)) ||
- ((code >= 0xb32) && (code <= 0xb33)) ||
- ((code >= 0xb36) && (code <= 0xb39)) ||
- (code == 0xb3d) ||
- ((code >= 0xb5c) && (code <= 0xb5d)) ||
- ((code >= 0xb5f) && (code <= 0xb61)) ||
- ((code >= 0xb85) && (code <= 0xb8a)) ||
- ((code >= 0xb8e) && (code <= 0xb90)) ||
- ((code >= 0xb92) && (code <= 0xb95)) ||
- ((code >= 0xb99) && (code <= 0xb9a)) ||
- (code == 0xb9c) ||
- ((code >= 0xb9e) && (code <= 0xb9f)) ||
- ((code >= 0xba3) && (code <= 0xba4)) ||
- ((code >= 0xba8) && (code <= 0xbaa)) ||
- ((code >= 0xbae) && (code <= 0xbb5)) ||
- ((code >= 0xbb7) && (code <= 0xbb9)) ||
- ((code >= 0xc05) && (code <= 0xc0c)) ||
- ((code >= 0xc0e) && (code <= 0xc10)) ||
- ((code >= 0xc12) && (code <= 0xc28)) ||
- ((code >= 0xc2a) && (code <= 0xc33)) ||
- ((code >= 0xc35) && (code <= 0xc39)) ||
- ((code >= 0xc60) && (code <= 0xc61)) ||
- ((code >= 0xc85) && (code <= 0xc8c)) ||
- ((code >= 0xc8e) && (code <= 0xc90)) ||
- ((code >= 0xc92) && (code <= 0xca8)) ||
- ((code >= 0xcaa) && (code <= 0xcb3)) ||
- ((code >= 0xcb5) && (code <= 0xcb9)) ||
- (code == 0xcde) ||
- ((code >= 0xce0) && (code <= 0xce1)) ||
- ((code >= 0xd05) && (code <= 0xd0c)) ||
- ((code >= 0xd0e) && (code <= 0xd10)) ||
- ((code >= 0xd12) && (code <= 0xd28)) ||
- ((code >= 0xd2a) && (code <= 0xd39)) ||
- ((code >= 0xd60) && (code <= 0xd61)) ||
- ((code >= 0xd85) && (code <= 0xd96)) ||
- ((code >= 0xd9a) && (code <= 0xdb1)) ||
- ((code >= 0xdb3) && (code <= 0xdbb)) ||
- (code == 0xdbd) ||
- ((code >= 0xdc0) && (code <= 0xdc6)) ||
- ((code >= 0xe01) && (code <= 0xe30)) ||
- ((code >= 0xe32) && (code <= 0xe33)) ||
- ((code >= 0xe40) && (code <= 0xe46)) ||
- ((code >= 0xe81) && (code <= 0xe82)) ||
- (code == 0xe84) ||
- ((code >= 0xe87) && (code <= 0xe88)) ||
- (code == 0xe8a) ||
- (code == 0xe8d) ||
- ((code >= 0xe94) && (code <= 0xe97)) ||
- ((code >= 0xe99) && (code <= 0xe9f)) ||
- ((code >= 0xea1) && (code <= 0xea3)) ||
- (code == 0xea5) ||
- (code == 0xea7) ||
- ((code >= 0xeaa) && (code <= 0xeab)) ||
- ((code >= 0xead) && (code <= 0xeb0)) ||
- ((code >= 0xeb2) && (code <= 0xeb3)) ||
- (code == 0xebd) ||
- ((code >= 0xec0) && (code <= 0xec4)) ||
- (code == 0xec6) ||
- ((code >= 0xedc) && (code <= 0xedd)) ||
- (code == 0xf00) ||
- ((code >= 0xf40) && (code <= 0xf47)) ||
- ((code >= 0xf49) && (code <= 0xf6a)) ||
- ((code >= 0xf88) && (code <= 0xf8b)) ||
- ((code >= 0x1000) && (code <= 0x1021)) ||
- ((code >= 0x1023) && (code <= 0x1027)) ||
- ((code >= 0x1029) && (code <= 0x102a)) ||
- ((code >= 0x1050) && (code <= 0x1055)) ||
- ((code >= 0x10a0) && (code <= 0x10c5)) ||
- ((code >= 0x10d0) && (code <= 0x10f6)) ||
- ((code >= 0x1100) && (code <= 0x1159)) ||
- ((code >= 0x115f) && (code <= 0x11a2)) ||
- ((code >= 0x11a8) && (code <= 0x11f9)) ||
- ((code >= 0x1200) && (code <= 0x1206)) ||
- ((code >= 0x1208) && (code <= 0x1246)) ||
- (code == 0x1248) ||
- ((code >= 0x124a) && (code <= 0x124d)) ||
- ((code >= 0x1250) && (code <= 0x1256)) ||
- (code == 0x1258) ||
- ((code >= 0x125a) && (code <= 0x125d)) ||
- ((code >= 0x1260) && (code <= 0x1286)) ||
- (code == 0x1288) ||
- ((code >= 0x128a) && (code <= 0x128d)) ||
- ((code >= 0x1290) && (code <= 0x12ae)) ||
- (code == 0x12b0) ||
- ((code >= 0x12b2) && (code <= 0x12b5)) ||
- ((code >= 0x12b8) && (code <= 0x12be)) ||
- (code == 0x12c0) ||
- ((code >= 0x12c2) && (code <= 0x12c5)) ||
- ((code >= 0x12c8) && (code <= 0x12ce)) ||
- ((code >= 0x12d0) && (code <= 0x12d6)) ||
- ((code >= 0x12d8) && (code <= 0x12ee)) ||
- ((code >= 0x12f0) && (code <= 0x130e)) ||
- (code == 0x1310) ||
- ((code >= 0x1312) && (code <= 0x1315)) ||
- ((code >= 0x1318) && (code <= 0x131e)) ||
- ((code >= 0x1320) && (code <= 0x1346)) ||
- ((code >= 0x1348) && (code <= 0x135a)) ||
- ((code >= 0x13a0) && (code <= 0x13f4)) ||
- ((code >= 0x1401) && (code <= 0x166c)) ||
- ((code >= 0x166f) && (code <= 0x1676)) ||
- ((code >= 0x1681) && (code <= 0x169a)) ||
- ((code >= 0x16a0) && (code <= 0x16ea)) ||
- ((code >= 0x1780) && (code <= 0x17b3)) ||
- ((code >= 0x1820) && (code <= 0x1877)) ||
- ((code >= 0x1880) && (code <= 0x18a8)) ||
- ((code >= 0x1e00) && (code <= 0x1e9b)) ||
- ((code >= 0x1ea0) && (code <= 0x1ef9)) ||
- ((code >= 0x1f00) && (code <= 0x1f15)) ||
- ((code >= 0x1f18) && (code <= 0x1f1d)) ||
- ((code >= 0x1f20) && (code <= 0x1f45)) ||
- ((code >= 0x1f48) && (code <= 0x1f4d)) ||
- ((code >= 0x1f50) && (code <= 0x1f57)) ||
- (code == 0x1f59) ||
- (code == 0x1f5b) ||
- (code == 0x1f5d) ||
- ((code >= 0x1f5f) && (code <= 0x1f7d)) ||
- ((code >= 0x1f80) && (code <= 0x1fb4)) ||
- ((code >= 0x1fb6) && (code <= 0x1fbc)) ||
- (code == 0x1fbe) ||
- ((code >= 0x1fc2) && (code <= 0x1fc4)) ||
- ((code >= 0x1fc6) && (code <= 0x1fcc)) ||
- ((code >= 0x1fd0) && (code <= 0x1fd3)) ||
- ((code >= 0x1fd6) && (code <= 0x1fdb)) ||
- ((code >= 0x1fe0) && (code <= 0x1fec)) ||
- ((code >= 0x1ff2) && (code <= 0x1ff4)) ||
- ((code >= 0x1ff6) && (code <= 0x1ffc)) ||
- (code == 0x207f) ||
- (code == 0x2102) ||
- (code == 0x2107) ||
- ((code >= 0x210a) && (code <= 0x2113)) ||
- (code == 0x2115) ||
- ((code >= 0x2119) && (code <= 0x211d)) ||
- (code == 0x2124) ||
- (code == 0x2126) ||
- (code == 0x2128) ||
- ((code >= 0x212a) && (code <= 0x212d)) ||
- ((code >= 0x212f) && (code <= 0x2131)) ||
- ((code >= 0x2133) && (code <= 0x2139)) ||
- ((code >= 0x3005) && (code <= 0x3006)) ||
- ((code >= 0x3031) && (code <= 0x3035)) ||
- ((code >= 0x3041) && (code <= 0x3094)) ||
- ((code >= 0x309d) && (code <= 0x309e)) ||
- ((code >= 0x30a1) && (code <= 0x30fa)) ||
- ((code >= 0x30fc) && (code <= 0x30fe)) ||
- ((code >= 0x3105) && (code <= 0x312c)) ||
- ((code >= 0x3131) && (code <= 0x318e)) ||
- ((code >= 0x31a0) && (code <= 0x31b7)) ||
- (code == 0x3400) ||
- (code == 0x4db5) ||
- (code == 0x4e00) ||
- (code == 0x9fa5) ||
- ((code >= 0xa000) && (code <= 0xa48c)) ||
- (code == 0xac00) ||
- (code == 0xd7a3) ||
- ((code >= 0xf900) && (code <= 0xfa2d)) ||
- ((code >= 0xfb00) && (code <= 0xfb06)) ||
- ((code >= 0xfb13) && (code <= 0xfb17)) ||
- (code == 0xfb1d) ||
- ((code >= 0xfb1f) && (code <= 0xfb28)) ||
- ((code >= 0xfb2a) && (code <= 0xfb36)) ||
- ((code >= 0xfb38) && (code <= 0xfb3c)) ||
- (code == 0xfb3e) ||
- ((code >= 0xfb40) && (code <= 0xfb41)) ||
- ((code >= 0xfb43) && (code <= 0xfb44)) ||
- ((code >= 0xfb46) && (code <= 0xfbb1)) ||
- ((code >= 0xfbd3) && (code <= 0xfd3d)) ||
- ((code >= 0xfd50) && (code <= 0xfd8f)) ||
- ((code >= 0xfd92) && (code <= 0xfdc7)) ||
- ((code >= 0xfdf0) && (code <= 0xfdfb)) ||
- ((code >= 0xfe70) && (code <= 0xfe72)) ||
- (code == 0xfe74) ||
- ((code >= 0xfe76) && (code <= 0xfefc)) ||
- ((code >= 0xff21) && (code <= 0xff3a)) ||
- ((code >= 0xff41) && (code <= 0xff5a)) ||
- ((code >= 0xff66) && (code <= 0xffbe)) ||
- ((code >= 0xffc2) && (code <= 0xffc7)) ||
- ((code >= 0xffca) && (code <= 0xffcf)) ||
- ((code >= 0xffd2) && (code <= 0xffd7)) ||
- ((code >= 0xffda) && (code <= 0xffdc)) ||
- ((code >= 0x10300) && (code <= 0x1031e)) ||
- ((code >= 0x10330) && (code <= 0x10349)) ||
- ((code >= 0x10400) && (code <= 0x10425)) ||
- ((code >= 0x10428) && (code <= 0x1044d)) ||
- ((code >= 0x1d400) && (code <= 0x1d454)) ||
- ((code >= 0x1d456) && (code <= 0x1d49c)) ||
- ((code >= 0x1d49e) && (code <= 0x1d49f)) ||
- (code == 0x1d4a2) ||
- ((code >= 0x1d4a5) && (code <= 0x1d4a6)) ||
- ((code >= 0x1d4a9) && (code <= 0x1d4ac)) ||
- ((code >= 0x1d4ae) && (code <= 0x1d4b9)) ||
- (code == 0x1d4bb) ||
- ((code >= 0x1d4bd) && (code <= 0x1d4c0)) ||
- ((code >= 0x1d4c2) && (code <= 0x1d4c3)) ||
- ((code >= 0x1d4c5) && (code <= 0x1d505)) ||
- ((code >= 0x1d507) && (code <= 0x1d50a)) ||
- ((code >= 0x1d50d) && (code <= 0x1d514)) ||
- ((code >= 0x1d516) && (code <= 0x1d51c)) ||
- ((code >= 0x1d51e) && (code <= 0x1d539)) ||
- ((code >= 0x1d53b) && (code <= 0x1d53e)) ||
- ((code >= 0x1d540) && (code <= 0x1d544)) ||
- (code == 0x1d546) ||
- ((code >= 0x1d54a) && (code <= 0x1d550)) ||
- ((code >= 0x1d552) && (code <= 0x1d6a3)) ||
- ((code >= 0x1d6a8) && (code <= 0x1d6c0)) ||
- ((code >= 0x1d6c2) && (code <= 0x1d6da)) ||
- ((code >= 0x1d6dc) && (code <= 0x1d6fa)) ||
- ((code >= 0x1d6fc) && (code <= 0x1d714)) ||
- ((code >= 0x1d716) && (code <= 0x1d734)) ||
- ((code >= 0x1d736) && (code <= 0x1d74e)) ||
- ((code >= 0x1d750) && (code <= 0x1d76e)) ||
- ((code >= 0x1d770) && (code <= 0x1d788)) ||
- ((code >= 0x1d78a) && (code <= 0x1d7a8)) ||
- ((code >= 0x1d7aa) && (code <= 0x1d7c2)) ||
- ((code >= 0x1d7c4) && (code <= 0x1d7c9)) ||
- (code == 0x20000) ||
- (code == 0x2a6d6) ||
- ((code >= 0x2f800) && (code <= 0x2fa1d)));
-}
-
-/**
- * xmlUCSIsCatLl:
- * @code: UCS code point
- *
- * Check whether the character is part of Ll UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatLl(int code) {
- return(((code >= 0x61) && (code <= 0x7a)) ||
- (code == 0xaa) ||
- (code == 0xb5) ||
- (code == 0xba) ||
- ((code >= 0xdf) && (code <= 0xf6)) ||
- ((code >= 0xf8) && (code <= 0xff)) ||
- (code == 0x101) ||
- (code == 0x103) ||
- (code == 0x105) ||
- (code == 0x107) ||
- (code == 0x109) ||
- (code == 0x10b) ||
- (code == 0x10d) ||
- (code == 0x10f) ||
- (code == 0x111) ||
- (code == 0x113) ||
- (code == 0x115) ||
- (code == 0x117) ||
- (code == 0x119) ||
- (code == 0x11b) ||
- (code == 0x11d) ||
- (code == 0x11f) ||
- (code == 0x121) ||
- (code == 0x123) ||
- (code == 0x125) ||
- (code == 0x127) ||
- (code == 0x129) ||
- (code == 0x12b) ||
- (code == 0x12d) ||
- (code == 0x12f) ||
- (code == 0x131) ||
- (code == 0x133) ||
- (code == 0x135) ||
- ((code >= 0x137) && (code <= 0x138)) ||
- (code == 0x13a) ||
- (code == 0x13c) ||
- (code == 0x13e) ||
- (code == 0x140) ||
- (code == 0x142) ||
- (code == 0x144) ||
- (code == 0x146) ||
- ((code >= 0x148) && (code <= 0x149)) ||
- (code == 0x14b) ||
- (code == 0x14d) ||
- (code == 0x14f) ||
- (code == 0x151) ||
- (code == 0x153) ||
- (code == 0x155) ||
- (code == 0x157) ||
- (code == 0x159) ||
- (code == 0x15b) ||
- (code == 0x15d) ||
- (code == 0x15f) ||
- (code == 0x161) ||
- (code == 0x163) ||
- (code == 0x165) ||
- (code == 0x167) ||
- (code == 0x169) ||
- (code == 0x16b) ||
- (code == 0x16d) ||
- (code == 0x16f) ||
- (code == 0x171) ||
- (code == 0x173) ||
- (code == 0x175) ||
- (code == 0x177) ||
- (code == 0x17a) ||
- (code == 0x17c) ||
- ((code >= 0x17e) && (code <= 0x180)) ||
- (code == 0x183) ||
- (code == 0x185) ||
- (code == 0x188) ||
- ((code >= 0x18c) && (code <= 0x18d)) ||
- (code == 0x192) ||
- (code == 0x195) ||
- ((code >= 0x199) && (code <= 0x19b)) ||
- (code == 0x19e) ||
- (code == 0x1a1) ||
- (code == 0x1a3) ||
- (code == 0x1a5) ||
- (code == 0x1a8) ||
- ((code >= 0x1aa) && (code <= 0x1ab)) ||
- (code == 0x1ad) ||
- (code == 0x1b0) ||
- (code == 0x1b4) ||
- (code == 0x1b6) ||
- ((code >= 0x1b9) && (code <= 0x1ba)) ||
- ((code >= 0x1bd) && (code <= 0x1bf)) ||
- (code == 0x1c6) ||
- (code == 0x1c9) ||
- (code == 0x1cc) ||
- (code == 0x1ce) ||
- (code == 0x1d0) ||
- (code == 0x1d2) ||
- (code == 0x1d4) ||
- (code == 0x1d6) ||
- (code == 0x1d8) ||
- (code == 0x1da) ||
- ((code >= 0x1dc) && (code <= 0x1dd)) ||
- (code == 0x1df) ||
- (code == 0x1e1) ||
- (code == 0x1e3) ||
- (code == 0x1e5) ||
- (code == 0x1e7) ||
- (code == 0x1e9) ||
- (code == 0x1eb) ||
- (code == 0x1ed) ||
- ((code >= 0x1ef) && (code <= 0x1f0)) ||
- (code == 0x1f3) ||
- (code == 0x1f5) ||
- (code == 0x1f9) ||
- (code == 0x1fb) ||
- (code == 0x1fd) ||
- (code == 0x1ff) ||
- (code == 0x201) ||
- (code == 0x203) ||
- (code == 0x205) ||
- (code == 0x207) ||
- (code == 0x209) ||
- (code == 0x20b) ||
- (code == 0x20d) ||
- (code == 0x20f) ||
- (code == 0x211) ||
- (code == 0x213) ||
- (code == 0x215) ||
- (code == 0x217) ||
- (code == 0x219) ||
- (code == 0x21b) ||
- (code == 0x21d) ||
- (code == 0x21f) ||
- (code == 0x223) ||
- (code == 0x225) ||
- (code == 0x227) ||
- (code == 0x229) ||
- (code == 0x22b) ||
- (code == 0x22d) ||
- (code == 0x22f) ||
- (code == 0x231) ||
- (code == 0x233) ||
- ((code >= 0x250) && (code <= 0x2ad)) ||
- (code == 0x390) ||
- ((code >= 0x3ac) && (code <= 0x3ce)) ||
- ((code >= 0x3d0) && (code <= 0x3d1)) ||
- ((code >= 0x3d5) && (code <= 0x3d7)) ||
- (code == 0x3db) ||
- (code == 0x3dd) ||
- (code == 0x3df) ||
- (code == 0x3e1) ||
- (code == 0x3e3) ||
- (code == 0x3e5) ||
- (code == 0x3e7) ||
- (code == 0x3e9) ||
- (code == 0x3eb) ||
- (code == 0x3ed) ||
- ((code >= 0x3ef) && (code <= 0x3f3)) ||
- (code == 0x3f5) ||
- ((code >= 0x430) && (code <= 0x45f)) ||
- (code == 0x461) ||
- (code == 0x463) ||
- (code == 0x465) ||
- (code == 0x467) ||
- (code == 0x469) ||
- (code == 0x46b) ||
- (code == 0x46d) ||
- (code == 0x46f) ||
- (code == 0x471) ||
- (code == 0x473) ||
- (code == 0x475) ||
- (code == 0x477) ||
- (code == 0x479) ||
- (code == 0x47b) ||
- (code == 0x47d) ||
- (code == 0x47f) ||
- (code == 0x481) ||
- (code == 0x48d) ||
- (code == 0x48f) ||
- (code == 0x491) ||
- (code == 0x493) ||
- (code == 0x495) ||
- (code == 0x497) ||
- (code == 0x499) ||
- (code == 0x49b) ||
- (code == 0x49d) ||
- (code == 0x49f) ||
- (code == 0x4a1) ||
- (code == 0x4a3) ||
- (code == 0x4a5) ||
- (code == 0x4a7) ||
- (code == 0x4a9) ||
- (code == 0x4ab) ||
- (code == 0x4ad) ||
- (code == 0x4af) ||
- (code == 0x4b1) ||
- (code == 0x4b3) ||
- (code == 0x4b5) ||
- (code == 0x4b7) ||
- (code == 0x4b9) ||
- (code == 0x4bb) ||
- (code == 0x4bd) ||
- (code == 0x4bf) ||
- (code == 0x4c2) ||
- (code == 0x4c4) ||
- (code == 0x4c8) ||
- (code == 0x4cc) ||
- (code == 0x4d1) ||
- (code == 0x4d3) ||
- (code == 0x4d5) ||
- (code == 0x4d7) ||
- (code == 0x4d9) ||
- (code == 0x4db) ||
- (code == 0x4dd) ||
- (code == 0x4df) ||
- (code == 0x4e1) ||
- (code == 0x4e3) ||
- (code == 0x4e5) ||
- (code == 0x4e7) ||
- (code == 0x4e9) ||
- (code == 0x4eb) ||
- (code == 0x4ed) ||
- (code == 0x4ef) ||
- (code == 0x4f1) ||
- (code == 0x4f3) ||
- (code == 0x4f5) ||
- (code == 0x4f9) ||
- ((code >= 0x561) && (code <= 0x587)) ||
- (code == 0x1e01) ||
- (code == 0x1e03) ||
- (code == 0x1e05) ||
- (code == 0x1e07) ||
- (code == 0x1e09) ||
- (code == 0x1e0b) ||
- (code == 0x1e0d) ||
- (code == 0x1e0f) ||
- (code == 0x1e11) ||
- (code == 0x1e13) ||
- (code == 0x1e15) ||
- (code == 0x1e17) ||
- (code == 0x1e19) ||
- (code == 0x1e1b) ||
- (code == 0x1e1d) ||
- (code == 0x1e1f) ||
- (code == 0x1e21) ||
- (code == 0x1e23) ||
- (code == 0x1e25) ||
- (code == 0x1e27) ||
- (code == 0x1e29) ||
- (code == 0x1e2b) ||
- (code == 0x1e2d) ||
- (code == 0x1e2f) ||
- (code == 0x1e31) ||
- (code == 0x1e33) ||
- (code == 0x1e35) ||
- (code == 0x1e37) ||
- (code == 0x1e39) ||
- (code == 0x1e3b) ||
- (code == 0x1e3d) ||
- (code == 0x1e3f) ||
- (code == 0x1e41) ||
- (code == 0x1e43) ||
- (code == 0x1e45) ||
- (code == 0x1e47) ||
- (code == 0x1e49) ||
- (code == 0x1e4b) ||
- (code == 0x1e4d) ||
- (code == 0x1e4f) ||
- (code == 0x1e51) ||
- (code == 0x1e53) ||
- (code == 0x1e55) ||
- (code == 0x1e57) ||
- (code == 0x1e59) ||
- (code == 0x1e5b) ||
- (code == 0x1e5d) ||
- (code == 0x1e5f) ||
- (code == 0x1e61) ||
- (code == 0x1e63) ||
- (code == 0x1e65) ||
- (code == 0x1e67) ||
- (code == 0x1e69) ||
- (code == 0x1e6b) ||
- (code == 0x1e6d) ||
- (code == 0x1e6f) ||
- (code == 0x1e71) ||
- (code == 0x1e73) ||
- (code == 0x1e75) ||
- (code == 0x1e77) ||
- (code == 0x1e79) ||
- (code == 0x1e7b) ||
- (code == 0x1e7d) ||
- (code == 0x1e7f) ||
- (code == 0x1e81) ||
- (code == 0x1e83) ||
- (code == 0x1e85) ||
- (code == 0x1e87) ||
- (code == 0x1e89) ||
- (code == 0x1e8b) ||
- (code == 0x1e8d) ||
- (code == 0x1e8f) ||
- (code == 0x1e91) ||
- (code == 0x1e93) ||
- ((code >= 0x1e95) && (code <= 0x1e9b)) ||
- (code == 0x1ea1) ||
- (code == 0x1ea3) ||
- (code == 0x1ea5) ||
- (code == 0x1ea7) ||
- (code == 0x1ea9) ||
- (code == 0x1eab) ||
- (code == 0x1ead) ||
- (code == 0x1eaf) ||
- (code == 0x1eb1) ||
- (code == 0x1eb3) ||
- (code == 0x1eb5) ||
- (code == 0x1eb7) ||
- (code == 0x1eb9) ||
- (code == 0x1ebb) ||
- (code == 0x1ebd) ||
- (code == 0x1ebf) ||
- (code == 0x1ec1) ||
- (code == 0x1ec3) ||
- (code == 0x1ec5) ||
- (code == 0x1ec7) ||
- (code == 0x1ec9) ||
- (code == 0x1ecb) ||
- (code == 0x1ecd) ||
- (code == 0x1ecf) ||
- (code == 0x1ed1) ||
- (code == 0x1ed3) ||
- (code == 0x1ed5) ||
- (code == 0x1ed7) ||
- (code == 0x1ed9) ||
- (code == 0x1edb) ||
- (code == 0x1edd) ||
- (code == 0x1edf) ||
- (code == 0x1ee1) ||
- (code == 0x1ee3) ||
- (code == 0x1ee5) ||
- (code == 0x1ee7) ||
- (code == 0x1ee9) ||
- (code == 0x1eeb) ||
- (code == 0x1eed) ||
- (code == 0x1eef) ||
- (code == 0x1ef1) ||
- (code == 0x1ef3) ||
- (code == 0x1ef5) ||
- (code == 0x1ef7) ||
- (code == 0x1ef9) ||
- ((code >= 0x1f00) && (code <= 0x1f07)) ||
- ((code >= 0x1f10) && (code <= 0x1f15)) ||
- ((code >= 0x1f20) && (code <= 0x1f27)) ||
- ((code >= 0x1f30) && (code <= 0x1f37)) ||
- ((code >= 0x1f40) && (code <= 0x1f45)) ||
- ((code >= 0x1f50) && (code <= 0x1f57)) ||
- ((code >= 0x1f60) && (code <= 0x1f67)) ||
- ((code >= 0x1f70) && (code <= 0x1f7d)) ||
- ((code >= 0x1f80) && (code <= 0x1f87)) ||
- ((code >= 0x1f90) && (code <= 0x1f97)) ||
- ((code >= 0x1fa0) && (code <= 0x1fa7)) ||
- ((code >= 0x1fb0) && (code <= 0x1fb4)) ||
- ((code >= 0x1fb6) && (code <= 0x1fb7)) ||
- (code == 0x1fbe) ||
- ((code >= 0x1fc2) && (code <= 0x1fc4)) ||
- ((code >= 0x1fc6) && (code <= 0x1fc7)) ||
- ((code >= 0x1fd0) && (code <= 0x1fd3)) ||
- ((code >= 0x1fd6) && (code <= 0x1fd7)) ||
- ((code >= 0x1fe0) && (code <= 0x1fe7)) ||
- ((code >= 0x1ff2) && (code <= 0x1ff4)) ||
- ((code >= 0x1ff6) && (code <= 0x1ff7)) ||
- (code == 0x207f) ||
- (code == 0x210a) ||
- ((code >= 0x210e) && (code <= 0x210f)) ||
- (code == 0x2113) ||
- (code == 0x212f) ||
- (code == 0x2134) ||
- (code == 0x2139) ||
- ((code >= 0xfb00) && (code <= 0xfb06)) ||
- ((code >= 0xfb13) && (code <= 0xfb17)) ||
- ((code >= 0xff41) && (code <= 0xff5a)) ||
- ((code >= 0x10428) && (code <= 0x1044d)) ||
- ((code >= 0x1d41a) && (code <= 0x1d433)) ||
- ((code >= 0x1d44e) && (code <= 0x1d454)) ||
- ((code >= 0x1d456) && (code <= 0x1d467)) ||
- ((code >= 0x1d482) && (code <= 0x1d49b)) ||
- ((code >= 0x1d4b6) && (code <= 0x1d4b9)) ||
- (code == 0x1d4bb) ||
- ((code >= 0x1d4bd) && (code <= 0x1d4c0)) ||
- ((code >= 0x1d4c2) && (code <= 0x1d4c3)) ||
- ((code >= 0x1d4c5) && (code <= 0x1d4cf)) ||
- ((code >= 0x1d4ea) && (code <= 0x1d503)) ||
- ((code >= 0x1d51e) && (code <= 0x1d537)) ||
- ((code >= 0x1d552) && (code <= 0x1d56b)) ||
- ((code >= 0x1d586) && (code <= 0x1d59f)) ||
- ((code >= 0x1d5ba) && (code <= 0x1d5d3)) ||
- ((code >= 0x1d5ee) && (code <= 0x1d607)) ||
- ((code >= 0x1d622) && (code <= 0x1d63b)) ||
- ((code >= 0x1d656) && (code <= 0x1d66f)) ||
- ((code >= 0x1d68a) && (code <= 0x1d6a3)) ||
- ((code >= 0x1d6c2) && (code <= 0x1d6da)) ||
- ((code >= 0x1d6dc) && (code <= 0x1d6e1)) ||
- ((code >= 0x1d6fc) && (code <= 0x1d714)) ||
- ((code >= 0x1d716) && (code <= 0x1d71b)) ||
- ((code >= 0x1d736) && (code <= 0x1d74e)) ||
- ((code >= 0x1d750) && (code <= 0x1d755)) ||
- ((code >= 0x1d770) && (code <= 0x1d788)) ||
- ((code >= 0x1d78a) && (code <= 0x1d78f)) ||
- ((code >= 0x1d7aa) && (code <= 0x1d7c2)) ||
- ((code >= 0x1d7c4) && (code <= 0x1d7c9)));
-}
-
-/**
- * xmlUCSIsCatLm:
- * @code: UCS code point
- *
- * Check whether the character is part of Lm UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatLm(int code) {
- return(((code >= 0x2b0) && (code <= 0x2b8)) ||
- ((code >= 0x2bb) && (code <= 0x2c1)) ||
- ((code >= 0x2d0) && (code <= 0x2d1)) ||
- ((code >= 0x2e0) && (code <= 0x2e4)) ||
- (code == 0x2ee) ||
- (code == 0x37a) ||
- (code == 0x559) ||
- (code == 0x640) ||
- ((code >= 0x6e5) && (code <= 0x6e6)) ||
- (code == 0xe46) ||
- (code == 0xec6) ||
- (code == 0x1843) ||
- (code == 0x3005) ||
- ((code >= 0x3031) && (code <= 0x3035)) ||
- ((code >= 0x309d) && (code <= 0x309e)) ||
- ((code >= 0x30fc) && (code <= 0x30fe)) ||
- (code == 0xff70) ||
- ((code >= 0xff9e) && (code <= 0xff9f)));
-}
-
-/**
- * xmlUCSIsCatLo:
- * @code: UCS code point
- *
- * Check whether the character is part of Lo UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatLo(int code) {
- return((code == 0x1bb) ||
- ((code >= 0x1c0) && (code <= 0x1c3)) ||
- ((code >= 0x5d0) && (code <= 0x5ea)) ||
- ((code >= 0x5f0) && (code <= 0x5f2)) ||
- ((code >= 0x621) && (code <= 0x63a)) ||
- ((code >= 0x641) && (code <= 0x64a)) ||
- ((code >= 0x671) && (code <= 0x6d3)) ||
- (code == 0x6d5) ||
- ((code >= 0x6fa) && (code <= 0x6fc)) ||
- (code == 0x710) ||
- ((code >= 0x712) && (code <= 0x72c)) ||
- ((code >= 0x780) && (code <= 0x7a5)) ||
- ((code >= 0x905) && (code <= 0x939)) ||
- (code == 0x93d) ||
- (code == 0x950) ||
- ((code >= 0x958) && (code <= 0x961)) ||
- ((code >= 0x985) && (code <= 0x98c)) ||
- ((code >= 0x98f) && (code <= 0x990)) ||
- ((code >= 0x993) && (code <= 0x9a8)) ||
- ((code >= 0x9aa) && (code <= 0x9b0)) ||
- (code == 0x9b2) ||
- ((code >= 0x9b6) && (code <= 0x9b9)) ||
- ((code >= 0x9dc) && (code <= 0x9dd)) ||
- ((code >= 0x9df) && (code <= 0x9e1)) ||
- ((code >= 0x9f0) && (code <= 0x9f1)) ||
- ((code >= 0xa05) && (code <= 0xa0a)) ||
- ((code >= 0xa0f) && (code <= 0xa10)) ||
- ((code >= 0xa13) && (code <= 0xa28)) ||
- ((code >= 0xa2a) && (code <= 0xa30)) ||
- ((code >= 0xa32) && (code <= 0xa33)) ||
- ((code >= 0xa35) && (code <= 0xa36)) ||
- ((code >= 0xa38) && (code <= 0xa39)) ||
- ((code >= 0xa59) && (code <= 0xa5c)) ||
- (code == 0xa5e) ||
- ((code >= 0xa72) && (code <= 0xa74)) ||
- ((code >= 0xa85) && (code <= 0xa8b)) ||
- (code == 0xa8d) ||
- ((code >= 0xa8f) && (code <= 0xa91)) ||
- ((code >= 0xa93) && (code <= 0xaa8)) ||
- ((code >= 0xaaa) && (code <= 0xab0)) ||
- ((code >= 0xab2) && (code <= 0xab3)) ||
- ((code >= 0xab5) && (code <= 0xab9)) ||
- (code == 0xabd) ||
- (code == 0xad0) ||
- (code == 0xae0) ||
- ((code >= 0xb05) && (code <= 0xb0c)) ||
- ((code >= 0xb0f) && (code <= 0xb10)) ||
- ((code >= 0xb13) && (code <= 0xb28)) ||
- ((code >= 0xb2a) && (code <= 0xb30)) ||
- ((code >= 0xb32) && (code <= 0xb33)) ||
- ((code >= 0xb36) && (code <= 0xb39)) ||
- (code == 0xb3d) ||
- ((code >= 0xb5c) && (code <= 0xb5d)) ||
- ((code >= 0xb5f) && (code <= 0xb61)) ||
- ((code >= 0xb85) && (code <= 0xb8a)) ||
- ((code >= 0xb8e) && (code <= 0xb90)) ||
- ((code >= 0xb92) && (code <= 0xb95)) ||
- ((code >= 0xb99) && (code <= 0xb9a)) ||
- (code == 0xb9c) ||
- ((code >= 0xb9e) && (code <= 0xb9f)) ||
- ((code >= 0xba3) && (code <= 0xba4)) ||
- ((code >= 0xba8) && (code <= 0xbaa)) ||
- ((code >= 0xbae) && (code <= 0xbb5)) ||
- ((code >= 0xbb7) && (code <= 0xbb9)) ||
- ((code >= 0xc05) && (code <= 0xc0c)) ||
- ((code >= 0xc0e) && (code <= 0xc10)) ||
- ((code >= 0xc12) && (code <= 0xc28)) ||
- ((code >= 0xc2a) && (code <= 0xc33)) ||
- ((code >= 0xc35) && (code <= 0xc39)) ||
- ((code >= 0xc60) && (code <= 0xc61)) ||
- ((code >= 0xc85) && (code <= 0xc8c)) ||
- ((code >= 0xc8e) && (code <= 0xc90)) ||
- ((code >= 0xc92) && (code <= 0xca8)) ||
- ((code >= 0xcaa) && (code <= 0xcb3)) ||
- ((code >= 0xcb5) && (code <= 0xcb9)) ||
- (code == 0xcde) ||
- ((code >= 0xce0) && (code <= 0xce1)) ||
- ((code >= 0xd05) && (code <= 0xd0c)) ||
- ((code >= 0xd0e) && (code <= 0xd10)) ||
- ((code >= 0xd12) && (code <= 0xd28)) ||
- ((code >= 0xd2a) && (code <= 0xd39)) ||
- ((code >= 0xd60) && (code <= 0xd61)) ||
- ((code >= 0xd85) && (code <= 0xd96)) ||
- ((code >= 0xd9a) && (code <= 0xdb1)) ||
- ((code >= 0xdb3) && (code <= 0xdbb)) ||
- (code == 0xdbd) ||
- ((code >= 0xdc0) && (code <= 0xdc6)) ||
- ((code >= 0xe01) && (code <= 0xe30)) ||
- ((code >= 0xe32) && (code <= 0xe33)) ||
- ((code >= 0xe40) && (code <= 0xe45)) ||
- ((code >= 0xe81) && (code <= 0xe82)) ||
- (code == 0xe84) ||
- ((code >= 0xe87) && (code <= 0xe88)) ||
- (code == 0xe8a) ||
- (code == 0xe8d) ||
- ((code >= 0xe94) && (code <= 0xe97)) ||
- ((code >= 0xe99) && (code <= 0xe9f)) ||
- ((code >= 0xea1) && (code <= 0xea3)) ||
- (code == 0xea5) ||
- (code == 0xea7) ||
- ((code >= 0xeaa) && (code <= 0xeab)) ||
- ((code >= 0xead) && (code <= 0xeb0)) ||
- ((code >= 0xeb2) && (code <= 0xeb3)) ||
- (code == 0xebd) ||
- ((code >= 0xec0) && (code <= 0xec4)) ||
- ((code >= 0xedc) && (code <= 0xedd)) ||
- (code == 0xf00) ||
- ((code >= 0xf40) && (code <= 0xf47)) ||
- ((code >= 0xf49) && (code <= 0xf6a)) ||
- ((code >= 0xf88) && (code <= 0xf8b)) ||
- ((code >= 0x1000) && (code <= 0x1021)) ||
- ((code >= 0x1023) && (code <= 0x1027)) ||
- ((code >= 0x1029) && (code <= 0x102a)) ||
- ((code >= 0x1050) && (code <= 0x1055)) ||
- ((code >= 0x10d0) && (code <= 0x10f6)) ||
- ((code >= 0x1100) && (code <= 0x1159)) ||
- ((code >= 0x115f) && (code <= 0x11a2)) ||
- ((code >= 0x11a8) && (code <= 0x11f9)) ||
- ((code >= 0x1200) && (code <= 0x1206)) ||
- ((code >= 0x1208) && (code <= 0x1246)) ||
- (code == 0x1248) ||
- ((code >= 0x124a) && (code <= 0x124d)) ||
- ((code >= 0x1250) && (code <= 0x1256)) ||
- (code == 0x1258) ||
- ((code >= 0x125a) && (code <= 0x125d)) ||
- ((code >= 0x1260) && (code <= 0x1286)) ||
- (code == 0x1288) ||
- ((code >= 0x128a) && (code <= 0x128d)) ||
- ((code >= 0x1290) && (code <= 0x12ae)) ||
- (code == 0x12b0) ||
- ((code >= 0x12b2) && (code <= 0x12b5)) ||
- ((code >= 0x12b8) && (code <= 0x12be)) ||
- (code == 0x12c0) ||
- ((code >= 0x12c2) && (code <= 0x12c5)) ||
- ((code >= 0x12c8) && (code <= 0x12ce)) ||
- ((code >= 0x12d0) && (code <= 0x12d6)) ||
- ((code >= 0x12d8) && (code <= 0x12ee)) ||
- ((code >= 0x12f0) && (code <= 0x130e)) ||
- (code == 0x1310) ||
- ((code >= 0x1312) && (code <= 0x1315)) ||
- ((code >= 0x1318) && (code <= 0x131e)) ||
- ((code >= 0x1320) && (code <= 0x1346)) ||
- ((code >= 0x1348) && (code <= 0x135a)) ||
- ((code >= 0x13a0) && (code <= 0x13f4)) ||
- ((code >= 0x1401) && (code <= 0x166c)) ||
- ((code >= 0x166f) && (code <= 0x1676)) ||
- ((code >= 0x1681) && (code <= 0x169a)) ||
- ((code >= 0x16a0) && (code <= 0x16ea)) ||
- ((code >= 0x1780) && (code <= 0x17b3)) ||
- ((code >= 0x1820) && (code <= 0x1842)) ||
- ((code >= 0x1844) && (code <= 0x1877)) ||
- ((code >= 0x1880) && (code <= 0x18a8)) ||
- ((code >= 0x2135) && (code <= 0x2138)) ||
- (code == 0x3006) ||
- ((code >= 0x3041) && (code <= 0x3094)) ||
- ((code >= 0x30a1) && (code <= 0x30fa)) ||
- ((code >= 0x3105) && (code <= 0x312c)) ||
- ((code >= 0x3131) && (code <= 0x318e)) ||
- ((code >= 0x31a0) && (code <= 0x31b7)) ||
- (code == 0x3400) ||
- (code == 0x4db5) ||
- (code == 0x4e00) ||
- (code == 0x9fa5) ||
- ((code >= 0xa000) && (code <= 0xa48c)) ||
- (code == 0xac00) ||
- (code == 0xd7a3) ||
- ((code >= 0xf900) && (code <= 0xfa2d)) ||
- (code == 0xfb1d) ||
- ((code >= 0xfb1f) && (code <= 0xfb28)) ||
- ((code >= 0xfb2a) && (code <= 0xfb36)) ||
- ((code >= 0xfb38) && (code <= 0xfb3c)) ||
- (code == 0xfb3e) ||
- ((code >= 0xfb40) && (code <= 0xfb41)) ||
- ((code >= 0xfb43) && (code <= 0xfb44)) ||
- ((code >= 0xfb46) && (code <= 0xfbb1)) ||
- ((code >= 0xfbd3) && (code <= 0xfd3d)) ||
- ((code >= 0xfd50) && (code <= 0xfd8f)) ||
- ((code >= 0xfd92) && (code <= 0xfdc7)) ||
- ((code >= 0xfdf0) && (code <= 0xfdfb)) ||
- ((code >= 0xfe70) && (code <= 0xfe72)) ||
- (code == 0xfe74) ||
- ((code >= 0xfe76) && (code <= 0xfefc)) ||
- ((code >= 0xff66) && (code <= 0xff6f)) ||
- ((code >= 0xff71) && (code <= 0xff9d)) ||
- ((code >= 0xffa0) && (code <= 0xffbe)) ||
- ((code >= 0xffc2) && (code <= 0xffc7)) ||
- ((code >= 0xffca) && (code <= 0xffcf)) ||
- ((code >= 0xffd2) && (code <= 0xffd7)) ||
- ((code >= 0xffda) && (code <= 0xffdc)) ||
- ((code >= 0x10300) && (code <= 0x1031e)) ||
- ((code >= 0x10330) && (code <= 0x10349)) ||
- (code == 0x20000) ||
- (code == 0x2a6d6) ||
- ((code >= 0x2f800) && (code <= 0x2fa1d)));
-}
-
-/**
- * xmlUCSIsCatLt:
- * @code: UCS code point
- *
- * Check whether the character is part of Lt UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatLt(int code) {
- return((code == 0x1c5) ||
- (code == 0x1c8) ||
- (code == 0x1cb) ||
- (code == 0x1f2) ||
- ((code >= 0x1f88) && (code <= 0x1f8f)) ||
- ((code >= 0x1f98) && (code <= 0x1f9f)) ||
- ((code >= 0x1fa8) && (code <= 0x1faf)) ||
- (code == 0x1fbc) ||
- (code == 0x1fcc) ||
- (code == 0x1ffc));
-}
-
-/**
- * xmlUCSIsCatLu:
- * @code: UCS code point
- *
- * Check whether the character is part of Lu UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatLu(int code) {
- return(((code >= 0x41) && (code <= 0x5a)) ||
- ((code >= 0xc0) && (code <= 0xd6)) ||
- ((code >= 0xd8) && (code <= 0xde)) ||
- (code == 0x100) ||
- (code == 0x102) ||
- (code == 0x104) ||
- (code == 0x106) ||
- (code == 0x108) ||
- (code == 0x10a) ||
- (code == 0x10c) ||
- (code == 0x10e) ||
- (code == 0x110) ||
- (code == 0x112) ||
- (code == 0x114) ||
- (code == 0x116) ||
- (code == 0x118) ||
- (code == 0x11a) ||
- (code == 0x11c) ||
- (code == 0x11e) ||
- (code == 0x120) ||
- (code == 0x122) ||
- (code == 0x124) ||
- (code == 0x126) ||
- (code == 0x128) ||
- (code == 0x12a) ||
- (code == 0x12c) ||
- (code == 0x12e) ||
- (code == 0x130) ||
- (code == 0x132) ||
- (code == 0x134) ||
- (code == 0x136) ||
- (code == 0x139) ||
- (code == 0x13b) ||
- (code == 0x13d) ||
- (code == 0x13f) ||
- (code == 0x141) ||
- (code == 0x143) ||
- (code == 0x145) ||
- (code == 0x147) ||
- (code == 0x14a) ||
- (code == 0x14c) ||
- (code == 0x14e) ||
- (code == 0x150) ||
- (code == 0x152) ||
- (code == 0x154) ||
- (code == 0x156) ||
- (code == 0x158) ||
- (code == 0x15a) ||
- (code == 0x15c) ||
- (code == 0x15e) ||
- (code == 0x160) ||
- (code == 0x162) ||
- (code == 0x164) ||
- (code == 0x166) ||
- (code == 0x168) ||
- (code == 0x16a) ||
- (code == 0x16c) ||
- (code == 0x16e) ||
- (code == 0x170) ||
- (code == 0x172) ||
- (code == 0x174) ||
- (code == 0x176) ||
- ((code >= 0x178) && (code <= 0x179)) ||
- (code == 0x17b) ||
- (code == 0x17d) ||
- ((code >= 0x181) && (code <= 0x182)) ||
- (code == 0x184) ||
- ((code >= 0x186) && (code <= 0x187)) ||
- ((code >= 0x189) && (code <= 0x18b)) ||
- ((code >= 0x18e) && (code <= 0x191)) ||
- ((code >= 0x193) && (code <= 0x194)) ||
- ((code >= 0x196) && (code <= 0x198)) ||
- ((code >= 0x19c) && (code <= 0x19d)) ||
- ((code >= 0x19f) && (code <= 0x1a0)) ||
- (code == 0x1a2) ||
- (code == 0x1a4) ||
- ((code >= 0x1a6) && (code <= 0x1a7)) ||
- (code == 0x1a9) ||
- (code == 0x1ac) ||
- ((code >= 0x1ae) && (code <= 0x1af)) ||
- ((code >= 0x1b1) && (code <= 0x1b3)) ||
- (code == 0x1b5) ||
- ((code >= 0x1b7) && (code <= 0x1b8)) ||
- (code == 0x1bc) ||
- (code == 0x1c4) ||
- (code == 0x1c7) ||
- (code == 0x1ca) ||
- (code == 0x1cd) ||
- (code == 0x1cf) ||
- (code == 0x1d1) ||
- (code == 0x1d3) ||
- (code == 0x1d5) ||
- (code == 0x1d7) ||
- (code == 0x1d9) ||
- (code == 0x1db) ||
- (code == 0x1de) ||
- (code == 0x1e0) ||
- (code == 0x1e2) ||
- (code == 0x1e4) ||
- (code == 0x1e6) ||
- (code == 0x1e8) ||
- (code == 0x1ea) ||
- (code == 0x1ec) ||
- (code == 0x1ee) ||
- (code == 0x1f1) ||
- (code == 0x1f4) ||
- ((code >= 0x1f6) && (code <= 0x1f8)) ||
- (code == 0x1fa) ||
- (code == 0x1fc) ||
- (code == 0x1fe) ||
- (code == 0x200) ||
- (code == 0x202) ||
- (code == 0x204) ||
- (code == 0x206) ||
- (code == 0x208) ||
- (code == 0x20a) ||
- (code == 0x20c) ||
- (code == 0x20e) ||
- (code == 0x210) ||
- (code == 0x212) ||
- (code == 0x214) ||
- (code == 0x216) ||
- (code == 0x218) ||
- (code == 0x21a) ||
- (code == 0x21c) ||
- (code == 0x21e) ||
- (code == 0x222) ||
- (code == 0x224) ||
- (code == 0x226) ||
- (code == 0x228) ||
- (code == 0x22a) ||
- (code == 0x22c) ||
- (code == 0x22e) ||
- (code == 0x230) ||
- (code == 0x232) ||
- (code == 0x386) ||
- ((code >= 0x388) && (code <= 0x38a)) ||
- (code == 0x38c) ||
- ((code >= 0x38e) && (code <= 0x38f)) ||
- ((code >= 0x391) && (code <= 0x3a1)) ||
- ((code >= 0x3a3) && (code <= 0x3ab)) ||
- ((code >= 0x3d2) && (code <= 0x3d4)) ||
- (code == 0x3da) ||
- (code == 0x3dc) ||
- (code == 0x3de) ||
- (code == 0x3e0) ||
- (code == 0x3e2) ||
- (code == 0x3e4) ||
- (code == 0x3e6) ||
- (code == 0x3e8) ||
- (code == 0x3ea) ||
- (code == 0x3ec) ||
- (code == 0x3ee) ||
- (code == 0x3f4) ||
- ((code >= 0x400) && (code <= 0x42f)) ||
- (code == 0x460) ||
- (code == 0x462) ||
- (code == 0x464) ||
- (code == 0x466) ||
- (code == 0x468) ||
- (code == 0x46a) ||
- (code == 0x46c) ||
- (code == 0x46e) ||
- (code == 0x470) ||
- (code == 0x472) ||
- (code == 0x474) ||
- (code == 0x476) ||
- (code == 0x478) ||
- (code == 0x47a) ||
- (code == 0x47c) ||
- (code == 0x47e) ||
- (code == 0x480) ||
- (code == 0x48c) ||
- (code == 0x48e) ||
- (code == 0x490) ||
- (code == 0x492) ||
- (code == 0x494) ||
- (code == 0x496) ||
- (code == 0x498) ||
- (code == 0x49a) ||
- (code == 0x49c) ||
- (code == 0x49e) ||
- (code == 0x4a0) ||
- (code == 0x4a2) ||
- (code == 0x4a4) ||
- (code == 0x4a6) ||
- (code == 0x4a8) ||
- (code == 0x4aa) ||
- (code == 0x4ac) ||
- (code == 0x4ae) ||
- (code == 0x4b0) ||
- (code == 0x4b2) ||
- (code == 0x4b4) ||
- (code == 0x4b6) ||
- (code == 0x4b8) ||
- (code == 0x4ba) ||
- (code == 0x4bc) ||
- (code == 0x4be) ||
- ((code >= 0x4c0) && (code <= 0x4c1)) ||
- (code == 0x4c3) ||
- (code == 0x4c7) ||
- (code == 0x4cb) ||
- (code == 0x4d0) ||
- (code == 0x4d2) ||
- (code == 0x4d4) ||
- (code == 0x4d6) ||
- (code == 0x4d8) ||
- (code == 0x4da) ||
- (code == 0x4dc) ||
- (code == 0x4de) ||
- (code == 0x4e0) ||
- (code == 0x4e2) ||
- (code == 0x4e4) ||
- (code == 0x4e6) ||
- (code == 0x4e8) ||
- (code == 0x4ea) ||
- (code == 0x4ec) ||
- (code == 0x4ee) ||
- (code == 0x4f0) ||
- (code == 0x4f2) ||
- (code == 0x4f4) ||
- (code == 0x4f8) ||
- ((code >= 0x531) && (code <= 0x556)) ||
- ((code >= 0x10a0) && (code <= 0x10c5)) ||
- (code == 0x1e00) ||
- (code == 0x1e02) ||
- (code == 0x1e04) ||
- (code == 0x1e06) ||
- (code == 0x1e08) ||
- (code == 0x1e0a) ||
- (code == 0x1e0c) ||
- (code == 0x1e0e) ||
- (code == 0x1e10) ||
- (code == 0x1e12) ||
- (code == 0x1e14) ||
- (code == 0x1e16) ||
- (code == 0x1e18) ||
- (code == 0x1e1a) ||
- (code == 0x1e1c) ||
- (code == 0x1e1e) ||
- (code == 0x1e20) ||
- (code == 0x1e22) ||
- (code == 0x1e24) ||
- (code == 0x1e26) ||
- (code == 0x1e28) ||
- (code == 0x1e2a) ||
- (code == 0x1e2c) ||
- (code == 0x1e2e) ||
- (code == 0x1e30) ||
- (code == 0x1e32) ||
- (code == 0x1e34) ||
- (code == 0x1e36) ||
- (code == 0x1e38) ||
- (code == 0x1e3a) ||
- (code == 0x1e3c) ||
- (code == 0x1e3e) ||
- (code == 0x1e40) ||
- (code == 0x1e42) ||
- (code == 0x1e44) ||
- (code == 0x1e46) ||
- (code == 0x1e48) ||
- (code == 0x1e4a) ||
- (code == 0x1e4c) ||
- (code == 0x1e4e) ||
- (code == 0x1e50) ||
- (code == 0x1e52) ||
- (code == 0x1e54) ||
- (code == 0x1e56) ||
- (code == 0x1e58) ||
- (code == 0x1e5a) ||
- (code == 0x1e5c) ||
- (code == 0x1e5e) ||
- (code == 0x1e60) ||
- (code == 0x1e62) ||
- (code == 0x1e64) ||
- (code == 0x1e66) ||
- (code == 0x1e68) ||
- (code == 0x1e6a) ||
- (code == 0x1e6c) ||
- (code == 0x1e6e) ||
- (code == 0x1e70) ||
- (code == 0x1e72) ||
- (code == 0x1e74) ||
- (code == 0x1e76) ||
- (code == 0x1e78) ||
- (code == 0x1e7a) ||
- (code == 0x1e7c) ||
- (code == 0x1e7e) ||
- (code == 0x1e80) ||
- (code == 0x1e82) ||
- (code == 0x1e84) ||
- (code == 0x1e86) ||
- (code == 0x1e88) ||
- (code == 0x1e8a) ||
- (code == 0x1e8c) ||
- (code == 0x1e8e) ||
- (code == 0x1e90) ||
- (code == 0x1e92) ||
- (code == 0x1e94) ||
- (code == 0x1ea0) ||
- (code == 0x1ea2) ||
- (code == 0x1ea4) ||
- (code == 0x1ea6) ||
- (code == 0x1ea8) ||
- (code == 0x1eaa) ||
- (code == 0x1eac) ||
- (code == 0x1eae) ||
- (code == 0x1eb0) ||
- (code == 0x1eb2) ||
- (code == 0x1eb4) ||
- (code == 0x1eb6) ||
- (code == 0x1eb8) ||
- (code == 0x1eba) ||
- (code == 0x1ebc) ||
- (code == 0x1ebe) ||
- (code == 0x1ec0) ||
- (code == 0x1ec2) ||
- (code == 0x1ec4) ||
- (code == 0x1ec6) ||
- (code == 0x1ec8) ||
- (code == 0x1eca) ||
- (code == 0x1ecc) ||
- (code == 0x1ece) ||
- (code == 0x1ed0) ||
- (code == 0x1ed2) ||
- (code == 0x1ed4) ||
- (code == 0x1ed6) ||
- (code == 0x1ed8) ||
- (code == 0x1eda) ||
- (code == 0x1edc) ||
- (code == 0x1ede) ||
- (code == 0x1ee0) ||
- (code == 0x1ee2) ||
- (code == 0x1ee4) ||
- (code == 0x1ee6) ||
- (code == 0x1ee8) ||
- (code == 0x1eea) ||
- (code == 0x1eec) ||
- (code == 0x1eee) ||
- (code == 0x1ef0) ||
- (code == 0x1ef2) ||
- (code == 0x1ef4) ||
- (code == 0x1ef6) ||
- (code == 0x1ef8) ||
- ((code >= 0x1f08) && (code <= 0x1f0f)) ||
- ((code >= 0x1f18) && (code <= 0x1f1d)) ||
- ((code >= 0x1f28) && (code <= 0x1f2f)) ||
- ((code >= 0x1f38) && (code <= 0x1f3f)) ||
- ((code >= 0x1f48) && (code <= 0x1f4d)) ||
- (code == 0x1f59) ||
- (code == 0x1f5b) ||
- (code == 0x1f5d) ||
- (code == 0x1f5f) ||
- ((code >= 0x1f68) && (code <= 0x1f6f)) ||
- ((code >= 0x1fb8) && (code <= 0x1fbb)) ||
- ((code >= 0x1fc8) && (code <= 0x1fcb)) ||
- ((code >= 0x1fd8) && (code <= 0x1fdb)) ||
- ((code >= 0x1fe8) && (code <= 0x1fec)) ||
- ((code >= 0x1ff8) && (code <= 0x1ffb)) ||
- (code == 0x2102) ||
- (code == 0x2107) ||
- ((code >= 0x210b) && (code <= 0x210d)) ||
- ((code >= 0x2110) && (code <= 0x2112)) ||
- (code == 0x2115) ||
- ((code >= 0x2119) && (code <= 0x211d)) ||
- (code == 0x2124) ||
- (code == 0x2126) ||
- (code == 0x2128) ||
- ((code >= 0x212a) && (code <= 0x212d)) ||
- ((code >= 0x2130) && (code <= 0x2131)) ||
- (code == 0x2133) ||
- ((code >= 0xff21) && (code <= 0xff3a)) ||
- ((code >= 0x10400) && (code <= 0x10425)) ||
- ((code >= 0x1d400) && (code <= 0x1d419)) ||
- ((code >= 0x1d434) && (code <= 0x1d44d)) ||
- ((code >= 0x1d468) && (code <= 0x1d481)) ||
- (code == 0x1d49c) ||
- ((code >= 0x1d49e) && (code <= 0x1d49f)) ||
- (code == 0x1d4a2) ||
- ((code >= 0x1d4a5) && (code <= 0x1d4a6)) ||
- ((code >= 0x1d4a9) && (code <= 0x1d4ac)) ||
- ((code >= 0x1d4ae) && (code <= 0x1d4b5)) ||
- ((code >= 0x1d4d0) && (code <= 0x1d4e9)) ||
- ((code >= 0x1d504) && (code <= 0x1d505)) ||
- ((code >= 0x1d507) && (code <= 0x1d50a)) ||
- ((code >= 0x1d50d) && (code <= 0x1d514)) ||
- ((code >= 0x1d516) && (code <= 0x1d51c)) ||
- ((code >= 0x1d538) && (code <= 0x1d539)) ||
- ((code >= 0x1d53b) && (code <= 0x1d53e)) ||
- ((code >= 0x1d540) && (code <= 0x1d544)) ||
- (code == 0x1d546) ||
- ((code >= 0x1d54a) && (code <= 0x1d550)) ||
- ((code >= 0x1d56c) && (code <= 0x1d585)) ||
- ((code >= 0x1d5a0) && (code <= 0x1d5b9)) ||
- ((code >= 0x1d5d4) && (code <= 0x1d5ed)) ||
- ((code >= 0x1d608) && (code <= 0x1d621)) ||
- ((code >= 0x1d63c) && (code <= 0x1d655)) ||
- ((code >= 0x1d670) && (code <= 0x1d689)) ||
- ((code >= 0x1d6a8) && (code <= 0x1d6c0)) ||
- ((code >= 0x1d6e2) && (code <= 0x1d6fa)) ||
- ((code >= 0x1d71c) && (code <= 0x1d734)) ||
- ((code >= 0x1d756) && (code <= 0x1d76e)) ||
- ((code >= 0x1d790) && (code <= 0x1d7a8)));
-}
-
-/**
- * xmlUCSIsCatM:
- * @code: UCS code point
- *
- * Check whether the character is part of M UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatM(int code) {
- return(((code >= 0x300) && (code <= 0x34e)) ||
- ((code >= 0x360) && (code <= 0x362)) ||
- ((code >= 0x483) && (code <= 0x486)) ||
- ((code >= 0x488) && (code <= 0x489)) ||
- ((code >= 0x591) && (code <= 0x5a1)) ||
- ((code >= 0x5a3) && (code <= 0x5b9)) ||
- ((code >= 0x5bb) && (code <= 0x5bd)) ||
- (code == 0x5bf) ||
- ((code >= 0x5c1) && (code <= 0x5c2)) ||
- (code == 0x5c4) ||
- ((code >= 0x64b) && (code <= 0x655)) ||
- (code == 0x670) ||
- ((code >= 0x6d6) && (code <= 0x6e4)) ||
- ((code >= 0x6e7) && (code <= 0x6e8)) ||
- ((code >= 0x6ea) && (code <= 0x6ed)) ||
- (code == 0x711) ||
- ((code >= 0x730) && (code <= 0x74a)) ||
- ((code >= 0x7a6) && (code <= 0x7b0)) ||
- ((code >= 0x901) && (code <= 0x903)) ||
- (code == 0x93c) ||
- ((code >= 0x93e) && (code <= 0x94d)) ||
- ((code >= 0x951) && (code <= 0x954)) ||
- ((code >= 0x962) && (code <= 0x963)) ||
- ((code >= 0x981) && (code <= 0x983)) ||
- (code == 0x9bc) ||
- ((code >= 0x9be) && (code <= 0x9c4)) ||
- ((code >= 0x9c7) && (code <= 0x9c8)) ||
- ((code >= 0x9cb) && (code <= 0x9cd)) ||
- (code == 0x9d7) ||
- ((code >= 0x9e2) && (code <= 0x9e3)) ||
- (code == 0xa02) ||
- (code == 0xa3c) ||
- ((code >= 0xa3e) && (code <= 0xa42)) ||
- ((code >= 0xa47) && (code <= 0xa48)) ||
- ((code >= 0xa4b) && (code <= 0xa4d)) ||
- ((code >= 0xa70) && (code <= 0xa71)) ||
- ((code >= 0xa81) && (code <= 0xa83)) ||
- (code == 0xabc) ||
- ((code >= 0xabe) && (code <= 0xac5)) ||
- ((code >= 0xac7) && (code <= 0xac9)) ||
- ((code >= 0xacb) && (code <= 0xacd)) ||
- ((code >= 0xb01) && (code <= 0xb03)) ||
- (code == 0xb3c) ||
- ((code >= 0xb3e) && (code <= 0xb43)) ||
- ((code >= 0xb47) && (code <= 0xb48)) ||
- ((code >= 0xb4b) && (code <= 0xb4d)) ||
- ((code >= 0xb56) && (code <= 0xb57)) ||
- ((code >= 0xb82) && (code <= 0xb83)) ||
- ((code >= 0xbbe) && (code <= 0xbc2)) ||
- ((code >= 0xbc6) && (code <= 0xbc8)) ||
- ((code >= 0xbca) && (code <= 0xbcd)) ||
- (code == 0xbd7) ||
- ((code >= 0xc01) && (code <= 0xc03)) ||
- ((code >= 0xc3e) && (code <= 0xc44)) ||
- ((code >= 0xc46) && (code <= 0xc48)) ||
- ((code >= 0xc4a) && (code <= 0xc4d)) ||
- ((code >= 0xc55) && (code <= 0xc56)) ||
- ((code >= 0xc82) && (code <= 0xc83)) ||
- ((code >= 0xcbe) && (code <= 0xcc4)) ||
- ((code >= 0xcc6) && (code <= 0xcc8)) ||
- ((code >= 0xcca) && (code <= 0xccd)) ||
- ((code >= 0xcd5) && (code <= 0xcd6)) ||
- ((code >= 0xd02) && (code <= 0xd03)) ||
- ((code >= 0xd3e) && (code <= 0xd43)) ||
- ((code >= 0xd46) && (code <= 0xd48)) ||
- ((code >= 0xd4a) && (code <= 0xd4d)) ||
- (code == 0xd57) ||
- ((code >= 0xd82) && (code <= 0xd83)) ||
- (code == 0xdca) ||
- ((code >= 0xdcf) && (code <= 0xdd4)) ||
- (code == 0xdd6) ||
- ((code >= 0xdd8) && (code <= 0xddf)) ||
- ((code >= 0xdf2) && (code <= 0xdf3)) ||
- (code == 0xe31) ||
- ((code >= 0xe34) && (code <= 0xe3a)) ||
- ((code >= 0xe47) && (code <= 0xe4e)) ||
- (code == 0xeb1) ||
- ((code >= 0xeb4) && (code <= 0xeb9)) ||
- ((code >= 0xebb) && (code <= 0xebc)) ||
- ((code >= 0xec8) && (code <= 0xecd)) ||
- ((code >= 0xf18) && (code <= 0xf19)) ||
- (code == 0xf35) ||
- (code == 0xf37) ||
- (code == 0xf39) ||
- ((code >= 0xf3e) && (code <= 0xf3f)) ||
- ((code >= 0xf71) && (code <= 0xf84)) ||
- ((code >= 0xf86) && (code <= 0xf87)) ||
- ((code >= 0xf90) && (code <= 0xf97)) ||
- ((code >= 0xf99) && (code <= 0xfbc)) ||
- (code == 0xfc6) ||
- ((code >= 0x102c) && (code <= 0x1032)) ||
- ((code >= 0x1036) && (code <= 0x1039)) ||
- ((code >= 0x1056) && (code <= 0x1059)) ||
- ((code >= 0x17b4) && (code <= 0x17d3)) ||
- (code == 0x18a9) ||
- ((code >= 0x20d0) && (code <= 0x20e3)) ||
- ((code >= 0x302a) && (code <= 0x302f)) ||
- ((code >= 0x3099) && (code <= 0x309a)) ||
- (code == 0xfb1e) ||
- ((code >= 0xfe20) && (code <= 0xfe23)) ||
- ((code >= 0x1d165) && (code <= 0x1d169)) ||
- ((code >= 0x1d16d) && (code <= 0x1d172)) ||
- ((code >= 0x1d17b) && (code <= 0x1d182)) ||
- ((code >= 0x1d185) && (code <= 0x1d18b)) ||
- ((code >= 0x1d1aa) && (code <= 0x1d1ad)));
-}
-
-/**
- * xmlUCSIsCatMc:
- * @code: UCS code point
- *
- * Check whether the character is part of Mc UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatMc(int code) {
- return((code == 0x903) ||
- ((code >= 0x93e) && (code <= 0x940)) ||
- ((code >= 0x949) && (code <= 0x94c)) ||
- ((code >= 0x982) && (code <= 0x983)) ||
- ((code >= 0x9be) && (code <= 0x9c0)) ||
- ((code >= 0x9c7) && (code <= 0x9c8)) ||
- ((code >= 0x9cb) && (code <= 0x9cc)) ||
- (code == 0x9d7) ||
- ((code >= 0xa3e) && (code <= 0xa40)) ||
- (code == 0xa83) ||
- ((code >= 0xabe) && (code <= 0xac0)) ||
- (code == 0xac9) ||
- ((code >= 0xacb) && (code <= 0xacc)) ||
- ((code >= 0xb02) && (code <= 0xb03)) ||
- (code == 0xb3e) ||
- (code == 0xb40) ||
- ((code >= 0xb47) && (code <= 0xb48)) ||
- ((code >= 0xb4b) && (code <= 0xb4c)) ||
- (code == 0xb57) ||
- (code == 0xb83) ||
- ((code >= 0xbbe) && (code <= 0xbbf)) ||
- ((code >= 0xbc1) && (code <= 0xbc2)) ||
- ((code >= 0xbc6) && (code <= 0xbc8)) ||
- ((code >= 0xbca) && (code <= 0xbcc)) ||
- (code == 0xbd7) ||
- ((code >= 0xc01) && (code <= 0xc03)) ||
- ((code >= 0xc41) && (code <= 0xc44)) ||
- ((code >= 0xc82) && (code <= 0xc83)) ||
- (code == 0xcbe) ||
- ((code >= 0xcc0) && (code <= 0xcc4)) ||
- ((code >= 0xcc7) && (code <= 0xcc8)) ||
- ((code >= 0xcca) && (code <= 0xccb)) ||
- ((code >= 0xcd5) && (code <= 0xcd6)) ||
- ((code >= 0xd02) && (code <= 0xd03)) ||
- ((code >= 0xd3e) && (code <= 0xd40)) ||
- ((code >= 0xd46) && (code <= 0xd48)) ||
- ((code >= 0xd4a) && (code <= 0xd4c)) ||
- (code == 0xd57) ||
- ((code >= 0xd82) && (code <= 0xd83)) ||
- ((code >= 0xdcf) && (code <= 0xdd1)) ||
- ((code >= 0xdd8) && (code <= 0xddf)) ||
- ((code >= 0xdf2) && (code <= 0xdf3)) ||
- ((code >= 0xf3e) && (code <= 0xf3f)) ||
- (code == 0xf7f) ||
- (code == 0x102c) ||
- (code == 0x1031) ||
- (code == 0x1038) ||
- ((code >= 0x1056) && (code <= 0x1057)) ||
- ((code >= 0x17b4) && (code <= 0x17b6)) ||
- ((code >= 0x17be) && (code <= 0x17c5)) ||
- ((code >= 0x17c7) && (code <= 0x17c8)) ||
- ((code >= 0x1d165) && (code <= 0x1d166)) ||
- ((code >= 0x1d16d) && (code <= 0x1d172)));
-}
-
-/**
- * xmlUCSIsCatMe:
- * @code: UCS code point
- *
- * Check whether the character is part of Me UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatMe(int code) {
- return(((code >= 0x488) && (code <= 0x489)) ||
- ((code >= 0x6dd) && (code <= 0x6de)) ||
- ((code >= 0x20dd) && (code <= 0x20e0)) ||
- ((code >= 0x20e2) && (code <= 0x20e3)));
-}
-
-/**
- * xmlUCSIsCatMn:
- * @code: UCS code point
- *
- * Check whether the character is part of Mn UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatMn(int code) {
- return(((code >= 0x300) && (code <= 0x34e)) ||
- ((code >= 0x360) && (code <= 0x362)) ||
- ((code >= 0x483) && (code <= 0x486)) ||
- ((code >= 0x591) && (code <= 0x5a1)) ||
- ((code >= 0x5a3) && (code <= 0x5b9)) ||
- ((code >= 0x5bb) && (code <= 0x5bd)) ||
- (code == 0x5bf) ||
- ((code >= 0x5c1) && (code <= 0x5c2)) ||
- (code == 0x5c4) ||
- ((code >= 0x64b) && (code <= 0x655)) ||
- (code == 0x670) ||
- ((code >= 0x6d6) && (code <= 0x6dc)) ||
- ((code >= 0x6df) && (code <= 0x6e4)) ||
- ((code >= 0x6e7) && (code <= 0x6e8)) ||
- ((code >= 0x6ea) && (code <= 0x6ed)) ||
- (code == 0x711) ||
- ((code >= 0x730) && (code <= 0x74a)) ||
- ((code >= 0x7a6) && (code <= 0x7b0)) ||
- ((code >= 0x901) && (code <= 0x902)) ||
- (code == 0x93c) ||
- ((code >= 0x941) && (code <= 0x948)) ||
- (code == 0x94d) ||
- ((code >= 0x951) && (code <= 0x954)) ||
- ((code >= 0x962) && (code <= 0x963)) ||
- (code == 0x981) ||
- (code == 0x9bc) ||
- ((code >= 0x9c1) && (code <= 0x9c4)) ||
- (code == 0x9cd) ||
- ((code >= 0x9e2) && (code <= 0x9e3)) ||
- (code == 0xa02) ||
- (code == 0xa3c) ||
- ((code >= 0xa41) && (code <= 0xa42)) ||
- ((code >= 0xa47) && (code <= 0xa48)) ||
- ((code >= 0xa4b) && (code <= 0xa4d)) ||
- ((code >= 0xa70) && (code <= 0xa71)) ||
- ((code >= 0xa81) && (code <= 0xa82)) ||
- (code == 0xabc) ||
- ((code >= 0xac1) && (code <= 0xac5)) ||
- ((code >= 0xac7) && (code <= 0xac8)) ||
- (code == 0xacd) ||
- (code == 0xb01) ||
- (code == 0xb3c) ||
- (code == 0xb3f) ||
- ((code >= 0xb41) && (code <= 0xb43)) ||
- (code == 0xb4d) ||
- (code == 0xb56) ||
- (code == 0xb82) ||
- (code == 0xbc0) ||
- (code == 0xbcd) ||
- ((code >= 0xc3e) && (code <= 0xc40)) ||
- ((code >= 0xc46) && (code <= 0xc48)) ||
- ((code >= 0xc4a) && (code <= 0xc4d)) ||
- ((code >= 0xc55) && (code <= 0xc56)) ||
- (code == 0xcbf) ||
- (code == 0xcc6) ||
- ((code >= 0xccc) && (code <= 0xccd)) ||
- ((code >= 0xd41) && (code <= 0xd43)) ||
- (code == 0xd4d) ||
- (code == 0xdca) ||
- ((code >= 0xdd2) && (code <= 0xdd4)) ||
- (code == 0xdd6) ||
- (code == 0xe31) ||
- ((code >= 0xe34) && (code <= 0xe3a)) ||
- ((code >= 0xe47) && (code <= 0xe4e)) ||
- (code == 0xeb1) ||
- ((code >= 0xeb4) && (code <= 0xeb9)) ||
- ((code >= 0xebb) && (code <= 0xebc)) ||
- ((code >= 0xec8) && (code <= 0xecd)) ||
- ((code >= 0xf18) && (code <= 0xf19)) ||
- (code == 0xf35) ||
- (code == 0xf37) ||
- (code == 0xf39) ||
- ((code >= 0xf71) && (code <= 0xf7e)) ||
- ((code >= 0xf80) && (code <= 0xf84)) ||
- ((code >= 0xf86) && (code <= 0xf87)) ||
- ((code >= 0xf90) && (code <= 0xf97)) ||
- ((code >= 0xf99) && (code <= 0xfbc)) ||
- (code == 0xfc6) ||
- ((code >= 0x102d) && (code <= 0x1030)) ||
- (code == 0x1032) ||
- ((code >= 0x1036) && (code <= 0x1037)) ||
- (code == 0x1039) ||
- ((code >= 0x1058) && (code <= 0x1059)) ||
- ((code >= 0x17b7) && (code <= 0x17bd)) ||
- (code == 0x17c6) ||
- ((code >= 0x17c9) && (code <= 0x17d3)) ||
- (code == 0x18a9) ||
- ((code >= 0x20d0) && (code <= 0x20dc)) ||
- (code == 0x20e1) ||
- ((code >= 0x302a) && (code <= 0x302f)) ||
- ((code >= 0x3099) && (code <= 0x309a)) ||
- (code == 0xfb1e) ||
- ((code >= 0xfe20) && (code <= 0xfe23)) ||
- ((code >= 0x1d167) && (code <= 0x1d169)) ||
- ((code >= 0x1d17b) && (code <= 0x1d182)) ||
- ((code >= 0x1d185) && (code <= 0x1d18b)) ||
- ((code >= 0x1d1aa) && (code <= 0x1d1ad)));
-}
-
-/**
- * xmlUCSIsCatN:
- * @code: UCS code point
- *
- * Check whether the character is part of N UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatN(int code) {
- return(((code >= 0x30) && (code <= 0x39)) ||
- ((code >= 0xb2) && (code <= 0xb3)) ||
- (code == 0xb9) ||
- ((code >= 0xbc) && (code <= 0xbe)) ||
- ((code >= 0x660) && (code <= 0x669)) ||
- ((code >= 0x6f0) && (code <= 0x6f9)) ||
- ((code >= 0x966) && (code <= 0x96f)) ||
- ((code >= 0x9e6) && (code <= 0x9ef)) ||
- ((code >= 0x9f4) && (code <= 0x9f9)) ||
- ((code >= 0xa66) && (code <= 0xa6f)) ||
- ((code >= 0xae6) && (code <= 0xaef)) ||
- ((code >= 0xb66) && (code <= 0xb6f)) ||
- ((code >= 0xbe7) && (code <= 0xbf2)) ||
- ((code >= 0xc66) && (code <= 0xc6f)) ||
- ((code >= 0xce6) && (code <= 0xcef)) ||
- ((code >= 0xd66) && (code <= 0xd6f)) ||
- ((code >= 0xe50) && (code <= 0xe59)) ||
- ((code >= 0xed0) && (code <= 0xed9)) ||
- ((code >= 0xf20) && (code <= 0xf33)) ||
- ((code >= 0x1040) && (code <= 0x1049)) ||
- ((code >= 0x1369) && (code <= 0x137c)) ||
- ((code >= 0x16ee) && (code <= 0x16f0)) ||
- ((code >= 0x17e0) && (code <= 0x17e9)) ||
- ((code >= 0x1810) && (code <= 0x1819)) ||
- (code == 0x2070) ||
- ((code >= 0x2074) && (code <= 0x2079)) ||
- ((code >= 0x2080) && (code <= 0x2089)) ||
- ((code >= 0x2153) && (code <= 0x2183)) ||
- ((code >= 0x2460) && (code <= 0x249b)) ||
- (code == 0x24ea) ||
- ((code >= 0x2776) && (code <= 0x2793)) ||
- (code == 0x3007) ||
- ((code >= 0x3021) && (code <= 0x3029)) ||
- ((code >= 0x3038) && (code <= 0x303a)) ||
- ((code >= 0x3192) && (code <= 0x3195)) ||
- ((code >= 0x3220) && (code <= 0x3229)) ||
- ((code >= 0x3280) && (code <= 0x3289)) ||
- ((code >= 0xff10) && (code <= 0xff19)) ||
- ((code >= 0x10320) && (code <= 0x10323)) ||
- (code == 0x1034a) ||
- ((code >= 0x1d7ce) && (code <= 0x1d7ff)));
-}
-
-/**
- * xmlUCSIsCatNd:
- * @code: UCS code point
- *
- * Check whether the character is part of Nd UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatNd(int code) {
- return(((code >= 0x30) && (code <= 0x39)) ||
- ((code >= 0x660) && (code <= 0x669)) ||
- ((code >= 0x6f0) && (code <= 0x6f9)) ||
- ((code >= 0x966) && (code <= 0x96f)) ||
- ((code >= 0x9e6) && (code <= 0x9ef)) ||
- ((code >= 0xa66) && (code <= 0xa6f)) ||
- ((code >= 0xae6) && (code <= 0xaef)) ||
- ((code >= 0xb66) && (code <= 0xb6f)) ||
- ((code >= 0xbe7) && (code <= 0xbef)) ||
- ((code >= 0xc66) && (code <= 0xc6f)) ||
- ((code >= 0xce6) && (code <= 0xcef)) ||
- ((code >= 0xd66) && (code <= 0xd6f)) ||
- ((code >= 0xe50) && (code <= 0xe59)) ||
- ((code >= 0xed0) && (code <= 0xed9)) ||
- ((code >= 0xf20) && (code <= 0xf29)) ||
- ((code >= 0x1040) && (code <= 0x1049)) ||
- ((code >= 0x1369) && (code <= 0x1371)) ||
- ((code >= 0x17e0) && (code <= 0x17e9)) ||
- ((code >= 0x1810) && (code <= 0x1819)) ||
- ((code >= 0xff10) && (code <= 0xff19)) ||
- ((code >= 0x1d7ce) && (code <= 0x1d7ff)));
-}
-
-/**
- * xmlUCSIsCatNl:
- * @code: UCS code point
- *
- * Check whether the character is part of Nl UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatNl(int code) {
- return(((code >= 0x16ee) && (code <= 0x16f0)) ||
- ((code >= 0x2160) && (code <= 0x2183)) ||
- (code == 0x3007) ||
- ((code >= 0x3021) && (code <= 0x3029)) ||
- ((code >= 0x3038) && (code <= 0x303a)) ||
- (code == 0x1034a));
-}
-
-/**
- * xmlUCSIsCatNo:
- * @code: UCS code point
- *
- * Check whether the character is part of No UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatNo(int code) {
- return(((code >= 0xb2) && (code <= 0xb3)) ||
- (code == 0xb9) ||
- ((code >= 0xbc) && (code <= 0xbe)) ||
- ((code >= 0x9f4) && (code <= 0x9f9)) ||
- ((code >= 0xbf0) && (code <= 0xbf2)) ||
- ((code >= 0xf2a) && (code <= 0xf33)) ||
- ((code >= 0x1372) && (code <= 0x137c)) ||
- (code == 0x2070) ||
- ((code >= 0x2074) && (code <= 0x2079)) ||
- ((code >= 0x2080) && (code <= 0x2089)) ||
- ((code >= 0x2153) && (code <= 0x215f)) ||
- ((code >= 0x2460) && (code <= 0x249b)) ||
- (code == 0x24ea) ||
- ((code >= 0x2776) && (code <= 0x2793)) ||
- ((code >= 0x3192) && (code <= 0x3195)) ||
- ((code >= 0x3220) && (code <= 0x3229)) ||
- ((code >= 0x3280) && (code <= 0x3289)) ||
- ((code >= 0x10320) && (code <= 0x10323)));
-}
-
-/**
- * xmlUCSIsCatP:
- * @code: UCS code point
- *
- * Check whether the character is part of P UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatP(int code) {
- return(((code >= 0x21) && (code <= 0x23)) ||
- ((code >= 0x25) && (code <= 0x2a)) ||
- ((code >= 0x2c) && (code <= 0x2f)) ||
- ((code >= 0x3a) && (code <= 0x3b)) ||
- ((code >= 0x3f) && (code <= 0x40)) ||
- ((code >= 0x5b) && (code <= 0x5d)) ||
- (code == 0x5f) ||
- (code == 0x7b) ||
- (code == 0x7d) ||
- (code == 0xa1) ||
- (code == 0xab) ||
- (code == 0xad) ||
- (code == 0xb7) ||
- (code == 0xbb) ||
- (code == 0xbf) ||
- (code == 0x37e) ||
- (code == 0x387) ||
- ((code >= 0x55a) && (code <= 0x55f)) ||
- ((code >= 0x589) && (code <= 0x58a)) ||
- (code == 0x5be) ||
- (code == 0x5c0) ||
- (code == 0x5c3) ||
- ((code >= 0x5f3) && (code <= 0x5f4)) ||
- (code == 0x60c) ||
- (code == 0x61b) ||
- (code == 0x61f) ||
- ((code >= 0x66a) && (code <= 0x66d)) ||
- (code == 0x6d4) ||
- ((code >= 0x700) && (code <= 0x70d)) ||
- ((code >= 0x964) && (code <= 0x965)) ||
- (code == 0x970) ||
- (code == 0xdf4) ||
- (code == 0xe4f) ||
- ((code >= 0xe5a) && (code <= 0xe5b)) ||
- ((code >= 0xf04) && (code <= 0xf12)) ||
- ((code >= 0xf3a) && (code <= 0xf3d)) ||
- (code == 0xf85) ||
- ((code >= 0x104a) && (code <= 0x104f)) ||
- (code == 0x10fb) ||
- ((code >= 0x1361) && (code <= 0x1368)) ||
- ((code >= 0x166d) && (code <= 0x166e)) ||
- ((code >= 0x169b) && (code <= 0x169c)) ||
- ((code >= 0x16eb) && (code <= 0x16ed)) ||
- ((code >= 0x17d4) && (code <= 0x17da)) ||
- (code == 0x17dc) ||
- ((code >= 0x1800) && (code <= 0x180a)) ||
- ((code >= 0x2010) && (code <= 0x2027)) ||
- ((code >= 0x2030) && (code <= 0x2043)) ||
- ((code >= 0x2045) && (code <= 0x2046)) ||
- ((code >= 0x2048) && (code <= 0x204d)) ||
- ((code >= 0x207d) && (code <= 0x207e)) ||
- ((code >= 0x208d) && (code <= 0x208e)) ||
- ((code >= 0x2329) && (code <= 0x232a)) ||
- ((code >= 0x3001) && (code <= 0x3003)) ||
- ((code >= 0x3008) && (code <= 0x3011)) ||
- ((code >= 0x3014) && (code <= 0x301f)) ||
- (code == 0x3030) ||
- (code == 0x30fb) ||
- ((code >= 0xfd3e) && (code <= 0xfd3f)) ||
- ((code >= 0xfe30) && (code <= 0xfe44)) ||
- ((code >= 0xfe49) && (code <= 0xfe52)) ||
- ((code >= 0xfe54) && (code <= 0xfe61)) ||
- (code == 0xfe63) ||
- (code == 0xfe68) ||
- ((code >= 0xfe6a) && (code <= 0xfe6b)) ||
- ((code >= 0xff01) && (code <= 0xff03)) ||
- ((code >= 0xff05) && (code <= 0xff0a)) ||
- ((code >= 0xff0c) && (code <= 0xff0f)) ||
- ((code >= 0xff1a) && (code <= 0xff1b)) ||
- ((code >= 0xff1f) && (code <= 0xff20)) ||
- ((code >= 0xff3b) && (code <= 0xff3d)) ||
- (code == 0xff3f) ||
- (code == 0xff5b) ||
- (code == 0xff5d) ||
- ((code >= 0xff61) && (code <= 0xff65)));
-}
-
-/**
- * xmlUCSIsCatPc:
- * @code: UCS code point
- *
- * Check whether the character is part of Pc UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatPc(int code) {
- return((code == 0x5f) ||
- ((code >= 0x203f) && (code <= 0x2040)) ||
- (code == 0x30fb) ||
- ((code >= 0xfe33) && (code <= 0xfe34)) ||
- ((code >= 0xfe4d) && (code <= 0xfe4f)) ||
- (code == 0xff3f) ||
- (code == 0xff65));
-}
-
-/**
- * xmlUCSIsCatPd:
- * @code: UCS code point
- *
- * Check whether the character is part of Pd UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatPd(int code) {
- return((code == 0x2d) ||
- (code == 0xad) ||
- (code == 0x58a) ||
- (code == 0x1806) ||
- ((code >= 0x2010) && (code <= 0x2015)) ||
- (code == 0x301c) ||
- (code == 0x3030) ||
- ((code >= 0xfe31) && (code <= 0xfe32)) ||
- (code == 0xfe58) ||
- (code == 0xfe63) ||
- (code == 0xff0d));
-}
-
-/**
- * xmlUCSIsCatPe:
- * @code: UCS code point
- *
- * Check whether the character is part of Pe UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatPe(int code) {
- return((code == 0x29) ||
- (code == 0x5d) ||
- (code == 0x7d) ||
- (code == 0xf3b) ||
- (code == 0xf3d) ||
- (code == 0x169c) ||
- (code == 0x2046) ||
- (code == 0x207e) ||
- (code == 0x208e) ||
- (code == 0x232a) ||
- (code == 0x3009) ||
- (code == 0x300b) ||
- (code == 0x300d) ||
- (code == 0x300f) ||
- (code == 0x3011) ||
- (code == 0x3015) ||
- (code == 0x3017) ||
- (code == 0x3019) ||
- (code == 0x301b) ||
- ((code >= 0x301e) && (code <= 0x301f)) ||
- (code == 0xfd3f) ||
- (code == 0xfe36) ||
- (code == 0xfe38) ||
- (code == 0xfe3a) ||
- (code == 0xfe3c) ||
- (code == 0xfe3e) ||
- (code == 0xfe40) ||
- (code == 0xfe42) ||
- (code == 0xfe44) ||
- (code == 0xfe5a) ||
- (code == 0xfe5c) ||
- (code == 0xfe5e) ||
- (code == 0xff09) ||
- (code == 0xff3d) ||
- (code == 0xff5d) ||
- (code == 0xff63));
-}
-
-/**
- * xmlUCSIsCatPf:
- * @code: UCS code point
- *
- * Check whether the character is part of Pf UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatPf(int code) {
- return((code == 0xbb) ||
- (code == 0x2019) ||
- (code == 0x201d) ||
- (code == 0x203a));
-}
-
-/**
- * xmlUCSIsCatPi:
- * @code: UCS code point
- *
- * Check whether the character is part of Pi UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatPi(int code) {
- return((code == 0xab) ||
- (code == 0x2018) ||
- ((code >= 0x201b) && (code <= 0x201c)) ||
- (code == 0x201f) ||
- (code == 0x2039));
-}
-
-/**
- * xmlUCSIsCatPo:
- * @code: UCS code point
- *
- * Check whether the character is part of Po UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatPo(int code) {
- return(((code >= 0x21) && (code <= 0x23)) ||
- ((code >= 0x25) && (code <= 0x27)) ||
- (code == 0x2a) ||
- (code == 0x2c) ||
- ((code >= 0x2e) && (code <= 0x2f)) ||
- ((code >= 0x3a) && (code <= 0x3b)) ||
- ((code >= 0x3f) && (code <= 0x40)) ||
- (code == 0x5c) ||
- (code == 0xa1) ||
- (code == 0xb7) ||
- (code == 0xbf) ||
- (code == 0x37e) ||
- (code == 0x387) ||
- ((code >= 0x55a) && (code <= 0x55f)) ||
- (code == 0x589) ||
- (code == 0x5be) ||
- (code == 0x5c0) ||
- (code == 0x5c3) ||
- ((code >= 0x5f3) && (code <= 0x5f4)) ||
- (code == 0x60c) ||
- (code == 0x61b) ||
- (code == 0x61f) ||
- ((code >= 0x66a) && (code <= 0x66d)) ||
- (code == 0x6d4) ||
- ((code >= 0x700) && (code <= 0x70d)) ||
- ((code >= 0x964) && (code <= 0x965)) ||
- (code == 0x970) ||
- (code == 0xdf4) ||
- (code == 0xe4f) ||
- ((code >= 0xe5a) && (code <= 0xe5b)) ||
- ((code >= 0xf04) && (code <= 0xf12)) ||
- (code == 0xf85) ||
- ((code >= 0x104a) && (code <= 0x104f)) ||
- (code == 0x10fb) ||
- ((code >= 0x1361) && (code <= 0x1368)) ||
- ((code >= 0x166d) && (code <= 0x166e)) ||
- ((code >= 0x16eb) && (code <= 0x16ed)) ||
- ((code >= 0x17d4) && (code <= 0x17da)) ||
- (code == 0x17dc) ||
- ((code >= 0x1800) && (code <= 0x1805)) ||
- ((code >= 0x1807) && (code <= 0x180a)) ||
- ((code >= 0x2016) && (code <= 0x2017)) ||
- ((code >= 0x2020) && (code <= 0x2027)) ||
- ((code >= 0x2030) && (code <= 0x2038)) ||
- ((code >= 0x203b) && (code <= 0x203e)) ||
- ((code >= 0x2041) && (code <= 0x2043)) ||
- ((code >= 0x2048) && (code <= 0x204d)) ||
- ((code >= 0x3001) && (code <= 0x3003)) ||
- (code == 0xfe30) ||
- ((code >= 0xfe49) && (code <= 0xfe4c)) ||
- ((code >= 0xfe50) && (code <= 0xfe52)) ||
- ((code >= 0xfe54) && (code <= 0xfe57)) ||
- ((code >= 0xfe5f) && (code <= 0xfe61)) ||
- (code == 0xfe68) ||
- ((code >= 0xfe6a) && (code <= 0xfe6b)) ||
- ((code >= 0xff01) && (code <= 0xff03)) ||
- ((code >= 0xff05) && (code <= 0xff07)) ||
- (code == 0xff0a) ||
- (code == 0xff0c) ||
- ((code >= 0xff0e) && (code <= 0xff0f)) ||
- ((code >= 0xff1a) && (code <= 0xff1b)) ||
- ((code >= 0xff1f) && (code <= 0xff20)) ||
- (code == 0xff3c) ||
- (code == 0xff61) ||
- (code == 0xff64));
-}
-
-/**
- * xmlUCSIsCatPs:
- * @code: UCS code point
- *
- * Check whether the character is part of Ps UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatPs(int code) {
- return((code == 0x28) ||
- (code == 0x5b) ||
- (code == 0x7b) ||
- (code == 0xf3a) ||
- (code == 0xf3c) ||
- (code == 0x169b) ||
- (code == 0x201a) ||
- (code == 0x201e) ||
- (code == 0x2045) ||
- (code == 0x207d) ||
- (code == 0x208d) ||
- (code == 0x2329) ||
- (code == 0x3008) ||
- (code == 0x300a) ||
- (code == 0x300c) ||
- (code == 0x300e) ||
- (code == 0x3010) ||
- (code == 0x3014) ||
- (code == 0x3016) ||
- (code == 0x3018) ||
- (code == 0x301a) ||
- (code == 0x301d) ||
- (code == 0xfd3e) ||
- (code == 0xfe35) ||
- (code == 0xfe37) ||
- (code == 0xfe39) ||
- (code == 0xfe3b) ||
- (code == 0xfe3d) ||
- (code == 0xfe3f) ||
- (code == 0xfe41) ||
- (code == 0xfe43) ||
- (code == 0xfe59) ||
- (code == 0xfe5b) ||
- (code == 0xfe5d) ||
- (code == 0xff08) ||
- (code == 0xff3b) ||
- (code == 0xff5b) ||
- (code == 0xff62));
-}
-
-/**
- * xmlUCSIsCatS:
- * @code: UCS code point
- *
- * Check whether the character is part of S UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatS(int code) {
- return((code == 0x24) ||
- (code == 0x2b) ||
- ((code >= 0x3c) && (code <= 0x3e)) ||
- (code == 0x5e) ||
- (code == 0x60) ||
- (code == 0x7c) ||
- (code == 0x7e) ||
- ((code >= 0xa2) && (code <= 0xa9)) ||
- (code == 0xac) ||
- ((code >= 0xae) && (code <= 0xb1)) ||
- (code == 0xb4) ||
- (code == 0xb6) ||
- (code == 0xb8) ||
- (code == 0xd7) ||
- (code == 0xf7) ||
- ((code >= 0x2b9) && (code <= 0x2ba)) ||
- ((code >= 0x2c2) && (code <= 0x2cf)) ||
- ((code >= 0x2d2) && (code <= 0x2df)) ||
- ((code >= 0x2e5) && (code <= 0x2ed)) ||
- ((code >= 0x374) && (code <= 0x375)) ||
- ((code >= 0x384) && (code <= 0x385)) ||
- (code == 0x482) ||
- (code == 0x6e9) ||
- ((code >= 0x6fd) && (code <= 0x6fe)) ||
- ((code >= 0x9f2) && (code <= 0x9f3)) ||
- (code == 0x9fa) ||
- (code == 0xb70) ||
- (code == 0xe3f) ||
- ((code >= 0xf01) && (code <= 0xf03)) ||
- ((code >= 0xf13) && (code <= 0xf17)) ||
- ((code >= 0xf1a) && (code <= 0xf1f)) ||
- (code == 0xf34) ||
- (code == 0xf36) ||
- (code == 0xf38) ||
- ((code >= 0xfbe) && (code <= 0xfc5)) ||
- ((code >= 0xfc7) && (code <= 0xfcc)) ||
- (code == 0xfcf) ||
- (code == 0x17db) ||
- (code == 0x1fbd) ||
- ((code >= 0x1fbf) && (code <= 0x1fc1)) ||
- ((code >= 0x1fcd) && (code <= 0x1fcf)) ||
- ((code >= 0x1fdd) && (code <= 0x1fdf)) ||
- ((code >= 0x1fed) && (code <= 0x1fef)) ||
- ((code >= 0x1ffd) && (code <= 0x1ffe)) ||
- (code == 0x2044) ||
- ((code >= 0x207a) && (code <= 0x207c)) ||
- ((code >= 0x208a) && (code <= 0x208c)) ||
- ((code >= 0x20a0) && (code <= 0x20af)) ||
- ((code >= 0x2100) && (code <= 0x2101)) ||
- ((code >= 0x2103) && (code <= 0x2106)) ||
- ((code >= 0x2108) && (code <= 0x2109)) ||
- (code == 0x2114) ||
- ((code >= 0x2116) && (code <= 0x2118)) ||
- ((code >= 0x211e) && (code <= 0x2123)) ||
- (code == 0x2125) ||
- (code == 0x2127) ||
- (code == 0x2129) ||
- (code == 0x212e) ||
- (code == 0x2132) ||
- (code == 0x213a) ||
- ((code >= 0x2190) && (code <= 0x21f3)) ||
- ((code >= 0x2200) && (code <= 0x22f1)) ||
- ((code >= 0x2300) && (code <= 0x2328)) ||
- ((code >= 0x232b) && (code <= 0x237b)) ||
- ((code >= 0x237d) && (code <= 0x239a)) ||
- ((code >= 0x2400) && (code <= 0x2426)) ||
- ((code >= 0x2440) && (code <= 0x244a)) ||
- ((code >= 0x249c) && (code <= 0x24e9)) ||
- ((code >= 0x2500) && (code <= 0x2595)) ||
- ((code >= 0x25a0) && (code <= 0x25f7)) ||
- ((code >= 0x2600) && (code <= 0x2613)) ||
- ((code >= 0x2619) && (code <= 0x2671)) ||
- ((code >= 0x2701) && (code <= 0x2704)) ||
- ((code >= 0x2706) && (code <= 0x2709)) ||
- ((code >= 0x270c) && (code <= 0x2727)) ||
- ((code >= 0x2729) && (code <= 0x274b)) ||
- (code == 0x274d) ||
- ((code >= 0x274f) && (code <= 0x2752)) ||
- (code == 0x2756) ||
- ((code >= 0x2758) && (code <= 0x275e)) ||
- ((code >= 0x2761) && (code <= 0x2767)) ||
- (code == 0x2794) ||
- ((code >= 0x2798) && (code <= 0x27af)) ||
- ((code >= 0x27b1) && (code <= 0x27be)) ||
- ((code >= 0x2800) && (code <= 0x28ff)) ||
- ((code >= 0x2e80) && (code <= 0x2e99)) ||
- ((code >= 0x2e9b) && (code <= 0x2ef3)) ||
- ((code >= 0x2f00) && (code <= 0x2fd5)) ||
- ((code >= 0x2ff0) && (code <= 0x2ffb)) ||
- (code == 0x3004) ||
- ((code >= 0x3012) && (code <= 0x3013)) ||
- (code == 0x3020) ||
- ((code >= 0x3036) && (code <= 0x3037)) ||
- ((code >= 0x303e) && (code <= 0x303f)) ||
- ((code >= 0x309b) && (code <= 0x309c)) ||
- ((code >= 0x3190) && (code <= 0x3191)) ||
- ((code >= 0x3196) && (code <= 0x319f)) ||
- ((code >= 0x3200) && (code <= 0x321c)) ||
- ((code >= 0x322a) && (code <= 0x3243)) ||
- ((code >= 0x3260) && (code <= 0x327b)) ||
- (code == 0x327f) ||
- ((code >= 0x328a) && (code <= 0x32b0)) ||
- ((code >= 0x32c0) && (code <= 0x32cb)) ||
- ((code >= 0x32d0) && (code <= 0x32fe)) ||
- ((code >= 0x3300) && (code <= 0x3376)) ||
- ((code >= 0x337b) && (code <= 0x33dd)) ||
- ((code >= 0x33e0) && (code <= 0x33fe)) ||
- ((code >= 0xa490) && (code <= 0xa4a1)) ||
- ((code >= 0xa4a4) && (code <= 0xa4b3)) ||
- ((code >= 0xa4b5) && (code <= 0xa4c0)) ||
- ((code >= 0xa4c2) && (code <= 0xa4c4)) ||
- (code == 0xa4c6) ||
- (code == 0xfb29) ||
- (code == 0xfe62) ||
- ((code >= 0xfe64) && (code <= 0xfe66)) ||
- (code == 0xfe69) ||
- (code == 0xff04) ||
- (code == 0xff0b) ||
- ((code >= 0xff1c) && (code <= 0xff1e)) ||
- (code == 0xff3e) ||
- (code == 0xff40) ||
- (code == 0xff5c) ||
- (code == 0xff5e) ||
- ((code >= 0xffe0) && (code <= 0xffe6)) ||
- ((code >= 0xffe8) && (code <= 0xffee)) ||
- ((code >= 0xfffc) && (code <= 0xfffd)) ||
- ((code >= 0x1d000) && (code <= 0x1d0f5)) ||
- ((code >= 0x1d100) && (code <= 0x1d126)) ||
- ((code >= 0x1d12a) && (code <= 0x1d164)) ||
- ((code >= 0x1d16a) && (code <= 0x1d16c)) ||
- ((code >= 0x1d183) && (code <= 0x1d184)) ||
- ((code >= 0x1d18c) && (code <= 0x1d1a9)) ||
- ((code >= 0x1d1ae) && (code <= 0x1d1dd)) ||
- (code == 0x1d6c1) ||
- (code == 0x1d6db) ||
- (code == 0x1d6fb) ||
- (code == 0x1d715) ||
- (code == 0x1d735) ||
- (code == 0x1d74f) ||
- (code == 0x1d76f) ||
- (code == 0x1d789) ||
- (code == 0x1d7a9) ||
- (code == 0x1d7c3));
-}
-
-/**
- * xmlUCSIsCatSc:
- * @code: UCS code point
- *
- * Check whether the character is part of Sc UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatSc(int code) {
- return((code == 0x24) ||
- ((code >= 0xa2) && (code <= 0xa5)) ||
- ((code >= 0x9f2) && (code <= 0x9f3)) ||
- (code == 0xe3f) ||
- (code == 0x17db) ||
- ((code >= 0x20a0) && (code <= 0x20af)) ||
- (code == 0xfe69) ||
- (code == 0xff04) ||
- ((code >= 0xffe0) && (code <= 0xffe1)) ||
- ((code >= 0xffe5) && (code <= 0xffe6)));
-}
-
-/**
- * xmlUCSIsCatSk:
- * @code: UCS code point
- *
- * Check whether the character is part of Sk UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatSk(int code) {
- return((code == 0x5e) ||
- (code == 0x60) ||
- (code == 0xa8) ||
- (code == 0xaf) ||
- (code == 0xb4) ||
- (code == 0xb8) ||
- ((code >= 0x2b9) && (code <= 0x2ba)) ||
- ((code >= 0x2c2) && (code <= 0x2cf)) ||
- ((code >= 0x2d2) && (code <= 0x2df)) ||
- ((code >= 0x2e5) && (code <= 0x2ed)) ||
- ((code >= 0x374) && (code <= 0x375)) ||
- ((code >= 0x384) && (code <= 0x385)) ||
- (code == 0x1fbd) ||
- ((code >= 0x1fbf) && (code <= 0x1fc1)) ||
- ((code >= 0x1fcd) && (code <= 0x1fcf)) ||
- ((code >= 0x1fdd) && (code <= 0x1fdf)) ||
- ((code >= 0x1fed) && (code <= 0x1fef)) ||
- ((code >= 0x1ffd) && (code <= 0x1ffe)) ||
- ((code >= 0x309b) && (code <= 0x309c)) ||
- (code == 0xff3e) ||
- (code == 0xff40) ||
- (code == 0xffe3));
-}
-
-/**
- * xmlUCSIsCatSm:
- * @code: UCS code point
- *
- * Check whether the character is part of Sm UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatSm(int code) {
- return((code == 0x2b) ||
- ((code >= 0x3c) && (code <= 0x3e)) ||
- (code == 0x7c) ||
- (code == 0x7e) ||
- (code == 0xac) ||
- (code == 0xb1) ||
- (code == 0xd7) ||
- (code == 0xf7) ||
- (code == 0x2044) ||
- ((code >= 0x207a) && (code <= 0x207c)) ||
- ((code >= 0x208a) && (code <= 0x208c)) ||
- ((code >= 0x2190) && (code <= 0x2194)) ||
- ((code >= 0x219a) && (code <= 0x219b)) ||
- (code == 0x21a0) ||
- (code == 0x21a3) ||
- (code == 0x21a6) ||
- (code == 0x21ae) ||
- ((code >= 0x21ce) && (code <= 0x21cf)) ||
- (code == 0x21d2) ||
- (code == 0x21d4) ||
- ((code >= 0x2200) && (code <= 0x22f1)) ||
- ((code >= 0x2308) && (code <= 0x230b)) ||
- ((code >= 0x2320) && (code <= 0x2321)) ||
- (code == 0x25b7) ||
- (code == 0x25c1) ||
- (code == 0x266f) ||
- (code == 0xfb29) ||
- (code == 0xfe62) ||
- ((code >= 0xfe64) && (code <= 0xfe66)) ||
- (code == 0xff0b) ||
- ((code >= 0xff1c) && (code <= 0xff1e)) ||
- (code == 0xff5c) ||
- (code == 0xff5e) ||
- (code == 0xffe2) ||
- ((code >= 0xffe9) && (code <= 0xffec)) ||
- (code == 0x1d6c1) ||
- (code == 0x1d6db) ||
- (code == 0x1d6fb) ||
- (code == 0x1d715) ||
- (code == 0x1d735) ||
- (code == 0x1d74f) ||
- (code == 0x1d76f) ||
- (code == 0x1d789) ||
- (code == 0x1d7a9) ||
- (code == 0x1d7c3));
-}
-
-/**
- * xmlUCSIsCatSo:
- * @code: UCS code point
- *
- * Check whether the character is part of So UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatSo(int code) {
- return(((code >= 0xa6) && (code <= 0xa7)) ||
- (code == 0xa9) ||
- (code == 0xae) ||
- (code == 0xb0) ||
- (code == 0xb6) ||
- (code == 0x482) ||
- (code == 0x6e9) ||
- ((code >= 0x6fd) && (code <= 0x6fe)) ||
- (code == 0x9fa) ||
- (code == 0xb70) ||
- ((code >= 0xf01) && (code <= 0xf03)) ||
- ((code >= 0xf13) && (code <= 0xf17)) ||
- ((code >= 0xf1a) && (code <= 0xf1f)) ||
- (code == 0xf34) ||
- (code == 0xf36) ||
- (code == 0xf38) ||
- ((code >= 0xfbe) && (code <= 0xfc5)) ||
- ((code >= 0xfc7) && (code <= 0xfcc)) ||
- (code == 0xfcf) ||
- ((code >= 0x2100) && (code <= 0x2101)) ||
- ((code >= 0x2103) && (code <= 0x2106)) ||
- ((code >= 0x2108) && (code <= 0x2109)) ||
- (code == 0x2114) ||
- ((code >= 0x2116) && (code <= 0x2118)) ||
- ((code >= 0x211e) && (code <= 0x2123)) ||
- (code == 0x2125) ||
- (code == 0x2127) ||
- (code == 0x2129) ||
- (code == 0x212e) ||
- (code == 0x2132) ||
- (code == 0x213a) ||
- ((code >= 0x2195) && (code <= 0x2199)) ||
- ((code >= 0x219c) && (code <= 0x219f)) ||
- ((code >= 0x21a1) && (code <= 0x21a2)) ||
- ((code >= 0x21a4) && (code <= 0x21a5)) ||
- ((code >= 0x21a7) && (code <= 0x21ad)) ||
- ((code >= 0x21af) && (code <= 0x21cd)) ||
- ((code >= 0x21d0) && (code <= 0x21d1)) ||
- (code == 0x21d3) ||
- ((code >= 0x21d5) && (code <= 0x21f3)) ||
- ((code >= 0x2300) && (code <= 0x2307)) ||
- ((code >= 0x230c) && (code <= 0x231f)) ||
- ((code >= 0x2322) && (code <= 0x2328)) ||
- ((code >= 0x232b) && (code <= 0x237b)) ||
- ((code >= 0x237d) && (code <= 0x239a)) ||
- ((code >= 0x2400) && (code <= 0x2426)) ||
- ((code >= 0x2440) && (code <= 0x244a)) ||
- ((code >= 0x249c) && (code <= 0x24e9)) ||
- ((code >= 0x2500) && (code <= 0x2595)) ||
- ((code >= 0x25a0) && (code <= 0x25b6)) ||
- ((code >= 0x25b8) && (code <= 0x25c0)) ||
- ((code >= 0x25c2) && (code <= 0x25f7)) ||
- ((code >= 0x2600) && (code <= 0x2613)) ||
- ((code >= 0x2619) && (code <= 0x266e)) ||
- ((code >= 0x2670) && (code <= 0x2671)) ||
- ((code >= 0x2701) && (code <= 0x2704)) ||
- ((code >= 0x2706) && (code <= 0x2709)) ||
- ((code >= 0x270c) && (code <= 0x2727)) ||
- ((code >= 0x2729) && (code <= 0x274b)) ||
- (code == 0x274d) ||
- ((code >= 0x274f) && (code <= 0x2752)) ||
- (code == 0x2756) ||
- ((code >= 0x2758) && (code <= 0x275e)) ||
- ((code >= 0x2761) && (code <= 0x2767)) ||
- (code == 0x2794) ||
- ((code >= 0x2798) && (code <= 0x27af)) ||
- ((code >= 0x27b1) && (code <= 0x27be)) ||
- ((code >= 0x2800) && (code <= 0x28ff)) ||
- ((code >= 0x2e80) && (code <= 0x2e99)) ||
- ((code >= 0x2e9b) && (code <= 0x2ef3)) ||
- ((code >= 0x2f00) && (code <= 0x2fd5)) ||
- ((code >= 0x2ff0) && (code <= 0x2ffb)) ||
- (code == 0x3004) ||
- ((code >= 0x3012) && (code <= 0x3013)) ||
- (code == 0x3020) ||
- ((code >= 0x3036) && (code <= 0x3037)) ||
- ((code >= 0x303e) && (code <= 0x303f)) ||
- ((code >= 0x3190) && (code <= 0x3191)) ||
- ((code >= 0x3196) && (code <= 0x319f)) ||
- ((code >= 0x3200) && (code <= 0x321c)) ||
- ((code >= 0x322a) && (code <= 0x3243)) ||
- ((code >= 0x3260) && (code <= 0x327b)) ||
- (code == 0x327f) ||
- ((code >= 0x328a) && (code <= 0x32b0)) ||
- ((code >= 0x32c0) && (code <= 0x32cb)) ||
- ((code >= 0x32d0) && (code <= 0x32fe)) ||
- ((code >= 0x3300) && (code <= 0x3376)) ||
- ((code >= 0x337b) && (code <= 0x33dd)) ||
- ((code >= 0x33e0) && (code <= 0x33fe)) ||
- ((code >= 0xa490) && (code <= 0xa4a1)) ||
- ((code >= 0xa4a4) && (code <= 0xa4b3)) ||
- ((code >= 0xa4b5) && (code <= 0xa4c0)) ||
- ((code >= 0xa4c2) && (code <= 0xa4c4)) ||
- (code == 0xa4c6) ||
- (code == 0xffe4) ||
- (code == 0xffe8) ||
- ((code >= 0xffed) && (code <= 0xffee)) ||
- ((code >= 0xfffc) && (code <= 0xfffd)) ||
- ((code >= 0x1d000) && (code <= 0x1d0f5)) ||
- ((code >= 0x1d100) && (code <= 0x1d126)) ||
- ((code >= 0x1d12a) && (code <= 0x1d164)) ||
- ((code >= 0x1d16a) && (code <= 0x1d16c)) ||
- ((code >= 0x1d183) && (code <= 0x1d184)) ||
- ((code >= 0x1d18c) && (code <= 0x1d1a9)) ||
- ((code >= 0x1d1ae) && (code <= 0x1d1dd)));
-}
-
-/**
- * xmlUCSIsCatZ:
- * @code: UCS code point
- *
- * Check whether the character is part of Z UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatZ(int code) {
- return((code == 0x20) ||
- (code == 0xa0) ||
- (code == 0x1680) ||
- ((code >= 0x2000) && (code <= 0x200b)) ||
- ((code >= 0x2028) && (code <= 0x2029)) ||
- (code == 0x202f) ||
- (code == 0x3000));
-}
-
-/**
- * xmlUCSIsCatZl:
- * @code: UCS code point
- *
- * Check whether the character is part of Zl UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatZl(int code) {
- return((code == 0x2028));
-}
-
-/**
- * xmlUCSIsCatZp:
- * @code: UCS code point
- *
- * Check whether the character is part of Zp UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatZp(int code) {
- return((code == 0x2029));
-}
-
-/**
- * xmlUCSIsCatZs:
- * @code: UCS code point
- *
- * Check whether the character is part of Zs UCS Category
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlUCSIsCatZs(int code) {
- return((code == 0x20) ||
- (code == 0xa0) ||
- (code == 0x1680) ||
- ((code >= 0x2000) && (code <= 0x200b)) ||
- (code == 0x202f) ||
- (code == 0x3000));
-}
-
-/**
- * xmlUCSIsCat:
- * @code: UCS code point
- * @cat: UCS Category name
- *
- * Check whether the caracter is part of the UCS Category
- *
- * Returns 1 if true, 0 if false and -1 on unknown category
- */
-int
-xmlUCSIsCat(int code, const char *cat) {
- if (!strcmp(cat, "C"))
- return(xmlUCSIsCatC(code));
- if (!strcmp(cat, "Cc"))
- return(xmlUCSIsCatCc(code));
- if (!strcmp(cat, "Cf"))
- return(xmlUCSIsCatCf(code));
- if (!strcmp(cat, "Co"))
- return(xmlUCSIsCatCo(code));
- if (!strcmp(cat, "Cs"))
- return(xmlUCSIsCatCs(code));
- if (!strcmp(cat, "L"))
- return(xmlUCSIsCatL(code));
- if (!strcmp(cat, "Ll"))
- return(xmlUCSIsCatLl(code));
- if (!strcmp(cat, "Lm"))
- return(xmlUCSIsCatLm(code));
- if (!strcmp(cat, "Lo"))
- return(xmlUCSIsCatLo(code));
- if (!strcmp(cat, "Lt"))
- return(xmlUCSIsCatLt(code));
- if (!strcmp(cat, "Lu"))
- return(xmlUCSIsCatLu(code));
- if (!strcmp(cat, "M"))
- return(xmlUCSIsCatM(code));
- if (!strcmp(cat, "Mc"))
- return(xmlUCSIsCatMc(code));
- if (!strcmp(cat, "Me"))
- return(xmlUCSIsCatMe(code));
- if (!strcmp(cat, "Mn"))
- return(xmlUCSIsCatMn(code));
- if (!strcmp(cat, "N"))
- return(xmlUCSIsCatN(code));
- if (!strcmp(cat, "Nd"))
- return(xmlUCSIsCatNd(code));
- if (!strcmp(cat, "Nl"))
- return(xmlUCSIsCatNl(code));
- if (!strcmp(cat, "No"))
- return(xmlUCSIsCatNo(code));
- if (!strcmp(cat, "P"))
- return(xmlUCSIsCatP(code));
- if (!strcmp(cat, "Pc"))
- return(xmlUCSIsCatPc(code));
- if (!strcmp(cat, "Pd"))
- return(xmlUCSIsCatPd(code));
- if (!strcmp(cat, "Pe"))
- return(xmlUCSIsCatPe(code));
- if (!strcmp(cat, "Pf"))
- return(xmlUCSIsCatPf(code));
- if (!strcmp(cat, "Pi"))
- return(xmlUCSIsCatPi(code));
- if (!strcmp(cat, "Po"))
- return(xmlUCSIsCatPo(code));
- if (!strcmp(cat, "Ps"))
- return(xmlUCSIsCatPs(code));
- if (!strcmp(cat, "S"))
- return(xmlUCSIsCatS(code));
- if (!strcmp(cat, "Sc"))
- return(xmlUCSIsCatSc(code));
- if (!strcmp(cat, "Sk"))
- return(xmlUCSIsCatSk(code));
- if (!strcmp(cat, "Sm"))
- return(xmlUCSIsCatSm(code));
- if (!strcmp(cat, "So"))
- return(xmlUCSIsCatSo(code));
- if (!strcmp(cat, "Z"))
- return(xmlUCSIsCatZ(code));
- if (!strcmp(cat, "Zl"))
- return(xmlUCSIsCatZl(code));
- if (!strcmp(cat, "Zp"))
- return(xmlUCSIsCatZp(code));
- if (!strcmp(cat, "Zs"))
- return(xmlUCSIsCatZs(code));
- return(-1);
-}
-
-
-#endif /* LIBXML_UNICODE_ENABLED */
diff --git a/bundle/libxml/xpath.c b/bundle/libxml/xpath.c
deleted file mode 100644
index 305bccf335..0000000000
--- a/bundle/libxml/xpath.c
+++ /dev/null
@@ -1,10990 +0,0 @@
-/*
- * xpath.c: XML Path Language implementation
- * XPath is a language for addressing parts of an XML document,
- * designed to be used by both XSLT and XPointer
- *
- * Reference: W3C Recommendation 16 November 1999
- * http://www.w3.org/TR/1999/REC-xpath-19991116
- * Public reference:
- * http://www.w3.org/TR/xpath
- *
- * See Copyright for the status of this software
- *
- * Author: daniel@veillard.com
- *
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-#ifdef LIBXML_XPATH_ENABLED
-
-#include <string.h>
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_MATH_H
-#include <math.h>
-#endif
-#ifdef HAVE_FLOAT_H
-#include <float.h>
-#endif
-#ifdef HAVE_CTYPE_H
-#include <ctype.h>
-#endif
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-
-#include <libxml/xmlmemory.h>
-#include <libxml/tree.h>
-#include <libxml/valid.h>
-#include <libxml/xpath.h>
-#include <libxml/xpathInternals.h>
-#include <libxml/parserInternals.h>
-#include <libxml/hash.h>
-#ifdef LIBXML_XPTR_ENABLED
-#include <libxml/xpointer.h>
-#endif
-#ifdef LIBXML_DEBUG_ENABLED
-#include <libxml/debugXML.h>
-#endif
-#include <libxml/xmlerror.h>
-#include <libxml/threads.h>
-#include <libxml/globals.h>
-
-/* #define DEBUG */
-/* #define DEBUG_STEP */
-/* #define DEBUG_STEP_NTH */
-/* #define DEBUG_EXPR */
-/* #define DEBUG_EVAL_COUNTS */
-
-static xmlNs xmlXPathXMLNamespaceStruct = {
- NULL,
- XML_NAMESPACE_DECL,
- XML_XML_NAMESPACE,
- BAD_CAST "xml",
- NULL
-};
-static xmlNsPtr xmlXPathXMLNamespace = &xmlXPathXMLNamespaceStruct;
-#ifndef LIBXML_THREAD_ENABLED
-/*
- * Optimizer is disabled only when threaded apps are detected while
- * the library ain't compiled for thread safety.
- */
-static int xmlXPathDisableOptimizer = 0;
-#endif
-
-/************************************************************************
- * *
- * Floating point stuff *
- * *
- ************************************************************************/
-
-#ifndef TRIO_REPLACE_STDIO
-#define TRIO_PUBLIC static
-#endif
-#include "trionan.c"
-
-/*
- * The lack of portability of this section of the libc is annoying !
- */
-double xmlXPathNAN = 0;
-double xmlXPathPINF = 1;
-double xmlXPathNINF = -1;
-double xmlXPathNZERO = 0;
-static int xmlXPathInitialized = 0;
-
-/**
- * xmlXPathInit:
- *
- * Initialize the XPath environment
- */
-void
-xmlXPathInit(void) {
- if (xmlXPathInitialized) return;
-
- xmlXPathPINF = trio_pinf();
- xmlXPathNINF = trio_ninf();
- xmlXPathNAN = trio_nan();
- xmlXPathNZERO = trio_nzero();
-
- xmlXPathInitialized = 1;
-}
-
-/**
- * xmlXPathIsNaN:
- * @val: a double value
- *
- * Provides a portable isnan() function to detect whether a double
- * is a NotaNumber. Based on trio code
- * http://sourceforge.net/projects/ctrio/
- *
- * Returns 1 if the value is a NaN, 0 otherwise
- */
-int
-xmlXPathIsNaN(double val) {
- return(trio_isnan(val));
-}
-
-/**
- * xmlXPathIsInf:
- * @val: a double value
- *
- * Provides a portable isinf() function to detect whether a double
- * is a +Infinite or -Infinite. Based on trio code
- * http://sourceforge.net/projects/ctrio/
- *
- * Returns 1 vi the value is +Infinite, -1 if -Infinite, 0 otherwise
- */
-int
-xmlXPathIsInf(double val) {
- return(trio_isinf(val));
-}
-
-/**
- * xmlXPathGetSign:
- * @val: a double value
- *
- * Provides a portable function to detect the sign of a double
- * Modified from trio code
- * http://sourceforge.net/projects/ctrio/
- *
- * Returns 1 if the value is Negative, 0 if positive
- */
-static int
-xmlXPathGetSign(double val) {
- return(trio_signbit(val));
-}
-
-
-/************************************************************************
- * *
- * Parser Types *
- * *
- ************************************************************************/
-
-/*
- * Types are private:
- */
-
-typedef enum {
- XPATH_OP_END=0,
- XPATH_OP_AND,
- XPATH_OP_OR,
- XPATH_OP_EQUAL,
- XPATH_OP_CMP,
- XPATH_OP_PLUS,
- XPATH_OP_MULT,
- XPATH_OP_UNION,
- XPATH_OP_ROOT,
- XPATH_OP_NODE,
- XPATH_OP_RESET,
- XPATH_OP_COLLECT,
- XPATH_OP_VALUE,
- XPATH_OP_VARIABLE,
- XPATH_OP_FUNCTION,
- XPATH_OP_ARG,
- XPATH_OP_PREDICATE,
- XPATH_OP_FILTER,
- XPATH_OP_SORT
-#ifdef LIBXML_XPTR_ENABLED
- ,XPATH_OP_RANGETO
-#endif
-} xmlXPathOp;
-
-typedef enum {
- AXIS_ANCESTOR = 1,
- AXIS_ANCESTOR_OR_SELF,
- AXIS_ATTRIBUTE,
- AXIS_CHILD,
- AXIS_DESCENDANT,
- AXIS_DESCENDANT_OR_SELF,
- AXIS_FOLLOWING,
- AXIS_FOLLOWING_SIBLING,
- AXIS_NAMESPACE,
- AXIS_PARENT,
- AXIS_PRECEDING,
- AXIS_PRECEDING_SIBLING,
- AXIS_SELF
-} xmlXPathAxisVal;
-
-typedef enum {
- NODE_TEST_NONE = 0,
- NODE_TEST_TYPE = 1,
- NODE_TEST_PI = 2,
- NODE_TEST_ALL = 3,
- NODE_TEST_NS = 4,
- NODE_TEST_NAME = 5
-} xmlXPathTestVal;
-
-typedef enum {
- NODE_TYPE_NODE = 0,
- NODE_TYPE_COMMENT = XML_COMMENT_NODE,
- NODE_TYPE_TEXT = XML_TEXT_NODE,
- NODE_TYPE_PI = XML_PI_NODE
-} xmlXPathTypeVal;
-
-
-typedef struct _xmlXPathStepOp xmlXPathStepOp;
-typedef xmlXPathStepOp *xmlXPathStepOpPtr;
-struct _xmlXPathStepOp {
- xmlXPathOp op;
- int ch1;
- int ch2;
- int value;
- int value2;
- int value3;
- void *value4;
- void *value5;
- void *cache;
- void *cacheURI;
-};
-
-struct _xmlXPathCompExpr {
- int nbStep;
- int maxStep;
- xmlXPathStepOp *steps; /* ops for computation */
- int last;
- xmlChar *expr;
-#ifdef DEBUG_EVAL_COUNTS
- int nb;
- xmlChar *string;
-#endif
-};
-
-/************************************************************************
- * *
- * Parser Type functions *
- * *
- ************************************************************************/
-
-/**
- * xmlXPathNewCompExpr:
- *
- * Create a new Xpath component
- *
- * Returns the newly allocated xmlXPathCompExprPtr or NULL in case of error
- */
-static xmlXPathCompExprPtr
-xmlXPathNewCompExpr(void) {
- xmlXPathCompExprPtr cur;
-
- cur = (xmlXPathCompExprPtr) xmlMalloc(sizeof(xmlXPathCompExpr));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNewCompExpr : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlXPathCompExpr));
- cur->maxStep = 10;
- cur->nbStep = 0;
- cur->steps = (xmlXPathStepOp *) xmlMalloc(cur->maxStep *
- sizeof(xmlXPathStepOp));
- if (cur->steps == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNewCompExpr : malloc failed\n");
- xmlFree(cur);
- return(NULL);
- }
- memset(cur->steps, 0, cur->maxStep * sizeof(xmlXPathStepOp));
- cur->last = -1;
-#ifdef DEBUG_EVAL_COUNTS
- cur->nb = 0;
-#endif
- return(cur);
-}
-
-/**
- * xmlXPathFreeCompExpr:
- * @comp: an XPATH comp
- *
- * Free up the memory allocated by @comp
- */
-void
-xmlXPathFreeCompExpr(xmlXPathCompExprPtr comp)
-{
- xmlXPathStepOpPtr op;
- int i;
-
- if (comp == NULL)
- return;
- for (i = 0; i < comp->nbStep; i++) {
- op = &comp->steps[i];
- if (op->value4 != NULL) {
- if (op->op == XPATH_OP_VALUE)
- xmlXPathFreeObject(op->value4);
- else
- xmlFree(op->value4);
- }
- if (op->value5 != NULL)
- xmlFree(op->value5);
- }
- if (comp->steps != NULL) {
- xmlFree(comp->steps);
- }
-#ifdef DEBUG_EVAL_COUNTS
- if (comp->string != NULL) {
- xmlFree(comp->string);
- }
-#endif
- if (comp->expr != NULL) {
- xmlFree(comp->expr);
- }
-
- xmlFree(comp);
-}
-
-/**
- * xmlXPathCompExprAdd:
- * @comp: the compiled expression
- * @ch1: first child index
- * @ch2: second child index
- * @op: an op
- * @value: the first int value
- * @value2: the second int value
- * @value3: the third int value
- * @value4: the first string value
- * @value5: the second string value
- *
- * Add an step to an XPath Compiled Expression
- *
- * Returns -1 in case of failure, the index otherwise
- */
-static int
-xmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, int ch2,
- xmlXPathOp op, int value,
- int value2, int value3, void *value4, void *value5) {
- if (comp->nbStep >= comp->maxStep) {
- xmlXPathStepOp *real;
-
- comp->maxStep *= 2;
- real = (xmlXPathStepOp *) xmlRealloc(comp->steps,
- comp->maxStep * sizeof(xmlXPathStepOp));
- if (real == NULL) {
- comp->maxStep /= 2;
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathCompExprAdd : realloc failed\n");
- return(-1);
- }
- comp->steps = real;
- }
- comp->last = comp->nbStep;
- comp->steps[comp->nbStep].ch1 = ch1;
- comp->steps[comp->nbStep].ch2 = ch2;
- comp->steps[comp->nbStep].op = op;
- comp->steps[comp->nbStep].value = value;
- comp->steps[comp->nbStep].value2 = value2;
- comp->steps[comp->nbStep].value3 = value3;
- comp->steps[comp->nbStep].value4 = value4;
- comp->steps[comp->nbStep].value5 = value5;
- comp->steps[comp->nbStep].cache = NULL;
- return(comp->nbStep++);
-}
-
-/**
- * xmlXPathCompSwap:
- * @comp: the compiled expression
- * @op: operation index
- *
- * Swaps 2 operations in the compiled expression
- */
-static void
-xmlXPathCompSwap(xmlXPathStepOpPtr op) {
- int tmp;
-
-#ifndef LIBXML_THREAD_ENABLED
- /*
- * Since this manipulates possibly shared variables, this is
- * disable if one detects that the library is used in a multithreaded
- * application
- */
- if (xmlXPathDisableOptimizer)
- return;
-#endif
-
- tmp = op->ch1;
- op->ch1 = op->ch2;
- op->ch2 = tmp;
-}
-
-#define PUSH_FULL_EXPR(op, op1, op2, val, val2, val3, val4, val5) \
- xmlXPathCompExprAdd(ctxt->comp, (op1), (op2), \
- (op), (val), (val2), (val3), (val4), (val5))
-#define PUSH_LONG_EXPR(op, val, val2, val3, val4, val5) \
- xmlXPathCompExprAdd(ctxt->comp, ctxt->comp->last, -1, \
- (op), (val), (val2), (val3), (val4), (val5))
-
-#define PUSH_LEAVE_EXPR(op, val, val2) \
-xmlXPathCompExprAdd(ctxt->comp, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL)
-
-#define PUSH_UNARY_EXPR(op, ch, val, val2) \
-xmlXPathCompExprAdd(ctxt->comp, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL)
-
-#define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2) \
-xmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op), (val), (val2), 0 ,NULL ,NULL)
-
-/************************************************************************
- * *
- * Debugging related functions *
- * *
- ************************************************************************/
-
-#define TODO \
- xmlGenericError(xmlGenericErrorContext, \
- "Unimplemented block at %s:%d\n", \
- __FILE__, __LINE__);
-
-#define STRANGE \
- xmlGenericError(xmlGenericErrorContext, \
- "Internal error at %s:%d\n", \
- __FILE__, __LINE__);
-
-#ifdef LIBXML_DEBUG_ENABLED
-static void
-xmlXPathDebugDumpNode(FILE *output, xmlNodePtr cur, int depth) {
- int i;
- char shift[100];
-
- for (i = 0;((i < depth) && (i < 25));i++)
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i] = shift[2 * i + 1] = 0;
- if (cur == NULL) {
- fprintf(output, shift);
- fprintf(output, "Node is NULL !\n");
- return;
-
- }
-
- if ((cur->type == XML_DOCUMENT_NODE) ||
- (cur->type == XML_HTML_DOCUMENT_NODE)) {
- fprintf(output, shift);
- fprintf(output, " /\n");
- } else if (cur->type == XML_ATTRIBUTE_NODE)
- xmlDebugDumpAttr(output, (xmlAttrPtr)cur, depth);
- else
- xmlDebugDumpOneNode(output, cur, depth);
-}
-static void
-xmlXPathDebugDumpNodeList(FILE *output, xmlNodePtr cur, int depth) {
- xmlNodePtr tmp;
- int i;
- char shift[100];
-
- for (i = 0;((i < depth) && (i < 25));i++)
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i] = shift[2 * i + 1] = 0;
- if (cur == NULL) {
- fprintf(output, shift);
- fprintf(output, "Node is NULL !\n");
- return;
-
- }
-
- while (cur != NULL) {
- tmp = cur;
- cur = cur->next;
- xmlDebugDumpOneNode(output, tmp, depth);
- }
-}
-
-static void
-xmlXPathDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur, int depth) {
- int i;
- char shift[100];
-
- for (i = 0;((i < depth) && (i < 25));i++)
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i] = shift[2 * i + 1] = 0;
-
- if (cur == NULL) {
- fprintf(output, shift);
- fprintf(output, "NodeSet is NULL !\n");
- return;
-
- }
-
- if (cur != NULL) {
- fprintf(output, "Set contains %d nodes:\n", cur->nodeNr);
- for (i = 0;i < cur->nodeNr;i++) {
- fprintf(output, shift);
- fprintf(output, "%d", i + 1);
- xmlXPathDebugDumpNode(output, cur->nodeTab[i], depth + 1);
- }
- }
-}
-
-static void
-xmlXPathDebugDumpValueTree(FILE *output, xmlNodeSetPtr cur, int depth) {
- int i;
- char shift[100];
-
- for (i = 0;((i < depth) && (i < 25));i++)
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i] = shift[2 * i + 1] = 0;
-
- if ((cur == NULL) || (cur->nodeNr == 0) || (cur->nodeTab[0] == NULL)) {
- fprintf(output, shift);
- fprintf(output, "Value Tree is NULL !\n");
- return;
-
- }
-
- fprintf(output, shift);
- fprintf(output, "%d", i + 1);
- xmlXPathDebugDumpNodeList(output, cur->nodeTab[0]->children, depth + 1);
-}
-#if defined(LIBXML_XPTR_ENABLED)
-static void
-xmlXPathDebugDumpLocationSet(FILE *output, xmlLocationSetPtr cur, int depth) {
- int i;
- char shift[100];
-
- for (i = 0;((i < depth) && (i < 25));i++)
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i] = shift[2 * i + 1] = 0;
-
- if (cur == NULL) {
- fprintf(output, shift);
- fprintf(output, "LocationSet is NULL !\n");
- return;
-
- }
-
- for (i = 0;i < cur->locNr;i++) {
- fprintf(output, shift);
- fprintf(output, "%d : ", i + 1);
- xmlXPathDebugDumpObject(output, cur->locTab[i], depth + 1);
- }
-}
-#endif /* LIBXML_XPTR_ENABLED */
-
-/**
- * xmlXPathDebugDumpObject:
- * @output: the FILE * to dump the output
- * @cur: the object to inspect
- * @depth: indentation level
- *
- * Dump the content of the object for debugging purposes
- */
-void
-xmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth) {
- int i;
- char shift[100];
-
- for (i = 0;((i < depth) && (i < 25));i++)
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i] = shift[2 * i + 1] = 0;
-
- fprintf(output, shift);
-
- if (cur == NULL) {
- fprintf(output, "Object is empty (NULL)\n");
- return;
- }
- switch(cur->type) {
- case XPATH_UNDEFINED:
- fprintf(output, "Object is uninitialized\n");
- break;
- case XPATH_NODESET:
- fprintf(output, "Object is a Node Set :\n");
- xmlXPathDebugDumpNodeSet(output, cur->nodesetval, depth);
- break;
- case XPATH_XSLT_TREE:
- fprintf(output, "Object is an XSLT value tree :\n");
- xmlXPathDebugDumpValueTree(output, cur->nodesetval, depth);
- break;
- case XPATH_BOOLEAN:
- fprintf(output, "Object is a Boolean : ");
- if (cur->boolval) fprintf(output, "true\n");
- else fprintf(output, "false\n");
- break;
- case XPATH_NUMBER:
- switch (xmlXPathIsInf(cur->floatval)) {
- case 1:
- fprintf(output, "Object is a number : Infinity\n");
- break;
- case -1:
- fprintf(output, "Object is a number : -Infinity\n");
- break;
- default:
- if (xmlXPathIsNaN(cur->floatval)) {
- fprintf(output, "Object is a number : NaN\n");
- } else if (cur->floatval == 0 && xmlXPathGetSign(cur->floatval) != 0) {
- fprintf(output, "Object is a number : 0\n");
- } else {
- fprintf(output, "Object is a number : %0g\n", cur->floatval);
- }
- }
- break;
- case XPATH_STRING:
- fprintf(output, "Object is a string : ");
- xmlDebugDumpString(output, cur->stringval);
- fprintf(output, "\n");
- break;
- case XPATH_POINT:
- fprintf(output, "Object is a point : index %d in node", cur->index);
- xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, depth + 1);
- fprintf(output, "\n");
- break;
- case XPATH_RANGE:
- if ((cur->user2 == NULL) ||
- ((cur->user2 == cur->user) && (cur->index == cur->index2))) {
- fprintf(output, "Object is a collapsed range :\n");
- fprintf(output, shift);
- if (cur->index >= 0)
- fprintf(output, "index %d in ", cur->index);
- fprintf(output, "node\n");
- xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user,
- depth + 1);
- } else {
- fprintf(output, "Object is a range :\n");
- fprintf(output, shift);
- fprintf(output, "From ");
- if (cur->index >= 0)
- fprintf(output, "index %d in ", cur->index);
- fprintf(output, "node\n");
- xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user,
- depth + 1);
- fprintf(output, shift);
- fprintf(output, "To ");
- if (cur->index2 >= 0)
- fprintf(output, "index %d in ", cur->index2);
- fprintf(output, "node\n");
- xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user2,
- depth + 1);
- fprintf(output, "\n");
- }
- break;
- case XPATH_LOCATIONSET:
-#if defined(LIBXML_XPTR_ENABLED)
- fprintf(output, "Object is a Location Set:\n");
- xmlXPathDebugDumpLocationSet(output,
- (xmlLocationSetPtr) cur->user, depth);
-#endif
- break;
- case XPATH_USERS:
- fprintf(output, "Object is user defined\n");
- break;
- }
-}
-
-static void
-xmlXPathDebugDumpStepOp(FILE *output, xmlXPathCompExprPtr comp,
- xmlXPathStepOpPtr op, int depth) {
- int i;
- char shift[100];
-
- for (i = 0;((i < depth) && (i < 25));i++)
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i] = shift[2 * i + 1] = 0;
-
- fprintf(output, shift);
- if (op == NULL) {
- fprintf(output, "Step is NULL\n");
- return;
- }
- switch (op->op) {
- case XPATH_OP_END:
- fprintf(output, "END"); break;
- case XPATH_OP_AND:
- fprintf(output, "AND"); break;
- case XPATH_OP_OR:
- fprintf(output, "OR"); break;
- case XPATH_OP_EQUAL:
- if (op->value)
- fprintf(output, "EQUAL =");
- else
- fprintf(output, "EQUAL !=");
- break;
- case XPATH_OP_CMP:
- if (op->value)
- fprintf(output, "CMP <");
- else
- fprintf(output, "CMP >");
- if (!op->value2)
- fprintf(output, "=");
- break;
- case XPATH_OP_PLUS:
- if (op->value == 0)
- fprintf(output, "PLUS -");
- else if (op->value == 1)
- fprintf(output, "PLUS +");
- else if (op->value == 2)
- fprintf(output, "PLUS unary -");
- else if (op->value == 3)
- fprintf(output, "PLUS unary - -");
- break;
- case XPATH_OP_MULT:
- if (op->value == 0)
- fprintf(output, "MULT *");
- else if (op->value == 1)
- fprintf(output, "MULT div");
- else
- fprintf(output, "MULT mod");
- break;
- case XPATH_OP_UNION:
- fprintf(output, "UNION"); break;
- case XPATH_OP_ROOT:
- fprintf(output, "ROOT"); break;
- case XPATH_OP_NODE:
- fprintf(output, "NODE"); break;
- case XPATH_OP_RESET:
- fprintf(output, "RESET"); break;
- case XPATH_OP_SORT:
- fprintf(output, "SORT"); break;
- case XPATH_OP_COLLECT: {
- xmlXPathAxisVal axis = op->value;
- xmlXPathTestVal test = op->value2;
- xmlXPathTypeVal type = op->value3;
- const xmlChar *prefix = op->value4;
- const xmlChar *name = op->value5;
-
- fprintf(output, "COLLECT ");
- switch (axis) {
- case AXIS_ANCESTOR:
- fprintf(output, " 'ancestors' "); break;
- case AXIS_ANCESTOR_OR_SELF:
- fprintf(output, " 'ancestors-or-self' "); break;
- case AXIS_ATTRIBUTE:
- fprintf(output, " 'attributes' "); break;
- case AXIS_CHILD:
- fprintf(output, " 'child' "); break;
- case AXIS_DESCENDANT:
- fprintf(output, " 'descendant' "); break;
- case AXIS_DESCENDANT_OR_SELF:
- fprintf(output, " 'descendant-or-self' "); break;
- case AXIS_FOLLOWING:
- fprintf(output, " 'following' "); break;
- case AXIS_FOLLOWING_SIBLING:
- fprintf(output, " 'following-siblings' "); break;
- case AXIS_NAMESPACE:
- fprintf(output, " 'namespace' "); break;
- case AXIS_PARENT:
- fprintf(output, " 'parent' "); break;
- case AXIS_PRECEDING:
- fprintf(output, " 'preceding' "); break;
- case AXIS_PRECEDING_SIBLING:
- fprintf(output, " 'preceding-sibling' "); break;
- case AXIS_SELF:
- fprintf(output, " 'self' "); break;
- }
- switch (test) {
- case NODE_TEST_NONE:
- fprintf(output, "'none' "); break;
- case NODE_TEST_TYPE:
- fprintf(output, "'type' "); break;
- case NODE_TEST_PI:
- fprintf(output, "'PI' "); break;
- case NODE_TEST_ALL:
- fprintf(output, "'all' "); break;
- case NODE_TEST_NS:
- fprintf(output, "'namespace' "); break;
- case NODE_TEST_NAME:
- fprintf(output, "'name' "); break;
- }
- switch (type) {
- case NODE_TYPE_NODE:
- fprintf(output, "'node' "); break;
- case NODE_TYPE_COMMENT:
- fprintf(output, "'comment' "); break;
- case NODE_TYPE_TEXT:
- fprintf(output, "'text' "); break;
- case NODE_TYPE_PI:
- fprintf(output, "'PI' "); break;
- }
- if (prefix != NULL)
- fprintf(output, "%s:", prefix);
- if (name != NULL)
- fprintf(output, "%s", name);
- break;
-
- }
- case XPATH_OP_VALUE: {
- xmlXPathObjectPtr object = (xmlXPathObjectPtr) op->value4;
-
- fprintf(output, "ELEM ");
- xmlXPathDebugDumpObject(output, object, 0);
- goto finish;
- }
- case XPATH_OP_VARIABLE: {
- const xmlChar *prefix = op->value5;
- const xmlChar *name = op->value4;
-
- if (prefix != NULL)
- fprintf(output, "VARIABLE %s:%s", prefix, name);
- else
- fprintf(output, "VARIABLE %s", name);
- break;
- }
- case XPATH_OP_FUNCTION: {
- int nbargs = op->value;
- const xmlChar *prefix = op->value5;
- const xmlChar *name = op->value4;
-
- if (prefix != NULL)
- fprintf(output, "FUNCTION %s:%s(%d args)",
- prefix, name, nbargs);
- else
- fprintf(output, "FUNCTION %s(%d args)", name, nbargs);
- break;
- }
- case XPATH_OP_ARG: fprintf(output, "ARG"); break;
- case XPATH_OP_PREDICATE: fprintf(output, "PREDICATE"); break;
- case XPATH_OP_FILTER: fprintf(output, "FILTER"); break;
-#ifdef LIBXML_XPTR_ENABLED
- case XPATH_OP_RANGETO: fprintf(output, "RANGETO"); break;
-#endif
- default:
- fprintf(output, "UNKNOWN %d\n", op->op); return;
- }
- fprintf(output, "\n");
-finish:
- if (op->ch1 >= 0)
- xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch1], depth + 1);
- if (op->ch2 >= 0)
- xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch2], depth + 1);
-}
-
-/**
- * xmlXPathDebugDumpCompExpr:
- * @output: the FILE * for the output
- * @comp: the precompiled XPath expression
- * @depth: the indentation level.
- *
- * Dumps the tree of the compiled XPath expression.
- */
-void
-xmlXPathDebugDumpCompExpr(FILE *output, xmlXPathCompExprPtr comp,
- int depth) {
- int i;
- char shift[100];
-
- for (i = 0;((i < depth) && (i < 25));i++)
- shift[2 * i] = shift[2 * i + 1] = ' ';
- shift[2 * i] = shift[2 * i + 1] = 0;
-
- fprintf(output, shift);
-
- if (comp == NULL) {
- fprintf(output, "Compiled Expression is NULL\n");
- return;
- }
- fprintf(output, "Compiled Expression : %d elements\n",
- comp->nbStep);
- i = comp->last;
- xmlXPathDebugDumpStepOp(output, comp, &comp->steps[i], depth + 1);
-}
-#endif /* LIBXML_DEBUG_ENABLED */
-
-/************************************************************************
- * *
- * Parser stacks related functions and macros *
- * *
- ************************************************************************/
-
-/**
- * valuePop:
- * @ctxt: an XPath evaluation context
- *
- * Pops the top XPath object from the value stack
- *
- * Returns the XPath object just removed
- */
-extern xmlXPathObjectPtr
-valuePop(xmlXPathParserContextPtr ctxt)
-{
- xmlXPathObjectPtr ret;
-
- if (ctxt->valueNr <= 0)
- return (0);
- ctxt->valueNr--;
- if (ctxt->valueNr > 0)
- ctxt->value = ctxt->valueTab[ctxt->valueNr - 1];
- else
- ctxt->value = NULL;
- ret = ctxt->valueTab[ctxt->valueNr];
- ctxt->valueTab[ctxt->valueNr] = 0;
- return (ret);
-}
-/**
- * valuePush:
- * @ctxt: an XPath evaluation context
- * @value: the XPath object
- *
- * Pushes a new XPath object on top of the value stack
- *
- * returns the number of items on the value stack
- */
-extern int
-valuePush(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr value)
-{
- if (ctxt->valueNr >= ctxt->valueMax) {
- ctxt->valueMax *= 2;
- ctxt->valueTab =
- (xmlXPathObjectPtr *) xmlRealloc(ctxt->valueTab,
- ctxt->valueMax *
- sizeof(ctxt->valueTab[0]));
- if (ctxt->valueTab == NULL) {
- xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
- return (0);
- }
- }
- ctxt->valueTab[ctxt->valueNr] = value;
- ctxt->value = value;
- return (ctxt->valueNr++);
-}
-
-/**
- * xmlXPathPopBoolean:
- * @ctxt: an XPath parser context
- *
- * Pops a boolean from the stack, handling conversion if needed.
- * Check error with #xmlXPathCheckError.
- *
- * Returns the boolean
- */
-int
-xmlXPathPopBoolean (xmlXPathParserContextPtr ctxt) {
- xmlXPathObjectPtr obj;
- int ret;
-
- obj = valuePop(ctxt);
- if (obj == NULL) {
- xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
- return(0);
- }
- ret = xmlXPathCastToBoolean(obj);
- xmlXPathFreeObject(obj);
- return(ret);
-}
-
-/**
- * xmlXPathPopNumber:
- * @ctxt: an XPath parser context
- *
- * Pops a number from the stack, handling conversion if needed.
- * Check error with #xmlXPathCheckError.
- *
- * Returns the number
- */
-double
-xmlXPathPopNumber (xmlXPathParserContextPtr ctxt) {
- xmlXPathObjectPtr obj;
- double ret;
-
- obj = valuePop(ctxt);
- if (obj == NULL) {
- xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
- return(0);
- }
- ret = xmlXPathCastToNumber(obj);
- xmlXPathFreeObject(obj);
- return(ret);
-}
-
-/**
- * xmlXPathPopString:
- * @ctxt: an XPath parser context
- *
- * Pops a string from the stack, handling conversion if needed.
- * Check error with #xmlXPathCheckError.
- *
- * Returns the string
- */
-xmlChar *
-xmlXPathPopString (xmlXPathParserContextPtr ctxt) {
- xmlXPathObjectPtr obj;
- xmlChar * ret;
-
- obj = valuePop(ctxt);
- if (obj == NULL) {
- xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
- return(NULL);
- }
- ret = xmlXPathCastToString(obj);
- /* TODO: needs refactoring somewhere else */
- if (obj->stringval == ret)
- obj->stringval = NULL;
- xmlXPathFreeObject(obj);
- return(ret);
-}
-
-/**
- * xmlXPathPopNodeSet:
- * @ctxt: an XPath parser context
- *
- * Pops a node-set from the stack, handling conversion if needed.
- * Check error with #xmlXPathCheckError.
- *
- * Returns the node-set
- */
-xmlNodeSetPtr
-xmlXPathPopNodeSet (xmlXPathParserContextPtr ctxt) {
- xmlXPathObjectPtr obj;
- xmlNodeSetPtr ret;
-
- if (ctxt->value == NULL) {
- xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
- return(NULL);
- }
- if (!xmlXPathStackIsNodeSet(ctxt)) {
- xmlXPathSetTypeError(ctxt);
- return(NULL);
- }
- obj = valuePop(ctxt);
- ret = obj->nodesetval;
- xmlXPathFreeNodeSetList(obj);
- return(ret);
-}
-
-/**
- * xmlXPathPopExternal:
- * @ctxt: an XPath parser context
- *
- * Pops an external object from the stack, handling conversion if needed.
- * Check error with #xmlXPathCheckError.
- *
- * Returns the object
- */
-void *
-xmlXPathPopExternal (xmlXPathParserContextPtr ctxt) {
- xmlXPathObjectPtr obj;
- void * ret;
-
- if (ctxt->value == NULL) {
- xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
- return(NULL);
- }
- if (ctxt->value->type != XPATH_USERS) {
- xmlXPathSetTypeError(ctxt);
- return(NULL);
- }
- obj = valuePop(ctxt);
- ret = obj->user;
- xmlXPathFreeObject(obj);
- return(ret);
-}
-
-/*
- * Macros for accessing the content. Those should be used only by the parser,
- * and not exported.
- *
- * Dirty macros, i.e. one need to make assumption on the context to use them
- *
- * CUR_PTR return the current pointer to the xmlChar to be parsed.
- * CUR returns the current xmlChar value, i.e. a 8 bit value
- * in ISO-Latin or UTF-8.
- * This should be used internally by the parser
- * only to compare to ASCII values otherwise it would break when
- * running with UTF-8 encoding.
- * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only
- * to compare on ASCII based substring.
- * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
- * strings within the parser.
- * CURRENT Returns the current char value, with the full decoding of
- * UTF-8 if we are using this mode. It returns an int.
- * NEXT Skip to the next character, this does the proper decoding
- * in UTF-8 mode. It also pop-up unfinished entities on the fly.
- * It returns the pointer to the current xmlChar.
- */
-
-#define CUR (*ctxt->cur)
-#define SKIP(val) ctxt->cur += (val)
-#define NXT(val) ctxt->cur[(val)]
-#define CUR_PTR ctxt->cur
-#define CUR_CHAR(l) xmlXPathCurrentChar(ctxt, &l)
-
-#define COPY_BUF(l,b,i,v) \
- if (l == 1) b[i++] = (xmlChar) v; \
- else i += xmlCopyChar(l,&b[i],v)
-
-#define NEXTL(l) ctxt->cur += l
-
-#define SKIP_BLANKS \
- while (IS_BLANK(*(ctxt->cur))) NEXT
-
-#define CURRENT (*ctxt->cur)
-#define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur)
-
-
-#ifndef DBL_DIG
-#define DBL_DIG 16
-#endif
-#ifndef DBL_EPSILON
-#define DBL_EPSILON 1E-9
-#endif
-
-#define UPPER_DOUBLE 1E9
-#define LOWER_DOUBLE 1E-5
-
-#define INTEGER_DIGITS DBL_DIG
-#define FRACTION_DIGITS (DBL_DIG + 1)
-#define EXPONENT_DIGITS (3 + 2)
-
-/**
- * xmlXPathFormatNumber:
- * @number: number to format
- * @buffer: output buffer
- * @buffersize: size of output buffer
- *
- * Convert the number into a string representation.
- */
-static void
-xmlXPathFormatNumber(double number, char buffer[], int buffersize)
-{
- switch (xmlXPathIsInf(number)) {
- case 1:
- if (buffersize > (int)sizeof("Infinity"))
- snprintf(buffer, buffersize, "Infinity");
- break;
- case -1:
- if (buffersize > (int)sizeof("-Infinity"))
- snprintf(buffer, buffersize, "-Infinity");
- break;
- default:
- if (xmlXPathIsNaN(number)) {
- if (buffersize > (int)sizeof("NaN"))
- snprintf(buffer, buffersize, "NaN");
- } else if (number == 0 && xmlXPathGetSign(number) != 0) {
- snprintf(buffer, buffersize, "0");
- } else if (number == ((int) number)) {
- char work[30];
- char *ptr, *cur;
- int res, value = (int) number;
-
- ptr = &buffer[0];
- if (value < 0) {
- *ptr++ = '-';
- value = -value;
- }
- if (value == 0) {
- *ptr++ = '0';
- } else {
- cur = &work[0];
- while (value != 0) {
- res = value % 10;
- value = value / 10;
- *cur++ = '0' + res;
- }
- cur--;
- while ((cur >= &work[0]) && (ptr - buffer < buffersize)) {
- *ptr++ = *cur--;
- }
- }
- if (ptr - buffer < buffersize) {
- *ptr = 0;
- } else if (buffersize > 0) {
- ptr--;
- *ptr = 0;
- }
- } else {
- /* 3 is sign, decimal point, and terminating zero */
- char work[DBL_DIG + EXPONENT_DIGITS + 3];
- int integer_place, fraction_place;
- char *ptr;
- char *after_fraction;
- double absolute_value;
- int size;
-
- absolute_value = fabs(number);
-
- /*
- * First choose format - scientific or regular floating point.
- * In either case, result is in work, and after_fraction points
- * just past the fractional part.
- */
- if ( ((absolute_value > UPPER_DOUBLE) ||
- (absolute_value < LOWER_DOUBLE)) &&
- (absolute_value != 0.0) ) {
- /* Use scientific notation */
- integer_place = DBL_DIG + EXPONENT_DIGITS + 1;
- fraction_place = DBL_DIG - 1;
- snprintf(work, sizeof(work),"%*.*e",
- integer_place, fraction_place, number);
- after_fraction = strchr(work + DBL_DIG, 'e');
- }
- else {
- /* Use regular notation */
- if (absolute_value > 0.0)
- integer_place = 1 + (int)log10(absolute_value);
- else
- integer_place = 0;
- fraction_place = (integer_place > 0)
- ? DBL_DIG - integer_place
- : DBL_DIG;
- size = snprintf(work, sizeof(work), "%0.*f",
- fraction_place, number);
- after_fraction = work + size;
- }
-
- /* Remove fractional trailing zeroes */
- ptr = after_fraction;
- while (*(--ptr) == '0')
- ;
- if (*ptr != '.')
- ptr++;
- strcpy(ptr, after_fraction);
-
- /* Finally copy result back to caller */
- size = strlen(work) + 1;
- if (size > buffersize) {
- work[buffersize - 1] = 0;
- size = buffersize;
- }
- memcpy(buffer, work, size);
- }
- break;
- }
-}
-
-/************************************************************************
- * *
- * Error handling routines *
- * *
- ************************************************************************/
-
-
-static const char *xmlXPathErrorMessages[] = {
- "Ok",
- "Number encoding",
- "Unfinished literal",
- "Start of literal",
- "Expected $ for variable reference",
- "Undefined variable",
- "Invalid predicate",
- "Invalid expression",
- "Missing closing curly brace",
- "Unregistered function",
- "Invalid operand",
- "Invalid type",
- "Invalid number of arguments",
- "Invalid context size",
- "Invalid context position",
- "Memory allocation error",
- "Syntax error",
- "Resource error",
- "Sub resource error",
- "Undefined namespace prefix",
- "Encoding error",
- "Char out of XML range"
-};
-
-/**
- * xmlXPatherror:
- * @ctxt: the XPath Parser context
- * @file: the file name
- * @line: the line number
- * @no: the error number
- *
- * Formats an error message.
- */
-void
-xmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file ATTRIBUTE_UNUSED,
- int line ATTRIBUTE_UNUSED, int no) {
- int n;
- const xmlChar *cur;
- const xmlChar *base;
-
- cur = ctxt->cur;
- base = ctxt->base;
- if ((cur == NULL) || (base == NULL)) {
- if ((ctxt->comp != NULL) && (ctxt->comp->expr != NULL)) {
- xmlGenericError(xmlGenericErrorContext,
- "XPath error %s in %s\n", xmlXPathErrorMessages[no],
- ctxt->comp->expr);
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "XPath error %s\n", xmlXPathErrorMessages[no]);
- }
-
- return;
- }
- xmlGenericError(xmlGenericErrorContext,
- "XPath error %s\n", xmlXPathErrorMessages[no]);
-
- while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
- cur--;
- }
- n = 0;
- while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
- cur--;
- if ((*cur == '\n') || (*cur == '\r')) cur++;
- base = cur;
- n = 0;
- while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
- xmlGenericError(xmlGenericErrorContext, "%c", (unsigned char) *cur++);
- n++;
- }
- xmlGenericError(xmlGenericErrorContext, "\n");
- cur = ctxt->cur;
- while ((*cur == '\n') || (*cur == '\r'))
- cur--;
- n = 0;
- while ((cur != base) && (n++ < 80)) {
- xmlGenericError(xmlGenericErrorContext, " ");
- base++;
- }
- xmlGenericError(xmlGenericErrorContext,"^\n");
-}
-
-
-/************************************************************************
- * *
- * Routines to handle NodeSets *
- * *
- ************************************************************************/
-
-/**
- * xmlXPathCmpNodes:
- * @node1: the first node
- * @node2: the second node
- *
- * Compare two nodes w.r.t document order
- *
- * Returns -2 in case of error 1 if first point < second point, 0 if
- * that's the same node, -1 otherwise
- */
-int
-xmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) {
- int depth1, depth2;
- xmlNodePtr cur, root;
-
- if ((node1 == NULL) || (node2 == NULL))
- return(-2);
- /*
- * a couple of optimizations which will avoid computations in most cases
- */
- if (node1 == node2)
- return(0);
- if ((node1->type == XML_NAMESPACE_DECL) ||
- (node2->type == XML_NAMESPACE_DECL))
- return(1);
- if (node1 == node2->prev)
- return(1);
- if (node1 == node2->next)
- return(-1);
-
-#if 0
- Unfortunately this does not work. Line number in entities reset
- to 1 within the entity :-(
-
- /*
- * Speedup using line numbers if availble.
- */
- if ((node1->type == XML_ELEMENT_NODE) &&
- (node2->type == XML_ELEMENT_NODE) &&
- (0 != (int) node1->content) && (0 != (int) node2->content)) {
- int l1, l2;
- l1 = (int) node1->content;
- l2 = (int) node2->content;
- if (l1 < l2)
- return(1);
- if (l1 > l2)
- return(-1);
- }
-#endif
- /*
- * compute depth to root
- */
- for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) {
- if (cur == node1)
- return(1);
- depth2++;
- }
- root = cur;
- for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) {
- if (cur == node2)
- return(-1);
- depth1++;
- }
- /*
- * Distinct document (or distinct entities :-( ) case.
- */
- if (root != cur) {
- return(-2);
- }
- /*
- * get the nearest common ancestor.
- */
- while (depth1 > depth2) {
- depth1--;
- node1 = node1->parent;
- }
- while (depth2 > depth1) {
- depth2--;
- node2 = node2->parent;
- }
- while (node1->parent != node2->parent) {
- node1 = node1->parent;
- node2 = node2->parent;
- /* should not happen but just in case ... */
- if ((node1 == NULL) || (node2 == NULL))
- return(-2);
- }
- /*
- * Find who's first.
- */
- if (node1 == node2->next)
- return(-1);
- for (cur = node1->next;cur != NULL;cur = cur->next)
- if (cur == node2)
- return(1);
- return(-1); /* assume there is no sibling list corruption */
-}
-
-/**
- * xmlXPathNodeSetSort:
- * @set: the node set
- *
- * Sort the node set in document order
- */
-void
-xmlXPathNodeSetSort(xmlNodeSetPtr set) {
- int i, j, incr, len;
- xmlNodePtr tmp;
-
- if (set == NULL)
- return;
-
- /* Use Shell's sort to sort the node-set */
- len = set->nodeNr;
- for (incr = len / 2; incr > 0; incr /= 2) {
- for (i = incr; i < len; i++) {
- j = i - incr;
- while (j >= 0) {
- if (xmlXPathCmpNodes(set->nodeTab[j],
- set->nodeTab[j + incr]) == -1) {
- tmp = set->nodeTab[j];
- set->nodeTab[j] = set->nodeTab[j + incr];
- set->nodeTab[j + incr] = tmp;
- j -= incr;
- } else
- break;
- }
- }
- }
-}
-
-#define XML_NODESET_DEFAULT 10
-/**
- * xmlXPathNodeSetDupNs:
- * @node: the parent node of the namespace XPath node
- * @ns: the libxml namespace declaration node.
- *
- * Namespace node in libxml don't match the XPath semantic. In a node set
- * the namespace nodes are duplicated and the next pointer is set to the
- * parent node in the XPath semantic.
- *
- * Returns the newly created object.
- */
-static xmlNodePtr
-xmlXPathNodeSetDupNs(xmlNodePtr node, xmlNsPtr ns) {
- xmlNsPtr cur;
-
- if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL))
- return(NULL);
- if ((node == NULL) || (node->type == XML_NAMESPACE_DECL))
- return((xmlNodePtr) ns);
-
- /*
- * Allocate a new Namespace and fill the fields.
- */
- cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
- if (cur == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNodeSetDupNs : malloc failed\n");
- return(NULL);
- }
- memset(cur, 0, sizeof(xmlNs));
- cur->type = XML_NAMESPACE_DECL;
- if (ns->href != NULL)
- cur->href = xmlStrdup(ns->href);
- if (ns->prefix != NULL)
- cur->prefix = xmlStrdup(ns->prefix);
- cur->next = (xmlNsPtr) node;
- return((xmlNodePtr) cur);
-}
-
-/**
- * xmlXPathNodeSetFreeNs:
- * @ns: the XPath namespace node found in a nodeset.
- *
- * Namespace node in libxml don't match the XPath semantic. In a node set
- * the namespace nodes are duplicated and the next pointer is set to the
- * parent node in the XPath semantic. Check if such a node need to be freed
- */
-void
-xmlXPathNodeSetFreeNs(xmlNsPtr ns) {
- if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL))
- return;
-
- if ((ns->next != NULL) && (ns->next->type != XML_NAMESPACE_DECL)) {
- if (ns->href != NULL)
- xmlFree((xmlChar *)ns->href);
- if (ns->prefix != NULL)
- xmlFree((xmlChar *)ns->prefix);
- xmlFree(ns);
- }
-}
-
-/**
- * xmlXPathNodeSetCreate:
- * @val: an initial xmlNodePtr, or NULL
- *
- * Create a new xmlNodeSetPtr of type double and of value @val
- *
- * Returns the newly created object.
- */
-xmlNodeSetPtr
-xmlXPathNodeSetCreate(xmlNodePtr val) {
- xmlNodeSetPtr ret;
-
- ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNodeSetCreate: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlNodeSet));
- if (val != NULL) {
- ret->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
- sizeof(xmlNodePtr));
- if (ret->nodeTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNodeSetCreate: out of memory\n");
- return(NULL);
- }
- memset(ret->nodeTab, 0 ,
- XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
- ret->nodeMax = XML_NODESET_DEFAULT;
- if (val->type == XML_NAMESPACE_DECL) {
- xmlNsPtr ns = (xmlNsPtr) val;
-
- ret->nodeTab[ret->nodeNr++] =
- xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
- } else
- ret->nodeTab[ret->nodeNr++] = val;
- }
- return(ret);
-}
-
-/**
- * xmlXPathNodeSetContains:
- * @cur: the node-set
- * @val: the node
- *
- * checks whether @cur contains @val
- *
- * Returns true (1) if @cur contains @val, false (0) otherwise
- */
-int
-xmlXPathNodeSetContains (xmlNodeSetPtr cur, xmlNodePtr val) {
- int i;
-
- if (val->type == XML_NAMESPACE_DECL) {
- for (i = 0; i < cur->nodeNr; i++) {
- if (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) {
- xmlNsPtr ns1, ns2;
-
- ns1 = (xmlNsPtr) val;
- ns2 = (xmlNsPtr) cur->nodeTab[i];
- if (ns1 == ns2)
- return(1);
- if ((ns1->next != NULL) && (ns2->next == ns1->next) &&
- (xmlStrEqual(ns1->prefix, ns2->prefix)))
- return(1);
- }
- }
- } else {
- for (i = 0; i < cur->nodeNr; i++) {
- if (cur->nodeTab[i] == val)
- return(1);
- }
- }
- return(0);
-}
-
-/**
- * xmlXPathNodeSetAddNs:
- * @cur: the initial node set
- * @node: the hosting node
- * @ns: a the namespace node
- *
- * add a new namespace node to an existing NodeSet
- */
-void
-xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
- int i;
-
- if ((ns == NULL) || (node == NULL) || (ns->type != XML_NAMESPACE_DECL) ||
- (node->type != XML_ELEMENT_NODE))
- return;
-
- /* @@ with_ns to check wether namespace nodes should be looked at @@ */
- /*
- * check against doublons
- */
- for (i = 0;i < cur->nodeNr;i++) {
- if ((cur->nodeTab[i] != NULL) &&
- (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) &&
- (((xmlNsPtr)cur->nodeTab[i])->next == (xmlNsPtr) node) &&
- (xmlStrEqual(ns->prefix, ((xmlNsPtr)cur->nodeTab[i])->prefix)))
- return;
- }
-
- /*
- * grow the nodeTab if needed
- */
- if (cur->nodeMax == 0) {
- cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
- sizeof(xmlNodePtr));
- if (cur->nodeTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNodeSetAdd: out of memory\n");
- return;
- }
- memset(cur->nodeTab, 0 ,
- XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
- cur->nodeMax = XML_NODESET_DEFAULT;
- } else if (cur->nodeNr == cur->nodeMax) {
- xmlNodePtr *temp;
-
- cur->nodeMax *= 2;
- temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
- sizeof(xmlNodePtr));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNodeSetAdd: out of memory\n");
- return;
- }
- cur->nodeTab = temp;
- }
- cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns);
-}
-
-/**
- * xmlXPathNodeSetAdd:
- * @cur: the initial node set
- * @val: a new xmlNodePtr
- *
- * add a new xmlNodePtr to an existing NodeSet
- */
-void
-xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
- int i;
-
- if (val == NULL) return;
-
- /* @@ with_ns to check wether namespace nodes should be looked at @@ */
- /*
- * check against doublons
- */
- for (i = 0;i < cur->nodeNr;i++)
- if (cur->nodeTab[i] == val) return;
-
- /*
- * grow the nodeTab if needed
- */
- if (cur->nodeMax == 0) {
- cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
- sizeof(xmlNodePtr));
- if (cur->nodeTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNodeSetAdd: out of memory\n");
- return;
- }
- memset(cur->nodeTab, 0 ,
- XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
- cur->nodeMax = XML_NODESET_DEFAULT;
- } else if (cur->nodeNr == cur->nodeMax) {
- xmlNodePtr *temp;
-
- cur->nodeMax *= 2;
- temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
- sizeof(xmlNodePtr));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNodeSetAdd: out of memory\n");
- return;
- }
- cur->nodeTab = temp;
- }
- if (val->type == XML_NAMESPACE_DECL) {
- xmlNsPtr ns = (xmlNsPtr) val;
-
- cur->nodeTab[cur->nodeNr++] =
- xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
- } else
- cur->nodeTab[cur->nodeNr++] = val;
-}
-
-/**
- * xmlXPathNodeSetAddUnique:
- * @cur: the initial node set
- * @val: a new xmlNodePtr
- *
- * add a new xmlNodePtr to an existing NodeSet, optimized version
- * when we are sure the node is not already in the set.
- */
-void
-xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
- if (val == NULL) return;
-
- /* @@ with_ns to check wether namespace nodes should be looked at @@ */
- /*
- * grow the nodeTab if needed
- */
- if (cur->nodeMax == 0) {
- cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
- sizeof(xmlNodePtr));
- if (cur->nodeTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNodeSetAddUnique: out of memory\n");
- return;
- }
- memset(cur->nodeTab, 0 ,
- XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
- cur->nodeMax = XML_NODESET_DEFAULT;
- } else if (cur->nodeNr == cur->nodeMax) {
- xmlNodePtr *temp;
-
- cur->nodeMax *= 2;
- temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
- sizeof(xmlNodePtr));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNodeSetAddUnique: out of memory\n");
- return;
- }
- cur->nodeTab = temp;
- }
- if (val->type == XML_NAMESPACE_DECL) {
- xmlNsPtr ns = (xmlNsPtr) val;
-
- cur->nodeTab[cur->nodeNr++] =
- xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
- } else
- cur->nodeTab[cur->nodeNr++] = val;
-}
-
-/**
- * xmlXPathNodeSetMerge:
- * @val1: the first NodeSet or NULL
- * @val2: the second NodeSet
- *
- * Merges two nodesets, all nodes from @val2 are added to @val1
- * if @val1 is NULL, a new set is created and copied from @val2
- *
- * Returns @val1 once extended or NULL in case of error.
- */
-xmlNodeSetPtr
-xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
- int i, j, initNr, skip;
-
- if (val2 == NULL) return(val1);
- if (val1 == NULL) {
- val1 = xmlXPathNodeSetCreate(NULL);
- }
-
- /* @@ with_ns to check wether namespace nodes should be looked at @@ */
- initNr = val1->nodeNr;
-
- for (i = 0;i < val2->nodeNr;i++) {
- /*
- * check against doublons
- */
- skip = 0;
- for (j = 0; j < initNr; j++) {
- if (val1->nodeTab[j] == val2->nodeTab[i]) {
- skip = 1;
- break;
- } else if ((val1->nodeTab[j]->type == XML_NAMESPACE_DECL) &&
- (val2->nodeTab[i]->type == XML_NAMESPACE_DECL)) {
- xmlNsPtr ns1, ns2;
- ns1 = (xmlNsPtr) val1->nodeTab[j];
- ns2 = (xmlNsPtr) val2->nodeTab[i];
- if ((ns1->next == ns2->next) &&
- (xmlStrEqual(ns1->prefix, ns2->prefix))) {
- skip = 1;
- break;
- }
- }
- }
- if (skip)
- continue;
-
- /*
- * grow the nodeTab if needed
- */
- if (val1->nodeMax == 0) {
- val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
- sizeof(xmlNodePtr));
- if (val1->nodeTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNodeSetMerge: out of memory\n");
- return(NULL);
- }
- memset(val1->nodeTab, 0 ,
- XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
- val1->nodeMax = XML_NODESET_DEFAULT;
- } else if (val1->nodeNr == val1->nodeMax) {
- xmlNodePtr *temp;
-
- val1->nodeMax *= 2;
- temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
- sizeof(xmlNodePtr));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNodeSetMerge: out of memory\n");
- return(NULL);
- }
- val1->nodeTab = temp;
- }
- if (val2->nodeTab[i]->type == XML_NAMESPACE_DECL) {
- xmlNsPtr ns = (xmlNsPtr) val2->nodeTab[i];
-
- val1->nodeTab[val1->nodeNr++] =
- xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
- } else
- val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i];
- }
-
- return(val1);
-}
-
-/**
- * xmlXPathNodeSetMergeUnique:
- * @val1: the first NodeSet or NULL
- * @val2: the second NodeSet
- *
- * Merges two nodesets, all nodes from @val2 are added to @val1
- * if @val1 is NULL, a new set is created and copied from @val2
- *
- * Returns @val1 once extended or NULL in case of error.
- */
-static xmlNodeSetPtr
-xmlXPathNodeSetMergeUnique(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
- int i, initNr;
-
- if (val2 == NULL) return(val1);
- if (val1 == NULL) {
- val1 = xmlXPathNodeSetCreate(NULL);
- }
-
- /* @@ with_ns to check wether namespace nodes should be looked at @@ */
- initNr = val1->nodeNr;
-
- for (i = 0;i < val2->nodeNr;i++) {
- /*
- * grow the nodeTab if needed
- */
- if (val1->nodeMax == 0) {
- val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
- sizeof(xmlNodePtr));
- if (val1->nodeTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNodeSetMerge: out of memory\n");
- return(NULL);
- }
- memset(val1->nodeTab, 0 ,
- XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
- val1->nodeMax = XML_NODESET_DEFAULT;
- } else if (val1->nodeNr == val1->nodeMax) {
- xmlNodePtr *temp;
-
- val1->nodeMax *= 2;
- temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
- sizeof(xmlNodePtr));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNodeSetMerge: out of memory\n");
- return(NULL);
- }
- val1->nodeTab = temp;
- }
- if (val2->nodeTab[i]->type == XML_NAMESPACE_DECL) {
- xmlNsPtr ns = (xmlNsPtr) val2->nodeTab[i];
-
- val1->nodeTab[val1->nodeNr++] =
- xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
- } else
- val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i];
- }
-
- return(val1);
-}
-
-/**
- * xmlXPathNodeSetDel:
- * @cur: the initial node set
- * @val: an xmlNodePtr
- *
- * Removes an xmlNodePtr from an existing NodeSet
- */
-void
-xmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val) {
- int i;
-
- if (cur == NULL) return;
- if (val == NULL) return;
-
- /*
- * check against doublons
- */
- for (i = 0;i < cur->nodeNr;i++)
- if (cur->nodeTab[i] == val) break;
-
- if (i >= cur->nodeNr) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n",
- val->name);
-#endif
- return;
- }
- if ((cur->nodeTab[i] != NULL) &&
- (cur->nodeTab[i]->type == XML_NAMESPACE_DECL))
- xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[i]);
- cur->nodeNr--;
- for (;i < cur->nodeNr;i++)
- cur->nodeTab[i] = cur->nodeTab[i + 1];
- cur->nodeTab[cur->nodeNr] = NULL;
-}
-
-/**
- * xmlXPathNodeSetRemove:
- * @cur: the initial node set
- * @val: the index to remove
- *
- * Removes an entry from an existing NodeSet list.
- */
-void
-xmlXPathNodeSetRemove(xmlNodeSetPtr cur, int val) {
- if (cur == NULL) return;
- if (val >= cur->nodeNr) return;
- if ((cur->nodeTab[val] != NULL) &&
- (cur->nodeTab[val]->type == XML_NAMESPACE_DECL))
- xmlXPathNodeSetFreeNs((xmlNsPtr) cur->nodeTab[val]);
- cur->nodeNr--;
- for (;val < cur->nodeNr;val++)
- cur->nodeTab[val] = cur->nodeTab[val + 1];
- cur->nodeTab[cur->nodeNr] = NULL;
-}
-
-/**
- * xmlXPathFreeNodeSet:
- * @obj: the xmlNodeSetPtr to free
- *
- * Free the NodeSet compound (not the actual nodes !).
- */
-void
-xmlXPathFreeNodeSet(xmlNodeSetPtr obj) {
- if (obj == NULL) return;
- if (obj->nodeTab != NULL) {
- int i;
-
- /* @@ with_ns to check wether namespace nodes should be looked at @@ */
- for (i = 0;i < obj->nodeNr;i++)
- if ((obj->nodeTab[i] != NULL) &&
- (obj->nodeTab[i]->type == XML_NAMESPACE_DECL))
- xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]);
- xmlFree(obj->nodeTab);
- }
- xmlFree(obj);
-}
-
-/**
- * xmlXPathFreeValueTree:
- * @obj: the xmlNodeSetPtr to free
- *
- * Free the NodeSet compound and the actual tree, this is different
- * from xmlXPathFreeNodeSet()
- */
-static void
-xmlXPathFreeValueTree(xmlNodeSetPtr obj) {
- int i;
-
- if (obj == NULL) return;
-
- if (obj->nodeTab != NULL) {
- for (i = 0;i < obj->nodeNr;i++) {
- if (obj->nodeTab[i] != NULL) {
- if (obj->nodeTab[i]->type == XML_NAMESPACE_DECL) {
- xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]);
- } else {
- xmlFreeNodeList(obj->nodeTab[i]);
- }
- }
- }
- xmlFree(obj->nodeTab);
- }
- xmlFree(obj);
-}
-
-#if defined(DEBUG) || defined(DEBUG_STEP)
-/**
- * xmlGenericErrorContextNodeSet:
- * @output: a FILE * for the output
- * @obj: the xmlNodeSetPtr to free
- *
- * Quick display of a NodeSet
- */
-void
-xmlGenericErrorContextNodeSet(FILE *output, xmlNodeSetPtr obj) {
- int i;
-
- if (output == NULL) output = xmlGenericErrorContext;
- if (obj == NULL) {
- fprintf(output, "NodeSet == NULL !\n");
- return;
- }
- if (obj->nodeNr == 0) {
- fprintf(output, "NodeSet is empty\n");
- return;
- }
- if (obj->nodeTab == NULL) {
- fprintf(output, " nodeTab == NULL !\n");
- return;
- }
- for (i = 0; i < obj->nodeNr; i++) {
- if (obj->nodeTab[i] == NULL) {
- fprintf(output, " NULL !\n");
- return;
- }
- if ((obj->nodeTab[i]->type == XML_DOCUMENT_NODE) ||
- (obj->nodeTab[i]->type == XML_HTML_DOCUMENT_NODE))
- fprintf(output, " /");
- else if (obj->nodeTab[i]->name == NULL)
- fprintf(output, " noname!");
- else fprintf(output, " %s", obj->nodeTab[i]->name);
- }
- fprintf(output, "\n");
-}
-#endif
-
-/**
- * xmlXPathNewNodeSet:
- * @val: the NodePtr value
- *
- * Create a new xmlXPathObjectPtr of type NodeSet and initialize
- * it with the single Node @val
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPathNewNodeSet(xmlNodePtr val) {
- xmlXPathObjectPtr ret;
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNewNodeSet: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_NODESET;
- ret->boolval = 0;
- ret->nodesetval = xmlXPathNodeSetCreate(val);
- /* @@ with_ns to check wether namespace nodes should be looked at @@ */
- return(ret);
-}
-
-/**
- * xmlXPathNewValueTree:
- * @val: the NodePtr value
- *
- * Create a new xmlXPathObjectPtr of type Value Tree (XSLT) and initialize
- * it with the tree root @val
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPathNewValueTree(xmlNodePtr val) {
- xmlXPathObjectPtr ret;
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNewNodeSet: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_XSLT_TREE;
- ret->boolval = 1;
- ret->user = (void *) val;
- ret->nodesetval = xmlXPathNodeSetCreate(val);
- return(ret);
-}
-
-/**
- * xmlXPathNewNodeSetList:
- * @val: an existing NodeSet
- *
- * Create a new xmlXPathObjectPtr of type NodeSet and initialize
- * it with the Nodeset @val
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPathNewNodeSetList(xmlNodeSetPtr val)
-{
- xmlXPathObjectPtr ret;
- int i;
-
- if (val == NULL)
- ret = NULL;
- else if (val->nodeTab == NULL)
- ret = xmlXPathNewNodeSet(NULL);
- else {
- ret = xmlXPathNewNodeSet(val->nodeTab[0]);
- for (i = 1; i < val->nodeNr; ++i)
- xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]);
- }
-
- return (ret);
-}
-
-/**
- * xmlXPathWrapNodeSet:
- * @val: the NodePtr value
- *
- * Wrap the Nodeset @val in a new xmlXPathObjectPtr
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPathWrapNodeSet(xmlNodeSetPtr val) {
- xmlXPathObjectPtr ret;
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathWrapNodeSet: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_NODESET;
- ret->nodesetval = val;
- return(ret);
-}
-
-/**
- * xmlXPathFreeNodeSetList:
- * @obj: an existing NodeSetList object
- *
- * Free up the xmlXPathObjectPtr @obj but don't deallocate the objects in
- * the list contrary to xmlXPathFreeObject().
- */
-void
-xmlXPathFreeNodeSetList(xmlXPathObjectPtr obj) {
- if (obj == NULL) return;
- xmlFree(obj);
-}
-
-/**
- * xmlXPathDifference:
- * @nodes1: a node-set
- * @nodes2: a node-set
- *
- * Implements the EXSLT - Sets difference() function:
- * node-set set:difference (node-set, node-set)
- *
- * Returns the difference between the two node sets, or nodes1 if
- * nodes2 is empty
- */
-xmlNodeSetPtr
-xmlXPathDifference (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
- xmlNodeSetPtr ret;
- int i, l1;
- xmlNodePtr cur;
-
- if (xmlXPathNodeSetIsEmpty(nodes2))
- return(nodes1);
-
- ret = xmlXPathNodeSetCreate(NULL);
- if (xmlXPathNodeSetIsEmpty(nodes1))
- return(ret);
-
- l1 = xmlXPathNodeSetGetLength(nodes1);
-
- for (i = 0; i < l1; i++) {
- cur = xmlXPathNodeSetItem(nodes1, i);
- if (!xmlXPathNodeSetContains(nodes2, cur))
- xmlXPathNodeSetAddUnique(ret, cur);
- }
- return(ret);
-}
-
-/**
- * xmlXPathIntersection:
- * @nodes1: a node-set
- * @nodes2: a node-set
- *
- * Implements the EXSLT - Sets intersection() function:
- * node-set set:intersection (node-set, node-set)
- *
- * Returns a node set comprising the nodes that are within both the
- * node sets passed as arguments
- */
-xmlNodeSetPtr
-xmlXPathIntersection (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
- xmlNodeSetPtr ret = xmlXPathNodeSetCreate(NULL);
- int i, l1;
- xmlNodePtr cur;
-
- if (xmlXPathNodeSetIsEmpty(nodes1))
- return(ret);
- if (xmlXPathNodeSetIsEmpty(nodes2))
- return(ret);
-
- l1 = xmlXPathNodeSetGetLength(nodes1);
-
- for (i = 0; i < l1; i++) {
- cur = xmlXPathNodeSetItem(nodes1, i);
- if (xmlXPathNodeSetContains(nodes2, cur))
- xmlXPathNodeSetAddUnique(ret, cur);
- }
- return(ret);
-}
-
-/**
- * xmlXPathDistinctSorted:
- * @nodes: a node-set, sorted by document order
- *
- * Implements the EXSLT - Sets distinct() function:
- * node-set set:distinct (node-set)
- *
- * Returns a subset of the nodes contained in @nodes, or @nodes if
- * it is empty
- */
-xmlNodeSetPtr
-xmlXPathDistinctSorted (xmlNodeSetPtr nodes) {
- xmlNodeSetPtr ret;
- xmlHashTablePtr hash;
- int i, l;
- xmlChar * strval;
- xmlNodePtr cur;
-
- if (xmlXPathNodeSetIsEmpty(nodes))
- return(nodes);
-
- ret = xmlXPathNodeSetCreate(NULL);
- l = xmlXPathNodeSetGetLength(nodes);
- hash = xmlHashCreate (l);
- for (i = 0; i < l; i++) {
- cur = xmlXPathNodeSetItem(nodes, i);
- strval = xmlXPathCastNodeToString(cur);
- if (xmlHashLookup(hash, strval) == NULL) {
- xmlHashAddEntry(hash, strval, strval);
- xmlXPathNodeSetAddUnique(ret, cur);
- } else {
- xmlFree(strval);
- }
- }
- xmlHashFree(hash, (xmlHashDeallocator) xmlFree);
- return(ret);
-}
-
-/**
- * xmlXPathDistinct:
- * @nodes: a node-set
- *
- * Implements the EXSLT - Sets distinct() function:
- * node-set set:distinct (node-set)
- * @nodes is sorted by document order, then #exslSetsDistinctSorted
- * is called with the sorted node-set
- *
- * Returns a subset of the nodes contained in @nodes, or @nodes if
- * it is empty
- */
-xmlNodeSetPtr
-xmlXPathDistinct (xmlNodeSetPtr nodes) {
- if (xmlXPathNodeSetIsEmpty(nodes))
- return(nodes);
-
- xmlXPathNodeSetSort(nodes);
- return(xmlXPathDistinctSorted(nodes));
-}
-
-/**
- * xmlXPathHasSameNodes:
- * @nodes1: a node-set
- * @nodes2: a node-set
- *
- * Implements the EXSLT - Sets has-same-nodes function:
- * boolean set:has-same-node(node-set, node-set)
- *
- * Returns true (1) if @nodes1 shares any node with @nodes2, false (0)
- * otherwise
- */
-int
-xmlXPathHasSameNodes (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
- int i, l;
- xmlNodePtr cur;
-
- if (xmlXPathNodeSetIsEmpty(nodes1) ||
- xmlXPathNodeSetIsEmpty(nodes2))
- return(0);
-
- l = xmlXPathNodeSetGetLength(nodes1);
- for (i = 0; i < l; i++) {
- cur = xmlXPathNodeSetItem(nodes1, i);
- if (xmlXPathNodeSetContains(nodes2, cur))
- return(1);
- }
- return(0);
-}
-
-/**
- * xmlXPathNodeLeadingSorted:
- * @nodes: a node-set, sorted by document order
- * @node: a node
- *
- * Implements the EXSLT - Sets leading() function:
- * node-set set:leading (node-set, node-set)
- *
- * Returns the nodes in @nodes that precede @node in document order,
- * @nodes if @node is NULL or an empty node-set if @nodes
- * doesn't contain @node
- */
-xmlNodeSetPtr
-xmlXPathNodeLeadingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) {
- int i, l;
- xmlNodePtr cur;
- xmlNodeSetPtr ret;
-
- if (node == NULL)
- return(nodes);
-
- ret = xmlXPathNodeSetCreate(NULL);
- if (xmlXPathNodeSetIsEmpty(nodes) ||
- (!xmlXPathNodeSetContains(nodes, node)))
- return(ret);
-
- l = xmlXPathNodeSetGetLength(nodes);
- for (i = 0; i < l; i++) {
- cur = xmlXPathNodeSetItem(nodes, i);
- if (cur == node)
- break;
- xmlXPathNodeSetAddUnique(ret, cur);
- }
- return(ret);
-}
-
-/**
- * xmlXPathNodeLeading:
- * @nodes: a node-set
- * @node: a node
- *
- * Implements the EXSLT - Sets leading() function:
- * node-set set:leading (node-set, node-set)
- * @nodes is sorted by document order, then #exslSetsNodeLeadingSorted
- * is called.
- *
- * Returns the nodes in @nodes that precede @node in document order,
- * @nodes if @node is NULL or an empty node-set if @nodes
- * doesn't contain @node
- */
-xmlNodeSetPtr
-xmlXPathNodeLeading (xmlNodeSetPtr nodes, xmlNodePtr node) {
- xmlXPathNodeSetSort(nodes);
- return(xmlXPathNodeLeadingSorted(nodes, node));
-}
-
-/**
- * xmlXPathLeadingSorted:
- * @nodes1: a node-set, sorted by document order
- * @nodes2: a node-set, sorted by document order
- *
- * Implements the EXSLT - Sets leading() function:
- * node-set set:leading (node-set, node-set)
- *
- * Returns the nodes in @nodes1 that precede the first node in @nodes2
- * in document order, @nodes1 if @nodes2 is NULL or empty or
- * an empty node-set if @nodes1 doesn't contain @nodes2
- */
-xmlNodeSetPtr
-xmlXPathLeadingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
- if (xmlXPathNodeSetIsEmpty(nodes2))
- return(nodes1);
- return(xmlXPathNodeLeadingSorted(nodes1,
- xmlXPathNodeSetItem(nodes2, 1)));
-}
-
-/**
- * xmlXPathLeading:
- * @nodes1: a node-set
- * @nodes2: a node-set
- *
- * Implements the EXSLT - Sets leading() function:
- * node-set set:leading (node-set, node-set)
- * @nodes1 and @nodes2 are sorted by document order, then
- * #exslSetsLeadingSorted is called.
- *
- * Returns the nodes in @nodes1 that precede the first node in @nodes2
- * in document order, @nodes1 if @nodes2 is NULL or empty or
- * an empty node-set if @nodes1 doesn't contain @nodes2
- */
-xmlNodeSetPtr
-xmlXPathLeading (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
- if (xmlXPathNodeSetIsEmpty(nodes2))
- return(nodes1);
- if (xmlXPathNodeSetIsEmpty(nodes1))
- return(xmlXPathNodeSetCreate(NULL));
- xmlXPathNodeSetSort(nodes1);
- xmlXPathNodeSetSort(nodes2);
- return(xmlXPathNodeLeadingSorted(nodes1,
- xmlXPathNodeSetItem(nodes2, 1)));
-}
-
-/**
- * xmlXPathNodeTrailingSorted:
- * @nodes: a node-set, sorted by document order
- * @node: a node
- *
- * Implements the EXSLT - Sets trailing() function:
- * node-set set:trailing (node-set, node-set)
- *
- * Returns the nodes in @nodes that follow @node in document order,
- * @nodes if @node is NULL or an empty node-set if @nodes
- * doesn't contain @node
- */
-xmlNodeSetPtr
-xmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) {
- int i, l;
- xmlNodePtr cur;
- xmlNodeSetPtr ret;
-
- if (node == NULL)
- return(nodes);
-
- ret = xmlXPathNodeSetCreate(NULL);
- if (xmlXPathNodeSetIsEmpty(nodes) ||
- (!xmlXPathNodeSetContains(nodes, node)))
- return(ret);
-
- l = xmlXPathNodeSetGetLength(nodes);
- for (i = l; i > 0; i--) {
- cur = xmlXPathNodeSetItem(nodes, i);
- if (cur == node)
- break;
- xmlXPathNodeSetAddUnique(ret, cur);
- }
- return(ret);
-}
-
-/**
- * xmlXPathNodeTrailing:
- * @nodes: a node-set
- * @node: a node
- *
- * Implements the EXSLT - Sets trailing() function:
- * node-set set:trailing (node-set, node-set)
- * @nodes is sorted by document order, then #xmlXPathNodeTrailingSorted
- * is called.
- *
- * Returns the nodes in @nodes that follow @node in document order,
- * @nodes if @node is NULL or an empty node-set if @nodes
- * doesn't contain @node
- */
-xmlNodeSetPtr
-xmlXPathNodeTrailing (xmlNodeSetPtr nodes, xmlNodePtr node) {
- xmlXPathNodeSetSort(nodes);
- return(xmlXPathNodeTrailingSorted(nodes, node));
-}
-
-/**
- * xmlXPathTrailingSorted:
- * @nodes1: a node-set, sorted by document order
- * @nodes2: a node-set, sorted by document order
- *
- * Implements the EXSLT - Sets trailing() function:
- * node-set set:trailing (node-set, node-set)
- *
- * Returns the nodes in @nodes1 that follow the first node in @nodes2
- * in document order, @nodes1 if @nodes2 is NULL or empty or
- * an empty node-set if @nodes1 doesn't contain @nodes2
- */
-xmlNodeSetPtr
-xmlXPathTrailingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
- if (xmlXPathNodeSetIsEmpty(nodes2))
- return(nodes1);
- return(xmlXPathNodeTrailingSorted(nodes1,
- xmlXPathNodeSetItem(nodes2, 0)));
-}
-
-/**
- * xmlXPathTrailing:
- * @nodes1: a node-set
- * @nodes2: a node-set
- *
- * Implements the EXSLT - Sets trailing() function:
- * node-set set:trailing (node-set, node-set)
- * @nodes1 and @nodes2 are sorted by document order, then
- * #xmlXPathTrailingSorted is called.
- *
- * Returns the nodes in @nodes1 that follow the first node in @nodes2
- * in document order, @nodes1 if @nodes2 is NULL or empty or
- * an empty node-set if @nodes1 doesn't contain @nodes2
- */
-xmlNodeSetPtr
-xmlXPathTrailing (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
- if (xmlXPathNodeSetIsEmpty(nodes2))
- return(nodes1);
- if (xmlXPathNodeSetIsEmpty(nodes1))
- return(xmlXPathNodeSetCreate(NULL));
- xmlXPathNodeSetSort(nodes1);
- xmlXPathNodeSetSort(nodes2);
- return(xmlXPathNodeTrailingSorted(nodes1,
- xmlXPathNodeSetItem(nodes2, 0)));
-}
-
-/************************************************************************
- * *
- * Routines to handle extra functions *
- * *
- ************************************************************************/
-
-/**
- * xmlXPathRegisterFunc:
- * @ctxt: the XPath context
- * @name: the function name
- * @f: the function implementation or NULL
- *
- * Register a new function. If @f is NULL it unregisters the function
- *
- * Returns 0 in case of success, -1 in case of error
- */
-int
-xmlXPathRegisterFunc(xmlXPathContextPtr ctxt, const xmlChar *name,
- xmlXPathFunction f) {
- return(xmlXPathRegisterFuncNS(ctxt, name, NULL, f));
-}
-
-/**
- * xmlXPathRegisterFuncNS:
- * @ctxt: the XPath context
- * @name: the function name
- * @ns_uri: the function namespace URI
- * @f: the function implementation or NULL
- *
- * Register a new function. If @f is NULL it unregisters the function
- *
- * Returns 0 in case of success, -1 in case of error
- */
-int
-xmlXPathRegisterFuncNS(xmlXPathContextPtr ctxt, const xmlChar *name,
- const xmlChar *ns_uri, xmlXPathFunction f) {
- if (ctxt == NULL)
- return(-1);
- if (name == NULL)
- return(-1);
-
- if (ctxt->funcHash == NULL)
- ctxt->funcHash = xmlHashCreate(0);
- if (ctxt->funcHash == NULL)
- return(-1);
- return(xmlHashAddEntry2(ctxt->funcHash, name, ns_uri, (void *) f));
-}
-
-/**
- * xmlXPathRegisterFuncLookup:
- * @ctxt: the XPath context
- * @f: the lookup function
- * @funcCtxt: the lookup data
- *
- * Registers an external mechanism to do function lookup.
- */
-void
-xmlXPathRegisterFuncLookup (xmlXPathContextPtr ctxt,
- xmlXPathFuncLookupFunc f,
- void *funcCtxt) {
- if (ctxt == NULL)
- return;
- ctxt->funcLookupFunc = (void *) f;
- ctxt->funcLookupData = funcCtxt;
-}
-
-/**
- * xmlXPathFunctionLookup:
- * @ctxt: the XPath context
- * @name: the function name
- *
- * Search in the Function array of the context for the given
- * function.
- *
- * Returns the xmlXPathFunction or NULL if not found
- */
-xmlXPathFunction
-xmlXPathFunctionLookup(xmlXPathContextPtr ctxt, const xmlChar *name) {
- if (ctxt == NULL)
- return (NULL);
-
- if (ctxt->funcLookupFunc != NULL) {
- xmlXPathFunction ret;
- xmlXPathFuncLookupFunc f;
-
- f = (xmlXPathFuncLookupFunc) ctxt->funcLookupFunc;
- ret = f(ctxt->funcLookupData, name, NULL);
- if (ret != NULL)
- return(ret);
- }
- return(xmlXPathFunctionLookupNS(ctxt, name, NULL));
-}
-
-/**
- * xmlXPathFunctionLookupNS:
- * @ctxt: the XPath context
- * @name: the function name
- * @ns_uri: the function namespace URI
- *
- * Search in the Function array of the context for the given
- * function.
- *
- * Returns the xmlXPathFunction or NULL if not found
- */
-xmlXPathFunction
-xmlXPathFunctionLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name,
- const xmlChar *ns_uri) {
- if (ctxt == NULL)
- return(NULL);
- if (name == NULL)
- return(NULL);
-
- if (ctxt->funcLookupFunc != NULL) {
- xmlXPathFunction ret;
- xmlXPathFuncLookupFunc f;
-
- f = (xmlXPathFuncLookupFunc) ctxt->funcLookupFunc;
- ret = f(ctxt->funcLookupData, name, ns_uri);
- if (ret != NULL)
- return(ret);
- }
-
- if (ctxt->funcHash == NULL)
- return(NULL);
-
- return((xmlXPathFunction) xmlHashLookup2(ctxt->funcHash, name, ns_uri));
-}
-
-/**
- * xmlXPathRegisteredFuncsCleanup:
- * @ctxt: the XPath context
- *
- * Cleanup the XPath context data associated to registered functions
- */
-void
-xmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt) {
- if (ctxt == NULL)
- return;
-
- xmlHashFree(ctxt->funcHash, NULL);
- ctxt->funcHash = NULL;
-}
-
-/************************************************************************
- * *
- * Routines to handle Variable *
- * *
- ************************************************************************/
-
-/**
- * xmlXPathRegisterVariable:
- * @ctxt: the XPath context
- * @name: the variable name
- * @value: the variable value or NULL
- *
- * Register a new variable value. If @value is NULL it unregisters
- * the variable
- *
- * Returns 0 in case of success, -1 in case of error
- */
-int
-xmlXPathRegisterVariable(xmlXPathContextPtr ctxt, const xmlChar *name,
- xmlXPathObjectPtr value) {
- return(xmlXPathRegisterVariableNS(ctxt, name, NULL, value));
-}
-
-/**
- * xmlXPathRegisterVariableNS:
- * @ctxt: the XPath context
- * @name: the variable name
- * @ns_uri: the variable namespace URI
- * @value: the variable value or NULL
- *
- * Register a new variable value. If @value is NULL it unregisters
- * the variable
- *
- * Returns 0 in case of success, -1 in case of error
- */
-int
-xmlXPathRegisterVariableNS(xmlXPathContextPtr ctxt, const xmlChar *name,
- const xmlChar *ns_uri,
- xmlXPathObjectPtr value) {
- if (ctxt == NULL)
- return(-1);
- if (name == NULL)
- return(-1);
-
- if (ctxt->varHash == NULL)
- ctxt->varHash = xmlHashCreate(0);
- if (ctxt->varHash == NULL)
- return(-1);
- return(xmlHashUpdateEntry2(ctxt->varHash, name, ns_uri,
- (void *) value,
- (xmlHashDeallocator)xmlXPathFreeObject));
-}
-
-/**
- * xmlXPathRegisterVariableLookup:
- * @ctxt: the XPath context
- * @f: the lookup function
- * @data: the lookup data
- *
- * register an external mechanism to do variable lookup
- */
-void
-xmlXPathRegisterVariableLookup(xmlXPathContextPtr ctxt,
- xmlXPathVariableLookupFunc f, void *data) {
- if (ctxt == NULL)
- return;
- ctxt->varLookupFunc = (void *) f;
- ctxt->varLookupData = data;
-}
-
-/**
- * xmlXPathVariableLookup:
- * @ctxt: the XPath context
- * @name: the variable name
- *
- * Search in the Variable array of the context for the given
- * variable value.
- *
- * Returns a copy of the value or NULL if not found
- */
-xmlXPathObjectPtr
-xmlXPathVariableLookup(xmlXPathContextPtr ctxt, const xmlChar *name) {
- if (ctxt == NULL)
- return(NULL);
-
- if (ctxt->varLookupFunc != NULL) {
- xmlXPathObjectPtr ret;
-
- ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
- (ctxt->varLookupData, name, NULL);
- return(ret);
- }
- return(xmlXPathVariableLookupNS(ctxt, name, NULL));
-}
-
-/**
- * xmlXPathVariableLookupNS:
- * @ctxt: the XPath context
- * @name: the variable name
- * @ns_uri: the variable namespace URI
- *
- * Search in the Variable array of the context for the given
- * variable value.
- *
- * Returns the a copy of the value or NULL if not found
- */
-xmlXPathObjectPtr
-xmlXPathVariableLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name,
- const xmlChar *ns_uri) {
- if (ctxt == NULL)
- return(NULL);
-
- if (ctxt->varLookupFunc != NULL) {
- xmlXPathObjectPtr ret;
-
- ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
- (ctxt->varLookupData, name, ns_uri);
- if (ret != NULL) return(ret);
- }
-
- if (ctxt->varHash == NULL)
- return(NULL);
- if (name == NULL)
- return(NULL);
-
- return(xmlXPathObjectCopy((xmlXPathObjectPtr)
- xmlHashLookup2(ctxt->varHash, name, ns_uri)));
-}
-
-/**
- * xmlXPathRegisteredVariablesCleanup:
- * @ctxt: the XPath context
- *
- * Cleanup the XPath context data associated to registered variables
- */
-void
-xmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt) {
- if (ctxt == NULL)
- return;
-
- xmlHashFree(ctxt->varHash, (xmlHashDeallocator)xmlXPathFreeObject);
- ctxt->varHash = NULL;
-}
-
-/**
- * xmlXPathRegisterNs:
- * @ctxt: the XPath context
- * @prefix: the namespace prefix
- * @ns_uri: the namespace name
- *
- * Register a new namespace. If @ns_uri is NULL it unregisters
- * the namespace
- *
- * Returns 0 in case of success, -1 in case of error
- */
-int
-xmlXPathRegisterNs(xmlXPathContextPtr ctxt, const xmlChar *prefix,
- const xmlChar *ns_uri) {
- if (ctxt == NULL)
- return(-1);
- if (prefix == NULL)
- return(-1);
-
- if (ctxt->nsHash == NULL)
- ctxt->nsHash = xmlHashCreate(10);
- if (ctxt->nsHash == NULL)
- return(-1);
- return(xmlHashUpdateEntry(ctxt->nsHash, prefix, (void *) xmlStrdup(ns_uri),
- (xmlHashDeallocator)xmlFree));
-}
-
-/**
- * xmlXPathNsLookup:
- * @ctxt: the XPath context
- * @prefix: the namespace prefix value
- *
- * Search in the namespace declaration array of the context for the given
- * namespace name associated to the given prefix
- *
- * Returns the value or NULL if not found
- */
-const xmlChar *
-xmlXPathNsLookup(xmlXPathContextPtr ctxt, const xmlChar *prefix) {
- if (ctxt == NULL)
- return(NULL);
- if (prefix == NULL)
- return(NULL);
-
-#ifdef XML_XML_NAMESPACE
- if (xmlStrEqual(prefix, (const xmlChar *) "xml"))
- return(XML_XML_NAMESPACE);
-#endif
-
- if (ctxt->namespaces != NULL) {
- int i;
-
- for (i = 0;i < ctxt->nsNr;i++) {
- if ((ctxt->namespaces[i] != NULL) &&
- (xmlStrEqual(ctxt->namespaces[i]->prefix, prefix)))
- return(ctxt->namespaces[i]->href);
- }
- }
-
- return((const xmlChar *) xmlHashLookup(ctxt->nsHash, prefix));
-}
-
-/**
- * xmlXPathRegisteredNsCleanup:
- * @ctxt: the XPath context
- *
- * Cleanup the XPath context data associated to registered variables
- */
-void
-xmlXPathRegisteredNsCleanup(xmlXPathContextPtr ctxt) {
- if (ctxt == NULL)
- return;
-
- xmlHashFree(ctxt->nsHash, (xmlHashDeallocator)xmlFree);
- ctxt->nsHash = NULL;
-}
-
-/************************************************************************
- * *
- * Routines to handle Values *
- * *
- ************************************************************************/
-
-/* Allocations are terrible, one need to optimize all this !!! */
-
-/**
- * xmlXPathNewFloat:
- * @val: the double value
- *
- * Create a new xmlXPathObjectPtr of type double and of value @val
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPathNewFloat(double val) {
- xmlXPathObjectPtr ret;
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNewFloat: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_NUMBER;
- ret->floatval = val;
- return(ret);
-}
-
-/**
- * xmlXPathNewBoolean:
- * @val: the boolean value
- *
- * Create a new xmlXPathObjectPtr of type boolean and of value @val
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPathNewBoolean(int val) {
- xmlXPathObjectPtr ret;
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNewBoolean: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_BOOLEAN;
- ret->boolval = (val != 0);
- return(ret);
-}
-
-/**
- * xmlXPathNewString:
- * @val: the xmlChar * value
- *
- * Create a new xmlXPathObjectPtr of type string and of value @val
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPathNewString(const xmlChar *val) {
- xmlXPathObjectPtr ret;
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNewString: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_STRING;
- if (val != NULL)
- ret->stringval = xmlStrdup(val);
- else
- ret->stringval = xmlStrdup((const xmlChar *)"");
- return(ret);
-}
-
-/**
- * xmlXPathWrapString:
- * @val: the xmlChar * value
- *
- * Wraps the @val string into an XPath object.
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPathWrapString (xmlChar *val) {
- xmlXPathObjectPtr ret;
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathWrapString: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_STRING;
- ret->stringval = val;
- return(ret);
-}
-
-/**
- * xmlXPathNewCString:
- * @val: the char * value
- *
- * Create a new xmlXPathObjectPtr of type string and of value @val
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPathNewCString(const char *val) {
- xmlXPathObjectPtr ret;
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNewCString: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_STRING;
- ret->stringval = xmlStrdup(BAD_CAST val);
- return(ret);
-}
-
-/**
- * xmlXPathWrapCString:
- * @val: the char * value
- *
- * Wraps a string into an XPath object.
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPathWrapCString (char * val) {
- return(xmlXPathWrapString((xmlChar *)(val)));
-}
-
-/**
- * xmlXPathWrapExternal:
- * @val: the user data
- *
- * Wraps the @val data into an XPath object.
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPathWrapExternal (void *val) {
- xmlXPathObjectPtr ret;
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathWrapExternal: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_USERS;
- ret->user = val;
- return(ret);
-}
-
-/**
- * xmlXPathObjectCopy:
- * @val: the original object
- *
- * allocate a new copy of a given object
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPathObjectCopy(xmlXPathObjectPtr val) {
- xmlXPathObjectPtr ret;
-
- if (val == NULL)
- return(NULL);
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathObjectCopy: out of memory\n");
- return(NULL);
- }
- memcpy(ret, val , (size_t) sizeof(xmlXPathObject));
- switch (val->type) {
- case XPATH_BOOLEAN:
- case XPATH_NUMBER:
- case XPATH_POINT:
- case XPATH_RANGE:
- break;
- case XPATH_STRING:
- ret->stringval = xmlStrdup(val->stringval);
- break;
- case XPATH_XSLT_TREE:
- if ((val->nodesetval != NULL) &&
- (val->nodesetval->nodeTab != NULL)) {
- ret->boolval = 1;
- ret->user = xmlDocCopyNode(val->nodesetval->nodeTab[0],
- val->nodesetval->nodeTab[0]->doc, 1);
- ret->nodesetval = xmlXPathNodeSetCreate(
- (xmlNodePtr) ret->user);
- } else
- ret->nodesetval = xmlXPathNodeSetCreate(NULL);
- /* Deallocate the copied tree value */
- break;
- case XPATH_NODESET:
- ret->nodesetval = xmlXPathNodeSetMerge(NULL, val->nodesetval);
- /* Do not deallocate the copied tree value */
- ret->boolval = 0;
- break;
- case XPATH_LOCATIONSET:
-#ifdef LIBXML_XPTR_ENABLED
- {
- xmlLocationSetPtr loc = val->user;
- ret->user = (void *) xmlXPtrLocationSetMerge(NULL, loc);
- break;
- }
-#endif
- case XPATH_USERS:
- ret->user = val->user;
- break;
- case XPATH_UNDEFINED:
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathObjectCopy: unsupported type %d\n",
- val->type);
- break;
- }
- return(ret);
-}
-
-/**
- * xmlXPathFreeObject:
- * @obj: the object to free
- *
- * Free up an xmlXPathObjectPtr object.
- */
-void
-xmlXPathFreeObject(xmlXPathObjectPtr obj) {
- if (obj == NULL) return;
- if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) {
- if (obj->boolval) {
- if (obj->user != NULL) {
- xmlXPathFreeNodeSet(obj->nodesetval);
- xmlFreeNodeList((xmlNodePtr) obj->user);
- } else if (obj->nodesetval != NULL)
- xmlXPathFreeValueTree(obj->nodesetval);
- } else {
- if (obj->nodesetval != NULL)
- xmlXPathFreeNodeSet(obj->nodesetval);
- }
-#ifdef LIBXML_XPTR_ENABLED
- } else if (obj->type == XPATH_LOCATIONSET) {
- if (obj->user != NULL)
- xmlXPtrFreeLocationSet(obj->user);
-#endif
- } else if (obj->type == XPATH_STRING) {
- if (obj->stringval != NULL)
- xmlFree(obj->stringval);
- }
-
- xmlFree(obj);
-}
-
-
-/************************************************************************
- * *
- * Type Casting Routines *
- * *
- ************************************************************************/
-
-/**
- * xmlXPathCastBooleanToString:
- * @val: a boolean
- *
- * Converts a boolean to its string value.
- *
- * Returns a newly allocated string.
- */
-xmlChar *
-xmlXPathCastBooleanToString (int val) {
- xmlChar *ret;
- if (val)
- ret = xmlStrdup((const xmlChar *) "true");
- else
- ret = xmlStrdup((const xmlChar *) "false");
- return(ret);
-}
-
-/**
- * xmlXPathCastNumberToString:
- * @val: a number
- *
- * Converts a number to its string value.
- *
- * Returns a newly allocated string.
- */
-xmlChar *
-xmlXPathCastNumberToString (double val) {
- xmlChar *ret;
- switch (xmlXPathIsInf(val)) {
- case 1:
- ret = xmlStrdup((const xmlChar *) "Infinity");
- break;
- case -1:
- ret = xmlStrdup((const xmlChar *) "-Infinity");
- break;
- default:
- if (xmlXPathIsNaN(val)) {
- ret = xmlStrdup((const xmlChar *) "NaN");
- } else if (val == 0 && xmlXPathGetSign(val) != 0) {
- ret = xmlStrdup((const xmlChar *) "0");
- } else {
- /* could be improved */
- char buf[100];
- xmlXPathFormatNumber(val, buf, 100);
- ret = xmlStrdup((const xmlChar *) buf);
- }
- }
- return(ret);
-}
-
-/**
- * xmlXPathCastNodeToString:
- * @node: a node
- *
- * Converts a node to its string value.
- *
- * Returns a newly allocated string.
- */
-xmlChar *
-xmlXPathCastNodeToString (xmlNodePtr node) {
- if ((node != NULL) && (node->type == XML_DOCUMENT_NODE))
- node = xmlDocGetRootElement((xmlDocPtr) node);
- return(xmlNodeGetContent(node));
-}
-
-/**
- * xmlXPathCastNodeSetToString:
- * @ns: a node-set
- *
- * Converts a node-set to its string value.
- *
- * Returns a newly allocated string.
- */
-xmlChar *
-xmlXPathCastNodeSetToString (xmlNodeSetPtr ns) {
- if ((ns == NULL) || (ns->nodeNr == 0) || (ns->nodeTab == NULL))
- return(xmlStrdup((const xmlChar *) ""));
-
- xmlXPathNodeSetSort(ns);
- return(xmlXPathCastNodeToString(ns->nodeTab[0]));
-}
-
-/**
- * xmlXPathCastToString:
- * @val: an XPath object
- *
- * Converts an existing object to its string() equivalent
- *
- * Returns the string value of the object, NULL in case of error.
- * A new string is allocated only if needed (@val isn't a
- * string object).
- */
-xmlChar *
-xmlXPathCastToString(xmlXPathObjectPtr val) {
- xmlChar *ret = NULL;
-
- if (val == NULL)
- return(xmlStrdup((const xmlChar *) ""));
- switch (val->type) {
- case XPATH_UNDEFINED:
-#ifdef DEBUG_EXPR
- xmlGenericError(xmlGenericErrorContext, "String: undefined\n");
-#endif
- ret = xmlStrdup((const xmlChar *) "");
- break;
- case XPATH_NODESET:
- case XPATH_XSLT_TREE:
- ret = xmlXPathCastNodeSetToString(val->nodesetval);
- break;
- case XPATH_STRING:
- return(xmlStrdup(val->stringval));
- case XPATH_BOOLEAN:
- ret = xmlXPathCastBooleanToString(val->boolval);
- break;
- case XPATH_NUMBER: {
- ret = xmlXPathCastNumberToString(val->floatval);
- break;
- }
- case XPATH_USERS:
- case XPATH_POINT:
- case XPATH_RANGE:
- case XPATH_LOCATIONSET:
- TODO
- ret = xmlStrdup((const xmlChar *) "");
- break;
- }
- return(ret);
-}
-
-/**
- * xmlXPathConvertString:
- * @val: an XPath object
- *
- * Converts an existing object to its string() equivalent
- *
- * Returns the new object, the old one is freed (or the operation
- * is done directly on @val)
- */
-xmlXPathObjectPtr
-xmlXPathConvertString(xmlXPathObjectPtr val) {
- xmlChar *res = NULL;
-
- if (val == NULL)
- return(xmlXPathNewCString(""));
-
- switch (val->type) {
- case XPATH_UNDEFINED:
-#ifdef DEBUG_EXPR
- xmlGenericError(xmlGenericErrorContext, "STRING: undefined\n");
-#endif
- break;
- case XPATH_NODESET:
- case XPATH_XSLT_TREE:
- res = xmlXPathCastNodeSetToString(val->nodesetval);
- break;
- case XPATH_STRING:
- return(val);
- case XPATH_BOOLEAN:
- res = xmlXPathCastBooleanToString(val->boolval);
- break;
- case XPATH_NUMBER:
- res = xmlXPathCastNumberToString(val->floatval);
- break;
- case XPATH_USERS:
- case XPATH_POINT:
- case XPATH_RANGE:
- case XPATH_LOCATIONSET:
- TODO;
- break;
- }
- xmlXPathFreeObject(val);
- if (res == NULL)
- return(xmlXPathNewCString(""));
- return(xmlXPathWrapString(res));
-}
-
-/**
- * xmlXPathCastBooleanToNumber:
- * @val: a boolean
- *
- * Converts a boolean to its number value
- *
- * Returns the number value
- */
-double
-xmlXPathCastBooleanToNumber(int val) {
- if (val)
- return(1.0);
- return(0.0);
-}
-
-/**
- * xmlXPathCastStringToNumber:
- * @val: a string
- *
- * Converts a string to its number value
- *
- * Returns the number value
- */
-double
-xmlXPathCastStringToNumber(const xmlChar * val) {
- return(xmlXPathStringEvalNumber(val));
-}
-
-/**
- * xmlXPathCastNodeToNumber:
- * @node: a node
- *
- * Converts a node to its number value
- *
- * Returns the number value
- */
-double
-xmlXPathCastNodeToNumber (xmlNodePtr node) {
- xmlChar *strval;
- double ret;
-
- if (node == NULL)
- return(xmlXPathNAN);
- strval = xmlXPathCastNodeToString(node);
- if (strval == NULL)
- return(xmlXPathNAN);
- ret = xmlXPathCastStringToNumber(strval);
- xmlFree(strval);
-
- return(ret);
-}
-
-/**
- * xmlXPathCastNodeSetToNumber:
- * @ns: a node-set
- *
- * Converts a node-set to its number value
- *
- * Returns the number value
- */
-double
-xmlXPathCastNodeSetToNumber (xmlNodeSetPtr ns) {
- xmlChar *str;
- double ret;
-
- if (ns == NULL)
- return(xmlXPathNAN);
- str = xmlXPathCastNodeSetToString(ns);
- ret = xmlXPathCastStringToNumber(str);
- xmlFree(str);
- return(ret);
-}
-
-/**
- * xmlXPathCastToNumber:
- * @val: an XPath object
- *
- * Converts an XPath object to its number value
- *
- * Returns the number value
- */
-double
-xmlXPathCastToNumber(xmlXPathObjectPtr val) {
- double ret = 0.0;
-
- if (val == NULL)
- return(xmlXPathNAN);
- switch (val->type) {
- case XPATH_UNDEFINED:
-#ifdef DEGUB_EXPR
- xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n");
-#endif
- ret = xmlXPathNAN;
- break;
- case XPATH_NODESET:
- case XPATH_XSLT_TREE:
- ret = xmlXPathCastNodeSetToNumber(val->nodesetval);
- break;
- case XPATH_STRING:
- ret = xmlXPathCastStringToNumber(val->stringval);
- break;
- case XPATH_NUMBER:
- ret = val->floatval;
- break;
- case XPATH_BOOLEAN:
- ret = xmlXPathCastBooleanToNumber(val->boolval);
- break;
- case XPATH_USERS:
- case XPATH_POINT:
- case XPATH_RANGE:
- case XPATH_LOCATIONSET:
- TODO;
- ret = xmlXPathNAN;
- break;
- }
- return(ret);
-}
-
-/**
- * xmlXPathConvertNumber:
- * @val: an XPath object
- *
- * Converts an existing object to its number() equivalent
- *
- * Returns the new object, the old one is freed (or the operation
- * is done directly on @val)
- */
-xmlXPathObjectPtr
-xmlXPathConvertNumber(xmlXPathObjectPtr val) {
- xmlXPathObjectPtr ret;
-
- if (val == NULL)
- return(xmlXPathNewFloat(0.0));
- if (val->type == XPATH_NUMBER)
- return(val);
- ret = xmlXPathNewFloat(xmlXPathCastToNumber(val));
- xmlXPathFreeObject(val);
- return(ret);
-}
-
-/**
- * xmlXPathCastNumberToBoolean:
- * @val: a number
- *
- * Converts a number to its boolean value
- *
- * Returns the boolean value
- */
-int
-xmlXPathCastNumberToBoolean (double val) {
- if (xmlXPathIsNaN(val) || (val == 0.0))
- return(0);
- return(1);
-}
-
-/**
- * xmlXPathCastStringToBoolean:
- * @val: a string
- *
- * Converts a string to its boolean value
- *
- * Returns the boolean value
- */
-int
-xmlXPathCastStringToBoolean (const xmlChar *val) {
- if ((val == NULL) || (xmlStrlen(val) == 0))
- return(0);
- return(1);
-}
-
-/**
- * xmlXPathCastNodeSetToBoolean:
- * @ns: a node-set
- *
- * Converts a node-set to its boolean value
- *
- * Returns the boolean value
- */
-int
-xmlXPathCastNodeSetToBoolean (xmlNodeSetPtr ns) {
- if ((ns == NULL) || (ns->nodeNr == 0))
- return(0);
- return(1);
-}
-
-/**
- * xmlXPathCastToBoolean:
- * @val: an XPath object
- *
- * Converts an XPath object to its boolean value
- *
- * Returns the boolean value
- */
-int
-xmlXPathCastToBoolean (xmlXPathObjectPtr val) {
- int ret = 0;
-
- if (val == NULL)
- return(0);
- switch (val->type) {
- case XPATH_UNDEFINED:
-#ifdef DEBUG_EXPR
- xmlGenericError(xmlGenericErrorContext, "BOOLEAN: undefined\n");
-#endif
- ret = 0;
- break;
- case XPATH_NODESET:
- case XPATH_XSLT_TREE:
- ret = xmlXPathCastNodeSetToBoolean(val->nodesetval);
- break;
- case XPATH_STRING:
- ret = xmlXPathCastStringToBoolean(val->stringval);
- break;
- case XPATH_NUMBER:
- ret = xmlXPathCastNumberToBoolean(val->floatval);
- break;
- case XPATH_BOOLEAN:
- ret = val->boolval;
- break;
- case XPATH_USERS:
- case XPATH_POINT:
- case XPATH_RANGE:
- case XPATH_LOCATIONSET:
- TODO;
- ret = 0;
- break;
- }
- return(ret);
-}
-
-
-/**
- * xmlXPathConvertBoolean:
- * @val: an XPath object
- *
- * Converts an existing object to its boolean() equivalent
- *
- * Returns the new object, the old one is freed (or the operation
- * is done directly on @val)
- */
-xmlXPathObjectPtr
-xmlXPathConvertBoolean(xmlXPathObjectPtr val) {
- xmlXPathObjectPtr ret;
-
- if (val == NULL)
- return(xmlXPathNewBoolean(0));
- if (val->type == XPATH_BOOLEAN)
- return(val);
- ret = xmlXPathNewBoolean(xmlXPathCastToBoolean(val));
- xmlXPathFreeObject(val);
- return(ret);
-}
-
-/************************************************************************
- * *
- * Routines to handle XPath contexts *
- * *
- ************************************************************************/
-
-/**
- * xmlXPathNewContext:
- * @doc: the XML document
- *
- * Create a new xmlXPathContext
- *
- * Returns the xmlXPathContext just allocated. The caller will need to free it.
- */
-xmlXPathContextPtr
-xmlXPathNewContext(xmlDocPtr doc) {
- xmlXPathContextPtr ret;
-
- ret = (xmlXPathContextPtr) xmlMalloc(sizeof(xmlXPathContext));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNewContext: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathContext));
- ret->doc = doc;
- ret->node = NULL;
-
- ret->varHash = NULL;
-
- ret->nb_types = 0;
- ret->max_types = 0;
- ret->types = NULL;
-
- ret->funcHash = xmlHashCreate(0);
-
- ret->nb_axis = 0;
- ret->max_axis = 0;
- ret->axis = NULL;
-
- ret->nsHash = NULL;
- ret->user = NULL;
-
- ret->contextSize = -1;
- ret->proximityPosition = -1;
-
- xmlXPathRegisterAllFunctions(ret);
-
- return(ret);
-}
-
-/**
- * xmlXPathFreeContext:
- * @ctxt: the context to free
- *
- * Free up an xmlXPathContext
- */
-void
-xmlXPathFreeContext(xmlXPathContextPtr ctxt) {
- xmlXPathRegisteredNsCleanup(ctxt);
- xmlXPathRegisteredFuncsCleanup(ctxt);
- xmlXPathRegisteredVariablesCleanup(ctxt);
- xmlFree(ctxt);
-}
-
-/************************************************************************
- * *
- * Routines to handle XPath parser contexts *
- * *
- ************************************************************************/
-
-#define CHECK_CTXT(ctxt) \
- if (ctxt == NULL) { \
- xmlGenericError(xmlGenericErrorContext, \
- "%s:%d Internal error: ctxt == NULL\n", \
- __FILE__, __LINE__); \
- } \
-
-
-#define CHECK_CONTEXT(ctxt) \
- if (ctxt == NULL) { \
- xmlGenericError(xmlGenericErrorContext, \
- "%s:%d Internal error: no context\n", \
- __FILE__, __LINE__); \
- } \
- else if (ctxt->doc == NULL) { \
- xmlGenericError(xmlGenericErrorContext, \
- "%s:%d Internal error: no document\n", \
- __FILE__, __LINE__); \
- } \
- else if (ctxt->doc->children == NULL) { \
- xmlGenericError(xmlGenericErrorContext, \
- "%s:%d Internal error: document without root\n", \
- __FILE__, __LINE__); \
- } \
-
-
-/**
- * xmlXPathNewParserContext:
- * @str: the XPath expression
- * @ctxt: the XPath context
- *
- * Create a new xmlXPathParserContext
- *
- * Returns the xmlXPathParserContext just allocated.
- */
-xmlXPathParserContextPtr
-xmlXPathNewParserContext(const xmlChar *str, xmlXPathContextPtr ctxt) {
- xmlXPathParserContextPtr ret;
-
- ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathNewParserContext: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
- ret->cur = ret->base = str;
- ret->context = ctxt;
-
- ret->comp = xmlXPathNewCompExpr();
- if (ret->comp == NULL) {
- xmlFree(ret->valueTab);
- xmlFree(ret);
- return(NULL);
- }
-
- return(ret);
-}
-
-/**
- * xmlXPathCompParserContext:
- * @comp: the XPath compiled expression
- * @ctxt: the XPath context
- *
- * Create a new xmlXPathParserContext when processing a compiled expression
- *
- * Returns the xmlXPathParserContext just allocated.
- */
-static xmlXPathParserContextPtr
-xmlXPathCompParserContext(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctxt) {
- xmlXPathParserContextPtr ret;
-
- ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathCompParserContext: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
-
- /* Allocate the value stack */
- ret->valueTab = (xmlXPathObjectPtr *)
- xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
- if (ret->valueTab == NULL) {
- xmlFree(ret);
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathCompParserContext: out of memory\n");
- return(NULL);
- }
- ret->valueNr = 0;
- ret->valueMax = 10;
- ret->value = NULL;
-
- ret->context = ctxt;
- ret->comp = comp;
-
- return(ret);
-}
-
-/**
- * xmlXPathFreeParserContext:
- * @ctxt: the context to free
- *
- * Free up an xmlXPathParserContext
- */
-void
-xmlXPathFreeParserContext(xmlXPathParserContextPtr ctxt) {
- if (ctxt->valueTab != NULL) {
- xmlFree(ctxt->valueTab);
- }
- if (ctxt->comp)
- xmlXPathFreeCompExpr(ctxt->comp);
- xmlFree(ctxt);
-}
-
-/************************************************************************
- * *
- * The implicit core function library *
- * *
- ************************************************************************/
-
-/**
- * xmlXPathNodeValHash:
- * @node: a node pointer
- *
- * Function computing the beginning of the string value of the node,
- * used to speed up comparisons
- *
- * Returns an int usable as a hash
- */
-static unsigned int
-xmlXPathNodeValHash(xmlNodePtr node) {
- int len = 2;
- const xmlChar * string = NULL;
- xmlNodePtr tmp = NULL;
- unsigned int ret = 0;
-
- if (node == NULL)
- return(0);
-
-
- switch (node->type) {
- case XML_COMMENT_NODE:
- case XML_PI_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_TEXT_NODE:
- string = node->content;
- if (string == NULL)
- return(0);
- if (string[0] == 0)
- return(0);
- return(((unsigned int) string[0]) +
- (((unsigned int) string[1]) << 8));
- case XML_NAMESPACE_DECL:
- string = ((xmlNsPtr)node)->href;
- if (string == NULL)
- return(0);
- if (string[0] == 0)
- return(0);
- return(((unsigned int) string[0]) +
- (((unsigned int) string[1]) << 8));
- case XML_ATTRIBUTE_NODE:
- tmp = ((xmlAttrPtr) node)->children;
- break;
- case XML_ELEMENT_NODE:
- tmp = node->children;
- break;
- default:
- return(0);
- }
- while (tmp != NULL) {
- switch (tmp->type) {
- case XML_COMMENT_NODE:
- case XML_PI_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_TEXT_NODE:
- string = tmp->content;
- break;
- case XML_NAMESPACE_DECL:
- string = ((xmlNsPtr)tmp)->href;
- break;
- default:
- break;
- }
- if ((string != NULL) && (string[0] != 0)) {
- if (string[0] == 0)
- return(0);
- if (len == 1) {
- return(ret + (((unsigned int) string[0]) << 8));
- }
- if (string[1] == 0) {
- len = 1;
- ret = (unsigned int) string[0];
- } else {
- return(((unsigned int) string[0]) +
- (((unsigned int) string[1]) << 8));
- }
- }
- /*
- * Skip to next node
- */
- if ((tmp->children != NULL) && (tmp->type != XML_DTD_NODE)) {
- if (tmp->children->type != XML_ENTITY_DECL) {
- tmp = tmp->children;
- continue;
- }
- }
- if (tmp == node)
- break;
-
- if (tmp->next != NULL) {
- tmp = tmp->next;
- continue;
- }
-
- do {
- tmp = tmp->parent;
- if (tmp == NULL)
- break;
- if (tmp == node) {
- tmp = NULL;
- break;
- }
- if (tmp->next != NULL) {
- tmp = tmp->next;
- break;
- }
- } while (tmp != NULL);
- }
- return(ret);
-}
-
-/**
- * xmlXPathStringHash:
- * @string: a string
- *
- * Function computing the beginning of the string value of the node,
- * used to speed up comparisons
- *
- * Returns an int usable as a hash
- */
-static unsigned int
-xmlXPathStringHash(const xmlChar * string) {
- if (string == NULL)
- return((unsigned int) 0);
- if (string[0] == 0)
- return(0);
- return(((unsigned int) string[0]) +
- (((unsigned int) string[1]) << 8));
-}
-
-/**
- * xmlXPathCompareNodeSetFloat:
- * @ctxt: the XPath Parser context
- * @inf: less than (1) or greater than (0)
- * @strict: is the comparison strict
- * @arg: the node set
- * @f: the value
- *
- * Implement the compare operation between a nodeset and a number
- * @ns < @val (1, 1, ...
- * @ns <= @val (1, 0, ...
- * @ns > @val (0, 1, ...
- * @ns >= @val (0, 0, ...
- *
- * If one object to be compared is a node-set and the other is a number,
- * then the comparison will be true if and only if there is a node in the
- * node-set such that the result of performing the comparison on the number
- * to be compared and on the result of converting the string-value of that
- * node to a number using the number function is true.
- *
- * Returns 0 or 1 depending on the results of the test.
- */
-static int
-xmlXPathCompareNodeSetFloat(xmlXPathParserContextPtr ctxt, int inf, int strict,
- xmlXPathObjectPtr arg, xmlXPathObjectPtr f) {
- int i, ret = 0;
- xmlNodeSetPtr ns;
- xmlChar *str2;
-
- if ((f == NULL) || (arg == NULL) ||
- ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) {
- xmlXPathFreeObject(arg);
- xmlXPathFreeObject(f);
- return(0);
- }
- ns = arg->nodesetval;
- if (ns != NULL) {
- for (i = 0;i < ns->nodeNr;i++) {
- str2 = xmlXPathCastNodeToString(ns->nodeTab[i]);
- if (str2 != NULL) {
- valuePush(ctxt,
- xmlXPathNewString(str2));
- xmlFree(str2);
- xmlXPathNumberFunction(ctxt, 1);
- valuePush(ctxt, xmlXPathObjectCopy(f));
- ret = xmlXPathCompareValues(ctxt, inf, strict);
- if (ret)
- break;
- }
- }
- }
- xmlXPathFreeObject(arg);
- xmlXPathFreeObject(f);
- return(ret);
-}
-
-/**
- * xmlXPathCompareNodeSetString:
- * @ctxt: the XPath Parser context
- * @inf: less than (1) or greater than (0)
- * @strict: is the comparison strict
- * @arg: the node set
- * @s: the value
- *
- * Implement the compare operation between a nodeset and a string
- * @ns < @val (1, 1, ...
- * @ns <= @val (1, 0, ...
- * @ns > @val (0, 1, ...
- * @ns >= @val (0, 0, ...
- *
- * If one object to be compared is a node-set and the other is a string,
- * then the comparison will be true if and only if there is a node in
- * the node-set such that the result of performing the comparison on the
- * string-value of the node and the other string is true.
- *
- * Returns 0 or 1 depending on the results of the test.
- */
-static int
-xmlXPathCompareNodeSetString(xmlXPathParserContextPtr ctxt, int inf, int strict,
- xmlXPathObjectPtr arg, xmlXPathObjectPtr s) {
- int i, ret = 0;
- xmlNodeSetPtr ns;
- xmlChar *str2;
-
- if ((s == NULL) || (arg == NULL) ||
- ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) {
- xmlXPathFreeObject(arg);
- xmlXPathFreeObject(s);
- return(0);
- }
- ns = arg->nodesetval;
- if (ns != NULL) {
- for (i = 0;i < ns->nodeNr;i++) {
- str2 = xmlXPathCastNodeToString(ns->nodeTab[i]);
- if (str2 != NULL) {
- valuePush(ctxt,
- xmlXPathNewString(str2));
- xmlFree(str2);
- valuePush(ctxt, xmlXPathObjectCopy(s));
- ret = xmlXPathCompareValues(ctxt, inf, strict);
- if (ret)
- break;
- }
- }
- }
- xmlXPathFreeObject(arg);
- xmlXPathFreeObject(s);
- return(ret);
-}
-
-/**
- * xmlXPathCompareNodeSets:
- * @inf: less than (1) or greater than (0)
- * @strict: is the comparison strict
- * @arg1: the first node set object
- * @arg2: the second node set object
- *
- * Implement the compare operation on nodesets:
- *
- * If both objects to be compared are node-sets, then the comparison
- * will be true if and only if there is a node in the first node-set
- * and a node in the second node-set such that the result of performing
- * the comparison on the string-values of the two nodes is true.
- * ....
- * When neither object to be compared is a node-set and the operator
- * is <=, <, >= or >, then the objects are compared by converting both
- * objects to numbers and comparing the numbers according to IEEE 754.
- * ....
- * The number function converts its argument to a number as follows:
- * - a string that consists of optional whitespace followed by an
- * optional minus sign followed by a Number followed by whitespace
- * is converted to the IEEE 754 number that is nearest (according
- * to the IEEE 754 round-to-nearest rule) to the mathematical value
- * represented by the string; any other string is converted to NaN
- *
- * Conclusion all nodes need to be converted first to their string value
- * and then the comparison must be done when possible
- */
-static int
-xmlXPathCompareNodeSets(int inf, int strict,
- xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) {
- int i, j, init = 0;
- double val1;
- double *values2;
- int ret = 0;
- xmlNodeSetPtr ns1;
- xmlNodeSetPtr ns2;
-
- if ((arg1 == NULL) ||
- ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE))) {
- xmlXPathFreeObject(arg2);
- return(0);
- }
- if ((arg2 == NULL) ||
- ((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE))) {
- xmlXPathFreeObject(arg1);
- xmlXPathFreeObject(arg2);
- return(0);
- }
-
- ns1 = arg1->nodesetval;
- ns2 = arg2->nodesetval;
-
- if ((ns1 == NULL) || (ns1->nodeNr <= 0)) {
- xmlXPathFreeObject(arg1);
- xmlXPathFreeObject(arg2);
- return(0);
- }
- if ((ns2 == NULL) || (ns2->nodeNr <= 0)) {
- xmlXPathFreeObject(arg1);
- xmlXPathFreeObject(arg2);
- return(0);
- }
-
- values2 = (double *) xmlMalloc(ns2->nodeNr * sizeof(double));
- if (values2 == NULL) {
- xmlXPathFreeObject(arg1);
- xmlXPathFreeObject(arg2);
- return(0);
- }
- for (i = 0;i < ns1->nodeNr;i++) {
- val1 = xmlXPathCastNodeToNumber(ns1->nodeTab[i]);
- if (xmlXPathIsNaN(val1))
- continue;
- for (j = 0;j < ns2->nodeNr;j++) {
- if (init == 0) {
- values2[j] = xmlXPathCastNodeToNumber(ns2->nodeTab[j]);
- }
- if (xmlXPathIsNaN(values2[j]))
- continue;
- if (inf && strict)
- ret = (val1 < values2[j]);
- else if (inf && !strict)
- ret = (val1 <= values2[j]);
- else if (!inf && strict)
- ret = (val1 > values2[j]);
- else if (!inf && !strict)
- ret = (val1 >= values2[j]);
- if (ret)
- break;
- }
- if (ret)
- break;
- init = 1;
- }
- xmlFree(values2);
- xmlXPathFreeObject(arg1);
- xmlXPathFreeObject(arg2);
- return(ret);
-}
-
-/**
- * xmlXPathCompareNodeSetValue:
- * @ctxt: the XPath Parser context
- * @inf: less than (1) or greater than (0)
- * @strict: is the comparison strict
- * @arg: the node set
- * @val: the value
- *
- * Implement the compare operation between a nodeset and a value
- * @ns < @val (1, 1, ...
- * @ns <= @val (1, 0, ...
- * @ns > @val (0, 1, ...
- * @ns >= @val (0, 0, ...
- *
- * If one object to be compared is a node-set and the other is a boolean,
- * then the comparison will be true if and only if the result of performing
- * the comparison on the boolean and on the result of converting
- * the node-set to a boolean using the boolean function is true.
- *
- * Returns 0 or 1 depending on the results of the test.
- */
-static int
-xmlXPathCompareNodeSetValue(xmlXPathParserContextPtr ctxt, int inf, int strict,
- xmlXPathObjectPtr arg, xmlXPathObjectPtr val) {
- if ((val == NULL) || (arg == NULL) ||
- ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
- return(0);
-
- switch(val->type) {
- case XPATH_NUMBER:
- return(xmlXPathCompareNodeSetFloat(ctxt, inf, strict, arg, val));
- case XPATH_NODESET:
- case XPATH_XSLT_TREE:
- return(xmlXPathCompareNodeSets(inf, strict, arg, val));
- case XPATH_STRING:
- return(xmlXPathCompareNodeSetString(ctxt, inf, strict, arg, val));
- case XPATH_BOOLEAN:
- valuePush(ctxt, arg);
- xmlXPathBooleanFunction(ctxt, 1);
- valuePush(ctxt, val);
- return(xmlXPathCompareValues(ctxt, inf, strict));
- default:
- TODO
- }
- return(0);
-}
-
-/**
- * xmlXPathEqualNodeSetString:
- * @arg: the nodeset object argument
- * @str: the string to compare to.
- * @neq: flag to show whether for '=' (0) or '!=' (1)
- *
- * Implement the equal operation on XPath objects content: @arg1 == @arg2
- * If one object to be compared is a node-set and the other is a string,
- * then the comparison will be true if and only if there is a node in
- * the node-set such that the result of performing the comparison on the
- * string-value of the node and the other string is true.
- *
- * Returns 0 or 1 depending on the results of the test.
- */
-static int
-xmlXPathEqualNodeSetString(xmlXPathObjectPtr arg, const xmlChar * str, int neq)
-{
- int i;
- xmlNodeSetPtr ns;
- xmlChar *str2;
- unsigned int hash;
-
- if ((str == NULL) || (arg == NULL) ||
- ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
- return (0);
- ns = arg->nodesetval;
- hash = xmlXPathStringHash(str);
- if (ns == NULL)
- return (0);
- if (ns->nodeNr <= 0) {
- if (hash == 0)
- return(neq ^ 1);
- return(neq);
- }
- for (i = 0; i < ns->nodeNr; i++) {
- if (xmlXPathNodeValHash(ns->nodeTab[i]) == hash) {
- str2 = xmlNodeGetContent(ns->nodeTab[i]);
- if ((str2 != NULL) && (xmlStrEqual(str, str2))) {
- xmlFree(str2);
- if (neq)
- continue;
- return (1);
- } else if (neq) {
- if (str2 != NULL)
- xmlFree(str2);
- return (1);
- }
- if (str2 != NULL)
- xmlFree(str2);
- } else if (neq)
- return (1);
- }
- return (0);
-}
-
-/**
- * xmlXPathEqualNodeSetFloat:
- * @arg: the nodeset object argument
- * @f: the float to compare to
- * @neq: flag to show whether to compare '=' (0) or '!=' (1)
- *
- * Implement the equal operation on XPath objects content: @arg1 == @arg2
- * If one object to be compared is a node-set and the other is a number,
- * then the comparison will be true if and only if there is a node in
- * the node-set such that the result of performing the comparison on the
- * number to be compared and on the result of converting the string-value
- * of that node to a number using the number function is true.
- *
- * Returns 0 or 1 depending on the results of the test.
- */
-static int
-xmlXPathEqualNodeSetFloat(xmlXPathParserContextPtr ctxt,
- xmlXPathObjectPtr arg, double f, int neq) {
- int i, ret=0;
- xmlNodeSetPtr ns;
- xmlChar *str2;
- xmlXPathObjectPtr val;
- double v;
-
- if ((arg == NULL) ||
- ((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
- return(0);
-
- ns = arg->nodesetval;
- if (ns != NULL) {
- for (i=0;i<ns->nodeNr;i++) {
- str2 = xmlXPathCastNodeToString(ns->nodeTab[i]);
- if (str2 != NULL) {
- valuePush(ctxt, xmlXPathNewString(str2));
- xmlFree(str2);
- xmlXPathNumberFunction(ctxt, 1);
- val = valuePop(ctxt);
- v = val->floatval;
- xmlXPathFreeObject(val);
- if (!xmlXPathIsNaN(v)) {
- if ((!neq) && (v==f)) {
- ret = 1;
- break;
- } else if ((neq) && (v!=f)) {
- ret = 1;
- break;
- }
- }
- }
- }
- }
-
- return(ret);
-}
-
-
-/**
- * xmlXPathEqualNodeSets:
- * @arg1: first nodeset object argument
- * @arg2: second nodeset object argument
- * @neq: flag to show whether to test '=' (0) or '!=' (1)
- *
- * Implement the equal / not equal operation on XPath nodesets:
- * @arg1 == @arg2 or @arg1 != @arg2
- * If both objects to be compared are node-sets, then the comparison
- * will be true if and only if there is a node in the first node-set and
- * a node in the second node-set such that the result of performing the
- * comparison on the string-values of the two nodes is true.
- *
- * (needless to say, this is a costly operation)
- *
- * Returns 0 or 1 depending on the results of the test.
- */
-static int
-xmlXPathEqualNodeSets(xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2, int neq) {
- int i, j;
- unsigned int *hashs1;
- unsigned int *hashs2;
- xmlChar **values1;
- xmlChar **values2;
- int ret = 0;
- xmlNodeSetPtr ns1;
- xmlNodeSetPtr ns2;
-
- if ((arg1 == NULL) ||
- ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)))
- return(0);
- if ((arg2 == NULL) ||
- ((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE)))
- return(0);
-
- ns1 = arg1->nodesetval;
- ns2 = arg2->nodesetval;
-
- if ((ns1 == NULL) || (ns1->nodeNr <= 0))
- return(0);
- if ((ns2 == NULL) || (ns2->nodeNr <= 0))
- return(0);
-
- /*
- * for equal, check if there is a node pertaining to both sets
- */
- if (neq == 0)
- for (i = 0;i < ns1->nodeNr;i++)
- for (j = 0;j < ns2->nodeNr;j++)
- if (ns1->nodeTab[i] == ns2->nodeTab[j])
- return(1);
-
- values1 = (xmlChar **) xmlMalloc(ns1->nodeNr * sizeof(xmlChar *));
- if (values1 == NULL)
- return(0);
- hashs1 = (unsigned int *) xmlMalloc(ns1->nodeNr * sizeof(unsigned int));
- if (hashs1 == NULL) {
- xmlFree(values1);
- return(0);
- }
- memset(values1, 0, ns1->nodeNr * sizeof(xmlChar *));
- values2 = (xmlChar **) xmlMalloc(ns2->nodeNr * sizeof(xmlChar *));
- if (values2 == NULL) {
- xmlFree(hashs1);
- xmlFree(values1);
- return(0);
- }
- hashs2 = (unsigned int *) xmlMalloc(ns2->nodeNr * sizeof(unsigned int));
- if (hashs2 == NULL) {
- xmlFree(hashs1);
- xmlFree(values1);
- xmlFree(values2);
- return(0);
- }
- memset(values2, 0, ns2->nodeNr * sizeof(xmlChar *));
- for (i = 0;i < ns1->nodeNr;i++) {
- hashs1[i] = xmlXPathNodeValHash(ns1->nodeTab[i]);
- for (j = 0;j < ns2->nodeNr;j++) {
- if (i == 0)
- hashs2[j] = xmlXPathNodeValHash(ns2->nodeTab[j]);
- if (hashs1[i] != hashs2[j]) {
- if (neq) {
- ret = 1;
- break;
- }
- }
- else {
- if (values1[i] == NULL)
- values1[i] = xmlNodeGetContent(ns1->nodeTab[i]);
- if (values2[j] == NULL)
- values2[j] = xmlNodeGetContent(ns2->nodeTab[j]);
- ret = xmlStrEqual(values1[i], values2[j]) ^ neq;
- if (ret)
- break;
- }
- }
- if (ret)
- break;
- }
- for (i = 0;i < ns1->nodeNr;i++)
- if (values1[i] != NULL)
- xmlFree(values1[i]);
- for (j = 0;j < ns2->nodeNr;j++)
- if (values2[j] != NULL)
- xmlFree(values2[j]);
- xmlFree(values1);
- xmlFree(values2);
- xmlFree(hashs1);
- xmlFree(hashs2);
- return(ret);
-}
-
-static int
-xmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt,
- xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) {
- int ret = 0;
- /*
- *At this point we are assured neither arg1 nor arg2
- *is a nodeset, so we can just pick the appropriate routine.
- */
- switch (arg1->type) {
- case XPATH_UNDEFINED:
-#ifdef DEBUG_EXPR
- xmlGenericError(xmlGenericErrorContext,
- "Equal: undefined\n");
-#endif
- break;
- case XPATH_BOOLEAN:
- switch (arg2->type) {
- case XPATH_UNDEFINED:
-#ifdef DEBUG_EXPR
- xmlGenericError(xmlGenericErrorContext,
- "Equal: undefined\n");
-#endif
- break;
- case XPATH_BOOLEAN:
-#ifdef DEBUG_EXPR
- xmlGenericError(xmlGenericErrorContext,
- "Equal: %d boolean %d \n",
- arg1->boolval, arg2->boolval);
-#endif
- ret = (arg1->boolval == arg2->boolval);
- break;
- case XPATH_NUMBER:
- ret = (arg1->boolval ==
- xmlXPathCastNumberToBoolean(arg2->floatval));
- break;
- case XPATH_STRING:
- if ((arg2->stringval == NULL) ||
- (arg2->stringval[0] == 0)) ret = 0;
- else
- ret = 1;
- ret = (arg1->boolval == ret);
- break;
- case XPATH_USERS:
- case XPATH_POINT:
- case XPATH_RANGE:
- case XPATH_LOCATIONSET:
- TODO
- break;
- case XPATH_NODESET:
- case XPATH_XSLT_TREE:
- break;
- }
- break;
- case XPATH_NUMBER:
- switch (arg2->type) {
- case XPATH_UNDEFINED:
-#ifdef DEBUG_EXPR
- xmlGenericError(xmlGenericErrorContext,
- "Equal: undefined\n");
-#endif
- break;
- case XPATH_BOOLEAN:
- ret = (arg2->boolval==
- xmlXPathCastNumberToBoolean(arg1->floatval));
- break;
- case XPATH_STRING:
- valuePush(ctxt, arg2);
- xmlXPathNumberFunction(ctxt, 1);
- arg2 = valuePop(ctxt);
- /* no break on purpose */
- case XPATH_NUMBER:
- /* Hand check NaN and Infinity equalities */
- if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) {
- ret = 0;
- } else if (xmlXPathIsInf(arg1->floatval) == 1) {
- if (xmlXPathIsInf(arg2->floatval) == 1)
- ret = 1;
- else
- ret = 0;
- } else if (xmlXPathIsInf(arg1->floatval) == -1) {
- if (xmlXPathIsInf(arg2->floatval) == -1)
- ret = 1;
- else
- ret = 0;
- } else if (xmlXPathIsInf(arg2->floatval) == 1) {
- if (xmlXPathIsInf(arg1->floatval) == 1)
- ret = 1;
- else
- ret = 0;
- } else if (xmlXPathIsInf(arg2->floatval) == -1) {
- if (xmlXPathIsInf(arg1->floatval) == -1)
- ret = 1;
- else
- ret = 0;
- } else {
- ret = (arg1->floatval == arg2->floatval);
- }
- break;
- case XPATH_USERS:
- case XPATH_POINT:
- case XPATH_RANGE:
- case XPATH_LOCATIONSET:
- TODO
- break;
- case XPATH_NODESET:
- case XPATH_XSLT_TREE:
- break;
- }
- break;
- case XPATH_STRING:
- switch (arg2->type) {
- case XPATH_UNDEFINED:
-#ifdef DEBUG_EXPR
- xmlGenericError(xmlGenericErrorContext,
- "Equal: undefined\n");
-#endif
- break;
- case XPATH_BOOLEAN:
- if ((arg1->stringval == NULL) ||
- (arg1->stringval[0] == 0)) ret = 0;
- else
- ret = 1;
- ret = (arg2->boolval == ret);
- break;
- case XPATH_STRING:
- ret = xmlStrEqual(arg1->stringval, arg2->stringval);
- break;
- case XPATH_NUMBER:
- valuePush(ctxt, arg1);
- xmlXPathNumberFunction(ctxt, 1);
- arg1 = valuePop(ctxt);
- /* Hand check NaN and Infinity equalities */
- if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) {
- ret = 0;
- } else if (xmlXPathIsInf(arg1->floatval) == 1) {
- if (xmlXPathIsInf(arg2->floatval) == 1)
- ret = 1;
- else
- ret = 0;
- } else if (xmlXPathIsInf(arg1->floatval) == -1) {
- if (xmlXPathIsInf(arg2->floatval) == -1)
- ret = 1;
- else
- ret = 0;
- } else if (xmlXPathIsInf(arg2->floatval) == 1) {
- if (xmlXPathIsInf(arg1->floatval) == 1)
- ret = 1;
- else
- ret = 0;
- } else if (xmlXPathIsInf(arg2->floatval) == -1) {
- if (xmlXPathIsInf(arg1->floatval) == -1)
- ret = 1;
- else
- ret = 0;
- } else {
- ret = (arg1->floatval == arg2->floatval);
- }
- break;
- case XPATH_USERS:
- case XPATH_POINT:
- case XPATH_RANGE:
- case XPATH_LOCATIONSET:
- TODO
- break;
- case XPATH_NODESET:
- case XPATH_XSLT_TREE:
- break;
- }
- break;
- case XPATH_USERS:
- case XPATH_POINT:
- case XPATH_RANGE:
- case XPATH_LOCATIONSET:
- TODO
- break;
- case XPATH_NODESET:
- case XPATH_XSLT_TREE:
- break;
- }
- xmlXPathFreeObject(arg1);
- xmlXPathFreeObject(arg2);
- return(ret);
-}
-
-/**
- * xmlXPathEqualValues:
- * @ctxt: the XPath Parser context
- *
- * Implement the equal operation on XPath objects content: @arg1 == @arg2
- *
- * Returns 0 or 1 depending on the results of the test.
- */
-int
-xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
- xmlXPathObjectPtr arg1, arg2, argtmp;
- int ret = 0;
-
- arg2 = valuePop(ctxt);
- arg1 = valuePop(ctxt);
- if ((arg1 == NULL) || (arg2 == NULL)) {
- if (arg1 != NULL)
- xmlXPathFreeObject(arg1);
- else
- xmlXPathFreeObject(arg2);
- XP_ERROR0(XPATH_INVALID_OPERAND);
- }
-
- if (arg1 == arg2) {
-#ifdef DEBUG_EXPR
- xmlGenericError(xmlGenericErrorContext,
- "Equal: by pointer\n");
-#endif
- return(1);
- }
-
- /*
- *If either argument is a nodeset, it's a 'special case'
- */
- if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) ||
- (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) {
- /*
- *Hack it to assure arg1 is the nodeset
- */
- if ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)) {
- argtmp = arg2;
- arg2 = arg1;
- arg1 = argtmp;
- }
- switch (arg2->type) {
- case XPATH_UNDEFINED:
-#ifdef DEBUG_EXPR
- xmlGenericError(xmlGenericErrorContext,
- "Equal: undefined\n");
-#endif
- break;
- case XPATH_NODESET:
- case XPATH_XSLT_TREE:
- ret = xmlXPathEqualNodeSets(arg1, arg2, 0);
- break;
- case XPATH_BOOLEAN:
- if ((arg1->nodesetval == NULL) ||
- (arg1->nodesetval->nodeNr == 0)) ret = 0;
- else
- ret = 1;
- ret = (ret == arg2->boolval);
- break;
- case XPATH_NUMBER:
- ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 0);
- break;
- case XPATH_STRING:
- ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval, 0);
- break;
- case XPATH_USERS:
- case XPATH_POINT:
- case XPATH_RANGE:
- case XPATH_LOCATIONSET:
- TODO
- break;
- }
- xmlXPathFreeObject(arg1);
- xmlXPathFreeObject(arg2);
- return(ret);
- }
-
- return (xmlXPathEqualValuesCommon(ctxt, arg1, arg2));
-}
-
-/**
- * xmlXPathNotEqualValues:
- * @ctxt: the XPath Parser context
- *
- * Implement the equal operation on XPath objects content: @arg1 == @arg2
- *
- * Returns 0 or 1 depending on the results of the test.
- */
-int
-xmlXPathNotEqualValues(xmlXPathParserContextPtr ctxt) {
- xmlXPathObjectPtr arg1, arg2, argtmp;
- int ret = 0;
-
- arg2 = valuePop(ctxt);
- arg1 = valuePop(ctxt);
- if ((arg1 == NULL) || (arg2 == NULL)) {
- if (arg1 != NULL)
- xmlXPathFreeObject(arg1);
- else
- xmlXPathFreeObject(arg2);
- XP_ERROR0(XPATH_INVALID_OPERAND);
- }
-
- if (arg1 == arg2) {
-#ifdef DEBUG_EXPR
- xmlGenericError(xmlGenericErrorContext,
- "NotEqual: by pointer\n");
-#endif
- return(0);
- }
-
- /*
- *If either argument is a nodeset, it's a 'special case'
- */
- if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) ||
- (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) {
- /*
- *Hack it to assure arg1 is the nodeset
- */
- if ((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)) {
- argtmp = arg2;
- arg2 = arg1;
- arg1 = argtmp;
- }
- switch (arg2->type) {
- case XPATH_UNDEFINED:
-#ifdef DEBUG_EXPR
- xmlGenericError(xmlGenericErrorContext,
- "NotEqual: undefined\n");
-#endif
- break;
- case XPATH_NODESET:
- case XPATH_XSLT_TREE:
- ret = xmlXPathEqualNodeSets(arg1, arg2, 1);
- break;
- case XPATH_BOOLEAN:
- if ((arg1->nodesetval == NULL) ||
- (arg1->nodesetval->nodeNr == 0)) ret = 0;
- else
- ret = 1;
- ret = (ret != arg2->boolval);
- break;
- case XPATH_NUMBER:
- ret = xmlXPathEqualNodeSetFloat(ctxt, arg1, arg2->floatval, 1);
- break;
- case XPATH_STRING:
- ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval,1);
- break;
- case XPATH_USERS:
- case XPATH_POINT:
- case XPATH_RANGE:
- case XPATH_LOCATIONSET:
- TODO
- break;
- }
- xmlXPathFreeObject(arg1);
- xmlXPathFreeObject(arg2);
- return(ret);
- }
-
- return (!xmlXPathEqualValuesCommon(ctxt, arg1, arg2));
-}
-
-/**
- * xmlXPathCompareValues:
- * @ctxt: the XPath Parser context
- * @inf: less than (1) or greater than (0)
- * @strict: is the comparison strict
- *
- * Implement the compare operation on XPath objects:
- * @arg1 < @arg2 (1, 1, ...
- * @arg1 <= @arg2 (1, 0, ...
- * @arg1 > @arg2 (0, 1, ...
- * @arg1 >= @arg2 (0, 0, ...
- *
- * When neither object to be compared is a node-set and the operator is
- * <=, <, >=, >, then the objects are compared by converted both objects
- * to numbers and comparing the numbers according to IEEE 754. The <
- * comparison will be true if and only if the first number is less than the
- * second number. The <= comparison will be true if and only if the first
- * number is less than or equal to the second number. The > comparison
- * will be true if and only if the first number is greater than the second
- * number. The >= comparison will be true if and only if the first number
- * is greater than or equal to the second number.
- *
- * Returns 1 if the comparison succeeded, 0 if it failed
- */
-int
-xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) {
- int ret = 0, arg1i = 0, arg2i = 0;
- xmlXPathObjectPtr arg1, arg2;
-
- arg2 = valuePop(ctxt);
- arg1 = valuePop(ctxt);
- if ((arg1 == NULL) || (arg2 == NULL)) {
- if (arg1 != NULL)
- xmlXPathFreeObject(arg1);
- else
- xmlXPathFreeObject(arg2);
- XP_ERROR0(XPATH_INVALID_OPERAND);
- }
-
- if ((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE) ||
- (arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) {
- if (((arg2->type == XPATH_NODESET) || (arg2->type == XPATH_XSLT_TREE)) &&
- ((arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE))){
- ret = xmlXPathCompareNodeSets(inf, strict, arg1, arg2);
- } else {
- if ((arg1->type == XPATH_NODESET) || (arg1->type == XPATH_XSLT_TREE)) {
- ret = xmlXPathCompareNodeSetValue(ctxt, inf, strict,
- arg1, arg2);
- } else {
- ret = xmlXPathCompareNodeSetValue(ctxt, !inf, strict,
- arg2, arg1);
- }
- }
- return(ret);
- }
-
- if (arg1->type != XPATH_NUMBER) {
- valuePush(ctxt, arg1);
- xmlXPathNumberFunction(ctxt, 1);
- arg1 = valuePop(ctxt);
- }
- if (arg1->type != XPATH_NUMBER) {
- xmlXPathFreeObject(arg1);
- xmlXPathFreeObject(arg2);
- XP_ERROR0(XPATH_INVALID_OPERAND);
- }
- if (arg2->type != XPATH_NUMBER) {
- valuePush(ctxt, arg2);
- xmlXPathNumberFunction(ctxt, 1);
- arg2 = valuePop(ctxt);
- }
- if (arg2->type != XPATH_NUMBER) {
- xmlXPathFreeObject(arg1);
- xmlXPathFreeObject(arg2);
- XP_ERROR0(XPATH_INVALID_OPERAND);
- }
- /*
- * Add tests for infinity and nan
- * => feedback on 3.4 for Inf and NaN
- */
- /* Hand check NaN and Infinity comparisons */
- if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) {
- ret=0;
- } else {
- arg1i=xmlXPathIsInf(arg1->floatval);
- arg2i=xmlXPathIsInf(arg2->floatval);
- if (inf && strict) {
- if ((arg1i == -1 && arg2i != -1) ||
- (arg2i == 1 && arg1i != 1)) {
- ret = 1;
- } else if (arg1i == 0 && arg2i == 0) {
- ret = (arg1->floatval < arg2->floatval);
- } else {
- ret = 0;
- }
- }
- else if (inf && !strict) {
- if (arg1i == -1 || arg2i == 1) {
- ret = 1;
- } else if (arg1i == 0 && arg2i == 0) {
- ret = (arg1->floatval <= arg2->floatval);
- } else {
- ret = 0;
- }
- }
- else if (!inf && strict) {
- if ((arg1i == 1 && arg2i != 1) ||
- (arg2i == -1 && arg1i != -1)) {
- ret = 1;
- } else if (arg1i == 0 && arg2i == 0) {
- ret = (arg1->floatval > arg2->floatval);
- } else {
- ret = 0;
- }
- }
- else if (!inf && !strict) {
- if (arg1i == 1 || arg2i == -1) {
- ret = 1;
- } else if (arg1i == 0 && arg2i == 0) {
- ret = (arg1->floatval >= arg2->floatval);
- } else {
- ret = 0;
- }
- }
- }
- xmlXPathFreeObject(arg1);
- xmlXPathFreeObject(arg2);
- return(ret);
-}
-
-/**
- * xmlXPathValueFlipSign:
- * @ctxt: the XPath Parser context
- *
- * Implement the unary - operation on an XPath object
- * The numeric operators convert their operands to numbers as if
- * by calling the number function.
- */
-void
-xmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt) {
- CAST_TO_NUMBER;
- CHECK_TYPE(XPATH_NUMBER);
- if (xmlXPathIsNaN(ctxt->value->floatval))
- ctxt->value->floatval=xmlXPathNAN;
- else if (xmlXPathIsInf(ctxt->value->floatval) == 1)
- ctxt->value->floatval=xmlXPathNINF;
- else if (xmlXPathIsInf(ctxt->value->floatval) == -1)
- ctxt->value->floatval=xmlXPathPINF;
- else if (ctxt->value->floatval == 0) {
- if (xmlXPathGetSign(ctxt->value->floatval) == 0)
- ctxt->value->floatval = xmlXPathNZERO;
- else
- ctxt->value->floatval = 0;
- }
- else
- ctxt->value->floatval = - ctxt->value->floatval;
-}
-
-/**
- * xmlXPathAddValues:
- * @ctxt: the XPath Parser context
- *
- * Implement the add operation on XPath objects:
- * The numeric operators convert their operands to numbers as if
- * by calling the number function.
- */
-void
-xmlXPathAddValues(xmlXPathParserContextPtr ctxt) {
- xmlXPathObjectPtr arg;
- double val;
-
- arg = valuePop(ctxt);
- if (arg == NULL)
- XP_ERROR(XPATH_INVALID_OPERAND);
- val = xmlXPathCastToNumber(arg);
- xmlXPathFreeObject(arg);
-
- CAST_TO_NUMBER;
- CHECK_TYPE(XPATH_NUMBER);
- ctxt->value->floatval += val;
-}
-
-/**
- * xmlXPathSubValues:
- * @ctxt: the XPath Parser context
- *
- * Implement the subtraction operation on XPath objects:
- * The numeric operators convert their operands to numbers as if
- * by calling the number function.
- */
-void
-xmlXPathSubValues(xmlXPathParserContextPtr ctxt) {
- xmlXPathObjectPtr arg;
- double val;
-
- arg = valuePop(ctxt);
- if (arg == NULL)
- XP_ERROR(XPATH_INVALID_OPERAND);
- val = xmlXPathCastToNumber(arg);
- xmlXPathFreeObject(arg);
-
- CAST_TO_NUMBER;
- CHECK_TYPE(XPATH_NUMBER);
- ctxt->value->floatval -= val;
-}
-
-/**
- * xmlXPathMultValues:
- * @ctxt: the XPath Parser context
- *
- * Implement the multiply operation on XPath objects:
- * The numeric operators convert their operands to numbers as if
- * by calling the number function.
- */
-void
-xmlXPathMultValues(xmlXPathParserContextPtr ctxt) {
- xmlXPathObjectPtr arg;
- double val;
-
- arg = valuePop(ctxt);
- if (arg == NULL)
- XP_ERROR(XPATH_INVALID_OPERAND);
- val = xmlXPathCastToNumber(arg);
- xmlXPathFreeObject(arg);
-
- CAST_TO_NUMBER;
- CHECK_TYPE(XPATH_NUMBER);
- ctxt->value->floatval *= val;
-}
-
-/**
- * xmlXPathDivValues:
- * @ctxt: the XPath Parser context
- *
- * Implement the div operation on XPath objects @arg1 / @arg2:
- * The numeric operators convert their operands to numbers as if
- * by calling the number function.
- */
-void
-xmlXPathDivValues(xmlXPathParserContextPtr ctxt) {
- xmlXPathObjectPtr arg;
- double val;
-
- arg = valuePop(ctxt);
- if (arg == NULL)
- XP_ERROR(XPATH_INVALID_OPERAND);
- val = xmlXPathCastToNumber(arg);
- xmlXPathFreeObject(arg);
-
- CAST_TO_NUMBER;
- CHECK_TYPE(XPATH_NUMBER);
- if (xmlXPathIsNaN(val) || xmlXPathIsNaN(ctxt->value->floatval))
- ctxt->value->floatval = xmlXPathNAN;
- else if (val == 0 && xmlXPathGetSign(val) != 0) {
- if (ctxt->value->floatval == 0)
- ctxt->value->floatval = xmlXPathNAN;
- else if (ctxt->value->floatval > 0)
- ctxt->value->floatval = xmlXPathNINF;
- else if (ctxt->value->floatval < 0)
- ctxt->value->floatval = xmlXPathPINF;
- }
- else if (val == 0) {
- if (ctxt->value->floatval == 0)
- ctxt->value->floatval = xmlXPathNAN;
- else if (ctxt->value->floatval > 0)
- ctxt->value->floatval = xmlXPathPINF;
- else if (ctxt->value->floatval < 0)
- ctxt->value->floatval = xmlXPathNINF;
- } else
- ctxt->value->floatval /= val;
-}
-
-/**
- * xmlXPathModValues:
- * @ctxt: the XPath Parser context
- *
- * Implement the mod operation on XPath objects: @arg1 / @arg2
- * The numeric operators convert their operands to numbers as if
- * by calling the number function.
- */
-void
-xmlXPathModValues(xmlXPathParserContextPtr ctxt) {
- xmlXPathObjectPtr arg;
- double arg1, arg2;
-
- arg = valuePop(ctxt);
- if (arg == NULL)
- XP_ERROR(XPATH_INVALID_OPERAND);
- arg2 = xmlXPathCastToNumber(arg);
- xmlXPathFreeObject(arg);
-
- CAST_TO_NUMBER;
- CHECK_TYPE(XPATH_NUMBER);
- arg1 = ctxt->value->floatval;
- if (arg2 == 0)
- ctxt->value->floatval = xmlXPathNAN;
- else {
- ctxt->value->floatval = fmod(arg1, arg2);
- }
-}
-
-/************************************************************************
- * *
- * The traversal functions *
- * *
- ************************************************************************/
-
-/*
- * A traversal function enumerates nodes along an axis.
- * Initially it must be called with NULL, and it indicates
- * termination on the axis by returning NULL.
- */
-typedef xmlNodePtr (*xmlXPathTraversalFunction)
- (xmlXPathParserContextPtr ctxt, xmlNodePtr cur);
-
-/**
- * xmlXPathNextSelf:
- * @ctxt: the XPath Parser context
- * @cur: the current node in the traversal
- *
- * Traversal function for the "self" direction
- * The self axis contains just the context node itself
- *
- * Returns the next element following that axis
- */
-xmlNodePtr
-xmlXPathNextSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
- if (cur == NULL)
- return(ctxt->context->node);
- return(NULL);
-}
-
-/**
- * xmlXPathNextChild:
- * @ctxt: the XPath Parser context
- * @cur: the current node in the traversal
- *
- * Traversal function for the "child" direction
- * The child axis contains the children of the context node in document order.
- *
- * Returns the next element following that axis
- */
-xmlNodePtr
-xmlXPathNextChild(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
- if (cur == NULL) {
- if (ctxt->context->node == NULL) return(NULL);
- switch (ctxt->context->node->type) {
- case XML_ELEMENT_NODE:
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- case XML_NOTATION_NODE:
- case XML_DTD_NODE:
- return(ctxt->context->node->children);
- case XML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_HTML_DOCUMENT_NODE:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- return(((xmlDocPtr) ctxt->context->node)->children);
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_ATTRIBUTE_NODE:
- case XML_NAMESPACE_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- return(NULL);
- }
- return(NULL);
- }
- if ((cur->type == XML_DOCUMENT_NODE) ||
- (cur->type == XML_HTML_DOCUMENT_NODE))
- return(NULL);
- return(cur->next);
-}
-
-/**
- * xmlXPathNextDescendant:
- * @ctxt: the XPath Parser context
- * @cur: the current node in the traversal
- *
- * Traversal function for the "descendant" direction
- * the descendant axis contains the descendants of the context node in document
- * order; a descendant is a child or a child of a child and so on.
- *
- * Returns the next element following that axis
- */
-xmlNodePtr
-xmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
- if (cur == NULL) {
- if (ctxt->context->node == NULL)
- return(NULL);
- if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
- (ctxt->context->node->type == XML_NAMESPACE_DECL))
- return(NULL);
-
- if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
- return(ctxt->context->doc->children);
- return(ctxt->context->node->children);
- }
-
- if (cur->children != NULL) {
- /*
- * Do not descend on entities declarations
- */
- if (cur->children->type != XML_ENTITY_DECL) {
- cur = cur->children;
- /*
- * Skip DTDs
- */
- if (cur->type != XML_DTD_NODE)
- return(cur);
- }
- }
-
- if (cur == ctxt->context->node) return(NULL);
-
- while (cur->next != NULL) {
- cur = cur->next;
- if ((cur->type != XML_ENTITY_DECL) &&
- (cur->type != XML_DTD_NODE))
- return(cur);
- }
-
- do {
- cur = cur->parent;
- if (cur == NULL) return(NULL);
- if (cur == ctxt->context->node) return(NULL);
- if (cur->next != NULL) {
- cur = cur->next;
- return(cur);
- }
- } while (cur != NULL);
- return(cur);
-}
-
-/**
- * xmlXPathNextDescendantOrSelf:
- * @ctxt: the XPath Parser context
- * @cur: the current node in the traversal
- *
- * Traversal function for the "descendant-or-self" direction
- * the descendant-or-self axis contains the context node and the descendants
- * of the context node in document order; thus the context node is the first
- * node on the axis, and the first child of the context node is the second node
- * on the axis
- *
- * Returns the next element following that axis
- */
-xmlNodePtr
-xmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
- if (cur == NULL) {
- if (ctxt->context->node == NULL)
- return(NULL);
- if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
- (ctxt->context->node->type == XML_NAMESPACE_DECL))
- return(NULL);
- return(ctxt->context->node);
- }
-
- return(xmlXPathNextDescendant(ctxt, cur));
-}
-
-/**
- * xmlXPathNextParent:
- * @ctxt: the XPath Parser context
- * @cur: the current node in the traversal
- *
- * Traversal function for the "parent" direction
- * The parent axis contains the parent of the context node, if there is one.
- *
- * Returns the next element following that axis
- */
-xmlNodePtr
-xmlXPathNextParent(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
- /*
- * the parent of an attribute or namespace node is the element
- * to which the attribute or namespace node is attached
- * Namespace handling !!!
- */
- if (cur == NULL) {
- if (ctxt->context->node == NULL) return(NULL);
- switch (ctxt->context->node->type) {
- case XML_ELEMENT_NODE:
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- case XML_NOTATION_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- case XML_ENTITY_DECL:
- if (ctxt->context->node->parent == NULL)
- return((xmlNodePtr) ctxt->context->doc);
- return(ctxt->context->node->parent);
- case XML_ATTRIBUTE_NODE: {
- xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node;
-
- return(att->parent);
- }
- case XML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_HTML_DOCUMENT_NODE:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- return(NULL);
- case XML_NAMESPACE_DECL: {
- xmlNsPtr ns = (xmlNsPtr) ctxt->context->node;
-
- if ((ns->next != NULL) &&
- (ns->next->type != XML_NAMESPACE_DECL))
- return((xmlNodePtr) ns->next);
- return(NULL);
- }
- }
- }
- return(NULL);
-}
-
-/**
- * xmlXPathNextAncestor:
- * @ctxt: the XPath Parser context
- * @cur: the current node in the traversal
- *
- * Traversal function for the "ancestor" direction
- * the ancestor axis contains the ancestors of the context node; the ancestors
- * of the context node consist of the parent of context node and the parent's
- * parent and so on; the nodes are ordered in reverse document order; thus the
- * parent is the first node on the axis, and the parent's parent is the second
- * node on the axis
- *
- * Returns the next element following that axis
- */
-xmlNodePtr
-xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
- /*
- * the parent of an attribute or namespace node is the element
- * to which the attribute or namespace node is attached
- * !!!!!!!!!!!!!
- */
- if (cur == NULL) {
- if (ctxt->context->node == NULL) return(NULL);
- switch (ctxt->context->node->type) {
- case XML_ELEMENT_NODE:
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_NOTATION_NODE:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- if (ctxt->context->node->parent == NULL)
- return((xmlNodePtr) ctxt->context->doc);
- return(ctxt->context->node->parent);
- case XML_ATTRIBUTE_NODE: {
- xmlAttrPtr tmp = (xmlAttrPtr) ctxt->context->node;
-
- return(tmp->parent);
- }
- case XML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_HTML_DOCUMENT_NODE:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- return(NULL);
- case XML_NAMESPACE_DECL: {
- xmlNsPtr ns = (xmlNsPtr) ctxt->context->node;
-
- if ((ns->next != NULL) &&
- (ns->next->type != XML_NAMESPACE_DECL))
- return((xmlNodePtr) ns->next);
- /* Bad, how did that namespace ended-up there ? */
- return(NULL);
- }
- }
- return(NULL);
- }
- if (cur == ctxt->context->doc->children)
- return((xmlNodePtr) ctxt->context->doc);
- if (cur == (xmlNodePtr) ctxt->context->doc)
- return(NULL);
- switch (cur->type) {
- case XML_ELEMENT_NODE:
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_ENTITY_NODE:
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- case XML_NOTATION_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- return(cur->parent);
- case XML_ATTRIBUTE_NODE: {
- xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node;
-
- return(att->parent);
- }
- case XML_NAMESPACE_DECL: {
- xmlNsPtr ns = (xmlNsPtr) ctxt->context->node;
-
- if ((ns->next != NULL) &&
- (ns->next->type != XML_NAMESPACE_DECL))
- return((xmlNodePtr) ns->next);
- /* Bad, how did that namespace ended-up there ? */
- return(NULL);
- }
- case XML_DOCUMENT_NODE:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_HTML_DOCUMENT_NODE:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- return(NULL);
- }
- return(NULL);
-}
-
-/**
- * xmlXPathNextAncestorOrSelf:
- * @ctxt: the XPath Parser context
- * @cur: the current node in the traversal
- *
- * Traversal function for the "ancestor-or-self" direction
- * he ancestor-or-self axis contains the context node and ancestors of
- * the context node in reverse document order; thus the context node is
- * the first node on the axis, and the context node's parent the second;
- * parent here is defined the same as with the parent axis.
- *
- * Returns the next element following that axis
- */
-xmlNodePtr
-xmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
- if (cur == NULL)
- return(ctxt->context->node);
- return(xmlXPathNextAncestor(ctxt, cur));
-}
-
-/**
- * xmlXPathNextFollowingSibling:
- * @ctxt: the XPath Parser context
- * @cur: the current node in the traversal
- *
- * Traversal function for the "following-sibling" direction
- * The following-sibling axis contains the following siblings of the context
- * node in document order.
- *
- * Returns the next element following that axis
- */
-xmlNodePtr
-xmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
- if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
- (ctxt->context->node->type == XML_NAMESPACE_DECL))
- return(NULL);
- if (cur == (xmlNodePtr) ctxt->context->doc)
- return(NULL);
- if (cur == NULL)
- return(ctxt->context->node->next);
- return(cur->next);
-}
-
-/**
- * xmlXPathNextPrecedingSibling:
- * @ctxt: the XPath Parser context
- * @cur: the current node in the traversal
- *
- * Traversal function for the "preceding-sibling" direction
- * The preceding-sibling axis contains the preceding siblings of the context
- * node in reverse document order; the first preceding sibling is first on the
- * axis; the sibling preceding that node is the second on the axis and so on.
- *
- * Returns the next element following that axis
- */
-xmlNodePtr
-xmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
- if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
- (ctxt->context->node->type == XML_NAMESPACE_DECL))
- return(NULL);
- if (cur == (xmlNodePtr) ctxt->context->doc)
- return(NULL);
- if (cur == NULL)
- return(ctxt->context->node->prev);
- if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE)) {
- cur = cur->prev;
- if (cur == NULL)
- return(ctxt->context->node->prev);
- }
- return(cur->prev);
-}
-
-/**
- * xmlXPathNextFollowing:
- * @ctxt: the XPath Parser context
- * @cur: the current node in the traversal
- *
- * Traversal function for the "following" direction
- * The following axis contains all nodes in the same document as the context
- * node that are after the context node in document order, excluding any
- * descendants and excluding attribute nodes and namespace nodes; the nodes
- * are ordered in document order
- *
- * Returns the next element following that axis
- */
-xmlNodePtr
-xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
- if (cur != NULL && cur->children != NULL)
- return cur->children ;
- if (cur == NULL) cur = ctxt->context->node;
- if (cur == NULL) return(NULL) ; /* ERROR */
- if (cur->next != NULL) return(cur->next) ;
- do {
- cur = cur->parent;
- if (cur == NULL) return(NULL);
- if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL);
- if (cur->next != NULL) return(cur->next);
- } while (cur != NULL);
- return(cur);
-}
-
-/*
- * xmlXPathIsAncestor:
- * @ancestor: the ancestor node
- * @node: the current node
- *
- * Check that @ancestor is a @node's ancestor
- *
- * returns 1 if @ancestor is a @node's ancestor, 0 otherwise.
- */
-static int
-xmlXPathIsAncestor(xmlNodePtr ancestor, xmlNodePtr node) {
- if ((ancestor == NULL) || (node == NULL)) return(0);
- /* nodes need to be in the same document */
- if (ancestor->doc != node->doc) return(0);
- /* avoid searching if ancestor or node is the root node */
- if (ancestor == (xmlNodePtr) node->doc) return(1);
- if (node == (xmlNodePtr) ancestor->doc) return(0);
- while (node->parent != NULL) {
- if (node->parent == ancestor)
- return(1);
- node = node->parent;
- }
- return(0);
-}
-
-/**
- * xmlXPathNextPreceding:
- * @ctxt: the XPath Parser context
- * @cur: the current node in the traversal
- *
- * Traversal function for the "preceding" direction
- * the preceding axis contains all nodes in the same document as the context
- * node that are before the context node in document order, excluding any
- * ancestors and excluding attribute nodes and namespace nodes; the nodes are
- * ordered in reverse document order
- *
- * Returns the next element following that axis
- */
-xmlNodePtr
-xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur)
-{
- if (cur == NULL)
- cur = ctxt->context->node;
- if (cur == NULL)
- return (NULL);
- if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))
- cur = cur->prev;
- do {
- if (cur->prev != NULL) {
- for (cur = cur->prev; cur->last != NULL; cur = cur->last) ;
- return (cur);
- }
-
- cur = cur->parent;
- if (cur == NULL)
- return (NULL);
- if (cur == ctxt->context->doc->children)
- return (NULL);
- } while (xmlXPathIsAncestor(cur, ctxt->context->node));
- return (cur);
-}
-
-/**
- * xmlXPathNextPrecedingInternal:
- * @ctxt: the XPath Parser context
- * @cur: the current node in the traversal
- *
- * Traversal function for the "preceding" direction
- * the preceding axis contains all nodes in the same document as the context
- * node that are before the context node in document order, excluding any
- * ancestors and excluding attribute nodes and namespace nodes; the nodes are
- * ordered in reverse document order
- * This is a faster implementation but internal only since it requires a
- * state kept in the parser context: ctxt->ancestor.
- *
- * Returns the next element following that axis
- */
-static xmlNodePtr
-xmlXPathNextPrecedingInternal(xmlXPathParserContextPtr ctxt,
- xmlNodePtr cur)
-{
- if (cur == NULL) {
- cur = ctxt->context->node;
- if (cur == NULL)
- return (NULL);
- ctxt->ancestor = cur->parent;
- }
- if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))
- cur = cur->prev;
- while (cur->prev == NULL) {
- cur = cur->parent;
- if (cur == NULL)
- return (NULL);
- if (cur == ctxt->context->doc->children)
- return (NULL);
- if (cur != ctxt->ancestor)
- return (cur);
- ctxt->ancestor = cur->parent;
- }
- cur = cur->prev;
- while (cur->last != NULL)
- cur = cur->last;
- return (cur);
-}
-
-/**
- * xmlXPathNextNamespace:
- * @ctxt: the XPath Parser context
- * @cur: the current attribute in the traversal
- *
- * Traversal function for the "namespace" direction
- * the namespace axis contains the namespace nodes of the context node;
- * the order of nodes on this axis is implementation-defined; the axis will
- * be empty unless the context node is an element
- *
- * We keep the XML namespace node at the end of the list.
- *
- * Returns the next element following that axis
- */
-xmlNodePtr
-xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
- if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL);
- if (ctxt->context->tmpNsList == NULL && cur != (xmlNodePtr) xmlXPathXMLNamespace) {
- if (ctxt->context->tmpNsList != NULL)
- xmlFree(ctxt->context->tmpNsList);
- ctxt->context->tmpNsList =
- xmlGetNsList(ctxt->context->doc, ctxt->context->node);
- ctxt->context->tmpNsNr = 0;
- if (ctxt->context->tmpNsList != NULL) {
- while (ctxt->context->tmpNsList[ctxt->context->tmpNsNr] != NULL) {
- ctxt->context->tmpNsNr++;
- }
- }
- return((xmlNodePtr) xmlXPathXMLNamespace);
- }
- if (ctxt->context->tmpNsNr > 0) {
- return (xmlNodePtr)ctxt->context->tmpNsList[--ctxt->context->tmpNsNr];
- } else {
- if (ctxt->context->tmpNsList != NULL)
- xmlFree(ctxt->context->tmpNsList);
- ctxt->context->tmpNsList = NULL;
- return(NULL);
- }
-}
-
-/**
- * xmlXPathNextAttribute:
- * @ctxt: the XPath Parser context
- * @cur: the current attribute in the traversal
- *
- * Traversal function for the "attribute" direction
- * TODO: support DTD inherited default attributes
- *
- * Returns the next element following that axis
- */
-xmlNodePtr
-xmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
- if (ctxt->context->node == NULL)
- return(NULL);
- if (ctxt->context->node->type != XML_ELEMENT_NODE)
- return(NULL);
- if (cur == NULL) {
- if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
- return(NULL);
- return((xmlNodePtr)ctxt->context->node->properties);
- }
- return((xmlNodePtr)cur->next);
-}
-
-/************************************************************************
- * *
- * NodeTest Functions *
- * *
- ************************************************************************/
-
-#define IS_FUNCTION 200
-
-
-/************************************************************************
- * *
- * Implicit tree core function library *
- * *
- ************************************************************************/
-
-/**
- * xmlXPathRoot:
- * @ctxt: the XPath Parser context
- *
- * Initialize the context to the root of the document
- */
-void
-xmlXPathRoot(xmlXPathParserContextPtr ctxt) {
- ctxt->context->node = (xmlNodePtr) ctxt->context->doc;
- valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
-}
-
-/************************************************************************
- * *
- * The explicit core function library *
- *http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html#corelib *
- * *
- ************************************************************************/
-
-
-/**
- * xmlXPathLastFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the last() XPath function
- * number last()
- * The last function returns the number of nodes in the context node list.
- */
-void
-xmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- CHECK_ARITY(0);
- if (ctxt->context->contextSize >= 0) {
- valuePush(ctxt, xmlXPathNewFloat((double) ctxt->context->contextSize));
-#ifdef DEBUG_EXPR
- xmlGenericError(xmlGenericErrorContext,
- "last() : %d\n", ctxt->context->contextSize);
-#endif
- } else {
- XP_ERROR(XPATH_INVALID_CTXT_SIZE);
- }
-}
-
-/**
- * xmlXPathPositionFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the position() XPath function
- * number position()
- * The position function returns the position of the context node in the
- * context node list. The first position is 1, and so the last position
- * will be equal to last().
- */
-void
-xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- CHECK_ARITY(0);
- if (ctxt->context->proximityPosition >= 0) {
- valuePush(ctxt,
- xmlXPathNewFloat((double) ctxt->context->proximityPosition));
-#ifdef DEBUG_EXPR
- xmlGenericError(xmlGenericErrorContext, "position() : %d\n",
- ctxt->context->proximityPosition);
-#endif
- } else {
- XP_ERROR(XPATH_INVALID_CTXT_POSITION);
- }
-}
-
-/**
- * xmlXPathCountFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the count() XPath function
- * number count(node-set)
- */
-void
-xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr cur;
-
- CHECK_ARITY(1);
- if ((ctxt->value == NULL) ||
- ((ctxt->value->type != XPATH_NODESET) &&
- (ctxt->value->type != XPATH_XSLT_TREE)))
- XP_ERROR(XPATH_INVALID_TYPE);
- cur = valuePop(ctxt);
-
- if ((cur == NULL) || (cur->nodesetval == NULL))
- valuePush(ctxt, xmlXPathNewFloat((double) 0));
- else if ((cur->type == XPATH_NODESET) || (cur->type == XPATH_XSLT_TREE)) {
- valuePush(ctxt, xmlXPathNewFloat((double) cur->nodesetval->nodeNr));
- } else {
- if ((cur->nodesetval->nodeNr != 1) ||
- (cur->nodesetval->nodeTab == NULL)) {
- valuePush(ctxt, xmlXPathNewFloat((double) 0));
- } else {
- xmlNodePtr tmp;
- int i = 0;
-
- tmp = cur->nodesetval->nodeTab[0];
- if (tmp != NULL) {
- tmp = tmp->children;
- while (tmp != NULL) {
- tmp = tmp->next;
- i++;
- }
- }
- valuePush(ctxt, xmlXPathNewFloat((double) i));
- }
- }
- xmlXPathFreeObject(cur);
-}
-
-/**
- * xmlXPathGetElementsByIds:
- * @doc: the document
- * @ids: a whitespace separated list of IDs
- *
- * Selects elements by their unique ID.
- *
- * Returns a node-set of selected elements.
- */
-static xmlNodeSetPtr
-xmlXPathGetElementsByIds (xmlDocPtr doc, const xmlChar *ids) {
- xmlNodeSetPtr ret;
- const xmlChar *cur = ids;
- xmlChar *ID;
- xmlAttrPtr attr;
- xmlNodePtr elem = NULL;
-
- ret = xmlXPathNodeSetCreate(NULL);
-
- while (IS_BLANK(*cur)) cur++;
- while (*cur != 0) {
- while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
- (*cur == '.') || (*cur == '-') ||
- (*cur == '_') || (*cur == ':') ||
- (IS_COMBINING(*cur)) ||
- (IS_EXTENDER(*cur)))
- cur++;
-
- if ((!IS_BLANK(*cur)) && (*cur != 0)) break;
-
- ID = xmlStrndup(ids, cur - ids);
- attr = xmlGetID(doc, ID);
- if (attr != NULL) {
- elem = attr->parent;
- xmlXPathNodeSetAdd(ret, elem);
- }
- if (ID != NULL)
- xmlFree(ID);
-
- while (IS_BLANK(*cur)) cur++;
- ids = cur;
- }
- return(ret);
-}
-
-/**
- * xmlXPathIdFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the id() XPath function
- * node-set id(object)
- * The id function selects elements by their unique ID
- * (see [5.2.1 Unique IDs]). When the argument to id is of type node-set,
- * then the result is the union of the result of applying id to the
- * string value of each of the nodes in the argument node-set. When the
- * argument to id is of any other type, the argument is converted to a
- * string as if by a call to the string function; the string is split
- * into a whitespace-separated list of tokens (whitespace is any sequence
- * of characters matching the production S); the result is a node-set
- * containing the elements in the same document as the context node that
- * have a unique ID equal to any of the tokens in the list.
- */
-void
-xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlChar *tokens;
- xmlNodeSetPtr ret;
- xmlXPathObjectPtr obj;
-
- CHECK_ARITY(1);
- obj = valuePop(ctxt);
- if (obj == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
- if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) {
- xmlNodeSetPtr ns;
- int i;
-
- ret = xmlXPathNodeSetCreate(NULL);
-
- if (obj->nodesetval != NULL) {
- for (i = 0; i < obj->nodesetval->nodeNr; i++) {
- tokens =
- xmlXPathCastNodeToString(obj->nodesetval->nodeTab[i]);
- ns = xmlXPathGetElementsByIds(ctxt->context->doc, tokens);
- ret = xmlXPathNodeSetMerge(ret, ns);
- xmlXPathFreeNodeSet(ns);
- if (tokens != NULL)
- xmlFree(tokens);
- }
- }
-
- xmlXPathFreeObject(obj);
- valuePush(ctxt, xmlXPathWrapNodeSet(ret));
- return;
- }
- obj = xmlXPathConvertString(obj);
-
- ret = xmlXPathGetElementsByIds(ctxt->context->doc, obj->stringval);
- valuePush(ctxt, xmlXPathWrapNodeSet(ret));
-
- xmlXPathFreeObject(obj);
- return;
-}
-
-/**
- * xmlXPathLocalNameFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the local-name() XPath function
- * string local-name(node-set?)
- * The local-name function returns a string containing the local part
- * of the name of the node in the argument node-set that is first in
- * document order. If the node-set is empty or the first node has no
- * name, an empty string is returned. If the argument is omitted it
- * defaults to the context node.
- */
-void
-xmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr cur;
-
- if (nargs == 0) {
- valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
- nargs = 1;
- }
-
- CHECK_ARITY(1);
- if ((ctxt->value == NULL) ||
- ((ctxt->value->type != XPATH_NODESET) &&
- (ctxt->value->type != XPATH_XSLT_TREE)))
- XP_ERROR(XPATH_INVALID_TYPE);
- cur = valuePop(ctxt);
-
- if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
- valuePush(ctxt, xmlXPathNewCString(""));
- } else {
- int i = 0; /* Should be first in document order !!!!! */
- switch (cur->nodesetval->nodeTab[i]->type) {
- case XML_ELEMENT_NODE:
- case XML_ATTRIBUTE_NODE:
- case XML_PI_NODE:
- valuePush(ctxt,
- xmlXPathNewString(cur->nodesetval->nodeTab[i]->name));
- break;
- case XML_NAMESPACE_DECL:
- valuePush(ctxt, xmlXPathNewString(
- ((xmlNsPtr)cur->nodesetval->nodeTab[i])->prefix));
- break;
- default:
- valuePush(ctxt, xmlXPathNewCString(""));
- }
- }
- xmlXPathFreeObject(cur);
-}
-
-/**
- * xmlXPathNamespaceURIFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the namespace-uri() XPath function
- * string namespace-uri(node-set?)
- * The namespace-uri function returns a string containing the
- * namespace URI of the expanded name of the node in the argument
- * node-set that is first in document order. If the node-set is empty,
- * the first node has no name, or the expanded name has no namespace
- * URI, an empty string is returned. If the argument is omitted it
- * defaults to the context node.
- */
-void
-xmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr cur;
-
- if (nargs == 0) {
- valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
- nargs = 1;
- }
- CHECK_ARITY(1);
- if ((ctxt->value == NULL) ||
- ((ctxt->value->type != XPATH_NODESET) &&
- (ctxt->value->type != XPATH_XSLT_TREE)))
- XP_ERROR(XPATH_INVALID_TYPE);
- cur = valuePop(ctxt);
-
- if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
- valuePush(ctxt, xmlXPathNewCString(""));
- } else {
- int i = 0; /* Should be first in document order !!!!! */
- switch (cur->nodesetval->nodeTab[i]->type) {
- case XML_ELEMENT_NODE:
- case XML_ATTRIBUTE_NODE:
- if (cur->nodesetval->nodeTab[i]->ns == NULL)
- valuePush(ctxt, xmlXPathNewCString(""));
- else
- valuePush(ctxt, xmlXPathNewString(
- cur->nodesetval->nodeTab[i]->ns->href));
- break;
- default:
- valuePush(ctxt, xmlXPathNewCString(""));
- }
- }
- xmlXPathFreeObject(cur);
-}
-
-/**
- * xmlXPathNameFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the name() XPath function
- * string name(node-set?)
- * The name function returns a string containing a QName representing
- * the name of the node in the argument node-set that is first in document
- * order. The QName must represent the name with respect to the namespace
- * declarations in effect on the node whose name is being represented.
- * Typically, this will be the form in which the name occurred in the XML
- * source. This need not be the case if there are namespace declarations
- * in effect on the node that associate multiple prefixes with the same
- * namespace. However, an implementation may include information about
- * the original prefix in its representation of nodes; in this case, an
- * implementation can ensure that the returned string is always the same
- * as the QName used in the XML source. If the argument it omitted it
- * defaults to the context node.
- * Libxml keep the original prefix so the "real qualified name" used is
- * returned.
- */
-static void
-xmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs)
-{
- xmlXPathObjectPtr cur;
-
- if (nargs == 0) {
- valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
- nargs = 1;
- }
-
- CHECK_ARITY(1);
- if ((ctxt->value == NULL) ||
- ((ctxt->value->type != XPATH_NODESET) &&
- (ctxt->value->type != XPATH_XSLT_TREE)))
- XP_ERROR(XPATH_INVALID_TYPE);
- cur = valuePop(ctxt);
-
- if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
- valuePush(ctxt, xmlXPathNewCString(""));
- } else {
- int i = 0; /* Should be first in document order !!!!! */
-
- switch (cur->nodesetval->nodeTab[i]->type) {
- case XML_ELEMENT_NODE:
- case XML_ATTRIBUTE_NODE:
- if ((cur->nodesetval->nodeTab[i]->ns == NULL) ||
- (cur->nodesetval->nodeTab[i]->ns->prefix == NULL))
- valuePush(ctxt,
- xmlXPathNewString(cur->nodesetval->
- nodeTab[i]->name));
-
- else {
- char name[2000];
-
- snprintf(name, sizeof(name), "%s:%s",
- (char *) cur->nodesetval->nodeTab[i]->ns->
- prefix,
- (char *) cur->nodesetval->nodeTab[i]->name);
- name[sizeof(name) - 1] = 0;
- valuePush(ctxt, xmlXPathNewCString(name));
- }
- break;
- default:
- valuePush(ctxt,
- xmlXPathNewNodeSet(cur->nodesetval->nodeTab[i]));
- xmlXPathLocalNameFunction(ctxt, 1);
- }
- }
- xmlXPathFreeObject(cur);
-}
-
-
-/**
- * xmlXPathStringFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the string() XPath function
- * string string(object?)
- * he string function converts an object to a string as follows:
- * - A node-set is converted to a string by returning the value of
- * the node in the node-set that is first in document order.
- * If the node-set is empty, an empty string is returned.
- * - A number is converted to a string as follows
- * + NaN is converted to the string NaN
- * + positive zero is converted to the string 0
- * + negative zero is converted to the string 0
- * + positive infinity is converted to the string Infinity
- * + negative infinity is converted to the string -Infinity
- * + if the number is an integer, the number is represented in
- * decimal form as a Number with no decimal point and no leading
- * zeros, preceded by a minus sign (-) if the number is negative
- * + otherwise, the number is represented in decimal form as a
- * Number including a decimal point with at least one digit
- * before the decimal point and at least one digit after the
- * decimal point, preceded by a minus sign (-) if the number
- * is negative; there must be no leading zeros before the decimal
- * point apart possibly from the one required digit immediately
- * before the decimal point; beyond the one required digit
- * after the decimal point there must be as many, but only as
- * many, more digits as are needed to uniquely distinguish the
- * number from all other IEEE 754 numeric values.
- * - The boolean false value is converted to the string false.
- * The boolean true value is converted to the string true.
- *
- * If the argument is omitted, it defaults to a node-set with the
- * context node as its only member.
- */
-void
-xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr cur;
-
- if (nargs == 0) {
- valuePush(ctxt,
- xmlXPathWrapString(
- xmlXPathCastNodeToString(ctxt->context->node)));
- return;
- }
-
- CHECK_ARITY(1);
- cur = valuePop(ctxt);
- if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
- cur = xmlXPathConvertString(cur);
- valuePush(ctxt, cur);
-}
-
-/**
- * xmlXPathStringLengthFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the string-length() XPath function
- * number string-length(string?)
- * The string-length returns the number of characters in the string
- * (see [3.6 Strings]). If the argument is omitted, it defaults to
- * the context node converted to a string, in other words the value
- * of the context node.
- */
-void
-xmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr cur;
-
- if (nargs == 0) {
- if (ctxt->context->node == NULL) {
- valuePush(ctxt, xmlXPathNewFloat(0));
- } else {
- xmlChar *content;
-
- content = xmlXPathCastNodeToString(ctxt->context->node);
- valuePush(ctxt, xmlXPathNewFloat(xmlUTF8Strlen(content)));
- xmlFree(content);
- }
- return;
- }
- CHECK_ARITY(1);
- CAST_TO_STRING;
- CHECK_TYPE(XPATH_STRING);
- cur = valuePop(ctxt);
- valuePush(ctxt, xmlXPathNewFloat(xmlUTF8Strlen(cur->stringval)));
- xmlXPathFreeObject(cur);
-}
-
-/**
- * xmlXPathConcatFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the concat() XPath function
- * string concat(string, string, string*)
- * The concat function returns the concatenation of its arguments.
- */
-void
-xmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr cur, newobj;
- xmlChar *tmp;
-
- if (nargs < 2) {
- CHECK_ARITY(2);
- }
-
- CAST_TO_STRING;
- cur = valuePop(ctxt);
- if ((cur == NULL) || (cur->type != XPATH_STRING)) {
- xmlXPathFreeObject(cur);
- return;
- }
- nargs--;
-
- while (nargs > 0) {
- CAST_TO_STRING;
- newobj = valuePop(ctxt);
- if ((newobj == NULL) || (newobj->type != XPATH_STRING)) {
- xmlXPathFreeObject(newobj);
- xmlXPathFreeObject(cur);
- XP_ERROR(XPATH_INVALID_TYPE);
- }
- tmp = xmlStrcat(newobj->stringval, cur->stringval);
- newobj->stringval = cur->stringval;
- cur->stringval = tmp;
-
- xmlXPathFreeObject(newobj);
- nargs--;
- }
- valuePush(ctxt, cur);
-}
-
-/**
- * xmlXPathContainsFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the contains() XPath function
- * boolean contains(string, string)
- * The contains function returns true if the first argument string
- * contains the second argument string, and otherwise returns false.
- */
-void
-xmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr hay, needle;
-
- CHECK_ARITY(2);
- CAST_TO_STRING;
- CHECK_TYPE(XPATH_STRING);
- needle = valuePop(ctxt);
- CAST_TO_STRING;
- hay = valuePop(ctxt);
- if ((hay == NULL) || (hay->type != XPATH_STRING)) {
- xmlXPathFreeObject(hay);
- xmlXPathFreeObject(needle);
- XP_ERROR(XPATH_INVALID_TYPE);
- }
- if (xmlStrstr(hay->stringval, needle->stringval))
- valuePush(ctxt, xmlXPathNewBoolean(1));
- else
- valuePush(ctxt, xmlXPathNewBoolean(0));
- xmlXPathFreeObject(hay);
- xmlXPathFreeObject(needle);
-}
-
-/**
- * xmlXPathStartsWithFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the starts-with() XPath function
- * boolean starts-with(string, string)
- * The starts-with function returns true if the first argument string
- * starts with the second argument string, and otherwise returns false.
- */
-void
-xmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr hay, needle;
- int n;
-
- CHECK_ARITY(2);
- CAST_TO_STRING;
- CHECK_TYPE(XPATH_STRING);
- needle = valuePop(ctxt);
- CAST_TO_STRING;
- hay = valuePop(ctxt);
- if ((hay == NULL) || (hay->type != XPATH_STRING)) {
- xmlXPathFreeObject(hay);
- xmlXPathFreeObject(needle);
- XP_ERROR(XPATH_INVALID_TYPE);
- }
- n = xmlStrlen(needle->stringval);
- if (xmlStrncmp(hay->stringval, needle->stringval, n))
- valuePush(ctxt, xmlXPathNewBoolean(0));
- else
- valuePush(ctxt, xmlXPathNewBoolean(1));
- xmlXPathFreeObject(hay);
- xmlXPathFreeObject(needle);
-}
-
-/**
- * xmlXPathSubstringFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the substring() XPath function
- * string substring(string, number, number?)
- * The substring function returns the substring of the first argument
- * starting at the position specified in the second argument with
- * length specified in the third argument. For example,
- * substring("12345",2,3) returns "234". If the third argument is not
- * specified, it returns the substring starting at the position specified
- * in the second argument and continuing to the end of the string. For
- * example, substring("12345",2) returns "2345". More precisely, each
- * character in the string (see [3.6 Strings]) is considered to have a
- * numeric position: the position of the first character is 1, the position
- * of the second character is 2 and so on. The returned substring contains
- * those characters for which the position of the character is greater than
- * or equal to the second argument and, if the third argument is specified,
- * less than the sum of the second and third arguments; the comparisons
- * and addition used for the above follow the standard IEEE 754 rules. Thus:
- * - substring("12345", 1.5, 2.6) returns "234"
- * - substring("12345", 0, 3) returns "12"
- * - substring("12345", 0 div 0, 3) returns ""
- * - substring("12345", 1, 0 div 0) returns ""
- * - substring("12345", -42, 1 div 0) returns "12345"
- * - substring("12345", -1 div 0, 1 div 0) returns ""
- */
-void
-xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr str, start, len;
- double le=0, in;
- int i, l, m;
- xmlChar *ret;
-
- if (nargs < 2) {
- CHECK_ARITY(2);
- }
- if (nargs > 3) {
- CHECK_ARITY(3);
- }
- /*
- * take care of possible last (position) argument
- */
- if (nargs == 3) {
- CAST_TO_NUMBER;
- CHECK_TYPE(XPATH_NUMBER);
- len = valuePop(ctxt);
- le = len->floatval;
- xmlXPathFreeObject(len);
- }
-
- CAST_TO_NUMBER;
- CHECK_TYPE(XPATH_NUMBER);
- start = valuePop(ctxt);
- in = start->floatval;
- xmlXPathFreeObject(start);
- CAST_TO_STRING;
- CHECK_TYPE(XPATH_STRING);
- str = valuePop(ctxt);
- m = xmlUTF8Strlen((const unsigned char *)str->stringval);
-
- /*
- * If last pos not present, calculate last position
- */
- if (nargs != 3) {
- le = (double)m;
- if (in < 1.0)
- in = 1.0;
- }
-
- /* Need to check for the special cases where either
- * the index is NaN, the length is NaN, or both
- * arguments are infinity (relying on Inf + -Inf = NaN)
- */
- if (!xmlXPathIsNaN(in + le) && !xmlXPathIsInf(in)) {
- /*
- * To meet the requirements of the spec, the arguments
- * must be converted to integer format before
- * initial index calculations are done
- *
- * First we go to integer form, rounding up
- * and checking for special cases
- */
- i = (int) in;
- if (((double)i)+0.5 <= in) i++;
-
- if (xmlXPathIsInf(le) == 1) {
- l = m;
- if (i < 1)
- i = 1;
- }
- else if (xmlXPathIsInf(le) == -1 || le < 0.0)
- l = 0;
- else {
- l = (int) le;
- if (((double)l)+0.5 <= le) l++;
- }
-
- /* Now we normalize inidices */
- i -= 1;
- l += i;
- if (i < 0)
- i = 0;
- if (l > m)
- l = m;
-
- /* number of chars to copy */
- l -= i;
-
- ret = xmlUTF8Strsub(str->stringval, i, l);
- }
- else {
- ret = NULL;
- }
-
- if (ret == NULL)
- valuePush(ctxt, xmlXPathNewCString(""));
- else {
- valuePush(ctxt, xmlXPathNewString(ret));
- xmlFree(ret);
- }
-
- xmlXPathFreeObject(str);
-}
-
-/**
- * xmlXPathSubstringBeforeFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the substring-before() XPath function
- * string substring-before(string, string)
- * The substring-before function returns the substring of the first
- * argument string that precedes the first occurrence of the second
- * argument string in the first argument string, or the empty string
- * if the first argument string does not contain the second argument
- * string. For example, substring-before("1999/04/01","/") returns 1999.
- */
-void
-xmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr str;
- xmlXPathObjectPtr find;
- xmlBufferPtr target;
- const xmlChar *point;
- int offset;
-
- CHECK_ARITY(2);
- CAST_TO_STRING;
- find = valuePop(ctxt);
- CAST_TO_STRING;
- str = valuePop(ctxt);
-
- target = xmlBufferCreate();
- if (target) {
- point = xmlStrstr(str->stringval, find->stringval);
- if (point) {
- offset = (int)(point - str->stringval);
- xmlBufferAdd(target, str->stringval, offset);
- }
- valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
- xmlBufferFree(target);
- }
-
- xmlXPathFreeObject(str);
- xmlXPathFreeObject(find);
-}
-
-/**
- * xmlXPathSubstringAfterFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the substring-after() XPath function
- * string substring-after(string, string)
- * The substring-after function returns the substring of the first
- * argument string that follows the first occurrence of the second
- * argument string in the first argument string, or the empty stringi
- * if the first argument string does not contain the second argument
- * string. For example, substring-after("1999/04/01","/") returns 04/01,
- * and substring-after("1999/04/01","19") returns 99/04/01.
- */
-void
-xmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr str;
- xmlXPathObjectPtr find;
- xmlBufferPtr target;
- const xmlChar *point;
- int offset;
-
- CHECK_ARITY(2);
- CAST_TO_STRING;
- find = valuePop(ctxt);
- CAST_TO_STRING;
- str = valuePop(ctxt);
-
- target = xmlBufferCreate();
- if (target) {
- point = xmlStrstr(str->stringval, find->stringval);
- if (point) {
- offset = (int)(point - str->stringval) + xmlStrlen(find->stringval);
- xmlBufferAdd(target, &str->stringval[offset],
- xmlStrlen(str->stringval) - offset);
- }
- valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
- xmlBufferFree(target);
- }
-
- xmlXPathFreeObject(str);
- xmlXPathFreeObject(find);
-}
-
-/**
- * xmlXPathNormalizeFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the normalize-space() XPath function
- * string normalize-space(string?)
- * The normalize-space function returns the argument string with white
- * space normalized by stripping leading and trailing whitespace
- * and replacing sequences of whitespace characters by a single
- * space. Whitespace characters are the same allowed by the S production
- * in XML. If the argument is omitted, it defaults to the context
- * node converted to a string, in other words the value of the context node.
- */
-void
-xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr obj = NULL;
- xmlChar *source = NULL;
- xmlBufferPtr target;
- xmlChar blank;
-
- if (nargs == 0) {
- /* Use current context node */
- valuePush(ctxt,
- xmlXPathWrapString(
- xmlXPathCastNodeToString(ctxt->context->node)));
- nargs = 1;
- }
-
- CHECK_ARITY(1);
- CAST_TO_STRING;
- CHECK_TYPE(XPATH_STRING);
- obj = valuePop(ctxt);
- source = obj->stringval;
-
- target = xmlBufferCreate();
- if (target && source) {
-
- /* Skip leading whitespaces */
- while (IS_BLANK(*source))
- source++;
-
- /* Collapse intermediate whitespaces, and skip trailing whitespaces */
- blank = 0;
- while (*source) {
- if (IS_BLANK(*source)) {
- blank = 0x20;
- } else {
- if (blank) {
- xmlBufferAdd(target, &blank, 1);
- blank = 0;
- }
- xmlBufferAdd(target, source, 1);
- }
- source++;
- }
-
- valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
- xmlBufferFree(target);
- }
- xmlXPathFreeObject(obj);
-}
-
-/**
- * xmlXPathTranslateFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the translate() XPath function
- * string translate(string, string, string)
- * The translate function returns the first argument string with
- * occurrences of characters in the second argument string replaced
- * by the character at the corresponding position in the third argument
- * string. For example, translate("bar","abc","ABC") returns the string
- * BAr. If there is a character in the second argument string with no
- * character at a corresponding position in the third argument string
- * (because the second argument string is longer than the third argument
- * string), then occurrences of that character in the first argument
- * string are removed. For example, translate("--aaa--","abc-","ABC")
- * returns "AAA". If a character occurs more than once in second
- * argument string, then the first occurrence determines the replacement
- * character. If the third argument string is longer than the second
- * argument string, then excess characters are ignored.
- */
-void
-xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr str;
- xmlXPathObjectPtr from;
- xmlXPathObjectPtr to;
- xmlBufferPtr target;
- int offset, max;
- xmlChar ch;
- xmlChar *point;
- xmlChar *cptr;
-
- CHECK_ARITY(3);
-
- CAST_TO_STRING;
- to = valuePop(ctxt);
- CAST_TO_STRING;
- from = valuePop(ctxt);
- CAST_TO_STRING;
- str = valuePop(ctxt);
-
- target = xmlBufferCreate();
- if (target) {
- max = xmlUTF8Strlen(to->stringval);
- for (cptr = str->stringval; (ch=*cptr); ) {
- offset = xmlUTF8Strloc(from->stringval, cptr);
- if (offset >= 0) {
- if (offset < max) {
- point = xmlUTF8Strpos(to->stringval, offset);
- if (point)
- xmlBufferAdd(target, point, xmlUTF8Strsize(point, 1));
- }
- } else
- xmlBufferAdd(target, cptr, xmlUTF8Strsize(cptr, 1));
-
- /* Step to next character in input */
- cptr++;
- if ( ch & 0x80 ) {
- /* if not simple ascii, verify proper format */
- if ( (ch & 0xc0) != 0xc0 ) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathTranslateFunction: Invalid UTF8 string\n");
- break;
- }
- /* then skip over remaining bytes for this char */
- while ( (ch <<= 1) & 0x80 )
- if ( (*cptr++ & 0xc0) != 0x80 ) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathTranslateFunction: Invalid UTF8 string\n");
- break;
- }
- if (ch & 0x80) /* must have had error encountered */
- break;
- }
- }
- }
- valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
- xmlBufferFree(target);
- xmlXPathFreeObject(str);
- xmlXPathFreeObject(from);
- xmlXPathFreeObject(to);
-}
-
-/**
- * xmlXPathBooleanFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the boolean() XPath function
- * boolean boolean(object)
- * he boolean function converts its argument to a boolean as follows:
- * - a number is true if and only if it is neither positive or
- * negative zero nor NaN
- * - a node-set is true if and only if it is non-empty
- * - a string is true if and only if its length is non-zero
- */
-void
-xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr cur;
-
- CHECK_ARITY(1);
- cur = valuePop(ctxt);
- if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
- cur = xmlXPathConvertBoolean(cur);
- valuePush(ctxt, cur);
-}
-
-/**
- * xmlXPathNotFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the not() XPath function
- * boolean not(boolean)
- * The not function returns true if its argument is false,
- * and false otherwise.
- */
-void
-xmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- CHECK_ARITY(1);
- CAST_TO_BOOLEAN;
- CHECK_TYPE(XPATH_BOOLEAN);
- ctxt->value->boolval = ! ctxt->value->boolval;
-}
-
-/**
- * xmlXPathTrueFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the true() XPath function
- * boolean true()
- */
-void
-xmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- CHECK_ARITY(0);
- valuePush(ctxt, xmlXPathNewBoolean(1));
-}
-
-/**
- * xmlXPathFalseFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the false() XPath function
- * boolean false()
- */
-void
-xmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- CHECK_ARITY(0);
- valuePush(ctxt, xmlXPathNewBoolean(0));
-}
-
-/**
- * xmlXPathLangFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the lang() XPath function
- * boolean lang(string)
- * The lang function returns true or false depending on whether the
- * language of the context node as specified by xml:lang attributes
- * is the same as or is a sublanguage of the language specified by
- * the argument string. The language of the context node is determined
- * by the value of the xml:lang attribute on the context node, or, if
- * the context node has no xml:lang attribute, by the value of the
- * xml:lang attribute on the nearest ancestor of the context node that
- * has an xml:lang attribute. If there is no such attribute, then lang
- * returns false. If there is such an attribute, then lang returns
- * true if the attribute value is equal to the argument ignoring case,
- * or if there is some suffix starting with - such that the attribute
- * value is equal to the argument ignoring that suffix of the attribute
- * value and ignoring case.
- */
-void
-xmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr val;
- const xmlChar *theLang;
- const xmlChar *lang;
- int ret = 0;
- int i;
-
- CHECK_ARITY(1);
- CAST_TO_STRING;
- CHECK_TYPE(XPATH_STRING);
- val = valuePop(ctxt);
- lang = val->stringval;
- theLang = xmlNodeGetLang(ctxt->context->node);
- if ((theLang != NULL) && (lang != NULL)) {
- for (i = 0;lang[i] != 0;i++)
- if (toupper(lang[i]) != toupper(theLang[i]))
- goto not_equal;
- ret = 1;
- }
-not_equal:
- xmlXPathFreeObject(val);
- valuePush(ctxt, xmlXPathNewBoolean(ret));
-}
-
-/**
- * xmlXPathNumberFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the number() XPath function
- * number number(object?)
- */
-void
-xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr cur;
- double res;
-
- if (nargs == 0) {
- if (ctxt->context->node == NULL) {
- valuePush(ctxt, xmlXPathNewFloat(0.0));
- } else {
- xmlChar* content = xmlNodeGetContent(ctxt->context->node);
-
- res = xmlXPathStringEvalNumber(content);
- valuePush(ctxt, xmlXPathNewFloat(res));
- xmlFree(content);
- }
- return;
- }
-
- CHECK_ARITY(1);
- cur = valuePop(ctxt);
- cur = xmlXPathConvertNumber(cur);
- valuePush(ctxt, cur);
-}
-
-/**
- * xmlXPathSumFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the sum() XPath function
- * number sum(node-set)
- * The sum function returns the sum of the values of the nodes in
- * the argument node-set.
- */
-void
-xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr cur;
- int i;
- double res = 0.0;
-
- CHECK_ARITY(1);
- if ((ctxt->value == NULL) ||
- ((ctxt->value->type != XPATH_NODESET) &&
- (ctxt->value->type != XPATH_XSLT_TREE)))
- XP_ERROR(XPATH_INVALID_TYPE);
- cur = valuePop(ctxt);
-
- if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
- valuePush(ctxt, xmlXPathNewFloat(0.0));
- } else {
- for (i = 0; i < cur->nodesetval->nodeNr; i++) {
- res += xmlXPathCastNodeToNumber(cur->nodesetval->nodeTab[i]);
- }
- valuePush(ctxt, xmlXPathNewFloat(res));
- }
- xmlXPathFreeObject(cur);
-}
-
-/**
- * xmlXPathFloorFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the floor() XPath function
- * number floor(number)
- * The floor function returns the largest (closest to positive infinity)
- * number that is not greater than the argument and that is an integer.
- */
-void
-xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- double f;
-
- CHECK_ARITY(1);
- CAST_TO_NUMBER;
- CHECK_TYPE(XPATH_NUMBER);
-
- f = (double)((int) ctxt->value->floatval);
- if (f != ctxt->value->floatval) {
- if (ctxt->value->floatval > 0)
- ctxt->value->floatval = f;
- else
- ctxt->value->floatval = f - 1;
- }
-}
-
-/**
- * xmlXPathCeilingFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the ceiling() XPath function
- * number ceiling(number)
- * The ceiling function returns the smallest (closest to negative infinity)
- * number that is not less than the argument and that is an integer.
- */
-void
-xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- double f;
-
- CHECK_ARITY(1);
- CAST_TO_NUMBER;
- CHECK_TYPE(XPATH_NUMBER);
-
-#if 0
- ctxt->value->floatval = ceil(ctxt->value->floatval);
-#else
- f = (double)((int) ctxt->value->floatval);
- if (f != ctxt->value->floatval) {
- if (ctxt->value->floatval > 0)
- ctxt->value->floatval = f + 1;
- else {
- if (ctxt->value->floatval < 0 && f == 0)
- ctxt->value->floatval = xmlXPathNZERO;
- else
- ctxt->value->floatval = f;
- }
-
- }
-#endif
-}
-
-/**
- * xmlXPathRoundFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the round() XPath function
- * number round(number)
- * The round function returns the number that is closest to the
- * argument and that is an integer. If there are two such numbers,
- * then the one that is even is returned.
- */
-void
-xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- double f;
-
- CHECK_ARITY(1);
- CAST_TO_NUMBER;
- CHECK_TYPE(XPATH_NUMBER);
-
- if ((xmlXPathIsNaN(ctxt->value->floatval)) ||
- (xmlXPathIsInf(ctxt->value->floatval) == 1) ||
- (xmlXPathIsInf(ctxt->value->floatval) == -1) ||
- (ctxt->value->floatval == 0.0))
- return;
-
- f = (double)((int) ctxt->value->floatval);
- if (ctxt->value->floatval < 0) {
- if (ctxt->value->floatval < f - 0.5)
- ctxt->value->floatval = f - 1;
- else
- ctxt->value->floatval = f;
- if (ctxt->value->floatval == 0)
- ctxt->value->floatval = xmlXPathNZERO;
- } else {
- if (ctxt->value->floatval < f + 0.5)
- ctxt->value->floatval = f;
- else
- ctxt->value->floatval = f + 1;
- }
-}
-
-/************************************************************************
- * *
- * The Parser *
- * *
- ************************************************************************/
-
-/*
- * a couple of forward declarations since we use a recursive call based
- * implementation.
- */
-static void xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt);
-static void xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter);
-static void xmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt);
-static void xmlXPathCompRelativeLocationPath(xmlXPathParserContextPtr ctxt);
-static xmlChar * xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt,
- int qualified);
-
-/**
- * xmlXPathCurrentChar:
- * @ctxt: the XPath parser context
- * @cur: pointer to the beginning of the char
- * @len: pointer to the length of the char read
- *
- * The current char value, if using UTF-8 this may actually span multiple
- * bytes in the input buffer.
- *
- * Returns the current char value and its length
- */
-
-static int
-xmlXPathCurrentChar(xmlXPathParserContextPtr ctxt, int *len) {
- unsigned char c;
- unsigned int val;
- const xmlChar *cur;
-
- if (ctxt == NULL)
- return(0);
- cur = ctxt->cur;
-
- /*
- * We are supposed to handle UTF8, check it's valid
- * From rfc2044: encoding of the Unicode values on UTF-8:
- *
- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
- * 0000 0000-0000 007F 0xxxxxxx
- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
- *
- * Check for the 0x110000 limit too
- */
- c = *cur;
- if (c & 0x80) {
- if ((cur[1] & 0xc0) != 0x80)
- goto encoding_error;
- if ((c & 0xe0) == 0xe0) {
-
- if ((cur[2] & 0xc0) != 0x80)
- goto encoding_error;
- if ((c & 0xf0) == 0xf0) {
- if (((c & 0xf8) != 0xf0) ||
- ((cur[3] & 0xc0) != 0x80))
- goto encoding_error;
- /* 4-byte code */
- *len = 4;
- val = (cur[0] & 0x7) << 18;
- val |= (cur[1] & 0x3f) << 12;
- val |= (cur[2] & 0x3f) << 6;
- val |= cur[3] & 0x3f;
- } else {
- /* 3-byte code */
- *len = 3;
- val = (cur[0] & 0xf) << 12;
- val |= (cur[1] & 0x3f) << 6;
- val |= cur[2] & 0x3f;
- }
- } else {
- /* 2-byte code */
- *len = 2;
- val = (cur[0] & 0x1f) << 6;
- val |= cur[1] & 0x3f;
- }
- if (!IS_CHAR(val)) {
- XP_ERROR0(XPATH_INVALID_CHAR_ERROR);
- }
- return(val);
- } else {
- /* 1-byte code */
- *len = 1;
- return((int) *cur);
- }
-encoding_error:
- /*
- * If we detect an UTF8 error that probably mean that the
- * input encoding didn't get properly advertized in the
- * declaration header. Report the error and switch the encoding
- * to ISO-Latin-1 (if you don't like this policy, just declare the
- * encoding !)
- */
- *len = 0;
- XP_ERROR0(XPATH_ENCODING_ERROR);
-}
-
-/**
- * xmlXPathParseNCName:
- * @ctxt: the XPath Parser context
- *
- * parse an XML namespace non qualified name.
- *
- * [NS 3] NCName ::= (Letter | '_') (NCNameChar)*
- *
- * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
- * CombiningChar | Extender
- *
- * Returns the namespace name or NULL
- */
-
-xmlChar *
-xmlXPathParseNCName(xmlXPathParserContextPtr ctxt) {
- const xmlChar *in;
- xmlChar *ret;
- int count = 0;
-
- /*
- * Accelerator for simple ASCII names
- */
- in = ctxt->cur;
- if (((*in >= 0x61) && (*in <= 0x7A)) ||
- ((*in >= 0x41) && (*in <= 0x5A)) ||
- (*in == '_')) {
- in++;
- while (((*in >= 0x61) && (*in <= 0x7A)) ||
- ((*in >= 0x41) && (*in <= 0x5A)) ||
- ((*in >= 0x30) && (*in <= 0x39)) ||
- (*in == '_') || (*in == '.') ||
- (*in == '-'))
- in++;
- if ((*in == ' ') || (*in == '>') || (*in == '/') ||
- (*in == '[') || (*in == ']') || (*in == ':') ||
- (*in == '@') || (*in == '*')) {
- count = in - ctxt->cur;
- if (count == 0)
- return(NULL);
- ret = xmlStrndup(ctxt->cur, count);
- ctxt->cur = in;
- return(ret);
- }
- }
- return(xmlXPathParseNameComplex(ctxt, 0));
-}
-
-
-/**
- * xmlXPathParseQName:
- * @ctxt: the XPath Parser context
- * @prefix: a xmlChar **
- *
- * parse an XML qualified name
- *
- * [NS 5] QName ::= (Prefix ':')? LocalPart
- *
- * [NS 6] Prefix ::= NCName
- *
- * [NS 7] LocalPart ::= NCName
- *
- * Returns the function returns the local part, and prefix is updated
- * to get the Prefix if any.
- */
-
-static xmlChar *
-xmlXPathParseQName(xmlXPathParserContextPtr ctxt, xmlChar **prefix) {
- xmlChar *ret = NULL;
-
- *prefix = NULL;
- ret = xmlXPathParseNCName(ctxt);
- if (CUR == ':') {
- *prefix = ret;
- NEXT;
- ret = xmlXPathParseNCName(ctxt);
- }
- return(ret);
-}
-
-/**
- * xmlXPathParseName:
- * @ctxt: the XPath Parser context
- *
- * parse an XML name
- *
- * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
- * CombiningChar | Extender
- *
- * [5] Name ::= (Letter | '_' | ':') (NameChar)*
- *
- * Returns the namespace name or NULL
- */
-
-xmlChar *
-xmlXPathParseName(xmlXPathParserContextPtr ctxt) {
- const xmlChar *in;
- xmlChar *ret;
- int count = 0;
-
- /*
- * Accelerator for simple ASCII names
- */
- in = ctxt->cur;
- if (((*in >= 0x61) && (*in <= 0x7A)) ||
- ((*in >= 0x41) && (*in <= 0x5A)) ||
- (*in == '_') || (*in == ':')) {
- in++;
- while (((*in >= 0x61) && (*in <= 0x7A)) ||
- ((*in >= 0x41) && (*in <= 0x5A)) ||
- ((*in >= 0x30) && (*in <= 0x39)) ||
- (*in == '_') || (*in == '-') ||
- (*in == ':') || (*in == '.'))
- in++;
- if ((*in > 0) && (*in < 0x80)) {
- count = in - ctxt->cur;
- ret = xmlStrndup(ctxt->cur, count);
- ctxt->cur = in;
- return(ret);
- }
- }
- return(xmlXPathParseNameComplex(ctxt, 1));
-}
-
-static xmlChar *
-xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, int qualified) {
- xmlChar buf[XML_MAX_NAMELEN + 5];
- int len = 0, l;
- int c;
-
- /*
- * Handler for more complex cases
- */
- c = CUR_CHAR(l);
- if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
- (c == '[') || (c == ']') || (c == '@') || /* accelerators */
- (c == '*') || /* accelerators */
- (!IS_LETTER(c) && (c != '_') &&
- ((qualified) && (c != ':')))) {
- return(NULL);
- }
-
- while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
- ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
- (c == '.') || (c == '-') ||
- (c == '_') || ((qualified) && (c == ':')) ||
- (IS_COMBINING(c)) ||
- (IS_EXTENDER(c)))) {
- COPY_BUF(l,buf,len,c);
- NEXTL(l);
- c = CUR_CHAR(l);
- if (len >= XML_MAX_NAMELEN) {
- /*
- * Okay someone managed to make a huge name, so he's ready to pay
- * for the processing speed.
- */
- xmlChar *buffer;
- int max = len * 2;
-
- buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
- if (buffer == NULL) {
- XP_ERROR0(XPATH_MEMORY_ERROR);
- }
- memcpy(buffer, buf, len);
- while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigname.xml */
- (c == '.') || (c == '-') ||
- (c == '_') || ((qualified) && (c == ':')) ||
- (IS_COMBINING(c)) ||
- (IS_EXTENDER(c))) {
- if (len + 10 > max) {
- max *= 2;
- buffer = (xmlChar *) xmlRealloc(buffer,
- max * sizeof(xmlChar));
- if (buffer == NULL) {
- XP_ERROR0(XPATH_MEMORY_ERROR);
- }
- }
- COPY_BUF(l,buffer,len,c);
- NEXTL(l);
- c = CUR_CHAR(l);
- }
- buffer[len] = 0;
- return(buffer);
- }
- }
- if (len == 0)
- return(NULL);
- return(xmlStrndup(buf, len));
-}
-
-#define MAX_FRAC 20
-
-static double my_pow10[MAX_FRAC] = {
- 1.0, 10.0, 100.0, 1000.0, 10000.0,
- 100000.0, 1000000.0, 10000000.0, 100000000.0, 1000000000.0,
- 10000000000.0, 100000000000.0, 1000000000000.0, 10000000000000.0,
- 100000000000000.0,
- 1000000000000000.0, 10000000000000000.0, 100000000000000000.0,
- 1000000000000000000.0, 10000000000000000000.0
-};
-
-/**
- * xmlXPathStringEvalNumber:
- * @str: A string to scan
- *
- * [30a] Float ::= Number ('e' Digits?)?
- *
- * [30] Number ::= Digits ('.' Digits?)?
- * | '.' Digits
- * [31] Digits ::= [0-9]+
- *
- * Compile a Number in the string
- * In complement of the Number expression, this function also handles
- * negative values : '-' Number.
- *
- * Returns the double value.
- */
-double
-xmlXPathStringEvalNumber(const xmlChar *str) {
- const xmlChar *cur = str;
- double ret;
- int ok = 0;
- int isneg = 0;
- int exponent = 0;
- int is_exponent_negative = 0;
-#ifdef __GNUC__
- unsigned long tmp = 0;
- double temp;
-#endif
- if (cur == NULL) return(0);
- while (IS_BLANK(*cur)) cur++;
- if ((*cur != '.') && ((*cur < '0') || (*cur > '9')) && (*cur != '-')) {
- return(xmlXPathNAN);
- }
- if (*cur == '-') {
- isneg = 1;
- cur++;
- }
-
-#ifdef __GNUC__
- /*
- * tmp/temp is a workaround against a gcc compiler bug
- * http://veillard.com/gcc.bug
- */
- ret = 0;
- while ((*cur >= '0') && (*cur <= '9')) {
- ret = ret * 10;
- tmp = (*cur - '0');
- ok = 1;
- cur++;
- temp = (double) tmp;
- ret = ret + temp;
- }
-#else
- ret = 0;
- while ((*cur >= '0') && (*cur <= '9')) {
- ret = ret * 10 + (*cur - '0');
- ok = 1;
- cur++;
- }
-#endif
-
- if (*cur == '.') {
- int v, frac = 0;
- double fraction = 0;
-
- cur++;
- if (((*cur < '0') || (*cur > '9')) && (!ok)) {
- return(xmlXPathNAN);
- }
- while (((*cur >= '0') && (*cur <= '9')) && (frac < MAX_FRAC)) {
- v = (*cur - '0');
- fraction = fraction * 10 + v;
- frac = frac + 1;
- cur++;
- }
- fraction /= my_pow10[frac];
- ret = ret + fraction;
- while ((*cur >= '0') && (*cur <= '9'))
- cur++;
- }
- if ((*cur == 'e') || (*cur == 'E')) {
- cur++;
- if (*cur == '-') {
- is_exponent_negative = 1;
- cur++;
- }
- while ((*cur >= '0') && (*cur <= '9')) {
- exponent = exponent * 10 + (*cur - '0');
- cur++;
- }
- }
- while (IS_BLANK(*cur)) cur++;
- if (*cur != 0) return(xmlXPathNAN);
- if (isneg) ret = -ret;
- if (is_exponent_negative) exponent = -exponent;
- ret *= pow(10.0, (double)exponent);
- return(ret);
-}
-
-/**
- * xmlXPathCompNumber:
- * @ctxt: the XPath Parser context
- *
- * [30] Number ::= Digits ('.' Digits?)?
- * | '.' Digits
- * [31] Digits ::= [0-9]+
- *
- * Compile a Number, then push it on the stack
- *
- */
-static void
-xmlXPathCompNumber(xmlXPathParserContextPtr ctxt)
-{
- double ret = 0.0;
- double mult = 1;
- int ok = 0;
- int exponent = 0;
- int is_exponent_negative = 0;
-#ifdef __GNUC__
- unsigned long tmp = 0;
- double temp;
-#endif
-
- CHECK_ERROR;
- if ((CUR != '.') && ((CUR < '0') || (CUR > '9'))) {
- XP_ERROR(XPATH_NUMBER_ERROR);
- }
-#ifdef __GNUC__
- /*
- * tmp/temp is a workaround against a gcc compiler bug
- * http://veillard.com/gcc.bug
- */
- ret = 0;
- while ((CUR >= '0') && (CUR <= '9')) {
- ret = ret * 10;
- tmp = (CUR - '0');
- ok = 1;
- NEXT;
- temp = (double) tmp;
- ret = ret + temp;
- }
-#else
- ret = 0;
- while ((CUR >= '0') && (CUR <= '9')) {
- ret = ret * 10 + (CUR - '0');
- ok = 1;
- NEXT;
- }
-#endif
- if (CUR == '.') {
- NEXT;
- if (((CUR < '0') || (CUR > '9')) && (!ok)) {
- XP_ERROR(XPATH_NUMBER_ERROR);
- }
- while ((CUR >= '0') && (CUR <= '9')) {
- mult /= 10;
- ret = ret + (CUR - '0') * mult;
- NEXT;
- }
- }
- if ((CUR == 'e') || (CUR == 'E')) {
- NEXT;
- if (CUR == '-') {
- is_exponent_negative = 1;
- NEXT;
- }
- while ((CUR >= '0') && (CUR <= '9')) {
- exponent = exponent * 10 + (CUR - '0');
- NEXT;
- }
- if (is_exponent_negative)
- exponent = -exponent;
- ret *= pow(10.0, (double) exponent);
- }
- PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_NUMBER, 0, 0,
- xmlXPathNewFloat(ret), NULL);
-}
-
-/**
- * xmlXPathParseLiteral:
- * @ctxt: the XPath Parser context
- *
- * Parse a Literal
- *
- * [29] Literal ::= '"' [^"]* '"'
- * | "'" [^']* "'"
- *
- * Returns the value found or NULL in case of error
- */
-static xmlChar *
-xmlXPathParseLiteral(xmlXPathParserContextPtr ctxt) {
- const xmlChar *q;
- xmlChar *ret = NULL;
-
- if (CUR == '"') {
- NEXT;
- q = CUR_PTR;
- while ((IS_CHAR(CUR)) && (CUR != '"'))
- NEXT;
- if (!IS_CHAR(CUR)) {
- XP_ERROR0(XPATH_UNFINISHED_LITERAL_ERROR);
- } else {
- ret = xmlStrndup(q, CUR_PTR - q);
- NEXT;
- }
- } else if (CUR == '\'') {
- NEXT;
- q = CUR_PTR;
- while ((IS_CHAR(CUR)) && (CUR != '\''))
- NEXT;
- if (!IS_CHAR(CUR)) {
- XP_ERROR0(XPATH_UNFINISHED_LITERAL_ERROR);
- } else {
- ret = xmlStrndup(q, CUR_PTR - q);
- NEXT;
- }
- } else {
- XP_ERROR0(XPATH_START_LITERAL_ERROR);
- }
- return(ret);
-}
-
-/**
- * xmlXPathCompLiteral:
- * @ctxt: the XPath Parser context
- *
- * Parse a Literal and push it on the stack.
- *
- * [29] Literal ::= '"' [^"]* '"'
- * | "'" [^']* "'"
- *
- * TODO: xmlXPathCompLiteral memory allocation could be improved.
- */
-static void
-xmlXPathCompLiteral(xmlXPathParserContextPtr ctxt) {
- const xmlChar *q;
- xmlChar *ret = NULL;
-
- if (CUR == '"') {
- NEXT;
- q = CUR_PTR;
- while ((IS_CHAR(CUR)) && (CUR != '"'))
- NEXT;
- if (!IS_CHAR(CUR)) {
- XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR);
- } else {
- ret = xmlStrndup(q, CUR_PTR - q);
- NEXT;
- }
- } else if (CUR == '\'') {
- NEXT;
- q = CUR_PTR;
- while ((IS_CHAR(CUR)) && (CUR != '\''))
- NEXT;
- if (!IS_CHAR(CUR)) {
- XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR);
- } else {
- ret = xmlStrndup(q, CUR_PTR - q);
- NEXT;
- }
- } else {
- XP_ERROR(XPATH_START_LITERAL_ERROR);
- }
- if (ret == NULL) return;
- PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_STRING, 0, 0,
- xmlXPathNewString(ret), NULL);
- xmlFree(ret);
-}
-
-/**
- * xmlXPathCompVariableReference:
- * @ctxt: the XPath Parser context
- *
- * Parse a VariableReference, evaluate it and push it on the stack.
- *
- * The variable bindings consist of a mapping from variable names
- * to variable values. The value of a variable is an object, which
- * of any of the types that are possible for the value of an expression,
- * and may also be of additional types not specified here.
- *
- * Early evaluation is possible since:
- * The variable bindings [...] used to evaluate a subexpression are
- * always the same as those used to evaluate the containing expression.
- *
- * [36] VariableReference ::= '$' QName
- */
-static void
-xmlXPathCompVariableReference(xmlXPathParserContextPtr ctxt) {
- xmlChar *name;
- xmlChar *prefix;
-
- SKIP_BLANKS;
- if (CUR != '$') {
- XP_ERROR(XPATH_VARIABLE_REF_ERROR);
- }
- NEXT;
- name = xmlXPathParseQName(ctxt, &prefix);
- if (name == NULL) {
- XP_ERROR(XPATH_VARIABLE_REF_ERROR);
- }
- ctxt->comp->last = -1;
- PUSH_LONG_EXPR(XPATH_OP_VARIABLE, 0, 0, 0,
- name, prefix);
- SKIP_BLANKS;
-}
-
-/**
- * xmlXPathIsNodeType:
- * @name: a name string
- *
- * Is the name given a NodeType one.
- *
- * [38] NodeType ::= 'comment'
- * | 'text'
- * | 'processing-instruction'
- * | 'node'
- *
- * Returns 1 if true 0 otherwise
- */
-int
-xmlXPathIsNodeType(const xmlChar *name) {
- if (name == NULL)
- return(0);
-
- if (xmlStrEqual(name, BAD_CAST "node"))
- return(1);
- if (xmlStrEqual(name, BAD_CAST "text"))
- return(1);
- if (xmlStrEqual(name, BAD_CAST "comment"))
- return(1);
- if (xmlStrEqual(name, BAD_CAST "processing-instruction"))
- return(1);
- return(0);
-}
-
-/**
- * xmlXPathCompFunctionCall:
- * @ctxt: the XPath Parser context
- *
- * [16] FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument)*)? ')'
- * [17] Argument ::= Expr
- *
- * Compile a function call, the evaluation of all arguments are
- * pushed on the stack
- */
-static void
-xmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) {
- xmlChar *name;
- xmlChar *prefix;
- int nbargs = 0;
-
- name = xmlXPathParseQName(ctxt, &prefix);
- if (name == NULL) {
- XP_ERROR(XPATH_EXPR_ERROR);
- }
- SKIP_BLANKS;
-#ifdef DEBUG_EXPR
- if (prefix == NULL)
- xmlGenericError(xmlGenericErrorContext, "Calling function %s\n",
- name);
- else
- xmlGenericError(xmlGenericErrorContext, "Calling function %s:%s\n",
- prefix, name);
-#endif
-
- if (CUR != '(') {
- XP_ERROR(XPATH_EXPR_ERROR);
- }
- NEXT;
- SKIP_BLANKS;
-
- ctxt->comp->last = -1;
- while (CUR != ')') {
- int op1 = ctxt->comp->last;
- ctxt->comp->last = -1;
- xmlXPathCompileExpr(ctxt);
- CHECK_ERROR;
- PUSH_BINARY_EXPR(XPATH_OP_ARG, op1, ctxt->comp->last, 0, 0);
- nbargs++;
- if (CUR == ')') break;
- if (CUR != ',') {
- XP_ERROR(XPATH_EXPR_ERROR);
- }
- NEXT;
- SKIP_BLANKS;
- }
- PUSH_LONG_EXPR(XPATH_OP_FUNCTION, nbargs, 0, 0,
- name, prefix);
- NEXT;
- SKIP_BLANKS;
-}
-
-/**
- * xmlXPathCompPrimaryExpr:
- * @ctxt: the XPath Parser context
- *
- * [15] PrimaryExpr ::= VariableReference
- * | '(' Expr ')'
- * | Literal
- * | Number
- * | FunctionCall
- *
- * Compile a primary expression.
- */
-static void
-xmlXPathCompPrimaryExpr(xmlXPathParserContextPtr ctxt) {
- SKIP_BLANKS;
- if (CUR == '$') xmlXPathCompVariableReference(ctxt);
- else if (CUR == '(') {
- NEXT;
- SKIP_BLANKS;
- xmlXPathCompileExpr(ctxt);
- CHECK_ERROR;
- if (CUR != ')') {
- XP_ERROR(XPATH_EXPR_ERROR);
- }
- NEXT;
- SKIP_BLANKS;
- } else if (IS_DIGIT(CUR) || (CUR == '.' && IS_DIGIT(NXT(1)))) {
- xmlXPathCompNumber(ctxt);
- } else if ((CUR == '\'') || (CUR == '"')) {
- xmlXPathCompLiteral(ctxt);
- } else {
- xmlXPathCompFunctionCall(ctxt);
- }
- SKIP_BLANKS;
-}
-
-/**
- * xmlXPathCompFilterExpr:
- * @ctxt: the XPath Parser context
- *
- * [20] FilterExpr ::= PrimaryExpr
- * | FilterExpr Predicate
- *
- * Compile a filter expression.
- * Square brackets are used to filter expressions in the same way that
- * they are used in location paths. It is an error if the expression to
- * be filtered does not evaluate to a node-set. The context node list
- * used for evaluating the expression in square brackets is the node-set
- * to be filtered listed in document order.
- */
-
-static void
-xmlXPathCompFilterExpr(xmlXPathParserContextPtr ctxt) {
- xmlXPathCompPrimaryExpr(ctxt);
- CHECK_ERROR;
- SKIP_BLANKS;
-
- while (CUR == '[') {
- xmlXPathCompPredicate(ctxt, 1);
- SKIP_BLANKS;
- }
-
-
-}
-
-/**
- * xmlXPathScanName:
- * @ctxt: the XPath Parser context
- *
- * Trickery: parse an XML name but without consuming the input flow
- * Needed to avoid insanity in the parser state.
- *
- * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
- * CombiningChar | Extender
- *
- * [5] Name ::= (Letter | '_' | ':') (NameChar)*
- *
- * [6] Names ::= Name (S Name)*
- *
- * Returns the Name parsed or NULL
- */
-
-static xmlChar *
-xmlXPathScanName(xmlXPathParserContextPtr ctxt) {
- xmlChar buf[XML_MAX_NAMELEN];
- int len = 0;
-
- SKIP_BLANKS;
- if (!IS_LETTER(CUR) && (CUR != '_') &&
- (CUR != ':')) {
- return(NULL);
- }
-
- while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) ||
- (NXT(len) == '.') || (NXT(len) == '-') ||
- (NXT(len) == '_') || (NXT(len) == ':') ||
- (IS_COMBINING(NXT(len))) ||
- (IS_EXTENDER(NXT(len)))) {
- buf[len] = NXT(len);
- len++;
- if (len >= XML_MAX_NAMELEN) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlScanName: reached XML_MAX_NAMELEN limit\n");
- while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) ||
- (NXT(len) == '.') || (NXT(len) == '-') ||
- (NXT(len) == '_') || (NXT(len) == ':') ||
- (IS_COMBINING(NXT(len))) ||
- (IS_EXTENDER(NXT(len))))
- len++;
- break;
- }
- }
- return(xmlStrndup(buf, len));
-}
-
-/**
- * xmlXPathCompPathExpr:
- * @ctxt: the XPath Parser context
- *
- * [19] PathExpr ::= LocationPath
- * | FilterExpr
- * | FilterExpr '/' RelativeLocationPath
- * | FilterExpr '//' RelativeLocationPath
- *
- * Compile a path expression.
- * The / operator and // operators combine an arbitrary expression
- * and a relative location path. It is an error if the expression
- * does not evaluate to a node-set.
- * The / operator does composition in the same way as when / is
- * used in a location path. As in location paths, // is short for
- * /descendant-or-self::node()/.
- */
-
-static void
-xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
- int lc = 1; /* Should we branch to LocationPath ? */
- xmlChar *name = NULL; /* we may have to preparse a name to find out */
-
- SKIP_BLANKS;
- if ((CUR == '$') || (CUR == '(') || (IS_DIGIT(CUR)) ||
- (CUR == '\'') || (CUR == '"') || (CUR == '.' && IS_DIGIT(NXT(1)))) {
- lc = 0;
- } else if (CUR == '*') {
- /* relative or absolute location path */
- lc = 1;
- } else if (CUR == '/') {
- /* relative or absolute location path */
- lc = 1;
- } else if (CUR == '@') {
- /* relative abbreviated attribute location path */
- lc = 1;
- } else if (CUR == '.') {
- /* relative abbreviated attribute location path */
- lc = 1;
- } else {
- /*
- * Problem is finding if we have a name here whether it's:
- * - a nodetype
- * - a function call in which case it's followed by '('
- * - an axis in which case it's followed by ':'
- * - a element name
- * We do an a priori analysis here rather than having to
- * maintain parsed token content through the recursive function
- * calls. This looks uglier but makes the code quite easier to
- * read/write/debug.
- */
- SKIP_BLANKS;
- name = xmlXPathScanName(ctxt);
- if ((name != NULL) && (xmlStrstr(name, (xmlChar *) "::") != NULL)) {
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext,
- "PathExpr: Axis\n");
-#endif
- lc = 1;
- xmlFree(name);
- } else if (name != NULL) {
- int len =xmlStrlen(name);
- int blank = 0;
-
-
- while (NXT(len) != 0) {
- if (NXT(len) == '/') {
- /* element name */
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext,
- "PathExpr: AbbrRelLocation\n");
-#endif
- lc = 1;
- break;
- } else if (IS_BLANK(NXT(len))) {
- /* skip to next */
- blank = 1;
- } else if (NXT(len) == ':') {
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext,
- "PathExpr: AbbrRelLocation\n");
-#endif
- lc = 1;
- break;
- } else if ((NXT(len) == '(')) {
- /* Note Type or Function */
- if (xmlXPathIsNodeType(name)) {
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext,
- "PathExpr: Type search\n");
-#endif
- lc = 1;
- } else {
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext,
- "PathExpr: function call\n");
-#endif
- lc = 0;
- }
- break;
- } else if ((NXT(len) == '[')) {
- /* element name */
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext,
- "PathExpr: AbbrRelLocation\n");
-#endif
- lc = 1;
- break;
- } else if ((NXT(len) == '<') || (NXT(len) == '>') ||
- (NXT(len) == '=')) {
- lc = 1;
- break;
- } else {
- lc = 1;
- break;
- }
- len++;
- }
- if (NXT(len) == 0) {
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext,
- "PathExpr: AbbrRelLocation\n");
-#endif
- /* element name */
- lc = 1;
- }
- xmlFree(name);
- } else {
- /* make sure all cases are covered explicitely */
- XP_ERROR(XPATH_EXPR_ERROR);
- }
- }
-
- if (lc) {
- if (CUR == '/') {
- PUSH_LEAVE_EXPR(XPATH_OP_ROOT, 0, 0);
- } else {
- PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0);
- }
- xmlXPathCompLocationPath(ctxt);
- } else {
- xmlXPathCompFilterExpr(ctxt);
- CHECK_ERROR;
- if ((CUR == '/') && (NXT(1) == '/')) {
- SKIP(2);
- SKIP_BLANKS;
-
- PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
- NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
- PUSH_UNARY_EXPR(XPATH_OP_RESET, ctxt->comp->last, 1, 0);
-
- xmlXPathCompRelativeLocationPath(ctxt);
- } else if (CUR == '/') {
- xmlXPathCompRelativeLocationPath(ctxt);
- }
- }
- SKIP_BLANKS;
-}
-
-/**
- * xmlXPathCompUnionExpr:
- * @ctxt: the XPath Parser context
- *
- * [18] UnionExpr ::= PathExpr
- * | UnionExpr '|' PathExpr
- *
- * Compile an union expression.
- */
-
-static void
-xmlXPathCompUnionExpr(xmlXPathParserContextPtr ctxt) {
- xmlXPathCompPathExpr(ctxt);
- CHECK_ERROR;
- SKIP_BLANKS;
- while (CUR == '|') {
- int op1 = ctxt->comp->last;
- PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0);
-
- NEXT;
- SKIP_BLANKS;
- xmlXPathCompPathExpr(ctxt);
-
- PUSH_BINARY_EXPR(XPATH_OP_UNION, op1, ctxt->comp->last, 0, 0);
-
- SKIP_BLANKS;
- }
-}
-
-/**
- * xmlXPathCompUnaryExpr:
- * @ctxt: the XPath Parser context
- *
- * [27] UnaryExpr ::= UnionExpr
- * | '-' UnaryExpr
- *
- * Compile an unary expression.
- */
-
-static void
-xmlXPathCompUnaryExpr(xmlXPathParserContextPtr ctxt) {
- int minus = 0;
- int found = 0;
-
- SKIP_BLANKS;
- while (CUR == '-') {
- minus = 1 - minus;
- found = 1;
- NEXT;
- SKIP_BLANKS;
- }
-
- xmlXPathCompUnionExpr(ctxt);
- CHECK_ERROR;
- if (found) {
- if (minus)
- PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 2, 0);
- else
- PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 3, 0);
- }
-}
-
-/**
- * xmlXPathCompMultiplicativeExpr:
- * @ctxt: the XPath Parser context
- *
- * [26] MultiplicativeExpr ::= UnaryExpr
- * | MultiplicativeExpr MultiplyOperator UnaryExpr
- * | MultiplicativeExpr 'div' UnaryExpr
- * | MultiplicativeExpr 'mod' UnaryExpr
- * [34] MultiplyOperator ::= '*'
- *
- * Compile an Additive expression.
- */
-
-static void
-xmlXPathCompMultiplicativeExpr(xmlXPathParserContextPtr ctxt) {
- xmlXPathCompUnaryExpr(ctxt);
- CHECK_ERROR;
- SKIP_BLANKS;
- while ((CUR == '*') ||
- ((CUR == 'd') && (NXT(1) == 'i') && (NXT(2) == 'v')) ||
- ((CUR == 'm') && (NXT(1) == 'o') && (NXT(2) == 'd'))) {
- int op = -1;
- int op1 = ctxt->comp->last;
-
- if (CUR == '*') {
- op = 0;
- NEXT;
- } else if (CUR == 'd') {
- op = 1;
- SKIP(3);
- } else if (CUR == 'm') {
- op = 2;
- SKIP(3);
- }
- SKIP_BLANKS;
- xmlXPathCompUnaryExpr(ctxt);
- CHECK_ERROR;
- PUSH_BINARY_EXPR(XPATH_OP_MULT, op1, ctxt->comp->last, op, 0);
- SKIP_BLANKS;
- }
-}
-
-/**
- * xmlXPathCompAdditiveExpr:
- * @ctxt: the XPath Parser context
- *
- * [25] AdditiveExpr ::= MultiplicativeExpr
- * | AdditiveExpr '+' MultiplicativeExpr
- * | AdditiveExpr '-' MultiplicativeExpr
- *
- * Compile an Additive expression.
- */
-
-static void
-xmlXPathCompAdditiveExpr(xmlXPathParserContextPtr ctxt) {
-
- xmlXPathCompMultiplicativeExpr(ctxt);
- CHECK_ERROR;
- SKIP_BLANKS;
- while ((CUR == '+') || (CUR == '-')) {
- int plus;
- int op1 = ctxt->comp->last;
-
- if (CUR == '+') plus = 1;
- else plus = 0;
- NEXT;
- SKIP_BLANKS;
- xmlXPathCompMultiplicativeExpr(ctxt);
- CHECK_ERROR;
- PUSH_BINARY_EXPR(XPATH_OP_PLUS, op1, ctxt->comp->last, plus, 0);
- SKIP_BLANKS;
- }
-}
-
-/**
- * xmlXPathCompRelationalExpr:
- * @ctxt: the XPath Parser context
- *
- * [24] RelationalExpr ::= AdditiveExpr
- * | RelationalExpr '<' AdditiveExpr
- * | RelationalExpr '>' AdditiveExpr
- * | RelationalExpr '<=' AdditiveExpr
- * | RelationalExpr '>=' AdditiveExpr
- *
- * A <= B > C is allowed ? Answer from James, yes with
- * (AdditiveExpr <= AdditiveExpr) > AdditiveExpr
- * which is basically what got implemented.
- *
- * Compile a Relational expression, then push the result
- * on the stack
- */
-
-static void
-xmlXPathCompRelationalExpr(xmlXPathParserContextPtr ctxt) {
- xmlXPathCompAdditiveExpr(ctxt);
- CHECK_ERROR;
- SKIP_BLANKS;
- while ((CUR == '<') ||
- (CUR == '>') ||
- ((CUR == '<') && (NXT(1) == '=')) ||
- ((CUR == '>') && (NXT(1) == '='))) {
- int inf, strict;
- int op1 = ctxt->comp->last;
-
- if (CUR == '<') inf = 1;
- else inf = 0;
- if (NXT(1) == '=') strict = 0;
- else strict = 1;
- NEXT;
- if (!strict) NEXT;
- SKIP_BLANKS;
- xmlXPathCompAdditiveExpr(ctxt);
- CHECK_ERROR;
- PUSH_BINARY_EXPR(XPATH_OP_CMP, op1, ctxt->comp->last, inf, strict);
- SKIP_BLANKS;
- }
-}
-
-/**
- * xmlXPathCompEqualityExpr:
- * @ctxt: the XPath Parser context
- *
- * [23] EqualityExpr ::= RelationalExpr
- * | EqualityExpr '=' RelationalExpr
- * | EqualityExpr '!=' RelationalExpr
- *
- * A != B != C is allowed ? Answer from James, yes with
- * (RelationalExpr = RelationalExpr) = RelationalExpr
- * (RelationalExpr != RelationalExpr) != RelationalExpr
- * which is basically what got implemented.
- *
- * Compile an Equality expression.
- *
- */
-static void
-xmlXPathCompEqualityExpr(xmlXPathParserContextPtr ctxt) {
- xmlXPathCompRelationalExpr(ctxt);
- CHECK_ERROR;
- SKIP_BLANKS;
- while ((CUR == '=') || ((CUR == '!') && (NXT(1) == '='))) {
- int eq;
- int op1 = ctxt->comp->last;
-
- if (CUR == '=') eq = 1;
- else eq = 0;
- NEXT;
- if (!eq) NEXT;
- SKIP_BLANKS;
- xmlXPathCompRelationalExpr(ctxt);
- CHECK_ERROR;
- PUSH_BINARY_EXPR(XPATH_OP_EQUAL, op1, ctxt->comp->last, eq, 0);
- SKIP_BLANKS;
- }
-}
-
-/**
- * xmlXPathCompAndExpr:
- * @ctxt: the XPath Parser context
- *
- * [22] AndExpr ::= EqualityExpr
- * | AndExpr 'and' EqualityExpr
- *
- * Compile an AND expression.
- *
- */
-static void
-xmlXPathCompAndExpr(xmlXPathParserContextPtr ctxt) {
- xmlXPathCompEqualityExpr(ctxt);
- CHECK_ERROR;
- SKIP_BLANKS;
- while ((CUR == 'a') && (NXT(1) == 'n') && (NXT(2) == 'd')) {
- int op1 = ctxt->comp->last;
- SKIP(3);
- SKIP_BLANKS;
- xmlXPathCompEqualityExpr(ctxt);
- CHECK_ERROR;
- PUSH_BINARY_EXPR(XPATH_OP_AND, op1, ctxt->comp->last, 0, 0);
- SKIP_BLANKS;
- }
-}
-
-/**
- * xmlXPathCompExpr:
- * @ctxt: the XPath Parser context
- *
- * [14] Expr ::= OrExpr
- * [21] OrExpr ::= AndExpr
- * | OrExpr 'or' AndExpr
- *
- * Parse and compile an expression
- */
-static void
-xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt) {
- xmlXPathCompAndExpr(ctxt);
- CHECK_ERROR;
- SKIP_BLANKS;
- while ((CUR == 'o') && (NXT(1) == 'r')) {
- int op1 = ctxt->comp->last;
- SKIP(2);
- SKIP_BLANKS;
- xmlXPathCompAndExpr(ctxt);
- CHECK_ERROR;
- PUSH_BINARY_EXPR(XPATH_OP_OR, op1, ctxt->comp->last, 0, 0);
- op1 = ctxt->comp->nbStep;
- SKIP_BLANKS;
- }
- if (ctxt->comp->steps[ctxt->comp->last].op != XPATH_OP_VALUE) {
- /* more ops could be optimized too */
- PUSH_UNARY_EXPR(XPATH_OP_SORT, ctxt->comp->last , 0, 0);
- }
-}
-
-/**
- * xmlXPathCompPredicate:
- * @ctxt: the XPath Parser context
- * @filter: act as a filter
- *
- * [8] Predicate ::= '[' PredicateExpr ']'
- * [9] PredicateExpr ::= Expr
- *
- * Compile a predicate expression
- */
-static void
-xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter) {
- int op1 = ctxt->comp->last;
-
- SKIP_BLANKS;
- if (CUR != '[') {
- XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
- }
- NEXT;
- SKIP_BLANKS;
-
- ctxt->comp->last = -1;
- xmlXPathCompileExpr(ctxt);
- CHECK_ERROR;
-
- if (CUR != ']') {
- XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
- }
-
- if (filter)
- PUSH_BINARY_EXPR(XPATH_OP_FILTER, op1, ctxt->comp->last, 0, 0);
- else
- PUSH_BINARY_EXPR(XPATH_OP_PREDICATE, op1, ctxt->comp->last, 0, 0);
-
- NEXT;
- SKIP_BLANKS;
-}
-
-/**
- * xmlXPathCompNodeTest:
- * @ctxt: the XPath Parser context
- * @test: pointer to a xmlXPathTestVal
- * @type: pointer to a xmlXPathTypeVal
- * @prefix: placeholder for a possible name prefix
- *
- * [7] NodeTest ::= NameTest
- * | NodeType '(' ')'
- * | 'processing-instruction' '(' Literal ')'
- *
- * [37] NameTest ::= '*'
- * | NCName ':' '*'
- * | QName
- * [38] NodeType ::= 'comment'
- * | 'text'
- * | 'processing-instruction'
- * | 'node'
- *
- * Returns the name found and update @test, @type and @prefix appropriately
- */
-static xmlChar *
-xmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
- xmlXPathTypeVal *type, const xmlChar **prefix,
- xmlChar *name) {
- int blanks;
-
- if ((test == NULL) || (type == NULL) || (prefix == NULL)) {
- STRANGE;
- return(NULL);
- }
- *type = 0;
- *test = 0;
- *prefix = NULL;
- SKIP_BLANKS;
-
- if ((name == NULL) && (CUR == '*')) {
- /*
- * All elements
- */
- NEXT;
- *test = NODE_TEST_ALL;
- return(NULL);
- }
-
- if (name == NULL)
- name = xmlXPathParseNCName(ctxt);
- if (name == NULL) {
- XP_ERROR0(XPATH_EXPR_ERROR);
- }
-
- blanks = IS_BLANK(CUR);
- SKIP_BLANKS;
- if (CUR == '(') {
- NEXT;
- /*
- * NodeType or PI search
- */
- if (xmlStrEqual(name, BAD_CAST "comment"))
- *type = NODE_TYPE_COMMENT;
- else if (xmlStrEqual(name, BAD_CAST "node"))
- *type = NODE_TYPE_NODE;
- else if (xmlStrEqual(name, BAD_CAST "processing-instruction"))
- *type = NODE_TYPE_PI;
- else if (xmlStrEqual(name, BAD_CAST "text"))
- *type = NODE_TYPE_TEXT;
- else {
- if (name != NULL)
- xmlFree(name);
- XP_ERROR0(XPATH_EXPR_ERROR);
- }
-
- *test = NODE_TEST_TYPE;
-
- SKIP_BLANKS;
- if (*type == NODE_TYPE_PI) {
- /*
- * Specific case: search a PI by name.
- */
- if (name != NULL)
- xmlFree(name);
- name = NULL;
- if (CUR != ')') {
- name = xmlXPathParseLiteral(ctxt);
- CHECK_ERROR 0;
- *test = NODE_TEST_PI;
- SKIP_BLANKS;
- }
- }
- if (CUR != ')') {
- if (name != NULL)
- xmlFree(name);
- XP_ERROR0(XPATH_UNCLOSED_ERROR);
- }
- NEXT;
- return(name);
- }
- *test = NODE_TEST_NAME;
- if ((!blanks) && (CUR == ':')) {
- NEXT;
-
- /*
- * Since currently the parser context don't have a
- * namespace list associated:
- * The namespace name for this prefix can be computed
- * only at evaluation time. The compilation is done
- * outside of any context.
- */
-#if 0
- *prefix = xmlXPathNsLookup(ctxt->context, name);
- if (name != NULL)
- xmlFree(name);
- if (*prefix == NULL) {
- XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR);
- }
-#else
- *prefix = name;
-#endif
-
- if (CUR == '*') {
- /*
- * All elements
- */
- NEXT;
- *test = NODE_TEST_ALL;
- return(NULL);
- }
-
- name = xmlXPathParseNCName(ctxt);
- if (name == NULL) {
- XP_ERROR0(XPATH_EXPR_ERROR);
- }
- }
- return(name);
-}
-
-/**
- * xmlXPathIsAxisName:
- * @name: a preparsed name token
- *
- * [6] AxisName ::= 'ancestor'
- * | 'ancestor-or-self'
- * | 'attribute'
- * | 'child'
- * | 'descendant'
- * | 'descendant-or-self'
- * | 'following'
- * | 'following-sibling'
- * | 'namespace'
- * | 'parent'
- * | 'preceding'
- * | 'preceding-sibling'
- * | 'self'
- *
- * Returns the axis or 0
- */
-static xmlXPathAxisVal
-xmlXPathIsAxisName(const xmlChar *name) {
- xmlXPathAxisVal ret = 0;
- switch (name[0]) {
- case 'a':
- if (xmlStrEqual(name, BAD_CAST "ancestor"))
- ret = AXIS_ANCESTOR;
- if (xmlStrEqual(name, BAD_CAST "ancestor-or-self"))
- ret = AXIS_ANCESTOR_OR_SELF;
- if (xmlStrEqual(name, BAD_CAST "attribute"))
- ret = AXIS_ATTRIBUTE;
- break;
- case 'c':
- if (xmlStrEqual(name, BAD_CAST "child"))
- ret = AXIS_CHILD;
- break;
- case 'd':
- if (xmlStrEqual(name, BAD_CAST "descendant"))
- ret = AXIS_DESCENDANT;
- if (xmlStrEqual(name, BAD_CAST "descendant-or-self"))
- ret = AXIS_DESCENDANT_OR_SELF;
- break;
- case 'f':
- if (xmlStrEqual(name, BAD_CAST "following"))
- ret = AXIS_FOLLOWING;
- if (xmlStrEqual(name, BAD_CAST "following-sibling"))
- ret = AXIS_FOLLOWING_SIBLING;
- break;
- case 'n':
- if (xmlStrEqual(name, BAD_CAST "namespace"))
- ret = AXIS_NAMESPACE;
- break;
- case 'p':
- if (xmlStrEqual(name, BAD_CAST "parent"))
- ret = AXIS_PARENT;
- if (xmlStrEqual(name, BAD_CAST "preceding"))
- ret = AXIS_PRECEDING;
- if (xmlStrEqual(name, BAD_CAST "preceding-sibling"))
- ret = AXIS_PRECEDING_SIBLING;
- break;
- case 's':
- if (xmlStrEqual(name, BAD_CAST "self"))
- ret = AXIS_SELF;
- break;
- }
- return(ret);
-}
-
-/**
- * xmlXPathCompStep:
- * @ctxt: the XPath Parser context
- *
- * [4] Step ::= AxisSpecifier NodeTest Predicate*
- * | AbbreviatedStep
- *
- * [12] AbbreviatedStep ::= '.' | '..'
- *
- * [5] AxisSpecifier ::= AxisName '::'
- * | AbbreviatedAxisSpecifier
- *
- * [13] AbbreviatedAxisSpecifier ::= '@'?
- *
- * Modified for XPtr range support as:
- *
- * [4xptr] Step ::= AxisSpecifier NodeTest Predicate*
- * | AbbreviatedStep
- * | 'range-to' '(' Expr ')' Predicate*
- *
- * Compile one step in a Location Path
- * A location step of . is short for self::node(). This is
- * particularly useful in conjunction with //. For example, the
- * location path .//para is short for
- * self::node()/descendant-or-self::node()/child::para
- * and so will select all para descendant elements of the context
- * node.
- * Similarly, a location step of .. is short for parent::node().
- * For example, ../title is short for parent::node()/child::title
- * and so will select the title children of the parent of the context
- * node.
- */
-static void
-xmlXPathCompStep(xmlXPathParserContextPtr ctxt) {
-#ifdef LIBXML_XPTR_ENABLED
- int rangeto = 0;
- int op2 = -1;
-#endif
-
- SKIP_BLANKS;
- if ((CUR == '.') && (NXT(1) == '.')) {
- SKIP(2);
- SKIP_BLANKS;
- PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_PARENT,
- NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
- } else if (CUR == '.') {
- NEXT;
- SKIP_BLANKS;
- } else {
- xmlChar *name = NULL;
- const xmlChar *prefix = NULL;
- xmlXPathTestVal test;
- xmlXPathAxisVal axis = 0;
- xmlXPathTypeVal type;
- int op1;
-
- /*
- * The modification needed for XPointer change to the production
- */
-#ifdef LIBXML_XPTR_ENABLED
- if (ctxt->xptr) {
- name = xmlXPathParseNCName(ctxt);
- if ((name != NULL) && (xmlStrEqual(name, BAD_CAST "range-to"))) {
- op2 = ctxt->comp->last;
- xmlFree(name);
- SKIP_BLANKS;
- if (CUR != '(') {
- XP_ERROR(XPATH_EXPR_ERROR);
- }
- NEXT;
- SKIP_BLANKS;
-
- xmlXPathCompileExpr(ctxt);
- /* PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, ctxt->comp->last, 0, 0); */
- CHECK_ERROR;
-
- SKIP_BLANKS;
- if (CUR != ')') {
- XP_ERROR(XPATH_EXPR_ERROR);
- }
- NEXT;
- rangeto = 1;
- goto eval_predicates;
- }
- }
-#endif
- if (CUR == '*') {
- axis = AXIS_CHILD;
- } else {
- if (name == NULL)
- name = xmlXPathParseNCName(ctxt);
- if (name != NULL) {
- axis = xmlXPathIsAxisName(name);
- if (axis != 0) {
- SKIP_BLANKS;
- if ((CUR == ':') && (NXT(1) == ':')) {
- SKIP(2);
- xmlFree(name);
- name = NULL;
- } else {
- /* an element name can conflict with an axis one :-\ */
- axis = AXIS_CHILD;
- }
- } else {
- axis = AXIS_CHILD;
- }
- } else if (CUR == '@') {
- NEXT;
- axis = AXIS_ATTRIBUTE;
- } else {
- axis = AXIS_CHILD;
- }
- }
-
- CHECK_ERROR;
-
- name = xmlXPathCompNodeTest(ctxt, &test, &type, &prefix, name);
- if (test == 0)
- return;
-
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext,
- "Basis : computing new set\n");
-#endif
-
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext, "Basis : ");
- if (ctxt->value == NULL)
- xmlGenericError(xmlGenericErrorContext, "no value\n");
- else if (ctxt->value->nodesetval == NULL)
- xmlGenericError(xmlGenericErrorContext, "Empty\n");
- else
- xmlGenericErrorContextNodeSet(stdout, ctxt->value->nodesetval);
-#endif
-
-eval_predicates:
- op1 = ctxt->comp->last;
- ctxt->comp->last = -1;
-
- SKIP_BLANKS;
- while (CUR == '[') {
- xmlXPathCompPredicate(ctxt, 0);
- }
-
-#ifdef LIBXML_XPTR_ENABLED
- if (rangeto) {
- PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, op1, 0, 0);
- } else
-#endif
- PUSH_FULL_EXPR(XPATH_OP_COLLECT, op1, ctxt->comp->last, axis,
- test, type, (void *)prefix, (void *)name);
-
- }
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext, "Step : ");
- if (ctxt->value == NULL)
- xmlGenericError(xmlGenericErrorContext, "no value\n");
- else if (ctxt->value->nodesetval == NULL)
- xmlGenericError(xmlGenericErrorContext, "Empty\n");
- else
- xmlGenericErrorContextNodeSet(xmlGenericErrorContext,
- ctxt->value->nodesetval);
-#endif
-}
-
-/**
- * xmlXPathCompRelativeLocationPath:
- * @ctxt: the XPath Parser context
- *
- * [3] RelativeLocationPath ::= Step
- * | RelativeLocationPath '/' Step
- * | AbbreviatedRelativeLocationPath
- * [11] AbbreviatedRelativeLocationPath ::= RelativeLocationPath '//' Step
- *
- * Compile a relative location path.
- */
-static void
-xmlXPathCompRelativeLocationPath
-(xmlXPathParserContextPtr ctxt) {
- SKIP_BLANKS;
- if ((CUR == '/') && (NXT(1) == '/')) {
- SKIP(2);
- SKIP_BLANKS;
- PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
- NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
- } else if (CUR == '/') {
- NEXT;
- SKIP_BLANKS;
- }
- xmlXPathCompStep(ctxt);
- SKIP_BLANKS;
- while (CUR == '/') {
- if ((CUR == '/') && (NXT(1) == '/')) {
- SKIP(2);
- SKIP_BLANKS;
- PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
- NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
- xmlXPathCompStep(ctxt);
- } else if (CUR == '/') {
- NEXT;
- SKIP_BLANKS;
- xmlXPathCompStep(ctxt);
- }
- SKIP_BLANKS;
- }
-}
-
-/**
- * xmlXPathCompLocationPath:
- * @ctxt: the XPath Parser context
- *
- * [1] LocationPath ::= RelativeLocationPath
- * | AbsoluteLocationPath
- * [2] AbsoluteLocationPath ::= '/' RelativeLocationPath?
- * | AbbreviatedAbsoluteLocationPath
- * [10] AbbreviatedAbsoluteLocationPath ::=
- * '//' RelativeLocationPath
- *
- * Compile a location path
- *
- * // is short for /descendant-or-self::node()/. For example,
- * //para is short for /descendant-or-self::node()/child::para and
- * so will select any para element in the document (even a para element
- * that is a document element will be selected by //para since the
- * document element node is a child of the root node); div//para is
- * short for div/descendant-or-self::node()/child::para and so will
- * select all para descendants of div children.
- */
-static void
-xmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt) {
- SKIP_BLANKS;
- if (CUR != '/') {
- xmlXPathCompRelativeLocationPath(ctxt);
- } else {
- while (CUR == '/') {
- if ((CUR == '/') && (NXT(1) == '/')) {
- SKIP(2);
- SKIP_BLANKS;
- PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
- NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
- xmlXPathCompRelativeLocationPath(ctxt);
- } else if (CUR == '/') {
- NEXT;
- SKIP_BLANKS;
- if ((CUR != 0 ) &&
- ((IS_LETTER(CUR)) || (CUR == '_') || (CUR == '.') ||
- (CUR == '@') || (CUR == '*')))
- xmlXPathCompRelativeLocationPath(ctxt);
- }
- }
- }
-}
-
-/************************************************************************
- * *
- * XPath precompiled expression evaluation *
- * *
- ************************************************************************/
-
-static int
-xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op);
-
-/**
- * xmlXPathNodeCollectAndTest:
- * @ctxt: the XPath Parser context
- * @op: the XPath precompiled step operation
- * @first: pointer to the first element in document order
- * @last: pointer to the last element in document order
- *
- * This is the function implementing a step: based on the current list
- * of nodes, it builds up a new list, looking at all nodes under that
- * axis and selecting them it also do the predicate filtering
- *
- * Pushes the new NodeSet resulting from the search.
- *
- * Returns the number of node traversed
- */
-static int
-xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
- xmlXPathStepOpPtr op,
- xmlNodePtr * first, xmlNodePtr * last)
-{
- xmlXPathAxisVal axis = op->value;
- xmlXPathTestVal test = op->value2;
- xmlXPathTypeVal type = op->value3;
- const xmlChar *prefix = op->value4;
- const xmlChar *name = op->value5;
- const xmlChar *URI = NULL;
-
-#ifdef DEBUG_STEP
- int n = 0;
-#endif
- int i, t = 0;
- xmlNodeSetPtr ret, list;
- xmlXPathTraversalFunction next = NULL;
- void (*addNode) (xmlNodeSetPtr, xmlNodePtr);
- xmlNodeSetPtr (*mergeNodeSet) (xmlNodeSetPtr, xmlNodeSetPtr);
- xmlNodePtr cur = NULL;
- xmlXPathObjectPtr obj;
- xmlNodeSetPtr nodelist;
- xmlNodePtr tmp;
-
- CHECK_TYPE0(XPATH_NODESET);
- obj = valuePop(ctxt);
- addNode = xmlXPathNodeSetAdd;
- mergeNodeSet = xmlXPathNodeSetMerge;
- if (prefix != NULL) {
- URI = xmlXPathNsLookup(ctxt->context, prefix);
- if (URI == NULL)
- XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR);
- }
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext, "new step : ");
-#endif
- switch (axis) {
- case AXIS_ANCESTOR:
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext, "axis 'ancestors' ");
-#endif
- first = NULL;
- next = xmlXPathNextAncestor;
- break;
- case AXIS_ANCESTOR_OR_SELF:
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext,
- "axis 'ancestors-or-self' ");
-#endif
- first = NULL;
- next = xmlXPathNextAncestorOrSelf;
- break;
- case AXIS_ATTRIBUTE:
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext, "axis 'attributes' ");
-#endif
- first = NULL;
- last = NULL;
- next = xmlXPathNextAttribute;
- mergeNodeSet = xmlXPathNodeSetMergeUnique;
- break;
- case AXIS_CHILD:
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext, "axis 'child' ");
-#endif
- last = NULL;
- next = xmlXPathNextChild;
- mergeNodeSet = xmlXPathNodeSetMergeUnique;
- break;
- case AXIS_DESCENDANT:
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext, "axis 'descendant' ");
-#endif
- last = NULL;
- next = xmlXPathNextDescendant;
- break;
- case AXIS_DESCENDANT_OR_SELF:
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext,
- "axis 'descendant-or-self' ");
-#endif
- last = NULL;
- next = xmlXPathNextDescendantOrSelf;
- break;
- case AXIS_FOLLOWING:
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext, "axis 'following' ");
-#endif
- last = NULL;
- next = xmlXPathNextFollowing;
- break;
- case AXIS_FOLLOWING_SIBLING:
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext,
- "axis 'following-siblings' ");
-#endif
- last = NULL;
- next = xmlXPathNextFollowingSibling;
- break;
- case AXIS_NAMESPACE:
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext, "axis 'namespace' ");
-#endif
- first = NULL;
- last = NULL;
- next = (xmlXPathTraversalFunction) xmlXPathNextNamespace;
- mergeNodeSet = xmlXPathNodeSetMergeUnique;
- break;
- case AXIS_PARENT:
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext, "axis 'parent' ");
-#endif
- first = NULL;
- next = xmlXPathNextParent;
- break;
- case AXIS_PRECEDING:
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext, "axis 'preceding' ");
-#endif
- first = NULL;
- next = xmlXPathNextPrecedingInternal;
- break;
- case AXIS_PRECEDING_SIBLING:
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext,
- "axis 'preceding-sibling' ");
-#endif
- first = NULL;
- next = xmlXPathNextPrecedingSibling;
- break;
- case AXIS_SELF:
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext, "axis 'self' ");
-#endif
- first = NULL;
- last = NULL;
- next = xmlXPathNextSelf;
- mergeNodeSet = xmlXPathNodeSetMergeUnique;
- break;
- }
- if (next == NULL)
- return(0);
-
- nodelist = obj->nodesetval;
- if (nodelist == NULL) {
- xmlXPathFreeObject(obj);
- valuePush(ctxt, xmlXPathWrapNodeSet(NULL));
- return(0);
- }
- addNode = xmlXPathNodeSetAddUnique;
- ret = NULL;
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext,
- " context contains %d nodes\n", nodelist->nodeNr);
- switch (test) {
- case NODE_TEST_NONE:
- xmlGenericError(xmlGenericErrorContext,
- " searching for none !!!\n");
- break;
- case NODE_TEST_TYPE:
- xmlGenericError(xmlGenericErrorContext,
- " searching for type %d\n", type);
- break;
- case NODE_TEST_PI:
- xmlGenericError(xmlGenericErrorContext,
- " searching for PI !!!\n");
- break;
- case NODE_TEST_ALL:
- xmlGenericError(xmlGenericErrorContext,
- " searching for *\n");
- break;
- case NODE_TEST_NS:
- xmlGenericError(xmlGenericErrorContext,
- " searching for namespace %s\n",
- prefix);
- break;
- case NODE_TEST_NAME:
- xmlGenericError(xmlGenericErrorContext,
- " searching for name %s\n", name);
- if (prefix != NULL)
- xmlGenericError(xmlGenericErrorContext,
- " with namespace %s\n", prefix);
- break;
- }
- xmlGenericError(xmlGenericErrorContext, "Testing : ");
-#endif
- /*
- * 2.3 Node Tests
- * - For the attribute axis, the principal node type is attribute.
- * - For the namespace axis, the principal node type is namespace.
- * - For other axes, the principal node type is element.
- *
- * A node test * is true for any node of the
- * principal node type. For example, child::* will
- * select all element children of the context node
- */
- tmp = ctxt->context->node;
- for (i = 0; i < nodelist->nodeNr; i++) {
- ctxt->context->node = nodelist->nodeTab[i];
-
- cur = NULL;
- list = xmlXPathNodeSetCreate(NULL);
- do {
- cur = next(ctxt, cur);
- if (cur == NULL)
- break;
- if ((first != NULL) && (*first == cur))
- break;
- if (((t % 256) == 0) &&
- (first != NULL) && (*first != NULL) &&
- (xmlXPathCmpNodes(*first, cur) >= 0))
- break;
- if ((last != NULL) && (*last == cur))
- break;
- if (((t % 256) == 0) &&
- (last != NULL) && (*last != NULL) &&
- (xmlXPathCmpNodes(cur, *last) >= 0))
- break;
- t++;
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext, " %s", cur->name);
-#endif
- switch (test) {
- case NODE_TEST_NONE:
- ctxt->context->node = tmp;
- STRANGE return(t);
- case NODE_TEST_TYPE:
- if ((cur->type == type) ||
- ((type == NODE_TYPE_NODE) &&
- ((cur->type == XML_DOCUMENT_NODE) ||
- (cur->type == XML_HTML_DOCUMENT_NODE) ||
- (cur->type == XML_ELEMENT_NODE) ||
- (cur->type == XML_NAMESPACE_DECL) ||
- (cur->type == XML_ATTRIBUTE_NODE) ||
- (cur->type == XML_PI_NODE) ||
- (cur->type == XML_COMMENT_NODE) ||
- (cur->type == XML_CDATA_SECTION_NODE) ||
- (cur->type == XML_TEXT_NODE))) ||
- ((type == NODE_TYPE_TEXT) &&
- (cur->type == XML_CDATA_SECTION_NODE))) {
-#ifdef DEBUG_STEP
- n++;
-#endif
- addNode(list, cur);
- }
- break;
- case NODE_TEST_PI:
- if (cur->type == XML_PI_NODE) {
- if ((name != NULL) &&
- (!xmlStrEqual(name, cur->name)))
- break;
-#ifdef DEBUG_STEP
- n++;
-#endif
- addNode(list, cur);
- }
- break;
- case NODE_TEST_ALL:
- if (axis == AXIS_ATTRIBUTE) {
- if (cur->type == XML_ATTRIBUTE_NODE) {
-#ifdef DEBUG_STEP
- n++;
-#endif
- addNode(list, cur);
- }
- } else if (axis == AXIS_NAMESPACE) {
- if (cur->type == XML_NAMESPACE_DECL) {
-#ifdef DEBUG_STEP
- n++;
-#endif
- xmlXPathNodeSetAddNs(list, ctxt->context->node,
- (xmlNsPtr) cur);
- }
- } else {
- if (cur->type == XML_ELEMENT_NODE) {
- if (prefix == NULL) {
-#ifdef DEBUG_STEP
- n++;
-#endif
- addNode(list, cur);
- } else if ((cur->ns != NULL) &&
- (xmlStrEqual(URI, cur->ns->href))) {
-#ifdef DEBUG_STEP
- n++;
-#endif
- addNode(list, cur);
- }
- }
- }
- break;
- case NODE_TEST_NS:{
- TODO;
- break;
- }
- case NODE_TEST_NAME:
- switch (cur->type) {
- case XML_ELEMENT_NODE:
- if (xmlStrEqual(name, cur->name)) {
- if (prefix == NULL) {
- if (cur->ns == NULL) {
-#ifdef DEBUG_STEP
- n++;
-#endif
- addNode(list, cur);
- }
- } else {
- if ((cur->ns != NULL) &&
- (xmlStrEqual(URI,
- cur->ns->href))) {
-#ifdef DEBUG_STEP
- n++;
-#endif
- addNode(list, cur);
- }
- }
- }
- break;
- case XML_ATTRIBUTE_NODE:{
- xmlAttrPtr attr = (xmlAttrPtr) cur;
-
- if (xmlStrEqual(name, attr->name)) {
- if (prefix == NULL) {
- if ((attr->ns == NULL) ||
- (attr->ns->prefix == NULL)) {
-#ifdef DEBUG_STEP
- n++;
-#endif
- addNode(list,
- (xmlNodePtr) attr);
- }
- } else {
- if ((attr->ns != NULL) &&
- (xmlStrEqual(URI,
- attr->ns->
- href))) {
-#ifdef DEBUG_STEP
- n++;
-#endif
- addNode(list,
- (xmlNodePtr) attr);
- }
- }
- }
- break;
- }
- case XML_NAMESPACE_DECL:
- if (cur->type == XML_NAMESPACE_DECL) {
- xmlNsPtr ns = (xmlNsPtr) cur;
-
- if ((ns->prefix != NULL) && (name != NULL)
- && (xmlStrEqual(ns->prefix, name))) {
-#ifdef DEBUG_STEP
- n++;
-#endif
- xmlXPathNodeSetAddNs(list,
- ctxt->context->node, (xmlNsPtr) cur);
- }
- }
- break;
- default:
- break;
- }
- break;
- break;
- }
- } while (cur != NULL);
-
- /*
- * If there is some predicate filtering do it now
- */
- if ((op->ch2 != -1) && (list != NULL) && (list->nodeNr > 0)) {
- xmlXPathObjectPtr obj2;
-
- valuePush(ctxt, xmlXPathWrapNodeSet(list));
- xmlXPathCompOpEval(ctxt, &ctxt->comp->steps[op->ch2]);
- CHECK_TYPE0(XPATH_NODESET);
- obj2 = valuePop(ctxt);
- list = obj2->nodesetval;
- obj2->nodesetval = NULL;
- xmlXPathFreeObject(obj2);
- }
- if (ret == NULL) {
- ret = list;
- } else {
- ret = mergeNodeSet(ret, list);
- xmlXPathFreeNodeSet(list);
- }
- }
- ctxt->context->node = tmp;
-#ifdef DEBUG_STEP
- xmlGenericError(xmlGenericErrorContext,
- "\nExamined %d nodes, found %d nodes at that step\n",
- t, n);
-#endif
- valuePush(ctxt, xmlXPathWrapNodeSet(ret));
- if ((obj->boolval) && (obj->user != NULL)) {
- ctxt->value->boolval = 1;
- ctxt->value->user = obj->user;
- obj->user = NULL;
- obj->boolval = 0;
- }
- xmlXPathFreeObject(obj);
- return(t);
-}
-
-/**
- * xmlXPathNodeCollectAndTestNth:
- * @ctxt: the XPath Parser context
- * @op: the XPath precompiled step operation
- * @indx: the index to collect
- * @first: pointer to the first element in document order
- * @last: pointer to the last element in document order
- *
- * This is the function implementing a step: based on the current list
- * of nodes, it builds up a new list, looking at all nodes under that
- * axis and selecting them it also do the predicate filtering
- *
- * Pushes the new NodeSet resulting from the search.
- * Returns the number of node traversed
- */
-static int
-xmlXPathNodeCollectAndTestNth(xmlXPathParserContextPtr ctxt,
- xmlXPathStepOpPtr op, int indx,
- xmlNodePtr * first, xmlNodePtr * last)
-{
- xmlXPathAxisVal axis = op->value;
- xmlXPathTestVal test = op->value2;
- xmlXPathTypeVal type = op->value3;
- const xmlChar *prefix = op->value4;
- const xmlChar *name = op->value5;
- const xmlChar *URI = NULL;
- int n = 0, t = 0;
-
- int i;
- xmlNodeSetPtr list;
- xmlXPathTraversalFunction next = NULL;
- void (*addNode) (xmlNodeSetPtr, xmlNodePtr);
- xmlNodePtr cur = NULL;
- xmlXPathObjectPtr obj;
- xmlNodeSetPtr nodelist;
- xmlNodePtr tmp;
-
- CHECK_TYPE0(XPATH_NODESET);
- obj = valuePop(ctxt);
- addNode = xmlXPathNodeSetAdd;
- if (prefix != NULL) {
- URI = xmlXPathNsLookup(ctxt->context, prefix);
- if (URI == NULL)
- XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR);
- }
-#ifdef DEBUG_STEP_NTH
- xmlGenericError(xmlGenericErrorContext, "new step : ");
- if (first != NULL) {
- if (*first != NULL)
- xmlGenericError(xmlGenericErrorContext, "first = %s ",
- (*first)->name);
- else
- xmlGenericError(xmlGenericErrorContext, "first = NULL ");
- }
- if (last != NULL) {
- if (*last != NULL)
- xmlGenericError(xmlGenericErrorContext, "last = %s ",
- (*last)->name);
- else
- xmlGenericError(xmlGenericErrorContext, "last = NULL ");
- }
-#endif
- switch (axis) {
- case AXIS_ANCESTOR:
-#ifdef DEBUG_STEP_NTH
- xmlGenericError(xmlGenericErrorContext, "axis 'ancestors' ");
-#endif
- first = NULL;
- next = xmlXPathNextAncestor;
- break;
- case AXIS_ANCESTOR_OR_SELF:
-#ifdef DEBUG_STEP_NTH
- xmlGenericError(xmlGenericErrorContext,
- "axis 'ancestors-or-self' ");
-#endif
- first = NULL;
- next = xmlXPathNextAncestorOrSelf;
- break;
- case AXIS_ATTRIBUTE:
-#ifdef DEBUG_STEP_NTH
- xmlGenericError(xmlGenericErrorContext, "axis 'attributes' ");
-#endif
- first = NULL;
- last = NULL;
- next = xmlXPathNextAttribute;
- break;
- case AXIS_CHILD:
-#ifdef DEBUG_STEP_NTH
- xmlGenericError(xmlGenericErrorContext, "axis 'child' ");
-#endif
- last = NULL;
- next = xmlXPathNextChild;
- break;
- case AXIS_DESCENDANT:
-#ifdef DEBUG_STEP_NTH
- xmlGenericError(xmlGenericErrorContext, "axis 'descendant' ");
-#endif
- last = NULL;
- next = xmlXPathNextDescendant;
- break;
- case AXIS_DESCENDANT_OR_SELF:
-#ifdef DEBUG_STEP_NTH
- xmlGenericError(xmlGenericErrorContext,
- "axis 'descendant-or-self' ");
-#endif
- last = NULL;
- next = xmlXPathNextDescendantOrSelf;
- break;
- case AXIS_FOLLOWING:
-#ifdef DEBUG_STEP_NTH
- xmlGenericError(xmlGenericErrorContext, "axis 'following' ");
-#endif
- last = NULL;
- next = xmlXPathNextFollowing;
- break;
- case AXIS_FOLLOWING_SIBLING:
-#ifdef DEBUG_STEP_NTH
- xmlGenericError(xmlGenericErrorContext,
- "axis 'following-siblings' ");
-#endif
- last = NULL;
- next = xmlXPathNextFollowingSibling;
- break;
- case AXIS_NAMESPACE:
-#ifdef DEBUG_STEP_NTH
- xmlGenericError(xmlGenericErrorContext, "axis 'namespace' ");
-#endif
- last = NULL;
- first = NULL;
- next = (xmlXPathTraversalFunction) xmlXPathNextNamespace;
- break;
- case AXIS_PARENT:
-#ifdef DEBUG_STEP_NTH
- xmlGenericError(xmlGenericErrorContext, "axis 'parent' ");
-#endif
- first = NULL;
- next = xmlXPathNextParent;
- break;
- case AXIS_PRECEDING:
-#ifdef DEBUG_STEP_NTH
- xmlGenericError(xmlGenericErrorContext, "axis 'preceding' ");
-#endif
- first = NULL;
- next = xmlXPathNextPrecedingInternal;
- break;
- case AXIS_PRECEDING_SIBLING:
-#ifdef DEBUG_STEP_NTH
- xmlGenericError(xmlGenericErrorContext,
- "axis 'preceding-sibling' ");
-#endif
- first = NULL;
- next = xmlXPathNextPrecedingSibling;
- break;
- case AXIS_SELF:
-#ifdef DEBUG_STEP_NTH
- xmlGenericError(xmlGenericErrorContext, "axis 'self' ");
-#endif
- first = NULL;
- last = NULL;
- next = xmlXPathNextSelf;
- break;
- }
- if (next == NULL)
- return(0);
-
- nodelist = obj->nodesetval;
- if (nodelist == NULL) {
- xmlXPathFreeObject(obj);
- valuePush(ctxt, xmlXPathWrapNodeSet(NULL));
- return(0);
- }
- addNode = xmlXPathNodeSetAddUnique;
-#ifdef DEBUG_STEP_NTH
- xmlGenericError(xmlGenericErrorContext,
- " context contains %d nodes\n", nodelist->nodeNr);
- switch (test) {
- case NODE_TEST_NONE:
- xmlGenericError(xmlGenericErrorContext,
- " searching for none !!!\n");
- break;
- case NODE_TEST_TYPE:
- xmlGenericError(xmlGenericErrorContext,
- " searching for type %d\n", type);
- break;
- case NODE_TEST_PI:
- xmlGenericError(xmlGenericErrorContext,
- " searching for PI !!!\n");
- break;
- case NODE_TEST_ALL:
- xmlGenericError(xmlGenericErrorContext,
- " searching for *\n");
- break;
- case NODE_TEST_NS:
- xmlGenericError(xmlGenericErrorContext,
- " searching for namespace %s\n",
- prefix);
- break;
- case NODE_TEST_NAME:
- xmlGenericError(xmlGenericErrorContext,
- " searching for name %s\n", name);
- if (prefix != NULL)
- xmlGenericError(xmlGenericErrorContext,
- " with namespace %s\n", prefix);
- break;
- }
- xmlGenericError(xmlGenericErrorContext, "Testing : ");
-#endif
- /*
- * 2.3 Node Tests
- * - For the attribute axis, the principal node type is attribute.
- * - For the namespace axis, the principal node type is namespace.
- * - For other axes, the principal node type is element.
- *
- * A node test * is true for any node of the
- * principal node type. For example, child::* will
- * select all element children of the context node
- */
- tmp = ctxt->context->node;
- list = xmlXPathNodeSetCreate(NULL);
- for (i = 0; i < nodelist->nodeNr; i++) {
- ctxt->context->node = nodelist->nodeTab[i];
-
- cur = NULL;
- n = 0;
- do {
- cur = next(ctxt, cur);
- if (cur == NULL)
- break;
- if ((first != NULL) && (*first == cur))
- break;
- if (((t % 256) == 0) &&
- (first != NULL) && (*first != NULL) &&
- (xmlXPathCmpNodes(*first, cur) >= 0))
- break;
- if ((last != NULL) && (*last == cur))
- break;
- if (((t % 256) == 0) &&
- (last != NULL) && (*last != NULL) &&
- (xmlXPathCmpNodes(cur, *last) >= 0))
- break;
- t++;
- switch (test) {
- case NODE_TEST_NONE:
- ctxt->context->node = tmp;
- STRANGE return(0);
- case NODE_TEST_TYPE:
- if ((cur->type == type) ||
- ((type == NODE_TYPE_NODE) &&
- ((cur->type == XML_DOCUMENT_NODE) ||
- (cur->type == XML_HTML_DOCUMENT_NODE) ||
- (cur->type == XML_ELEMENT_NODE) ||
- (cur->type == XML_PI_NODE) ||
- (cur->type == XML_COMMENT_NODE) ||
- (cur->type == XML_CDATA_SECTION_NODE) ||
- (cur->type == XML_TEXT_NODE))) ||
- ((type == NODE_TYPE_TEXT) &&
- (cur->type == XML_CDATA_SECTION_NODE))) {
- n++;
- if (n == indx)
- addNode(list, cur);
- }
- break;
- case NODE_TEST_PI:
- if (cur->type == XML_PI_NODE) {
- if ((name != NULL) &&
- (!xmlStrEqual(name, cur->name)))
- break;
- n++;
- if (n == indx)
- addNode(list, cur);
- }
- break;
- case NODE_TEST_ALL:
- if (axis == AXIS_ATTRIBUTE) {
- if (cur->type == XML_ATTRIBUTE_NODE) {
- n++;
- if (n == indx)
- addNode(list, cur);
- }
- } else if (axis == AXIS_NAMESPACE) {
- if (cur->type == XML_NAMESPACE_DECL) {
- n++;
- if (n == indx)
- xmlXPathNodeSetAddNs(list, ctxt->context->node,
- (xmlNsPtr) cur);
- }
- } else {
- if (cur->type == XML_ELEMENT_NODE) {
- if (prefix == NULL) {
- n++;
- if (n == indx)
- addNode(list, cur);
- } else if ((cur->ns != NULL) &&
- (xmlStrEqual(URI, cur->ns->href))) {
- n++;
- if (n == indx)
- addNode(list, cur);
- }
- }
- }
- break;
- case NODE_TEST_NS:{
- TODO;
- break;
- }
- case NODE_TEST_NAME:
- switch (cur->type) {
- case XML_ELEMENT_NODE:
- if (xmlStrEqual(name, cur->name)) {
- if (prefix == NULL) {
- if (cur->ns == NULL) {
- n++;
- if (n == indx)
- addNode(list, cur);
- }
- } else {
- if ((cur->ns != NULL) &&
- (xmlStrEqual(URI,
- cur->ns->href))) {
- n++;
- if (n == indx)
- addNode(list, cur);
- }
- }
- }
- break;
- case XML_ATTRIBUTE_NODE:{
- xmlAttrPtr attr = (xmlAttrPtr) cur;
-
- if (xmlStrEqual(name, attr->name)) {
- if (prefix == NULL) {
- if ((attr->ns == NULL) ||
- (attr->ns->prefix == NULL)) {
- n++;
- if (n == indx)
- addNode(list, cur);
- }
- } else {
- if ((attr->ns != NULL) &&
- (xmlStrEqual(URI,
- attr->ns->
- href))) {
- n++;
- if (n == indx)
- addNode(list, cur);
- }
- }
- }
- break;
- }
- case XML_NAMESPACE_DECL:
- if (cur->type == XML_NAMESPACE_DECL) {
- xmlNsPtr ns = (xmlNsPtr) cur;
-
- if ((ns->prefix != NULL) && (name != NULL)
- && (xmlStrEqual(ns->prefix, name))) {
- n++;
- if (n == indx)
- xmlXPathNodeSetAddNs(list,
- ctxt->context->node, (xmlNsPtr) cur);
- }
- }
- break;
- default:
- break;
- }
- break;
- break;
- }
- } while (n < indx);
- }
- ctxt->context->node = tmp;
-#ifdef DEBUG_STEP_NTH
- xmlGenericError(xmlGenericErrorContext,
- "\nExamined %d nodes, found %d nodes at that step\n",
- t, list->nodeNr);
-#endif
- valuePush(ctxt, xmlXPathWrapNodeSet(list));
- if ((obj->boolval) && (obj->user != NULL)) {
- ctxt->value->boolval = 1;
- ctxt->value->user = obj->user;
- obj->user = NULL;
- obj->boolval = 0;
- }
- xmlXPathFreeObject(obj);
- return(t);
-}
-
-/**
- * xmlXPathCompOpEvalFirst:
- * @ctxt: the XPath parser context with the compiled expression
- * @op: an XPath compiled operation
- * @first: the first elem found so far
- *
- * Evaluate the Precompiled XPath operation searching only the first
- * element in document order
- *
- * Returns the number of examined objects.
- */
-static int
-xmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt,
- xmlXPathStepOpPtr op, xmlNodePtr * first)
-{
- int total = 0, cur;
- xmlXPathCompExprPtr comp;
- xmlXPathObjectPtr arg1, arg2;
-
- CHECK_ERROR0;
- comp = ctxt->comp;
- switch (op->op) {
- case XPATH_OP_END:
- return (0);
- case XPATH_OP_UNION:
- total =
- xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1],
- first);
- CHECK_ERROR0;
- if ((ctxt->value != NULL)
- && (ctxt->value->type == XPATH_NODESET)
- && (ctxt->value->nodesetval != NULL)
- && (ctxt->value->nodesetval->nodeNr >= 1)) {
- /*
- * limit tree traversing to first node in the result
- */
- xmlXPathNodeSetSort(ctxt->value->nodesetval);
- *first = ctxt->value->nodesetval->nodeTab[0];
- }
- cur =
- xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch2],
- first);
- CHECK_ERROR0;
- CHECK_TYPE0(XPATH_NODESET);
- arg2 = valuePop(ctxt);
-
- CHECK_TYPE0(XPATH_NODESET);
- arg1 = valuePop(ctxt);
-
- arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval,
- arg2->nodesetval);
- valuePush(ctxt, arg1);
- xmlXPathFreeObject(arg2);
- /* optimizer */
- if (total > cur)
- xmlXPathCompSwap(op);
- return (total + cur);
- case XPATH_OP_ROOT:
- xmlXPathRoot(ctxt);
- return (0);
- case XPATH_OP_NODE:
- if (op->ch1 != -1)
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
- if (op->ch2 != -1)
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
- CHECK_ERROR0;
- valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
- return (total);
- case XPATH_OP_RESET:
- if (op->ch1 != -1)
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
- if (op->ch2 != -1)
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
- CHECK_ERROR0;
- ctxt->context->node = NULL;
- return (total);
- case XPATH_OP_COLLECT:{
- if (op->ch1 == -1)
- return (total);
-
- total = xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
-
- /*
- * Optimization for [n] selection where n is a number
- */
- if ((op->ch2 != -1) &&
- (comp->steps[op->ch2].op == XPATH_OP_PREDICATE) &&
- (comp->steps[op->ch2].ch1 == -1) &&
- (comp->steps[op->ch2].ch2 != -1) &&
- (comp->steps[comp->steps[op->ch2].ch2].op ==
- XPATH_OP_VALUE)) {
- xmlXPathObjectPtr val;
-
- val = comp->steps[comp->steps[op->ch2].ch2].value4;
- if ((val != NULL) && (val->type == XPATH_NUMBER)) {
- int indx = (int) val->floatval;
-
- if (val->floatval == (float) indx) {
- xmlXPathNodeCollectAndTestNth(ctxt, op, indx,
- first, NULL);
- return (total);
- }
- }
- }
- total += xmlXPathNodeCollectAndTest(ctxt, op, first, NULL);
- return (total);
- }
- case XPATH_OP_VALUE:
- valuePush(ctxt,
- xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4));
- return (0);
- case XPATH_OP_SORT:
- if (op->ch1 != -1)
- total +=
- xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1],
- first);
- CHECK_ERROR0;
- if ((ctxt->value != NULL)
- && (ctxt->value->type == XPATH_NODESET)
- && (ctxt->value->nodesetval != NULL))
- xmlXPathNodeSetSort(ctxt->value->nodesetval);
- return (total);
- default:
- return (xmlXPathCompOpEval(ctxt, op));
- }
-}
-
-/**
- * xmlXPathCompOpEvalLast:
- * @ctxt: the XPath parser context with the compiled expression
- * @op: an XPath compiled operation
- * @last: the last elem found so far
- *
- * Evaluate the Precompiled XPath operation searching only the last
- * element in document order
- *
- * Returns the number of node traversed
- */
-static int
-xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
- xmlNodePtr * last)
-{
- int total = 0, cur;
- xmlXPathCompExprPtr comp;
- xmlXPathObjectPtr arg1, arg2;
-
- CHECK_ERROR0;
- comp = ctxt->comp;
- switch (op->op) {
- case XPATH_OP_END:
- return (0);
- case XPATH_OP_UNION:
- total =
- xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1], last);
- CHECK_ERROR0;
- if ((ctxt->value != NULL)
- && (ctxt->value->type == XPATH_NODESET)
- && (ctxt->value->nodesetval != NULL)
- && (ctxt->value->nodesetval->nodeNr >= 1)) {
- /*
- * limit tree traversing to first node in the result
- */
- xmlXPathNodeSetSort(ctxt->value->nodesetval);
- *last =
- ctxt->value->nodesetval->nodeTab[ctxt->value->
- nodesetval->nodeNr -
- 1];
- }
- cur =
- xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch2], last);
- CHECK_ERROR0;
- if ((ctxt->value != NULL)
- && (ctxt->value->type == XPATH_NODESET)
- && (ctxt->value->nodesetval != NULL)
- && (ctxt->value->nodesetval->nodeNr >= 1)) {
- }
- CHECK_TYPE0(XPATH_NODESET);
- arg2 = valuePop(ctxt);
-
- CHECK_TYPE0(XPATH_NODESET);
- arg1 = valuePop(ctxt);
-
- arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval,
- arg2->nodesetval);
- valuePush(ctxt, arg1);
- xmlXPathFreeObject(arg2);
- /* optimizer */
- if (total > cur)
- xmlXPathCompSwap(op);
- return (total + cur);
- case XPATH_OP_ROOT:
- xmlXPathRoot(ctxt);
- return (0);
- case XPATH_OP_NODE:
- if (op->ch1 != -1)
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
- if (op->ch2 != -1)
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
- CHECK_ERROR0;
- valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
- return (total);
- case XPATH_OP_RESET:
- if (op->ch1 != -1)
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
- if (op->ch2 != -1)
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
- CHECK_ERROR0;
- ctxt->context->node = NULL;
- return (total);
- case XPATH_OP_COLLECT:{
- if (op->ch1 == -1)
- return (0);
-
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
-
- /*
- * Optimization for [n] selection where n is a number
- */
- if ((op->ch2 != -1) &&
- (comp->steps[op->ch2].op == XPATH_OP_PREDICATE) &&
- (comp->steps[op->ch2].ch1 == -1) &&
- (comp->steps[op->ch2].ch2 != -1) &&
- (comp->steps[comp->steps[op->ch2].ch2].op ==
- XPATH_OP_VALUE)) {
- xmlXPathObjectPtr val;
-
- val = comp->steps[comp->steps[op->ch2].ch2].value4;
- if ((val != NULL) && (val->type == XPATH_NUMBER)) {
- int indx = (int) val->floatval;
-
- if (val->floatval == (float) indx) {
- total +=
- xmlXPathNodeCollectAndTestNth(ctxt, op,
- indx, NULL,
- last);
- return (total);
- }
- }
- }
- total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, last);
- return (total);
- }
- case XPATH_OP_VALUE:
- valuePush(ctxt,
- xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4));
- return (0);
- case XPATH_OP_SORT:
- if (op->ch1 != -1)
- total +=
- xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1],
- last);
- CHECK_ERROR0;
- if ((ctxt->value != NULL)
- && (ctxt->value->type == XPATH_NODESET)
- && (ctxt->value->nodesetval != NULL))
- xmlXPathNodeSetSort(ctxt->value->nodesetval);
- return (total);
- default:
- return (xmlXPathCompOpEval(ctxt, op));
- }
-}
-
-/**
- * xmlXPathCompOpEval:
- * @ctxt: the XPath parser context with the compiled expression
- * @op: an XPath compiled operation
- *
- * Evaluate the Precompiled XPath operation
- * Returns the number of node traversed
- */
-static int
-xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
-{
- int total = 0;
- int equal, ret;
- xmlXPathCompExprPtr comp;
- xmlXPathObjectPtr arg1, arg2;
- xmlNodePtr bak;
- xmlDocPtr bakd;
- int pp;
- int cs;
-
- CHECK_ERROR0;
- comp = ctxt->comp;
- switch (op->op) {
- case XPATH_OP_END:
- return (0);
- case XPATH_OP_AND:
- bakd = ctxt->context->doc;
- bak = ctxt->context->node;
- pp = ctxt->context->proximityPosition;
- cs = ctxt->context->contextSize;
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
- xmlXPathBooleanFunction(ctxt, 1);
- if ((ctxt->value == NULL) || (ctxt->value->boolval == 0))
- return (total);
- arg2 = valuePop(ctxt);
- ctxt->context->doc = bakd;
- ctxt->context->node = bak;
- ctxt->context->proximityPosition = pp;
- ctxt->context->contextSize = cs;
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
- if (ctxt->error) {
- xmlXPathFreeObject(arg2);
- return(0);
- }
- xmlXPathBooleanFunction(ctxt, 1);
- arg1 = valuePop(ctxt);
- arg1->boolval &= arg2->boolval;
- valuePush(ctxt, arg1);
- xmlXPathFreeObject(arg2);
- return (total);
- case XPATH_OP_OR:
- bakd = ctxt->context->doc;
- bak = ctxt->context->node;
- pp = ctxt->context->proximityPosition;
- cs = ctxt->context->contextSize;
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
- xmlXPathBooleanFunction(ctxt, 1);
- if ((ctxt->value == NULL) || (ctxt->value->boolval == 1))
- return (total);
- arg2 = valuePop(ctxt);
- ctxt->context->doc = bakd;
- ctxt->context->node = bak;
- ctxt->context->proximityPosition = pp;
- ctxt->context->contextSize = cs;
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
- if (ctxt->error) {
- xmlXPathFreeObject(arg2);
- return(0);
- }
- xmlXPathBooleanFunction(ctxt, 1);
- arg1 = valuePop(ctxt);
- arg1->boolval |= arg2->boolval;
- valuePush(ctxt, arg1);
- xmlXPathFreeObject(arg2);
- return (total);
- case XPATH_OP_EQUAL:
- bakd = ctxt->context->doc;
- bak = ctxt->context->node;
- pp = ctxt->context->proximityPosition;
- cs = ctxt->context->contextSize;
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
- ctxt->context->doc = bakd;
- ctxt->context->node = bak;
- ctxt->context->proximityPosition = pp;
- ctxt->context->contextSize = cs;
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
- CHECK_ERROR0;
- if (op->value)
- equal = xmlXPathEqualValues(ctxt);
- else
- equal = xmlXPathNotEqualValues(ctxt);
- valuePush(ctxt, xmlXPathNewBoolean(equal));
- return (total);
- case XPATH_OP_CMP:
- bakd = ctxt->context->doc;
- bak = ctxt->context->node;
- pp = ctxt->context->proximityPosition;
- cs = ctxt->context->contextSize;
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
- ctxt->context->doc = bakd;
- ctxt->context->node = bak;
- ctxt->context->proximityPosition = pp;
- ctxt->context->contextSize = cs;
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
- CHECK_ERROR0;
- ret = xmlXPathCompareValues(ctxt, op->value, op->value2);
- valuePush(ctxt, xmlXPathNewBoolean(ret));
- return (total);
- case XPATH_OP_PLUS:
- bakd = ctxt->context->doc;
- bak = ctxt->context->node;
- pp = ctxt->context->proximityPosition;
- cs = ctxt->context->contextSize;
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
- if (op->ch2 != -1) {
- ctxt->context->doc = bakd;
- ctxt->context->node = bak;
- ctxt->context->proximityPosition = pp;
- ctxt->context->contextSize = cs;
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
- }
- CHECK_ERROR0;
- if (op->value == 0)
- xmlXPathSubValues(ctxt);
- else if (op->value == 1)
- xmlXPathAddValues(ctxt);
- else if (op->value == 2)
- xmlXPathValueFlipSign(ctxt);
- else if (op->value == 3) {
- CAST_TO_NUMBER;
- CHECK_TYPE0(XPATH_NUMBER);
- }
- return (total);
- case XPATH_OP_MULT:
- bakd = ctxt->context->doc;
- bak = ctxt->context->node;
- pp = ctxt->context->proximityPosition;
- cs = ctxt->context->contextSize;
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
- ctxt->context->doc = bakd;
- ctxt->context->node = bak;
- ctxt->context->proximityPosition = pp;
- ctxt->context->contextSize = cs;
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
- CHECK_ERROR0;
- if (op->value == 0)
- xmlXPathMultValues(ctxt);
- else if (op->value == 1)
- xmlXPathDivValues(ctxt);
- else if (op->value == 2)
- xmlXPathModValues(ctxt);
- return (total);
- case XPATH_OP_UNION:
- bakd = ctxt->context->doc;
- bak = ctxt->context->node;
- pp = ctxt->context->proximityPosition;
- cs = ctxt->context->contextSize;
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
- ctxt->context->doc = bakd;
- ctxt->context->node = bak;
- ctxt->context->proximityPosition = pp;
- ctxt->context->contextSize = cs;
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
- CHECK_ERROR0;
- CHECK_TYPE0(XPATH_NODESET);
- arg2 = valuePop(ctxt);
-
- CHECK_TYPE0(XPATH_NODESET);
- arg1 = valuePop(ctxt);
-
- arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval,
- arg2->nodesetval);
- valuePush(ctxt, arg1);
- xmlXPathFreeObject(arg2);
- return (total);
- case XPATH_OP_ROOT:
- xmlXPathRoot(ctxt);
- return (total);
- case XPATH_OP_NODE:
- if (op->ch1 != -1)
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
- if (op->ch2 != -1)
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
- CHECK_ERROR0;
- valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
- return (total);
- case XPATH_OP_RESET:
- if (op->ch1 != -1)
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
- if (op->ch2 != -1)
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
- CHECK_ERROR0;
- ctxt->context->node = NULL;
- return (total);
- case XPATH_OP_COLLECT:{
- if (op->ch1 == -1)
- return (total);
-
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
-
- /*
- * Optimization for [n] selection where n is a number
- */
- if ((op->ch2 != -1) &&
- (comp->steps[op->ch2].op == XPATH_OP_PREDICATE) &&
- (comp->steps[op->ch2].ch1 == -1) &&
- (comp->steps[op->ch2].ch2 != -1) &&
- (comp->steps[comp->steps[op->ch2].ch2].op ==
- XPATH_OP_VALUE)) {
- xmlXPathObjectPtr val;
-
- val = comp->steps[comp->steps[op->ch2].ch2].value4;
- if ((val != NULL) && (val->type == XPATH_NUMBER)) {
- int indx = (int) val->floatval;
-
- if (val->floatval == (float) indx) {
- total +=
- xmlXPathNodeCollectAndTestNth(ctxt, op,
- indx, NULL,
- NULL);
- return (total);
- }
- }
- }
- total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, NULL);
- return (total);
- }
- case XPATH_OP_VALUE:
- valuePush(ctxt,
- xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4));
- return (total);
- case XPATH_OP_VARIABLE:{
- xmlXPathObjectPtr val;
-
- if (op->ch1 != -1)
- total +=
- xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- if (op->value5 == NULL) {
- val = xmlXPathVariableLookup(ctxt->context, op->value4);
- if (val == NULL) {
- ctxt->error = XPATH_UNDEF_VARIABLE_ERROR;
- return(0);
- }
- valuePush(ctxt, val);
- } else {
- const xmlChar *URI;
-
- URI = xmlXPathNsLookup(ctxt->context, op->value5);
- if (URI == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathCompOpEval: variable %s bound to undefined prefix %s\n",
- op->value4, op->value5);
- return (total);
- }
- val = xmlXPathVariableLookupNS(ctxt->context,
- op->value4, URI);
- if (val == NULL) {
- ctxt->error = XPATH_UNDEF_VARIABLE_ERROR;
- return(0);
- }
- valuePush(ctxt, val);
- }
- return (total);
- }
- case XPATH_OP_FUNCTION:{
- xmlXPathFunction func;
- const xmlChar *oldFunc, *oldFuncURI;
- int i;
-
- if (op->ch1 != -1)
- total +=
- xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- if (ctxt->valueNr < op->value) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathCompOpEval: parameter error\n");
- ctxt->error = XPATH_INVALID_OPERAND;
- return (total);
- }
- for (i = 0; i < op->value; i++)
- if (ctxt->valueTab[(ctxt->valueNr - 1) - i] == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathCompOpEval: parameter error\n");
- ctxt->error = XPATH_INVALID_OPERAND;
- return (total);
- }
- if (op->cache != NULL)
- func = (xmlXPathFunction) op->cache;
- else {
- const xmlChar *URI = NULL;
-
- if (op->value5 == NULL)
- func =
- xmlXPathFunctionLookup(ctxt->context,
- op->value4);
- else {
- URI = xmlXPathNsLookup(ctxt->context, op->value5);
- if (URI == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathCompOpEval: function %s bound to undefined prefix %s\n",
- op->value4, op->value5);
- return (total);
- }
- func = xmlXPathFunctionLookupNS(ctxt->context,
- op->value4, URI);
- }
- if (func == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathCompOpEval: function %s not found\n",
- op->value4);
- XP_ERROR0(XPATH_UNKNOWN_FUNC_ERROR);
- }
- op->cache = (void *) func;
- op->cacheURI = (void *) URI;
- }
- oldFunc = ctxt->context->function;
- oldFuncURI = ctxt->context->functionURI;
- ctxt->context->function = op->value4;
- ctxt->context->functionURI = op->cacheURI;
- func(ctxt, op->value);
- ctxt->context->function = oldFunc;
- ctxt->context->functionURI = oldFuncURI;
- return (total);
- }
- case XPATH_OP_ARG:
- bakd = ctxt->context->doc;
- bak = ctxt->context->node;
- if (op->ch1 != -1)
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- ctxt->context->doc = bakd;
- ctxt->context->node = bak;
- CHECK_ERROR0;
- if (op->ch2 != -1)
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
- ctxt->context->doc = bakd;
- ctxt->context->node = bak;
- CHECK_ERROR0;
- return (total);
- case XPATH_OP_PREDICATE:
- case XPATH_OP_FILTER:{
- xmlXPathObjectPtr res;
- xmlXPathObjectPtr obj, tmp;
- xmlNodeSetPtr newset = NULL;
- xmlNodeSetPtr oldset;
- xmlNodePtr oldnode;
- int i;
-
- /*
- * Optimization for ()[1] selection i.e. the first elem
- */
- if ((op->ch1 != -1) && (op->ch2 != -1) &&
- (comp->steps[op->ch1].op == XPATH_OP_SORT) &&
- (comp->steps[op->ch2].op == XPATH_OP_VALUE)) {
- xmlXPathObjectPtr val;
-
- val = comp->steps[op->ch2].value4;
- if ((val != NULL) && (val->type == XPATH_NUMBER) &&
- (val->floatval == 1.0)) {
- xmlNodePtr first = NULL;
-
- total +=
- xmlXPathCompOpEvalFirst(ctxt,
- &comp->steps[op->ch1],
- &first);
- CHECK_ERROR0;
- /*
- * The nodeset should be in document order,
- * Keep only the first value
- */
- if ((ctxt->value != NULL) &&
- (ctxt->value->type == XPATH_NODESET) &&
- (ctxt->value->nodesetval != NULL) &&
- (ctxt->value->nodesetval->nodeNr > 1))
- ctxt->value->nodesetval->nodeNr = 1;
- return (total);
- }
- }
- /*
- * Optimization for ()[last()] selection i.e. the last elem
- */
- if ((op->ch1 != -1) && (op->ch2 != -1) &&
- (comp->steps[op->ch1].op == XPATH_OP_SORT) &&
- (comp->steps[op->ch2].op == XPATH_OP_SORT)) {
- int f = comp->steps[op->ch2].ch1;
-
- if ((f != -1) &&
- (comp->steps[f].op == XPATH_OP_FUNCTION) &&
- (comp->steps[f].value5 == NULL) &&
- (comp->steps[f].value == 0) &&
- (comp->steps[f].value4 != NULL) &&
- (xmlStrEqual
- (comp->steps[f].value4, BAD_CAST "last"))) {
- xmlNodePtr last = NULL;
-
- total +=
- xmlXPathCompOpEvalLast(ctxt,
- &comp->steps[op->ch1],
- &last);
- CHECK_ERROR0;
- /*
- * The nodeset should be in document order,
- * Keep only the last value
- */
- if ((ctxt->value != NULL) &&
- (ctxt->value->type == XPATH_NODESET) &&
- (ctxt->value->nodesetval != NULL) &&
- (ctxt->value->nodesetval->nodeTab != NULL) &&
- (ctxt->value->nodesetval->nodeNr > 1)) {
- ctxt->value->nodesetval->nodeTab[0] =
- ctxt->value->nodesetval->nodeTab[ctxt->
- value->
- nodesetval->
- nodeNr -
- 1];
- ctxt->value->nodesetval->nodeNr = 1;
- }
- return (total);
- }
- }
-
- if (op->ch1 != -1)
- total +=
- xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
- if (op->ch2 == -1)
- return (total);
- if (ctxt->value == NULL)
- return (total);
-
- oldnode = ctxt->context->node;
-
-#ifdef LIBXML_XPTR_ENABLED
- /*
- * Hum are we filtering the result of an XPointer expression
- */
- if (ctxt->value->type == XPATH_LOCATIONSET) {
- xmlLocationSetPtr newlocset = NULL;
- xmlLocationSetPtr oldlocset;
-
- /*
- * Extract the old locset, and then evaluate the result of the
- * expression for all the element in the locset. use it to grow
- * up a new locset.
- */
- CHECK_TYPE0(XPATH_LOCATIONSET);
- obj = valuePop(ctxt);
- oldlocset = obj->user;
- ctxt->context->node = NULL;
-
- if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
- ctxt->context->contextSize = 0;
- ctxt->context->proximityPosition = 0;
- if (op->ch2 != -1)
- total +=
- xmlXPathCompOpEval(ctxt,
- &comp->steps[op->ch2]);
- res = valuePop(ctxt);
- if (res != NULL)
- xmlXPathFreeObject(res);
- valuePush(ctxt, obj);
- CHECK_ERROR0;
- return (total);
- }
- newlocset = xmlXPtrLocationSetCreate(NULL);
-
- for (i = 0; i < oldlocset->locNr; i++) {
- /*
- * Run the evaluation with a node list made of a
- * single item in the nodelocset.
- */
- ctxt->context->node = oldlocset->locTab[i]->user;
- tmp = xmlXPathNewNodeSet(ctxt->context->node);
- valuePush(ctxt, tmp);
- ctxt->context->contextSize = oldlocset->locNr;
- ctxt->context->proximityPosition = i + 1;
-
- if (op->ch2 != -1)
- total +=
- xmlXPathCompOpEval(ctxt,
- &comp->steps[op->ch2]);
- CHECK_ERROR0;
-
- /*
- * The result of the evaluation need to be tested to
- * decided whether the filter succeeded or not
- */
- res = valuePop(ctxt);
- if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
- xmlXPtrLocationSetAdd(newlocset,
- xmlXPathObjectCopy
- (oldlocset->locTab[i]));
- }
-
- /*
- * Cleanup
- */
- if (res != NULL)
- xmlXPathFreeObject(res);
- if (ctxt->value == tmp) {
- res = valuePop(ctxt);
- xmlXPathFreeObject(res);
- }
-
- ctxt->context->node = NULL;
- }
-
- /*
- * The result is used as the new evaluation locset.
- */
- xmlXPathFreeObject(obj);
- ctxt->context->node = NULL;
- ctxt->context->contextSize = -1;
- ctxt->context->proximityPosition = -1;
- valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
- ctxt->context->node = oldnode;
- return (total);
- }
-#endif /* LIBXML_XPTR_ENABLED */
-
- /*
- * Extract the old set, and then evaluate the result of the
- * expression for all the element in the set. use it to grow
- * up a new set.
- */
- CHECK_TYPE0(XPATH_NODESET);
- obj = valuePop(ctxt);
- oldset = obj->nodesetval;
-
- oldnode = ctxt->context->node;
- ctxt->context->node = NULL;
-
- if ((oldset == NULL) || (oldset->nodeNr == 0)) {
- ctxt->context->contextSize = 0;
- ctxt->context->proximityPosition = 0;
- if (op->ch2 != -1)
- total +=
- xmlXPathCompOpEval(ctxt,
- &comp->steps[op->ch2]);
- CHECK_ERROR0;
- res = valuePop(ctxt);
- if (res != NULL)
- xmlXPathFreeObject(res);
- valuePush(ctxt, obj);
- ctxt->context->node = oldnode;
- CHECK_ERROR0;
- } else {
- /*
- * Initialize the new set.
- */
- newset = xmlXPathNodeSetCreate(NULL);
-
- for (i = 0; i < oldset->nodeNr; i++) {
- /*
- * Run the evaluation with a node list made of
- * a single item in the nodeset.
- */
- ctxt->context->node = oldset->nodeTab[i];
- tmp = xmlXPathNewNodeSet(ctxt->context->node);
- valuePush(ctxt, tmp);
- ctxt->context->contextSize = oldset->nodeNr;
- ctxt->context->proximityPosition = i + 1;
-
- if (op->ch2 != -1)
- total +=
- xmlXPathCompOpEval(ctxt,
- &comp->steps[op->ch2]);
- CHECK_ERROR0;
-
- /*
- * The result of the evaluation need to be tested to
- * decided whether the filter succeeded or not
- */
- res = valuePop(ctxt);
- if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
- xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);
- }
-
- /*
- * Cleanup
- */
- if (res != NULL)
- xmlXPathFreeObject(res);
- if (ctxt->value == tmp) {
- res = valuePop(ctxt);
- xmlXPathFreeObject(res);
- }
-
- ctxt->context->node = NULL;
- }
-
- /*
- * The result is used as the new evaluation set.
- */
- xmlXPathFreeObject(obj);
- ctxt->context->node = NULL;
- ctxt->context->contextSize = -1;
- ctxt->context->proximityPosition = -1;
- valuePush(ctxt, xmlXPathWrapNodeSet(newset));
- }
- ctxt->context->node = oldnode;
- return (total);
- }
- case XPATH_OP_SORT:
- if (op->ch1 != -1)
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- CHECK_ERROR0;
- if ((ctxt->value != NULL) &&
- (ctxt->value->type == XPATH_NODESET) &&
- (ctxt->value->nodesetval != NULL))
- xmlXPathNodeSetSort(ctxt->value->nodesetval);
- return (total);
-#ifdef LIBXML_XPTR_ENABLED
- case XPATH_OP_RANGETO:{
- xmlXPathObjectPtr range;
- xmlXPathObjectPtr res, obj;
- xmlXPathObjectPtr tmp;
- xmlLocationSetPtr newset = NULL;
- xmlNodeSetPtr oldset;
- int i;
-
- if (op->ch1 != -1)
- total +=
- xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- if (op->ch2 == -1)
- return (total);
-
- CHECK_TYPE0(XPATH_NODESET);
- obj = valuePop(ctxt);
- oldset = obj->nodesetval;
- ctxt->context->node = NULL;
-
- newset = xmlXPtrLocationSetCreate(NULL);
-
- if (oldset != NULL) {
- for (i = 0; i < oldset->nodeNr; i++) {
- /*
- * Run the evaluation with a node list made of a single item
- * in the nodeset.
- */
- ctxt->context->node = oldset->nodeTab[i];
- tmp = xmlXPathNewNodeSet(ctxt->context->node);
- valuePush(ctxt, tmp);
-
- if (op->ch2 != -1)
- total +=
- xmlXPathCompOpEval(ctxt,
- &comp->steps[op->ch2]);
- CHECK_ERROR0;
-
- /*
- * The result of the evaluation need to be tested to
- * decided whether the filter succeeded or not
- */
- res = valuePop(ctxt);
- range =
- xmlXPtrNewRangeNodeObject(oldset->nodeTab[i],
- res);
- if (range != NULL) {
- xmlXPtrLocationSetAdd(newset, range);
- }
-
- /*
- * Cleanup
- */
- if (res != NULL)
- xmlXPathFreeObject(res);
- if (ctxt->value == tmp) {
- res = valuePop(ctxt);
- xmlXPathFreeObject(res);
- }
-
- ctxt->context->node = NULL;
- }
- }
-
- /*
- * The result is used as the new evaluation set.
- */
- xmlXPathFreeObject(obj);
- ctxt->context->node = NULL;
- ctxt->context->contextSize = -1;
- ctxt->context->proximityPosition = -1;
- valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
- return (total);
- }
-#endif /* LIBXML_XPTR_ENABLED */
- }
- xmlGenericError(xmlGenericErrorContext,
- "XPath: unknown precompiled operation %d\n", op->op);
- return (total);
-}
-
-/**
- * xmlXPathRunEval:
- * @ctxt: the XPath parser context with the compiled expression
- *
- * Evaluate the Precompiled XPath expression in the given context.
- */
-static void
-xmlXPathRunEval(xmlXPathParserContextPtr ctxt) {
- xmlXPathCompExprPtr comp;
-
- if ((ctxt == NULL) || (ctxt->comp == NULL))
- return;
-
- if (ctxt->valueTab == NULL) {
- /* Allocate the value stack */
- ctxt->valueTab = (xmlXPathObjectPtr *)
- xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
- if (ctxt->valueTab == NULL) {
- xmlFree(ctxt);
- }
- ctxt->valueNr = 0;
- ctxt->valueMax = 10;
- ctxt->value = NULL;
- }
- comp = ctxt->comp;
- if(comp->last < 0) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathRunEval: last is less than zero\n");
- return;
- }
- xmlXPathCompOpEval(ctxt, &comp->steps[comp->last]);
-}
-
-/************************************************************************
- * *
- * Public interfaces *
- * *
- ************************************************************************/
-
-/**
- * xmlXPathEvalPredicate:
- * @ctxt: the XPath context
- * @res: the Predicate Expression evaluation result
- *
- * Evaluate a predicate result for the current node.
- * A PredicateExpr is evaluated by evaluating the Expr and converting
- * the result to a boolean. If the result is a number, the result will
- * be converted to true if the number is equal to the position of the
- * context node in the context node list (as returned by the position
- * function) and will be converted to false otherwise; if the result
- * is not a number, then the result will be converted as if by a call
- * to the boolean function.
- *
- * Returns 1 if predicate is true, 0 otherwise
- */
-int
-xmlXPathEvalPredicate(xmlXPathContextPtr ctxt, xmlXPathObjectPtr res) {
- if (res == NULL) return(0);
- switch (res->type) {
- case XPATH_BOOLEAN:
- return(res->boolval);
- case XPATH_NUMBER:
- return(res->floatval == ctxt->proximityPosition);
- case XPATH_NODESET:
- case XPATH_XSLT_TREE:
- if (res->nodesetval == NULL)
- return(0);
- return(res->nodesetval->nodeNr != 0);
- case XPATH_STRING:
- return((res->stringval != NULL) &&
- (xmlStrlen(res->stringval) != 0));
- default:
- STRANGE
- }
- return(0);
-}
-
-/**
- * xmlXPathEvaluatePredicateResult:
- * @ctxt: the XPath Parser context
- * @res: the Predicate Expression evaluation result
- *
- * Evaluate a predicate result for the current node.
- * A PredicateExpr is evaluated by evaluating the Expr and converting
- * the result to a boolean. If the result is a number, the result will
- * be converted to true if the number is equal to the position of the
- * context node in the context node list (as returned by the position
- * function) and will be converted to false otherwise; if the result
- * is not a number, then the result will be converted as if by a call
- * to the boolean function.
- *
- * Returns 1 if predicate is true, 0 otherwise
- */
-int
-xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
- xmlXPathObjectPtr res) {
- if (res == NULL) return(0);
- switch (res->type) {
- case XPATH_BOOLEAN:
- return(res->boolval);
- case XPATH_NUMBER:
- return(res->floatval == ctxt->context->proximityPosition);
- case XPATH_NODESET:
- case XPATH_XSLT_TREE:
- if (res->nodesetval == NULL)
- return(0);
- return(res->nodesetval->nodeNr != 0);
- case XPATH_STRING:
- return((res->stringval != NULL) &&
- (xmlStrlen(res->stringval) != 0));
- default:
- STRANGE
- }
- return(0);
-}
-
-/**
- * xmlXPathCompile:
- * @str: the XPath expression
- *
- * Compile an XPath expression
- *
- * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
- * the caller has to free the object.
- */
-xmlXPathCompExprPtr
-xmlXPathCompile(const xmlChar *str) {
- xmlXPathParserContextPtr ctxt;
- xmlXPathCompExprPtr comp;
-
- xmlXPathInit();
-
- ctxt = xmlXPathNewParserContext(str, NULL);
- xmlXPathCompileExpr(ctxt);
-
- if (*ctxt->cur != 0) {
- /*
- * aleksey: in some cases this line prints *second* error message
- * (see bug #78858) and probably this should be fixed.
- * However, we are not sure that all error messages are printed
- * out in other places. It's not critical so we leave it as-is for now
- */
- xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
- comp = NULL;
- } else {
- comp = ctxt->comp;
- ctxt->comp = NULL;
- }
- xmlXPathFreeParserContext(ctxt);
- if (comp != NULL) {
- comp->expr = xmlStrdup(str);
-#ifdef DEBUG_EVAL_COUNTS
- comp->string = xmlStrdup(str);
- comp->nb = 0;
-#endif
- }
- return(comp);
-}
-
-/**
- * xmlXPathCompiledEval:
- * @comp: the compiled XPath expression
- * @ctx: the XPath context
- *
- * Evaluate the Precompiled XPath expression in the given context.
- *
- * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
- * the caller has to free the object.
- */
-xmlXPathObjectPtr
-xmlXPathCompiledEval(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctx) {
- xmlXPathParserContextPtr ctxt;
- xmlXPathObjectPtr res, tmp, init = NULL;
- int stack = 0;
-#ifndef LIBXML_THREAD_ENABLED
- static int reentance = 0;
-#endif
-
- if ((comp == NULL) || (ctx == NULL))
- return(NULL);
- xmlXPathInit();
-
- CHECK_CONTEXT(ctx)
-
-#ifndef LIBXML_THREAD_ENABLED
- reentance++;
- if (reentance > 1)
- xmlXPathDisableOptimizer = 1;
-#endif
-
-#ifdef DEBUG_EVAL_COUNTS
- comp->nb++;
- if ((comp->string != NULL) && (comp->nb > 100)) {
- fprintf(stderr, "100 x %s\n", comp->string);
- comp->nb = 0;
- }
-#endif
- ctxt = xmlXPathCompParserContext(comp, ctx);
- xmlXPathRunEval(ctxt);
-
- if (ctxt->value == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathCompiledEval: evaluation failed\n");
- res = NULL;
- } else {
- res = valuePop(ctxt);
- }
-
-
- do {
- tmp = valuePop(ctxt);
- if (tmp != NULL) {
- if (tmp != init)
- stack++;
- xmlXPathFreeObject(tmp);
- }
- } while (tmp != NULL);
- if ((stack != 0) && (res != NULL)) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathCompiledEval: %d object left on the stack\n",
- stack);
- }
- if (ctxt->error != XPATH_EXPRESSION_OK) {
- xmlXPathFreeObject(res);
- res = NULL;
- }
-
-
- ctxt->comp = NULL;
- xmlXPathFreeParserContext(ctxt);
-#ifndef LIBXML_THREAD_ENABLED
- reentance--;
-#endif
- return(res);
-}
-
-/**
- * xmlXPathEvalExpr:
- * @ctxt: the XPath Parser context
- *
- * Parse and evaluate an XPath expression in the given context,
- * then push the result on the context stack
- */
-void
-xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
- xmlXPathCompileExpr(ctxt);
- CHECK_ERROR;
- xmlXPathRunEval(ctxt);
-}
-
-/**
- * xmlXPathEval:
- * @str: the XPath expression
- * @ctx: the XPath context
- *
- * Evaluate the XPath Location Path in the given context.
- *
- * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
- * the caller has to free the object.
- */
-xmlXPathObjectPtr
-xmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) {
- xmlXPathParserContextPtr ctxt;
- xmlXPathObjectPtr res, tmp, init = NULL;
- int stack = 0;
-
- xmlXPathInit();
-
- CHECK_CONTEXT(ctx)
-
- ctxt = xmlXPathNewParserContext(str, ctx);
- xmlXPathEvalExpr(ctxt);
-
- if (ctxt->value == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathEval: evaluation failed\n");
- res = NULL;
- } else if (*ctxt->cur != 0) {
- xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
- res = NULL;
- } else {
- res = valuePop(ctxt);
- }
-
- do {
- tmp = valuePop(ctxt);
- if (tmp != NULL) {
- if (tmp != init)
- stack++;
- xmlXPathFreeObject(tmp);
- }
- } while (tmp != NULL);
- if ((stack != 0) && (res != NULL)) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathEval: %d object left on the stack\n",
- stack);
- }
- if (ctxt->error != XPATH_EXPRESSION_OK) {
- xmlXPathFreeObject(res);
- res = NULL;
- }
-
- xmlXPathFreeParserContext(ctxt);
- return(res);
-}
-
-/**
- * xmlXPathEvalExpression:
- * @str: the XPath expression
- * @ctxt: the XPath context
- *
- * Evaluate the XPath expression in the given context.
- *
- * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
- * the caller has to free the object.
- */
-xmlXPathObjectPtr
-xmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt) {
- xmlXPathParserContextPtr pctxt;
- xmlXPathObjectPtr res, tmp;
- int stack = 0;
-
- xmlXPathInit();
-
- CHECK_CONTEXT(ctxt)
-
- pctxt = xmlXPathNewParserContext(str, ctxt);
- xmlXPathEvalExpr(pctxt);
-
- if (*pctxt->cur != 0) {
- xmlXPatherror(pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
- res = NULL;
- } else {
- res = valuePop(pctxt);
- }
- do {
- tmp = valuePop(pctxt);
- if (tmp != NULL) {
- xmlXPathFreeObject(tmp);
- stack++;
- }
- } while (tmp != NULL);
- if ((stack != 0) && (res != NULL)) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathEvalExpression: %d object left on the stack\n",
- stack);
- }
- xmlXPathFreeParserContext(pctxt);
- return(res);
-}
-
-/************************************************************************
- * *
- * Extra functions not pertaining to the XPath spec *
- * *
- ************************************************************************/
-/**
- * xmlXPathEscapeUriFunction:
- * @ctxt: the XPath Parser context
- * @nargs: the number of arguments
- *
- * Implement the escape-uri() XPath function
- * string escape-uri(string $str, bool $escape-reserved)
- *
- * This function applies the URI escaping rules defined in section 2 of [RFC
- * 2396] to the string supplied as $uri-part, which typically represents all
- * or part of a URI. The effect of the function is to replace any special
- * character in the string by an escape sequence of the form %xx%yy...,
- * where xxyy... is the hexadecimal representation of the octets used to
- * represent the character in UTF-8.
- *
- * The set of characters that are escaped depends on the setting of the
- * boolean argument $escape-reserved.
- *
- * If $escape-reserved is true, all characters are escaped other than lower
- * case letters a-z, upper case letters A-Z, digits 0-9, and the characters
- * referred to in [RFC 2396] as "marks": specifically, "-" | "_" | "." | "!"
- * | "~" | "*" | "'" | "(" | ")". The "%" character itself is escaped only
- * if it is not followed by two hexadecimal digits (that is, 0-9, a-f, and
- * A-F).
- *
- * If $escape-reserved is false, the behavior differs in that characters
- * referred to in [RFC 2396] as reserved characters are not escaped. These
- * characters are ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ",".
- *
- * [RFC 2396] does not define whether escaped URIs should use lower case or
- * upper case for hexadecimal digits. To ensure that escaped URIs can be
- * compared using string comparison functions, this function must always use
- * the upper-case letters A-F.
- *
- * Generally, $escape-reserved should be set to true when escaping a string
- * that is to form a single part of a URI, and to false when escaping an
- * entire URI or URI reference.
- *
- * In the case of non-ascii characters, the string is encoded according to
- * utf-8 and then converted according to RFC 2396.
- *
- * Examples
- * xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles#ocean"), true())
- * returns "gopher%3A%2F%2Fspinaltap.micro.umn.edu%2F00%2FWeather%2FCalifornia%2FLos%20Angeles%23ocean"
- * xf:escape-uri ("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles#ocean"), false())
- * returns "gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles%23ocean"
- *
- */
-static void
-xmlXPathEscapeUriFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr str;
- int escape_reserved;
- xmlBufferPtr target;
- xmlChar *cptr;
- xmlChar escape[4];
-
- CHECK_ARITY(2);
-
- escape_reserved = xmlXPathPopBoolean(ctxt);
-
- CAST_TO_STRING;
- str = valuePop(ctxt);
-
- target = xmlBufferCreate();
-
- escape[0] = '%';
- escape[3] = 0;
-
- if (target) {
- for (cptr = str->stringval; *cptr; cptr++) {
- if ((*cptr >= 'A' && *cptr <= 'Z') ||
- (*cptr >= 'a' && *cptr <= 'z') ||
- (*cptr >= '0' && *cptr <= '9') ||
- *cptr == '-' || *cptr == '_' || *cptr == '.' ||
- *cptr == '!' || *cptr == '~' || *cptr == '*' ||
- *cptr == '\''|| *cptr == '(' || *cptr == ')' ||
- (*cptr == '%' &&
- ((cptr[1] >= 'A' && cptr[1] <= 'F') ||
- (cptr[1] >= 'a' && cptr[1] <= 'f') ||
- (cptr[1] >= '0' && cptr[1] <= '9')) &&
- ((cptr[2] >= 'A' && cptr[2] <= 'F') ||
- (cptr[2] >= 'a' && cptr[2] <= 'f') ||
- (cptr[2] >= '0' && cptr[2] <= '9'))) ||
- (!escape_reserved &&
- (*cptr == ';' || *cptr == '/' || *cptr == '?' ||
- *cptr == ':' || *cptr == '@' || *cptr == '&' ||
- *cptr == '=' || *cptr == '+' || *cptr == '$' ||
- *cptr == ','))) {
- xmlBufferAdd(target, cptr, 1);
- } else {
- if ((*cptr >> 4) < 10)
- escape[1] = '0' + (*cptr >> 4);
- else
- escape[1] = 'A' - 10 + (*cptr >> 4);
- if ((*cptr & 0xF) < 10)
- escape[2] = '0' + (*cptr & 0xF);
- else
- escape[2] = 'A' - 10 + (*cptr & 0xF);
-
- xmlBufferAdd(target, &escape[0], 3);
- }
- }
- }
- valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
- xmlBufferFree(target);
- xmlXPathFreeObject(str);
-}
-
-/**
- * xmlXPathRegisterAllFunctions:
- * @ctxt: the XPath context
- *
- * Registers all default XPath functions in this context
- */
-void
-xmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt)
-{
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"boolean",
- xmlXPathBooleanFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"ceiling",
- xmlXPathCeilingFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"count",
- xmlXPathCountFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"concat",
- xmlXPathConcatFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"contains",
- xmlXPathContainsFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"id",
- xmlXPathIdFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"false",
- xmlXPathFalseFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"floor",
- xmlXPathFloorFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"last",
- xmlXPathLastFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"lang",
- xmlXPathLangFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"local-name",
- xmlXPathLocalNameFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"not",
- xmlXPathNotFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"name",
- xmlXPathNameFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"namespace-uri",
- xmlXPathNamespaceURIFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize-space",
- xmlXPathNormalizeFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"number",
- xmlXPathNumberFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"position",
- xmlXPathPositionFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"round",
- xmlXPathRoundFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string",
- xmlXPathStringFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string-length",
- xmlXPathStringLengthFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"starts-with",
- xmlXPathStartsWithFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring",
- xmlXPathSubstringFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-before",
- xmlXPathSubstringBeforeFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-after",
- xmlXPathSubstringAfterFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"sum",
- xmlXPathSumFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"true",
- xmlXPathTrueFunction);
- xmlXPathRegisterFunc(ctxt, (const xmlChar *)"translate",
- xmlXPathTranslateFunction);
-
- xmlXPathRegisterFuncNS(ctxt, (const xmlChar *)"escape-uri",
- (const xmlChar *)"http://www.w3.org/2002/08/xquery-functions",
- xmlXPathEscapeUriFunction);
-}
-
-#endif /* LIBXML_XPATH_ENABLED */
diff --git a/bundle/libxml/xpointer.c b/bundle/libxml/xpointer.c
deleted file mode 100644
index 4c4cf991c5..0000000000
--- a/bundle/libxml/xpointer.c
+++ /dev/null
@@ -1,2902 +0,0 @@
-/*
- * xpointer.c : Code to handle XML Pointer
- *
- * World Wide Web Consortium Working Draft 03-March-1998
- * http://www.w3.org/TR/2000/CR-xptr-20000607
- *
- * See Copyright for the status of this software.
- *
- * daniel@veillard.com
- */
-
-#define IN_LIBXML
-#include "libxml.h"
-
-/*
- * TODO: better handling of error cases, the full expression should
- * be parsed beforehand instead of a progressive evaluation
- * TODO: Access into entities references are not supported now ...
- * need a start to be able to pop out of entities refs since
- * parent is the endity declaration, not the ref.
- */
-
-#include <string.h>
-#include <libxml/xpointer.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/parserInternals.h>
-#include <libxml/uri.h>
-#include <libxml/xpath.h>
-#include <libxml/xpathInternals.h>
-#include <libxml/xmlerror.h>
-#include <libxml/globals.h>
-
-#ifdef LIBXML_XPTR_ENABLED
-
-/* Add support of the xmlns() xpointer scheme to initialize the namespaces */
-#define XPTR_XMLNS_SCHEME
-
-/* #define DEBUG_RANGES */
-#ifdef DEBUG_RANGES
-#ifdef LIBXML_DEBUG_ENABLED
-#include <libxml/debugXML.h>
-#endif
-#endif
-
-#define TODO \
- xmlGenericError(xmlGenericErrorContext, \
- "Unimplemented block at %s:%d\n", \
- __FILE__, __LINE__);
-
-#define STRANGE \
- xmlGenericError(xmlGenericErrorContext, \
- "Internal error at %s:%d\n", \
- __FILE__, __LINE__);
-
-/************************************************************************
- * *
- * A few helper functions for child sequences *
- * *
- ************************************************************************/
-
-xmlNodePtr xmlXPtrAdvanceNode(xmlNodePtr cur);
-/**
- * xmlXPtrGetArity:
- * @cur: the node
- *
- * Returns the number of child for an element, -1 in case of error
- */
-static int
-xmlXPtrGetArity(xmlNodePtr cur) {
- int i;
- if (cur == NULL)
- return(-1);
- cur = cur->children;
- for (i = 0;cur != NULL;cur = cur->next) {
- if ((cur->type == XML_ELEMENT_NODE) ||
- (cur->type == XML_DOCUMENT_NODE) ||
- (cur->type == XML_HTML_DOCUMENT_NODE)) {
- i++;
- }
- }
- return(i);
-}
-
-/**
- * xmlXPtrGetIndex:
- * @cur: the node
- *
- * Returns the index of the node in its parent children list, -1
- * in case of error
- */
-static int
-xmlXPtrGetIndex(xmlNodePtr cur) {
- int i;
- if (cur == NULL)
- return(-1);
- for (i = 1;cur != NULL;cur = cur->prev) {
- if ((cur->type == XML_ELEMENT_NODE) ||
- (cur->type == XML_DOCUMENT_NODE) ||
- (cur->type == XML_HTML_DOCUMENT_NODE)) {
- i++;
- }
- }
- return(i);
-}
-
-/**
- * xmlXPtrGetNthChild:
- * @cur: the node
- * @no: the child number
- *
- * Returns the @no'th element child of @cur or NULL
- */
-static xmlNodePtr
-xmlXPtrGetNthChild(xmlNodePtr cur, int no) {
- int i;
- if (cur == NULL)
- return(cur);
- cur = cur->children;
- for (i = 0;i <= no;cur = cur->next) {
- if (cur == NULL)
- return(cur);
- if ((cur->type == XML_ELEMENT_NODE) ||
- (cur->type == XML_DOCUMENT_NODE) ||
- (cur->type == XML_HTML_DOCUMENT_NODE)) {
- i++;
- if (i == no)
- break;
- }
- }
- return(cur);
-}
-
-/************************************************************************
- * *
- * Handling of XPointer specific types *
- * *
- ************************************************************************/
-
-/**
- * xmlXPtrCmpPoints:
- * @node1: the first node
- * @index1: the first index
- * @node2: the second node
- * @index2: the second index
- *
- * Compare two points w.r.t document order
- *
- * Returns -2 in case of error 1 if first point < second point, 0 if
- * that's the same point, -1 otherwise
- */
-static int
-xmlXPtrCmpPoints(xmlNodePtr node1, int index1, xmlNodePtr node2, int index2) {
- if ((node1 == NULL) || (node2 == NULL))
- return(-2);
- /*
- * a couple of optimizations which will avoid computations in most cases
- */
- if (node1 == node2) {
- if (index1 < index2)
- return(1);
- if (index1 > index2)
- return(-1);
- return(0);
- }
- return(xmlXPathCmpNodes(node1, node2));
-}
-
-/**
- * xmlXPtrNewPoint:
- * @node: the xmlNodePtr
- * @indx: the indx within the node
- *
- * Create a new xmlXPathObjectPtr of type point
- *
- * Returns the newly created object.
- */
-static xmlXPathObjectPtr
-xmlXPtrNewPoint(xmlNodePtr node, int indx) {
- xmlXPathObjectPtr ret;
-
- if (node == NULL)
- return(NULL);
- if (indx < 0)
- return(NULL);
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrNewPoint: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_POINT;
- ret->user = (void *) node;
- ret->index = indx;
- return(ret);
-}
-
-/**
- * xmlXPtrRangeCheckOrder:
- * @range: an object range
- *
- * Make sure the points in the range are in the right order
- */
-static void
-xmlXPtrRangeCheckOrder(xmlXPathObjectPtr range) {
- int tmp;
- xmlNodePtr tmp2;
- if (range == NULL)
- return;
- if (range->type != XPATH_RANGE)
- return;
- if (range->user2 == NULL)
- return;
- tmp = xmlXPtrCmpPoints(range->user, range->index,
- range->user2, range->index2);
- if (tmp == -1) {
- tmp2 = range->user;
- range->user = range->user2;
- range->user2 = tmp2;
- tmp = range->index;
- range->index = range->index2;
- range->index2 = tmp;
- }
-}
-
-/**
- * xmlXPtrRangesEqual:
- * @range1: the first range
- * @range2: the second range
- *
- * Compare two ranges
- *
- * Returns 1 if equal, 0 otherwise
- */
-static int
-xmlXPtrRangesEqual(xmlXPathObjectPtr range1, xmlXPathObjectPtr range2) {
- if (range1 == range2)
- return(1);
- if ((range1 == NULL) || (range2 == NULL))
- return(0);
- if (range1->type != range2->type)
- return(0);
- if (range1->type != XPATH_RANGE)
- return(0);
- if (range1->user != range2->user)
- return(0);
- if (range1->index != range2->index)
- return(0);
- if (range1->user2 != range2->user2)
- return(0);
- if (range1->index2 != range2->index2)
- return(0);
- return(1);
-}
-
-/**
- * xmlXPtrNewRange:
- * @start: the starting node
- * @startindex: the start index
- * @end: the ending point
- * @endindex: the ending index
- *
- * Create a new xmlXPathObjectPtr of type range
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPtrNewRange(xmlNodePtr start, int startindex,
- xmlNodePtr end, int endindex) {
- xmlXPathObjectPtr ret;
-
- if (start == NULL)
- return(NULL);
- if (end == NULL)
- return(NULL);
- if (startindex < 0)
- return(NULL);
- if (endindex < 0)
- return(NULL);
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrNewRange: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_RANGE;
- ret->user = start;
- ret->index = startindex;
- ret->user2 = end;
- ret->index2 = endindex;
- xmlXPtrRangeCheckOrder(ret);
- return(ret);
-}
-
-/**
- * xmlXPtrNewRangePoints:
- * @start: the starting point
- * @end: the ending point
- *
- * Create a new xmlXPathObjectPtr of type range using 2 Points
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPtrNewRangePoints(xmlXPathObjectPtr start, xmlXPathObjectPtr end) {
- xmlXPathObjectPtr ret;
-
- if (start == NULL)
- return(NULL);
- if (end == NULL)
- return(NULL);
- if (start->type != XPATH_POINT)
- return(NULL);
- if (end->type != XPATH_POINT)
- return(NULL);
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrNewRangePoints: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_RANGE;
- ret->user = start->user;
- ret->index = start->index;
- ret->user2 = end->user;
- ret->index2 = end->index;
- xmlXPtrRangeCheckOrder(ret);
- return(ret);
-}
-
-/**
- * xmlXPtrNewRangePointNode:
- * @start: the starting point
- * @end: the ending node
- *
- * Create a new xmlXPathObjectPtr of type range from a point to a node
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPtrNewRangePointNode(xmlXPathObjectPtr start, xmlNodePtr end) {
- xmlXPathObjectPtr ret;
-
- if (start == NULL)
- return(NULL);
- if (end == NULL)
- return(NULL);
- if (start->type != XPATH_POINT)
- return(NULL);
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrNewRangePointNode: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_RANGE;
- ret->user = start->user;
- ret->index = start->index;
- ret->user2 = end;
- ret->index2 = -1;
- xmlXPtrRangeCheckOrder(ret);
- return(ret);
-}
-
-/**
- * xmlXPtrNewRangeNodePoint:
- * @start: the starting node
- * @end: the ending point
- *
- * Create a new xmlXPathObjectPtr of type range from a node to a point
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPtrNewRangeNodePoint(xmlNodePtr start, xmlXPathObjectPtr end) {
- xmlXPathObjectPtr ret;
-
- if (start == NULL)
- return(NULL);
- if (end == NULL)
- return(NULL);
- if (start->type != XPATH_POINT)
- return(NULL);
- if (end->type != XPATH_POINT)
- return(NULL);
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrNewRangeNodePoint: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_RANGE;
- ret->user = start;
- ret->index = -1;
- ret->user2 = end->user;
- ret->index2 = end->index;
- xmlXPtrRangeCheckOrder(ret);
- return(ret);
-}
-
-/**
- * xmlXPtrNewRangeNodes:
- * @start: the starting node
- * @end: the ending node
- *
- * Create a new xmlXPathObjectPtr of type range using 2 nodes
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPtrNewRangeNodes(xmlNodePtr start, xmlNodePtr end) {
- xmlXPathObjectPtr ret;
-
- if (start == NULL)
- return(NULL);
- if (end == NULL)
- return(NULL);
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrNewRangeNodes: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_RANGE;
- ret->user = start;
- ret->index = -1;
- ret->user2 = end;
- ret->index2 = -1;
- xmlXPtrRangeCheckOrder(ret);
- return(ret);
-}
-
-/**
- * xmlXPtrNewCollapsedRange:
- * @start: the starting and ending node
- *
- * Create a new xmlXPathObjectPtr of type range using a single nodes
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPtrNewCollapsedRange(xmlNodePtr start) {
- xmlXPathObjectPtr ret;
-
- if (start == NULL)
- return(NULL);
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrNewCollapsedRange: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_RANGE;
- ret->user = start;
- ret->index = -1;
- ret->user2 = NULL;
- ret->index2 = -1;
- return(ret);
-}
-
-/**
- * xmlXPtrNewRangeNodeObject:
- * @start: the starting node
- * @end: the ending object
- *
- * Create a new xmlXPathObjectPtr of type range from a not to an object
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
- xmlXPathObjectPtr ret;
-
- if (start == NULL)
- return(NULL);
- if (end == NULL)
- return(NULL);
- switch (end->type) {
- case XPATH_POINT:
- break;
- case XPATH_NODESET:
- /*
- * Empty set ...
- */
- if (end->nodesetval->nodeNr <= 0)
- return(NULL);
- break;
- default:
- TODO
- return(NULL);
- }
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrNewRangeNodeObject: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_RANGE;
- ret->user = start;
- ret->index = -1;
- switch (end->type) {
- case XPATH_POINT:
- ret->user2 = end->user;
- ret->index2 = end->index;
- case XPATH_NODESET: {
- ret->user2 = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
- ret->index2 = -1;
- break;
- }
- default:
- STRANGE
- return(NULL);
- }
- xmlXPtrRangeCheckOrder(ret);
- return(ret);
-}
-
-#define XML_RANGESET_DEFAULT 10
-
-/**
- * xmlXPtrLocationSetCreate:
- * @val: an initial xmlXPathObjectPtr, or NULL
- *
- * Create a new xmlLocationSetPtr of type double and of value @val
- *
- * Returns the newly created object.
- */
-xmlLocationSetPtr
-xmlXPtrLocationSetCreate(xmlXPathObjectPtr val) {
- xmlLocationSetPtr ret;
-
- ret = (xmlLocationSetPtr) xmlMalloc(sizeof(xmlLocationSet));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrLocationSetCreate: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlLocationSet));
- if (val != NULL) {
- ret->locTab = (xmlXPathObjectPtr *) xmlMalloc(XML_RANGESET_DEFAULT *
- sizeof(xmlXPathObjectPtr));
- if (ret->locTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrLocationSetCreate: out of memory\n");
- return(NULL);
- }
- memset(ret->locTab, 0 ,
- XML_RANGESET_DEFAULT * (size_t) sizeof(xmlXPathObjectPtr));
- ret->locMax = XML_RANGESET_DEFAULT;
- ret->locTab[ret->locNr++] = val;
- }
- return(ret);
-}
-
-/**
- * xmlXPtrLocationSetAdd:
- * @cur: the initial range set
- * @val: a new xmlXPathObjectPtr
- *
- * add a new xmlXPathObjectPtr to an existing LocationSet
- * If the location already exist in the set @val is freed.
- */
-void
-xmlXPtrLocationSetAdd(xmlLocationSetPtr cur, xmlXPathObjectPtr val) {
- int i;
-
- if (val == NULL) return;
-
- /*
- * check against doublons
- */
- for (i = 0;i < cur->locNr;i++) {
- if (xmlXPtrRangesEqual(cur->locTab[i], val)) {
- xmlXPathFreeObject(val);
- return;
- }
- }
-
- /*
- * grow the locTab if needed
- */
- if (cur->locMax == 0) {
- cur->locTab = (xmlXPathObjectPtr *) xmlMalloc(XML_RANGESET_DEFAULT *
- sizeof(xmlXPathObjectPtr));
- if (cur->locTab == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrLocationSetAdd: out of memory\n");
- return;
- }
- memset(cur->locTab, 0 ,
- XML_RANGESET_DEFAULT * (size_t) sizeof(xmlXPathObjectPtr));
- cur->locMax = XML_RANGESET_DEFAULT;
- } else if (cur->locNr == cur->locMax) {
- xmlXPathObjectPtr *temp;
-
- cur->locMax *= 2;
- temp = (xmlXPathObjectPtr *) xmlRealloc(cur->locTab, cur->locMax *
- sizeof(xmlXPathObjectPtr));
- if (temp == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrLocationSetAdd: out of memory\n");
- return;
- }
- cur->locTab = temp;
- }
- cur->locTab[cur->locNr++] = val;
-}
-
-/**
- * xmlXPtrLocationSetMerge:
- * @val1: the first LocationSet
- * @val2: the second LocationSet
- *
- * Merges two rangesets, all ranges from @val2 are added to @val1
- *
- * Returns val1 once extended or NULL in case of error.
- */
-xmlLocationSetPtr
-xmlXPtrLocationSetMerge(xmlLocationSetPtr val1, xmlLocationSetPtr val2) {
- int i;
-
- if (val1 == NULL) return(NULL);
- if (val2 == NULL) return(val1);
-
- /*
- * !!!!! this can be optimized a lot, knowing that both
- * val1 and val2 already have unicity of their values.
- */
-
- for (i = 0;i < val2->locNr;i++)
- xmlXPtrLocationSetAdd(val1, val2->locTab[i]);
-
- return(val1);
-}
-
-/**
- * xmlXPtrLocationSetDel:
- * @cur: the initial range set
- * @val: an xmlXPathObjectPtr
- *
- * Removes an xmlXPathObjectPtr from an existing LocationSet
- */
-void
-xmlXPtrLocationSetDel(xmlLocationSetPtr cur, xmlXPathObjectPtr val) {
- int i;
-
- if (cur == NULL) return;
- if (val == NULL) return;
-
- /*
- * check against doublons
- */
- for (i = 0;i < cur->locNr;i++)
- if (cur->locTab[i] == val) break;
-
- if (i >= cur->locNr) {
-#ifdef DEBUG
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrLocationSetDel: Range wasn't found in RangeList\n");
-#endif
- return;
- }
- cur->locNr--;
- for (;i < cur->locNr;i++)
- cur->locTab[i] = cur->locTab[i + 1];
- cur->locTab[cur->locNr] = NULL;
-}
-
-/**
- * xmlXPtrLocationSetRemove:
- * @cur: the initial range set
- * @val: the index to remove
- *
- * Removes an entry from an existing LocationSet list.
- */
-void
-xmlXPtrLocationSetRemove(xmlLocationSetPtr cur, int val) {
- if (cur == NULL) return;
- if (val >= cur->locNr) return;
- cur->locNr--;
- for (;val < cur->locNr;val++)
- cur->locTab[val] = cur->locTab[val + 1];
- cur->locTab[cur->locNr] = NULL;
-}
-
-/**
- * xmlXPtrFreeLocationSet:
- * @obj: the xmlLocationSetPtr to free
- *
- * Free the LocationSet compound (not the actual ranges !).
- */
-void
-xmlXPtrFreeLocationSet(xmlLocationSetPtr obj) {
- int i;
-
- if (obj == NULL) return;
- if (obj->locTab != NULL) {
- for (i = 0;i < obj->locNr; i++) {
- xmlXPathFreeObject(obj->locTab[i]);
- }
- xmlFree(obj->locTab);
- }
- xmlFree(obj);
-}
-
-/**
- * xmlXPtrNewLocationSetNodes:
- * @start: the start NodePtr value
- * @end: the end NodePtr value or NULL
- *
- * Create a new xmlXPathObjectPtr of type LocationSet and initialize
- * it with the single range made of the two nodes @start and @end
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPtrNewLocationSetNodes(xmlNodePtr start, xmlNodePtr end) {
- xmlXPathObjectPtr ret;
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrNewLocationSetNodes: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_LOCATIONSET;
- if (end == NULL)
- ret->user = xmlXPtrLocationSetCreate(xmlXPtrNewCollapsedRange(start));
- else
- ret->user = xmlXPtrLocationSetCreate(xmlXPtrNewRangeNodes(start,end));
- return(ret);
-}
-
-/**
- * xmlXPtrNewLocationSetNodeSet:
- * @set: a node set
- *
- * Create a new xmlXPathObjectPtr of type LocationSet and initialize
- * it with all the nodes from @set
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPtrNewLocationSetNodeSet(xmlNodeSetPtr set) {
- xmlXPathObjectPtr ret;
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrNewLocationSetNodeSet: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_LOCATIONSET;
- if (set != NULL) {
- int i;
- xmlLocationSetPtr newset;
-
- newset = xmlXPtrLocationSetCreate(NULL);
- if (newset == NULL)
- return(ret);
-
- for (i = 0;i < set->nodeNr;i++)
- xmlXPtrLocationSetAdd(newset,
- xmlXPtrNewCollapsedRange(set->nodeTab[i]));
-
- ret->user = (void *) newset;
- }
- return(ret);
-}
-
-/**
- * xmlXPtrWrapLocationSet:
- * @val: the LocationSet value
- *
- * Wrap the LocationSet @val in a new xmlXPathObjectPtr
- *
- * Returns the newly created object.
- */
-xmlXPathObjectPtr
-xmlXPtrWrapLocationSet(xmlLocationSetPtr val) {
- xmlXPathObjectPtr ret;
-
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
- if (ret == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrWrapLocationSet: out of memory\n");
- return(NULL);
- }
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
- ret->type = XPATH_LOCATIONSET;
- ret->user = (void *) val;
- return(ret);
-}
-
-/************************************************************************
- * *
- * The parser *
- * *
- ************************************************************************/
-
-/*
- * Macros for accessing the content. Those should be used only by the parser,
- * and not exported.
- *
- * Dirty macros, i.e. one need to make assumption on the context to use them
- *
- * CUR_PTR return the current pointer to the xmlChar to be parsed.
- * CUR returns the current xmlChar value, i.e. a 8 bit value
- * in ISO-Latin or UTF-8.
- * This should be used internally by the parser
- * only to compare to ASCII values otherwise it would break when
- * running with UTF-8 encoding.
- * NXT(n) returns the n'th next xmlChar. Same as CUR is should be used only
- * to compare on ASCII based substring.
- * SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
- * strings within the parser.
- * CURRENT Returns the current char value, with the full decoding of
- * UTF-8 if we are using this mode. It returns an int.
- * NEXT Skip to the next character, this does the proper decoding
- * in UTF-8 mode. It also pop-up unfinished entities on the fly.
- * It returns the pointer to the current xmlChar.
- */
-
-#define CUR (*ctxt->cur)
-#define SKIP(val) ctxt->cur += (val)
-#define NXT(val) ctxt->cur[(val)]
-#define CUR_PTR ctxt->cur
-
-#define SKIP_BLANKS \
- while (IS_BLANK(*(ctxt->cur))) NEXT
-
-#define CURRENT (*ctxt->cur)
-#define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur)
-
-/*
- * xmlXPtrGetChildNo:
- * @ctxt: the XPointer Parser context
- * @index: the child number
- *
- * Move the current node of the nodeset on the stack to the
- * given child if found
- */
-static void
-xmlXPtrGetChildNo(xmlXPathParserContextPtr ctxt, int indx) {
- xmlNodePtr cur = NULL;
- xmlXPathObjectPtr obj;
- xmlNodeSetPtr oldset;
-
- CHECK_TYPE(XPATH_NODESET);
- obj = valuePop(ctxt);
- oldset = obj->nodesetval;
- if ((indx <= 0) || (oldset == NULL) || (oldset->nodeNr != 1)) {
- xmlXPathFreeObject(obj);
- valuePush(ctxt, xmlXPathNewNodeSet(NULL));
- return;
- }
- cur = xmlXPtrGetNthChild(oldset->nodeTab[0], indx);
- if (cur == NULL) {
- xmlXPathFreeObject(obj);
- valuePush(ctxt, xmlXPathNewNodeSet(NULL));
- return;
- }
- oldset->nodeTab[0] = cur;
- valuePush(ctxt, obj);
-}
-
-/**
- * xmlXPtrEvalXPtrPart:
- * @ctxt: the XPointer Parser context
- * @name: the preparsed Scheme for the XPtrPart
- *
- * XPtrPart ::= 'xpointer' '(' XPtrExpr ')'
- * | Scheme '(' SchemeSpecificExpr ')'
- *
- * Scheme ::= NCName - 'xpointer' [VC: Non-XPointer schemes]
- *
- * SchemeSpecificExpr ::= StringWithBalancedParens
- *
- * StringWithBalancedParens ::=
- * [^()]* ('(' StringWithBalancedParens ')' [^()]*)*
- * [VC: Parenthesis escaping]
- *
- * XPtrExpr ::= Expr [VC: Parenthesis escaping]
- *
- * VC: Parenthesis escaping:
- * The end of an XPointer part is signaled by the right parenthesis ")"
- * character that is balanced with the left parenthesis "(" character
- * that began the part. Any unbalanced parenthesis character inside the
- * expression, even within literals, must be escaped with a circumflex (^)
- * character preceding it. If the expression contains any literal
- * occurrences of the circumflex, each must be escaped with an additional
- * circumflex (that is, ^^). If the unescaped parentheses in the expression
- * are not balanced, a syntax error results.
- *
- * Parse and evaluate an XPtrPart. Basically it generates the unescaped
- * string and if the scheme is 'xpointer' it will call the XPath interpreter.
- *
- * TODO: there is no new scheme registration mechanism
- */
-
-static void
-xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
- xmlChar *buffer, *cur;
- int len;
- int level;
-
- if (name == NULL)
- name = xmlXPathParseName(ctxt);
- if (name == NULL)
- XP_ERROR(XPATH_EXPR_ERROR);
-
- if (CUR != '(')
- XP_ERROR(XPATH_EXPR_ERROR);
- NEXT;
- level = 1;
-
- len = xmlStrlen(ctxt->cur);
- len++;
- buffer = (xmlChar *) xmlMalloc(len * sizeof (xmlChar));
- if (buffer == NULL) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrEvalXPtrPart: out of memory\n");
- return;
- }
-
- cur = buffer;
- while (CUR != 0) {
- if (CUR == ')') {
- level--;
- if (level == 0) {
- NEXT;
- break;
- }
- *cur++ = CUR;
- } else if (CUR == '(') {
- level++;
- *cur++ = CUR;
- } else if (CUR == '^') {
- NEXT;
- if ((CUR == ')') || (CUR == '(') || (CUR == '^')) {
- *cur++ = CUR;
- } else {
- *cur++ = '^';
- *cur++ = CUR;
- }
- } else {
- *cur++ = CUR;
- }
- NEXT;
- }
- *cur = 0;
-
- if ((level != 0) && (CUR == 0)) {
- xmlFree(buffer);
- XP_ERROR(XPTR_SYNTAX_ERROR);
- }
-
- if (xmlStrEqual(name, (xmlChar *) "xpointer")) {
- const xmlChar *left = CUR_PTR;
-
- CUR_PTR = buffer;
- xmlXPathEvalExpr(ctxt);
- CUR_PTR=left;
-#ifdef XPTR_XMLNS_SCHEME
- } else if (xmlStrEqual(name, (xmlChar *) "xmlns")) {
- const xmlChar *left = CUR_PTR;
- xmlChar *prefix;
- xmlChar *URI;
- xmlURIPtr value;
-
- CUR_PTR = buffer;
- prefix = xmlXPathParseNCName(ctxt);
- if (prefix == NULL) {
- xmlFree(buffer);
- xmlFree(name);
- XP_ERROR(XPTR_SYNTAX_ERROR);
- }
- SKIP_BLANKS;
- if (CUR != '=') {
- xmlFree(prefix);
- xmlFree(buffer);
- xmlFree(name);
- XP_ERROR(XPTR_SYNTAX_ERROR);
- }
- NEXT;
- SKIP_BLANKS;
- /* @@ check escaping in the XPointer WD */
-
- value = xmlParseURI((const char *)ctxt->cur);
- if (value == NULL) {
- xmlFree(prefix);
- xmlFree(buffer);
- xmlFree(name);
- XP_ERROR(XPTR_SYNTAX_ERROR);
- }
- URI = xmlSaveUri(value);
- xmlFreeURI(value);
- if (URI == NULL) {
- xmlFree(prefix);
- xmlFree(buffer);
- xmlFree(name);
- XP_ERROR(XPATH_MEMORY_ERROR);
- }
-
- xmlXPathRegisterNs(ctxt->context, prefix, URI);
- CUR_PTR = left;
- xmlFree(URI);
- xmlFree(prefix);
-#endif /* XPTR_XMLNS_SCHEME */
- } else {
- xmlGenericError(xmlGenericErrorContext,
- "unsupported scheme '%s'\n", name);
- }
- xmlFree(buffer);
- xmlFree(name);
-}
-
-/**
- * xmlXPtrEvalFullXPtr:
- * @ctxt: the XPointer Parser context
- * @name: the preparsed Scheme for the first XPtrPart
- *
- * FullXPtr ::= XPtrPart (S? XPtrPart)*
- *
- * As the specs says:
- * -----------
- * When multiple XPtrParts are provided, they must be evaluated in
- * left-to-right order. If evaluation of one part fails, the nexti
- * is evaluated. The following conditions cause XPointer part failure:
- *
- * - An unknown scheme
- * - A scheme that does not locate any sub-resource present in the resource
- * - A scheme that is not applicable to the media type of the resource
- *
- * The XPointer application must consume a failed XPointer part and
- * attempt to evaluate the next one, if any. The result of the first
- * XPointer part whose evaluation succeeds is taken to be the fragment
- * located by the XPointer as a whole. If all the parts fail, the result
- * for the XPointer as a whole is a sub-resource error.
- * -----------
- *
- * Parse and evaluate a Full XPtr i.e. possibly a cascade of XPath based
- * expressions or other schemes.
- */
-static void
-xmlXPtrEvalFullXPtr(xmlXPathParserContextPtr ctxt, xmlChar *name) {
- if (name == NULL)
- name = xmlXPathParseName(ctxt);
- if (name == NULL)
- XP_ERROR(XPATH_EXPR_ERROR);
- while (name != NULL) {
- xmlXPtrEvalXPtrPart(ctxt, name);
-
- /* in case of syntax error, break here */
- if (ctxt->error != XPATH_EXPRESSION_OK)
- return;
-
- /*
- * If the returned value is a non-empty nodeset
- * or location set, return here.
- */
- if (ctxt->value != NULL) {
- xmlXPathObjectPtr obj = ctxt->value;
-
- switch (obj->type) {
- case XPATH_LOCATIONSET: {
- xmlLocationSetPtr loc = ctxt->value->user;
- if ((loc != NULL) && (loc->locNr > 0))
- return;
- break;
- }
- case XPATH_NODESET: {
- xmlNodeSetPtr loc = ctxt->value->nodesetval;
- if ((loc != NULL) && (loc->nodeNr > 0))
- return;
- break;
- }
- default:
- break;
- }
-
- /*
- * Evaluating to improper values is equivalent to
- * a sub-resource error, clean-up the stack
- */
- do {
- obj = valuePop(ctxt);
- if (obj != NULL) {
- xmlXPathFreeObject(obj);
- }
- } while (obj != NULL);
- }
-
- /*
- * Is there another XPointer part.
- */
- SKIP_BLANKS;
- name = xmlXPathParseName(ctxt);
- }
-}
-
-/**
- * xmlXPtrEvalChildSeq:
- * @ctxt: the XPointer Parser context
- * @name: a possible ID name of the child sequence
- *
- * ChildSeq ::= '/1' ('/' [0-9]*)*
- * | Name ('/' [0-9]*)+
- *
- * Parse and evaluate a Child Sequence. This routine also handle the
- * case of a Bare Name used to get a document ID.
- */
-static void
-xmlXPtrEvalChildSeq(xmlXPathParserContextPtr ctxt, xmlChar *name) {
- /*
- * XPointer don't allow by syntax to address in mutirooted trees
- * this might prove useful in some cases, warn about it.
- */
- if ((name == NULL) && (CUR == '/') && (NXT(1) != '1')) {
- xmlGenericError(xmlGenericErrorContext,
- "warning: ChildSeq not starting by /1\n");
- }
-
- if (name != NULL) {
- valuePush(ctxt, xmlXPathNewString(name));
- xmlFree(name);
- xmlXPathIdFunction(ctxt, 1);
- CHECK_ERROR;
- }
-
- while (CUR == '/') {
- int child = 0;
- NEXT;
-
- while ((CUR >= '0') && (CUR <= '9')) {
- child = child * 10 + (CUR - '0');
- NEXT;
- }
- xmlXPtrGetChildNo(ctxt, child);
- }
-}
-
-
-/**
- * xmlXPtrEvalXPointer:
- * @ctxt: the XPointer Parser context
- *
- * XPointer ::= Name
- * | ChildSeq
- * | FullXPtr
- *
- * Parse and evaluate an XPointer
- */
-static void
-xmlXPtrEvalXPointer(xmlXPathParserContextPtr ctxt) {
- if (ctxt->valueTab == NULL) {
- /* Allocate the value stack */
- ctxt->valueTab = (xmlXPathObjectPtr *)
- xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
- if (ctxt->valueTab == NULL) {
- xmlFree(ctxt);
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPathEvalXPointer: out of memory\n");
- return;
- }
- ctxt->valueNr = 0;
- ctxt->valueMax = 10;
- ctxt->value = NULL;
- }
- SKIP_BLANKS;
- if (CUR == '/') {
- xmlXPathRoot(ctxt);
- xmlXPtrEvalChildSeq(ctxt, NULL);
- } else {
- xmlChar *name;
-
- name = xmlXPathParseName(ctxt);
- if (name == NULL)
- XP_ERROR(XPATH_EXPR_ERROR);
- if (CUR == '(') {
- xmlXPtrEvalFullXPtr(ctxt, name);
- /* Short evaluation */
- return;
- } else {
- /* this handle both Bare Names and Child Sequences */
- xmlXPtrEvalChildSeq(ctxt, name);
- }
- }
- SKIP_BLANKS;
- if (CUR != 0)
- XP_ERROR(XPATH_EXPR_ERROR);
-}
-
-
-/************************************************************************
- * *
- * General routines *
- * *
- ************************************************************************/
-
-void xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs);
-void xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs);
-
-/**
- * xmlXPtrNewContext:
- * @doc: the XML document
- * @here: the node that directly contains the XPointer being evaluated or NULL
- * @origin: the element from which a user or program initiated traversal of
- * the link, or NULL.
- *
- * Create a new XPointer context
- *
- * Returns the xmlXPathContext just allocated.
- */
-xmlXPathContextPtr
-xmlXPtrNewContext(xmlDocPtr doc, xmlNodePtr here, xmlNodePtr origin) {
- xmlXPathContextPtr ret;
-
- ret = xmlXPathNewContext(doc);
- if (ret == NULL)
- return(ret);
- ret->xptr = 1;
- ret->here = here;
- ret->origin = origin;
-
- xmlXPathRegisterFunc(ret, (xmlChar *)"range-to",
- xmlXPtrRangeToFunction);
- xmlXPathRegisterFunc(ret, (xmlChar *)"range",
- xmlXPtrRangeFunction);
- xmlXPathRegisterFunc(ret, (xmlChar *)"range-inside",
- xmlXPtrRangeInsideFunction);
- xmlXPathRegisterFunc(ret, (xmlChar *)"string-range",
- xmlXPtrStringRangeFunction);
- xmlXPathRegisterFunc(ret, (xmlChar *)"start-point",
- xmlXPtrStartPointFunction);
- xmlXPathRegisterFunc(ret, (xmlChar *)"end-point",
- xmlXPtrEndPointFunction);
- xmlXPathRegisterFunc(ret, (xmlChar *)"here",
- xmlXPtrHereFunction);
- xmlXPathRegisterFunc(ret, (xmlChar *)" origin",
- xmlXPtrOriginFunction);
-
- return(ret);
-}
-
-/**
- * xmlXPtrEval:
- * @str: the XPointer expression
- * @ctx: the XPointer context
- *
- * Evaluate the XPath Location Path in the given context.
- *
- * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
- * the caller has to free the object.
- */
-xmlXPathObjectPtr
-xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) {
- xmlXPathParserContextPtr ctxt;
- xmlXPathObjectPtr res = NULL, tmp;
- xmlXPathObjectPtr init = NULL;
- int stack = 0;
-
- xmlXPathInit();
-
- if ((ctx == NULL) || (str == NULL))
- return(NULL);
-
- ctxt = xmlXPathNewParserContext(str, ctx);
- ctxt->xptr = 1;
- xmlXPtrEvalXPointer(ctxt);
-
- if ((ctxt->value != NULL) &&
- (ctxt->value->type != XPATH_NODESET) &&
- (ctxt->value->type != XPATH_LOCATIONSET)) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrEval: evaluation failed to return a node set\n");
- } else {
- res = valuePop(ctxt);
- }
-
- do {
- tmp = valuePop(ctxt);
- if (tmp != NULL) {
- if (tmp != init) {
- if (tmp->type == XPATH_NODESET) {
- /*
- * Evaluation may push a root nodeset which is unused
- */
- xmlNodeSetPtr set;
- set = tmp->nodesetval;
- if ((set->nodeNr != 1) ||
- (set->nodeTab[0] != (xmlNodePtr) ctx->doc))
- stack++;
- } else
- stack++;
- }
- xmlXPathFreeObject(tmp);
- }
- } while (tmp != NULL);
- if (stack != 0) {
- xmlGenericError(xmlGenericErrorContext,
- "xmlXPtrEval: %d object left on the stack\n",
- stack);
- }
- if (ctxt->error != XPATH_EXPRESSION_OK) {
- xmlXPathFreeObject(res);
- res = NULL;
- }
-
- xmlXPathFreeParserContext(ctxt);
- return(res);
-}
-
-/**
- * xmlXPtrBuildRangeNodeList:
- * @range: a range object
- *
- * Build a node list tree copy of the range
- *
- * Returns an xmlNodePtr list or NULL.
- * the caller has to free the node tree.
- */
-static xmlNodePtr
-xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {
- /* pointers to generated nodes */
- xmlNodePtr list = NULL, last = NULL, parent = NULL, tmp;
- /* pointers to traversal nodes */
- xmlNodePtr start, cur, end;
- int index1, index2;
-
- if (range == NULL)
- return(NULL);
- if (range->type != XPATH_RANGE)
- return(NULL);
- start = (xmlNodePtr) range->user;
-
- if (start == NULL)
- return(NULL);
- end = range->user2;
- if (end == NULL)
- return(xmlCopyNode(start, 1));
-
- cur = start;
- index1 = range->index;
- index2 = range->index2;
- while (cur != NULL) {
- if (cur == end) {
- if (cur->type == XML_TEXT_NODE) {
- const xmlChar *content = cur->content;
- int len;
-
- if (content == NULL) {
- tmp = xmlNewTextLen(NULL, 0);
- } else {
- len = index2;
- if ((cur == start) && (index1 > 1)) {
- content += (index1 - 1);
- len -= (index1 - 1);
- index1 = 0;
- } else {
- len = index2;
- }
- tmp = xmlNewTextLen(content, len);
- }
- /* single sub text node selection */
- if (list == NULL)
- return(tmp);
- /* prune and return full set */
- if (last != NULL)
- xmlAddNextSibling(last, tmp);
- else
- xmlAddChild(parent, tmp);
- return(list);
- } else {
- tmp = xmlCopyNode(cur, 0);
- if (list == NULL)
- list = tmp;
- else {
- if (last != NULL)
- xmlAddNextSibling(last, tmp);
- else
- xmlAddChild(parent, tmp);
- }
- last = NULL;
- parent = tmp;
-
- if (index2 > 1) {
- end = xmlXPtrGetNthChild(cur, index2 - 1);
- index2 = 0;
- }
- if ((cur == start) && (index1 > 1)) {
- cur = xmlXPtrGetNthChild(cur, index1 - 1);
- index1 = 0;
- } else {
- cur = cur->children;
- }
- /*
- * Now gather the remaining nodes from cur to end
- */
- continue; /* while */
- }
- } else if ((cur == start) &&
- (list == NULL) /* looks superfluous but ... */ ) {
- if ((cur->type == XML_TEXT_NODE) ||
- (cur->type == XML_CDATA_SECTION_NODE)) {
- const xmlChar *content = cur->content;
-
- if (content == NULL) {
- tmp = xmlNewTextLen(NULL, 0);
- } else {
- if (index1 > 1) {
- content += (index1 - 1);
- }
- tmp = xmlNewText(content);
- }
- last = list = tmp;
- } else {
- if ((cur == start) && (index1 > 1)) {
- tmp = xmlCopyNode(cur, 0);
- list = tmp;
- parent = tmp;
- last = NULL;
- cur = xmlXPtrGetNthChild(cur, index1 - 1);
- index1 = 0;
- /*
- * Now gather the remaining nodes from cur to end
- */
- continue; /* while */
- }
- tmp = xmlCopyNode(cur, 1);
- list = tmp;
- parent = NULL;
- last = tmp;
- }
- } else {
- tmp = NULL;
- switch (cur->type) {
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_NODE:
- /* Do not copy DTD informations */
- break;
- case XML_ENTITY_DECL:
- TODO /* handle crossing entities -> stack needed */
- break;
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- /* don't consider it part of the tree content */
- break;
- case XML_ATTRIBUTE_NODE:
- /* Humm, should not happen ! */
- STRANGE
- break;
- default:
- tmp = xmlCopyNode(cur, 1);
- break;
- }
- if (tmp != NULL) {
- if ((list == NULL) || ((last == NULL) && (parent == NULL))) {
- STRANGE
- return(NULL);
- }
- if (last != NULL)
- xmlAddNextSibling(last, tmp);
- else {
- xmlAddChild(parent, tmp);
- last = tmp;
- }
- }
- }
- /*
- * Skip to next node in document order
- */
- if ((list == NULL) || ((last == NULL) && (parent == NULL))) {
- STRANGE
- return(NULL);
- }
- cur = xmlXPtrAdvanceNode(cur);
- }
- return(list);
-}
-
-/**
- * xmlXPtrBuildNodeList:
- * @obj: the XPointer result from the evaluation.
- *
- * Build a node list tree copy of the XPointer result.
- * This will drop Attributes and Namespace declarations.
- *
- * Returns an xmlNodePtr list or NULL.
- * the caller has to free the node tree.
- */
-xmlNodePtr
-xmlXPtrBuildNodeList(xmlXPathObjectPtr obj) {
- xmlNodePtr list = NULL, last = NULL;
- int i;
-
- if (obj == NULL)
- return(NULL);
- switch (obj->type) {
- case XPATH_NODESET: {
- xmlNodeSetPtr set = obj->nodesetval;
- if (set == NULL)
- return(NULL);
- for (i = 0;i < set->nodeNr;i++) {
- if (set->nodeTab[i] == NULL)
- continue;
- switch (set->nodeTab[i]->type) {
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- 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:
- case XML_HTML_DOCUMENT_NODE:
-#ifdef LIBXML_DOCB_ENABLED
- case XML_DOCB_DOCUMENT_NODE:
-#endif
- case XML_XINCLUDE_START:
- case XML_XINCLUDE_END:
- break;
- case XML_ATTRIBUTE_NODE:
- case XML_NAMESPACE_DECL:
- case XML_DOCUMENT_TYPE_NODE:
- case XML_DOCUMENT_FRAG_NODE:
- case XML_NOTATION_NODE:
- case XML_DTD_NODE:
- case XML_ELEMENT_DECL:
- case XML_ATTRIBUTE_DECL:
- case XML_ENTITY_DECL:
- continue; /* for */
- }
- if (last == NULL)
- list = last = xmlCopyNode(set->nodeTab[i], 1);
- else {
- xmlAddNextSibling(last, xmlCopyNode(set->nodeTab[i], 1));
- if (last->next != NULL)
- last = last->next;
- }
- }
- break;
- }
- case XPATH_LOCATIONSET: {
- xmlLocationSetPtr set = (xmlLocationSetPtr) obj->user;
- if (set == NULL)
- return(NULL);
- for (i = 0;i < set->locNr;i++) {
- if (last == NULL)
- list = last = xmlXPtrBuildNodeList(set->locTab[i]);
- else
- xmlAddNextSibling(last,
- xmlXPtrBuildNodeList(set->locTab[i]));
- if (last != NULL) {
- while (last->next != NULL)
- last = last->next;
- }
- }
- break;
- }
- case XPATH_RANGE:
- return(xmlXPtrBuildRangeNodeList(obj));
- case XPATH_POINT:
- return(xmlCopyNode(obj->user, 0));
- default:
- break;
- }
- return(list);
-}
-
-/************************************************************************
- * *
- * XPointer functions *
- * *
- ************************************************************************/
-
-/**
- * xmlXPtrNbLocChildren:
- * @node: an xmlNodePtr
- *
- * Count the number of location children of @node or the length of the
- * string value in case of text/PI/Comments nodes
- *
- * Returns the number of location children
- */
-static int
-xmlXPtrNbLocChildren(xmlNodePtr node) {
- int ret = 0;
- if (node == NULL)
- return(-1);
- switch (node->type) {
- case XML_HTML_DOCUMENT_NODE:
- case XML_DOCUMENT_NODE:
- case XML_ELEMENT_NODE:
- node = node->children;
- while (node != NULL) {
- if (node->type == XML_ELEMENT_NODE)
- ret++;
- node = node->next;
- }
- break;
- case XML_ATTRIBUTE_NODE:
- return(-1);
-
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_ENTITY_REF_NODE:
- ret = xmlStrlen(node->content);
- break;
- default:
- return(-1);
- }
- return(ret);
-}
-
-/**
- * xmlXPtrHereFunction:
- * @ctxt: the XPointer Parser context
- * @nargs: the number of args
- *
- * Function implementing here() operation
- * as described in 5.4.3
- */
-void
-xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- CHECK_ARITY(0);
-
- if (ctxt->context->here == NULL)
- XP_ERROR(XPTR_SYNTAX_ERROR);
-
- valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->here, NULL));
-}
-
-/**
- * xmlXPtrOriginFunction:
- * @ctxt: the XPointer Parser context
- * @nargs: the number of args
- *
- * Function implementing origin() operation
- * as described in 5.4.3
- */
-void
-xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- CHECK_ARITY(0);
-
- if (ctxt->context->origin == NULL)
- XP_ERROR(XPTR_SYNTAX_ERROR);
-
- valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->origin, NULL));
-}
-
-/**
- * xmlXPtrStartPointFunction:
- * @ctxt: the XPointer Parser context
- * @nargs: the number of args
- *
- * Function implementing start-point() operation
- * as described in 5.4.3
- * ----------------
- * location-set start-point(location-set)
- *
- * For each location x in the argument location-set, start-point adds a
- * location of type point to the result location-set. That point represents
- * the start point of location x and is determined by the following rules:
- *
- * - If x is of type point, the start point is x.
- * - If x is of type range, the start point is the start point of x.
- * - If x is of type root, element, text, comment, or processing instruction,
- * - the container node of the start point is x and the index is 0.
- * - If x is of type attribute or namespace, the function must signal a
- * syntax error.
- * ----------------
- *
- */
-void
-xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr tmp, obj, point;
- xmlLocationSetPtr newset = NULL;
- xmlLocationSetPtr oldset = NULL;
-
- CHECK_ARITY(1);
- if ((ctxt->value == NULL) ||
- ((ctxt->value->type != XPATH_LOCATIONSET) &&
- (ctxt->value->type != XPATH_NODESET)))
- XP_ERROR(XPATH_INVALID_TYPE)
-
- obj = valuePop(ctxt);
- if (obj->type == XPATH_NODESET) {
- /*
- * First convert to a location set
- */
- tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval);
- xmlXPathFreeObject(obj);
- obj = tmp;
- }
-
- newset = xmlXPtrLocationSetCreate(NULL);
- if (newset == NULL) {
- xmlXPathFreeObject(obj);
- XP_ERROR(XPATH_MEMORY_ERROR);
- }
- oldset = (xmlLocationSetPtr) obj->user;
- if (oldset != NULL) {
- int i;
-
- for (i = 0; i < oldset->locNr; i++) {
- tmp = oldset->locTab[i];
- if (tmp == NULL)
- continue;
- point = NULL;
- switch (tmp->type) {
- case XPATH_POINT:
- point = xmlXPtrNewPoint(tmp->user, tmp->index);
- break;
- case XPATH_RANGE: {
- xmlNodePtr node = tmp->user;
- if (node != NULL) {
- if (node->type == XML_ATTRIBUTE_NODE) {
- /* TODO: Namespace Nodes ??? */
- xmlXPathFreeObject(obj);
- xmlXPtrFreeLocationSet(newset);
- XP_ERROR(XPTR_SYNTAX_ERROR);
- }
- point = xmlXPtrNewPoint(node, tmp->index);
- }
- break;
- }
- default:
- /*** Should we raise an error ?
- xmlXPathFreeObject(obj);
- xmlXPathFreeObject(newset);
- XP_ERROR(XPATH_INVALID_TYPE)
- ***/
- break;
- }
- if (point != NULL)
- xmlXPtrLocationSetAdd(newset, point);
- }
- }
- xmlXPathFreeObject(obj);
- valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
-}
-
-/**
- * xmlXPtrEndPointFunction:
- * @ctxt: the XPointer Parser context
- * @nargs: the number of args
- *
- * Function implementing end-point() operation
- * as described in 5.4.3
- * ----------------------------
- * location-set end-point(location-set)
- *
- * For each location x in the argument location-set, end-point adds a
- * location of type point to the result location-set. That point represents
- * the end point of location x and is determined by the following rules:
- *
- * - If x is of type point, the resulting point is x.
- * - If x is of type range, the resulting point is the end point of x.
- * - If x is of type root or element, the container node of the resulting
- * point is x and the index is the number of location children of x.
- * - If x is of type text, comment, or processing instruction, the container
- * node of the resulting point is x and the index is the length of the
- * string-value of x.
- * - If x is of type attribute or namespace, the function must signal a
- * syntax error.
- * ----------------------------
- */
-void
-xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr tmp, obj, point;
- xmlLocationSetPtr newset = NULL;
- xmlLocationSetPtr oldset = NULL;
-
- CHECK_ARITY(1);
- if ((ctxt->value == NULL) ||
- ((ctxt->value->type != XPATH_LOCATIONSET) &&
- (ctxt->value->type != XPATH_NODESET)))
- XP_ERROR(XPATH_INVALID_TYPE)
-
- obj = valuePop(ctxt);
- if (obj->type == XPATH_NODESET) {
- /*
- * First convert to a location set
- */
- tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval);
- xmlXPathFreeObject(obj);
- obj = tmp;
- }
-
- newset = xmlXPtrLocationSetCreate(NULL);
- oldset = (xmlLocationSetPtr) obj->user;
- if (oldset != NULL) {
- int i;
-
- for (i = 0; i < oldset->locNr; i++) {
- tmp = oldset->locTab[i];
- if (tmp == NULL)
- continue;
- point = NULL;
- switch (tmp->type) {
- case XPATH_POINT:
- point = xmlXPtrNewPoint(tmp->user, tmp->index);
- break;
- case XPATH_RANGE: {
- xmlNodePtr node = tmp->user2;
- if (node != NULL) {
- if (node->type == XML_ATTRIBUTE_NODE) {
- /* TODO: Namespace Nodes ??? */
- xmlXPathFreeObject(obj);
- xmlXPtrFreeLocationSet(newset);
- XP_ERROR(XPTR_SYNTAX_ERROR);
- }
- point = xmlXPtrNewPoint(node, tmp->index2);
- } else if (tmp->user == NULL) {
- point = xmlXPtrNewPoint(node,
- xmlXPtrNbLocChildren(node));
- }
- break;
- }
- default:
- /*** Should we raise an error ?
- xmlXPathFreeObject(obj);
- xmlXPathFreeObject(newset);
- XP_ERROR(XPATH_INVALID_TYPE)
- ***/
- break;
- }
- if (point != NULL)
- xmlXPtrLocationSetAdd(newset, point);
- }
- }
- xmlXPathFreeObject(obj);
- valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
-}
-
-
-/**
- * xmlXPtrCoveringRange:
- * @ctxt: the XPointer Parser context
- * @loc: the location for which the covering range must be computed
- *
- * A covering range is a range that wholly encompasses a location
- * Section 5.3.3. Covering Ranges for All Location Types
- * http://www.w3.org/TR/xptr#N2267
- *
- * Returns a new location or NULL in case of error
- */
-static xmlXPathObjectPtr
-xmlXPtrCoveringRange(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr loc) {
- if (loc == NULL)
- return(NULL);
- if ((ctxt == NULL) || (ctxt->context == NULL) ||
- (ctxt->context->doc == NULL))
- return(NULL);
- switch (loc->type) {
- case XPATH_POINT:
- return(xmlXPtrNewRange(loc->user, loc->index,
- loc->user, loc->index));
- case XPATH_RANGE:
- if (loc->user2 != NULL) {
- return(xmlXPtrNewRange(loc->user, loc->index,
- loc->user2, loc->index2));
- } else {
- xmlNodePtr node = (xmlNodePtr) loc->user;
- if (node == (xmlNodePtr) ctxt->context->doc) {
- return(xmlXPtrNewRange(node, 0, node,
- xmlXPtrGetArity(node)));
- } else {
- switch (node->type) {
- case XML_ATTRIBUTE_NODE:
- /* !!! our model is slightly different than XPath */
- return(xmlXPtrNewRange(node, 0, node,
- xmlXPtrGetArity(node)));
- case XML_ELEMENT_NODE:
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- case XML_DOCUMENT_NODE:
- case XML_NOTATION_NODE:
- case XML_HTML_DOCUMENT_NODE: {
- int indx = xmlXPtrGetIndex(node);
-
- node = node->parent;
- return(xmlXPtrNewRange(node, indx - 1,
- node, indx + 1));
- }
- default:
- return(NULL);
- }
- }
- }
- default:
- TODO /* missed one case ??? */
- }
- return(NULL);
-}
-
-/**
- * xmlXPtrRangeFunction:
- * @ctxt: the XPointer Parser context
- * @nargs: the number of args
- *
- * Function implementing the range() function 5.4.3
- * location-set range(location-set )
- *
- * The range function returns ranges covering the locations in
- * the argument location-set. For each location x in the argument
- * location-set, a range location representing the covering range of
- * x is added to the result location-set.
- */
-void
-xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- int i;
- xmlXPathObjectPtr set;
- xmlLocationSetPtr oldset;
- xmlLocationSetPtr newset;
-
- CHECK_ARITY(1);
- if ((ctxt->value == NULL) ||
- ((ctxt->value->type != XPATH_LOCATIONSET) &&
- (ctxt->value->type != XPATH_NODESET)))
- XP_ERROR(XPATH_INVALID_TYPE)
-
- set = valuePop(ctxt);
- if (set->type == XPATH_NODESET) {
- xmlXPathObjectPtr tmp;
-
- /*
- * First convert to a location set
- */
- tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
- xmlXPathFreeObject(set);
- set = tmp;
- }
- oldset = (xmlLocationSetPtr) set->user;
-
- /*
- * The loop is to compute the covering range for each item and add it
- */
- newset = xmlXPtrLocationSetCreate(NULL);
- for (i = 0;i < oldset->locNr;i++) {
- xmlXPtrLocationSetAdd(newset,
- xmlXPtrCoveringRange(ctxt, oldset->locTab[i]));
- }
-
- /*
- * Save the new value and cleanup
- */
- valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
- xmlXPathFreeObject(set);
-}
-
-/**
- * xmlXPtrInsideRange:
- * @ctxt: the XPointer Parser context
- * @loc: the location for which the inside range must be computed
- *
- * A inside range is a range described in the range-inside() description
- *
- * Returns a new location or NULL in case of error
- */
-static xmlXPathObjectPtr
-xmlXPtrInsideRange(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr loc) {
- if (loc == NULL)
- return(NULL);
- if ((ctxt == NULL) || (ctxt->context == NULL) ||
- (ctxt->context->doc == NULL))
- return(NULL);
- switch (loc->type) {
- case XPATH_POINT: {
- xmlNodePtr node = (xmlNodePtr) loc->user;
- switch (node->type) {
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE: {
- if (node->content == NULL) {
- return(xmlXPtrNewRange(node, 0, node, 0));
- } else {
- return(xmlXPtrNewRange(node, 0, node,
- xmlStrlen(node->content)));
- }
- }
- case XML_ATTRIBUTE_NODE:
- case XML_ELEMENT_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_DOCUMENT_NODE:
- case XML_NOTATION_NODE:
- case XML_HTML_DOCUMENT_NODE: {
- return(xmlXPtrNewRange(node, 0, node,
- xmlXPtrGetArity(node)));
- }
- default:
- break;
- }
- return(NULL);
- }
- case XPATH_RANGE: {
- xmlNodePtr node = (xmlNodePtr) loc->user;
- if (loc->user2 != NULL) {
- return(xmlXPtrNewRange(node, loc->index,
- loc->user2, loc->index2));
- } else {
- switch (node->type) {
- case XML_PI_NODE:
- case XML_COMMENT_NODE:
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE: {
- if (node->content == NULL) {
- return(xmlXPtrNewRange(node, 0, node, 0));
- } else {
- return(xmlXPtrNewRange(node, 0, node,
- xmlStrlen(node->content)));
- }
- }
- case XML_ATTRIBUTE_NODE:
- case XML_ELEMENT_NODE:
- case XML_ENTITY_REF_NODE:
- case XML_DOCUMENT_NODE:
- case XML_NOTATION_NODE:
- case XML_HTML_DOCUMENT_NODE: {
- return(xmlXPtrNewRange(node, 0, node,
- xmlXPtrGetArity(node)));
- }
- default:
- break;
- }
- return(NULL);
- }
- }
- default:
- TODO /* missed one case ??? */
- }
- return(NULL);
-}
-
-/**
- * xmlXPtrRangeInsideFunction:
- * @ctxt: the XPointer Parser context
- * @nargs: the number of args
- *
- * Function implementing the range-inside() function 5.4.3
- * location-set range-inside(location-set )
- *
- * The range-inside function returns ranges covering the contents of
- * the locations in the argument location-set. For each location x in
- * the argument location-set, a range location is added to the result
- * location-set. If x is a range location, then x is added to the
- * result location-set. If x is not a range location, then x is used
- * as the container location of the start and end points of the range
- * location to be added; the index of the start point of the range is
- * zero; if the end point is a character point then its index is the
- * length of the string-value of x, and otherwise is the number of
- * location children of x.
- *
- */
-void
-xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- int i;
- xmlXPathObjectPtr set;
- xmlLocationSetPtr oldset;
- xmlLocationSetPtr newset;
-
- CHECK_ARITY(1);
- if ((ctxt->value == NULL) ||
- ((ctxt->value->type != XPATH_LOCATIONSET) &&
- (ctxt->value->type != XPATH_NODESET)))
- XP_ERROR(XPATH_INVALID_TYPE)
-
- set = valuePop(ctxt);
- if (set->type == XPATH_NODESET) {
- xmlXPathObjectPtr tmp;
-
- /*
- * First convert to a location set
- */
- tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
- xmlXPathFreeObject(set);
- set = tmp;
- }
- oldset = (xmlLocationSetPtr) set->user;
-
- /*
- * The loop is to compute the covering range for each item and add it
- */
- newset = xmlXPtrLocationSetCreate(NULL);
- for (i = 0;i < oldset->locNr;i++) {
- xmlXPtrLocationSetAdd(newset,
- xmlXPtrInsideRange(ctxt, oldset->locTab[i]));
- }
-
- /*
- * Save the new value and cleanup
- */
- valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
- xmlXPathFreeObject(set);
-}
-
-/**
- * xmlXPtrRangeToFunction:
- * @ctxt: the XPointer Parser context
- * @nargs: the number of args
- *
- * Implement the range-to() XPointer function
- */
-void
-xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- xmlXPathObjectPtr range;
- const xmlChar *cur;
- xmlXPathObjectPtr res, obj;
- xmlXPathObjectPtr tmp;
- xmlLocationSetPtr newset = NULL;
- xmlNodeSetPtr oldset;
- int i;
-
- CHECK_ARITY(1);
- /*
- * Save the expression pointer since we will have to evaluate
- * it multiple times. Initialize the new set.
- */
- CHECK_TYPE(XPATH_NODESET);
- obj = valuePop(ctxt);
- oldset = obj->nodesetval;
- ctxt->context->node = NULL;
-
- cur = ctxt->cur;
- newset = xmlXPtrLocationSetCreate(NULL);
-
- for (i = 0; i < oldset->nodeNr; i++) {
- ctxt->cur = cur;
-
- /*
- * Run the evaluation with a node list made of a single item
- * in the nodeset.
- */
- ctxt->context->node = oldset->nodeTab[i];
- tmp = xmlXPathNewNodeSet(ctxt->context->node);
- valuePush(ctxt, tmp);
-
- xmlXPathEvalExpr(ctxt);
- CHECK_ERROR;
-
- /*
- * The result of the evaluation need to be tested to
- * decided whether the filter succeeded or not
- */
- res = valuePop(ctxt);
- range = xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], res);
- if (range != NULL) {
- xmlXPtrLocationSetAdd(newset, range);
- }
-
- /*
- * Cleanup
- */
- if (res != NULL)
- xmlXPathFreeObject(res);
- if (ctxt->value == tmp) {
- res = valuePop(ctxt);
- xmlXPathFreeObject(res);
- }
-
- ctxt->context->node = NULL;
- }
-
- /*
- * The result is used as the new evaluation set.
- */
- xmlXPathFreeObject(obj);
- ctxt->context->node = NULL;
- ctxt->context->contextSize = -1;
- ctxt->context->proximityPosition = -1;
- valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
-}
-
-/**
- * xmlXPtrAdvanceNode:
- * @cur: the node
- *
- * Advance to the next element or text node in document order
- * TODO: add a stack for entering/exiting entities
- *
- * Returns -1 in case of failure, 0 otherwise
- */
-xmlNodePtr
-xmlXPtrAdvanceNode(xmlNodePtr cur) {
-next:
- if (cur == NULL)
- return(NULL);
- if (cur->children != NULL) {
- cur = cur->children ;
- goto found;
- }
- if (cur->next != NULL) {
- cur = cur->next;
- goto found;
- }
- do {
- cur = cur->parent;
- if (cur == NULL) return(NULL);
- if (cur->next != NULL) {
- cur = cur->next;
- goto found;
- }
- } while (cur != NULL);
-
-found:
- if ((cur->type != XML_ELEMENT_NODE) &&
- (cur->type != XML_TEXT_NODE) &&
- (cur->type != XML_DOCUMENT_NODE) &&
- (cur->type != XML_HTML_DOCUMENT_NODE) &&
- (cur->type != XML_CDATA_SECTION_NODE))
- goto next;
- if (cur->type == XML_ENTITY_REF_NODE) {
- TODO
- }
- return(cur);
-}
-
-/**
- * xmlXPtrAdvanceChar:
- * @node: the node
- * @indx: the indx
- * @bytes: the number of bytes
- *
- * Advance a point of the associated number of bytes (not UTF8 chars)
- *
- * Returns -1 in case of failure, 0 otherwise
- */
-static int
-xmlXPtrAdvanceChar(xmlNodePtr *node, int *indx, int bytes) {
- xmlNodePtr cur;
- int pos;
- int len;
-
- if ((node == NULL) || (indx == NULL))
- return(-1);
- cur = *node;
- if (cur == NULL)
- return(-1);
- pos = *indx;
-
- while (bytes >= 0) {
- /*
- * First position to the beginning of the first text node
- * corresponding to this point
- */
- while ((cur != NULL) &&
- ((cur->type == XML_ELEMENT_NODE) ||
- (cur->type == XML_DOCUMENT_NODE) ||
- (cur->type == XML_HTML_DOCUMENT_NODE))) {
- if (pos > 0) {
- cur = xmlXPtrGetNthChild(cur, pos);
- pos = 0;
- } else {
- cur = xmlXPtrAdvanceNode(cur);
- pos = 0;
- }
- }
-
- if (cur == NULL) {
- *node = NULL;
- *indx = 0;
- return(-1);
- }
-
- /*
- * if there is no move needed return the current value.
- */
- if (pos == 0) pos = 1;
- if (bytes == 0) {
- *node = cur;
- *indx = pos;
- return(0);
- }
- /*
- * We should have a text (or cdata) node ...
- */
- len = 0;
- if ((cur->type != XML_ELEMENT_NODE) &&
- (cur->content != NULL)) {
- len = xmlStrlen(cur->content);
- }
- if (pos > len) {
- /* Strange, the indx in the text node is greater than it's len */
- STRANGE
- pos = len;
- }
- if (pos + bytes >= len) {
- bytes -= (len - pos);
- cur = xmlXPtrAdvanceNode(cur);
- cur = 0;
- } else if (pos + bytes < len) {
- pos += bytes;
- *node = cur;
- *indx = pos;
- return(0);
- }
- }
- return(-1);
-}
-
-/**
- * xmlXPtrMatchString:
- * @string: the string to search
- * @start: the start textnode
- * @startindex: the start index
- * @end: the end textnode IN/OUT
- * @endindex: the end index IN/OUT
- *
- * Check whether the document contains @string at the position
- * (@start, @startindex) and limited by the (@end, @endindex) point
- *
- * Returns -1 in case of failure, 0 if not found, 1 if found in which case
- * (@start, @startindex) will indicate the position of the beginning
- * of the range and (@end, @endindex) will indicate the end
- * of the range
- */
-static int
-xmlXPtrMatchString(const xmlChar *string, xmlNodePtr start, int startindex,
- xmlNodePtr *end, int *endindex) {
- xmlNodePtr cur;
- int pos; /* 0 based */
- int len; /* in bytes */
- int stringlen; /* in bytes */
- int match;
-
- if (string == NULL)
- return(-1);
- if (start == NULL)
- return(-1);
- if ((end == NULL) || (endindex == NULL))
- return(-1);
- cur = start;
- if (cur == NULL)
- return(-1);
- pos = startindex - 1;
- stringlen = xmlStrlen(string);
-
- while (stringlen > 0) {
- if ((cur == *end) && (pos + stringlen > *endindex))
- return(0);
-
- if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) {
- len = xmlStrlen(cur->content);
- if (len >= pos + stringlen) {
- match = (!xmlStrncmp(&cur->content[pos], string, stringlen));
- if (match) {
-#ifdef DEBUG_RANGES
- xmlGenericError(xmlGenericErrorContext,
- "found range %d bytes at index %d of ->",
- stringlen, pos + 1);
- xmlDebugDumpString(stdout, cur->content);
- xmlGenericError(xmlGenericErrorContext, "\n");
-#endif
- *end = cur;
- *endindex = pos + stringlen;
- return(1);
- } else {
- return(0);
- }
- } else {
- int sub = len - pos;
- match = (!xmlStrncmp(&cur->content[pos], string, sub));
- if (match) {
-#ifdef DEBUG_RANGES
- xmlGenericError(xmlGenericErrorContext,
- "found subrange %d bytes at index %d of ->",
- sub, pos + 1);
- xmlDebugDumpString(stdout, cur->content);
- xmlGenericError(xmlGenericErrorContext, "\n");
-#endif
- string = &string[sub];
- stringlen -= sub;
- } else {
- return(0);
- }
- }
- }
- cur = xmlXPtrAdvanceNode(cur);
- if (cur == NULL)
- return(0);
- pos = 0;
- }
- return(1);
-}
-
-/**
- * xmlXPtrSearchString:
- * @string: the string to search
- * @start: the start textnode IN/OUT
- * @startindex: the start index IN/OUT
- * @end: the end textnode
- * @endindex: the end index
- *
- * Search the next occurrence of @string within the document content
- * until the (@end, @endindex) point is reached
- *
- * Returns -1 in case of failure, 0 if not found, 1 if found in which case
- * (@start, @startindex) will indicate the position of the beginning
- * of the range and (@end, @endindex) will indicate the end
- * of the range
- */
-static int
-xmlXPtrSearchString(const xmlChar *string, xmlNodePtr *start, int *startindex,
- xmlNodePtr *end, int *endindex) {
- xmlNodePtr cur;
- const xmlChar *str;
- int pos; /* 0 based */
- int len; /* in bytes */
- xmlChar first;
-
- if (string == NULL)
- return(-1);
- if ((start == NULL) || (startindex == NULL))
- return(-1);
- if ((end == NULL) || (endindex == NULL))
- return(-1);
- cur = *start;
- if (cur == NULL)
- return(-1);
- pos = *startindex - 1;
- first = string[0];
-
- while (cur != NULL) {
- if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) {
- len = xmlStrlen(cur->content);
- while (pos <= len) {
- if (first != 0) {
- str = xmlStrchr(&cur->content[pos], first);
- if (str != NULL) {
- pos = (str - (xmlChar *)(cur->content));
-#ifdef DEBUG_RANGES
- xmlGenericError(xmlGenericErrorContext,
- "found '%c' at index %d of ->",
- first, pos + 1);
- xmlDebugDumpString(stdout, cur->content);
- xmlGenericError(xmlGenericErrorContext, "\n");
-#endif
- if (xmlXPtrMatchString(string, cur, pos + 1,
- end, endindex)) {
- *start = cur;
- *startindex = pos + 1;
- return(1);
- }
- pos++;
- } else {
- pos = len + 1;
- }
- } else {
- /*
- * An empty string is considered to match before each
- * character of the string-value and after the final
- * character.
- */
-#ifdef DEBUG_RANGES
- xmlGenericError(xmlGenericErrorContext,
- "found '' at index %d of ->",
- pos + 1);
- xmlDebugDumpString(stdout, cur->content);
- xmlGenericError(xmlGenericErrorContext, "\n");
-#endif
- *start = cur;
- *startindex = pos + 1;
- *end = cur;
- *endindex = pos + 1;
- return(1);
- }
- }
- }
- if ((cur == *end) && (pos >= *endindex))
- return(0);
- cur = xmlXPtrAdvanceNode(cur);
- if (cur == NULL)
- return(0);
- pos = 1;
- }
- return(0);
-}
-
-/**
- * xmlXPtrGetLastChar:
- * @node: the node
- * @index: the index
- *
- * Computes the point coordinates of the last char of this point
- *
- * Returns -1 in case of failure, 0 otherwise
- */
-static int
-xmlXPtrGetLastChar(xmlNodePtr *node, int *indx) {
- xmlNodePtr cur;
- int pos, len = 0;
-
- if ((node == NULL) || (indx == NULL))
- return(-1);
- cur = *node;
- pos = *indx;
-
- if (cur == NULL)
- return(-1);
-
- if ((cur->type == XML_ELEMENT_NODE) ||
- (cur->type == XML_DOCUMENT_NODE) ||
- (cur->type == XML_HTML_DOCUMENT_NODE)) {
- if (pos > 0) {
- cur = xmlXPtrGetNthChild(cur, pos);
- pos = 0;
- }
- }
- while (cur != NULL) {
- if (cur->last != NULL)
- cur = cur->last;
- else if ((cur->type != XML_ELEMENT_NODE) &&
- (cur->content != NULL)) {
- len = xmlStrlen(cur->content);
- break;
- } else {
- return(-1);
- }
- }
- if (cur == NULL)
- return(-1);
- *node = cur;
- *indx = len;
- return(0);
-}
-
-/**
- * xmlXPtrGetStartPoint:
- * @obj: an range
- * @node: the resulting node
- * @indx: the resulting index
- *
- * read the object and return the start point coordinates.
- *
- * Returns -1 in case of failure, 0 otherwise
- */
-static int
-xmlXPtrGetStartPoint(xmlXPathObjectPtr obj, xmlNodePtr *node, int *indx) {
- if ((obj == NULL) || (node == NULL) || (indx == NULL))
- return(-1);
-
- switch (obj->type) {
- case XPATH_POINT:
- *node = obj->user;
- if (obj->index <= 0)
- *indx = 0;
- else
- *indx = obj->index;
- return(0);
- case XPATH_RANGE:
- *node = obj->user;
- if (obj->index <= 0)
- *indx = 0;
- else
- *indx = obj->index;
- return(0);
- default:
- break;
- }
- return(-1);
-}
-
-/**
- * xmlXPtrGetEndPoint:
- * @obj: an range
- * @node: the resulting node
- * @indx: the resulting indx
- *
- * read the object and return the end point coordinates.
- *
- * Returns -1 in case of failure, 0 otherwise
- */
-static int
-xmlXPtrGetEndPoint(xmlXPathObjectPtr obj, xmlNodePtr *node, int *indx) {
- if ((obj == NULL) || (node == NULL) || (indx == NULL))
- return(-1);
-
- switch (obj->type) {
- case XPATH_POINT:
- *node = obj->user;
- if (obj->index <= 0)
- *indx = 0;
- else
- *indx = obj->index;
- return(0);
- case XPATH_RANGE:
- *node = obj->user;
- if (obj->index <= 0)
- *indx = 0;
- else
- *indx = obj->index;
- return(0);
- default:
- break;
- }
- return(-1);
-}
-
-/**
- * xmlXPtrStringRangeFunction:
- * @ctxt: the XPointer Parser context
- * @nargs: the number of args
- *
- * Function implementing the string-range() function
- * range as described in 5.4.2
- *
- * ------------------------------
- * [Definition: For each location in the location-set argument,
- * string-range returns a set of string ranges, a set of substrings in a
- * string. Specifically, the string-value of the location is searched for
- * substrings that match the string argument, and the resulting location-set
- * will contain a range location for each non-overlapping match.]
- * An empty string is considered to match before each character of the
- * string-value and after the final character. Whitespace in a string
- * is matched literally, with no normalization except that provided by
- * XML for line ends. The third argument gives the position of the first
- * character to be in the resulting range, relative to the start of the
- * match. The default value is 1, which makes the range start immediately
- * before the first character of the matched string. The fourth argument
- * gives the number of characters in the range; the default is that the
- * range extends to the end of the matched string.
- *
- * Element boundaries, as well as entire embedded nodes such as processing
- * instructions and comments, are ignored as defined in [XPath].
- *
- * If the string in the second argument is not found in the string-value
- * of the location, or if a value in the third or fourth argument indicates
- * a string that is beyond the beginning or end of the document, the
- * expression fails.
- *
- * The points of the range-locations in the returned location-set will
- * all be character points.
- * ------------------------------
- */
-void
-xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
- int i, startindex, endindex, fendindex;
- xmlNodePtr start, end, fend;
- xmlXPathObjectPtr set;
- xmlLocationSetPtr oldset;
- xmlLocationSetPtr newset;
- xmlXPathObjectPtr string;
- xmlXPathObjectPtr position = NULL;
- xmlXPathObjectPtr number = NULL;
- int found, pos = 0, num = 0;
-
- /*
- * Grab the arguments
- */
- if ((nargs < 2) || (nargs > 4))
- XP_ERROR(XPATH_INVALID_ARITY);
-
- if (nargs >= 4) {
- CHECK_TYPE(XPATH_NUMBER);
- number = valuePop(ctxt);
- if (number != NULL)
- num = (int) number->floatval;
- }
- if (nargs >= 3) {
- CHECK_TYPE(XPATH_NUMBER);
- position = valuePop(ctxt);
- if (position != NULL)
- pos = (int) position->floatval;
- }
- CHECK_TYPE(XPATH_STRING);
- string = valuePop(ctxt);
- if ((ctxt->value == NULL) ||
- ((ctxt->value->type != XPATH_LOCATIONSET) &&
- (ctxt->value->type != XPATH_NODESET)))
- XP_ERROR(XPATH_INVALID_TYPE)
-
- set = valuePop(ctxt);
- if (set->type == XPATH_NODESET) {
- xmlXPathObjectPtr tmp;
-
- /*
- * First convert to a location set
- */
- tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
- xmlXPathFreeObject(set);
- set = tmp;
- }
- oldset = (xmlLocationSetPtr) set->user;
-
- /*
- * The loop is to search for each element in the location set
- * the list of location set corresponding to that search
- */
- newset = xmlXPtrLocationSetCreate(NULL);
- for (i = 0;i < oldset->locNr;i++) {
-#ifdef DEBUG_RANGES
- xmlXPathDebugDumpObject(stdout, oldset->locTab[i], 0);
-#endif
-
- xmlXPtrGetStartPoint(oldset->locTab[i], &start, &startindex);
- xmlXPtrGetEndPoint(oldset->locTab[i], &end, &endindex);
- xmlXPtrAdvanceChar(&start, &startindex, 0);
- xmlXPtrGetLastChar(&end, &endindex);
-
-#ifdef DEBUG_RANGES
- xmlGenericError(xmlGenericErrorContext,
- "from index %d of ->", startindex);
- xmlDebugDumpString(stdout, start->content);
- xmlGenericError(xmlGenericErrorContext, "\n");
- xmlGenericError(xmlGenericErrorContext,
- "to index %d of ->", endindex);
- xmlDebugDumpString(stdout, end->content);
- xmlGenericError(xmlGenericErrorContext, "\n");
-#endif
- do {
- fend = end;
- fendindex = endindex;
- found = xmlXPtrSearchString(string->stringval, &start, &startindex,
- &fend, &fendindex);
- if (found == 1) {
- if (position == NULL) {
- xmlXPtrLocationSetAdd(newset,
- xmlXPtrNewRange(start, startindex, fend, fendindex));
- } else if (xmlXPtrAdvanceChar(&start, &startindex,
- pos - 1) == 0) {
- if ((number != NULL) && (num > 0)) {
- int rindx;
- xmlNodePtr rend;
- rend = start;
- rindx = startindex - 1;
- if (xmlXPtrAdvanceChar(&rend, &rindx,
- num) == 0) {
- xmlXPtrLocationSetAdd(newset,
- xmlXPtrNewRange(start, startindex,
- rend, rindx));
- }
- } else if ((number != NULL) && (num <= 0)) {
- xmlXPtrLocationSetAdd(newset,
- xmlXPtrNewRange(start, startindex,
- start, startindex));
- } else {
- xmlXPtrLocationSetAdd(newset,
- xmlXPtrNewRange(start, startindex,
- fend, fendindex));
- }
- }
- start = fend;
- startindex = fendindex;
- if (string->stringval[0] == 0)
- startindex++;
- }
- } while (found == 1);
- }
-
- /*
- * Save the new value and cleanup
- */
- valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
- xmlXPathFreeObject(set);
- xmlXPathFreeObject(string);
- if (position) xmlXPathFreeObject(position);
- if (number) xmlXPathFreeObject(number);
-}
-
-/**
- * xmlXPtrEvalRangePredicate:
- * @ctxt: the XPointer Parser context
- *
- * [8] Predicate ::= '[' PredicateExpr ']'
- * [9] PredicateExpr ::= Expr
- *
- * Evaluate a predicate as in xmlXPathEvalPredicate() but for
- * a Location Set instead of a node set
- */
-void
-xmlXPtrEvalRangePredicate(xmlXPathParserContextPtr ctxt) {
- const xmlChar *cur;
- xmlXPathObjectPtr res;
- xmlXPathObjectPtr obj, tmp;
- xmlLocationSetPtr newset = NULL;
- xmlLocationSetPtr oldset;
- int i;
-
- SKIP_BLANKS;
- if (CUR != '[') {
- XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
- }
- NEXT;
- SKIP_BLANKS;
-
- /*
- * Extract the old set, and then evaluate the result of the
- * expression for all the element in the set. use it to grow
- * up a new set.
- */
- CHECK_TYPE(XPATH_LOCATIONSET);
- obj = valuePop(ctxt);
- oldset = obj->user;
- ctxt->context->node = NULL;
-
- if ((oldset == NULL) || (oldset->locNr == 0)) {
- ctxt->context->contextSize = 0;
- ctxt->context->proximityPosition = 0;
- xmlXPathEvalExpr(ctxt);
- res = valuePop(ctxt);
- if (res != NULL)
- xmlXPathFreeObject(res);
- valuePush(ctxt, obj);
- CHECK_ERROR;
- } else {
- /*
- * Save the expression pointer since we will have to evaluate
- * it multiple times. Initialize the new set.
- */
- cur = ctxt->cur;
- newset = xmlXPtrLocationSetCreate(NULL);
-
- for (i = 0; i < oldset->locNr; i++) {
- ctxt->cur = cur;
-
- /*
- * Run the evaluation with a node list made of a single item
- * in the nodeset.
- */
- ctxt->context->node = oldset->locTab[i]->user;
- tmp = xmlXPathNewNodeSet(ctxt->context->node);
- valuePush(ctxt, tmp);
- ctxt->context->contextSize = oldset->locNr;
- ctxt->context->proximityPosition = i + 1;
-
- xmlXPathEvalExpr(ctxt);
- CHECK_ERROR;
-
- /*
- * The result of the evaluation need to be tested to
- * decided whether the filter succeeded or not
- */
- res = valuePop(ctxt);
- if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
- xmlXPtrLocationSetAdd(newset,
- xmlXPathObjectCopy(oldset->locTab[i]));
- }
-
- /*
- * Cleanup
- */
- if (res != NULL)
- xmlXPathFreeObject(res);
- if (ctxt->value == tmp) {
- res = valuePop(ctxt);
- xmlXPathFreeObject(res);
- }
-
- ctxt->context->node = NULL;
- }
-
- /*
- * The result is used as the new evaluation set.
- */
- xmlXPathFreeObject(obj);
- ctxt->context->node = NULL;
- ctxt->context->contextSize = -1;
- ctxt->context->proximityPosition = -1;
- valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
- }
- if (CUR != ']') {
- XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
- }
-
- NEXT;
- SKIP_BLANKS;
-}
-
-#else
-#endif
-
diff --git a/configure.in b/configure.in
index 730774022c..a6ab6f213b 100644
--- a/configure.in
+++ b/configure.in
@@ -777,16 +777,8 @@ AC_ARG_ENABLE(all,
PHP_ENABLE_ALL=$enableval
])
-AC_ARG_ENABLE(bundle-all,
-[ --disable-bundle-all Disable all bundled libraries by default.
-], [
- PHP_BUNDLE_ALL=$enableval
-])
-
# reading config stubs
esyscmd(./build/config-stubs ext)
-esyscmd(./build/config-stubs bundle)
-
dnl Other settings.
dnl -------------------------------------------------------------------------
diff --git a/ext/domxml/config.m4 b/ext/domxml/config.m4
index 5124e4e21f..7d25997e4f 100644
--- a/ext/domxml/config.m4
+++ b/ext/domxml/config.m4
@@ -2,20 +2,6 @@ dnl
dnl $Id$
dnl
-PHP_ARG_WITH(dom, for DOM support,
-[ --with-dom[=DIR] Include DOM support])
-
-if test "$PHP_DOM" != "no"; then
-
- if test "$PHP_BUNDLE_LIBXML" = "no"; then
- AC_MSG_RESULT(not found)
- AC_MSG_ERROR(libxml2 required)
- fi
-
- AC_DEFINE(HAVE_DOMXML,1,[ ])
- PHP_NEW_EXTENSION(domxml, php_domxml.c, $ext_shared)
-fi
-
AC_DEFUN(PHP_DOM_XSLT_CHECK_VERSION,[
old_CPPFLAGS=$CPPFLAGS
CPPFLAGS=-I$DOMXSLT_DIR/include
@@ -50,20 +36,37 @@ AC_DEFUN(PHP_DOM_EXSLT_CHECK_VERSION,[
CPPFLAGS=$old_CPPFLAGS
])
+PHP_ARG_WITH(dom, for DOM support,
+[ --with-dom[=DIR] Include DOM support (requires libxml >= 2.4.14).
+ DIR is the libxml install directory.])
+
+if test "$PHP_DOM" != "no"; then
+
+ PHP_LIBXML_DIR=$PHP_DOM
+
+ PHP_SETUP_LIBXML(DOMXML_SHARED_LIBADD, [
+ AC_DEFINE(HAVE_DOMXML,1,[ ])
+ PHP_NEW_EXTENSION(domxml, php_domxml.c, $ext_shared)
+ PHP_SUBST(DOMXML_SHARED_LIBADD)
+ ], [
+ AC_MSG_ERROR([xml2-config not found. Please check your libxml2 installation.])
+ ])
+fi
+
PHP_ARG_WITH(dom-xslt, for DOM XSLT support,
[ --with-dom-xslt[=DIR] DOMXML: Include DOM XSLT support (requires libxslt >= 1.0.18).
DIR is the libxslt install directory.], no, no)
-PHP_ARG_WITH(dom-exslt, for DOM EXSLT support,
-[ --with-dom-exslt[=DIR] DOMXML: Include DOM EXSLT support (requires libxslt >= 1.0.18).
- DIR is the libexslt install directory.], no, no)
-
if test "$PHP_DOM_XSLT" != "no"; then
- if test -r $PHP_DOM_XSLT/include/libxslt/transform.h; then
+ if test "$PHP_DOM" = "no"; then
+ AC_MSG_ERROR([DOMXSLT requires DOMXML. Use --with-dom[=DIR]])
+ fi
+
+ if test -r "$PHP_DOM_XSLT/include/libxslt/transform.h"; then
DOMXSLT_DIR=$PHP_DOM_XSLT
else
- for i in /usr/local /usr; do
+ for i in $PHP_LIBXML_DIR /usr/local /usr; do
test -r $i/include/libxslt/transform.h && DOMXSLT_DIR=$i
done
fi
@@ -76,35 +79,34 @@ if test "$PHP_DOM_XSLT" != "no"; then
PHP_DOM_XSLT_CHECK_VERSION
PHP_ADD_LIBRARY_WITH_PATH(xslt, $DOMXSLT_DIR/lib, DOMXML_SHARED_LIBADD)
-
PHP_ADD_INCLUDE($DOMXSLT_DIR/include)
- if test "$PHP_DOM" = "no"; then
- AC_MSG_ERROR(DOMXSLT requires DOMXML. Use --with-dom)
- fi
-
- if test -f $DOMXSLT_DIR/lib/libxsltbreakpoint.a -o -f $DOMXSLT_DIR/lib/libxsltbreakpoint.$SHLIB_SUFFIX_NAME ; then
- PHP_ADD_LIBRARY_WITH_PATH(xsltbreakpoint, $DOMXSLT_DIR/lib, DOMXML_SHARED_LIBADD)
+ if test -f $PHP_LIBXML_DIR/lib/libxsltbreakpoint.a -o -f $PHP_LIBXML_DIR/lib/libxsltbreakpoint.$SHLIB_SUFFIX_NAME; then
+ PHP_ADD_LIBRARY_WITH_PATH(xsltbreakpoint, $PHP_LIBXML_DIR/lib, DOMXML_SHARED_LIBADD)
fi
AC_DEFINE(HAVE_DOMXSLT,1,[ ])
-
- PHP_SUBST(DOMXML_SHARED_LIBADD)
fi
+
+PHP_ARG_WITH(dom-exslt, for DOM EXSLT support,
+[ --with-dom-exslt[=DIR] DOMXML: Include DOM EXSLT support (requires libxslt >= 1.0.18).
+ DIR is the libexslt install directory.], no, no)
+
if test "$PHP_DOM_EXSLT" != "no"; then
+
if test "$PHP_DOM" = "no"; then
- AC_MSG_ERROR(DOMEXSLT requires DOMXML. Use --with-dom=<DIR>)
+ AC_MSG_ERROR([DOMEXSLT requires DOMXML. Use --with-dom[=DIR]])
fi
if test "$PHP_DOM_XSLT" = "no"; then
- AC_MSG_ERROR(DOMEXSLT requires DOMXSLT. Use --with-dom-xslt=<DIR>)
+ AC_MSG_ERROR([DOMEXSLT requires DOMXSLT. Use --with-dom-xslt[=DIR]])
fi
-
+
if test -r $PHP_DOM_EXSLT/include/libexslt/exslt.h; then
DOMEXSLT_DIR=$PHP_DOM_EXSLT
else
- for i in /usr/local /usr; do
+ for i in $PHP_LIBXML_DIR /usr/local /usr; do
test -r $i/include/libexslt/exslt.h && DOMEXSLT_DIR=$i
done
fi
@@ -117,11 +119,7 @@ if test "$PHP_DOM_EXSLT" != "no"; then
PHP_DOM_EXSLT_CHECK_VERSION
PHP_ADD_LIBRARY_WITH_PATH(exslt, $DOMEXSLT_DIR/lib, DOMXML_SHARED_LIBADD)
-
PHP_ADD_INCLUDE($DOMEXSLT_DIR/include)
-
AC_DEFINE(HAVE_DOMEXSLT,1,[ ])
-
PHP_SUBST(DOMXML_SHARED_LIBADD)
-
fi
diff --git a/ext/xml/config.m4 b/ext/xml/config.m4
index c4c2de4aa6..481ee5d612 100644
--- a/ext/xml/config.m4
+++ b/ext/xml/config.m4
@@ -2,15 +2,54 @@ dnl
dnl $Id$
dnl
-PHP_ARG_ENABLE(xml,whether to enable XML support,
-[ --disable-xml Disable XML support using bundled expat lib], yes)
+AC_C_BIGENDIAN
-if test "$PHP_XML" = "yes"; then
- AC_DEFINE(HAVE_XML, 1, [ ])
+if test "$ac_cv_c_bigendian" = "yes"; then
+ order=4321
+else
+ order=1234
+fi
+
+PHP_ARG_WITH(xml,whether to enable XML support,
+[ --without-xml Disable XML support. Requires libxml2.], yes)
+
+PHP_ARG_WITH(libxml-dir, libxml install dir,
+[ --with-libxml-dir=DIR XML: libxml install prefix], no, no)
+
+PHP_ARG_WITH(expat-dir, libexpat install dir,
+[ --with-expat-dir=DIR XML: libexpat install prefix (deprecated)], no, no)
+
+if test "$PHP_XML" != "no"; then
+
+ if test "$PHP_XML" != "yes" && test -n "$PHP_LIBXML_DIR"; then
+ PHP_LIBXML_DIR=$PHP_XML
+ fi
+
+ PHP_SETUP_LIBXML(XML_SHARED_LIBADD, [
+ xml_sources="xml.c compat.c"
+ ], [
+ AC_MSG_ERROR(xml2-config not found. Use --with-libxml-dir=<DIR>)
+ ])
+
+ if test "$PHP_EXPAT_DIR" != "no"; then
+ AC_DEFINE(HAVE_LIBEXPAT, 1, [ ])
+ xml_sources="xml.c"
+
+ for i in $PHP_XML $PHP_EXPAT_DIR; do
+ if test -f "$i/lib/libexpat.a" -o -f "$i/lib/libexpat.$SHLIB_SUFFIX_NAME"; then
+ EXPAT_DIR=$i
+ fi
+ done
+
+ if test -z "$EXPAT_DIR"; then
+ AC_MSG_ERROR(not found. Please reinstall the expat distribution.)
+ fi
- if test "$PHP_BUNDLE_EXPAT" = "no" && test "$PHP_BUNDLE_LIBXML" = "no"; then
- AC_MSG_ERROR(xml support is enabled, however both xml libraries have been disabled.)
- fi
+ PHP_ADD_INCLUDE($EXPAT_DIR/include)
+ PHP_ADD_LIBRARY_WITH_PATH(expat, $EXPAT_DIR/lib, XML_SHARED_LIBADD)
+ fi
- PHP_NEW_EXTENSION(xml, compat.c xml.c, $ext_shared)
+ PHP_NEW_EXTENSION(xml, $xml_sources, $ext_shared)
+ PHP_SUBST(XML_SHARED_LIBADD)
+ AC_DEFINE(HAVE_XML, 1, [ ])
fi
diff --git a/ext/xmlrpc/config.m4 b/ext/xmlrpc/config.m4
index 712e240470..30e262d61a 100644
--- a/ext/xmlrpc/config.m4
+++ b/ext/xmlrpc/config.m4
@@ -11,10 +11,10 @@ PHP_ARG_WITH(xmlrpc, for XMLRPC-EPI support,
[ --with-xmlrpc[=DIR] Include XMLRPC-EPI support.])
PHP_ARG_WITH(expat-dir, libexpat dir for XMLRPC-EPI,
-[ --with-expat-dir=DIR XMLRPC-EPI: libexpat dir for XMLRPC-EPI.],yes,no)
+[ --with-expat-dir=DIR XMLRPC-EPI: libexpat dir for XMLRPC-EPI.],no,no)
PHP_ARG_WITH(iconv-dir, iconv dir for XMLRPC-EPI,
-[ --with-iconv-dir=DIR XMLRPC-EPI: iconv dir for XMLRPC-EPI.],yes,no)
+[ --with-iconv-dir=DIR XMLRPC-EPI: iconv dir for XMLRPC-EPI.],no,no)
if test "$PHP_XMLRPC" != "no"; then
@@ -87,7 +87,5 @@ dnl for xmlrpc-epi because of this.
PHP_ADD_INCLUDE($XMLRPC_DIR)
PHP_ADD_LIBRARY_WITH_PATH(xmlrpc, $XMLRPC_DIR/lib, XMLRPC_SHARED_LIBADD)
-
fi
-